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
29 #include "vkDefs.hpp"
30 #include "vkPlatform.hpp"
31 #include "vkStrUtil.hpp"
32 #include "vkRef.hpp"
33 #include "vkRefUtil.hpp"
34 #include "vkQueryUtil.hpp"
35 #include "vkMemUtil.hpp"
36 #include "vkDeviceUtil.hpp"
37 #include "vkPrograms.hpp"
38 #include "vkTypeUtil.hpp"
39 #include "vkWsiPlatform.hpp"
40 #include "vkWsiUtil.hpp"
41 #include "vkAllocationCallbackUtil.hpp"
42
43 #include "tcuTestLog.hpp"
44 #include "tcuFormatUtil.hpp"
45 #include "tcuPlatform.hpp"
46 #include "tcuResultCollector.hpp"
47
48 #include "deUniquePtr.hpp"
49 #include "deStringUtil.hpp"
50
51 namespace vk
52 {
53
operator !=(const VkSurfaceFormatKHR & a,const VkSurfaceFormatKHR & b)54 inline bool operator!= (const VkSurfaceFormatKHR& a, const VkSurfaceFormatKHR& b)
55 {
56 return (a.format != b.format) || (a.colorSpace != b.colorSpace);
57 }
58
operator ==(const VkSurfaceFormatKHR & a,const VkSurfaceFormatKHR & b)59 inline bool operator== (const VkSurfaceFormatKHR& a, const VkSurfaceFormatKHR& b)
60 {
61 return !(a != b);
62 }
63
64 } // vk
65
66 namespace vkt
67 {
68 namespace wsi
69 {
70
71 namespace
72 {
73
74 using namespace vk;
75 using namespace vk::wsi;
76
77 using tcu::TestLog;
78 using tcu::Maybe;
79 using tcu::UVec2;
80
81 using de::MovePtr;
82 using de::UniquePtr;
83
84 using std::string;
85 using std::vector;
86
87 enum
88 {
89 SURFACE_EXTENT_DETERMINED_BY_SWAPCHAIN_MAGIC = 0xffffffff
90 };
91
92 typedef vector<VkExtensionProperties> Extensions;
93
checkAllSupported(const Extensions & supportedExtensions,const vector<string> & requiredExtensions)94 void checkAllSupported (const Extensions& supportedExtensions, const vector<string>& requiredExtensions)
95 {
96 for (vector<string>::const_iterator requiredExtName = requiredExtensions.begin();
97 requiredExtName != requiredExtensions.end();
98 ++requiredExtName)
99 {
100 if (!isExtensionSupported(supportedExtensions, RequiredExtension(*requiredExtName)))
101 TCU_THROW(NotSupportedError, (*requiredExtName + " is not supported").c_str());
102 }
103 }
104
createInstanceWithWsi(const PlatformInterface & vkp,const Extensions & supportedExtensions,Type wsiType,const VkAllocationCallbacks * pAllocator=DE_NULL)105 Move<VkInstance> createInstanceWithWsi (const PlatformInterface& vkp,
106 const Extensions& supportedExtensions,
107 Type wsiType,
108 const VkAllocationCallbacks* pAllocator = DE_NULL)
109 {
110 vector<string> extensions;
111
112 extensions.push_back("VK_KHR_surface");
113 extensions.push_back(getExtensionName(wsiType));
114
115 checkAllSupported(supportedExtensions, extensions);
116
117 return createDefaultInstance(vkp, vector<string>(), extensions, pAllocator);
118 }
119
120 struct InstanceHelper
121 {
122 const vector<VkExtensionProperties> supportedExtensions;
123 Unique<VkInstance> instance;
124 const InstanceDriver vki;
125
InstanceHelpervkt::wsi::__anon1d6584650111::InstanceHelper126 InstanceHelper (Context& context, Type wsiType, const VkAllocationCallbacks* pAllocator = DE_NULL)
127 : supportedExtensions (enumerateInstanceExtensionProperties(context.getPlatformInterface(),
128 DE_NULL))
129 , instance (createInstanceWithWsi(context.getPlatformInterface(),
130 supportedExtensions,
131 wsiType,
132 pAllocator))
133 , vki (context.getPlatformInterface(), *instance)
134 {}
135 };
136
createDisplay(const vk::Platform & platform,const Extensions & supportedExtensions,Type wsiType)137 MovePtr<Display> createDisplay (const vk::Platform& platform,
138 const Extensions& supportedExtensions,
139 Type wsiType)
140 {
141 try
142 {
143 return MovePtr<Display>(platform.createWsiDisplay(wsiType));
144 }
145 catch (const tcu::NotSupportedError& e)
146 {
147 if (isExtensionSupported(supportedExtensions, RequiredExtension(getExtensionName(wsiType))))
148 {
149 // If VK_KHR_{platform}_surface was supported, vk::Platform implementation
150 // must support creating native display & window for that WSI type.
151 throw tcu::TestError(e.getMessage());
152 }
153 else
154 throw;
155 }
156 }
157
createWindow(const Display & display,const Maybe<UVec2> & initialSize)158 MovePtr<Window> createWindow (const Display& display, const Maybe<UVec2>& initialSize)
159 {
160 try
161 {
162 return MovePtr<Window>(display.createWindow(initialSize));
163 }
164 catch (const tcu::NotSupportedError& e)
165 {
166 // See createDisplay - assuming that wsi::Display was supported platform port
167 // should also support creating a window.
168 throw tcu::TestError(e.getMessage());
169 }
170 }
171
172 struct NativeObjects
173 {
174 const UniquePtr<Display> display;
175 const UniquePtr<Window> window;
176
NativeObjectsvkt::wsi::__anon1d6584650111::NativeObjects177 NativeObjects (Context& context,
178 const Extensions& supportedExtensions,
179 Type wsiType,
180 const Maybe<UVec2>& initialWindowSize = tcu::nothing<UVec2>())
181 : display (createDisplay(context.getTestContext().getPlatform().getVulkanPlatform(), supportedExtensions, wsiType))
182 , window (createWindow(*display, initialWindowSize))
183 {}
184 };
185
createSurfaceTest(Context & context,Type wsiType)186 tcu::TestStatus createSurfaceTest (Context& context, Type wsiType)
187 {
188 const InstanceHelper instHelper (context, wsiType);
189 const NativeObjects native (context, instHelper.supportedExtensions, wsiType);
190 const Unique<VkSurfaceKHR> surface (createSurface(instHelper.vki, *instHelper.instance, wsiType, *native.display, *native.window));
191
192 return tcu::TestStatus::pass("Creating surface succeeded");
193 }
194
createSurfaceCustomAllocatorTest(Context & context,Type wsiType)195 tcu::TestStatus createSurfaceCustomAllocatorTest (Context& context, Type wsiType)
196 {
197 AllocationCallbackRecorder allocationRecorder (getSystemAllocator());
198 tcu::TestLog& log = context.getTestContext().getLog();
199
200 {
201 const InstanceHelper instHelper (context, wsiType, allocationRecorder.getCallbacks());
202 const NativeObjects native (context, instHelper.supportedExtensions, wsiType);
203 const Unique<VkSurfaceKHR> surface (createSurface(instHelper.vki,
204 *instHelper.instance,
205 wsiType,
206 *native.display,
207 *native.window,
208 allocationRecorder.getCallbacks()));
209
210 if (!validateAndLog(log,
211 allocationRecorder,
212 (1u<<VK_SYSTEM_ALLOCATION_SCOPE_OBJECT) |
213 (1u<<VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE)))
214 return tcu::TestStatus::fail("Detected invalid system allocation callback");
215 }
216
217 if (!validateAndLog(log, allocationRecorder, 0u))
218 return tcu::TestStatus::fail("Detected invalid system allocation callback");
219
220 if (allocationRecorder.getRecordsBegin() == allocationRecorder.getRecordsEnd())
221 return tcu::TestStatus(QP_TEST_RESULT_QUALITY_WARNING, "Allocation callbacks were not used");
222 else
223 return tcu::TestStatus::pass("Creating surface succeeded using custom allocator");
224 }
225
createSurfaceSimulateOOMTest(Context & context,Type wsiType)226 tcu::TestStatus createSurfaceSimulateOOMTest (Context& context, Type wsiType)
227 {
228 tcu::TestLog& log = context.getTestContext().getLog();
229
230 for (deUint32 numPassingAllocs = 0; numPassingAllocs <= 1024u; ++numPassingAllocs)
231 {
232 AllocationCallbackRecorder allocationRecorder (getSystemAllocator());
233 DeterministicFailAllocator failingAllocator (allocationRecorder.getCallbacks(), numPassingAllocs);
234 bool gotOOM = false;
235
236 log << TestLog::Message << "Testing with " << numPassingAllocs << " first allocations succeeding" << TestLog::EndMessage;
237
238 try
239 {
240 const InstanceHelper instHelper (context, wsiType, failingAllocator.getCallbacks());
241 const NativeObjects native (context, instHelper.supportedExtensions, wsiType);
242 const Unique<VkSurfaceKHR> surface (createSurface(instHelper.vki,
243 *instHelper.instance,
244 wsiType,
245 *native.display,
246 *native.window,
247 failingAllocator.getCallbacks()));
248
249 if (!validateAndLog(log,
250 allocationRecorder,
251 (1u<<VK_SYSTEM_ALLOCATION_SCOPE_OBJECT) |
252 (1u<<VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE)))
253 return tcu::TestStatus::fail("Detected invalid system allocation callback");
254 }
255 catch (const OutOfMemoryError& e)
256 {
257 log << TestLog::Message << "Got " << e.getError() << TestLog::EndMessage;
258 gotOOM = true;
259 }
260
261 if (!validateAndLog(log, allocationRecorder, 0u))
262 return tcu::TestStatus::fail("Detected invalid system allocation callback");
263
264 if (!gotOOM)
265 {
266 log << TestLog::Message << "Creating surface succeeded!" << TestLog::EndMessage;
267
268 if (numPassingAllocs == 0)
269 return tcu::TestStatus(QP_TEST_RESULT_QUALITY_WARNING, "Allocation callbacks were not used");
270 else
271 return tcu::TestStatus::pass("OOM simulation completed");
272 }
273 }
274
275 return tcu::TestStatus(QP_TEST_RESULT_QUALITY_WARNING, "Creating surface did not succeed, callback limit exceeded");
276 }
277
getNumQueueFamilies(const InstanceInterface & vki,VkPhysicalDevice physicalDevice)278 deUint32 getNumQueueFamilies (const InstanceInterface& vki, VkPhysicalDevice physicalDevice)
279 {
280 deUint32 numFamilies = 0;
281
282 vki.getPhysicalDeviceQueueFamilyProperties(physicalDevice, &numFamilies, DE_NULL);
283
284 return numFamilies;
285 }
286
querySurfaceSupportTest(Context & context,Type wsiType)287 tcu::TestStatus querySurfaceSupportTest (Context& context, Type wsiType)
288 {
289 tcu::TestLog& log = context.getTestContext().getLog();
290 tcu::ResultCollector results (log);
291
292 const InstanceHelper instHelper (context, wsiType);
293 const NativeObjects native (context, instHelper.supportedExtensions, wsiType);
294 const Unique<VkSurfaceKHR> surface (createSurface(instHelper.vki, *instHelper.instance, wsiType, *native.display, *native.window));
295 const vector<VkPhysicalDevice> physicalDevices = enumeratePhysicalDevices(instHelper.vki, *instHelper.instance);
296
297 // On Android surface must be supported by all devices and queue families
298 const bool expectSupportedOnAll = wsiType == TYPE_ANDROID;
299
300 for (size_t deviceNdx = 0; deviceNdx < physicalDevices.size(); ++deviceNdx)
301 {
302 const VkPhysicalDevice physicalDevice = physicalDevices[deviceNdx];
303 const deUint32 numQueueFamilies = getNumQueueFamilies(instHelper.vki, physicalDevice);
304
305 for (deUint32 queueFamilyNdx = 0; queueFamilyNdx < numQueueFamilies; ++queueFamilyNdx)
306 {
307 const VkBool32 isSupported = getPhysicalDeviceSurfaceSupport(instHelper.vki, physicalDevice, queueFamilyNdx, *surface);
308
309 log << TestLog::Message << "Device " << deviceNdx << ", queue family " << queueFamilyNdx << ": "
310 << (isSupported == VK_FALSE ? "NOT " : "") << "supported"
311 << TestLog::EndMessage;
312
313 if (expectSupportedOnAll && !isSupported)
314 results.fail("Surface must be supported by all devices and queue families");
315 }
316 }
317
318 return tcu::TestStatus(results.getResult(), results.getMessage());
319 }
320
isSupportedByAnyQueue(const InstanceInterface & vki,VkPhysicalDevice physicalDevice,VkSurfaceKHR surface)321 bool isSupportedByAnyQueue (const InstanceInterface& vki, VkPhysicalDevice physicalDevice, VkSurfaceKHR surface)
322 {
323 const deUint32 numQueueFamilies = getNumQueueFamilies(vki, physicalDevice);
324
325 for (deUint32 queueFamilyNdx = 0; queueFamilyNdx < numQueueFamilies; ++queueFamilyNdx)
326 {
327 if (getPhysicalDeviceSurfaceSupport(vki, physicalDevice, queueFamilyNdx, surface) != VK_FALSE)
328 return true;
329 }
330
331 return false;
332 }
333
validateSurfaceCapabilities(tcu::ResultCollector & results,const VkSurfaceCapabilitiesKHR & capabilities)334 void validateSurfaceCapabilities (tcu::ResultCollector& results, const VkSurfaceCapabilitiesKHR& capabilities)
335 {
336 results.check(capabilities.minImageCount > 0,
337 "minImageCount must be larger than 0");
338
339 results.check(capabilities.minImageExtent.width > 0 &&
340 capabilities.minImageExtent.height > 0,
341 "minImageExtent dimensions must be larger than 0");
342
343 results.check(capabilities.maxImageExtent.width > 0 &&
344 capabilities.maxImageExtent.height > 0,
345 "maxImageExtent dimensions must be larger than 0");
346
347 results.check(capabilities.minImageExtent.width <= capabilities.maxImageExtent.width &&
348 capabilities.minImageExtent.height <= capabilities.maxImageExtent.height,
349 "maxImageExtent must be larger or equal to minImageExtent");
350
351 if (capabilities.currentExtent.width != SURFACE_EXTENT_DETERMINED_BY_SWAPCHAIN_MAGIC ||
352 capabilities.currentExtent.height != SURFACE_EXTENT_DETERMINED_BY_SWAPCHAIN_MAGIC)
353 {
354 results.check(capabilities.currentExtent.width > 0 &&
355 capabilities.currentExtent.height > 0,
356 "currentExtent dimensions must be larger than 0");
357
358 results.check(de::inRange(capabilities.currentExtent.width, capabilities.minImageExtent.width, capabilities.maxImageExtent.width) &&
359 de::inRange(capabilities.currentExtent.height, capabilities.minImageExtent.height, capabilities.maxImageExtent.height),
360 "currentExtent is not in supported extent limits");
361 }
362
363 results.check(capabilities.maxImageArrayLayers > 0,
364 "maxImageArrayLayers must be larger than 0");
365
366 results.check((capabilities.supportedUsageFlags & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) != 0,
367 "VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT must be set in supportedUsageFlags");
368
369 results.check(capabilities.supportedTransforms != 0,
370 "At least one transform must be supported");
371
372 results.check(dePop32(capabilities.currentTransform) != 0,
373 "Invalid currentTransform");
374
375 results.check((capabilities.supportedTransforms & capabilities.currentTransform) != 0,
376 "currentTransform is not supported by surface");
377
378 results.check(capabilities.supportedCompositeAlpha != 0,
379 "At least one alpha mode must be supported");
380 }
381
querySurfaceCapabilitiesTest(Context & context,Type wsiType)382 tcu::TestStatus querySurfaceCapabilitiesTest (Context& context, Type wsiType)
383 {
384 tcu::TestLog& log = context.getTestContext().getLog();
385 tcu::ResultCollector results (log);
386
387 const InstanceHelper instHelper (context, wsiType);
388 const NativeObjects native (context, instHelper.supportedExtensions, wsiType);
389 const Unique<VkSurfaceKHR> surface (createSurface(instHelper.vki, *instHelper.instance, wsiType, *native.display, *native.window));
390 const vector<VkPhysicalDevice> physicalDevices = enumeratePhysicalDevices(instHelper.vki, *instHelper.instance);
391
392 for (size_t deviceNdx = 0; deviceNdx < physicalDevices.size(); ++deviceNdx)
393 {
394 if (isSupportedByAnyQueue(instHelper.vki, physicalDevices[deviceNdx], *surface))
395 {
396 const VkSurfaceCapabilitiesKHR capabilities = getPhysicalDeviceSurfaceCapabilities(instHelper.vki,
397 physicalDevices[deviceNdx],
398 *surface);
399
400 log << TestLog::Message << "Device " << deviceNdx << ": " << capabilities << TestLog::EndMessage;
401
402 validateSurfaceCapabilities(results, capabilities);
403 }
404 // else skip query as surface is not supported by the device
405 }
406
407 return tcu::TestStatus(results.getResult(), results.getMessage());
408 }
409
validateSurfaceFormats(tcu::ResultCollector & results,Type wsiType,const vector<VkSurfaceFormatKHR> & formats)410 void validateSurfaceFormats (tcu::ResultCollector& results, Type wsiType, const vector<VkSurfaceFormatKHR>& formats)
411 {
412 const VkSurfaceFormatKHR* requiredFormats = DE_NULL;
413 size_t numRequiredFormats = 0;
414
415 if (wsiType == TYPE_ANDROID)
416 {
417 static const VkSurfaceFormatKHR s_androidFormats[] =
418 {
419 { VK_FORMAT_R8G8B8A8_UNORM, VK_COLORSPACE_SRGB_NONLINEAR_KHR },
420 { VK_FORMAT_R8G8B8A8_SRGB, VK_COLORSPACE_SRGB_NONLINEAR_KHR },
421 { VK_FORMAT_R5G6B5_UNORM_PACK16, VK_COLORSPACE_SRGB_NONLINEAR_KHR }
422 };
423
424 requiredFormats = &s_androidFormats[0];
425 numRequiredFormats = DE_LENGTH_OF_ARRAY(s_androidFormats);
426 }
427
428 for (size_t ndx = 0; ndx < numRequiredFormats; ++ndx)
429 {
430 const VkSurfaceFormatKHR& requiredFormat = requiredFormats[ndx];
431
432 if (!de::contains(formats.begin(), formats.end(), requiredFormat))
433 results.fail(de::toString(requiredFormat) + " not supported");
434 }
435 }
436
querySurfaceFormatsTest(Context & context,Type wsiType)437 tcu::TestStatus querySurfaceFormatsTest (Context& context, Type wsiType)
438 {
439 tcu::TestLog& log = context.getTestContext().getLog();
440 tcu::ResultCollector results (log);
441
442 const InstanceHelper instHelper (context, wsiType);
443 const NativeObjects native (context, instHelper.supportedExtensions, wsiType);
444 const Unique<VkSurfaceKHR> surface (createSurface(instHelper.vki, *instHelper.instance, wsiType, *native.display, *native.window));
445 const vector<VkPhysicalDevice> physicalDevices = enumeratePhysicalDevices(instHelper.vki, *instHelper.instance);
446
447 for (size_t deviceNdx = 0; deviceNdx < physicalDevices.size(); ++deviceNdx)
448 {
449 if (isSupportedByAnyQueue(instHelper.vki, physicalDevices[deviceNdx], *surface))
450 {
451 const vector<VkSurfaceFormatKHR> formats = getPhysicalDeviceSurfaceFormats(instHelper.vki,
452 physicalDevices[deviceNdx],
453 *surface);
454
455 log << TestLog::Message << "Device " << deviceNdx << ": " << tcu::formatArray(formats.begin(), formats.end()) << TestLog::EndMessage;
456
457 validateSurfaceFormats(results, wsiType, formats);
458 }
459 // else skip query as surface is not supported by the device
460 }
461
462 return tcu::TestStatus(results.getResult(), results.getMessage());
463 }
464
validateSurfacePresentModes(tcu::ResultCollector & results,Type wsiType,const vector<VkPresentModeKHR> & modes)465 void validateSurfacePresentModes (tcu::ResultCollector& results, Type wsiType, const vector<VkPresentModeKHR>& modes)
466 {
467 results.check(de::contains(modes.begin(), modes.end(), VK_PRESENT_MODE_FIFO_KHR),
468 "VK_PRESENT_MODE_FIFO_KHR is not supported");
469
470 if (wsiType == TYPE_ANDROID)
471 results.check(de::contains(modes.begin(), modes.end(), VK_PRESENT_MODE_MAILBOX_KHR),
472 "VK_PRESENT_MODE_MAILBOX_KHR is not supported");
473 }
474
querySurfacePresentModesTest(Context & context,Type wsiType)475 tcu::TestStatus querySurfacePresentModesTest (Context& context, Type wsiType)
476 {
477 tcu::TestLog& log = context.getTestContext().getLog();
478 tcu::ResultCollector results (log);
479
480 const InstanceHelper instHelper (context, wsiType);
481 const NativeObjects native (context, instHelper.supportedExtensions, wsiType);
482 const Unique<VkSurfaceKHR> surface (createSurface(instHelper.vki, *instHelper.instance, wsiType, *native.display, *native.window));
483 const vector<VkPhysicalDevice> physicalDevices = enumeratePhysicalDevices(instHelper.vki, *instHelper.instance);
484
485 for (size_t deviceNdx = 0; deviceNdx < physicalDevices.size(); ++deviceNdx)
486 {
487 if (isSupportedByAnyQueue(instHelper.vki, physicalDevices[deviceNdx], *surface))
488 {
489 const vector<VkPresentModeKHR> modes = getPhysicalDeviceSurfacePresentModes(instHelper.vki, physicalDevices[deviceNdx], *surface);
490
491 log << TestLog::Message << "Device " << deviceNdx << ": " << tcu::formatArray(modes.begin(), modes.end()) << TestLog::EndMessage;
492
493 validateSurfacePresentModes(results, wsiType, modes);
494 }
495 // else skip query as surface is not supported by the device
496 }
497
498 return tcu::TestStatus(results.getResult(), results.getMessage());
499 }
500
createSurfaceInitialSizeTest(Context & context,Type wsiType)501 tcu::TestStatus createSurfaceInitialSizeTest (Context& context, Type wsiType)
502 {
503 tcu::TestLog& log = context.getTestContext().getLog();
504 tcu::ResultCollector results (log);
505
506 const InstanceHelper instHelper (context, wsiType);
507
508 const UniquePtr<Display> nativeDisplay (createDisplay(context.getTestContext().getPlatform().getVulkanPlatform(),
509 instHelper.supportedExtensions,
510 wsiType));
511
512 const vector<VkPhysicalDevice> physicalDevices = enumeratePhysicalDevices(instHelper.vki, *instHelper.instance);
513 const UVec2 sizes[] =
514 {
515 UVec2(64, 64),
516 UVec2(124, 119),
517 UVec2(256, 512)
518 };
519
520 DE_ASSERT(getPlatformProperties(wsiType).features & PlatformProperties::FEATURE_INITIAL_WINDOW_SIZE);
521
522 for (int sizeNdx = 0; sizeNdx < DE_LENGTH_OF_ARRAY(sizes); ++sizeNdx)
523 {
524 const UVec2& testSize = sizes[sizeNdx];
525 const UniquePtr<Window> nativeWindow (createWindow(*nativeDisplay, tcu::just(testSize)));
526 const Unique<VkSurfaceKHR> surface (createSurface(instHelper.vki, *instHelper.instance, wsiType, *nativeDisplay, *nativeWindow));
527
528 for (size_t deviceNdx = 0; deviceNdx < physicalDevices.size(); ++deviceNdx)
529 {
530 if (isSupportedByAnyQueue(instHelper.vki, physicalDevices[deviceNdx], *surface))
531 {
532 const VkSurfaceCapabilitiesKHR capabilities = getPhysicalDeviceSurfaceCapabilities(instHelper.vki, physicalDevices[deviceNdx], *surface);
533
534 // \note Assumes that surface size is NOT set by swapchain if initial window size is honored by platform
535 results.check(capabilities.currentExtent.width == testSize.x() &&
536 capabilities.currentExtent.height == testSize.y(),
537 "currentExtent " + de::toString(capabilities.currentExtent) + " doesn't match requested size " + de::toString(testSize));
538 }
539 }
540 }
541
542 return tcu::TestStatus(results.getResult(), results.getMessage());
543 }
544
resizeSurfaceTest(Context & context,Type wsiType)545 tcu::TestStatus resizeSurfaceTest (Context& context, Type wsiType)
546 {
547 tcu::TestLog& log = context.getTestContext().getLog();
548 tcu::ResultCollector results (log);
549
550 const InstanceHelper instHelper (context, wsiType);
551
552 const UniquePtr<Display> nativeDisplay (createDisplay(context.getTestContext().getPlatform().getVulkanPlatform(),
553 instHelper.supportedExtensions,
554 wsiType));
555 UniquePtr<Window> nativeWindow (createWindow(*nativeDisplay, tcu::nothing<UVec2>()));
556
557 const vector<VkPhysicalDevice> physicalDevices = enumeratePhysicalDevices(instHelper.vki, *instHelper.instance);
558 const Unique<VkSurfaceKHR> surface (createSurface(instHelper.vki, *instHelper.instance, wsiType, *nativeDisplay, *nativeWindow));
559
560 const UVec2 sizes[] =
561 {
562 UVec2(64, 64),
563 UVec2(124, 119),
564 UVec2(256, 512)
565 };
566
567 DE_ASSERT(getPlatformProperties(wsiType).features & PlatformProperties::FEATURE_RESIZE_WINDOW);
568
569 for (int sizeNdx = 0; sizeNdx < DE_LENGTH_OF_ARRAY(sizes); ++sizeNdx)
570 {
571 const UVec2 testSize = sizes[sizeNdx];
572
573 try
574 {
575 nativeWindow->resize(testSize);
576 }
577 catch (const tcu::Exception& e)
578 {
579 // Make sure all exception types result in a test failure
580 results.fail(e.getMessage());
581 }
582
583 for (size_t deviceNdx = 0; deviceNdx < physicalDevices.size(); ++deviceNdx)
584 {
585 if (isSupportedByAnyQueue(instHelper.vki, physicalDevices[deviceNdx], *surface))
586 {
587 const VkSurfaceCapabilitiesKHR capabilities = getPhysicalDeviceSurfaceCapabilities(instHelper.vki, physicalDevices[deviceNdx], *surface);
588
589 // \note Assumes that surface size is NOT set by swapchain if initial window size is honored by platform
590 results.check(capabilities.currentExtent.width == testSize.x() &&
591 capabilities.currentExtent.height == testSize.y(),
592 "currentExtent " + de::toString(capabilities.currentExtent) + " doesn't match requested size " + de::toString(testSize));
593 }
594 }
595 }
596
597 return tcu::TestStatus(results.getResult(), results.getMessage());
598 }
599
600 } // anonymous
601
createSurfaceTests(tcu::TestCaseGroup * testGroup,vk::wsi::Type wsiType)602 void createSurfaceTests (tcu::TestCaseGroup* testGroup, vk::wsi::Type wsiType)
603 {
604 const PlatformProperties& platformProperties = getPlatformProperties(wsiType);
605
606 addFunctionCase(testGroup, "create", "Create surface", createSurfaceTest, wsiType);
607 addFunctionCase(testGroup, "create_custom_allocator", "Create surface with custom allocator", createSurfaceCustomAllocatorTest, wsiType);
608 addFunctionCase(testGroup, "create_simulate_oom", "Create surface with simulating OOM", createSurfaceSimulateOOMTest, wsiType);
609 addFunctionCase(testGroup, "query_support", "Query surface support", querySurfaceSupportTest, wsiType);
610 addFunctionCase(testGroup, "query_capabilities", "Query surface capabilities", querySurfaceCapabilitiesTest, wsiType);
611 addFunctionCase(testGroup, "query_formats", "Query surface formats", querySurfaceFormatsTest, wsiType);
612 addFunctionCase(testGroup, "query_present_modes", "Query surface present modes", querySurfacePresentModesTest, wsiType);
613
614 if ((platformProperties.features & PlatformProperties::FEATURE_INITIAL_WINDOW_SIZE) != 0)
615 addFunctionCase(testGroup, "initial_size", "Create surface with initial window size set", createSurfaceInitialSizeTest, wsiType);
616
617 if ((platformProperties.features & PlatformProperties::FEATURE_RESIZE_WINDOW) != 0)
618 addFunctionCase(testGroup, "resize", "Resize window and surface", resizeSurfaceTest, wsiType);
619 }
620
621 } // wsi
622 } // vkt
623