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
30 namespace vk
31 {
32 namespace wsi
33 {
34
35 //! Get canonical WSI name that should be used for example in test case and group names.
getName(Type wsiType)36 const 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 "macos",
47 };
48 return de::getSizedArrayElement<TYPE_LAST>(s_names, wsiType);
49 }
50
getExtensionName(Type wsiType)51 const char* getExtensionName (Type wsiType)
52 {
53 static const char* const s_extNames[] =
54 {
55 "VK_KHR_xlib_surface",
56 "VK_KHR_xcb_surface",
57 "VK_KHR_wayland_surface",
58 "VK_KHR_mir_surface",
59 "VK_KHR_android_surface",
60 "VK_KHR_win32_surface",
61 "VK_MVK_macos_surface"
62 };
63 return de::getSizedArrayElement<TYPE_LAST>(s_extNames, wsiType);
64 }
65
getPlatformProperties(Type wsiType)66 const PlatformProperties& getPlatformProperties (Type wsiType)
67 {
68 // \note These are declared here (rather than queried through vk::Platform for example)
69 // on purpose. The behavior of a platform is partly defined by the platform spec,
70 // and partly by WSI extensions, and platform ports should not need to override
71 // that definition.
72
73 const deUint32 noDisplayLimit = std::numeric_limits<deUint32>::max();
74 const deUint32 noWindowLimit = std::numeric_limits<deUint32>::max();
75
76 static const PlatformProperties s_properties[] =
77 {
78 // VK_KHR_xlib_surface
79 {
80 PlatformProperties::FEATURE_INITIAL_WINDOW_SIZE|PlatformProperties::FEATURE_RESIZE_WINDOW,
81 PlatformProperties::SWAPCHAIN_EXTENT_MUST_MATCH_WINDOW_SIZE,
82 noDisplayLimit,
83 noWindowLimit,
84 },
85 // VK_KHR_xcb_surface
86 {
87 PlatformProperties::FEATURE_INITIAL_WINDOW_SIZE|PlatformProperties::FEATURE_RESIZE_WINDOW,
88 PlatformProperties::SWAPCHAIN_EXTENT_MUST_MATCH_WINDOW_SIZE,
89 noDisplayLimit,
90 noWindowLimit,
91 },
92 // VK_KHR_wayland_surface
93 {
94 0u,
95 PlatformProperties::SWAPCHAIN_EXTENT_SETS_WINDOW_SIZE,
96 noDisplayLimit,
97 noWindowLimit,
98 },
99 // VK_KHR_mir_surface
100 {
101 PlatformProperties::FEATURE_INITIAL_WINDOW_SIZE|PlatformProperties::FEATURE_RESIZE_WINDOW,
102 PlatformProperties::SWAPCHAIN_EXTENT_SCALED_TO_WINDOW_SIZE,
103 noDisplayLimit,
104 noWindowLimit,
105 },
106 // VK_KHR_android_surface
107 {
108 PlatformProperties::FEATURE_INITIAL_WINDOW_SIZE,
109 PlatformProperties::SWAPCHAIN_EXTENT_SCALED_TO_WINDOW_SIZE,
110 1u,
111 1u, // Only one window available
112 },
113 // VK_KHR_win32_surface
114 {
115 PlatformProperties::FEATURE_INITIAL_WINDOW_SIZE|PlatformProperties::FEATURE_RESIZE_WINDOW,
116 PlatformProperties::SWAPCHAIN_EXTENT_MUST_MATCH_WINDOW_SIZE,
117 noDisplayLimit,
118 noWindowLimit,
119 },
120 // VK_MVK_macos_surface
121 {
122 PlatformProperties::FEATURE_INITIAL_WINDOW_SIZE|PlatformProperties::FEATURE_RESIZE_WINDOW,
123 PlatformProperties::SWAPCHAIN_EXTENT_MUST_MATCH_WINDOW_SIZE,
124 noDisplayLimit,
125 noWindowLimit,
126 },
127 };
128
129 return de::getSizedArrayElement<TYPE_LAST>(s_properties, wsiType);
130 }
131
createSurface(const InstanceInterface & vki,VkInstance instance,Type wsiType,const Display & nativeDisplay,const Window & nativeWindow,const VkAllocationCallbacks * pAllocator,VkSurfaceKHR * pSurface)132 VkResult createSurface (const InstanceInterface& vki,
133 VkInstance instance,
134 Type wsiType,
135 const Display& nativeDisplay,
136 const Window& nativeWindow,
137 const VkAllocationCallbacks* pAllocator,
138 VkSurfaceKHR* pSurface)
139 {
140 // Update this function if you add more WSI implementations
141 DE_STATIC_ASSERT(TYPE_LAST == 7);
142
143 switch (wsiType)
144 {
145 case TYPE_XLIB:
146 {
147 const XlibDisplayInterface& xlibDisplay = dynamic_cast<const XlibDisplayInterface&>(nativeDisplay);
148 const XlibWindowInterface& xlibWindow = dynamic_cast<const XlibWindowInterface&>(nativeWindow);
149 const VkXlibSurfaceCreateInfoKHR createInfo =
150 {
151 VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR,
152 DE_NULL,
153 (VkXlibSurfaceCreateFlagsKHR)0,
154 xlibDisplay.getNative(),
155 xlibWindow.getNative()
156 };
157
158 return vki.createXlibSurfaceKHR(instance, &createInfo, pAllocator, pSurface);
159 }
160
161 case TYPE_XCB:
162 {
163 const XcbDisplayInterface& xcbDisplay = dynamic_cast<const XcbDisplayInterface&>(nativeDisplay);
164 const XcbWindowInterface& xcbWindow = dynamic_cast<const XcbWindowInterface&>(nativeWindow);
165 const VkXcbSurfaceCreateInfoKHR createInfo =
166 {
167 VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR,
168 DE_NULL,
169 (VkXcbSurfaceCreateFlagsKHR)0,
170 xcbDisplay.getNative(),
171 xcbWindow.getNative()
172 };
173
174 return vki.createXcbSurfaceKHR(instance, &createInfo, pAllocator, pSurface);
175 }
176
177 case TYPE_WAYLAND:
178 {
179 const WaylandDisplayInterface& waylandDisplay = dynamic_cast<const WaylandDisplayInterface&>(nativeDisplay);
180 const WaylandWindowInterface& waylandWindow = dynamic_cast<const WaylandWindowInterface&>(nativeWindow);
181 const VkWaylandSurfaceCreateInfoKHR createInfo =
182 {
183 VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR,
184 DE_NULL,
185 (VkWaylandSurfaceCreateFlagsKHR)0,
186 waylandDisplay.getNative(),
187 waylandWindow.getNative()
188 };
189
190 return vki.createWaylandSurfaceKHR(instance, &createInfo, pAllocator, pSurface);
191 }
192
193 case TYPE_MIR:
194 {
195 const MirDisplayInterface& mirDisplay = dynamic_cast<const MirDisplayInterface&>(nativeDisplay);
196 const MirWindowInterface& mirWindow = dynamic_cast<const MirWindowInterface&>(nativeWindow);
197 const VkMirSurfaceCreateInfoKHR createInfo =
198 {
199 VK_STRUCTURE_TYPE_MIR_SURFACE_CREATE_INFO_KHR,
200 DE_NULL,
201 (VkXcbSurfaceCreateFlagsKHR)0,
202 mirDisplay.getNative(),
203 mirWindow.getNative()
204 };
205
206 return vki.createMirSurfaceKHR(instance, &createInfo, pAllocator, pSurface);
207 }
208
209 case TYPE_ANDROID:
210 {
211 const AndroidWindowInterface& androidWindow = dynamic_cast<const AndroidWindowInterface&>(nativeWindow);
212 const VkAndroidSurfaceCreateInfoKHR createInfo =
213 {
214 VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR,
215 DE_NULL,
216 (VkAndroidSurfaceCreateFlagsKHR)0,
217 androidWindow.getNative()
218 };
219
220 return vki.createAndroidSurfaceKHR(instance, &createInfo, pAllocator, pSurface);
221 }
222
223 case TYPE_WIN32:
224 {
225 const Win32DisplayInterface& win32Display = dynamic_cast<const Win32DisplayInterface&>(nativeDisplay);
226 const Win32WindowInterface& win32Window = dynamic_cast<const Win32WindowInterface&>(nativeWindow);
227 const VkWin32SurfaceCreateInfoKHR createInfo =
228 {
229 VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR,
230 DE_NULL,
231 (VkWin32SurfaceCreateFlagsKHR)0,
232 win32Display.getNative(),
233 win32Window.getNative()
234 };
235
236 return vki.createWin32SurfaceKHR(instance, &createInfo, pAllocator, pSurface);
237 }
238
239 case TYPE_MACOS:
240 {
241 const MacOSWindowInterface& macOSWindow = dynamic_cast<const MacOSWindowInterface&>(nativeWindow);
242 const VkMacOSSurfaceCreateInfoMVK createInfo =
243 {
244 VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK,
245 DE_NULL,
246 (VkMacOSSurfaceCreateFlagsMVK)0,
247 macOSWindow.getNative()
248 };
249
250 return vki.createMacOSSurfaceMVK(instance, &createInfo, pAllocator, pSurface);
251 }
252
253 default:
254 DE_FATAL("Unknown WSI type");
255 return VK_ERROR_SURFACE_LOST_KHR;
256 }
257 }
258
createSurface(const InstanceInterface & vki,VkInstance instance,Type wsiType,const Display & nativeDisplay,const Window & nativeWindow,const VkAllocationCallbacks * pAllocator)259 Move<VkSurfaceKHR> createSurface (const InstanceInterface& vki,
260 VkInstance instance,
261 Type wsiType,
262 const Display& nativeDisplay,
263 const Window& nativeWindow,
264 const VkAllocationCallbacks* pAllocator)
265 {
266 VkSurfaceKHR object = 0;
267 VK_CHECK(createSurface(vki, instance, wsiType, nativeDisplay, nativeWindow, pAllocator, &object));
268 return Move<VkSurfaceKHR>(check<VkSurfaceKHR>(object), Deleter<VkSurfaceKHR>(vki, instance, pAllocator));
269 }
270
getPhysicalDeviceSurfaceSupport(const InstanceInterface & vki,VkPhysicalDevice physicalDevice,deUint32 queueFamilyIndex,VkSurfaceKHR surface)271 VkBool32 getPhysicalDeviceSurfaceSupport (const InstanceInterface& vki,
272 VkPhysicalDevice physicalDevice,
273 deUint32 queueFamilyIndex,
274 VkSurfaceKHR surface)
275 {
276 VkBool32 result = 0;
277
278 VK_CHECK(vki.getPhysicalDeviceSurfaceSupportKHR(physicalDevice, queueFamilyIndex, surface, &result));
279
280 return result;
281 }
282
getPhysicalDeviceSurfaceCapabilities(const InstanceInterface & vki,VkPhysicalDevice physicalDevice,VkSurfaceKHR surface)283 VkSurfaceCapabilitiesKHR getPhysicalDeviceSurfaceCapabilities (const InstanceInterface& vki,
284 VkPhysicalDevice physicalDevice,
285 VkSurfaceKHR surface)
286 {
287 VkSurfaceCapabilitiesKHR capabilities;
288
289 deMemset(&capabilities, 0, sizeof(capabilities));
290
291 VK_CHECK(vki.getPhysicalDeviceSurfaceCapabilitiesKHR(physicalDevice, surface, &capabilities));
292
293 return capabilities;
294 }
295
getPhysicalDeviceSurfaceFormats(const InstanceInterface & vki,VkPhysicalDevice physicalDevice,VkSurfaceKHR surface)296 std::vector<VkSurfaceFormatKHR> getPhysicalDeviceSurfaceFormats (const InstanceInterface& vki,
297 VkPhysicalDevice physicalDevice,
298 VkSurfaceKHR surface)
299 {
300 deUint32 numFormats = 0;
301
302 VK_CHECK(vki.getPhysicalDeviceSurfaceFormatsKHR(physicalDevice, surface, &numFormats, DE_NULL));
303
304 if (numFormats > 0)
305 {
306 std::vector<VkSurfaceFormatKHR> formats (numFormats);
307
308 VK_CHECK(vki.getPhysicalDeviceSurfaceFormatsKHR(physicalDevice, surface, &numFormats, &formats[0]));
309
310 return formats;
311 }
312 else
313 return std::vector<VkSurfaceFormatKHR>();
314 }
315
getPhysicalDeviceSurfacePresentModes(const InstanceInterface & vki,VkPhysicalDevice physicalDevice,VkSurfaceKHR surface)316 std::vector<VkPresentModeKHR> getPhysicalDeviceSurfacePresentModes (const InstanceInterface& vki,
317 VkPhysicalDevice physicalDevice,
318 VkSurfaceKHR surface)
319 {
320 deUint32 numModes = 0;
321
322 VK_CHECK(vki.getPhysicalDeviceSurfacePresentModesKHR(physicalDevice, surface, &numModes, DE_NULL));
323
324 if (numModes > 0)
325 {
326 std::vector<VkPresentModeKHR> modes (numModes);
327
328 VK_CHECK(vki.getPhysicalDeviceSurfacePresentModesKHR(physicalDevice, surface, &numModes, &modes[0]));
329
330 return modes;
331 }
332 else
333 return std::vector<VkPresentModeKHR>();
334 }
335
getSwapchainImages(const DeviceInterface & vkd,VkDevice device,VkSwapchainKHR swapchain)336 std::vector<VkImage> getSwapchainImages (const DeviceInterface& vkd,
337 VkDevice device,
338 VkSwapchainKHR swapchain)
339 {
340 deUint32 numImages = 0;
341
342 VK_CHECK(vkd.getSwapchainImagesKHR(device, swapchain, &numImages, DE_NULL));
343
344 if (numImages > 0)
345 {
346 std::vector<VkImage> images (numImages);
347
348 VK_CHECK(vkd.getSwapchainImagesKHR(device, swapchain, &numImages, &images[0]));
349
350 return images;
351 }
352 else
353 return std::vector<VkImage>();
354 }
355
356 } // wsi
357 } // vk
358