101 lines
3.5 KiB
C++
101 lines
3.5 KiB
C++
|
// 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);
|
||
|
}
|