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