void VulkanWindow::InitializeSurface() { #if defined ( VK_USE_PLATFORM_WIN32_KHR ) VkWin32SurfaceCreateInfoKHR win32_surface_create_info_khr {}; win32_surface_create_info_khr.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR; win32_surface_create_info_khr.hwnd = reinterpret_cast<HWND> ( mWindowId ); win32_surface_create_info_khr.hinstance = reinterpret_cast<HINSTANCE> ( GetWindowLongPtr ( win32_surface_create_info_khr.hwnd, GWLP_HINSTANCE ) ); if ( VkResult result = vkCreateWin32SurfaceKHR ( mVulkanRenderer.GetInstance(), &win32_surface_create_info_khr, nullptr, &mVkSurfaceKHR ) ) { std::ostringstream stream; stream << "Call to vkCreateWin32SurfaceKHR failed: ( " << GetVulkanResultString ( result ) << " )"; throw std::runtime_error ( stream.str().c_str() ); } #elif defined( VK_USE_PLATFORM_XLIB_KHR ) VkXlibSurfaceCreateInfoKHR xlib_surface_create_info_khr {}; xlib_surface_create_info_khr.sType = VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR; xlib_surface_create_info_khr.dpy = XOpenDisplay ( nullptr ); xlib_surface_create_info_khr.window = reinterpret_cast<::Window> ( mWindowId ); if ( VkResult result = vkCreateXlibSurfaceKHR ( mVulkanRenderer.GetInstance(), &xlib_surface_create_info_khr, nullptr, &mVkSurfaceKHR ) ) { std::ostringstream stream; stream << "Call to vkCreateXlibSurfaceKHR failed: ( " << GetVulkanResultString ( result ) << " )"; throw std::runtime_error ( stream.str().c_str() ); } #endif VkBool32 wsi_supported = false; vkGetPhysicalDeviceSurfaceSupportKHR ( mVulkanRenderer.GetPhysicalDevice(), mVulkanRenderer.GetQueueFamilyIndex(), mVkSurfaceKHR, &wsi_supported ); if ( !wsi_supported ) { std::ostringstream stream; stream << "WSI not supported."; throw std::runtime_error ( stream.str().c_str() ); } }
VkSurfaceKHR VKTS_APIENTRY _wsiSurfaceCreate(const VkInstance instance, VKTS_NATIVE_DISPLAY nativeDisplay, VKTS_NATIVE_WINDOW nativeWindow) { if (!instance) { return VK_NULL_HANDLE; } // VkResult result; VkSurfaceKHR surface; if (g_hasXcb) { VkXcbSurfaceCreateInfoKHR xcbSurfaceCreateInfoKHR; memset(&xcbSurfaceCreateInfoKHR, 0, sizeof(VkXcbSurfaceCreateInfoKHR)); xcbSurfaceCreateInfoKHR.sType = VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR; xcbSurfaceCreateInfoKHR.flags = 0; xcbSurfaceCreateInfoKHR.connection = XGetXCBConnection(nativeDisplay); xcbSurfaceCreateInfoKHR.window = (xcb_window_t)nativeWindow; result = vkCreateXcbSurfaceKHR(instance, &xcbSurfaceCreateInfoKHR, nullptr, &surface); if (result != VK_SUCCESS) { return VK_NULL_HANDLE; } return surface; } if (g_hasXlib) { VkXlibSurfaceCreateInfoKHR xlibSurfaceCreateInfoKHR; memset(&xlibSurfaceCreateInfoKHR, 0, sizeof(VkXlibSurfaceCreateInfoKHR)); xlibSurfaceCreateInfoKHR.sType = VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR; xlibSurfaceCreateInfoKHR.flags = 0; xlibSurfaceCreateInfoKHR.dpy = nativeDisplay; xlibSurfaceCreateInfoKHR.window = nativeWindow; result = vkCreateXlibSurfaceKHR(instance, &xlibSurfaceCreateInfoKHR, nullptr, &surface); if (result != VK_SUCCESS) { return VK_NULL_HANDLE; } return surface; } return VK_NULL_HANDLE; }
bool VulkanCommon::CreatePresentationSurface() { #if defined(VK_USE_PLATFORM_WIN32_KHR) VkWin32SurfaceCreateInfoKHR surface_create_info = { VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR, // VkStructureType sType nullptr, // const void *pNext 0, // VkWin32SurfaceCreateFlagsKHR flags Window.Instance, // HINSTANCE hinstance Window.Handle // HWND hwnd }; if( vkCreateWin32SurfaceKHR( Vulkan.Instance, &surface_create_info, nullptr, &Vulkan.PresentationSurface ) == VK_SUCCESS ) { return true; } #elif defined(VK_USE_PLATFORM_XCB_KHR) VkXcbSurfaceCreateInfoKHR surface_create_info = { VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR, // VkStructureType sType nullptr, // const void *pNext 0, // VkXcbSurfaceCreateFlagsKHR flags Window.Connection, // xcb_connection_t* connection Window.Handle // xcb_window_t window }; if( vkCreateXcbSurfaceKHR( Vulkan.Instance, &surface_create_info, nullptr, &Vulkan.PresentationSurface ) == VK_SUCCESS ) { return true; } #elif defined(VK_USE_PLATFORM_XLIB_KHR) VkXlibSurfaceCreateInfoKHR surface_create_info = { VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR, // VkStructureType sType nullptr, // const void *pNext 0, // VkXlibSurfaceCreateFlagsKHR flags Window.DisplayPtr, // Display *dpy Window.Handle // Window window }; if( vkCreateXlibSurfaceKHR( Vulkan.Instance, &surface_create_info, nullptr, &Vulkan.PresentationSurface ) == VK_SUCCESS ) { return true; } #endif std::cout << "Could not create presentation surface!" << std::endl; return false; }
void VulkanContext::ReinitSurface(int width, int height) { if (surface_ != VK_NULL_HANDLE) { ILOG("Destroying Vulkan surface (%d, %d)", width_, height_); vkDestroySurfaceKHR(instance_, surface_, nullptr); surface_ = VK_NULL_HANDLE; } ILOG("Creating Vulkan surface (%d, %d)", width, height); switch (winsys_) { #ifdef _WIN32 case WINDOWSYSTEM_WIN32: { HINSTANCE connection = (HINSTANCE)winsysData1_; HWND window = (HWND)winsysData2_; RECT rc; GetClientRect(window, &rc); width = rc.right - rc.left; height = rc.bottom - rc.top; VkWin32SurfaceCreateInfoKHR win32{ VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR }; win32.flags = 0; win32.hwnd = window; win32.hinstance = connection; VkResult res = vkCreateWin32SurfaceKHR(instance_, &win32, nullptr, &surface_); assert(res == VK_SUCCESS); break; } #endif #if defined(__ANDROID__) case WINDOWSYSTEM_ANDROID: { ANativeWindow *wnd = (ANativeWindow *)winsysData1_; VkAndroidSurfaceCreateInfoKHR android{ VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR }; android.flags = 0; android.window = wnd; VkResult res = vkCreateAndroidSurfaceKHR(instance_, &android, nullptr, &surface_); assert(res == VK_SUCCESS); break; } #endif #if defined(VK_USE_PLATFORM_XLIB_KHR) case WINDOWSYSTEM_XLIB: { VkXlibSurfaceCreateInfoKHR xlib = { VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR }; xlib.flags = 0; xlib.dpy = (Display *)winsysData1_; xlib.window = (Window)winsysData2_; VkResult res = vkCreateXlibSurfaceKHR(instance_, &xlib, nullptr, &surface_); assert(res == VK_SUCCESS); break; } #endif #if defined(VK_USE_PLATFORM_XCB_KHR) case WINDOWSYSTEM_XCB: { VkXCBSurfaceCreateInfoKHR xcb = { VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR }; xcb.flags = 0; xcb.connection = (Connection *)winsysData1_; xcb.window = (Window)(uintptr_t)winsysData2_; VkResult res = vkCreateXcbSurfaceKHR(instance_, &xcb, nullptr, &surface_); assert(res == VK_SUCCESS); break; } #endif #if defined(VK_USE_PLATFORM_WAYLAND_KHR) case WINDOWSYSTEM_WAYLAND: { VkWaylandSurfaceCreateInfoKHR wayland = { VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR }; wayland.flags = 0; wayland.display = (wl_display *)winsysData1_; wayland.surface = (wl_surface *)winsysData2_; VkResult res = vkCreateWaylandSurfaceKHR(instance_, &wayland, nullptr, &surface_); assert(res == VK_SUCCESS); break; } #endif default: _assert_msg_(G3D, false, "Vulkan support for chosen window system not implemented"); break; } width_ = width; height_ = height; }
VkSurfaceKHR SwapChain::CreateVulkanSurface(VkInstance instance, void* hwnd) { #if defined(VK_USE_PLATFORM_WIN32_KHR) VkWin32SurfaceCreateInfoKHR surface_create_info = { VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR, // VkStructureType sType nullptr, // const void* pNext 0, // VkWin32SurfaceCreateFlagsKHR flags nullptr, // HINSTANCE hinstance reinterpret_cast<HWND>(hwnd) // HWND hwnd }; VkSurfaceKHR surface; VkResult res = vkCreateWin32SurfaceKHR(instance, &surface_create_info, nullptr, &surface); if (res != VK_SUCCESS) { LOG_VULKAN_ERROR(res, "vkCreateWin32SurfaceKHR failed: "); return VK_NULL_HANDLE; } return surface; #elif defined(VK_USE_PLATFORM_XLIB_KHR) // Assuming the display handles are compatible, or shared. This matches what we do in the // GL backend, but it's not ideal. Display* display = XOpenDisplay(nullptr); VkXlibSurfaceCreateInfoKHR surface_create_info = { VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR, // VkStructureType sType nullptr, // const void* pNext 0, // VkXlibSurfaceCreateFlagsKHR flags display, // Display* dpy reinterpret_cast<Window>(hwnd) // Window window }; VkSurfaceKHR surface; VkResult res = vkCreateXlibSurfaceKHR(instance, &surface_create_info, nullptr, &surface); if (res != VK_SUCCESS) { LOG_VULKAN_ERROR(res, "vkCreateXlibSurfaceKHR failed: "); return VK_NULL_HANDLE; } return surface; #elif defined(VK_USE_PLATFORM_XCB_KHR) // If we ever switch to using xcb, we should pass the display handle as well. Display* display = XOpenDisplay(nullptr); xcb_connection_t* connection = XGetXCBConnection(display); VkXcbSurfaceCreateInfoKHR surface_create_info = { VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR, // VkStructureType sType nullptr, // const void* pNext 0, // VkXcbSurfaceCreateFlagsKHR flags connection, // xcb_connection_t* connection static_cast<xcb_window_t>(reinterpret_cast<uintptr_t>(hwnd)) // xcb_window_t window }; VkSurfaceKHR surface; VkResult res = vkCreateXcbSurfaceKHR(instance, &surface_create_info, nullptr, &surface); if (res != VK_SUCCESS) { LOG_VULKAN_ERROR(res, "vkCreateXcbSurfaceKHR failed: "); return VK_NULL_HANDLE; } return surface; #elif defined(VK_USE_PLATFORM_ANDROID_KHR) VkAndroidSurfaceCreateInfoKHR surface_create_info = { VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR, // VkStructureType sType nullptr, // const void* pNext 0, // VkAndroidSurfaceCreateFlagsKHR flags reinterpret_cast<ANativeWindow*>(hwnd) // ANativeWindow* window }; VkSurfaceKHR surface; VkResult res = vkCreateAndroidSurfaceKHR(instance, &surface_create_info, nullptr, &surface); if (res != VK_SUCCESS) { LOG_VULKAN_ERROR(res, "vkCreateAndroidSurfaceKHR failed: "); return VK_NULL_HANDLE; } return surface; #else return VK_NULL_HANDLE; #endif }