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"
28 #include "vktCustomInstancesDevices.hpp"
29 #include "vktNativeObjectsUtil.hpp"
32 #include "vkPlatform.hpp"
33 #include "vkStrUtil.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"
46 #include "tcuTestLog.hpp"
47 #include "tcuFormatUtil.hpp"
48 #include "tcuPlatform.hpp"
49 #include "tcuResultCollector.hpp"
50 #include "tcuCommandLine.hpp"
52 #include "deUniquePtr.hpp"
53 #include "deStringUtil.hpp"
59 inline bool operator!= (const VkSurfaceFormatKHR& a, const VkSurfaceFormatKHR& b)
61 return (a.format != b.format) || (a.colorSpace != b.colorSpace);
64 inline bool operator== (const VkSurfaceFormatKHR& a, const VkSurfaceFormatKHR& b)
69 inline bool operator!= (const VkExtent2D& a, const VkExtent2D& b)
71 return (a.width != b.width) || (a.height != b.height);
74 inline bool operator!= (const VkSurfaceCapabilitiesKHR& a, const VkSurfaceCapabilitiesKHR& b)
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);
99 using namespace vk::wsi;
113 SURFACE_EXTENT_DETERMINED_BY_SWAPCHAIN_MAGIC = 0xffffffff
118 GUARD_SIZE = 0x20, //!< Number of bytes to check
119 GUARD_VALUE = 0xcd, //!< Data pattern
123 class CheckIncompleteResult
126 virtual ~CheckIncompleteResult (void) {}
127 virtual void getResult (const InstanceInterface& vki, const VkPhysicalDevice physDevice, const VkSurfaceKHR surface, T* data) = 0;
129 void operator() (tcu::ResultCollector& results,
130 const InstanceInterface& vki,
131 const VkPhysicalDevice physDevice,
132 const VkSurfaceKHR surface,
133 const std::size_t expectedCompleteSize)
135 if (expectedCompleteSize == 0)
138 vector<T> outputData (expectedCompleteSize);
139 const deUint32 usedSize = static_cast<deUint32>(expectedCompleteSize / 3);
141 ValidateQueryBits::fillBits(outputData.begin(), outputData.end()); // unused entries should have this pattern intact
143 m_result = VK_SUCCESS;
145 getResult(vki, physDevice, surface, &outputData[0]); // update m_count and m_result
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");
156 struct CheckPhysicalDeviceSurfaceFormatsIncompleteResult : public CheckIncompleteResult<VkSurfaceFormatKHR>
158 void getResult (const InstanceInterface& vki, const VkPhysicalDevice physDevice, const VkSurfaceKHR surface, VkSurfaceFormatKHR* data)
160 m_result = vki.getPhysicalDeviceSurfaceFormatsKHR(physDevice, surface, &m_count, data);
164 struct CheckPhysicalDeviceSurfacePresentModesIncompleteResult : public CheckIncompleteResult<VkPresentModeKHR>
166 void getResult (const InstanceInterface& vki, const VkPhysicalDevice physDevice, const VkSurfaceKHR surface, VkPresentModeKHR* data)
168 m_result = vki.getPhysicalDeviceSurfacePresentModesKHR(physDevice, surface, &m_count, data);
172 typedef vector<VkExtensionProperties> Extensions;
174 CustomInstance createInstanceWithWsi (Context& context,
176 const vector<string> extraExtensions,
177 const VkAllocationCallbacks* pAllocator = DE_NULL)
179 const deUint32 version = context.getUsedApiVersion();
180 vector<string> extensions = extraExtensions;
182 extensions.push_back("VK_KHR_surface");
183 extensions.push_back(getExtensionName(wsiType));
185 vector<string> instanceExtensions;
186 for (const auto& ext : extensions)
188 if (!context.isInstanceFunctionalitySupported(ext))
189 TCU_THROW(NotSupportedError, (ext + " is not supported").c_str());
191 if (!isCoreInstanceExtension(version, ext))
192 instanceExtensions.push_back(ext);
195 return vkt::createCustomInstanceWithExtensions(context, instanceExtensions, pAllocator);
198 struct InstanceHelper
200 const vector<VkExtensionProperties> supportedExtensions;
201 CustomInstance instance;
202 const InstanceDriver& vki;
204 InstanceHelper (Context& context, Type wsiType, const VkAllocationCallbacks* pAllocator = DE_NULL)
205 : supportedExtensions (enumerateInstanceExtensionProperties(context.getPlatformInterface(),
207 , instance (createInstanceWithWsi(context,
211 , vki (instance.getDriver())
214 InstanceHelper (Context& context, Type wsiType, const vector<string>& extensions, const VkAllocationCallbacks* pAllocator = DE_NULL)
215 : supportedExtensions (enumerateInstanceExtensionProperties(context.getPlatformInterface(),
217 , instance (createInstanceWithWsi(context,
221 , vki (instance.getDriver())
225 tcu::TestStatus createSurfaceTest (Context& context, Type wsiType)
227 const InstanceHelper instHelper (context, wsiType);
228 const NativeObjects native (context, instHelper.supportedExtensions, wsiType);
229 const Unique<VkSurfaceKHR> surface (createSurface(instHelper.vki, instHelper.instance, wsiType, native.getDisplay(), native.getWindow()));
231 return tcu::TestStatus::pass("Creating surface succeeded");
234 tcu::TestStatus querySurfaceCounterTest (Context& context, Type wsiType)
236 const InstanceHelper instHelper (context, wsiType);
237 const NativeObjects native (context, instHelper.supportedExtensions, wsiType);
238 const Unique<VkSurfaceKHR> surface (createSurface(instHelper.vki, instHelper.instance, wsiType, native.getDisplay(), native.getWindow()));
239 const vk::InstanceInterface& vki = context.getInstanceInterface();
240 const vk::VkPhysicalDevice physicalDevice = context.getPhysicalDevice();
242 if (!isInstanceExtensionSupported(context.getUsedApiVersion(), context.getInstanceExtensions(), "VK_EXT_display_surface_counter"))
243 TCU_THROW(NotSupportedError, "VK_EXT_display_surface_counter not supported");
245 const vk::VkSurfaceCapabilities2EXT capsExt = getPhysicalDeviceSurfaceCapabilities2EXT (vki, physicalDevice, surface.get());
246 const vk::VkSurfaceCapabilitiesKHR capsKhr = getPhysicalDeviceSurfaceCapabilities (vki, physicalDevice, surface.get());
248 if (!sameSurfaceCapabilities(capsKhr, capsExt))
250 return tcu::TestStatus::fail("KHR and EXT surface capabilities do not match");
253 if (capsExt.supportedSurfaceCounters != 0)
255 return tcu::TestStatus::fail("supportedSurfaceCounters nonzero (" + de::toString(capsExt.supportedSurfaceCounters) + ") for non-display surface");
258 return tcu::TestStatus::pass("Pass");
261 tcu::TestStatus createSurfaceCustomAllocatorTest (Context& context, Type wsiType)
263 AllocationCallbackRecorder allocationRecorder (getSystemAllocator());
264 tcu::TestLog& log = context.getTestContext().getLog();
267 const InstanceHelper instHelper (context, wsiType, allocationRecorder.getCallbacks());
268 const NativeObjects native (context, instHelper.supportedExtensions, wsiType);
269 const Unique<VkSurfaceKHR> surface (createSurface(instHelper.vki,
274 allocationRecorder.getCallbacks()));
276 if (!validateAndLog(log,
278 (1u<<VK_SYSTEM_ALLOCATION_SCOPE_OBJECT) |
279 (1u<<VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE)))
280 return tcu::TestStatus::fail("Detected invalid system allocation callback");
283 if (!validateAndLog(log, allocationRecorder, 0u))
284 return tcu::TestStatus::fail("Detected invalid system allocation callback");
286 if (allocationRecorder.getRecordsBegin() == allocationRecorder.getRecordsEnd())
287 return tcu::TestStatus(QP_TEST_RESULT_QUALITY_WARNING, "Allocation callbacks were not used");
289 return tcu::TestStatus::pass("Creating surface succeeded using custom allocator");
292 tcu::TestStatus createSurfaceSimulateOOMTest (Context& context, Type wsiType)
294 tcu::TestLog& log = context.getTestContext().getLog();
296 for (deUint32 numPassingAllocs = 0; numPassingAllocs <= 1024u; ++numPassingAllocs)
298 AllocationCallbackRecorder allocationRecorder (getSystemAllocator());
299 DeterministicFailAllocator failingAllocator (allocationRecorder.getCallbacks(),
300 DeterministicFailAllocator::MODE_DO_NOT_COUNT,
304 log << TestLog::Message << "Testing with " << numPassingAllocs << " first allocations succeeding" << TestLog::EndMessage;
308 const InstanceHelper instHelper (context, wsiType, failingAllocator.getCallbacks());
310 // OOM is not simulated for VkInstance as we don't want to spend time
311 // testing OOM paths inside instance creation.
312 failingAllocator.reset(DeterministicFailAllocator::MODE_COUNT_AND_FAIL, numPassingAllocs);
314 const NativeObjects native (context, instHelper.supportedExtensions, wsiType);
315 const Unique<VkSurfaceKHR> surface (createSurface(instHelper.vki,
320 failingAllocator.getCallbacks()));
322 if (!validateAndLog(log,
324 (1u<<VK_SYSTEM_ALLOCATION_SCOPE_OBJECT) |
325 (1u<<VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE)))
326 return tcu::TestStatus::fail("Detected invalid system allocation callback");
328 catch (const OutOfMemoryError& e)
330 log << TestLog::Message << "Got " << e.getError() << TestLog::EndMessage;
334 if (!validateAndLog(log, allocationRecorder, 0u))
335 return tcu::TestStatus::fail("Detected invalid system allocation callback");
339 log << TestLog::Message << "Creating surface succeeded!" << TestLog::EndMessage;
341 if (numPassingAllocs == 0)
342 return tcu::TestStatus(QP_TEST_RESULT_QUALITY_WARNING, "Allocation callbacks were not used");
344 return tcu::TestStatus::pass("OOM simulation completed");
348 return tcu::TestStatus(QP_TEST_RESULT_QUALITY_WARNING, "Creating surface did not succeed, callback limit exceeded");
351 deUint32 getNumQueueFamilies (const InstanceInterface& vki, VkPhysicalDevice physicalDevice)
353 deUint32 numFamilies = 0;
355 vki.getPhysicalDeviceQueueFamilyProperties(physicalDevice, &numFamilies, DE_NULL);
360 tcu::TestStatus querySurfaceSupportTest (Context& context, Type wsiType)
362 tcu::TestLog& log = context.getTestContext().getLog();
363 tcu::ResultCollector results (log);
365 const InstanceHelper instHelper (context, wsiType);
366 const NativeObjects native (context, instHelper.supportedExtensions, wsiType);
367 const Unique<VkSurfaceKHR> surface (createSurface(instHelper.vki, instHelper.instance, wsiType, native.getDisplay(), native.getWindow()));
368 const vector<VkPhysicalDevice> physicalDevices = enumeratePhysicalDevices(instHelper.vki, instHelper.instance);
370 // On Android surface must be supported by all devices and queue families
371 const bool expectSupportedOnAll = wsiType == TYPE_ANDROID;
373 for (size_t deviceNdx = 0; deviceNdx < physicalDevices.size(); ++deviceNdx)
375 const VkPhysicalDevice physicalDevice = physicalDevices[deviceNdx];
376 const deUint32 numQueueFamilies = getNumQueueFamilies(instHelper.vki, physicalDevice);
378 for (deUint32 queueFamilyNdx = 0; queueFamilyNdx < numQueueFamilies; ++queueFamilyNdx)
380 const VkBool32 isSupported = getPhysicalDeviceSurfaceSupport(instHelper.vki, physicalDevice, queueFamilyNdx, *surface);
382 log << TestLog::Message << "Device " << deviceNdx << ", queue family " << queueFamilyNdx << ": "
383 << (isSupported == VK_FALSE ? "NOT " : "") << "supported"
384 << TestLog::EndMessage;
386 if (expectSupportedOnAll && !isSupported)
387 results.fail("Surface must be supported by all devices and queue families");
391 return tcu::TestStatus(results.getResult(), results.getMessage());
394 tcu::TestStatus queryPresentationSupportTest(Context& context, Type wsiType)
396 tcu::TestLog& log = context.getTestContext().getLog();
397 tcu::ResultCollector results (log);
399 const InstanceHelper instHelper (context, wsiType);
400 const NativeObjects native (context, instHelper.supportedExtensions, wsiType);
401 const Unique<VkSurfaceKHR> surface (createSurface(instHelper.vki, instHelper.instance, wsiType, native.getDisplay(), native.getWindow()));
402 const vector<VkPhysicalDevice> physicalDevices = enumeratePhysicalDevices(instHelper.vki, instHelper.instance);
405 for (size_t deviceNdx = 0; deviceNdx < physicalDevices.size(); ++deviceNdx)
407 const VkPhysicalDevice physicalDevice = physicalDevices[deviceNdx];
408 const deUint32 numQueueFamilies = getNumQueueFamilies(instHelper.vki, physicalDevice);
410 for (deUint32 queueFamilyNdx = 0; queueFamilyNdx < numQueueFamilies; ++queueFamilyNdx)
412 VkBool32 isPresentationSupported = getPhysicalDevicePresentationSupport(instHelper.vki, physicalDevice, queueFamilyNdx, wsiType, native.getDisplay());
413 VkBool32 isSurfaceSupported = getPhysicalDeviceSurfaceSupport(instHelper.vki, physicalDevice, queueFamilyNdx, *surface);
415 log << TestLog::Message << "Device " << deviceNdx << ", queue family " << queueFamilyNdx << ": presentation "
416 << (isPresentationSupported == VK_FALSE ? "NOT " : "") << "supported. Surface "
417 << (isSurfaceSupported == VK_FALSE ? "NOT " : "") << "supported."
418 << TestLog::EndMessage;
420 if (isPresentationSupported != isSurfaceSupported)
421 results.fail("Presentation support is different from surface support");
425 return tcu::TestStatus(results.getResult(), results.getMessage());
428 bool isSupportedByAnyQueue (const InstanceInterface& vki, VkPhysicalDevice physicalDevice, VkSurfaceKHR surface)
430 const deUint32 numQueueFamilies = getNumQueueFamilies(vki, physicalDevice);
432 for (deUint32 queueFamilyNdx = 0; queueFamilyNdx < numQueueFamilies; ++queueFamilyNdx)
434 if (getPhysicalDeviceSurfaceSupport(vki, physicalDevice, queueFamilyNdx, surface) != VK_FALSE)
441 void validateSurfaceCapabilities (tcu::ResultCollector& results, const VkSurfaceCapabilitiesKHR& capabilities)
443 results.check(capabilities.minImageCount > 0,
444 "minImageCount must be larger than 0");
446 results.check(capabilities.minImageExtent.width > 0 &&
447 capabilities.minImageExtent.height > 0,
448 "minImageExtent dimensions must be larger than 0");
450 results.check(capabilities.maxImageExtent.width > 0 &&
451 capabilities.maxImageExtent.height > 0,
452 "maxImageExtent dimensions must be larger than 0");
454 results.check(capabilities.minImageExtent.width <= capabilities.maxImageExtent.width &&
455 capabilities.minImageExtent.height <= capabilities.maxImageExtent.height,
456 "maxImageExtent must be larger or equal to minImageExtent");
458 if (capabilities.currentExtent.width != SURFACE_EXTENT_DETERMINED_BY_SWAPCHAIN_MAGIC ||
459 capabilities.currentExtent.height != SURFACE_EXTENT_DETERMINED_BY_SWAPCHAIN_MAGIC)
461 results.check(capabilities.currentExtent.width > 0 &&
462 capabilities.currentExtent.height > 0,
463 "currentExtent dimensions must be larger than 0");
465 results.check(de::inRange(capabilities.currentExtent.width, capabilities.minImageExtent.width, capabilities.maxImageExtent.width) &&
466 de::inRange(capabilities.currentExtent.height, capabilities.minImageExtent.height, capabilities.maxImageExtent.height),
467 "currentExtent is not in supported extent limits");
470 results.check(capabilities.maxImageArrayLayers > 0,
471 "maxImageArrayLayers must be larger than 0");
473 results.check((capabilities.supportedUsageFlags & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) != 0,
474 "VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT must be set in supportedUsageFlags");
476 results.check(capabilities.supportedTransforms != 0,
477 "At least one transform must be supported");
479 results.check(dePop32(capabilities.currentTransform) != 0,
480 "Invalid currentTransform");
482 results.check((capabilities.supportedTransforms & capabilities.currentTransform) != 0,
483 "currentTransform is not supported by surface");
485 results.check(capabilities.supportedCompositeAlpha != 0,
486 "At least one alpha mode must be supported");
489 tcu::TestStatus querySurfaceCapabilitiesTest (Context& context, Type wsiType)
491 tcu::TestLog& log = context.getTestContext().getLog();
492 tcu::ResultCollector results (log);
494 const InstanceHelper instHelper (context, wsiType);
495 const NativeObjects native (context, instHelper.supportedExtensions, wsiType);
496 const Unique<VkSurfaceKHR> surface (createSurface(instHelper.vki, instHelper.instance, wsiType, native.getDisplay(), native.getWindow()));
497 const vector<VkPhysicalDevice> physicalDevices = enumeratePhysicalDevices(instHelper.vki, instHelper.instance);
499 for (size_t deviceNdx = 0; deviceNdx < physicalDevices.size(); ++deviceNdx)
501 if (isSupportedByAnyQueue(instHelper.vki, physicalDevices[deviceNdx], *surface))
503 const VkSurfaceCapabilitiesKHR capabilities = getPhysicalDeviceSurfaceCapabilities(instHelper.vki,
504 physicalDevices[deviceNdx],
507 log << TestLog::Message << "Device " << deviceNdx << ": " << capabilities << TestLog::EndMessage;
509 validateSurfaceCapabilities(results, capabilities);
511 // else skip query as surface is not supported by the device
514 return tcu::TestStatus(results.getResult(), results.getMessage());
517 tcu::TestStatus querySurfaceCapabilities2Test (Context& context, Type wsiType)
519 tcu::TestLog& log = context.getTestContext().getLog();
520 tcu::ResultCollector results (log);
522 const InstanceHelper instHelper (context, wsiType, vector<string>(1, string("VK_KHR_get_surface_capabilities2")));
523 const NativeObjects native (context, instHelper.supportedExtensions, wsiType);
524 const Unique<VkSurfaceKHR> surface (createSurface(instHelper.vki, instHelper.instance, wsiType, native.getDisplay(), native.getWindow()));
525 const vector<VkPhysicalDevice> physicalDevices = enumeratePhysicalDevices(instHelper.vki, instHelper.instance);
527 for (size_t deviceNdx = 0; deviceNdx < physicalDevices.size(); ++deviceNdx)
529 if (isSupportedByAnyQueue(instHelper.vki, physicalDevices[deviceNdx], *surface))
531 const VkSurfaceCapabilitiesKHR refCapabilities = getPhysicalDeviceSurfaceCapabilities(instHelper.vki,
532 physicalDevices[deviceNdx],
534 VkSurfaceCapabilities2KHR extCapabilities;
536 deMemset(&extCapabilities, 0xcd, sizeof(VkSurfaceCapabilities2KHR));
537 extCapabilities.sType = VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_KHR;
538 extCapabilities.pNext = DE_NULL;
541 const VkPhysicalDeviceSurfaceInfo2KHR surfaceInfo =
543 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SURFACE_INFO_2_KHR,
547 VkPhysicalDeviceSurfaceInfo2KHR infoCopy;
549 deMemcpy(&infoCopy, &surfaceInfo, sizeof(VkPhysicalDeviceSurfaceInfo2KHR));
551 VK_CHECK(instHelper.vki.getPhysicalDeviceSurfaceCapabilities2KHR(physicalDevices[deviceNdx], &surfaceInfo, &extCapabilities));
553 results.check(deMemoryEqual(&surfaceInfo, &infoCopy, sizeof(VkPhysicalDeviceSurfaceInfo2KHR)) == DE_TRUE, "Driver wrote into input struct");
556 results.check(extCapabilities.sType == VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_KHR &&
557 extCapabilities.pNext == DE_NULL,
558 "sType/pNext modified");
560 if (refCapabilities != extCapabilities.surfaceCapabilities)
562 log << TestLog::Message
563 << "Device " << deviceNdx
564 << ": expected " << refCapabilities
565 << ", got " << extCapabilities.surfaceCapabilities
566 << TestLog::EndMessage;
567 results.fail("Mismatch between VK_KHR_surface and VK_KHR_surface2 query results");
572 return tcu::TestStatus(results.getResult(), results.getMessage());
575 tcu::TestStatus querySurfaceProtectedCapabilitiesTest (Context& context, Type wsiType)
577 tcu::TestLog& log = context.getTestContext().getLog();
578 tcu::ResultCollector results (log);
580 vector<string> requiredExtensions;
581 requiredExtensions.push_back("VK_KHR_get_surface_capabilities2");
582 requiredExtensions.push_back("VK_KHR_surface_protected_capabilities");
583 const InstanceHelper instHelper (context, wsiType, requiredExtensions);
584 const NativeObjects native (context, instHelper.supportedExtensions, wsiType);
585 const Unique<VkSurfaceKHR> surface (createSurface(instHelper.vki, instHelper.instance, wsiType, native.getDisplay(), native.getWindow()));
586 const vector<VkPhysicalDevice> physicalDevices = enumeratePhysicalDevices(instHelper.vki, instHelper.instance);
588 for (size_t deviceNdx = 0; deviceNdx < physicalDevices.size(); ++deviceNdx)
590 if (isSupportedByAnyQueue(instHelper.vki, physicalDevices[deviceNdx], *surface))
592 VkSurfaceCapabilities2KHR extCapabilities;
593 VkSurfaceProtectedCapabilitiesKHR extProtectedCapabilities;
595 deMemset(&extProtectedCapabilities, 0xcd, sizeof(VkSurfaceProtectedCapabilitiesKHR));
596 extProtectedCapabilities.sType = VK_STRUCTURE_TYPE_SURFACE_PROTECTED_CAPABILITIES_KHR;
597 extProtectedCapabilities.pNext = DE_NULL;
599 deMemset(&extCapabilities, 0xcd, sizeof(VkSurfaceCapabilities2KHR));
600 extCapabilities.sType = VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_KHR;
601 extCapabilities.pNext = &extProtectedCapabilities;
604 VkPhysicalDeviceSurfaceInfo2KHR infoCopy;
605 const VkPhysicalDeviceSurfaceInfo2KHR surfaceInfo =
607 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SURFACE_INFO_2_KHR,
613 deMemcpy(&infoCopy, &surfaceInfo, sizeof(VkPhysicalDeviceSurfaceInfo2KHR));
615 VK_CHECK(instHelper.vki.getPhysicalDeviceSurfaceCapabilities2KHR(physicalDevices[deviceNdx], &surfaceInfo, &extCapabilities));
617 results.check(deMemoryEqual(&surfaceInfo, &infoCopy, sizeof(VkPhysicalDeviceSurfaceInfo2KHR)) == DE_TRUE, "Driver wrote into input struct");
620 results.check(extCapabilities.sType == VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_KHR &&
621 extCapabilities.pNext == &extProtectedCapabilities,
622 "sType/pNext modified");
624 results.check(extProtectedCapabilities.sType == VK_STRUCTURE_TYPE_SURFACE_PROTECTED_CAPABILITIES_KHR &&
625 extProtectedCapabilities.pNext == DE_NULL,
626 "sType/pNext modified");
628 results.check(extProtectedCapabilities.supportsProtected == 0 ||
629 extProtectedCapabilities.supportsProtected == 1,
630 "supportsProtected ");
634 return tcu::TestStatus(results.getResult(), results.getMessage());
637 void validateSurfaceFormats (tcu::ResultCollector& results, Type wsiType, const vector<VkSurfaceFormatKHR>& formats)
639 const VkSurfaceFormatKHR* requiredFormats = DE_NULL;
640 size_t numRequiredFormats = 0;
642 if (wsiType == TYPE_ANDROID)
644 static const VkSurfaceFormatKHR s_androidFormats[] =
646 { VK_FORMAT_R8G8B8A8_UNORM, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR },
647 { VK_FORMAT_R8G8B8A8_SRGB, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR },
648 { VK_FORMAT_R5G6B5_UNORM_PACK16, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR }
651 requiredFormats = &s_androidFormats[0];
652 numRequiredFormats = DE_LENGTH_OF_ARRAY(s_androidFormats);
655 for (size_t ndx = 0; ndx < numRequiredFormats; ++ndx)
657 const VkSurfaceFormatKHR& requiredFormat = requiredFormats[ndx];
659 if (!de::contains(formats.begin(), formats.end(), requiredFormat))
660 results.fail(de::toString(requiredFormat) + " not supported");
663 // Check that there are no duplicates
664 for (size_t ndx = 1; ndx < formats.size(); ++ndx)
666 if (de::contains(formats.begin(), formats.begin() + ndx, formats[ndx]))
667 results.fail("Found duplicate entry " + de::toString(formats[ndx]));
671 tcu::TestStatus querySurfaceFormatsTest (Context& context, Type wsiType)
673 tcu::TestLog& log = context.getTestContext().getLog();
674 tcu::ResultCollector results (log);
676 const InstanceHelper instHelper (context, wsiType);
677 const NativeObjects native (context, instHelper.supportedExtensions, wsiType);
678 const Unique<VkSurfaceKHR> surface (createSurface(instHelper.vki, instHelper.instance, wsiType, native.getDisplay(), native.getWindow()));
679 const vector<VkPhysicalDevice> physicalDevices = enumeratePhysicalDevices(instHelper.vki, instHelper.instance);
681 for (size_t deviceNdx = 0; deviceNdx < physicalDevices.size(); ++deviceNdx)
683 if (isSupportedByAnyQueue(instHelper.vki, physicalDevices[deviceNdx], *surface))
685 deUint32 numFormats = 0;
687 VK_CHECK(instHelper.vki.getPhysicalDeviceSurfaceFormatsKHR(physicalDevices[deviceNdx], *surface, &numFormats, DE_NULL));
689 std::vector<VkSurfaceFormatKHR> formats (numFormats + 1);
693 const deUint32 numFormatsOrig = numFormats;
695 // check if below call properly overwrites formats count
698 VK_CHECK(instHelper.vki.getPhysicalDeviceSurfaceFormatsKHR(physicalDevices[deviceNdx], *surface, &numFormats, &formats[0]));
700 if (numFormats != numFormatsOrig)
701 results.fail("Format count changed between calls");
706 log << TestLog::Message << "Device " << deviceNdx << ": " << tcu::formatArray(formats.begin(), formats.end()) << TestLog::EndMessage;
708 validateSurfaceFormats(results, wsiType, formats);
709 CheckPhysicalDeviceSurfaceFormatsIncompleteResult()(results, instHelper.vki, physicalDevices[deviceNdx], *surface, formats.size());
711 // else skip query as surface is not supported by the device
714 return tcu::TestStatus(results.getResult(), results.getMessage());
717 tcu::TestStatus querySurfaceFormats2Test (Context& context, Type wsiType)
719 tcu::TestLog& log = context.getTestContext().getLog();
720 tcu::ResultCollector results (log);
722 const InstanceHelper instHelper (context, wsiType, vector<string>(1, string("VK_KHR_get_surface_capabilities2")));
723 const NativeObjects native (context, instHelper.supportedExtensions, wsiType);
724 const Unique<VkSurfaceKHR> surface (createSurface(instHelper.vki, instHelper.instance, wsiType, native.getDisplay(), native.getWindow()));
725 const vector<VkPhysicalDevice> physicalDevices = enumeratePhysicalDevices(instHelper.vki, instHelper.instance);
727 for (size_t deviceNdx = 0; deviceNdx < physicalDevices.size(); ++deviceNdx)
729 if (isSupportedByAnyQueue(instHelper.vki, physicalDevices[deviceNdx], *surface))
731 const vector<VkSurfaceFormatKHR> refFormats = getPhysicalDeviceSurfaceFormats(instHelper.vki,
732 physicalDevices[deviceNdx],
734 const VkPhysicalDeviceSurfaceInfo2KHR surfaceInfo =
736 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SURFACE_INFO_2_KHR,
740 deUint32 numFormats = 0;
742 VK_CHECK(instHelper.vki.getPhysicalDeviceSurfaceFormats2KHR(physicalDevices[deviceNdx], &surfaceInfo, &numFormats, DE_NULL));
744 if ((size_t)numFormats != refFormats.size())
745 results.fail("vkGetPhysicalDeviceSurfaceFormats2KHR() returned different number of formats");
749 vector<VkSurfaceFormat2KHR> formats (numFormats + 1);
751 for (size_t ndx = 0; ndx < formats.size(); ++ndx)
753 formats[ndx].sType = VK_STRUCTURE_TYPE_SURFACE_FORMAT_2_KHR;
754 formats[ndx].pNext = DE_NULL;
757 const deUint32 numFormatsOrig = numFormats;
759 // check if below call properly overwrites formats count
762 VK_CHECK(instHelper.vki.getPhysicalDeviceSurfaceFormats2KHR(physicalDevices[deviceNdx], &surfaceInfo, &numFormats, &formats[0]));
764 if ((size_t)numFormats != numFormatsOrig)
765 results.fail("Format count changed between calls");
770 vector<VkSurfaceFormatKHR> extFormats (formats.size());
772 for (size_t ndx = 0; ndx < formats.size(); ++ndx)
774 results.check(formats[ndx].sType == VK_STRUCTURE_TYPE_SURFACE_FORMAT_2_KHR &&
775 formats[ndx].pNext == DE_NULL,
776 "sType/pNext modified");
777 extFormats[ndx] = formats[ndx].surfaceFormat;
780 for (size_t ndx = 0; ndx < refFormats.size(); ++ndx)
782 if (!de::contains(extFormats.begin(), extFormats.end(), refFormats[ndx]))
783 results.fail(de::toString(refFormats[ndx]) + " missing from extended query");
787 // Check VK_INCOMPLETE
789 vector<VkSurfaceFormat2KHR> formatsClone (formats);
790 deUint32 numToSupply = numFormats/2;
791 VkResult queryResult;
793 ValidateQueryBits::fillBits(formatsClone.begin() + numToSupply, formatsClone.end());
795 queryResult = instHelper.vki.getPhysicalDeviceSurfaceFormats2KHR(physicalDevices[deviceNdx], &surfaceInfo, &numToSupply, &formatsClone[0]);
797 results.check(queryResult == VK_INCOMPLETE, "Expected VK_INCOMPLETE");
798 results.check(ValidateQueryBits::checkBits(formatsClone.begin() + numToSupply, formatsClone.end()),
799 "Driver wrote past last element");
801 for (size_t ndx = 0; ndx < (size_t)numToSupply; ++ndx)
803 results.check(formatsClone[ndx].sType == VK_STRUCTURE_TYPE_SURFACE_FORMAT_2_KHR &&
804 formatsClone[ndx].pNext == DE_NULL &&
805 formatsClone[ndx].surfaceFormat == formats[ndx].surfaceFormat,
806 "Returned element " + de::toString(ndx) + " is different");
811 // else skip query as surface is not supported by the device
814 return tcu::TestStatus(results.getResult(), results.getMessage());
817 void validateSurfacePresentModes (tcu::ResultCollector& results, Type wsiType, const vector<VkPresentModeKHR>& modes)
819 results.check(de::contains(modes.begin(), modes.end(), VK_PRESENT_MODE_FIFO_KHR),
820 "VK_PRESENT_MODE_FIFO_KHR is not supported");
822 if (wsiType == TYPE_ANDROID)
823 results.check(de::contains(modes.begin(), modes.end(), VK_PRESENT_MODE_MAILBOX_KHR),
824 "VK_PRESENT_MODE_MAILBOX_KHR is not supported");
827 tcu::TestStatus querySurfacePresentModesTest (Context& context, Type wsiType)
829 tcu::TestLog& log = context.getTestContext().getLog();
830 tcu::ResultCollector results (log);
832 const InstanceHelper instHelper (context, wsiType);
833 const NativeObjects native (context, instHelper.supportedExtensions, wsiType);
834 const Unique<VkSurfaceKHR> surface (createSurface(instHelper.vki, instHelper.instance, wsiType, native.getDisplay(), native.getWindow()));
835 const vector<VkPhysicalDevice> physicalDevices = enumeratePhysicalDevices(instHelper.vki, instHelper.instance);
837 for (size_t deviceNdx = 0; deviceNdx < physicalDevices.size(); ++deviceNdx)
839 if (isSupportedByAnyQueue(instHelper.vki, physicalDevices[deviceNdx], *surface))
841 deUint32 numModes = 0;
843 VK_CHECK(instHelper.vki.getPhysicalDeviceSurfacePresentModesKHR(physicalDevices[deviceNdx], *surface, &numModes, DE_NULL));
845 vector<VkPresentModeKHR> modes (numModes + 1);
849 const deUint32 numModesOrig = numModes;
851 // check if below call properly overwrites mode count
854 VK_CHECK(instHelper.vki.getPhysicalDeviceSurfacePresentModesKHR(physicalDevices[deviceNdx], *surface, &numModes, &modes[0]));
856 if ((size_t)numModes != numModesOrig)
857 TCU_FAIL("Mode count changed between calls");
862 log << TestLog::Message << "Device " << deviceNdx << ": " << tcu::formatArray(modes.begin(), modes.end()) << TestLog::EndMessage;
864 validateSurfacePresentModes(results, wsiType, modes);
865 CheckPhysicalDeviceSurfacePresentModesIncompleteResult()(results, instHelper.vki, physicalDevices[deviceNdx], *surface, modes.size());
867 // else skip query as surface is not supported by the device
870 return tcu::TestStatus(results.getResult(), results.getMessage());
873 tcu::TestStatus queryDevGroupSurfacePresentCapabilitiesTest (Context& context, Type wsiType)
875 tcu::TestLog& log = context.getTestContext().getLog();
876 const InstanceHelper instHelper (context, wsiType, vector<string>(1, string("VK_KHR_device_group_creation")));
877 const float queuePriority = 1.0f;
878 const tcu::CommandLine& cmdLine = context.getTestContext().getCommandLine();
879 const deUint32 devGroupIdx = cmdLine.getVKDeviceGroupId() - 1;
880 const deUint32 deviceIdx = context.getTestContext().getCommandLine().getVKDeviceId() - 1u;
881 const VkDeviceGroupPresentModeFlagsKHR requiredFlag = VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_BIT_KHR;
882 const VkDeviceGroupPresentModeFlagsKHR maxValidFlag = VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_BIT_KHR|VK_DEVICE_GROUP_PRESENT_MODE_REMOTE_BIT_KHR |
883 VK_DEVICE_GROUP_PRESENT_MODE_SUM_BIT_KHR|VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_MULTI_DEVICE_BIT_KHR;
884 deUint8 buffer [sizeof(VkDeviceGroupPresentCapabilitiesKHR) + GUARD_SIZE];
885 deUint32 queueFamilyIndex = 0;
886 VkDeviceGroupPresentCapabilitiesKHR* presentCapabilities;
887 VkPhysicalDevice physicalDevice = chooseDevice(instHelper.vki, instHelper.instance, cmdLine);
888 const Extensions& supportedExtensions = enumerateDeviceExtensionProperties(instHelper.vki, physicalDevice, DE_NULL);
889 std::vector<const char*> deviceExtensions;
891 if (!isCoreDeviceExtension(context.getUsedApiVersion(), "VK_KHR_device_group"))
892 deviceExtensions.push_back("VK_KHR_device_group");
893 deviceExtensions.push_back("VK_KHR_swapchain");
895 for (int ndx = 0; ndx < int(deviceExtensions.size()); ++ndx)
897 if (!isExtensionSupported(supportedExtensions, RequiredExtension(deviceExtensions[ndx])))
898 TCU_THROW(NotSupportedError, (string(deviceExtensions[ndx]) + " is not supported").c_str());
901 const vector<VkPhysicalDeviceGroupProperties> deviceGroupProps = enumeratePhysicalDeviceGroups(instHelper.vki, instHelper.instance);
903 const std::vector<VkQueueFamilyProperties> queueProps = getPhysicalDeviceQueueFamilyProperties(instHelper.vki, deviceGroupProps[devGroupIdx].physicalDevices[deviceIdx]);
904 for (size_t queueNdx = 0; queueNdx < queueProps.size(); queueNdx++)
906 if (queueProps[queueNdx].queueFlags & VK_QUEUE_GRAPHICS_BIT)
907 queueFamilyIndex = (deUint32)queueNdx;
909 const VkDeviceQueueCreateInfo deviceQueueCreateInfo =
911 VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, //type
913 (VkDeviceQueueCreateFlags)0u, //flags
914 queueFamilyIndex, //queueFamilyIndex;
916 &queuePriority, //pQueuePriorities;
918 const VkDeviceGroupDeviceCreateInfo deviceGroupInfo =
920 VK_STRUCTURE_TYPE_DEVICE_GROUP_DEVICE_CREATE_INFO_KHR, //stype
922 deviceGroupProps[devGroupIdx].physicalDeviceCount, //physicalDeviceCount
923 deviceGroupProps[devGroupIdx].physicalDevices //physicalDevices
926 const VkDeviceCreateInfo deviceCreateInfo =
928 VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, //sType;
929 &deviceGroupInfo, //pNext;
930 (VkDeviceCreateFlags)0u, //flags
931 1, //queueRecordCount;
932 &deviceQueueCreateInfo, //pRequestedQueues;
934 DE_NULL, //ppEnabledLayerNames;
935 deUint32(deviceExtensions.size()), //enabledExtensionCount;
936 (deviceExtensions.empty() ? DE_NULL : &deviceExtensions[0]), //ppEnabledExtensionNames;
937 DE_NULL, //pEnabledFeatures;
940 Move<VkDevice> deviceGroup = createCustomDevice(context.getTestContext().getCommandLine().isValidationEnabled(), context.getPlatformInterface(), instHelper.instance, instHelper.vki, deviceGroupProps[devGroupIdx].physicalDevices[deviceIdx], &deviceCreateInfo);
941 const DeviceDriver vk (context.getPlatformInterface(), instHelper.instance, *deviceGroup);
944 presentCapabilities = reinterpret_cast<VkDeviceGroupPresentCapabilitiesKHR*>(buffer);
945 deMemset(buffer, GUARD_VALUE, sizeof(buffer));
946 presentCapabilities->sType = VK_STRUCTURE_TYPE_DEVICE_GROUP_PRESENT_CAPABILITIES_KHR;
947 presentCapabilities->pNext = DE_NULL;
948 VK_CHECK(vk.getDeviceGroupPresentCapabilitiesKHR(deviceGroup.get(), presentCapabilities));
951 for (deInt32 ndx = 0; ndx < GUARD_SIZE; ndx++)
953 if (buffer[ndx + sizeof(VkDeviceGroupPresentCapabilitiesKHR)] != GUARD_VALUE)
955 log << TestLog::Message << "deviceGroupPresentCapabilities - Guard offset " << ndx << " not valid" << TestLog::EndMessage;
956 return tcu::TestStatus::fail("deviceGroupPresentCapabilities buffer overflow");
960 // Check each physical device can present on itself
961 for (size_t physDevIdx = 0; physDevIdx < VK_MAX_DEVICE_GROUP_SIZE_KHR; physDevIdx++)
963 if (presentCapabilities->presentMask[physDevIdx])
964 if (!((1 << physDevIdx) & (presentCapabilities->presentMask[physDevIdx])))
965 return tcu::TestStatus::fail("deviceGroupPresentCapabilities, device can not present on itself, invalid present mask");
968 // Check if flags are valid
969 if ((!(presentCapabilities->modes & requiredFlag)) ||
970 presentCapabilities->modes > maxValidFlag)
971 return tcu::TestStatus::fail("deviceGroupPresentCapabilities flag not valid");
973 return tcu::TestStatus::pass("Querying deviceGroup present capabilities succeeded");
976 tcu::TestStatus queryDevGroupSurfacePresentModesTest (Context& context, Type wsiType)
978 tcu::TestLog& log = context.getTestContext().getLog();
979 tcu::ResultCollector results (log);
980 const InstanceHelper instHelper (context, wsiType, vector<string>(1, string("VK_KHR_device_group_creation")));
981 const NativeObjects native (context, instHelper.supportedExtensions, wsiType);
982 const Unique<VkSurfaceKHR> surface (createSurface(instHelper.vki, instHelper.instance, wsiType, native.getDisplay(), native.getWindow()));
983 const float queuePriority = 1.0f;
984 const tcu::CommandLine& cmdLine = context.getTestContext().getCommandLine();
985 const deUint32 devGroupIdx = cmdLine.getVKDeviceGroupId() - 1;
986 const deUint32 deviceIdx = context.getTestContext().getCommandLine().getVKDeviceId() - 1u;
987 const VkDeviceGroupPresentModeFlagsKHR requiredFlag = VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_BIT_KHR;
988 const VkDeviceGroupPresentModeFlagsKHR maxValidFlag = VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_BIT_KHR|VK_DEVICE_GROUP_PRESENT_MODE_REMOTE_BIT_KHR |
989 VK_DEVICE_GROUP_PRESENT_MODE_SUM_BIT_KHR|VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_MULTI_DEVICE_BIT_KHR;
990 VkResult result = VK_SUCCESS;
991 deUint8 buffer [sizeof(VkDeviceGroupPresentModeFlagsKHR) + GUARD_SIZE];
992 deUint32 rectCount = 0;
993 deUint32 incompleteRectCount = 0;
994 deUint32 queueFamilyIndex = 0;
995 VkRect2D* presentRectangles;
996 VkDeviceGroupPresentModeFlagsKHR* presentModeFlags;
997 vector<deUint8> rectanglesBuffer;
998 VkPhysicalDevice physicalDevice = chooseDevice(instHelper.vki, instHelper.instance, cmdLine);
999 const Extensions& supportedExtensions = enumerateDeviceExtensionProperties(instHelper.vki, physicalDevice, DE_NULL);
1000 std::vector<const char*> deviceExtensions;
1002 if (!isCoreDeviceExtension(context.getUsedApiVersion(), "VK_KHR_device_group"))
1003 deviceExtensions.push_back("VK_KHR_device_group");
1004 deviceExtensions.push_back("VK_KHR_swapchain");
1006 for (int ndx = 0; ndx < int(deviceExtensions.size()); ++ndx)
1008 if (!isExtensionSupported(supportedExtensions, RequiredExtension(deviceExtensions[ndx])))
1009 TCU_THROW(NotSupportedError, (string(deviceExtensions[ndx]) + " is not supported").c_str());
1012 const vector<VkPhysicalDeviceGroupProperties> deviceGroupProps = enumeratePhysicalDeviceGroups(instHelper.vki, instHelper.instance);
1013 const std::vector<VkQueueFamilyProperties> queueProps = getPhysicalDeviceQueueFamilyProperties(instHelper.vki, deviceGroupProps[devGroupIdx].physicalDevices[deviceIdx]);
1014 for (size_t queueNdx = 0; queueNdx < queueProps.size(); queueNdx++)
1016 if (queueProps[queueNdx].queueFlags & VK_QUEUE_GRAPHICS_BIT)
1017 queueFamilyIndex = (deUint32)queueNdx;
1019 const VkDeviceQueueCreateInfo deviceQueueCreateInfo =
1021 VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, //type
1023 (VkDeviceQueueCreateFlags)0u, //flags
1024 queueFamilyIndex, //queueFamilyIndex;
1026 &queuePriority, //pQueuePriorities;
1028 const VkDeviceGroupDeviceCreateInfo deviceGroupInfo =
1030 VK_STRUCTURE_TYPE_DEVICE_GROUP_DEVICE_CREATE_INFO_KHR, //stype
1032 deviceGroupProps[devGroupIdx].physicalDeviceCount, //physicalDeviceCount
1033 deviceGroupProps[devGroupIdx].physicalDevices //physicalDevices
1036 const VkDeviceCreateInfo deviceCreateInfo =
1038 VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, //sType;
1039 &deviceGroupInfo, //pNext;
1040 (VkDeviceCreateFlags)0u, //flags
1041 1, //queueRecordCount;
1042 &deviceQueueCreateInfo, //pRequestedQueues;
1044 DE_NULL, //ppEnabledLayerNames;
1045 deUint32(deviceExtensions.size()), //enabledExtensionCount;
1046 (deviceExtensions.empty() ? DE_NULL : &deviceExtensions[0]), //ppEnabledExtensionNames;
1047 DE_NULL, //pEnabledFeatures;
1050 Move<VkDevice> deviceGroup = createCustomDevice(context.getTestContext().getCommandLine().isValidationEnabled(), context.getPlatformInterface(), instHelper.instance, instHelper.vki, deviceGroupProps[devGroupIdx].physicalDevices[deviceIdx], &deviceCreateInfo);
1051 const DeviceDriver vk (context.getPlatformInterface(), instHelper.instance, *deviceGroup);
1052 presentModeFlags = reinterpret_cast<VkDeviceGroupPresentModeFlagsKHR*>(buffer);
1053 deMemset(buffer, GUARD_VALUE, sizeof(buffer));
1055 VK_CHECK(vk.getDeviceGroupSurfacePresentModesKHR(deviceGroup.get(), *surface, presentModeFlags));
1058 for (deInt32 ndx = 0; ndx < GUARD_SIZE; ndx++)
1060 if (buffer[ndx + sizeof(VkDeviceGroupPresentModeFlagsKHR)] != GUARD_VALUE)
1062 log << TestLog::Message << "queryDevGroupSurfacePresentModesTest - Guard offset " << ndx << " not valid" << TestLog::EndMessage;
1063 return tcu::TestStatus::fail("queryDevGroupSurfacePresentModesTest buffer overflow");
1067 // Check if flags are valid
1068 if ((!(*presentModeFlags & requiredFlag)) ||
1069 *presentModeFlags > maxValidFlag)
1070 return tcu::TestStatus::fail("queryDevGroupSurfacePresentModesTest flag not valid");
1072 // getPhysicalDevicePresentRectanglesKHR is supported only when VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_MULTI_DEVICE_BIT_KHR is set
1073 if ((*presentModeFlags & VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_MULTI_DEVICE_BIT_KHR))
1075 for (size_t physDevIdx = 0; physDevIdx < deviceGroupProps[devGroupIdx].physicalDeviceCount; physDevIdx++)
1077 VK_CHECK(instHelper.vki.getPhysicalDevicePresentRectanglesKHR(deviceGroupProps[devGroupIdx].physicalDevices[physDevIdx], *surface, &rectCount, DE_NULL));
1078 rectanglesBuffer.resize(sizeof(VkRect2D) * rectCount + GUARD_SIZE);
1079 presentRectangles = reinterpret_cast<VkRect2D*>(rectanglesBuffer.data());
1080 deMemset(rectanglesBuffer.data(), GUARD_VALUE, rectanglesBuffer.size());
1082 VK_CHECK(instHelper.vki.getPhysicalDevicePresentRectanglesKHR(deviceGroupProps[devGroupIdx].physicalDevices[physDevIdx], *surface, &rectCount, presentRectangles));
1085 for (deInt32 ndx = 0; ndx < GUARD_SIZE; ndx++)
1087 if (rectanglesBuffer[ndx + sizeof(VkRect2D) * rectCount] != GUARD_VALUE)
1089 log << TestLog::Message << "getPhysicalDevicePresentRectanglesKHR - Guard offset " << ndx << " not valid" << TestLog::EndMessage;
1090 return tcu::TestStatus::fail("getPhysicalDevicePresentRectanglesKHR buffer overflow");
1094 // Check rectangles do not overlap
1095 for (size_t rectIdx1 = 0; rectIdx1 < rectCount; rectIdx1++)
1097 for (size_t rectIdx2 = 0; rectIdx2 < rectCount; rectIdx2++)
1099 if (rectIdx1 != rectIdx2)
1101 deUint32 rectATop = presentRectangles[rectIdx1].offset.y;
1102 deUint32 rectALeft = presentRectangles[rectIdx1].offset.x;
1103 deUint32 rectABottom = presentRectangles[rectIdx1].offset.y + presentRectangles[rectIdx1].extent.height;
1104 deUint32 rectARight = presentRectangles[rectIdx1].offset.x + presentRectangles[rectIdx1].extent.width;
1106 deUint32 rectBTop = presentRectangles[rectIdx2].offset.y;
1107 deUint32 rectBLeft = presentRectangles[rectIdx2].offset.x;
1108 deUint32 rectBBottom = presentRectangles[rectIdx2].offset.y + presentRectangles[rectIdx2].extent.height;
1109 deUint32 rectBRight = presentRectangles[rectIdx2].offset.x + presentRectangles[rectIdx2].extent.width;
1111 if (rectALeft < rectBRight && rectARight > rectBLeft &&
1112 rectATop < rectBBottom && rectABottom > rectBTop)
1113 return tcu::TestStatus::fail("getPhysicalDevicePresentRectanglesKHR rectangles overlap");
1119 incompleteRectCount = rectCount / 2;
1120 result = instHelper.vki.getPhysicalDevicePresentRectanglesKHR(deviceGroupProps[devGroupIdx].physicalDevices[physDevIdx], *surface, &incompleteRectCount, presentRectangles);
1121 results.check(result == VK_INCOMPLETE, "Expected VK_INCOMPLETE");
1125 return tcu::TestStatus(results.getResult(), results.getMessage());
1128 tcu::TestStatus createSurfaceInitialSizeTest (Context& context, Type wsiType)
1130 tcu::TestLog& log = context.getTestContext().getLog();
1131 tcu::ResultCollector results (log);
1133 const InstanceHelper instHelper (context, wsiType);
1135 const UniquePtr<Display> nativeDisplay (NativeObjects::createDisplay(context.getTestContext().getPlatform().getVulkanPlatform(),
1136 instHelper.supportedExtensions,
1139 const vector<VkPhysicalDevice> physicalDevices = enumeratePhysicalDevices(instHelper.vki, instHelper.instance);
1140 const UVec2 sizes[] =
1147 DE_ASSERT(getPlatformProperties(wsiType).features & PlatformProperties::FEATURE_INITIAL_WINDOW_SIZE);
1149 for (int sizeNdx = 0; sizeNdx < DE_LENGTH_OF_ARRAY(sizes); ++sizeNdx)
1151 const UVec2& testSize = sizes[sizeNdx];
1152 const UniquePtr<Window> nativeWindow (NativeObjects::createWindow(*nativeDisplay, tcu::just(testSize)));
1153 const Unique<VkSurfaceKHR> surface (createSurface(instHelper.vki, instHelper.instance, wsiType, *nativeDisplay, *nativeWindow));
1155 for (size_t deviceNdx = 0; deviceNdx < physicalDevices.size(); ++deviceNdx)
1157 if (isSupportedByAnyQueue(instHelper.vki, physicalDevices[deviceNdx], *surface))
1159 const VkSurfaceCapabilitiesKHR capabilities = getPhysicalDeviceSurfaceCapabilities(instHelper.vki, physicalDevices[deviceNdx], *surface);
1161 // \note Assumes that surface size is NOT set by swapchain if initial window size is honored by platform
1162 results.check(capabilities.currentExtent.width == testSize.x() &&
1163 capabilities.currentExtent.height == testSize.y(),
1164 "currentExtent " + de::toString(capabilities.currentExtent) + " doesn't match requested size " + de::toString(testSize));
1169 return tcu::TestStatus(results.getResult(), results.getMessage());
1172 tcu::TestStatus resizeSurfaceTest (Context& context, Type wsiType)
1174 tcu::TestLog& log = context.getTestContext().getLog();
1175 tcu::ResultCollector results (log);
1177 const InstanceHelper instHelper (context, wsiType);
1179 const UniquePtr<Display> nativeDisplay (NativeObjects::createDisplay(context.getTestContext().getPlatform().getVulkanPlatform(),
1180 instHelper.supportedExtensions,
1182 UniquePtr<Window> nativeWindow (NativeObjects::createWindow(*nativeDisplay, tcu::nothing<UVec2>()));
1184 const vector<VkPhysicalDevice> physicalDevices = enumeratePhysicalDevices(instHelper.vki, instHelper.instance);
1185 const Unique<VkSurfaceKHR> surface (createSurface(instHelper.vki, instHelper.instance, wsiType, *nativeDisplay, *nativeWindow));
1187 const UVec2 sizes[] =
1194 DE_ASSERT(getPlatformProperties(wsiType).features & PlatformProperties::FEATURE_RESIZE_WINDOW);
1196 for (int sizeNdx = 0; sizeNdx < DE_LENGTH_OF_ARRAY(sizes); ++sizeNdx)
1198 const UVec2 testSize = sizes[sizeNdx];
1202 nativeWindow->resize(testSize);
1204 catch (const tcu::Exception& e)
1206 // Make sure all exception types result in a test failure
1207 results.fail(e.getMessage());
1210 for (size_t deviceNdx = 0; deviceNdx < physicalDevices.size(); ++deviceNdx)
1212 if (isSupportedByAnyQueue(instHelper.vki, physicalDevices[deviceNdx], *surface))
1214 const VkSurfaceCapabilitiesKHR capabilities = getPhysicalDeviceSurfaceCapabilities(instHelper.vki, physicalDevices[deviceNdx], *surface);
1216 // \note Assumes that surface size is NOT set by swapchain if initial window size is honored by platform
1217 results.check(capabilities.currentExtent.width == testSize.x() &&
1218 capabilities.currentExtent.height == testSize.y(),
1219 "currentExtent " + de::toString(capabilities.currentExtent) + " doesn't match requested size " + de::toString(testSize));
1224 return tcu::TestStatus(results.getResult(), results.getMessage());
1227 tcu::TestStatus destroyNullHandleSurfaceTest (Context& context, Type wsiType)
1229 const InstanceHelper instHelper (context, wsiType);
1230 const VkSurfaceKHR nullHandle = DE_NULL;
1232 // Default allocator
1233 instHelper.vki.destroySurfaceKHR(instHelper.instance, nullHandle, DE_NULL);
1237 AllocationCallbackRecorder recordingAllocator (getSystemAllocator(), 1u);
1239 instHelper.vki.destroySurfaceKHR(instHelper.instance, nullHandle, recordingAllocator.getCallbacks());
1241 if (recordingAllocator.getNumRecords() != 0u)
1242 return tcu::TestStatus::fail("Implementation allocated/freed the memory");
1245 return tcu::TestStatus::pass("Destroying a VK_NULL_HANDLE surface has no effect");
1250 void createSurfaceTests (tcu::TestCaseGroup* testGroup, vk::wsi::Type wsiType)
1252 const PlatformProperties& platformProperties = getPlatformProperties(wsiType);
1254 addFunctionCase(testGroup, "create", "Create surface", createSurfaceTest, wsiType);
1255 addFunctionCase(testGroup, "create_custom_allocator", "Create surface with custom allocator", createSurfaceCustomAllocatorTest, wsiType);
1256 addFunctionCase(testGroup, "create_simulate_oom", "Create surface with simulating OOM", createSurfaceSimulateOOMTest, wsiType);
1257 addFunctionCase(testGroup, "query_support", "Query surface support", querySurfaceSupportTest, wsiType);
1258 addFunctionCase(testGroup, "query_presentation_support", "Query native presentation support", queryPresentationSupportTest, wsiType);
1259 addFunctionCase(testGroup, "query_capabilities", "Query surface capabilities", querySurfaceCapabilitiesTest, wsiType);
1260 addFunctionCase(testGroup, "query_capabilities2", "Query extended surface capabilities", querySurfaceCapabilities2Test, wsiType);
1261 addFunctionCase(testGroup, "query_protected_capabilities", "Query protected surface capabilities", querySurfaceProtectedCapabilitiesTest, wsiType);
1262 addFunctionCase(testGroup, "query_surface_counters", "Query and check available surface counters", querySurfaceCounterTest, wsiType);
1263 addFunctionCase(testGroup, "query_formats", "Query surface formats", querySurfaceFormatsTest, wsiType);
1264 addFunctionCase(testGroup, "query_formats2", "Query extended surface formats", querySurfaceFormats2Test, wsiType);
1265 addFunctionCase(testGroup, "query_present_modes", "Query surface present modes", querySurfacePresentModesTest, wsiType);
1266 addFunctionCase(testGroup, "query_devgroup_present_capabilities", "Query surface present modes capabilities in device groups",queryDevGroupSurfacePresentCapabilitiesTest,wsiType);
1267 addFunctionCase(testGroup, "query_devgroup_present_modes", "Query surface present modes for device groups", queryDevGroupSurfacePresentModesTest, wsiType);
1268 addFunctionCase(testGroup, "destroy_null_handle", "Destroy VK_NULL_HANDLE surface", destroyNullHandleSurfaceTest, wsiType);
1270 if ((platformProperties.features & PlatformProperties::FEATURE_INITIAL_WINDOW_SIZE) != 0)
1271 addFunctionCase(testGroup, "initial_size", "Create surface with initial window size set", createSurfaceInitialSizeTest, wsiType);
1273 if ((platformProperties.features & PlatformProperties::FEATURE_RESIZE_WINDOW) != 0)
1274 addFunctionCase(testGroup, "resize", "Resize window and surface", resizeSurfaceTest, wsiType);