summaryrefslogtreecommitdiffstats
path: root/thirdparty/openxr/src/loader/api_layer_interface.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'thirdparty/openxr/src/loader/api_layer_interface.cpp')
-rw-r--r--thirdparty/openxr/src/loader/api_layer_interface.cpp69
1 files changed, 67 insertions, 2 deletions
diff --git a/thirdparty/openxr/src/loader/api_layer_interface.cpp b/thirdparty/openxr/src/loader/api_layer_interface.cpp
index c9e24ec40b..fb509de270 100644
--- a/thirdparty/openxr/src/loader/api_layer_interface.cpp
+++ b/thirdparty/openxr/src/loader/api_layer_interface.cpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2017-2023, The Khronos Group Inc.
+// Copyright (c) 2017-2024, The Khronos Group Inc.
// Copyright (c) 2017-2019 Valve Corporation
// Copyright (c) 2017-2019 LunarG, Inc.
//
@@ -9,13 +9,14 @@
#include "api_layer_interface.hpp"
-#include "loader_interfaces.h"
+#include "loader_init_data.hpp"
#include "loader_logger.hpp"
#include "loader_platform.hpp"
#include "manifest_file.hpp"
#include "platform_utils.hpp"
#include <openxr/openxr.h>
+#include <openxr/openxr_loader_negotiation.h>
#include <cstring>
#include <memory>
@@ -282,6 +283,38 @@ XrResult ApiLayerInterface::LoadApiLayers(const std::string& openxr_command, uin
LoaderLogger::LogWarningMessage(openxr_command, warning_message);
continue;
}
+#ifdef XR_KHR_LOADER_INIT_SUPPORT
+ if (!LoaderInitData::instance().initialized()) {
+ LoaderLogger::LogErrorMessage(openxr_command, "ApiLayerInterface::LoadApiLayers skipping manifest file " +
+ manifest_file->Filename() +
+ " because xrInitializeLoaderKHR was not yet called.");
+
+ LoaderPlatformLibraryClose(layer_library);
+ return XR_ERROR_VALIDATION_FAILURE;
+ }
+ bool forwardedInitLoader = false;
+ {
+ // If we have xrInitializeLoaderKHR exposed as an export, forward call to it.
+ const auto function_name = manifest_file->GetFunctionName("xrInitializeLoaderKHR");
+ auto initLoader =
+ reinterpret_cast<PFN_xrInitializeLoaderKHR>(LoaderPlatformLibraryGetProcAddr(layer_library, function_name));
+ if (initLoader != nullptr) {
+ // we found the entry point one way or another.
+ LoaderLogger::LogInfoMessage(openxr_command,
+ "ApiLayerInterface::LoadApiLayers forwarding xrInitializeLoaderKHR call to API layer "
+ "before calling xrNegotiateLoaderApiLayerInterface.");
+ XrResult res = initLoader(LoaderInitData::instance().getParam());
+ if (!XR_SUCCEEDED(res)) {
+ LoaderLogger::LogErrorMessage(
+ openxr_command, "ApiLayerInterface::LoadApiLayers forwarded call to xrInitializeLoaderKHR failed.");
+
+ LoaderPlatformLibraryClose(layer_library);
+ return res;
+ }
+ forwardedInitLoader = true;
+ }
+ }
+#endif
// Get and settle on an layer interface version (using any provided name if required).
std::string function_name = manifest_file->GetFunctionName("xrNegotiateLoaderApiLayerInterface");
@@ -324,6 +357,38 @@ XrResult ApiLayerInterface::LoadApiLayers(const std::string& openxr_command, uin
LoaderLogger::LogWarningMessage(openxr_command, warning_message);
res = XR_ERROR_FILE_CONTENTS_INVALID;
}
+
+#ifdef XR_KHR_LOADER_INIT_SUPPORT
+ if (XR_SUCCEEDED(res) && !forwardedInitLoader) {
+ // Forward initialize loader call, where possible and if we did not do so before.
+ PFN_xrVoidFunction initializeVoid = nullptr;
+ PFN_xrInitializeLoaderKHR initialize = nullptr;
+
+ // Now we may try asking xrGetInstanceProcAddr on the API layer
+ if (XR_SUCCEEDED(api_layer_info.getInstanceProcAddr(XR_NULL_HANDLE, "xrInitializeLoaderKHR", &initializeVoid))) {
+ if (initializeVoid == nullptr) {
+ LoaderLogger::LogErrorMessage(openxr_command,
+ "ApiLayerInterface::LoadApiLayers got success from xrGetInstanceProcAddr "
+ "for xrInitializeLoaderKHR, but output a null pointer.");
+ res = XR_ERROR_RUNTIME_FAILURE;
+ } else {
+ initialize = reinterpret_cast<PFN_xrInitializeLoaderKHR>(initializeVoid);
+ }
+ }
+ if (initialize != nullptr) {
+ // we found the entry point one way or another.
+ LoaderLogger::LogInfoMessage(openxr_command,
+ "ApiLayerInterface::LoadApiLayers forwarding xrInitializeLoaderKHR call to API layer "
+ "after calling xrNegotiateLoaderApiLayerInterface.");
+ res = initialize(LoaderInitData::instance().getParam());
+ if (!XR_SUCCEEDED(res)) {
+ LoaderLogger::LogErrorMessage(
+ openxr_command, "ApiLayerInterface::LoadApiLayers forwarded call to xrInitializeLoaderKHR failed.");
+ }
+ }
+ }
+#endif
+
if (XR_FAILED(res)) {
if (!any_loaded) {
last_error = res;