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