Blender V4.5
GHOST_XrContext.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2020-2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
10
11#include <algorithm>
12#include <cassert>
13#include <sstream>
14#include <string>
15#include <string_view>
16
17#include "GHOST_Types.h"
18#include "GHOST_XrException.hh"
19#include "GHOST_XrSession.hh"
20#include "GHOST_Xr_intern.hh"
21
22#include "GHOST_XrContext.hh"
23
25 XrInstance instance = XR_NULL_HANDLE;
26 XrInstanceProperties instance_properties = {};
27
28 std::vector<XrExtensionProperties> extensions;
29 std::vector<XrApiLayerProperties> layers;
30
31 static PFN_xrCreateDebugUtilsMessengerEXT s_xrCreateDebugUtilsMessengerEXT_fn;
32 static PFN_xrDestroyDebugUtilsMessengerEXT s_xrDestroyDebugUtilsMessengerEXT_fn;
33
34 XrDebugUtilsMessengerEXT debug_messenger = XR_NULL_HANDLE;
35};
36
37PFN_xrCreateDebugUtilsMessengerEXT OpenXRInstanceData::s_xrCreateDebugUtilsMessengerEXT_fn =
38 nullptr;
39PFN_xrDestroyDebugUtilsMessengerEXT OpenXRInstanceData::s_xrDestroyDebugUtilsMessengerEXT_fn =
40 nullptr;
41
42GHOST_XrErrorHandlerFn GHOST_XrContext::s_error_handler = nullptr;
43void *GHOST_XrContext::s_error_handler_customdata = nullptr;
44
45/* -------------------------------------------------------------------- */
48
49GHOST_XrContext::GHOST_XrContext(const GHOST_XrContextCreateInfo *create_info)
50 : m_oxr(std::make_unique<OpenXRInstanceData>()),
51 m_debug(create_info->context_flag & GHOST_kXrContextDebug),
52 m_debug_time(create_info->context_flag & GHOST_kXrContextDebugTime)
53{
54}
55
57{
58 /* Destroy session data first. Otherwise xrDestroyInstance will implicitly do it, before the
59 * session had a chance to do so explicitly. */
60 m_session = nullptr;
61
62 if (m_oxr->debug_messenger != XR_NULL_HANDLE) {
63 assert(m_oxr->s_xrDestroyDebugUtilsMessengerEXT_fn != nullptr);
64 m_oxr->s_xrDestroyDebugUtilsMessengerEXT_fn(m_oxr->debug_messenger);
65 }
66 if (m_oxr->instance != XR_NULL_HANDLE) {
67 CHECK_XR_ASSERT(xrDestroyInstance(m_oxr->instance));
68 m_oxr->instance = XR_NULL_HANDLE;
69 }
70}
71
72void GHOST_XrContext::initialize(const GHOST_XrContextCreateInfo *create_info)
73{
74 initApiLayers();
75 initExtensions();
76 if (isDebugMode()) {
77 printSDKVersion();
78 printAvailableAPILayersAndExtensionsInfo();
79 }
80
81 /* Multiple graphics binding extensions can be enabled, but only one will actually be used
82 * (determined later on). */
83 const std::vector<GHOST_TXrGraphicsBinding> graphics_binding_types =
84 determineGraphicsBindingTypesToEnable(create_info);
85
86 assert(m_oxr->instance == XR_NULL_HANDLE);
87 createOpenXRInstance(graphics_binding_types);
88 storeInstanceProperties();
89
90 /* Multiple bindings may be enabled. Now that we know the runtime in use, settle for one. */
91 m_gpu_binding_type = determineGraphicsBindingTypeToUse(graphics_binding_types, create_info);
92
93 printInstanceInfo();
94 if (isDebugMode()) {
95 initDebugMessenger();
96 }
97}
98
99void GHOST_XrContext::createOpenXRInstance(
100 const std::vector<GHOST_TXrGraphicsBinding> &graphics_binding_types)
101{
102 XrInstanceCreateInfo create_info = {XR_TYPE_INSTANCE_CREATE_INFO};
103
104 std::string("Blender").copy(create_info.applicationInfo.applicationName,
105 XR_MAX_APPLICATION_NAME_SIZE);
106 create_info.applicationInfo.apiVersion = XR_CURRENT_API_VERSION;
107
108 getAPILayersToEnable(m_enabled_layers);
109 getExtensionsToEnable(graphics_binding_types, m_enabled_extensions);
110 create_info.enabledApiLayerCount = m_enabled_layers.size();
111 create_info.enabledApiLayerNames = m_enabled_layers.data();
112 create_info.enabledExtensionCount = m_enabled_extensions.size();
113 create_info.enabledExtensionNames = m_enabled_extensions.data();
114 if (isDebugMode()) {
115 printExtensionsAndAPILayersToEnable();
116 }
117
118 CHECK_XR(xrCreateInstance(&create_info, &m_oxr->instance),
119 "Failed to connect to an OpenXR runtime.");
120}
121
122void GHOST_XrContext::storeInstanceProperties()
123{
124 const std::map<std::string, GHOST_TXrOpenXRRuntimeID> runtime_map = {
125 {"Monado(XRT) by Collabora et al", OPENXR_RUNTIME_MONADO},
126 {"Oculus", OPENXR_RUNTIME_OCULUS},
127 {"SteamVR/OpenXR", OPENXR_RUNTIME_STEAMVR},
128 {"Windows Mixed Reality Runtime", OPENXR_RUNTIME_WMR},
129 {"Varjo OpenXR Runtime", OPENXR_RUNTIME_VARJO}};
130 decltype(runtime_map)::const_iterator runtime_map_iter;
131
132 m_oxr->instance_properties.type = XR_TYPE_INSTANCE_PROPERTIES;
133 CHECK_XR(xrGetInstanceProperties(m_oxr->instance, &m_oxr->instance_properties),
134 "Failed to get OpenXR runtime information. Do you have an active runtime set up?");
135
136 runtime_map_iter = runtime_map.find(m_oxr->instance_properties.runtimeName);
137 if (runtime_map_iter != runtime_map.end()) {
138 m_runtime_id = runtime_map_iter->second;
139 }
140}
141 /* Create, Initialize and Destruct */
143
144/* -------------------------------------------------------------------- */
147
148void GHOST_XrContext::printSDKVersion()
149{
150 const XrVersion sdk_version = XR_CURRENT_API_VERSION;
151
152 printf("OpenXR SDK Version: %u.%u.%u\n",
153 XR_VERSION_MAJOR(sdk_version),
154 XR_VERSION_MINOR(sdk_version),
155 XR_VERSION_PATCH(sdk_version));
156}
157
158void GHOST_XrContext::printInstanceInfo()
159{
160 assert(m_oxr->instance != XR_NULL_HANDLE);
161
162 printf("Connected to OpenXR runtime: %s (Version %u.%u.%u)\n",
163 m_oxr->instance_properties.runtimeName,
164 XR_VERSION_MAJOR(m_oxr->instance_properties.runtimeVersion),
165 XR_VERSION_MINOR(m_oxr->instance_properties.runtimeVersion),
166 XR_VERSION_PATCH(m_oxr->instance_properties.runtimeVersion));
167}
168
169void GHOST_XrContext::printAvailableAPILayersAndExtensionsInfo()
170{
171 puts("Available OpenXR API-layers/extensions:");
172 for (const XrApiLayerProperties &layer_info : m_oxr->layers) {
173 printf("Layer: %s\n", layer_info.layerName);
174 }
175 for (const XrExtensionProperties &ext_info : m_oxr->extensions) {
176 printf("Extension: %s\n", ext_info.extensionName);
177 }
178}
179
180void GHOST_XrContext::printExtensionsAndAPILayersToEnable()
181{
182 for (const char *layer_name : m_enabled_layers) {
183 printf("Enabling OpenXR API-Layer: %s\n", layer_name);
184 }
185 for (const char *ext_name : m_enabled_extensions) {
186 printf("Enabling OpenXR Extension: %s\n", ext_name);
187 }
188}
189
190static XrBool32 debug_messenger_func(XrDebugUtilsMessageSeverityFlagsEXT /*messageSeverity*/,
191 XrDebugUtilsMessageTypeFlagsEXT /*messageTypes*/,
192 const XrDebugUtilsMessengerCallbackDataEXT *callbackData,
193 void * /*userData*/)
194{
195 puts("OpenXR Debug Message:");
196 puts(callbackData->message);
197 return XR_FALSE; /* OpenXR spec suggests always returning false. */
198}
199
200void GHOST_XrContext::initDebugMessenger()
201{
202 XrDebugUtilsMessengerCreateInfoEXT create_info = {XR_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT};
203
204 /* Extension functions need to be obtained through xrGetInstanceProcAddr(). */
205 if (XR_FAILED(xrGetInstanceProcAddr(
206 m_oxr->instance,
207 "xrCreateDebugUtilsMessengerEXT",
208 (PFN_xrVoidFunction *)&m_oxr->s_xrCreateDebugUtilsMessengerEXT_fn)) ||
209 XR_FAILED(xrGetInstanceProcAddr(
210 m_oxr->instance,
211 "xrDestroyDebugUtilsMessengerEXT",
212 (PFN_xrVoidFunction *)&m_oxr->s_xrDestroyDebugUtilsMessengerEXT_fn)))
213 {
214 m_oxr->s_xrCreateDebugUtilsMessengerEXT_fn = nullptr;
215 m_oxr->s_xrDestroyDebugUtilsMessengerEXT_fn = nullptr;
216
217 fprintf(stderr,
218 "Could not use XR_EXT_debug_utils to enable debug prints. Not a fatal error, "
219 "continuing without the messenger.\n");
220 return;
221 }
222
223 create_info.messageSeverities = XR_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT |
224 XR_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT |
225 XR_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT |
226 XR_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT;
227 create_info.messageTypes = XR_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT |
228 XR_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT |
229 XR_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT;
230 create_info.userCallback = debug_messenger_func;
231
232 if (XR_FAILED(m_oxr->s_xrCreateDebugUtilsMessengerEXT_fn(
233 m_oxr->instance, &create_info, &m_oxr->debug_messenger)))
234 {
235 fprintf(stderr,
236 "Failed to create OpenXR debug messenger. Not a fatal error, continuing without the "
237 "messenger.\n");
238 return;
239 }
240}
241 /* Debug Printing */
243
244/* -------------------------------------------------------------------- */
247
249{
250 GHOST_XrError error;
251
252 error.user_message = exception->m_msg.data();
253 error.customdata = s_error_handler_customdata;
254
255 if (isDebugMode()) {
256 fprintf(stderr,
257 "Error: \t%s\n\tOpenXR error value: %i\n",
258 error.user_message,
259 exception->m_result);
260 }
261
262 /* Potentially destroys GHOST_XrContext */
263 s_error_handler(&error);
264}
265
266void GHOST_XrContext::setErrorHandler(GHOST_XrErrorHandlerFn handler_fn, void *customdata)
267{
268 s_error_handler = handler_fn;
269 s_error_handler_customdata = customdata;
270}
271 /* Error handling */
273
274/* -------------------------------------------------------------------- */
277
281void GHOST_XrContext::initExtensionsEx(std::vector<XrExtensionProperties> &extensions,
282 const char *layer_name)
283{
284 uint32_t extension_count = 0;
285
286 /* Get count for array creation/init first. */
287 CHECK_XR(xrEnumerateInstanceExtensionProperties(layer_name, 0, &extension_count, nullptr),
288 "Failed to query OpenXR runtime information. Do you have an active runtime set up?");
289
290 if (extension_count == 0) {
291 /* Extensions are optional, can successfully exit. */
292 return;
293 }
294
295 for (uint32_t i = 0; i < extension_count; i++) {
296 XrExtensionProperties ext = {XR_TYPE_EXTENSION_PROPERTIES};
297 extensions.push_back(ext);
298 }
299
300 /* Actually get the extensions. */
301 CHECK_XR(xrEnumerateInstanceExtensionProperties(
302 layer_name, extension_count, &extension_count, extensions.data()),
303 "Failed to query OpenXR runtime information. Do you have an active runtime set up?");
304}
305
306void GHOST_XrContext::initExtensions()
307{
308 initExtensionsEx(m_oxr->extensions, nullptr);
309}
310
311void GHOST_XrContext::initApiLayers()
312{
313 uint32_t layer_count = 0;
314
315 /* Get count for array creation/init first. */
316 CHECK_XR(xrEnumerateApiLayerProperties(0, &layer_count, nullptr),
317 "Failed to query OpenXR runtime information. Do you have an active runtime set up?");
318
319 if (layer_count == 0) {
320 /* Layers are optional, can safely exit. */
321 return;
322 }
323
324 m_oxr->layers = std::vector<XrApiLayerProperties>(layer_count);
325 for (XrApiLayerProperties &layer : m_oxr->layers) {
326 layer.type = XR_TYPE_API_LAYER_PROPERTIES;
327 }
328
329 /* Actually get the layers. */
330 CHECK_XR(xrEnumerateApiLayerProperties(layer_count, &layer_count, m_oxr->layers.data()),
331 "Failed to query OpenXR runtime information. Do you have an active runtime set up?");
332 for (const XrApiLayerProperties &layer : m_oxr->layers) {
333 /* Each layer may have own extensions. */
334 initExtensionsEx(m_oxr->extensions, layer.layerName);
335 }
336}
337
338static bool openxr_layer_is_available(const std::vector<XrApiLayerProperties> &layers_info,
339 const std::string &layer_name)
340{
341 for (const XrApiLayerProperties &layer_info : layers_info) {
342 if (layer_info.layerName == layer_name) {
343 return true;
344 }
345 }
346
347 return false;
348}
349
351 const std::vector<XrExtensionProperties> &extensions_info,
352 const std::string_view &extension_name)
353{
354 for (const XrExtensionProperties &ext_info : extensions_info) {
355 if (ext_info.extensionName == extension_name) {
356 return true;
357 }
358 }
359
360 return false;
361}
362
366void GHOST_XrContext::getAPILayersToEnable(std::vector<const char *> &r_ext_names)
367{
368 static std::vector<std::string> try_layers;
369
370 try_layers.clear();
371
372 if (isDebugMode()) {
373 try_layers.push_back("XR_APILAYER_LUNARG_core_validation");
374 }
375
376 r_ext_names.reserve(try_layers.size());
377
378 for (const std::string &layer : try_layers) {
379 if (openxr_layer_is_available(m_oxr->layers, layer)) {
380 r_ext_names.push_back(layer.data());
381 }
382 }
383}
384
385static const char *openxr_ext_name_from_wm_gpu_binding(GHOST_TXrGraphicsBinding binding)
386{
387 switch (binding) {
388 case GHOST_kXrGraphicsOpenGL:
389 return XR_KHR_OPENGL_ENABLE_EXTENSION_NAME;
390
391#ifdef WITH_VULKAN_BACKEND
392 case GHOST_kXrGraphicsVulkan:
393 return XR_KHR_VULKAN_ENABLE2_EXTENSION_NAME;
394#endif
395
396#ifdef WIN32
397# ifdef WITH_OPENGL_BACKEND
398 case GHOST_kXrGraphicsOpenGLD3D11:
399# endif
400# ifdef WITH_VULKAN_BACKEND
401 case GHOST_kXrGraphicsVulkanD3D11:
402# endif
403 return XR_KHR_D3D11_ENABLE_EXTENSION_NAME;
404#endif
405 case GHOST_kXrGraphicsUnknown:
406 assert(!"Could not identify graphics binding to choose.");
407 return nullptr;
408 }
409
410 return nullptr;
411}
412
416void GHOST_XrContext::getExtensionsToEnable(
417 const std::vector<GHOST_TXrGraphicsBinding> &graphics_binding_types,
418 std::vector<const char *> &r_ext_names)
419{
420 std::vector<std::string_view> try_ext;
421
422 /* Try enabling debug extension. */
423 if (isDebugMode()) {
424 try_ext.push_back(XR_EXT_DEBUG_UTILS_EXTENSION_NAME);
425 }
426
427 /* Interaction profile extensions. */
428 try_ext.push_back(XR_EXT_HP_MIXED_REALITY_CONTROLLER_EXTENSION_NAME);
429 try_ext.push_back(XR_HTC_VIVE_COSMOS_CONTROLLER_INTERACTION_EXTENSION_NAME);
430#ifdef XR_HTC_VIVE_FOCUS3_CONTROLLER_INTERACTION_EXTENSION_NAME
431 try_ext.push_back(XR_HTC_VIVE_FOCUS3_CONTROLLER_INTERACTION_EXTENSION_NAME);
432#endif
433 try_ext.push_back(XR_HUAWEI_CONTROLLER_INTERACTION_EXTENSION_NAME);
434
435 /* Controller model extension. */
436 try_ext.push_back(XR_MSFT_CONTROLLER_MODEL_EXTENSION_NAME);
437
438 /* Varjo quad view extension. */
439 try_ext.push_back(XR_VARJO_QUAD_VIEWS_EXTENSION_NAME);
440
441 /* Varjo foveated extension. */
442 try_ext.push_back(XR_VARJO_FOVEATED_RENDERING_EXTENSION_NAME);
443
444 /* Meta/Facebook passthrough extension. */
445 try_ext.push_back(XR_FB_PASSTHROUGH_EXTENSION_NAME);
446
447 r_ext_names.reserve(try_ext.size() + graphics_binding_types.size());
448
449 /* Add graphics binding extensions (may be multiple ones, we'll settle for one to use later, once
450 * we have more info about the runtime). */
451 for (GHOST_TXrGraphicsBinding type : graphics_binding_types) {
452 const char *gpu_binding = openxr_ext_name_from_wm_gpu_binding(type);
453 assert(openxr_extension_is_available(m_oxr->extensions, gpu_binding));
454 r_ext_names.push_back(gpu_binding);
455 }
456
457#if defined(WITH_GHOST_X11)
458 if (openxr_extension_is_available(m_oxr->extensions, XR_MNDX_EGL_ENABLE_EXTENSION_NAME)) {
459 /* Use EGL if that backend is available. */
460 r_ext_names.push_back(XR_MNDX_EGL_ENABLE_EXTENSION_NAME);
461 }
462#endif
463
464 for (const std::string_view &ext : try_ext) {
465 if (openxr_extension_is_available(m_oxr->extensions, ext)) {
466 r_ext_names.push_back(ext.data());
467 }
468 }
469}
470
475std::vector<GHOST_TXrGraphicsBinding> GHOST_XrContext::determineGraphicsBindingTypesToEnable(
476 const GHOST_XrContextCreateInfo *create_info)
477{
478 std::vector<GHOST_TXrGraphicsBinding> result;
479 assert(create_info->gpu_binding_candidates != nullptr);
480 assert(create_info->gpu_binding_candidates_count > 0);
481
482 for (uint32_t i = 0; i < create_info->gpu_binding_candidates_count; i++) {
483 assert(create_info->gpu_binding_candidates[i] != GHOST_kXrGraphicsUnknown);
484 const char *ext_name = openxr_ext_name_from_wm_gpu_binding(
485 create_info->gpu_binding_candidates[i]);
486 if (openxr_extension_is_available(m_oxr->extensions, ext_name)) {
487 result.push_back(create_info->gpu_binding_candidates[i]);
488 }
489 }
490
491 if (result.empty()) {
492 throw GHOST_XrException("No supported graphics binding found.");
493 }
494
495 return result;
496}
497
498GHOST_TXrGraphicsBinding GHOST_XrContext::determineGraphicsBindingTypeToUse(
499 const std::vector<GHOST_TXrGraphicsBinding> &enabled_types,
500 const GHOST_XrContextCreateInfo *create_info)
501{
502 /* Return the first working type. */
503 for (GHOST_TXrGraphicsBinding type : enabled_types) {
504#ifdef WIN32
505 /* The SteamVR OpenGL backend currently fails for NVIDIA GPU's. Disable it and allow falling
506 * back to the DirectX one. */
507 if ((m_runtime_id == OPENXR_RUNTIME_STEAMVR) && (type == GHOST_kXrGraphicsOpenGL) &&
508 ((create_info->context_flag & GHOST_kXrContextGpuNVIDIA) != 0))
509 {
510 continue;
511 }
512#else
513 ((void)create_info);
514#endif
515
516 assert(type != GHOST_kXrGraphicsUnknown);
517 return type;
518 }
519
520 throw GHOST_XrException("Failed to determine a graphics binding to use.");
521}
522 /* OpenXR API-Layers and Extensions */
524
525/* -------------------------------------------------------------------- */
530
531void GHOST_XrContext::startSession(const GHOST_XrSessionBeginInfo *begin_info)
532{
533 m_custom_funcs.session_create_fn = begin_info->create_fn;
534 m_custom_funcs.session_exit_fn = begin_info->exit_fn;
535 m_custom_funcs.session_exit_customdata = begin_info->exit_customdata;
536
537 if (m_session == nullptr) {
538 m_session = std::make_unique<GHOST_XrSession>(*this);
539 }
540 m_session->start(begin_info);
541}
542
544{
545 if (m_session) {
546 if (m_session->isRunning()) {
547 m_session->requestEnd();
548 }
549 else {
550 m_session = nullptr;
551 }
552 }
553}
554
556{
557 return m_session && m_session->isRunning();
558}
559
560void GHOST_XrContext::drawSessionViews(void *draw_customdata)
561{
562 m_session->draw(draw_customdata);
563}
564
568void GHOST_XrContext::handleSessionStateChange(const XrEventDataSessionStateChanged &lifecycle)
569{
570 if (m_session &&
571 m_session->handleStateChangeEvent(lifecycle) == GHOST_XrSession::SESSION_DESTROY)
572 {
573 m_session = nullptr;
574 }
575}
576 /* Session Management */
578
579/* -------------------------------------------------------------------- */
584
586{
587 return m_session.get();
588}
589
591{
592 return m_session.get();
593}
594
595void GHOST_XrContext::setGraphicsContextBindFuncs(GHOST_XrGraphicsContextBindFn bind_fn,
596 GHOST_XrGraphicsContextUnbindFn unbind_fn)
597{
598 if (m_session) {
599 m_session->unbindGraphicsContext();
600 }
601 m_custom_funcs.gpu_ctx_bind_fn = bind_fn;
602 m_custom_funcs.gpu_ctx_unbind_fn = unbind_fn;
603}
604
605void GHOST_XrContext::setDrawViewFunc(GHOST_XrDrawViewFn draw_view_fn)
606{
607 m_custom_funcs.draw_view_fn = draw_view_fn;
608}
609
611 GHOST_XrPassthroughEnabledFn passthrough_enabled_fn)
612{
613 m_custom_funcs.passthrough_enabled_fn = passthrough_enabled_fn;
614}
615
617 GHOST_XrDisablePassthroughFn disable_passthrough_fn)
618{
619 m_custom_funcs.disable_passthrough_fn = disable_passthrough_fn;
620}
621
623{
624 /* Must only be called after the session was started */
625 assert(m_session);
626 return m_session->needsUpsideDownDrawing();
627}
628 /* Public Accessors and Mutators */
630
631/* -------------------------------------------------------------------- */
634
636{
637 return m_runtime_id;
638}
639
641{
642 return m_custom_funcs;
643}
644
645GHOST_TXrGraphicsBinding GHOST_XrContext::getGraphicsBindingType() const
646{
647 return m_gpu_binding_type;
648}
649
651{
652 return m_oxr->instance;
653}
654
656{
657 return m_debug;
658}
659
661{
662 return m_debug_time;
663}
664
665bool GHOST_XrContext::isExtensionEnabled(const char *ext) const
666{
667 bool contains = std::find(m_enabled_extensions.begin(), m_enabled_extensions.end(), ext) !=
668 m_enabled_extensions.end();
669 return contains;
670}
671 /* Ghost Internal Accessors and Mutators */
static const char * openxr_ext_name_from_wm_gpu_binding(GHOST_TXrGraphicsBinding binding)
static XrBool32 debug_messenger_func(XrDebugUtilsMessageSeverityFlagsEXT, XrDebugUtilsMessageTypeFlagsEXT, const XrDebugUtilsMessengerCallbackDataEXT *callbackData, void *)
static bool openxr_layer_is_available(const std::vector< XrApiLayerProperties > &layers_info, const std::string &layer_name)
static bool openxr_extension_is_available(const std::vector< XrExtensionProperties > &extensions_info, const std::string_view &extension_name)
GHOST_TXrOpenXRRuntimeID
@ OPENXR_RUNTIME_MONADO
@ OPENXR_RUNTIME_OCULUS
@ OPENXR_RUNTIME_STEAMVR
@ OPENXR_RUNTIME_WMR
@ OPENXR_RUNTIME_VARJO
#define CHECK_XR_ASSERT(call)
#define CHECK_XR(call, error_msg)
XrInstance getInstance() const
void setDisablePassthroughFunc(GHOST_XrDisablePassthroughFn disable_passthrough_fn) override
GHOST_TXrOpenXRRuntimeID getOpenXRRuntimeID() const
void setGraphicsContextBindFuncs(GHOST_XrGraphicsContextBindFn bind_fn, GHOST_XrGraphicsContextUnbindFn unbind_fn) override
GHOST_TXrGraphicsBinding getGraphicsBindingType() const
void drawSessionViews(void *draw_customdata) override
void handleSessionStateChange(const XrEventDataSessionStateChanged &lifecycle)
const GHOST_XrCustomFuncs & getCustomFuncs() const
void dispatchErrorMessage(const class GHOST_XrException *exception) const override
bool isDebugTimeMode() const
void setDrawViewFunc(GHOST_XrDrawViewFn draw_view_fn) override
bool needsUpsideDownDrawing() const override
bool isSessionRunning() const override
void startSession(const GHOST_XrSessionBeginInfo *begin_info) override
void endSession() override
bool isExtensionEnabled(const char *ext) const
GHOST_XrContext(const GHOST_XrContextCreateInfo *create_info)
bool isDebugMode() const
void initialize(const GHOST_XrContextCreateInfo *create_info)
static void setErrorHandler(GHOST_XrErrorHandlerFn handler_fn, void *customdata)
void setPassthroughEnabledFunc(GHOST_XrPassthroughEnabledFn passthrough_enabled_fn) override
GHOST_XrSession * getSession() override
#define assert(assertion)
#define printf(...)
static void error(const char *str)
XrDebugUtilsMessengerEXT debug_messenger
XrInstanceProperties instance_properties
std::vector< XrExtensionProperties > extensions
static PFN_xrDestroyDebugUtilsMessengerEXT s_xrDestroyDebugUtilsMessengerEXT_fn
std::vector< XrApiLayerProperties > layers
static PFN_xrCreateDebugUtilsMessengerEXT s_xrCreateDebugUtilsMessengerEXT_fn
i
Definition text_draw.cc:230