Vulkan: Add vk_icdInitializeConnectToServiceCallback()
This entry point is a private implementation detail between
the Fuchsia Vulkan loader and the Vulkan ICDs on this platform.
It is called by the loader early on to pass the address of a global
function pointer, that can later be used by extensions to connect
to Fuchsia FIDL services.
This is equivalent to the Fuchsia fdio_service_connect() function,
except that this scheme prevents adding libfdio as a dependency
into the ICD shared library.
Bug: fxb/13095
Bug: fxb/13074
Change-Id: Idd2a0a9b78495fff4bdb17d9f6afc446b067d7e0
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/44019
Tested-by: Nicolas Capens <nicolascapens@google.com>
Presubmit-Ready: David Turner <digit@google.com>
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
diff --git a/CMakeLists.txt b/CMakeLists.txt
index f973cba..c26ffac 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -257,10 +257,18 @@
set_property(TARGET ${TARGET} APPEND_STRING PROPERTY LINK_FLAGS " -Wl,-undefined,error")
endif()
elseif(LINUX OR FUCHSIA)
+ # NOTE: The Fuchsia linker script is needed to export the vk_icdInitializeConnectToServiceCallback
+ # entry point (a private implementation detail betwen the Fuchsia Vulkan loader and the ICD).
+ if ((FUCHSIA) AND ("${TARGET}" STREQUAL "vk_swiftshader"))
+ set(LINKER_VERSION_SCRIPT "fuchsia_vk_swiftshader.lds")
+ else()
+ set(LINKER_VERSION_SCRIPT "${TARGET}.lds")
+ endif()
+
# The version script only exports the API functions and
# hides all the others.
- set_property(TARGET ${TARGET} APPEND_STRING PROPERTY LINK_FLAGS " -Wl,--version-script=${DIR}/${TARGET}.lds")
- set_property(TARGET ${TARGET} APPEND_STRING PROPERTY LINK_DEPENDS "${DIR}/${TARGET}.lds;")
+ set_property(TARGET ${TARGET} APPEND_STRING PROPERTY LINK_FLAGS " -Wl,--version-script=${DIR}/${LINKER_VERSION_SCRIPT}")
+ set_property(TARGET ${TARGET} APPEND_STRING PROPERTY LINK_DEPENDS "${DIR}/${LINKER_VERSION_SCRIPT};")
# -Bsymbolic binds symbol references to their global definitions within
# a shared object, thereby preventing symbol preemption.
diff --git a/src/Vulkan/VkGetProcAddress.cpp b/src/Vulkan/VkGetProcAddress.cpp
index 95310d3..2c762b8 100644
--- a/src/Vulkan/VkGetProcAddress.cpp
+++ b/src/Vulkan/VkGetProcAddress.cpp
@@ -517,4 +517,8 @@
}
};
+#endif // __ANDROID__
+
+#if VK_USE_PLATFORM_FUCHSIA
+PFN_vkConnectToService vk::icdFuchsiaServiceConnectCallback = nullptr;
#endif
diff --git a/src/Vulkan/VkGetProcAddress.h b/src/Vulkan/VkGetProcAddress.h
index 6eb017f..5918673 100644
--- a/src/Vulkan/VkGetProcAddress.h
+++ b/src/Vulkan/VkGetProcAddress.h
@@ -27,4 +27,16 @@
} // namespace vk
-#endif // VK_UTILS_HPP_
\ No newline at end of file
+#if VK_USE_PLATFORM_FUCHSIA
+// See vk_icdInitializeServiceConnectCallback() in libVulkan.cpp for details
+// about this global pointer. Since this is a private implementation detail
+// between the Vulkan loader and the ICDs, this type will never be part of
+// the <vulkan/vulkan_fuchsia.h> headers, so define the type here.
+typedef VkResult(VKAPI_PTR* PFN_vkConnectToService)(const char* pName, uint32_t handle);
+
+namespace vk {
+extern PFN_vkConnectToService icdFuchsiaServiceConnectCallback;
+}
+#endif // VK_USE_PLATFORM_FUCHSIA
+
+#endif // VK_UTILS_HPP_
diff --git a/src/Vulkan/fuchsia_vk_swiftshader.lds b/src/Vulkan/fuchsia_vk_swiftshader.lds
new file mode 100644
index 0000000..b235a69
--- /dev/null
+++ b/src/Vulkan/fuchsia_vk_swiftshader.lds
@@ -0,0 +1,20 @@
+# For Fuchsia, we must not export anything other than loader-related API
+# There is also the vk_icdInitializeConnectToServiceCallback entry point
+# that is specific to the Fuchsia Vulkan loader implementation.
+{
+global:
+ vkGetInstanceProcAddr;
+
+ # Loader-ICD interface functions
+ vk_icdGetInstanceProcAddr;
+ vk_icdNegotiateLoaderICDInterfaceVersion;
+ vk_icdInitializeConnectToServiceCallback;
+
+ # Type-strings and type-infos required by sanitizers
+ _ZTS*;
+ _ZTI*;
+
+local:
+ *;
+};
+
diff --git a/src/Vulkan/libVulkan.cpp b/src/Vulkan/libVulkan.cpp
index 54273a6..f235a6f 100644
--- a/src/Vulkan/libVulkan.cpp
+++ b/src/Vulkan/libVulkan.cpp
@@ -275,6 +275,26 @@
return VK_SUCCESS;
}
+#if VK_USE_PLATFORM_FUCHSIA
+
+// This symbol must be exported by a Fuchsia Vulkan ICD. The Vulkan loader will
+// call it, passing the address of a global function pointer that can later be
+// used at runtime to connect to Fuchsia FIDL services, as required by certain
+// extensions. See https://fxbug.dev/13095 for more details.
+//
+// NOTE: This entry point has not been upstreamed to Khronos yet, which reserves
+// all symbols starting with vk_icd. See https://fxbug.dev/13074 which
+// tracks upstreaming progress.
+VK_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vk_icdInitializeConnectToServiceCallback(
+ PFN_vkConnectToService callback)
+{
+ TRACE("(callback = %p)", callback);
+ vk::icdFuchsiaServiceConnectCallback = callback;
+ return VK_SUCCESS;
+}
+
+#endif // VK_USE_PLATFORM_FUCHSIA
+
static const VkExtensionProperties instanceExtensionProperties[] = {
{ VK_KHR_DEVICE_GROUP_CREATION_EXTENSION_NAME, VK_KHR_DEVICE_GROUP_CREATION_SPEC_VERSION },
{ VK_KHR_EXTERNAL_FENCE_CAPABILITIES_EXTENSION_NAME, VK_KHR_EXTERNAL_FENCE_CAPABILITIES_SPEC_VERSION },