godot/thirdparty/openxr/src/loader/loader_core.cpp

// Copyright (c) 2017-2024, The Khronos Group Inc.
// Copyright (c) 2017-2019 Valve Corporation
// Copyright (c) 2017-2019 LunarG, Inc.
//
// SPDX-License-Identifier: Apache-2.0 OR MIT
//
// Initial Authors: Mark Young <[email protected]>, Dave Houlton <[email protected]>
//

#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS)
#define _CRT_SECURE_NO_WARNINGS
#endif  // defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS)

#include "api_layer_interface.hpp"
#include "exception_handling.hpp"
#include "hex_and_handles.h"
#include "loader_init_data.hpp"
#include "loader_instance.hpp"
#include "loader_logger_recorders.hpp"
#include "loader_logger.hpp"
#include "loader_platform.hpp"
#include "runtime_interface.hpp"
#include "xr_generated_dispatch_table_core.h"
#include "xr_generated_loader.hpp"

#include <openxr/openxr.h>

#include <cstring>
#include <memory>
#include <mutex>
#include <sstream>
#include <string>
#include <utility>
#include <vector>

// Global loader lock to:
//   1. Ensure ActiveLoaderInstance get and set operations are done atomically.
//   2. Ensure RuntimeInterface isn't used to unload the runtime while the runtime is in use.
static std::mutex &GetGlobalLoaderMutex() {}

// Prototypes for the debug utils calls used internally.
static XRAPI_ATTR XrResult XRAPI_CALL LoaderTrampolineCreateDebugUtilsMessengerEXT(
    XrInstance instance, const XrDebugUtilsMessengerCreateInfoEXT *createInfo, XrDebugUtilsMessengerEXT *messenger);
static XRAPI_ATTR XrResult XRAPI_CALL LoaderTrampolineDestroyDebugUtilsMessengerEXT(XrDebugUtilsMessengerEXT messenger);

// Terminal functions needed by xrCreateInstance.
static XRAPI_ATTR XrResult XRAPI_CALL LoaderXrTermGetInstanceProcAddr(XrInstance, const char *, PFN_xrVoidFunction *);
static XRAPI_ATTR XrResult XRAPI_CALL LoaderXrTermCreateInstance(const XrInstanceCreateInfo *, XrInstance *);
static XRAPI_ATTR XrResult XRAPI_CALL LoaderXrTermCreateApiLayerInstance(const XrInstanceCreateInfo *,
                                                                         const struct XrApiLayerCreateInfo *, XrInstance *);
static XRAPI_ATTR XrResult XRAPI_CALL LoaderXrTermSetDebugUtilsObjectNameEXT(XrInstance, const XrDebugUtilsObjectNameInfoEXT *);
static XRAPI_ATTR XrResult XRAPI_CALL LoaderXrTermCreateDebugUtilsMessengerEXT(XrInstance,
                                                                               const XrDebugUtilsMessengerCreateInfoEXT *,
                                                                               XrDebugUtilsMessengerEXT *);
static XRAPI_ATTR XrResult XRAPI_CALL LoaderXrTermDestroyDebugUtilsMessengerEXT(XrDebugUtilsMessengerEXT);
static XRAPI_ATTR XrResult XRAPI_CALL LoaderXrTermSubmitDebugUtilsMessageEXT(
    XrInstance instance, XrDebugUtilsMessageSeverityFlagsEXT messageSeverity, XrDebugUtilsMessageTypeFlagsEXT messageTypes,
    const XrDebugUtilsMessengerCallbackDataEXT *callbackData);
static XRAPI_ATTR XrResult XRAPI_CALL LoaderXrGetInstanceProcAddr(XrInstance instance, const char *name,
                                                                  PFN_xrVoidFunction *function);

// Utility template function meant to validate if a fixed size string contains
// a null-terminator.
template <size_t max_length>
inline bool IsMissingNullTerminator(const char (&str)[max_length]) {}

// ---- Core 1.0 manual loader trampoline functions
#ifdef XR_KHR_LOADER_INIT_SUPPORT  // platforms that support XR_KHR_loader_init.
XRAPI_ATTR XrResult XRAPI_CALL LoaderXrInitializeLoaderKHR(const XrLoaderInitInfoBaseHeaderKHR *loaderInitInfo) XRLOADER_ABI_TRY {
    LoaderLogger::LogVerboseMessage("xrInitializeLoaderKHR", "Entering loader trampoline");
    return InitializeLoaderInitData(loaderInitInfo);
}
XRLOADER_ABI_CATCH_FALLBACK
#endif

static XRAPI_ATTR XrResult XRAPI_CALL LoaderXrEnumerateApiLayerProperties(uint32_t propertyCapacityInput,
                                                                          uint32_t *propertyCountOutput,
                                                                          XrApiLayerProperties *properties) XRLOADER_ABI_TRY {}
XRLOADER_ABI_CATCH_FALLBACK

static XRAPI_ATTR XrResult XRAPI_CALL
LoaderXrEnumerateInstanceExtensionProperties(const char *layerName, uint32_t propertyCapacityInput, uint32_t *propertyCountOutput,
                                             XrExtensionProperties *properties) XRLOADER_ABI_TRY {}
XRLOADER_ABI_CATCH_FALLBACK

static XRAPI_ATTR XrResult XRAPI_CALL LoaderXrCreateInstance(const XrInstanceCreateInfo *info,
                                                             XrInstance *instance) XRLOADER_ABI_TRY {}
XRLOADER_ABI_CATCH_FALLBACK

static XRAPI_ATTR XrResult XRAPI_CALL LoaderXrDestroyInstance(XrInstance instance) XRLOADER_ABI_TRY {}
XRLOADER_ABI_CATCH_FALLBACK

// ---- Core 1.0 manual loader terminator functions

// Validate that the applicationInfo structure in the XrInstanceCreateInfo is valid.
static XrResult ValidateApplicationInfo(const XrApplicationInfo &info) {}

// Validate that the XrInstanceCreateInfo is valid
static XrResult ValidateInstanceCreateInfo(const XrInstanceCreateInfo *info) {}

static XRAPI_ATTR XrResult XRAPI_CALL LoaderXrTermCreateInstance(const XrInstanceCreateInfo *createInfo,
                                                                 XrInstance *instance) XRLOADER_ABI_TRY {}
XRLOADER_ABI_CATCH_FALLBACK

static XRAPI_ATTR XrResult XRAPI_CALL LoaderXrTermCreateApiLayerInstance(const XrInstanceCreateInfo *info,
                                                                         const struct XrApiLayerCreateInfo * /*apiLayerInfo*/,
                                                                         XrInstance *instance) {}

static XRAPI_ATTR XrResult XRAPI_CALL LoaderXrTermDestroyInstance(XrInstance instance) XRLOADER_ABI_TRY {}
XRLOADER_ABI_CATCH_FALLBACK

static XRAPI_ATTR XrResult XRAPI_CALL LoaderXrTermGetInstanceProcAddr(XrInstance instance, const char *name,
                                                                      PFN_xrVoidFunction *function) XRLOADER_ABI_TRY {}
XRLOADER_ABI_CATCH_FALLBACK

// ---- Extension manual loader trampoline functions

static XRAPI_ATTR XrResult XRAPI_CALL
LoaderTrampolineCreateDebugUtilsMessengerEXT(XrInstance instance, const XrDebugUtilsMessengerCreateInfoEXT *createInfo,
                                             XrDebugUtilsMessengerEXT *messenger) XRLOADER_ABI_TRY {}
XRLOADER_ABI_CATCH_BAD_ALLOC_OOM XRLOADER_ABI_CATCH_FALLBACK

    static XRAPI_ATTR XrResult XRAPI_CALL
    LoaderTrampolineDestroyDebugUtilsMessengerEXT(XrDebugUtilsMessengerEXT messenger) XRLOADER_ABI_TRY {}
XRLOADER_ABI_CATCH_FALLBACK

static XRAPI_ATTR XrResult XRAPI_CALL
LoaderTrampolineSessionBeginDebugUtilsLabelRegionEXT(XrSession session, const XrDebugUtilsLabelEXT *labelInfo) XRLOADER_ABI_TRY {}
XRLOADER_ABI_CATCH_FALLBACK

static XRAPI_ATTR XrResult XRAPI_CALL LoaderTrampolineSessionEndDebugUtilsLabelRegionEXT(XrSession session) XRLOADER_ABI_TRY {}
XRLOADER_ABI_CATCH_FALLBACK

static XRAPI_ATTR XrResult XRAPI_CALL
LoaderTrampolineSessionInsertDebugUtilsLabelEXT(XrSession session, const XrDebugUtilsLabelEXT *labelInfo) XRLOADER_ABI_TRY {}
XRLOADER_ABI_CATCH_FALLBACK

// No-op trampoline needed for xrGetInstanceProcAddr. Work done in terminator.
static XRAPI_ATTR XrResult XRAPI_CALL
LoaderTrampolineSetDebugUtilsObjectNameEXT(XrInstance instance, const XrDebugUtilsObjectNameInfoEXT *nameInfo) XRLOADER_ABI_TRY {}
XRLOADER_ABI_CATCH_FALLBACK

// No-op trampoline needed for xrGetInstanceProcAddr. Work done in terminator.
static XRAPI_ATTR XrResult XRAPI_CALL LoaderTrampolineSubmitDebugUtilsMessageEXT(
    XrInstance instance, XrDebugUtilsMessageSeverityFlagsEXT messageSeverity, XrDebugUtilsMessageTypeFlagsEXT messageTypes,
    const XrDebugUtilsMessengerCallbackDataEXT *callbackData) XRLOADER_ABI_TRY {}
XRLOADER_ABI_CATCH_FALLBACK

// ---- Extension manual loader terminator functions

XRAPI_ATTR XrResult XRAPI_CALL LoaderXrTermCreateDebugUtilsMessengerEXT(XrInstance instance,
                                                                        const XrDebugUtilsMessengerCreateInfoEXT *createInfo,
                                                                        XrDebugUtilsMessengerEXT *messenger) XRLOADER_ABI_TRY {}
XRLOADER_ABI_CATCH_FALLBACK

XRAPI_ATTR XrResult XRAPI_CALL LoaderXrTermDestroyDebugUtilsMessengerEXT(XrDebugUtilsMessengerEXT messenger) XRLOADER_ABI_TRY {}
XRLOADER_ABI_CATCH_FALLBACK

XRAPI_ATTR XrResult XRAPI_CALL LoaderXrTermSubmitDebugUtilsMessageEXT(
    XrInstance instance, XrDebugUtilsMessageSeverityFlagsEXT messageSeverity, XrDebugUtilsMessageTypeFlagsEXT messageTypes,
    const XrDebugUtilsMessengerCallbackDataEXT *callbackData) XRLOADER_ABI_TRY {}
XRLOADER_ABI_CATCH_FALLBACK

XRAPI_ATTR XrResult XRAPI_CALL
LoaderXrTermSetDebugUtilsObjectNameEXT(XrInstance instance, const XrDebugUtilsObjectNameInfoEXT *nameInfo) XRLOADER_ABI_TRY {}
XRLOADER_ABI_CATCH_FALLBACK

XRAPI_ATTR XrResult XRAPI_CALL LoaderXrGetInstanceProcAddr(XrInstance instance, const char *name,
                                                           PFN_xrVoidFunction *function) XRLOADER_ABI_TRY {}
XRLOADER_ABI_CATCH_FALLBACK

// Exported loader functions
//
// The application might override these by exporting the same symbols and so we can't use these
// symbols anywhere in the loader code, and instead the internal non exported functions that these
// stubs call should be used internally.
LOADER_EXPORT XRAPI_ATTR XrResult XRAPI_CALL xrEnumerateApiLayerProperties(uint32_t propertyCapacityInput,
                                                                           uint32_t *propertyCountOutput,
                                                                           XrApiLayerProperties *properties) {}

LOADER_EXPORT XRAPI_ATTR XrResult XRAPI_CALL xrEnumerateInstanceExtensionProperties(const char *layerName,
                                                                                    uint32_t propertyCapacityInput,
                                                                                    uint32_t *propertyCountOutput,
                                                                                    XrExtensionProperties *properties) {}

LOADER_EXPORT XRAPI_ATTR XrResult XRAPI_CALL xrCreateInstance(const XrInstanceCreateInfo *info, XrInstance *instance) {}

LOADER_EXPORT XRAPI_ATTR XrResult XRAPI_CALL xrDestroyInstance(XrInstance instance) {}

LOADER_EXPORT XRAPI_ATTR XrResult XRAPI_CALL xrGetInstanceProcAddr(XrInstance instance, const char *name,
                                                                   PFN_xrVoidFunction *function) {}

#ifdef XR_KHR_LOADER_INIT_SUPPORT
LOADER_EXPORT XRAPI_ATTR XrResult XRAPI_CALL xrInitializeLoaderKHR(const XrLoaderInitInfoBaseHeaderKHR *loaderInitInfo) {
    return LoaderXrInitializeLoaderKHR(loaderInitInfo);
}
#endif