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
NewVulkanForXlib(const XlibWindowInfo & info,const DisplayParams & displayParams)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