/*------------------------------------------------------------------------- * Vulkan CTS Framework * -------------------- * * Copyright (c) 2016 Google Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *//*! * \file * \brief Windowing System Integration (WSI) Utilities. *//*--------------------------------------------------------------------*/ #include "vkWsiUtil.hpp" #include "deArrayUtil.hpp" #include "deMemory.h" #include namespace vk { namespace wsi { //! Get canonical WSI name that should be used for example in test case and group names. const char* getName (Type wsiType) { static const char* const s_names[] = { "xlib", "xcb", "wayland", "mir", "android", "win32", "macos", }; return de::getSizedArrayElement(s_names, wsiType); } const char* getExtensionName (Type wsiType) { static const char* const s_extNames[] = { "VK_KHR_xlib_surface", "VK_KHR_xcb_surface", "VK_KHR_wayland_surface", "VK_KHR_mir_surface", "VK_KHR_android_surface", "VK_KHR_win32_surface", "VK_MVK_macos_surface" }; return de::getSizedArrayElement(s_extNames, wsiType); } const PlatformProperties& getPlatformProperties (Type wsiType) { // \note These are declared here (rather than queried through vk::Platform for example) // on purpose. The behavior of a platform is partly defined by the platform spec, // and partly by WSI extensions, and platform ports should not need to override // that definition. const deUint32 noDisplayLimit = std::numeric_limits::max(); const deUint32 noWindowLimit = std::numeric_limits::max(); static const PlatformProperties s_properties[] = { // VK_KHR_xlib_surface { PlatformProperties::FEATURE_INITIAL_WINDOW_SIZE|PlatformProperties::FEATURE_RESIZE_WINDOW, PlatformProperties::SWAPCHAIN_EXTENT_MUST_MATCH_WINDOW_SIZE, noDisplayLimit, noWindowLimit, }, // VK_KHR_xcb_surface { PlatformProperties::FEATURE_INITIAL_WINDOW_SIZE|PlatformProperties::FEATURE_RESIZE_WINDOW, PlatformProperties::SWAPCHAIN_EXTENT_MUST_MATCH_WINDOW_SIZE, noDisplayLimit, noWindowLimit, }, // VK_KHR_wayland_surface { 0u, PlatformProperties::SWAPCHAIN_EXTENT_SETS_WINDOW_SIZE, noDisplayLimit, noWindowLimit, }, // VK_KHR_mir_surface { PlatformProperties::FEATURE_INITIAL_WINDOW_SIZE|PlatformProperties::FEATURE_RESIZE_WINDOW, PlatformProperties::SWAPCHAIN_EXTENT_SCALED_TO_WINDOW_SIZE, noDisplayLimit, noWindowLimit, }, // VK_KHR_android_surface { PlatformProperties::FEATURE_INITIAL_WINDOW_SIZE, PlatformProperties::SWAPCHAIN_EXTENT_SCALED_TO_WINDOW_SIZE, 1u, 1u, // Only one window available }, // VK_KHR_win32_surface { PlatformProperties::FEATURE_INITIAL_WINDOW_SIZE|PlatformProperties::FEATURE_RESIZE_WINDOW, PlatformProperties::SWAPCHAIN_EXTENT_MUST_MATCH_WINDOW_SIZE, noDisplayLimit, noWindowLimit, }, // VK_MVK_macos_surface { PlatformProperties::FEATURE_INITIAL_WINDOW_SIZE|PlatformProperties::FEATURE_RESIZE_WINDOW, PlatformProperties::SWAPCHAIN_EXTENT_MUST_MATCH_WINDOW_SIZE, noDisplayLimit, noWindowLimit, }, }; return de::getSizedArrayElement(s_properties, wsiType); } VkResult createSurface (const InstanceInterface& vki, VkInstance instance, Type wsiType, const Display& nativeDisplay, const Window& nativeWindow, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface) { // Update this function if you add more WSI implementations DE_STATIC_ASSERT(TYPE_LAST == 7); switch (wsiType) { case TYPE_XLIB: { const XlibDisplayInterface& xlibDisplay = dynamic_cast(nativeDisplay); const XlibWindowInterface& xlibWindow = dynamic_cast(nativeWindow); const VkXlibSurfaceCreateInfoKHR createInfo = { VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR, DE_NULL, (VkXlibSurfaceCreateFlagsKHR)0, xlibDisplay.getNative(), xlibWindow.getNative() }; return vki.createXlibSurfaceKHR(instance, &createInfo, pAllocator, pSurface); } case TYPE_XCB: { const XcbDisplayInterface& xcbDisplay = dynamic_cast(nativeDisplay); const XcbWindowInterface& xcbWindow = dynamic_cast(nativeWindow); const VkXcbSurfaceCreateInfoKHR createInfo = { VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR, DE_NULL, (VkXcbSurfaceCreateFlagsKHR)0, xcbDisplay.getNative(), xcbWindow.getNative() }; return vki.createXcbSurfaceKHR(instance, &createInfo, pAllocator, pSurface); } case TYPE_WAYLAND: { const WaylandDisplayInterface& waylandDisplay = dynamic_cast(nativeDisplay); const WaylandWindowInterface& waylandWindow = dynamic_cast(nativeWindow); const VkWaylandSurfaceCreateInfoKHR createInfo = { VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR, DE_NULL, (VkWaylandSurfaceCreateFlagsKHR)0, waylandDisplay.getNative(), waylandWindow.getNative() }; return vki.createWaylandSurfaceKHR(instance, &createInfo, pAllocator, pSurface); } case TYPE_MIR: { const MirDisplayInterface& mirDisplay = dynamic_cast(nativeDisplay); const MirWindowInterface& mirWindow = dynamic_cast(nativeWindow); const VkMirSurfaceCreateInfoKHR createInfo = { VK_STRUCTURE_TYPE_MIR_SURFACE_CREATE_INFO_KHR, DE_NULL, (VkXcbSurfaceCreateFlagsKHR)0, mirDisplay.getNative(), mirWindow.getNative() }; return vki.createMirSurfaceKHR(instance, &createInfo, pAllocator, pSurface); } case TYPE_ANDROID: { const AndroidWindowInterface& androidWindow = dynamic_cast(nativeWindow); const VkAndroidSurfaceCreateInfoKHR createInfo = { VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR, DE_NULL, (VkAndroidSurfaceCreateFlagsKHR)0, androidWindow.getNative() }; return vki.createAndroidSurfaceKHR(instance, &createInfo, pAllocator, pSurface); } case TYPE_WIN32: { const Win32DisplayInterface& win32Display = dynamic_cast(nativeDisplay); const Win32WindowInterface& win32Window = dynamic_cast(nativeWindow); const VkWin32SurfaceCreateInfoKHR createInfo = { VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR, DE_NULL, (VkWin32SurfaceCreateFlagsKHR)0, win32Display.getNative(), win32Window.getNative() }; return vki.createWin32SurfaceKHR(instance, &createInfo, pAllocator, pSurface); } case TYPE_MACOS: { const MacOSWindowInterface& macOSWindow = dynamic_cast(nativeWindow); const VkMacOSSurfaceCreateInfoMVK createInfo = { VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK, DE_NULL, (VkMacOSSurfaceCreateFlagsMVK)0, macOSWindow.getNative() }; return vki.createMacOSSurfaceMVK(instance, &createInfo, pAllocator, pSurface); } default: DE_FATAL("Unknown WSI type"); return VK_ERROR_SURFACE_LOST_KHR; } } Move createSurface (const InstanceInterface& vki, VkInstance instance, Type wsiType, const Display& nativeDisplay, const Window& nativeWindow, const VkAllocationCallbacks* pAllocator) { VkSurfaceKHR object = 0; VK_CHECK(createSurface(vki, instance, wsiType, nativeDisplay, nativeWindow, pAllocator, &object)); return Move(check(object), Deleter(vki, instance, pAllocator)); } VkBool32 getPhysicalDeviceSurfaceSupport (const InstanceInterface& vki, VkPhysicalDevice physicalDevice, deUint32 queueFamilyIndex, VkSurfaceKHR surface) { VkBool32 result = 0; VK_CHECK(vki.getPhysicalDeviceSurfaceSupportKHR(physicalDevice, queueFamilyIndex, surface, &result)); return result; } VkSurfaceCapabilitiesKHR getPhysicalDeviceSurfaceCapabilities (const InstanceInterface& vki, VkPhysicalDevice physicalDevice, VkSurfaceKHR surface) { VkSurfaceCapabilitiesKHR capabilities; deMemset(&capabilities, 0, sizeof(capabilities)); VK_CHECK(vki.getPhysicalDeviceSurfaceCapabilitiesKHR(physicalDevice, surface, &capabilities)); return capabilities; } std::vector getPhysicalDeviceSurfaceFormats (const InstanceInterface& vki, VkPhysicalDevice physicalDevice, VkSurfaceKHR surface) { deUint32 numFormats = 0; VK_CHECK(vki.getPhysicalDeviceSurfaceFormatsKHR(physicalDevice, surface, &numFormats, DE_NULL)); if (numFormats > 0) { std::vector formats (numFormats); VK_CHECK(vki.getPhysicalDeviceSurfaceFormatsKHR(physicalDevice, surface, &numFormats, &formats[0])); return formats; } else return std::vector(); } std::vector getPhysicalDeviceSurfacePresentModes (const InstanceInterface& vki, VkPhysicalDevice physicalDevice, VkSurfaceKHR surface) { deUint32 numModes = 0; VK_CHECK(vki.getPhysicalDeviceSurfacePresentModesKHR(physicalDevice, surface, &numModes, DE_NULL)); if (numModes > 0) { std::vector modes (numModes); VK_CHECK(vki.getPhysicalDeviceSurfacePresentModesKHR(physicalDevice, surface, &numModes, &modes[0])); return modes; } else return std::vector(); } std::vector getSwapchainImages (const DeviceInterface& vkd, VkDevice device, VkSwapchainKHR swapchain) { deUint32 numImages = 0; VK_CHECK(vkd.getSwapchainImagesKHR(device, swapchain, &numImages, DE_NULL)); if (numImages > 0) { std::vector images (numImages); VK_CHECK(vkd.getSwapchainImagesKHR(device, swapchain, &numImages, &images[0])); return images; } else return std::vector(); } } // wsi } // vk