1 /*-------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
5 * Copyright (c) 2016 Google Inc.
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
21 * \brief VkSurface Tests
22 *//*--------------------------------------------------------------------*/
24 #include "vktWsiSurfaceTests.hpp"
26 #include "vktTestCaseUtil.hpp"
27 #include "vktTestGroupUtil.hpp"
30 #include "vkPlatform.hpp"
31 #include "vkStrUtil.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 #include "vkQueryUtil.hpp"
44 #include "tcuTestLog.hpp"
45 #include "tcuFormatUtil.hpp"
46 #include "tcuPlatform.hpp"
47 #include "tcuResultCollector.hpp"
48 #include "tcuCommandLine.hpp"
50 #include "deUniquePtr.hpp"
51 #include "deStringUtil.hpp"
57 inline bool operator!= (const VkSurfaceFormatKHR& a, const VkSurfaceFormatKHR& b)
59 return (a.format != b.format) || (a.colorSpace != b.colorSpace);
62 inline bool operator== (const VkSurfaceFormatKHR& a, const VkSurfaceFormatKHR& b)
67 inline bool operator!= (const VkExtent2D& a, const VkExtent2D& b)
69 return (a.width != b.width) || (a.height != b.height);
72 inline bool operator!= (const VkSurfaceCapabilitiesKHR& a, const VkSurfaceCapabilitiesKHR& b)
74 return (a.minImageCount != b.minImageCount) ||
75 (a.maxImageCount != b.maxImageCount) ||
76 (a.currentExtent != b.currentExtent) ||
77 (a.minImageExtent != b.minImageExtent) ||
78 (a.maxImageExtent != b.maxImageExtent) ||
79 (a.maxImageArrayLayers != b.maxImageArrayLayers) ||
80 (a.supportedTransforms != b.supportedTransforms) ||
81 (a.currentTransform != b.currentTransform) ||
82 (a.supportedCompositeAlpha != b.supportedCompositeAlpha) ||
83 (a.supportedUsageFlags != b.supportedUsageFlags);
97 using namespace vk::wsi;
111 SURFACE_EXTENT_DETERMINED_BY_SWAPCHAIN_MAGIC = 0xffffffff
116 GUARD_SIZE = 0x20, //!< Number of bytes to check
117 GUARD_VALUE = 0xcd, //!< Data pattern
121 class CheckIncompleteResult
124 virtual ~CheckIncompleteResult (void) {}
125 virtual void getResult (const InstanceInterface& vki, const VkPhysicalDevice physDevice, const VkSurfaceKHR surface, T* data) = 0;
127 void operator() (tcu::ResultCollector& results,
128 const InstanceInterface& vki,
129 const VkPhysicalDevice physDevice,
130 const VkSurfaceKHR surface,
131 const std::size_t expectedCompleteSize)
133 if (expectedCompleteSize == 0)
136 vector<T> outputData (expectedCompleteSize);
137 const deUint32 usedSize = static_cast<deUint32>(expectedCompleteSize / 3);
139 ValidateQueryBits::fillBits(outputData.begin(), outputData.end()); // unused entries should have this pattern intact
141 m_result = VK_SUCCESS;
143 getResult(vki, physDevice, surface, &outputData[0]); // update m_count and m_result
145 if (m_count != usedSize || m_result != VK_INCOMPLETE || !ValidateQueryBits::checkBits(outputData.begin() + m_count, outputData.end()))
146 results.fail("Query didn't return VK_INCOMPLETE");
154 struct CheckPhysicalDeviceSurfaceFormatsIncompleteResult : public CheckIncompleteResult<VkSurfaceFormatKHR>
156 void getResult (const InstanceInterface& vki, const VkPhysicalDevice physDevice, const VkSurfaceKHR surface, VkSurfaceFormatKHR* data)
158 m_result = vki.getPhysicalDeviceSurfaceFormatsKHR(physDevice, surface, &m_count, data);
162 struct CheckPhysicalDeviceSurfacePresentModesIncompleteResult : public CheckIncompleteResult<VkPresentModeKHR>
164 void getResult (const InstanceInterface& vki, const VkPhysicalDevice physDevice, const VkSurfaceKHR surface, VkPresentModeKHR* data)
166 m_result = vki.getPhysicalDeviceSurfacePresentModesKHR(physDevice, surface, &m_count, data);
170 typedef vector<VkExtensionProperties> Extensions;
172 Move<VkInstance> createInstanceWithWsi (const PlatformInterface& vkp,
174 const Extensions& supportedExtensions,
176 const vector<string> extraExtensions,
177 const VkAllocationCallbacks* pAllocator = DE_NULL)
179 vector<string> extensions = extraExtensions;
181 extensions.push_back("VK_KHR_surface");
182 extensions.push_back(getExtensionName(wsiType));
184 vector<string> instanceExtensions;
186 for (vector<string>::const_iterator extensionName = extensions.begin();
187 extensionName != extensions.end();
190 if (!isInstanceExtensionSupported(version, supportedExtensions, RequiredExtension(*extensionName)))
191 TCU_THROW(NotSupportedError, (*extensionName + " is not supported").c_str());
193 if (!isCoreInstanceExtension(version, *extensionName))
194 instanceExtensions.push_back(*extensionName);
197 return vk::createDefaultInstance(vkp, version, vector<string>(), instanceExtensions, pAllocator);
200 struct InstanceHelper
202 const vector<VkExtensionProperties> supportedExtensions;
203 Unique<VkInstance> instance;
204 const InstanceDriver vki;
206 InstanceHelper (Context& context, Type wsiType, const VkAllocationCallbacks* pAllocator = DE_NULL)
207 : supportedExtensions (enumerateInstanceExtensionProperties(context.getPlatformInterface(),
209 , instance (createInstanceWithWsi(context.getPlatformInterface(),
210 context.getUsedApiVersion(),
215 , vki (context.getPlatformInterface(), *instance)
218 InstanceHelper (Context& context, Type wsiType, const vector<string>& extensions, const VkAllocationCallbacks* pAllocator = DE_NULL)
219 : supportedExtensions (enumerateInstanceExtensionProperties(context.getPlatformInterface(),
221 , instance (createInstanceWithWsi(context.getPlatformInterface(),
222 context.getUsedApiVersion(),
227 , vki (context.getPlatformInterface(), *instance)
231 MovePtr<Display> createDisplay (const vk::Platform& platform,
232 const Extensions& supportedExtensions,
237 return MovePtr<Display>(platform.createWsiDisplay(wsiType));
239 catch (const tcu::NotSupportedError& e)
241 if (isExtensionSupported(supportedExtensions, RequiredExtension(getExtensionName(wsiType))) &&
242 platform.hasDisplay(wsiType))
244 // If VK_KHR_{platform}_surface was supported, vk::Platform implementation
245 // must support creating native display & window for that WSI type.
246 throw tcu::TestError(e.getMessage());
253 MovePtr<Window> createWindow (const Display& display, const Maybe<UVec2>& initialSize)
257 return MovePtr<Window>(display.createWindow(initialSize));
259 catch (const tcu::NotSupportedError& e)
261 // See createDisplay - assuming that wsi::Display was supported platform port
262 // should also support creating a window.
263 throw tcu::TestError(e.getMessage());
269 const UniquePtr<Display> display;
270 const UniquePtr<Window> window;
272 NativeObjects (Context& context,
273 const Extensions& supportedExtensions,
275 const Maybe<UVec2>& initialWindowSize = tcu::nothing<UVec2>())
276 : display (createDisplay(context.getTestContext().getPlatform().getVulkanPlatform(), supportedExtensions, wsiType))
277 , window (createWindow(*display, initialWindowSize))
281 tcu::TestStatus createSurfaceTest (Context& context, Type wsiType)
283 const InstanceHelper instHelper (context, wsiType);
284 const NativeObjects native (context, instHelper.supportedExtensions, wsiType);
285 const Unique<VkSurfaceKHR> surface (createSurface(instHelper.vki, *instHelper.instance, wsiType, *native.display, *native.window));
287 return tcu::TestStatus::pass("Creating surface succeeded");
290 tcu::TestStatus createSurfaceCustomAllocatorTest (Context& context, Type wsiType)
292 AllocationCallbackRecorder allocationRecorder (getSystemAllocator());
293 tcu::TestLog& log = context.getTestContext().getLog();
296 const InstanceHelper instHelper (context, wsiType, allocationRecorder.getCallbacks());
297 const NativeObjects native (context, instHelper.supportedExtensions, wsiType);
298 const Unique<VkSurfaceKHR> surface (createSurface(instHelper.vki,
299 *instHelper.instance,
303 allocationRecorder.getCallbacks()));
305 if (!validateAndLog(log,
307 (1u<<VK_SYSTEM_ALLOCATION_SCOPE_OBJECT) |
308 (1u<<VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE)))
309 return tcu::TestStatus::fail("Detected invalid system allocation callback");
312 if (!validateAndLog(log, allocationRecorder, 0u))
313 return tcu::TestStatus::fail("Detected invalid system allocation callback");
315 if (allocationRecorder.getRecordsBegin() == allocationRecorder.getRecordsEnd())
316 return tcu::TestStatus(QP_TEST_RESULT_QUALITY_WARNING, "Allocation callbacks were not used");
318 return tcu::TestStatus::pass("Creating surface succeeded using custom allocator");
321 tcu::TestStatus createSurfaceSimulateOOMTest (Context& context, Type wsiType)
323 tcu::TestLog& log = context.getTestContext().getLog();
325 for (deUint32 numPassingAllocs = 0; numPassingAllocs <= 1024u; ++numPassingAllocs)
327 AllocationCallbackRecorder allocationRecorder (getSystemAllocator());
328 DeterministicFailAllocator failingAllocator (allocationRecorder.getCallbacks(),
329 DeterministicFailAllocator::MODE_DO_NOT_COUNT,
333 log << TestLog::Message << "Testing with " << numPassingAllocs << " first allocations succeeding" << TestLog::EndMessage;
337 const InstanceHelper instHelper (context, wsiType, failingAllocator.getCallbacks());
339 // OOM is not simulated for VkInstance as we don't want to spend time
340 // testing OOM paths inside instance creation.
341 failingAllocator.reset(DeterministicFailAllocator::MODE_COUNT_AND_FAIL, numPassingAllocs);
343 const NativeObjects native (context, instHelper.supportedExtensions, wsiType);
344 const Unique<VkSurfaceKHR> surface (createSurface(instHelper.vki,
345 *instHelper.instance,
349 failingAllocator.getCallbacks()));
351 if (!validateAndLog(log,
353 (1u<<VK_SYSTEM_ALLOCATION_SCOPE_OBJECT) |
354 (1u<<VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE)))
355 return tcu::TestStatus::fail("Detected invalid system allocation callback");
357 catch (const OutOfMemoryError& e)
359 log << TestLog::Message << "Got " << e.getError() << TestLog::EndMessage;
363 if (!validateAndLog(log, allocationRecorder, 0u))
364 return tcu::TestStatus::fail("Detected invalid system allocation callback");
368 log << TestLog::Message << "Creating surface succeeded!" << TestLog::EndMessage;
370 if (numPassingAllocs == 0)
371 return tcu::TestStatus(QP_TEST_RESULT_QUALITY_WARNING, "Allocation callbacks were not used");
373 return tcu::TestStatus::pass("OOM simulation completed");
377 return tcu::TestStatus(QP_TEST_RESULT_QUALITY_WARNING, "Creating surface did not succeed, callback limit exceeded");
380 deUint32 getNumQueueFamilies (const InstanceInterface& vki, VkPhysicalDevice physicalDevice)
382 deUint32 numFamilies = 0;
384 vki.getPhysicalDeviceQueueFamilyProperties(physicalDevice, &numFamilies, DE_NULL);
389 tcu::TestStatus querySurfaceSupportTest (Context& context, Type wsiType)
391 tcu::TestLog& log = context.getTestContext().getLog();
392 tcu::ResultCollector results (log);
394 const InstanceHelper instHelper (context, wsiType);
395 const NativeObjects native (context, instHelper.supportedExtensions, wsiType);
396 const Unique<VkSurfaceKHR> surface (createSurface(instHelper.vki, *instHelper.instance, wsiType, *native.display, *native.window));
397 const vector<VkPhysicalDevice> physicalDevices = enumeratePhysicalDevices(instHelper.vki, *instHelper.instance);
399 // On Android surface must be supported by all devices and queue families
400 const bool expectSupportedOnAll = wsiType == TYPE_ANDROID;
402 for (size_t deviceNdx = 0; deviceNdx < physicalDevices.size(); ++deviceNdx)
404 const VkPhysicalDevice physicalDevice = physicalDevices[deviceNdx];
405 const deUint32 numQueueFamilies = getNumQueueFamilies(instHelper.vki, physicalDevice);
407 for (deUint32 queueFamilyNdx = 0; queueFamilyNdx < numQueueFamilies; ++queueFamilyNdx)
409 const VkBool32 isSupported = getPhysicalDeviceSurfaceSupport(instHelper.vki, physicalDevice, queueFamilyNdx, *surface);
411 log << TestLog::Message << "Device " << deviceNdx << ", queue family " << queueFamilyNdx << ": "
412 << (isSupported == VK_FALSE ? "NOT " : "") << "supported"
413 << TestLog::EndMessage;
415 if (expectSupportedOnAll && !isSupported)
416 results.fail("Surface must be supported by all devices and queue families");
420 return tcu::TestStatus(results.getResult(), results.getMessage());
423 bool isSupportedByAnyQueue (const InstanceInterface& vki, VkPhysicalDevice physicalDevice, VkSurfaceKHR surface)
425 const deUint32 numQueueFamilies = getNumQueueFamilies(vki, physicalDevice);
427 for (deUint32 queueFamilyNdx = 0; queueFamilyNdx < numQueueFamilies; ++queueFamilyNdx)
429 if (getPhysicalDeviceSurfaceSupport(vki, physicalDevice, queueFamilyNdx, surface) != VK_FALSE)
436 void validateSurfaceCapabilities (tcu::ResultCollector& results, const VkSurfaceCapabilitiesKHR& capabilities)
438 results.check(capabilities.minImageCount > 0,
439 "minImageCount must be larger than 0");
441 results.check(capabilities.minImageExtent.width > 0 &&
442 capabilities.minImageExtent.height > 0,
443 "minImageExtent dimensions must be larger than 0");
445 results.check(capabilities.maxImageExtent.width > 0 &&
446 capabilities.maxImageExtent.height > 0,
447 "maxImageExtent dimensions must be larger than 0");
449 results.check(capabilities.minImageExtent.width <= capabilities.maxImageExtent.width &&
450 capabilities.minImageExtent.height <= capabilities.maxImageExtent.height,
451 "maxImageExtent must be larger or equal to minImageExtent");
453 if (capabilities.currentExtent.width != SURFACE_EXTENT_DETERMINED_BY_SWAPCHAIN_MAGIC ||
454 capabilities.currentExtent.height != SURFACE_EXTENT_DETERMINED_BY_SWAPCHAIN_MAGIC)
456 results.check(capabilities.currentExtent.width > 0 &&
457 capabilities.currentExtent.height > 0,
458 "currentExtent dimensions must be larger than 0");
460 results.check(de::inRange(capabilities.currentExtent.width, capabilities.minImageExtent.width, capabilities.maxImageExtent.width) &&
461 de::inRange(capabilities.currentExtent.height, capabilities.minImageExtent.height, capabilities.maxImageExtent.height),
462 "currentExtent is not in supported extent limits");
465 results.check(capabilities.maxImageArrayLayers > 0,
466 "maxImageArrayLayers must be larger than 0");
468 results.check((capabilities.supportedUsageFlags & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) != 0,
469 "VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT must be set in supportedUsageFlags");
471 results.check(capabilities.supportedTransforms != 0,
472 "At least one transform must be supported");
474 results.check(dePop32(capabilities.currentTransform) != 0,
475 "Invalid currentTransform");
477 results.check((capabilities.supportedTransforms & capabilities.currentTransform) != 0,
478 "currentTransform is not supported by surface");
480 results.check(capabilities.supportedCompositeAlpha != 0,
481 "At least one alpha mode must be supported");
484 tcu::TestStatus querySurfaceCapabilitiesTest (Context& context, Type wsiType)
486 tcu::TestLog& log = context.getTestContext().getLog();
487 tcu::ResultCollector results (log);
489 const InstanceHelper instHelper (context, wsiType);
490 const NativeObjects native (context, instHelper.supportedExtensions, wsiType);
491 const Unique<VkSurfaceKHR> surface (createSurface(instHelper.vki, *instHelper.instance, wsiType, *native.display, *native.window));
492 const vector<VkPhysicalDevice> physicalDevices = enumeratePhysicalDevices(instHelper.vki, *instHelper.instance);
494 for (size_t deviceNdx = 0; deviceNdx < physicalDevices.size(); ++deviceNdx)
496 if (isSupportedByAnyQueue(instHelper.vki, physicalDevices[deviceNdx], *surface))
498 const VkSurfaceCapabilitiesKHR capabilities = getPhysicalDeviceSurfaceCapabilities(instHelper.vki,
499 physicalDevices[deviceNdx],
502 log << TestLog::Message << "Device " << deviceNdx << ": " << capabilities << TestLog::EndMessage;
504 validateSurfaceCapabilities(results, capabilities);
506 // else skip query as surface is not supported by the device
509 return tcu::TestStatus(results.getResult(), results.getMessage());
512 tcu::TestStatus querySurfaceCapabilities2Test (Context& context, Type wsiType)
514 tcu::TestLog& log = context.getTestContext().getLog();
515 tcu::ResultCollector results (log);
517 const InstanceHelper instHelper (context, wsiType, vector<string>(1, string("VK_KHR_get_surface_capabilities2")));
518 const NativeObjects native (context, instHelper.supportedExtensions, wsiType);
519 const Unique<VkSurfaceKHR> surface (createSurface(instHelper.vki, *instHelper.instance, wsiType, *native.display, *native.window));
520 const vector<VkPhysicalDevice> physicalDevices = enumeratePhysicalDevices(instHelper.vki, *instHelper.instance);
522 for (size_t deviceNdx = 0; deviceNdx < physicalDevices.size(); ++deviceNdx)
524 if (isSupportedByAnyQueue(instHelper.vki, physicalDevices[deviceNdx], *surface))
526 const VkSurfaceCapabilitiesKHR refCapabilities = getPhysicalDeviceSurfaceCapabilities(instHelper.vki,
527 physicalDevices[deviceNdx],
529 VkSurfaceCapabilities2KHR extCapabilities;
531 deMemset(&extCapabilities, 0xcd, sizeof(VkSurfaceCapabilities2KHR));
532 extCapabilities.sType = VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_KHR;
533 extCapabilities.pNext = DE_NULL;
536 const VkPhysicalDeviceSurfaceInfo2KHR surfaceInfo =
538 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SURFACE_INFO_2_KHR,
542 VkPhysicalDeviceSurfaceInfo2KHR infoCopy;
544 deMemcpy(&infoCopy, &surfaceInfo, sizeof(VkPhysicalDeviceSurfaceInfo2KHR));
546 VK_CHECK(instHelper.vki.getPhysicalDeviceSurfaceCapabilities2KHR(physicalDevices[deviceNdx], &surfaceInfo, &extCapabilities));
548 results.check(deMemoryEqual(&surfaceInfo, &infoCopy, sizeof(VkPhysicalDeviceSurfaceInfo2KHR)) == DE_TRUE, "Driver wrote into input struct");
551 results.check(extCapabilities.sType == VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_KHR &&
552 extCapabilities.pNext == DE_NULL,
553 "sType/pNext modified");
555 if (refCapabilities != extCapabilities.surfaceCapabilities)
557 log << TestLog::Message
558 << "Device " << deviceNdx
559 << ": expected " << refCapabilities
560 << ", got " << extCapabilities.surfaceCapabilities
561 << TestLog::EndMessage;
562 results.fail("Mismatch between VK_KHR_surface and VK_KHR_surface2 query results");
567 return tcu::TestStatus(results.getResult(), results.getMessage());
570 void validateSurfaceFormats (tcu::ResultCollector& results, Type wsiType, const vector<VkSurfaceFormatKHR>& formats)
572 const VkSurfaceFormatKHR* requiredFormats = DE_NULL;
573 size_t numRequiredFormats = 0;
575 if (wsiType == TYPE_ANDROID)
577 static const VkSurfaceFormatKHR s_androidFormats[] =
579 { VK_FORMAT_R8G8B8A8_UNORM, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR },
580 { VK_FORMAT_R8G8B8A8_SRGB, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR },
581 { VK_FORMAT_R5G6B5_UNORM_PACK16, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR }
584 requiredFormats = &s_androidFormats[0];
585 numRequiredFormats = DE_LENGTH_OF_ARRAY(s_androidFormats);
588 for (size_t ndx = 0; ndx < numRequiredFormats; ++ndx)
590 const VkSurfaceFormatKHR& requiredFormat = requiredFormats[ndx];
592 if (!de::contains(formats.begin(), formats.end(), requiredFormat))
593 results.fail(de::toString(requiredFormat) + " not supported");
596 // Check that there are no duplicates
597 for (size_t ndx = 1; ndx < formats.size(); ++ndx)
599 if (de::contains(formats.begin(), formats.begin() + ndx, formats[ndx]))
600 results.fail("Found duplicate entry " + de::toString(formats[ndx]));
604 tcu::TestStatus querySurfaceFormatsTest (Context& context, Type wsiType)
606 tcu::TestLog& log = context.getTestContext().getLog();
607 tcu::ResultCollector results (log);
609 const InstanceHelper instHelper (context, wsiType);
610 const NativeObjects native (context, instHelper.supportedExtensions, wsiType);
611 const Unique<VkSurfaceKHR> surface (createSurface(instHelper.vki, *instHelper.instance, wsiType, *native.display, *native.window));
612 const vector<VkPhysicalDevice> physicalDevices = enumeratePhysicalDevices(instHelper.vki, *instHelper.instance);
614 for (size_t deviceNdx = 0; deviceNdx < physicalDevices.size(); ++deviceNdx)
616 if (isSupportedByAnyQueue(instHelper.vki, physicalDevices[deviceNdx], *surface))
618 deUint32 numFormats = 0;
620 VK_CHECK(instHelper.vki.getPhysicalDeviceSurfaceFormatsKHR(physicalDevices[deviceNdx], *surface, &numFormats, DE_NULL));
622 std::vector<VkSurfaceFormatKHR> formats (numFormats + 1);
626 const deUint32 numFormatsOrig = numFormats;
628 // check if below call properly overwrites formats count
631 VK_CHECK(instHelper.vki.getPhysicalDeviceSurfaceFormatsKHR(physicalDevices[deviceNdx], *surface, &numFormats, &formats[0]));
633 if (numFormats != numFormatsOrig)
634 results.fail("Format count changed between calls");
639 log << TestLog::Message << "Device " << deviceNdx << ": " << tcu::formatArray(formats.begin(), formats.end()) << TestLog::EndMessage;
641 validateSurfaceFormats(results, wsiType, formats);
642 CheckPhysicalDeviceSurfaceFormatsIncompleteResult()(results, instHelper.vki, physicalDevices[deviceNdx], *surface, formats.size());
644 // else skip query as surface is not supported by the device
647 return tcu::TestStatus(results.getResult(), results.getMessage());
650 tcu::TestStatus querySurfaceFormats2Test (Context& context, Type wsiType)
652 tcu::TestLog& log = context.getTestContext().getLog();
653 tcu::ResultCollector results (log);
655 const InstanceHelper instHelper (context, wsiType, vector<string>(1, string("VK_KHR_get_surface_capabilities2")));
656 const NativeObjects native (context, instHelper.supportedExtensions, wsiType);
657 const Unique<VkSurfaceKHR> surface (createSurface(instHelper.vki, *instHelper.instance, wsiType, *native.display, *native.window));
658 const vector<VkPhysicalDevice> physicalDevices = enumeratePhysicalDevices(instHelper.vki, *instHelper.instance);
660 for (size_t deviceNdx = 0; deviceNdx < physicalDevices.size(); ++deviceNdx)
662 if (isSupportedByAnyQueue(instHelper.vki, physicalDevices[deviceNdx], *surface))
664 const vector<VkSurfaceFormatKHR> refFormats = getPhysicalDeviceSurfaceFormats(instHelper.vki,
665 physicalDevices[deviceNdx],
667 const VkPhysicalDeviceSurfaceInfo2KHR surfaceInfo =
669 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SURFACE_INFO_2_KHR,
673 deUint32 numFormats = 0;
675 VK_CHECK(instHelper.vki.getPhysicalDeviceSurfaceFormats2KHR(physicalDevices[deviceNdx], &surfaceInfo, &numFormats, DE_NULL));
677 if ((size_t)numFormats != refFormats.size())
678 results.fail("vkGetPhysicalDeviceSurfaceFormats2KHR() returned different number of formats");
682 vector<VkSurfaceFormat2KHR> formats (numFormats + 1);
684 for (size_t ndx = 0; ndx < formats.size(); ++ndx)
686 formats[ndx].sType = VK_STRUCTURE_TYPE_SURFACE_FORMAT_2_KHR;
687 formats[ndx].pNext = DE_NULL;
690 const deUint32 numFormatsOrig = numFormats;
692 // check if below call properly overwrites formats count
695 VK_CHECK(instHelper.vki.getPhysicalDeviceSurfaceFormats2KHR(physicalDevices[deviceNdx], &surfaceInfo, &numFormats, &formats[0]));
697 if ((size_t)numFormats != numFormatsOrig)
698 results.fail("Format count changed between calls");
703 vector<VkSurfaceFormatKHR> extFormats (formats.size());
705 for (size_t ndx = 0; ndx < formats.size(); ++ndx)
707 results.check(formats[ndx].sType == VK_STRUCTURE_TYPE_SURFACE_FORMAT_2_KHR &&
708 formats[ndx].pNext == DE_NULL,
709 "sType/pNext modified");
710 extFormats[ndx] = formats[ndx].surfaceFormat;
713 for (size_t ndx = 0; ndx < refFormats.size(); ++ndx)
715 if (!de::contains(extFormats.begin(), extFormats.end(), refFormats[ndx]))
716 results.fail(de::toString(refFormats[ndx]) + " missing from extended query");
720 // Check VK_INCOMPLETE
722 vector<VkSurfaceFormat2KHR> formatsClone (formats);
723 deUint32 numToSupply = numFormats/2;
724 VkResult queryResult;
726 ValidateQueryBits::fillBits(formatsClone.begin() + numToSupply, formatsClone.end());
728 queryResult = instHelper.vki.getPhysicalDeviceSurfaceFormats2KHR(physicalDevices[deviceNdx], &surfaceInfo, &numToSupply, &formatsClone[0]);
730 results.check(queryResult == VK_INCOMPLETE, "Expected VK_INCOMPLETE");
731 results.check(ValidateQueryBits::checkBits(formatsClone.begin() + numToSupply, formatsClone.end()),
732 "Driver wrote past last element");
734 for (size_t ndx = 0; ndx < (size_t)numToSupply; ++ndx)
736 results.check(formatsClone[ndx].sType == VK_STRUCTURE_TYPE_SURFACE_FORMAT_2_KHR &&
737 formatsClone[ndx].pNext == DE_NULL &&
738 formatsClone[ndx].surfaceFormat == formats[ndx].surfaceFormat,
739 "Returned element " + de::toString(ndx) + " is different");
744 // else skip query as surface is not supported by the device
747 return tcu::TestStatus(results.getResult(), results.getMessage());
750 void validateSurfacePresentModes (tcu::ResultCollector& results, Type wsiType, const vector<VkPresentModeKHR>& modes)
752 results.check(de::contains(modes.begin(), modes.end(), VK_PRESENT_MODE_FIFO_KHR),
753 "VK_PRESENT_MODE_FIFO_KHR is not supported");
755 if (wsiType == TYPE_ANDROID)
756 results.check(de::contains(modes.begin(), modes.end(), VK_PRESENT_MODE_MAILBOX_KHR),
757 "VK_PRESENT_MODE_MAILBOX_KHR is not supported");
760 tcu::TestStatus querySurfacePresentModesTest (Context& context, Type wsiType)
762 tcu::TestLog& log = context.getTestContext().getLog();
763 tcu::ResultCollector results (log);
765 const InstanceHelper instHelper (context, wsiType);
766 const NativeObjects native (context, instHelper.supportedExtensions, wsiType);
767 const Unique<VkSurfaceKHR> surface (createSurface(instHelper.vki, *instHelper.instance, wsiType, *native.display, *native.window));
768 const vector<VkPhysicalDevice> physicalDevices = enumeratePhysicalDevices(instHelper.vki, *instHelper.instance);
770 for (size_t deviceNdx = 0; deviceNdx < physicalDevices.size(); ++deviceNdx)
772 if (isSupportedByAnyQueue(instHelper.vki, physicalDevices[deviceNdx], *surface))
774 deUint32 numModes = 0;
776 VK_CHECK(instHelper.vki.getPhysicalDeviceSurfacePresentModesKHR(physicalDevices[deviceNdx], *surface, &numModes, DE_NULL));
778 vector<VkPresentModeKHR> modes (numModes + 1);
782 const deUint32 numModesOrig = numModes;
784 // check if below call properly overwrites mode count
787 VK_CHECK(instHelper.vki.getPhysicalDeviceSurfacePresentModesKHR(physicalDevices[deviceNdx], *surface, &numModes, &modes[0]));
789 if ((size_t)numModes != numModesOrig)
790 TCU_FAIL("Mode count changed between calls");
795 log << TestLog::Message << "Device " << deviceNdx << ": " << tcu::formatArray(modes.begin(), modes.end()) << TestLog::EndMessage;
797 validateSurfacePresentModes(results, wsiType, modes);
798 CheckPhysicalDeviceSurfacePresentModesIncompleteResult()(results, instHelper.vki, physicalDevices[deviceNdx], *surface, modes.size());
800 // else skip query as surface is not supported by the device
803 return tcu::TestStatus(results.getResult(), results.getMessage());
806 tcu::TestStatus queryDevGroupSurfacePresentCapabilitiesTest (Context& context, Type wsiType)
808 tcu::TestLog& log = context.getTestContext().getLog();
809 const InstanceHelper instHelper (context, wsiType, vector<string>(1, string("VK_KHR_device_group_creation")));
810 const float queuePriority = 1.0f;
811 const tcu::CommandLine& cmdLine = context.getTestContext().getCommandLine();
812 const deUint32 devGroupIdx = cmdLine.getVKDeviceGroupId() - 1;
813 const deUint32 deviceIdx = context.getTestContext().getCommandLine().getVKDeviceId() - 1u;
814 const VkDeviceGroupPresentModeFlagsKHR requiredFlag = VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_BIT_KHR;
815 const VkDeviceGroupPresentModeFlagsKHR maxValidFlag = VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_BIT_KHR|VK_DEVICE_GROUP_PRESENT_MODE_REMOTE_BIT_KHR |
816 VK_DEVICE_GROUP_PRESENT_MODE_SUM_BIT_KHR|VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_MULTI_DEVICE_BIT_KHR;
817 deUint8 buffer [sizeof(VkDeviceGroupPresentCapabilitiesKHR) + GUARD_SIZE];
818 deUint32 queueFamilyIndex = 0;
819 VkDeviceGroupPresentCapabilitiesKHR* presentCapabilities;
820 VkPhysicalDevice physicalDevice = chooseDevice(instHelper.vki, *instHelper.instance, cmdLine);
821 const Extensions& supportedExtensions = enumerateDeviceExtensionProperties(instHelper.vki, physicalDevice, DE_NULL);
822 std::vector<const char*> deviceExtensions;
824 if (!isCoreDeviceExtension(context.getUsedApiVersion(), "VK_KHR_device_group"))
825 deviceExtensions.push_back("VK_KHR_device_group");
826 deviceExtensions.push_back("VK_KHR_swapchain");
828 for (int ndx = 0; ndx < int(deviceExtensions.size()); ++ndx)
830 if (!isExtensionSupported(supportedExtensions, RequiredExtension(deviceExtensions[ndx])))
831 TCU_THROW(NotSupportedError, (string(deviceExtensions[ndx]) + " is not supported").c_str());
834 const vector<VkPhysicalDeviceGroupProperties> deviceGroupProps = enumeratePhysicalDeviceGroups(instHelper.vki, *instHelper.instance);
836 const std::vector<VkQueueFamilyProperties> queueProps = getPhysicalDeviceQueueFamilyProperties(instHelper.vki, deviceGroupProps[devGroupIdx].physicalDevices[deviceIdx]);
837 for (size_t queueNdx = 0; queueNdx < queueProps.size(); queueNdx++)
839 if (queueProps[queueNdx].queueFlags & VK_QUEUE_GRAPHICS_BIT)
840 queueFamilyIndex = (deUint32)queueNdx;
842 const VkDeviceQueueCreateInfo deviceQueueCreateInfo =
844 VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, //type
846 (VkDeviceQueueCreateFlags)0u, //flags
847 queueFamilyIndex, //queueFamilyIndex;
849 &queuePriority, //pQueuePriorities;
851 const VkDeviceGroupDeviceCreateInfo deviceGroupInfo =
853 VK_STRUCTURE_TYPE_DEVICE_GROUP_DEVICE_CREATE_INFO_KHR, //stype
855 deviceGroupProps[devGroupIdx].physicalDeviceCount, //physicalDeviceCount
856 deviceGroupProps[devGroupIdx].physicalDevices //physicalDevices
858 const VkDeviceCreateInfo deviceCreateInfo =
860 VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, //sType;
861 &deviceGroupInfo, //pNext;
862 (VkDeviceCreateFlags)0u, //flags
863 1, //queueRecordCount;
864 &deviceQueueCreateInfo, //pRequestedQueues;
866 DE_NULL, //ppEnabledLayerNames;
867 deUint32(deviceExtensions.size()), //enabledExtensionCount;
868 (deviceExtensions.empty() ? DE_NULL : &deviceExtensions[0]), //ppEnabledExtensionNames;
869 DE_NULL, //pEnabledFeatures;
871 Move<VkDevice> deviceGroup = createDevice(context.getPlatformInterface(), *instHelper.instance, instHelper.vki, deviceGroupProps[devGroupIdx].physicalDevices[deviceIdx], &deviceCreateInfo);
872 const DeviceDriver vk (context.getPlatformInterface(), *instHelper.instance, *deviceGroup);
875 presentCapabilities = reinterpret_cast<VkDeviceGroupPresentCapabilitiesKHR*>(buffer);
876 deMemset(buffer, GUARD_VALUE, sizeof(buffer));
877 presentCapabilities->sType = VK_STRUCTURE_TYPE_DEVICE_GROUP_PRESENT_CAPABILITIES_KHR;
878 presentCapabilities->pNext = DE_NULL;
879 VK_CHECK(vk.getDeviceGroupPresentCapabilitiesKHR(deviceGroup.get(), presentCapabilities));
882 for (deInt32 ndx = 0; ndx < GUARD_SIZE; ndx++)
884 if (buffer[ndx + sizeof(VkDeviceGroupPresentCapabilitiesKHR)] != GUARD_VALUE)
886 log << TestLog::Message << "deviceGroupPresentCapabilities - Guard offset " << ndx << " not valid" << TestLog::EndMessage;
887 return tcu::TestStatus::fail("deviceGroupPresentCapabilities buffer overflow");
891 // Check each physical device can present on itself
892 for (size_t physDevIdx = 0; physDevIdx < VK_MAX_DEVICE_GROUP_SIZE_KHR; physDevIdx++)
894 if (presentCapabilities->presentMask[physDevIdx])
895 if (!((1 << physDevIdx) & (presentCapabilities->presentMask[physDevIdx])))
896 return tcu::TestStatus::fail("deviceGroupPresentCapabilities, device can not present on itself, invalid present mask");
899 // Check if flags are valid
900 if ((!(presentCapabilities->modes & requiredFlag)) ||
901 presentCapabilities->modes > maxValidFlag)
902 return tcu::TestStatus::fail("deviceGroupPresentCapabilities flag not valid");
904 return tcu::TestStatus::pass("Querying deviceGroup present capabilities succeeded");
907 tcu::TestStatus queryDevGroupSurfacePresentModesTest (Context& context, Type wsiType)
909 tcu::TestLog& log = context.getTestContext().getLog();
910 tcu::ResultCollector results (log);
911 const InstanceHelper instHelper (context, wsiType, vector<string>(1, string("VK_KHR_device_group_creation")));
912 const NativeObjects native (context, instHelper.supportedExtensions, wsiType);
913 const Unique<VkSurfaceKHR> surface (createSurface(instHelper.vki, *instHelper.instance, wsiType, *native.display, *native.window));
914 const float queuePriority = 1.0f;
915 const tcu::CommandLine& cmdLine = context.getTestContext().getCommandLine();
916 const deUint32 devGroupIdx = cmdLine.getVKDeviceGroupId() - 1;
917 const deUint32 deviceIdx = context.getTestContext().getCommandLine().getVKDeviceId() - 1u;
918 const VkDeviceGroupPresentModeFlagsKHR requiredFlag = VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_BIT_KHR;
919 const VkDeviceGroupPresentModeFlagsKHR maxValidFlag = VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_BIT_KHR|VK_DEVICE_GROUP_PRESENT_MODE_REMOTE_BIT_KHR |
920 VK_DEVICE_GROUP_PRESENT_MODE_SUM_BIT_KHR|VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_MULTI_DEVICE_BIT_KHR;
921 VkResult result = VK_SUCCESS;
922 deUint8 buffer [sizeof(VkDeviceGroupPresentModeFlagsKHR) + GUARD_SIZE];
923 deUint32 rectCount = 0;
924 deUint32 incompleteRectCount = 0;
925 deUint32 queueFamilyIndex = 0;
926 VkRect2D* presentRectangles;
927 VkDeviceGroupPresentModeFlagsKHR* presentModeFlags;
928 vector<deUint8> rectanglesBuffer;
929 VkPhysicalDevice physicalDevice = chooseDevice(instHelper.vki, *instHelper.instance, cmdLine);
930 const Extensions& supportedExtensions = enumerateDeviceExtensionProperties(instHelper.vki, physicalDevice, DE_NULL);
931 std::vector<const char*> deviceExtensions;
933 if (!isCoreDeviceExtension(context.getUsedApiVersion(), "VK_KHR_device_group"))
934 deviceExtensions.push_back("VK_KHR_device_group");
935 deviceExtensions.push_back("VK_KHR_swapchain");
937 for (int ndx = 0; ndx < int(deviceExtensions.size()); ++ndx)
939 if (!isExtensionSupported(supportedExtensions, RequiredExtension(deviceExtensions[ndx])))
940 TCU_THROW(NotSupportedError, (string(deviceExtensions[ndx]) + " is not supported").c_str());
943 const vector<VkPhysicalDeviceGroupProperties> deviceGroupProps = enumeratePhysicalDeviceGroups(instHelper.vki, *instHelper.instance);
944 const std::vector<VkQueueFamilyProperties> queueProps = getPhysicalDeviceQueueFamilyProperties(instHelper.vki, deviceGroupProps[devGroupIdx].physicalDevices[deviceIdx]);
945 for (size_t queueNdx = 0; queueNdx < queueProps.size(); queueNdx++)
947 if (queueProps[queueNdx].queueFlags & VK_QUEUE_GRAPHICS_BIT)
948 queueFamilyIndex = (deUint32)queueNdx;
950 const VkDeviceQueueCreateInfo deviceQueueCreateInfo =
952 VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, //type
954 (VkDeviceQueueCreateFlags)0u, //flags
955 queueFamilyIndex, //queueFamilyIndex;
957 &queuePriority, //pQueuePriorities;
959 const VkDeviceGroupDeviceCreateInfo deviceGroupInfo =
961 VK_STRUCTURE_TYPE_DEVICE_GROUP_DEVICE_CREATE_INFO_KHR, //stype
963 deviceGroupProps[devGroupIdx].physicalDeviceCount, //physicalDeviceCount
964 deviceGroupProps[devGroupIdx].physicalDevices //physicalDevices
966 const VkDeviceCreateInfo deviceCreateInfo =
968 VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, //sType;
969 &deviceGroupInfo, //pNext;
970 (VkDeviceCreateFlags)0u, //flags
971 1, //queueRecordCount;
972 &deviceQueueCreateInfo, //pRequestedQueues;
974 DE_NULL, //ppEnabledLayerNames;
975 deUint32(deviceExtensions.size()), //enabledExtensionCount;
976 (deviceExtensions.empty() ? DE_NULL : &deviceExtensions[0]), //ppEnabledExtensionNames;
977 DE_NULL, //pEnabledFeatures;
980 Move<VkDevice> deviceGroup = createDevice(context.getPlatformInterface(), *instHelper.instance, instHelper.vki, deviceGroupProps[devGroupIdx].physicalDevices[deviceIdx], &deviceCreateInfo);
981 const DeviceDriver vk (context.getPlatformInterface(), *instHelper.instance, *deviceGroup);
982 presentModeFlags = reinterpret_cast<VkDeviceGroupPresentModeFlagsKHR*>(buffer);
983 deMemset(buffer, GUARD_VALUE, sizeof(buffer));
985 VK_CHECK(vk.getDeviceGroupSurfacePresentModesKHR(deviceGroup.get(), *surface, presentModeFlags));
988 for (deInt32 ndx = 0; ndx < GUARD_SIZE; ndx++)
990 if (buffer[ndx + sizeof(VkDeviceGroupPresentModeFlagsKHR)] != GUARD_VALUE)
992 log << TestLog::Message << "queryDevGroupSurfacePresentModesTest - Guard offset " << ndx << " not valid" << TestLog::EndMessage;
993 return tcu::TestStatus::fail("queryDevGroupSurfacePresentModesTest buffer overflow");
997 // Check if flags are valid
998 if ((!(*presentModeFlags & requiredFlag)) ||
999 *presentModeFlags > maxValidFlag)
1000 return tcu::TestStatus::fail("queryDevGroupSurfacePresentModesTest flag not valid");
1002 // Check presentation rectangles
1003 if (*presentModeFlags == VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_MULTI_DEVICE_BIT_KHR)
1005 for (size_t physDevIdx = 0; physDevIdx < deviceGroupProps[devGroupIdx].physicalDeviceCount; physDevIdx++)
1007 VK_CHECK(instHelper.vki.getPhysicalDevicePresentRectanglesKHR(deviceGroupProps[devGroupIdx].physicalDevices[physDevIdx], *surface, &rectCount, DE_NULL));
1008 rectanglesBuffer.resize(sizeof(VkRect2D) * rectCount + GUARD_SIZE);
1009 presentRectangles = reinterpret_cast<VkRect2D*>(rectanglesBuffer.data());
1010 deMemset(rectanglesBuffer.data(), GUARD_VALUE, rectanglesBuffer.size());
1012 VK_CHECK(instHelper.vki.getPhysicalDevicePresentRectanglesKHR(deviceGroupProps[devGroupIdx].physicalDevices[physDevIdx], *surface, &rectCount, presentRectangles));
1015 for (deInt32 ndx = 0; ndx < GUARD_SIZE; ndx++)
1017 if (rectanglesBuffer[ndx + sizeof(VkRect2D) * rectCount] != GUARD_VALUE)
1019 log << TestLog::Message << "getPhysicalDevicePresentRectanglesKHR - Guard offset " << ndx << " not valid" << TestLog::EndMessage;
1020 return tcu::TestStatus::fail("getPhysicalDevicePresentRectanglesKHR buffer overflow");
1024 // Check rectangles do not overlap
1025 for (size_t rectIdx1 = 0; rectIdx1 < rectCount; rectIdx1++)
1027 for (size_t rectIdx2 = 0; rectIdx2 < rectCount; rectIdx2++)
1029 if (rectIdx1 != rectIdx2)
1031 deUint32 rectATop = presentRectangles[rectIdx1].offset.y;
1032 deUint32 rectALeft = presentRectangles[rectIdx1].offset.x;
1033 deUint32 rectABottom = presentRectangles[rectIdx1].offset.y + presentRectangles[rectIdx1].extent.height;
1034 deUint32 rectARight = presentRectangles[rectIdx1].offset.x + presentRectangles[rectIdx1].extent.width;
1036 deUint32 rectBTop = presentRectangles[rectIdx2].offset.y;
1037 deUint32 rectBLeft = presentRectangles[rectIdx2].offset.x;
1038 deUint32 rectBBottom = presentRectangles[rectIdx2].offset.y + presentRectangles[rectIdx2].extent.height;
1039 deUint32 rectBRight = presentRectangles[rectIdx2].offset.x + presentRectangles[rectIdx2].extent.width;
1041 if (rectALeft < rectBRight && rectARight > rectBLeft &&
1042 rectATop < rectBBottom && rectABottom > rectBTop)
1043 return tcu::TestStatus::fail("getPhysicalDevicePresentRectanglesKHR rectangles overlap");
1049 incompleteRectCount = rectCount / 2;
1050 result = instHelper.vki.getPhysicalDevicePresentRectanglesKHR(deviceGroupProps[devGroupIdx].physicalDevices[physDevIdx], *surface, &incompleteRectCount, presentRectangles);
1051 results.check(result == VK_INCOMPLETE, "Expected VK_INCOMPLETE");
1054 return tcu::TestStatus(results.getResult(), results.getMessage());
1057 tcu::TestStatus createSurfaceInitialSizeTest (Context& context, Type wsiType)
1059 tcu::TestLog& log = context.getTestContext().getLog();
1060 tcu::ResultCollector results (log);
1062 const InstanceHelper instHelper (context, wsiType);
1064 const UniquePtr<Display> nativeDisplay (createDisplay(context.getTestContext().getPlatform().getVulkanPlatform(),
1065 instHelper.supportedExtensions,
1068 const vector<VkPhysicalDevice> physicalDevices = enumeratePhysicalDevices(instHelper.vki, *instHelper.instance);
1069 const UVec2 sizes[] =
1076 DE_ASSERT(getPlatformProperties(wsiType).features & PlatformProperties::FEATURE_INITIAL_WINDOW_SIZE);
1078 for (int sizeNdx = 0; sizeNdx < DE_LENGTH_OF_ARRAY(sizes); ++sizeNdx)
1080 const UVec2& testSize = sizes[sizeNdx];
1081 const UniquePtr<Window> nativeWindow (createWindow(*nativeDisplay, tcu::just(testSize)));
1082 const Unique<VkSurfaceKHR> surface (createSurface(instHelper.vki, *instHelper.instance, wsiType, *nativeDisplay, *nativeWindow));
1084 for (size_t deviceNdx = 0; deviceNdx < physicalDevices.size(); ++deviceNdx)
1086 if (isSupportedByAnyQueue(instHelper.vki, physicalDevices[deviceNdx], *surface))
1088 const VkSurfaceCapabilitiesKHR capabilities = getPhysicalDeviceSurfaceCapabilities(instHelper.vki, physicalDevices[deviceNdx], *surface);
1090 // \note Assumes that surface size is NOT set by swapchain if initial window size is honored by platform
1091 results.check(capabilities.currentExtent.width == testSize.x() &&
1092 capabilities.currentExtent.height == testSize.y(),
1093 "currentExtent " + de::toString(capabilities.currentExtent) + " doesn't match requested size " + de::toString(testSize));
1098 return tcu::TestStatus(results.getResult(), results.getMessage());
1101 tcu::TestStatus resizeSurfaceTest (Context& context, Type wsiType)
1103 tcu::TestLog& log = context.getTestContext().getLog();
1104 tcu::ResultCollector results (log);
1106 const InstanceHelper instHelper (context, wsiType);
1108 const UniquePtr<Display> nativeDisplay (createDisplay(context.getTestContext().getPlatform().getVulkanPlatform(),
1109 instHelper.supportedExtensions,
1111 UniquePtr<Window> nativeWindow (createWindow(*nativeDisplay, tcu::nothing<UVec2>()));
1113 const vector<VkPhysicalDevice> physicalDevices = enumeratePhysicalDevices(instHelper.vki, *instHelper.instance);
1114 const Unique<VkSurfaceKHR> surface (createSurface(instHelper.vki, *instHelper.instance, wsiType, *nativeDisplay, *nativeWindow));
1116 const UVec2 sizes[] =
1123 DE_ASSERT(getPlatformProperties(wsiType).features & PlatformProperties::FEATURE_RESIZE_WINDOW);
1125 for (int sizeNdx = 0; sizeNdx < DE_LENGTH_OF_ARRAY(sizes); ++sizeNdx)
1127 const UVec2 testSize = sizes[sizeNdx];
1131 nativeWindow->resize(testSize);
1133 catch (const tcu::Exception& e)
1135 // Make sure all exception types result in a test failure
1136 results.fail(e.getMessage());
1139 for (size_t deviceNdx = 0; deviceNdx < physicalDevices.size(); ++deviceNdx)
1141 if (isSupportedByAnyQueue(instHelper.vki, physicalDevices[deviceNdx], *surface))
1143 const VkSurfaceCapabilitiesKHR capabilities = getPhysicalDeviceSurfaceCapabilities(instHelper.vki, physicalDevices[deviceNdx], *surface);
1145 // \note Assumes that surface size is NOT set by swapchain if initial window size is honored by platform
1146 results.check(capabilities.currentExtent.width == testSize.x() &&
1147 capabilities.currentExtent.height == testSize.y(),
1148 "currentExtent " + de::toString(capabilities.currentExtent) + " doesn't match requested size " + de::toString(testSize));
1153 return tcu::TestStatus(results.getResult(), results.getMessage());
1156 tcu::TestStatus destroyNullHandleSurfaceTest (Context& context, Type wsiType)
1158 const InstanceHelper instHelper (context, wsiType);
1159 const VkSurfaceKHR nullHandle = DE_NULL;
1161 // Default allocator
1162 instHelper.vki.destroySurfaceKHR(*instHelper.instance, nullHandle, DE_NULL);
1166 AllocationCallbackRecorder recordingAllocator (getSystemAllocator(), 1u);
1168 instHelper.vki.destroySurfaceKHR(*instHelper.instance, nullHandle, recordingAllocator.getCallbacks());
1170 if (recordingAllocator.getNumRecords() != 0u)
1171 return tcu::TestStatus::fail("Implementation allocated/freed the memory");
1174 return tcu::TestStatus::pass("Destroying a VK_NULL_HANDLE surface has no effect");
1179 void createSurfaceTests (tcu::TestCaseGroup* testGroup, vk::wsi::Type wsiType)
1181 const PlatformProperties& platformProperties = getPlatformProperties(wsiType);
1183 addFunctionCase(testGroup, "create", "Create surface", createSurfaceTest, wsiType);
1184 addFunctionCase(testGroup, "create_custom_allocator", "Create surface with custom allocator", createSurfaceCustomAllocatorTest, wsiType);
1185 addFunctionCase(testGroup, "create_simulate_oom", "Create surface with simulating OOM", createSurfaceSimulateOOMTest, wsiType);
1186 addFunctionCase(testGroup, "query_support", "Query surface support", querySurfaceSupportTest, wsiType);
1187 addFunctionCase(testGroup, "query_capabilities", "Query surface capabilities", querySurfaceCapabilitiesTest, wsiType);
1188 addFunctionCase(testGroup, "query_capabilities2", "Query extended surface capabilities", querySurfaceCapabilities2Test, wsiType);
1189 addFunctionCase(testGroup, "query_formats", "Query surface formats", querySurfaceFormatsTest, wsiType);
1190 addFunctionCase(testGroup, "query_formats2", "Query extended surface formats", querySurfaceFormats2Test, wsiType);
1191 addFunctionCase(testGroup, "query_present_modes", "Query surface present modes", querySurfacePresentModesTest, wsiType);
1192 addFunctionCase(testGroup, "query_devgroup_present_capabilities", "Query surface present modes capabilities in device groups",queryDevGroupSurfacePresentCapabilitiesTest,wsiType);
1193 addFunctionCase(testGroup, "query_devgroup_present_modes", "Query surface present modes for device groups", queryDevGroupSurfacePresentModesTest, wsiType);
1194 addFunctionCase(testGroup, "destroy_null_handle", "Destroy VK_NULL_HANDLE surface", destroyNullHandleSurfaceTest, wsiType);
1196 if ((platformProperties.features & PlatformProperties::FEATURE_INITIAL_WINDOW_SIZE) != 0)
1197 addFunctionCase(testGroup, "initial_size", "Create surface with initial window size set", createSurfaceInitialSizeTest, wsiType);
1199 if ((platformProperties.features & PlatformProperties::FEATURE_RESIZE_WINDOW) != 0)
1200 addFunctionCase(testGroup, "resize", "Resize window and surface", resizeSurfaceTest, wsiType);