blob: b7428c9def265e35df60d37dd4414e73c24c50ca [file] [log] [blame]
/*-------------------------------------------------------------------------
* Vulkan CTS Framework
* --------------------
*
* Copyright (c) 2016 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*//*!
* \file
* \brief Windowing System Integration (WSI) Utilities.
*//*--------------------------------------------------------------------*/
#include "vkWsiUtil.hpp"
#include "deArrayUtil.hpp"
#include "deMemory.h"
#include <limits>
namespace vk
{
namespace wsi
{
//! Get canonical WSI name that should be used for example in test case and group names.
const char* getName (Type wsiType)
{
static const char* const s_names[] =
{
"xlib",
"xcb",
"wayland",
"mir",
"android",
"win32",
"macos",
};
return de::getSizedArrayElement<TYPE_LAST>(s_names, wsiType);
}
const char* getExtensionName (Type wsiType)
{
static const char* const s_extNames[] =
{
"VK_KHR_xlib_surface",
"VK_KHR_xcb_surface",
"VK_KHR_wayland_surface",
"VK_KHR_mir_surface",
"VK_KHR_android_surface",
"VK_KHR_win32_surface",
"VK_MVK_macos_surface"
};
return de::getSizedArrayElement<TYPE_LAST>(s_extNames, wsiType);
}
const PlatformProperties& getPlatformProperties (Type wsiType)
{
// \note These are declared here (rather than queried through vk::Platform for example)
// on purpose. The behavior of a platform is partly defined by the platform spec,
// and partly by WSI extensions, and platform ports should not need to override
// that definition.
const deUint32 noDisplayLimit = std::numeric_limits<deUint32>::max();
const deUint32 noWindowLimit = std::numeric_limits<deUint32>::max();
static const PlatformProperties s_properties[] =
{
// VK_KHR_xlib_surface
{
PlatformProperties::FEATURE_INITIAL_WINDOW_SIZE|PlatformProperties::FEATURE_RESIZE_WINDOW,
PlatformProperties::SWAPCHAIN_EXTENT_MUST_MATCH_WINDOW_SIZE,
noDisplayLimit,
noWindowLimit,
},
// VK_KHR_xcb_surface
{
PlatformProperties::FEATURE_INITIAL_WINDOW_SIZE|PlatformProperties::FEATURE_RESIZE_WINDOW,
PlatformProperties::SWAPCHAIN_EXTENT_MUST_MATCH_WINDOW_SIZE,
noDisplayLimit,
noWindowLimit,
},
// VK_KHR_wayland_surface
{
0u,
PlatformProperties::SWAPCHAIN_EXTENT_SETS_WINDOW_SIZE,
noDisplayLimit,
noWindowLimit,
},
// VK_KHR_mir_surface
{
PlatformProperties::FEATURE_INITIAL_WINDOW_SIZE|PlatformProperties::FEATURE_RESIZE_WINDOW,
PlatformProperties::SWAPCHAIN_EXTENT_SCALED_TO_WINDOW_SIZE,
noDisplayLimit,
noWindowLimit,
},
// VK_KHR_android_surface
{
PlatformProperties::FEATURE_INITIAL_WINDOW_SIZE,
PlatformProperties::SWAPCHAIN_EXTENT_SCALED_TO_WINDOW_SIZE,
1u,
1u, // Only one window available
},
// VK_KHR_win32_surface
{
PlatformProperties::FEATURE_INITIAL_WINDOW_SIZE|PlatformProperties::FEATURE_RESIZE_WINDOW,
PlatformProperties::SWAPCHAIN_EXTENT_MUST_MATCH_WINDOW_SIZE,
noDisplayLimit,
noWindowLimit,
},
// VK_MVK_macos_surface
{
PlatformProperties::FEATURE_INITIAL_WINDOW_SIZE|PlatformProperties::FEATURE_RESIZE_WINDOW,
PlatformProperties::SWAPCHAIN_EXTENT_MUST_MATCH_WINDOW_SIZE,
noDisplayLimit,
noWindowLimit,
},
};
return de::getSizedArrayElement<TYPE_LAST>(s_properties, wsiType);
}
VkResult createSurface (const InstanceInterface& vki,
VkInstance instance,
Type wsiType,
const Display& nativeDisplay,
const Window& nativeWindow,
const VkAllocationCallbacks* pAllocator,
VkSurfaceKHR* pSurface)
{
// Update this function if you add more WSI implementations
DE_STATIC_ASSERT(TYPE_LAST == 7);
switch (wsiType)
{
case TYPE_XLIB:
{
const XlibDisplayInterface& xlibDisplay = dynamic_cast<const XlibDisplayInterface&>(nativeDisplay);
const XlibWindowInterface& xlibWindow = dynamic_cast<const XlibWindowInterface&>(nativeWindow);
const VkXlibSurfaceCreateInfoKHR createInfo =
{
VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR,
DE_NULL,
(VkXlibSurfaceCreateFlagsKHR)0,
xlibDisplay.getNative(),
xlibWindow.getNative()
};
return vki.createXlibSurfaceKHR(instance, &createInfo, pAllocator, pSurface);
}
case TYPE_XCB:
{
const XcbDisplayInterface& xcbDisplay = dynamic_cast<const XcbDisplayInterface&>(nativeDisplay);
const XcbWindowInterface& xcbWindow = dynamic_cast<const XcbWindowInterface&>(nativeWindow);
const VkXcbSurfaceCreateInfoKHR createInfo =
{
VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR,
DE_NULL,
(VkXcbSurfaceCreateFlagsKHR)0,
xcbDisplay.getNative(),
xcbWindow.getNative()
};
return vki.createXcbSurfaceKHR(instance, &createInfo, pAllocator, pSurface);
}
case TYPE_WAYLAND:
{
const WaylandDisplayInterface& waylandDisplay = dynamic_cast<const WaylandDisplayInterface&>(nativeDisplay);
const WaylandWindowInterface& waylandWindow = dynamic_cast<const WaylandWindowInterface&>(nativeWindow);
const VkWaylandSurfaceCreateInfoKHR createInfo =
{
VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR,
DE_NULL,
(VkWaylandSurfaceCreateFlagsKHR)0,
waylandDisplay.getNative(),
waylandWindow.getNative()
};
return vki.createWaylandSurfaceKHR(instance, &createInfo, pAllocator, pSurface);
}
case TYPE_MIR:
{
const MirDisplayInterface& mirDisplay = dynamic_cast<const MirDisplayInterface&>(nativeDisplay);
const MirWindowInterface& mirWindow = dynamic_cast<const MirWindowInterface&>(nativeWindow);
const VkMirSurfaceCreateInfoKHR createInfo =
{
VK_STRUCTURE_TYPE_MIR_SURFACE_CREATE_INFO_KHR,
DE_NULL,
(VkXcbSurfaceCreateFlagsKHR)0,
mirDisplay.getNative(),
mirWindow.getNative()
};
return vki.createMirSurfaceKHR(instance, &createInfo, pAllocator, pSurface);
}
case TYPE_ANDROID:
{
const AndroidWindowInterface& androidWindow = dynamic_cast<const AndroidWindowInterface&>(nativeWindow);
const VkAndroidSurfaceCreateInfoKHR createInfo =
{
VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR,
DE_NULL,
(VkAndroidSurfaceCreateFlagsKHR)0,
androidWindow.getNative()
};
return vki.createAndroidSurfaceKHR(instance, &createInfo, pAllocator, pSurface);
}
case TYPE_WIN32:
{
const Win32DisplayInterface& win32Display = dynamic_cast<const Win32DisplayInterface&>(nativeDisplay);
const Win32WindowInterface& win32Window = dynamic_cast<const Win32WindowInterface&>(nativeWindow);
const VkWin32SurfaceCreateInfoKHR createInfo =
{
VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR,
DE_NULL,
(VkWin32SurfaceCreateFlagsKHR)0,
win32Display.getNative(),
win32Window.getNative()
};
return vki.createWin32SurfaceKHR(instance, &createInfo, pAllocator, pSurface);
}
case TYPE_MACOS:
{
const MacOSWindowInterface& macOSWindow = dynamic_cast<const MacOSWindowInterface&>(nativeWindow);
const VkMacOSSurfaceCreateInfoMVK createInfo =
{
VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK,
DE_NULL,
(VkMacOSSurfaceCreateFlagsMVK)0,
macOSWindow.getNative()
};
return vki.createMacOSSurfaceMVK(instance, &createInfo, pAllocator, pSurface);
}
default:
DE_FATAL("Unknown WSI type");
return VK_ERROR_SURFACE_LOST_KHR;
}
}
Move<VkSurfaceKHR> createSurface (const InstanceInterface& vki,
VkInstance instance,
Type wsiType,
const Display& nativeDisplay,
const Window& nativeWindow,
const VkAllocationCallbacks* pAllocator)
{
VkSurfaceKHR object = 0;
VK_CHECK(createSurface(vki, instance, wsiType, nativeDisplay, nativeWindow, pAllocator, &object));
return Move<VkSurfaceKHR>(check<VkSurfaceKHR>(object), Deleter<VkSurfaceKHR>(vki, instance, pAllocator));
}
VkBool32 getPhysicalDeviceSurfaceSupport (const InstanceInterface& vki,
VkPhysicalDevice physicalDevice,
deUint32 queueFamilyIndex,
VkSurfaceKHR surface)
{
VkBool32 result = 0;
VK_CHECK(vki.getPhysicalDeviceSurfaceSupportKHR(physicalDevice, queueFamilyIndex, surface, &result));
return result;
}
VkSurfaceCapabilitiesKHR getPhysicalDeviceSurfaceCapabilities (const InstanceInterface& vki,
VkPhysicalDevice physicalDevice,
VkSurfaceKHR surface)
{
VkSurfaceCapabilitiesKHR capabilities;
deMemset(&capabilities, 0, sizeof(capabilities));
VK_CHECK(vki.getPhysicalDeviceSurfaceCapabilitiesKHR(physicalDevice, surface, &capabilities));
return capabilities;
}
std::vector<VkSurfaceFormatKHR> getPhysicalDeviceSurfaceFormats (const InstanceInterface& vki,
VkPhysicalDevice physicalDevice,
VkSurfaceKHR surface)
{
deUint32 numFormats = 0;
VK_CHECK(vki.getPhysicalDeviceSurfaceFormatsKHR(physicalDevice, surface, &numFormats, DE_NULL));
if (numFormats > 0)
{
std::vector<VkSurfaceFormatKHR> formats (numFormats);
VK_CHECK(vki.getPhysicalDeviceSurfaceFormatsKHR(physicalDevice, surface, &numFormats, &formats[0]));
return formats;
}
else
return std::vector<VkSurfaceFormatKHR>();
}
std::vector<VkPresentModeKHR> getPhysicalDeviceSurfacePresentModes (const InstanceInterface& vki,
VkPhysicalDevice physicalDevice,
VkSurfaceKHR surface)
{
deUint32 numModes = 0;
VK_CHECK(vki.getPhysicalDeviceSurfacePresentModesKHR(physicalDevice, surface, &numModes, DE_NULL));
if (numModes > 0)
{
std::vector<VkPresentModeKHR> modes (numModes);
VK_CHECK(vki.getPhysicalDeviceSurfacePresentModesKHR(physicalDevice, surface, &numModes, &modes[0]));
return modes;
}
else
return std::vector<VkPresentModeKHR>();
}
std::vector<VkImage> getSwapchainImages (const DeviceInterface& vkd,
VkDevice device,
VkSwapchainKHR swapchain)
{
deUint32 numImages = 0;
VK_CHECK(vkd.getSwapchainImagesKHR(device, swapchain, &numImages, DE_NULL));
if (numImages > 0)
{
std::vector<VkImage> images (numImages);
VK_CHECK(vkd.getSwapchainImagesKHR(device, swapchain, &numImages, &images[0]));
return images;
}
else
return std::vector<VkImage>();
}
} // wsi
} // vk