1 2 /* 3 * Copyright 2016 Google Inc. 4 * 5 * Use of this source code is governed by a BSD-style license that can be 6 * found in the LICENSE file. 7 */ 8 9 10 #include "vk/GrVkInterface.h" 11 #include "vk/GrVkUtil.h" 12 13 #include <X11/Xlib-xcb.h> 14 15 #include "WindowContextFactory_unix.h" 16 #include "../VulkanWindowContext.h" 17 18 namespace sk_app { 19 20 namespace window_context_factory { 21 22 WindowContext* NewVulkanForXlib(const XlibWindowInfo& info, const DisplayParams& displayParams) { 23 auto createVkSurface = [&info](VkInstance instance) -> VkSurfaceKHR { 24 static PFN_vkCreateXcbSurfaceKHR createXcbSurfaceKHR = nullptr; 25 if (!createXcbSurfaceKHR) { 26 createXcbSurfaceKHR = 27 (PFN_vkCreateXcbSurfaceKHR) vkGetInstanceProcAddr(instance, 28 "vkCreateXcbSurfaceKHR"); 29 } 30 31 VkSurfaceKHR surface; 32 33 VkXcbSurfaceCreateInfoKHR surfaceCreateInfo; 34 memset(&surfaceCreateInfo, 0, sizeof(VkXcbSurfaceCreateInfoKHR)); 35 surfaceCreateInfo.sType = VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR; 36 surfaceCreateInfo.pNext = nullptr; 37 surfaceCreateInfo.flags = 0; 38 surfaceCreateInfo.connection = XGetXCBConnection(info.fDisplay); 39 surfaceCreateInfo.window = info.fWindow; 40 41 VkResult res = createXcbSurfaceKHR(instance, &surfaceCreateInfo, nullptr, &surface); 42 if (VK_SUCCESS != res) { 43 return VK_NULL_HANDLE; 44 } 45 46 return surface; 47 }; 48 49 auto canPresent = [&info](VkInstance instance, VkPhysicalDevice physDev, 50 uint32_t queueFamilyIndex) { 51 static PFN_vkGetPhysicalDeviceXcbPresentationSupportKHR 52 getPhysicalDeviceXcbPresentationSupportKHR = nullptr; 53 if (!getPhysicalDeviceXcbPresentationSupportKHR) { 54 getPhysicalDeviceXcbPresentationSupportKHR = 55 (PFN_vkGetPhysicalDeviceXcbPresentationSupportKHR) 56 vkGetInstanceProcAddr(instance, 57 "vkGetPhysicalDeviceXcbPresentationSupportKHR"); 58 } 59 60 61 Display* display = info.fDisplay; 62 VisualID visualID = info.fVisualInfo->visualid; 63 VkBool32 check = getPhysicalDeviceXcbPresentationSupportKHR(physDev, 64 queueFamilyIndex, 65 XGetXCBConnection(display), 66 visualID); 67 return (VK_FALSE != check); 68 }; 69 WindowContext* context = new VulkanWindowContext(displayParams, createVkSurface, canPresent); 70 if (!context->isValid()) { 71 delete context; 72 return nullptr; 73 } 74 return context; 75 } 76 77 } // namespace VulkanWindowContextFactory 78 79 } // namespace sk_app 80