1 | // Copyright (c) 2017-2023, The Khronos Group Inc. |
2 | // Copyright (c) 2017-2019 Valve Corporation |
3 | // Copyright (c) 2017-2019 LunarG, Inc. |
4 | // |
5 | // SPDX-License-Identifier: Apache-2.0 OR MIT |
6 | // |
7 | // Initial Author: Mark Young <marky@lunarg.com> |
8 | // |
9 | |
10 | #pragma once |
11 | |
12 | #include "extra_algorithms.h" |
13 | #include "loader_interfaces.h" |
14 | |
15 | #include <openxr/openxr.h> |
16 | |
17 | #include <array> |
18 | #include <cmath> |
19 | #include <memory> |
20 | #include <mutex> |
21 | #include <string> |
22 | #include <unordered_map> |
23 | #include <vector> |
24 | |
25 | class ApiLayerInterface; |
26 | struct XrGeneratedDispatchTable; |
27 | class LoaderInstance; |
28 | |
29 | // Manage the single loader instance that is available. |
30 | namespace ActiveLoaderInstance { |
31 | // Set the active loader instance. This will fail if there is already an active loader instance. |
32 | XrResult Set(std::unique_ptr<LoaderInstance> loader_instance, const char* log_function_name); |
33 | |
34 | // Returns true if there is an active loader instance. |
35 | bool IsAvailable(); |
36 | |
37 | // Get the active LoaderInstance. |
38 | XrResult Get(LoaderInstance** loader_instance, const char* log_function_name); |
39 | |
40 | // Destroy the currently active LoaderInstance if there is one. This will make the loader able to create a new XrInstance if needed. |
41 | void Remove(); |
42 | }; // namespace ActiveLoaderInstance |
43 | |
44 | // Manages information needed by the loader for an XrInstance, such as what extensions are available and the dispatch table. |
45 | class LoaderInstance { |
46 | public: |
47 | // Factory method |
48 | static XrResult CreateInstance(PFN_xrGetInstanceProcAddr get_instance_proc_addr_term, PFN_xrCreateInstance create_instance_term, |
49 | PFN_xrCreateApiLayerInstance create_api_layer_instance_term, |
50 | std::vector<std::unique_ptr<ApiLayerInterface>> layer_interfaces, |
51 | const XrInstanceCreateInfo* createInfo, std::unique_ptr<LoaderInstance>* loader_instance); |
52 | static const std::array<XrExtensionProperties, 1>& LoaderSpecificExtensions(); |
53 | |
54 | virtual ~LoaderInstance(); |
55 | |
56 | XrInstance GetInstanceHandle() { return _runtime_instance; } |
57 | const std::unique_ptr<XrGeneratedDispatchTable>& DispatchTable() { return _dispatch_table; } |
58 | std::vector<std::unique_ptr<ApiLayerInterface>>& LayerInterfaces() { return _api_layer_interfaces; } |
59 | bool ExtensionIsEnabled(const std::string& extension); |
60 | XrDebugUtilsMessengerEXT DefaultDebugUtilsMessenger() { return _messenger; } |
61 | void SetDefaultDebugUtilsMessenger(XrDebugUtilsMessengerEXT messenger) { _messenger = messenger; } |
62 | XrResult GetInstanceProcAddr(const char* name, PFN_xrVoidFunction* function); |
63 | |
64 | private: |
65 | LoaderInstance(XrInstance instance, const XrInstanceCreateInfo* createInfo, PFN_xrGetInstanceProcAddr topmost_gipa, |
66 | std::vector<std::unique_ptr<ApiLayerInterface>> api_layer_interfaces); |
67 | |
68 | private: |
69 | XrInstance _runtime_instance{XR_NULL_HANDLE}; |
70 | PFN_xrGetInstanceProcAddr _topmost_gipa{nullptr}; |
71 | std::vector<std::string> _enabled_extensions; |
72 | std::vector<std::unique_ptr<ApiLayerInterface>> _api_layer_interfaces; |
73 | |
74 | std::unique_ptr<XrGeneratedDispatchTable> _dispatch_table; |
75 | // Internal debug messenger created during xrCreateInstance |
76 | XrDebugUtilsMessengerEXT _messenger{XR_NULL_HANDLE}; |
77 | }; |
78 | |