1/*------------------------------------------------------------------------- 2 * Vulkan CTS Framework 3 * -------------------- 4 * 5 * Copyright (c) 2016 Google Inc. 6 * 7 * Licensed under the Apache License, Version 2.0 (the "License"); 8 * you may not use this file except in compliance with the License. 9 * You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, software 14 * distributed under the License is distributed on an "AS IS" BASIS, 15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 * See the License for the specific language governing permissions and 17 * limitations under the License. 18 * 19 *//*! 20 * \file 21 * \brief Windowing System Integration (WSI) Utilities. 22 *//*--------------------------------------------------------------------*/ 23 24#include "vkWsiUtil.hpp" 25#include "deArrayUtil.hpp" 26#include "deMemory.h" 27 28#include <limits> 29 30namespace vk 31{ 32namespace wsi 33{ 34 35//! Get canonical WSI name that should be used for example in test case and group names. 36const char* getName (Type wsiType) 37{ 38 static const char* const s_names[] = 39 { 40 "xlib", 41 "xcb", 42 "wayland", 43 "mir", 44 "android", 45 "win32", 46 }; 47 return de::getSizedArrayElement<TYPE_LAST>(s_names, wsiType); 48} 49 50const char* getExtensionName (Type wsiType) 51{ 52 static const char* const s_extNames[] = 53 { 54 "VK_KHR_xlib_surface", 55 "VK_KHR_xcb_surface", 56 "VK_KHR_wayland_surface", 57 "VK_KHR_mir_surface", 58 "VK_KHR_android_surface", 59 "VK_KHR_win32_surface", 60 }; 61 return de::getSizedArrayElement<TYPE_LAST>(s_extNames, wsiType); 62} 63 64const PlatformProperties& getPlatformProperties (Type wsiType) 65{ 66 // \note These are declared here (rather than queried through vk::Platform for example) 67 // on purpose. The behavior of a platform is partly defined by the platform spec, 68 // and partly by WSI extensions, and platform ports should not need to override 69 // that definition. 70 71 const deUint32 noDisplayLimit = std::numeric_limits<deUint32>::max(); 72 const deUint32 noWindowLimit = std::numeric_limits<deUint32>::max(); 73 74 static const PlatformProperties s_properties[] = 75 { 76 // VK_KHR_xlib_surface 77 { 78 PlatformProperties::FEATURE_INITIAL_WINDOW_SIZE|PlatformProperties::FEATURE_RESIZE_WINDOW, 79 PlatformProperties::SWAPCHAIN_EXTENT_MUST_MATCH_WINDOW_SIZE, 80 noDisplayLimit, 81 noWindowLimit, 82 }, 83 // VK_KHR_xcb_surface 84 { 85 PlatformProperties::FEATURE_INITIAL_WINDOW_SIZE|PlatformProperties::FEATURE_RESIZE_WINDOW, 86 PlatformProperties::SWAPCHAIN_EXTENT_MUST_MATCH_WINDOW_SIZE, 87 noDisplayLimit, 88 noWindowLimit, 89 }, 90 // VK_KHR_wayland_surface 91 { 92 0u, 93 PlatformProperties::SWAPCHAIN_EXTENT_SETS_WINDOW_SIZE, 94 noDisplayLimit, 95 noWindowLimit, 96 }, 97 // VK_KHR_mir_surface 98 { 99 PlatformProperties::FEATURE_INITIAL_WINDOW_SIZE|PlatformProperties::FEATURE_RESIZE_WINDOW, 100 PlatformProperties::SWAPCHAIN_EXTENT_SCALED_TO_WINDOW_SIZE, 101 noDisplayLimit, 102 noWindowLimit, 103 }, 104 // VK_KHR_android_surface 105 { 106 PlatformProperties::FEATURE_INITIAL_WINDOW_SIZE, 107 PlatformProperties::SWAPCHAIN_EXTENT_SCALED_TO_WINDOW_SIZE, 108 1u, 109 1u, // Only one window available 110 }, 111 // VK_KHR_win32_surface 112 { 113 PlatformProperties::FEATURE_INITIAL_WINDOW_SIZE|PlatformProperties::FEATURE_RESIZE_WINDOW, 114 PlatformProperties::SWAPCHAIN_EXTENT_MUST_MATCH_WINDOW_SIZE, 115 noDisplayLimit, 116 noWindowLimit, 117 }, 118 }; 119 120 return de::getSizedArrayElement<TYPE_LAST>(s_properties, wsiType); 121} 122 123VkResult createSurface (const InstanceInterface& vki, 124 VkInstance instance, 125 Type wsiType, 126 const Display& nativeDisplay, 127 const Window& nativeWindow, 128 const VkAllocationCallbacks* pAllocator, 129 VkSurfaceKHR* pSurface) 130{ 131 // Update this function if you add more WSI implementations 132 DE_STATIC_ASSERT(TYPE_LAST == 6); 133 134 switch (wsiType) 135 { 136 case TYPE_XLIB: 137 { 138 const XlibDisplayInterface& xlibDisplay = dynamic_cast<const XlibDisplayInterface&>(nativeDisplay); 139 const XlibWindowInterface& xlibWindow = dynamic_cast<const XlibWindowInterface&>(nativeWindow); 140 const VkXlibSurfaceCreateInfoKHR createInfo = 141 { 142 VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR, 143 DE_NULL, 144 (VkXlibSurfaceCreateFlagsKHR)0, 145 xlibDisplay.getNative(), 146 xlibWindow.getNative() 147 }; 148 149 return vki.createXlibSurfaceKHR(instance, &createInfo, pAllocator, pSurface); 150 } 151 152 case TYPE_XCB: 153 { 154 const XcbDisplayInterface& xcbDisplay = dynamic_cast<const XcbDisplayInterface&>(nativeDisplay); 155 const XcbWindowInterface& xcbWindow = dynamic_cast<const XcbWindowInterface&>(nativeWindow); 156 const VkXcbSurfaceCreateInfoKHR createInfo = 157 { 158 VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR, 159 DE_NULL, 160 (VkXcbSurfaceCreateFlagsKHR)0, 161 xcbDisplay.getNative(), 162 xcbWindow.getNative() 163 }; 164 165 return vki.createXcbSurfaceKHR(instance, &createInfo, pAllocator, pSurface); 166 } 167 168 case TYPE_WAYLAND: 169 { 170 const WaylandDisplayInterface& waylandDisplay = dynamic_cast<const WaylandDisplayInterface&>(nativeDisplay); 171 const WaylandWindowInterface& waylandWindow = dynamic_cast<const WaylandWindowInterface&>(nativeWindow); 172 const VkWaylandSurfaceCreateInfoKHR createInfo = 173 { 174 VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR, 175 DE_NULL, 176 (VkWaylandSurfaceCreateFlagsKHR)0, 177 waylandDisplay.getNative(), 178 waylandWindow.getNative() 179 }; 180 181 return vki.createWaylandSurfaceKHR(instance, &createInfo, pAllocator, pSurface); 182 } 183 184 case TYPE_MIR: 185 { 186 const MirDisplayInterface& mirDisplay = dynamic_cast<const MirDisplayInterface&>(nativeDisplay); 187 const MirWindowInterface& mirWindow = dynamic_cast<const MirWindowInterface&>(nativeWindow); 188 const VkMirSurfaceCreateInfoKHR createInfo = 189 { 190 VK_STRUCTURE_TYPE_MIR_SURFACE_CREATE_INFO_KHR, 191 DE_NULL, 192 (VkXcbSurfaceCreateFlagsKHR)0, 193 mirDisplay.getNative(), 194 mirWindow.getNative() 195 }; 196 197 return vki.createMirSurfaceKHR(instance, &createInfo, pAllocator, pSurface); 198 } 199 200 case TYPE_ANDROID: 201 { 202 const AndroidWindowInterface& androidWindow = dynamic_cast<const AndroidWindowInterface&>(nativeWindow); 203 const VkAndroidSurfaceCreateInfoKHR createInfo = 204 { 205 VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR, 206 DE_NULL, 207 (VkAndroidSurfaceCreateFlagsKHR)0, 208 androidWindow.getNative() 209 }; 210 211 return vki.createAndroidSurfaceKHR(instance, &createInfo, pAllocator, pSurface); 212 } 213 214 case TYPE_WIN32: 215 { 216 const Win32DisplayInterface& win32Display = dynamic_cast<const Win32DisplayInterface&>(nativeDisplay); 217 const Win32WindowInterface& win32Window = dynamic_cast<const Win32WindowInterface&>(nativeWindow); 218 const VkWin32SurfaceCreateInfoKHR createInfo = 219 { 220 VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR, 221 DE_NULL, 222 (VkWin32SurfaceCreateFlagsKHR)0, 223 win32Display.getNative(), 224 win32Window.getNative() 225 }; 226 227 return vki.createWin32SurfaceKHR(instance, &createInfo, pAllocator, pSurface); 228 } 229 230 default: 231 DE_FATAL("Unknown WSI type"); 232 return VK_ERROR_SURFACE_LOST_KHR; 233 } 234} 235 236Move<VkSurfaceKHR> createSurface (const InstanceInterface& vki, 237 VkInstance instance, 238 Type wsiType, 239 const Display& nativeDisplay, 240 const Window& nativeWindow, 241 const VkAllocationCallbacks* pAllocator) 242{ 243 VkSurfaceKHR object = 0; 244 VK_CHECK(createSurface(vki, instance, wsiType, nativeDisplay, nativeWindow, pAllocator, &object)); 245 return Move<VkSurfaceKHR>(check<VkSurfaceKHR>(object), Deleter<VkSurfaceKHR>(vki, instance, pAllocator)); 246} 247 248VkBool32 getPhysicalDeviceSurfaceSupport (const InstanceInterface& vki, 249 VkPhysicalDevice physicalDevice, 250 deUint32 queueFamilyIndex, 251 VkSurfaceKHR surface) 252{ 253 VkBool32 result = 0; 254 255 VK_CHECK(vki.getPhysicalDeviceSurfaceSupportKHR(physicalDevice, queueFamilyIndex, surface, &result)); 256 257 return result; 258} 259 260VkSurfaceCapabilitiesKHR getPhysicalDeviceSurfaceCapabilities (const InstanceInterface& vki, 261 VkPhysicalDevice physicalDevice, 262 VkSurfaceKHR surface) 263{ 264 VkSurfaceCapabilitiesKHR capabilities; 265 266 deMemset(&capabilities, 0, sizeof(capabilities)); 267 268 VK_CHECK(vki.getPhysicalDeviceSurfaceCapabilitiesKHR(physicalDevice, surface, &capabilities)); 269 270 return capabilities; 271} 272 273std::vector<VkSurfaceFormatKHR> getPhysicalDeviceSurfaceFormats (const InstanceInterface& vki, 274 VkPhysicalDevice physicalDevice, 275 VkSurfaceKHR surface) 276{ 277 deUint32 numFormats = 0; 278 279 VK_CHECK(vki.getPhysicalDeviceSurfaceFormatsKHR(physicalDevice, surface, &numFormats, DE_NULL)); 280 281 if (numFormats > 0) 282 { 283 std::vector<VkSurfaceFormatKHR> formats (numFormats); 284 285 VK_CHECK(vki.getPhysicalDeviceSurfaceFormatsKHR(physicalDevice, surface, &numFormats, &formats[0])); 286 287 return formats; 288 } 289 else 290 return std::vector<VkSurfaceFormatKHR>(); 291} 292 293std::vector<VkPresentModeKHR> getPhysicalDeviceSurfacePresentModes (const InstanceInterface& vki, 294 VkPhysicalDevice physicalDevice, 295 VkSurfaceKHR surface) 296{ 297 deUint32 numModes = 0; 298 299 VK_CHECK(vki.getPhysicalDeviceSurfacePresentModesKHR(physicalDevice, surface, &numModes, DE_NULL)); 300 301 if (numModes > 0) 302 { 303 std::vector<VkPresentModeKHR> modes (numModes); 304 305 VK_CHECK(vki.getPhysicalDeviceSurfacePresentModesKHR(physicalDevice, surface, &numModes, &modes[0])); 306 307 return modes; 308 } 309 else 310 return std::vector<VkPresentModeKHR>(); 311} 312 313std::vector<VkImage> getSwapchainImages (const DeviceInterface& vkd, 314 VkDevice device, 315 VkSwapchainKHR swapchain) 316{ 317 deUint32 numImages = 0; 318 319 VK_CHECK(vkd.getSwapchainImagesKHR(device, swapchain, &numImages, DE_NULL)); 320 321 if (numImages > 0) 322 { 323 std::vector<VkImage> images (numImages); 324 325 VK_CHECK(vkd.getSwapchainImagesKHR(device, swapchain, &numImages, &images[0])); 326 327 return images; 328 } 329 else 330 return std::vector<VkImage>(); 331} 332 333} // wsi 334} // vk 335