1cb93a386Sopenharmony_ci/*
2cb93a386Sopenharmony_ci * Copyright 2019 Google Inc.
3cb93a386Sopenharmony_ci *
4cb93a386Sopenharmony_ci * Use of this source code is governed by a BSD-style license that can be
5cb93a386Sopenharmony_ci * found in the LICENSE file.
6cb93a386Sopenharmony_ci */
7cb93a386Sopenharmony_ci
8cb93a386Sopenharmony_ci#include "tools/sk_app/DawnWindowContext.h"
9cb93a386Sopenharmony_ci#include "tools/sk_app/unix/WindowContextFactory_unix.h"
10cb93a386Sopenharmony_ci#include "dawn_native/DawnNative.h"
11cb93a386Sopenharmony_ci#include "dawn_native/VulkanBackend.h"
12cb93a386Sopenharmony_ci#include "src/ports/SkOSLibrary.h"
13cb93a386Sopenharmony_ci#include "tools/gpu/vk/VkTestUtils.h"
14cb93a386Sopenharmony_ci
15cb93a386Sopenharmony_ci#include <vulkan/vulkan.h>
16cb93a386Sopenharmony_ci#include <X11/Xlib-xcb.h>
17cb93a386Sopenharmony_ci
18cb93a386Sopenharmony_ciusing sk_app::window_context_factory::XlibWindowInfo;
19cb93a386Sopenharmony_ciusing sk_app::DisplayParams;
20cb93a386Sopenharmony_ciusing sk_app::DawnWindowContext;
21cb93a386Sopenharmony_ci
22cb93a386Sopenharmony_cinamespace sk_app {
23cb93a386Sopenharmony_ci
24cb93a386Sopenharmony_ciclass DawnVulkanWindowContext_xlib : public DawnWindowContext {
25cb93a386Sopenharmony_cipublic:
26cb93a386Sopenharmony_ci    DawnVulkanWindowContext_xlib(const XlibWindowInfo&, const DisplayParams&);
27cb93a386Sopenharmony_ci    ~DawnVulkanWindowContext_xlib() override {}
28cb93a386Sopenharmony_ci    wgpu::Device onInitializeContext() override;
29cb93a386Sopenharmony_ci    void onDestroyContext() override {}
30cb93a386Sopenharmony_ci    DawnSwapChainImplementation createSwapChainImplementation(
31cb93a386Sopenharmony_ci            int width, int height, const DisplayParams& params) override;
32cb93a386Sopenharmony_ci    void onSwapBuffers() override {}
33cb93a386Sopenharmony_ci
34cb93a386Sopenharmony_ciprivate:
35cb93a386Sopenharmony_ci    Display*     fDisplay;
36cb93a386Sopenharmony_ci    XWindow      fWindow;
37cb93a386Sopenharmony_ci    VkSurfaceKHR fVkSurface = nullptr;
38cb93a386Sopenharmony_ci
39cb93a386Sopenharmony_ci    using INHERITED = DawnWindowContext;
40cb93a386Sopenharmony_ci};
41cb93a386Sopenharmony_ci
42cb93a386Sopenharmony_ciDawnVulkanWindowContext_xlib::DawnVulkanWindowContext_xlib(const XlibWindowInfo& winInfo,
43cb93a386Sopenharmony_ci                                                           const DisplayParams& params)
44cb93a386Sopenharmony_ci        : INHERITED(params, wgpu::TextureFormat::BGRA8Unorm)
45cb93a386Sopenharmony_ci        , fDisplay(winInfo.fDisplay)
46cb93a386Sopenharmony_ci        , fWindow(winInfo.fWindow) {
47cb93a386Sopenharmony_ci    XWindow root;
48cb93a386Sopenharmony_ci    int x, y;
49cb93a386Sopenharmony_ci    unsigned int border_width, depth;
50cb93a386Sopenharmony_ci    unsigned int width, height;
51cb93a386Sopenharmony_ci    XGetGeometry(fDisplay, fWindow, &root, &x, &y, &width, &height, &border_width, &depth);
52cb93a386Sopenharmony_ci    this->initializeContext(width, height);
53cb93a386Sopenharmony_ci}
54cb93a386Sopenharmony_ci
55cb93a386Sopenharmony_ciDawnSwapChainImplementation DawnVulkanWindowContext_xlib::createSwapChainImplementation(
56cb93a386Sopenharmony_ci        int width, int height, const DisplayParams& params) {
57cb93a386Sopenharmony_ci    return dawn_native::vulkan::CreateNativeSwapChainImpl(fDevice.Get(), fVkSurface);
58cb93a386Sopenharmony_ci}
59cb93a386Sopenharmony_ci
60cb93a386Sopenharmony_ciwgpu::Device DawnVulkanWindowContext_xlib::onInitializeContext() {
61cb93a386Sopenharmony_ci    wgpu::Device device = this->createDevice(dawn_native::BackendType::Vulkan);
62cb93a386Sopenharmony_ci    if (!device) {
63cb93a386Sopenharmony_ci        return nullptr;
64cb93a386Sopenharmony_ci    }
65cb93a386Sopenharmony_ci
66cb93a386Sopenharmony_ci    void *vkLib = SkLoadDynamicLibrary("libvulkan.so.1");
67cb93a386Sopenharmony_ci    if (!vkLib) {
68cb93a386Sopenharmony_ci        return nullptr;
69cb93a386Sopenharmony_ci    }
70cb93a386Sopenharmony_ci    VkInstance instance = dawn_native::vulkan::GetInstance(device.Get());
71cb93a386Sopenharmony_ci    if (!instance) {
72cb93a386Sopenharmony_ci        return nullptr;
73cb93a386Sopenharmony_ci    }
74cb93a386Sopenharmony_ci    auto createXcbSurfaceKHR =
75cb93a386Sopenharmony_ci        reinterpret_cast<PFN_vkCreateXcbSurfaceKHR>(SkGetProcedureAddress(vkLib,
76cb93a386Sopenharmony_ci                                                                        "vkCreateXcbSurfaceKHR"));
77cb93a386Sopenharmony_ci    if (!createXcbSurfaceKHR) {
78cb93a386Sopenharmony_ci        printf("couldn't get extensions :(\n");
79cb93a386Sopenharmony_ci        return nullptr;
80cb93a386Sopenharmony_ci    }
81cb93a386Sopenharmony_ci
82cb93a386Sopenharmony_ci    VkXcbSurfaceCreateInfoKHR surfaceCreateInfo;
83cb93a386Sopenharmony_ci    memset(&surfaceCreateInfo, 0, sizeof(VkXcbSurfaceCreateInfoKHR));
84cb93a386Sopenharmony_ci    surfaceCreateInfo.sType = VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR;
85cb93a386Sopenharmony_ci    surfaceCreateInfo.pNext = nullptr;
86cb93a386Sopenharmony_ci    surfaceCreateInfo.flags = 0;
87cb93a386Sopenharmony_ci    surfaceCreateInfo.connection = XGetXCBConnection(fDisplay);
88cb93a386Sopenharmony_ci    surfaceCreateInfo.window = fWindow;
89cb93a386Sopenharmony_ci
90cb93a386Sopenharmony_ci    createXcbSurfaceKHR(instance, &surfaceCreateInfo, nullptr, &fVkSurface);
91cb93a386Sopenharmony_ci    return device;
92cb93a386Sopenharmony_ci}
93cb93a386Sopenharmony_ci
94cb93a386Sopenharmony_cinamespace window_context_factory {
95cb93a386Sopenharmony_ci
96cb93a386Sopenharmony_cistd::unique_ptr<WindowContext> MakeDawnVulkanForXlib(const XlibWindowInfo& winInfo,
97cb93a386Sopenharmony_ci                                                     const DisplayParams& params) {
98cb93a386Sopenharmony_ci    std::unique_ptr<WindowContext> ctx(new DawnVulkanWindowContext_xlib(winInfo, params));
99cb93a386Sopenharmony_ci    if (!ctx->isValid()) {
100cb93a386Sopenharmony_ci        return nullptr;
101cb93a386Sopenharmony_ci    }
102cb93a386Sopenharmony_ci    return ctx;
103cb93a386Sopenharmony_ci}
104cb93a386Sopenharmony_ci
105cb93a386Sopenharmony_ci}
106cb93a386Sopenharmony_ci
107cb93a386Sopenharmony_ci}  // namespace sk_app
108