| // Copyright 2019 The Dawn Authors |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| |
| // A mock GLFW implementation that supports Fuchsia, but only implements |
| // the functions called from Dawn. |
| |
| // NOTE: This must be included before GLFW/glfw3.h because the latter will |
| // include <vulkan/vulkan.h> and "common/vulkan_platform.h" wants to be |
| // the first header to do so for sanity reasons (e.g. undefining weird |
| // macros on Windows and Linux). |
| // clang-format off |
| #include "common/vulkan_platform.h" |
| #include "common/Assert.h" |
| #include <GLFW/glfw3.h> |
| // clang-format on |
| |
| #include <dlfcn.h> |
| |
| int glfwInit(void) { |
| return GLFW_TRUE; |
| } |
| |
| void glfwDefaultWindowHints(void) { |
| } |
| |
| void glfwWindowHint(int hint, int value) { |
| DAWN_UNUSED(hint); |
| DAWN_UNUSED(value); |
| } |
| |
| struct GLFWwindow { |
| PFN_vkGetInstanceProcAddr GetInstanceProcAddress = nullptr; |
| void* vulkan_loader = nullptr; |
| |
| GLFWwindow() { |
| vulkan_loader = ::dlopen("libvulkan.so", RTLD_NOW); |
| ASSERT(vulkan_loader != nullptr); |
| GetInstanceProcAddress = reinterpret_cast<PFN_vkGetInstanceProcAddr>( |
| dlsym(vulkan_loader, "vkGetInstanceProcAddr")); |
| ASSERT(GetInstanceProcAddress != nullptr); |
| } |
| |
| ~GLFWwindow() { |
| if (vulkan_loader) { |
| ::dlclose(vulkan_loader); |
| } |
| vulkan_loader = nullptr; |
| } |
| }; |
| |
| GLFWwindow* glfwCreateWindow(int width, |
| int height, |
| const char* title, |
| GLFWmonitor* monitor, |
| GLFWwindow* share) { |
| ASSERT(monitor == nullptr); |
| ASSERT(share == nullptr); |
| DAWN_UNUSED(width); |
| DAWN_UNUSED(height); |
| DAWN_UNUSED(title); |
| return new GLFWwindow(); |
| } |
| |
| VkResult glfwCreateWindowSurface(VkInstance instance, |
| GLFWwindow* window, |
| const VkAllocationCallbacks* allocator, |
| VkSurfaceKHR* surface) { |
| // IMPORTANT: This assumes that the VkInstance was created with a Fuchsia |
| // swapchain layer enabled, as well as the corresponding extension that |
| // is queried here to perform the surface creation. Dawn should do all |
| // required steps in VulkanInfo.cpp, VulkanFunctions.cpp and BackendVk.cpp. |
| |
| auto vkCreateImagePipeSurfaceFUCHSIA = reinterpret_cast<PFN_vkCreateImagePipeSurfaceFUCHSIA>( |
| window->GetInstanceProcAddress(instance, "vkCreateImagePipeSurfaceFUCHSIA")); |
| ASSERT(vkCreateImagePipeSurfaceFUCHSIA != nullptr); |
| if (!vkCreateImagePipeSurfaceFUCHSIA) { |
| *surface = VK_NULL_HANDLE; |
| return VK_ERROR_FEATURE_NOT_PRESENT; |
| } |
| |
| const struct VkImagePipeSurfaceCreateInfoFUCHSIA create_info = { |
| VK_STRUCTURE_TYPE_IMAGEPIPE_SURFACE_CREATE_INFO_FUCHSIA, |
| nullptr, // pNext |
| 0, // flags, ignored for now |
| ZX_HANDLE_INVALID, // imagePipeHandle, a null handle matches the framebuffer. |
| }; |
| |
| return vkCreateImagePipeSurfaceFUCHSIA(instance, &create_info, nullptr, surface); |
| } |