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 };
47 return de::getSizedArrayElement<TYPE_LAST>(s_names, wsiType);
48 }
49
getExtensionName(Type wsiType)50 const 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
getPlatformProperties(Type wsiType)64 const 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
createSurface(const InstanceInterface & vki,VkInstance instance,Type wsiType,const Display & nativeDisplay,const Window & nativeWindow,const VkAllocationCallbacks * pAllocator,VkSurfaceKHR * pSurface)123 VkResult 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
createSurface(const InstanceInterface & vki,VkInstance instance,Type wsiType,const Display & nativeDisplay,const Window & nativeWindow,const VkAllocationCallbacks * pAllocator)236 Move<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
getPhysicalDeviceSurfaceSupport(const InstanceInterface & vki,VkPhysicalDevice physicalDevice,deUint32 queueFamilyIndex,VkSurfaceKHR surface)248 VkBool32 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
getPhysicalDeviceSurfaceCapabilities(const InstanceInterface & vki,VkPhysicalDevice physicalDevice,VkSurfaceKHR surface)260 VkSurfaceCapabilitiesKHR 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
getPhysicalDeviceSurfaceFormats(const InstanceInterface & vki,VkPhysicalDevice physicalDevice,VkSurfaceKHR surface)273 std::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
getPhysicalDeviceSurfacePresentModes(const InstanceInterface & vki,VkPhysicalDevice physicalDevice,VkSurfaceKHR surface)293 std::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
getSwapchainImages(const DeviceInterface & vkd,VkDevice device,VkSwapchainKHR swapchain)313 std::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