• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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