Home | History | Annotate | Download | only in vulkan
      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.
     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 
     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 
     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 
    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 
    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 
    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 
    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 
    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 
    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 
    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