Add Fuchsia support

Fuchsia (fuchsia.dev) builds with GN and uses a loader service to load
the ICD into the application's address space.

ANGLE builds have been verified.
Reemoves unused variable is_icd.
This commit is contained in:
Craig Stout
2020-09-30 22:59:30 -04:00
committed by Lenny Komow
parent b0fbde85c9
commit ff8d9992c9
7 changed files with 444 additions and 13 deletions
+74 -7
View File
@@ -13,11 +13,13 @@
# See the License for the specific language governing permissions and
# limitations under the License.
import("//build_overrides/build.gni")
import("//build_overrides/vulkan_loader.gni")
# Fuchsia has non-upstream changes to the vulkan loader, so we don't want
# to build it from upstream sources.
assert(!is_fuchsia)
if (is_fuchsia) {
import("//build/cpp/sdk_shared_library.gni")
import("//build/sdk/sdk_documentation.gni")
}
if (!is_android) {
vulkan_undefine_configs = []
@@ -32,7 +34,20 @@ if (is_win) {
config("vulkan_internal_config") {
defines = [ "VULKAN_NON_CMAKE_BUILD" ]
if (is_clang || !is_win) {
cflags = [ "-Wno-unused-function" ]
cflags = [
"-Wno-conversion",
"-Wno-extra-semi",
"-Wno-sign-compare",
"-Wno-unreachable-code",
"-Wno-unused-function",
"-Wno-unused-variable",
]
}
if (is_fuchsia) {
defines += [
"SYSCONFDIR=\"/config\"",
"EXTRASYSCONFDIR=\"/pkg/data\"",
]
}
if (is_linux || is_mac) {
defines += [
@@ -66,7 +81,9 @@ config("vulkan_loader_config") {
}
if (!is_android) {
if (vulkan_loader_shared) {
if (is_fuchsia) {
library_type = "sdk_shared_library"
} else if (vulkan_loader_shared) {
library_type = "shared_library"
} else {
library_type = "static_library"
@@ -133,11 +150,29 @@ if (!is_android) {
frameworks = [ "CoreFoundation.framework" ]
}
public_deps = [ "$vulkan_headers_dir:vulkan_headers" ]
configs -= [ "//build/config/compiler:chromium_code" ]
configs += [ "//build/config/compiler:no_chromium_code" ]
if (build_with_chromium) {
configs -= [ "//build/config/compiler:chromium_code" ]
configs += [ "//build/config/compiler:no_chromium_code" ]
}
configs += [ ":vulkan_internal_config" ]
public_configs = [ ":vulkan_loader_config" ]
configs -= vulkan_undefine_configs
if (is_fuchsia) {
output_name = "vulkan"
category = "partner"
# The Vulkan loader's interface is defined by standard Khronos vulkan headers
# which can be obtained separately from the loader implementation itself.
no_headers = true
deps = [
":dlopen_fuchsia",
"//sdk/lib/fdio",
]
runtime_deps = [ "//sdk/lib/fdio:fdio_sdk" ]
}
}
if (is_linux && vulkan_loader_shared) {
@@ -149,3 +184,35 @@ if (!is_android) {
}
}
}
if (is_fuchsia) {
config("fuchsia_config") {
include_dirs = [ "fuchsia" ]
}
source_set("dlopen_fuchsia") {
public_configs = [ ":fuchsia_config" ]
sources = [
"fuchsia/dlopen_fuchsia.c",
"fuchsia/dlopen_fuchsia.h",
]
deps = [
"//sdk/fidl/fuchsia.vulkan.loader:fuchsia.vulkan.loader_c_client",
"//sdk/lib/fdio",
]
}
sdk_documentation("vulkan_license") {
name = "vulkan_license"
category = "public"
files = [
{
source = "LICENSE.txt"
dest = "LICENSE.vulkan"
},
]
}
}
+10
View File
@@ -10,6 +10,7 @@ Instructions for building this repository on Linux, Windows, and MacOS.
1. [Windows Build](#building-on-windows)
1. [Linux Build](#building-on-linux)
1. [MacOS build](#building-on-macos)
1. [Fuchsia build](#building-on-fuchsia)
## Contributing to the Repository
@@ -677,3 +678,12 @@ To run the loader test script, change to the `build/tests` directory in your
Vulkan-Loader repository, and run:
./vk_loader_validation_tests
## Building on Fuchsia
Fuchsia uses the project's GN build system to integrate with the Fuchsia platform build.
### SDK Symbols
The Vulkan Loader is a component of the Fuchsia SDK, so it must explicitly declare its exported symbols in
the file vulkan.symbols.api; see [SDK](https://fuchsia.dev/fuchsia-src/development/sdk).
+87
View File
@@ -0,0 +1,87 @@
/*
*
* Copyright (c) 2018 Google Inc.
*
* 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.
*
*/
#include "dlopen_fuchsia.h"
#include <fcntl.h>
#include <fuchsia/vulkan/loader/c/fidl.h>
#include <lib/fdio/io.h>
#include <lib/fdio/directory.h>
#include <stdio.h>
#include <string.h>
#include <threads.h>
#include <zircon/dlfcn.h>
#include <zircon/syscalls.h>
static char g_error[128] = {};
const char *dlerror_fuchsia(void) { return g_error; }
static zx_handle_t vulkan_loader_svc = ZX_HANDLE_INVALID;
void connect_to_vulkan_loader_svc(void) {
zx_handle_t svc1, svc2;
if (zx_channel_create(0, &svc1, &svc2) != ZX_OK) return;
if (fdio_service_connect("/svc/" fuchsia_vulkan_loader_Loader_Name, svc1) != ZX_OK) {
zx_handle_close(svc2);
return;
}
vulkan_loader_svc = svc2;
}
static once_flag svc_connect_once_flag = ONCE_FLAG_INIT;
void *dlopen_fuchsia(const char *name, int mode, bool driver) {
// First try to just dlopen() from our own namespace. This will succeed for
// any layers that are packaged with the application, but will fail for
// client drivers loaded from the system.
void *result;
if (!driver) {
result = dlopen(name, mode);
if (result != NULL) return result;
}
// If we couldn't find the library in our own namespace, connect to the
// loader service to request this library.
call_once(&svc_connect_once_flag, connect_to_vulkan_loader_svc);
if (vulkan_loader_svc == ZX_HANDLE_INVALID) {
snprintf(g_error, sizeof(g_error), "libvulkan.so:dlopen_fuchsia: no connection to loader svc\n");
return NULL;
}
zx_handle_t vmo = ZX_HANDLE_INVALID;
zx_status_t st = fuchsia_vulkan_loader_LoaderGet(vulkan_loader_svc, name, strlen(name), &vmo);
if (st != ZX_OK) {
snprintf(g_error, sizeof(g_error), "libvulkan.so:dlopen_fuchsia: Get() failed: %d\n", st);
return NULL;
}
if (vmo == ZX_HANDLE_INVALID) {
snprintf(g_error, sizeof(g_error), "libvulkan.so:dlopen_fuchsia: Get() returned invalid vmo\n");
return NULL;
}
result = dlopen_vmo(vmo, mode);
zx_handle_close(vmo);
if (!result) {
snprintf(g_error, sizeof(g_error), "%s", dlerror());
}
return result;
}
+29
View File
@@ -0,0 +1,29 @@
/*
*
* Copyright (c) 2018 Google Inc.
*
* 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.
*
*/
#pragma once
#include <zircon/compiler.h>
#include <stdbool.h>
__BEGIN_CDECLS
// If not |driver|, then the request is to load a layer.
void *dlopen_fuchsia(const char *name, int mode, bool driver);
const char *dlerror_fuchsia(void);
__END_CDECLS
+9 -2
View File
@@ -253,7 +253,7 @@ void *loader_device_heap_realloc(const struct loader_device *device, void *pMemo
}
// Environment variables
#if defined(__linux__) || defined(__APPLE__)
#if defined(__linux__) || defined(__APPLE__) || defined(__Fuchsia__)
static inline bool IsHighIntegrity() {
return geteuid() != getuid() || getegid() != getgid();
@@ -277,6 +277,8 @@ static inline char *loader_secure_getenv(const char *name, const struct loader_i
// This algorithm is derived from glibc code that sets an internal
// variable (__libc_enable_secure) if the process is running under setuid or setgid.
return IsHighIntegrity() ? NULL : loader_getenv(name, inst);
#elif defined(__Fuchsia__)
return loader_getenv(name, inst);
#else
// Linux
#if defined(HAVE_SECURE_GETENV) && !defined(USE_UNSAFE_FILE_SEARCH)
@@ -2317,7 +2319,11 @@ static VkResult loader_scanned_icd_add(const struct loader_instance *inst, struc
// TODO implement smarter opening/closing of libraries. For now this
// function leaves libraries open and the scanned_icd_clear closes them
#if defined(__Fuchsia__)
handle = loader_platform_open_driver(filename);
#else
handle = loader_platform_open_library(filename);
#endif
if (NULL == handle) {
loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, loader_platform_open_library_error(filename));
goto out;
@@ -3955,12 +3961,14 @@ static VkResult ReadDataFilesInSearchPaths(const struct loader_instance *inst, e
if (xdgdatadirs == NULL) {
xdgdata_alloc = false;
}
#if !defined(__Fuchsia__)
if (xdgconfdirs == NULL || xdgconfdirs[0] == '\0') {
xdgconfdirs = FALLBACK_CONFIG_DIRS;
}
if (xdgdatadirs == NULL || xdgdatadirs[0] == '\0') {
xdgdatadirs = FALLBACK_DATA_DIRS;
}
#endif
// Only use HOME if XDG_DATA_HOME is not present on the system
if (NULL == xdgdatahome) {
@@ -4308,7 +4316,6 @@ out:
static VkResult ReadDataFilesInRegistry(const struct loader_instance *inst, enum loader_data_files_type data_file_type,
bool warn_if_not_present, char *registry_location, struct loader_data_files *out_files) {
VkResult vk_result = VK_SUCCESS;
bool is_icd = (data_file_type == LOADER_DATA_FILE_MANIFEST_ICD);
char *search_path = NULL;
// These calls look at the PNP/Device section of the registry.
+28 -4
View File
@@ -28,10 +28,14 @@
#include <winsock2.h>
#endif // _WIN32
#if defined(__Fuchsia__)
#include "dlopen_fuchsia.h"
#endif // defined(__Fuchsia__)
#include "vulkan/vk_platform.h"
#include "vulkan/vk_sdk_platform.h"
#if defined(__linux__) || defined(__APPLE__)
#if defined(__linux__) || defined(__APPLE__) || defined(__Fuchsia__)
/* Linux-specific common code: */
// Headers:
@@ -118,6 +122,8 @@ static inline char *loader_platform_executable_path(char *buffer, size_t size) {
buffer[ret] = '\0';
return buffer;
}
#elif defined(__Fuchsia__)
static inline char *loader_platform_executable_path(char *buffer, size_t size) { return NULL; }
#endif // defined (__APPLE__)
// Compatability with compilers that don't support __has_feature
@@ -131,14 +137,32 @@ static inline char *loader_platform_executable_path(char *buffer, size_t size) {
// Dynamic Loading of libraries:
typedef void *loader_platform_dl_handle;
static inline loader_platform_dl_handle loader_platform_open_library(const char *libPath) {
// When loading the library, we use RTLD_LAZY so that not all symbols have to be
// resolved at this time (which improves performance). Note that if not all symbols
// can be resolved, this could cause crashes later. Use the LD_BIND_NOW environment
// variable to force all symbols to be resolved here.
return dlopen(libPath, RTLD_LAZY | RTLD_LOCAL);
#define LOADER_DLOPEN_MODE (RTLD_LAZY | RTLD_LOCAL)
#if defined(__Fuchsia__)
static inline loader_platform_dl_handle loader_platform_open_driver(const char *libPath) {
return dlopen_fuchsia(libPath, LOADER_DLOPEN_MODE, true);
}
static inline loader_platform_dl_handle loader_platform_open_library(const char *libPath) {
return dlopen_fuchsia(libPath, LOADER_DLOPEN_MODE, false);
}
#else
static inline loader_platform_dl_handle loader_platform_open_library(const char *libPath) {
return dlopen(libPath, LOADER_DLOPEN_MODE);
}
#endif
static inline const char *loader_platform_open_library_error(const char *libPath) {
#ifdef __Fuchsia__
return dlerror_fuchsia();
#else
return dlerror();
#endif
}
static inline const char *loader_platform_open_library_error(const char *libPath) { return dlerror(); }
static inline void loader_platform_close_library(loader_platform_dl_handle library) { dlclose(library); }
static inline void *loader_platform_get_proc_address(loader_platform_dl_handle library, const char *name) {
assert(library);
+207
View File
@@ -0,0 +1,207 @@
vkAcquireNextImage2KHR
vkAcquireNextImageKHR
vkAllocateCommandBuffers
vkAllocateDescriptorSets
vkAllocateMemory
vkBeginCommandBuffer
vkBindBufferMemory
vkBindBufferMemory2
vkBindImageMemory
vkBindImageMemory2
vkCmdBeginQuery
vkCmdBeginRenderPass
vkCmdBeginRenderPass2
vkCmdBindDescriptorSets
vkCmdBindIndexBuffer
vkCmdBindPipeline
vkCmdBindVertexBuffers
vkCmdBlitImage
vkCmdClearAttachments
vkCmdClearColorImage
vkCmdClearDepthStencilImage
vkCmdCopyBuffer
vkCmdCopyBufferToImage
vkCmdCopyImage
vkCmdCopyImageToBuffer
vkCmdCopyQueryPoolResults
vkCmdDispatch
vkCmdDispatchBase
vkCmdDispatchIndirect
vkCmdDraw
vkCmdDrawIndexed
vkCmdDrawIndexedIndirect
vkCmdDrawIndexedIndirectCount
vkCmdDrawIndirect
vkCmdDrawIndirectCount
vkCmdEndQuery
vkCmdEndRenderPass
vkCmdEndRenderPass2
vkCmdExecuteCommands
vkCmdFillBuffer
vkCmdNextSubpass
vkCmdNextSubpass2
vkCmdPipelineBarrier
vkCmdPushConstants
vkCmdResetEvent
vkCmdResetQueryPool
vkCmdResolveImage
vkCmdSetBlendConstants
vkCmdSetDepthBias
vkCmdSetDepthBounds
vkCmdSetDeviceMask
vkCmdSetEvent
vkCmdSetLineWidth
vkCmdSetScissor
vkCmdSetStencilCompareMask
vkCmdSetStencilReference
vkCmdSetStencilWriteMask
vkCmdSetViewport
vkCmdUpdateBuffer
vkCmdWaitEvents
vkCmdWriteTimestamp
vkCreateBuffer
vkCreateBufferView
vkCreateCommandPool
vkCreateComputePipelines
vkCreateDescriptorPool
vkCreateDescriptorSetLayout
vkCreateDescriptorUpdateTemplate
vkCreateDevice
vkCreateDisplayModeKHR
vkCreateDisplayPlaneSurfaceKHR
vkCreateEvent
vkCreateFence
vkCreateFramebuffer
vkCreateGraphicsPipelines
vkCreateImage
vkCreateImagePipeSurfaceFUCHSIA
vkCreateImageView
vkCreateInstance
vkCreatePipelineCache
vkCreatePipelineLayout
vkCreateQueryPool
vkCreateRenderPass
vkCreateRenderPass2
vkCreateSampler
vkCreateSamplerYcbcrConversion
vkCreateSemaphore
vkCreateShaderModule
vkCreateSharedSwapchainsKHR
vkCreateSwapchainKHR
vkDestroyBuffer
vkDestroyBufferView
vkDestroyCommandPool
vkDestroyDescriptorPool
vkDestroyDescriptorSetLayout
vkDestroyDescriptorUpdateTemplate
vkDestroyDevice
vkDestroyEvent
vkDestroyFence
vkDestroyFramebuffer
vkDestroyImage
vkDestroyImageView
vkDestroyInstance
vkDestroyPipeline
vkDestroyPipelineCache
vkDestroyPipelineLayout
vkDestroyQueryPool
vkDestroyRenderPass
vkDestroySampler
vkDestroySamplerYcbcrConversion
vkDestroySemaphore
vkDestroyShaderModule
vkDestroySurfaceKHR
vkDestroySwapchainKHR
vkDeviceWaitIdle
vkEndCommandBuffer
vkEnumerateDeviceExtensionProperties
vkEnumerateDeviceLayerProperties
vkEnumerateInstanceExtensionProperties
vkEnumerateInstanceLayerProperties
vkEnumerateInstanceVersion
vkEnumeratePhysicalDeviceGroups
vkEnumeratePhysicalDevices
vkFlushMappedMemoryRanges
vkFreeCommandBuffers
vkFreeDescriptorSets
vkFreeMemory
vkGetBufferDeviceAddress
vkGetBufferMemoryRequirements
vkGetBufferMemoryRequirements2
vkGetBufferOpaqueCaptureAddress
vkGetDescriptorSetLayoutSupport
vkGetDeviceGroupPeerMemoryFeatures
vkGetDeviceGroupPresentCapabilitiesKHR
vkGetDeviceGroupSurfacePresentModesKHR
vkGetDeviceMemoryCommitment
vkGetDeviceMemoryOpaqueCaptureAddress
vkGetDeviceProcAddr
vkGetDeviceQueue
vkGetDeviceQueue2
vkGetDisplayModeProperties2KHR
vkGetDisplayModePropertiesKHR
vkGetDisplayPlaneCapabilities2KHR
vkGetDisplayPlaneCapabilitiesKHR
vkGetDisplayPlaneSupportedDisplaysKHR
vkGetEventStatus
vkGetFenceStatus
vkGetImageMemoryRequirements
vkGetImageMemoryRequirements2
vkGetImageSparseMemoryRequirements
vkGetImageSparseMemoryRequirements2
vkGetImageSubresourceLayout
vkGetInstanceProcAddr
vkGetPhysicalDeviceDisplayPlaneProperties2KHR
vkGetPhysicalDeviceDisplayPlanePropertiesKHR
vkGetPhysicalDeviceDisplayProperties2KHR
vkGetPhysicalDeviceDisplayPropertiesKHR
vkGetPhysicalDeviceExternalBufferProperties
vkGetPhysicalDeviceExternalFenceProperties
vkGetPhysicalDeviceExternalSemaphoreProperties
vkGetPhysicalDeviceFeatures
vkGetPhysicalDeviceFeatures2
vkGetPhysicalDeviceFormatProperties
vkGetPhysicalDeviceFormatProperties2
vkGetPhysicalDeviceImageFormatProperties
vkGetPhysicalDeviceImageFormatProperties2
vkGetPhysicalDeviceMemoryProperties
vkGetPhysicalDeviceMemoryProperties2
vkGetPhysicalDevicePresentRectanglesKHR
vkGetPhysicalDeviceProperties
vkGetPhysicalDeviceProperties2
vkGetPhysicalDeviceQueueFamilyProperties
vkGetPhysicalDeviceQueueFamilyProperties2
vkGetPhysicalDeviceSparseImageFormatProperties
vkGetPhysicalDeviceSparseImageFormatProperties2
vkGetPhysicalDeviceSurfaceCapabilities2KHR
vkGetPhysicalDeviceSurfaceCapabilitiesKHR
vkGetPhysicalDeviceSurfaceFormats2KHR
vkGetPhysicalDeviceSurfaceFormatsKHR
vkGetPhysicalDeviceSurfacePresentModesKHR
vkGetPhysicalDeviceSurfaceSupportKHR
vkGetPipelineCacheData
vkGetQueryPoolResults
vkGetRenderAreaGranularity
vkGetSemaphoreCounterValue
vkGetSwapchainImagesKHR
vkInvalidateMappedMemoryRanges
vkMapMemory
vkMergePipelineCaches
vkQueueBindSparse
vkQueuePresentKHR
vkQueueSubmit
vkQueueWaitIdle
vkResetCommandBuffer
vkResetCommandPool
vkResetDescriptorPool
vkResetEvent
vkResetFences
vkResetQueryPool
vkSetEvent
vkSignalSemaphore
vkTrimCommandPool
vkUnmapMemory
vkUpdateDescriptorSetWithTemplate
vkUpdateDescriptorSets
vkWaitForFences
vkWaitSemaphores