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