1 // Copyright 2019 The Dawn Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 // A mock GLFW implementation that supports Fuchsia, but only implements
16 // the functions called from Dawn.
17
18 // NOTE: This must be included before GLFW/glfw3.h because the latter will
19 // include <vulkan/vulkan.h> and "common/vulkan_platform.h" wants to be
20 // the first header to do so for sanity reasons (e.g. undefining weird
21 // macros on Windows and Linux).
22 // clang-format off
23 #include "common/vulkan_platform.h"
24 #include "common/Assert.h"
25 #include <GLFW/glfw3.h>
26 // clang-format on
27
28 #include <dlfcn.h>
29
glfwInit(void)30 int glfwInit(void) {
31 return GLFW_TRUE;
32 }
33
glfwDefaultWindowHints(void)34 void glfwDefaultWindowHints(void) {
35 }
36
glfwWindowHint(int hint,int value)37 void glfwWindowHint(int hint, int value) {
38 DAWN_UNUSED(hint);
39 DAWN_UNUSED(value);
40 }
41
42 struct GLFWwindow {
43 PFN_vkGetInstanceProcAddr GetInstanceProcAddress = nullptr;
44 void* vulkan_loader = nullptr;
45
GLFWwindowGLFWwindow46 GLFWwindow() {
47 vulkan_loader = ::dlopen("libvulkan.so", RTLD_NOW);
48 ASSERT(vulkan_loader != nullptr);
49 GetInstanceProcAddress = reinterpret_cast<PFN_vkGetInstanceProcAddr>(
50 dlsym(vulkan_loader, "vkGetInstanceProcAddr"));
51 ASSERT(GetInstanceProcAddress != nullptr);
52 }
53
~GLFWwindowGLFWwindow54 ~GLFWwindow() {
55 if (vulkan_loader) {
56 ::dlclose(vulkan_loader);
57 }
58 vulkan_loader = nullptr;
59 }
60 };
61
glfwCreateWindow(int width,int height,const char * title,GLFWmonitor * monitor,GLFWwindow * share)62 GLFWwindow* glfwCreateWindow(int width,
63 int height,
64 const char* title,
65 GLFWmonitor* monitor,
66 GLFWwindow* share) {
67 ASSERT(monitor == nullptr);
68 ASSERT(share == nullptr);
69 DAWN_UNUSED(width);
70 DAWN_UNUSED(height);
71 DAWN_UNUSED(title);
72 return new GLFWwindow();
73 }
74
glfwCreateWindowSurface(VkInstance instance,GLFWwindow * window,const VkAllocationCallbacks * allocator,VkSurfaceKHR * surface)75 VkResult glfwCreateWindowSurface(VkInstance instance,
76 GLFWwindow* window,
77 const VkAllocationCallbacks* allocator,
78 VkSurfaceKHR* surface) {
79 // IMPORTANT: This assumes that the VkInstance was created with a Fuchsia
80 // swapchain layer enabled, as well as the corresponding extension that
81 // is queried here to perform the surface creation. Dawn should do all
82 // required steps in VulkanInfo.cpp, VulkanFunctions.cpp and BackendVk.cpp.
83
84 auto vkCreateImagePipeSurfaceFUCHSIA = reinterpret_cast<PFN_vkCreateImagePipeSurfaceFUCHSIA>(
85 window->GetInstanceProcAddress(instance, "vkCreateImagePipeSurfaceFUCHSIA"));
86 ASSERT(vkCreateImagePipeSurfaceFUCHSIA != nullptr);
87 if (!vkCreateImagePipeSurfaceFUCHSIA) {
88 *surface = VK_NULL_HANDLE;
89 return VK_ERROR_FEATURE_NOT_PRESENT;
90 }
91
92 const struct VkImagePipeSurfaceCreateInfoFUCHSIA create_info = {
93 VK_STRUCTURE_TYPE_IMAGEPIPE_SURFACE_CREATE_INFO_FUCHSIA,
94 nullptr, // pNext
95 0, // flags, ignored for now
96 ZX_HANDLE_INVALID, // imagePipeHandle, a null handle matches the framebuffer.
97 };
98
99 return vkCreateImagePipeSurfaceFUCHSIA(instance, &create_info, nullptr, surface);
100 }
101