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 "vk/VkTestUtils.h" 14 15 #include <X11/Xlib-xcb.h> 16 17 #include "WindowContextFactory_unix.h" 18 #include "../VulkanWindowContext.h" 19 20 namespace sk_app { 21 22 namespace window_context_factory { 23 24 WindowContext* NewVulkanForXlib(const XlibWindowInfo& info, const DisplayParams& displayParams) { 25 PFN_vkGetInstanceProcAddr instProc; 26 PFN_vkGetDeviceProcAddr devProc; 27 if (!sk_gpu_test::LoadVkLibraryAndGetProcAddrFuncs(&instProc, &devProc)) { 28 return nullptr; 29 } 30 31 auto createVkSurface = [&info, instProc](VkInstance instance) -> VkSurfaceKHR { 32 static PFN_vkCreateXcbSurfaceKHR createXcbSurfaceKHR = nullptr; 33 if (!createXcbSurfaceKHR) { 34 createXcbSurfaceKHR = 35 (PFN_vkCreateXcbSurfaceKHR) instProc(instance, "vkCreateXcbSurfaceKHR"); 36 } 37 38 VkSurfaceKHR surface; 39 40 VkXcbSurfaceCreateInfoKHR surfaceCreateInfo; 41 memset(&surfaceCreateInfo, 0, sizeof(VkXcbSurfaceCreateInfoKHR)); 42 surfaceCreateInfo.sType = VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR; 43 surfaceCreateInfo.pNext = nullptr; 44 surfaceCreateInfo.flags = 0; 45 surfaceCreateInfo.connection = XGetXCBConnection(info.fDisplay); 46 surfaceCreateInfo.window = info.fWindow; 47 48 VkResult res = createXcbSurfaceKHR(instance, &surfaceCreateInfo, nullptr, &surface); 49 if (VK_SUCCESS != res) { 50 return VK_NULL_HANDLE; 51 } 52 53 return surface; 54 }; 55 56 auto canPresent = [&info, instProc](VkInstance instance, VkPhysicalDevice physDev, 57 uint32_t queueFamilyIndex) { 58 static PFN_vkGetPhysicalDeviceXcbPresentationSupportKHR 59 getPhysicalDeviceXcbPresentationSupportKHR = nullptr; 60 if (!getPhysicalDeviceXcbPresentationSupportKHR) { 61 getPhysicalDeviceXcbPresentationSupportKHR = 62 (PFN_vkGetPhysicalDeviceXcbPresentationSupportKHR) 63 instProc(instance, "vkGetPhysicalDeviceXcbPresentationSupportKHR"); 64 } 65 66 67 Display* display = info.fDisplay; 68 VisualID visualID = info.fVisualInfo->visualid; 69 VkBool32 check = getPhysicalDeviceXcbPresentationSupportKHR(physDev, 70 queueFamilyIndex, 71 XGetXCBConnection(display), 72 visualID); 73 return (VK_FALSE != check); 74 }; 75 WindowContext* context = new VulkanWindowContext(displayParams, createVkSurface, canPresent, 76 instProc, devProc); 77 if (!context->isValid()) { 78 delete context; 79 return nullptr; 80 } 81 return context; 82 } 83 84 } // namespace VulkanWindowContextFactory 85 86 } // namespace sk_app 87