13 #include <string_view>
27 std::vector<XrApiLayerProperties>
layers;
40 GHOST_XrErrorHandlerFn GHOST_XrContext::s_error_handler =
nullptr;
41 void *GHOST_XrContext::s_error_handler_customdata =
nullptr;
49 m_debug(create_info->context_flag & GHOST_kXrContextDebug),
50 m_debug_time(create_info->context_flag & GHOST_kXrContextDebugTime)
60 if (m_oxr->debug_messenger != XR_NULL_HANDLE) {
61 assert(m_oxr->s_xrDestroyDebugUtilsMessengerEXT_fn !=
nullptr);
62 m_oxr->s_xrDestroyDebugUtilsMessengerEXT_fn(m_oxr->debug_messenger);
64 if (m_oxr->instance != XR_NULL_HANDLE) {
66 m_oxr->instance = XR_NULL_HANDLE;
76 printAvailableAPILayersAndExtensionsInfo();
81 const std::vector<GHOST_TXrGraphicsBinding> graphics_binding_types =
82 determineGraphicsBindingTypesToEnable(create_info);
84 assert(m_oxr->instance == XR_NULL_HANDLE);
85 createOpenXRInstance(graphics_binding_types);
86 storeInstanceProperties();
89 m_gpu_binding_type = determineGraphicsBindingTypeToUse(graphics_binding_types, create_info);
97 void GHOST_XrContext::createOpenXRInstance(
98 const std::vector<GHOST_TXrGraphicsBinding> &graphics_binding_types)
100 XrInstanceCreateInfo create_info = {XR_TYPE_INSTANCE_CREATE_INFO};
102 std::string(
"Blender").copy(create_info.applicationInfo.applicationName,
103 XR_MAX_APPLICATION_NAME_SIZE);
104 create_info.applicationInfo.apiVersion = XR_CURRENT_API_VERSION;
106 getAPILayersToEnable(m_enabled_layers);
107 getExtensionsToEnable(graphics_binding_types, m_enabled_extensions);
108 create_info.enabledApiLayerCount = m_enabled_layers.size();
109 create_info.enabledApiLayerNames = m_enabled_layers.data();
110 create_info.enabledExtensionCount = m_enabled_extensions.size();
111 create_info.enabledExtensionNames = m_enabled_extensions.data();
113 printExtensionsAndAPILayersToEnable();
116 CHECK_XR(xrCreateInstance(&create_info, &m_oxr->instance),
117 "Failed to connect to an OpenXR runtime.");
120 void GHOST_XrContext::storeInstanceProperties()
122 const std::map<std::string, GHOST_TXrOpenXRRuntimeID> runtime_map = {
128 decltype(runtime_map)::const_iterator runtime_map_iter;
130 m_oxr->instance_properties.type = XR_TYPE_INSTANCE_PROPERTIES;
131 CHECK_XR(xrGetInstanceProperties(m_oxr->instance, &m_oxr->instance_properties),
132 "Failed to get OpenXR runtime information. Do you have an active runtime set up?");
134 runtime_map_iter = runtime_map.find(m_oxr->instance_properties.runtimeName);
135 if (runtime_map_iter != runtime_map.end()) {
136 m_runtime_id = runtime_map_iter->second;
146 void GHOST_XrContext::printSDKVersion()
148 const XrVersion sdk_version = XR_CURRENT_API_VERSION;
150 printf(
"OpenXR SDK Version: %u.%u.%u\n",
151 XR_VERSION_MAJOR(sdk_version),
152 XR_VERSION_MINOR(sdk_version),
153 XR_VERSION_PATCH(sdk_version));
156 void GHOST_XrContext::printInstanceInfo()
158 assert(m_oxr->instance != XR_NULL_HANDLE);
160 printf(
"Connected to OpenXR runtime: %s (Version %u.%u.%u)\n",
161 m_oxr->instance_properties.runtimeName,
162 XR_VERSION_MAJOR(m_oxr->instance_properties.runtimeVersion),
163 XR_VERSION_MINOR(m_oxr->instance_properties.runtimeVersion),
164 XR_VERSION_PATCH(m_oxr->instance_properties.runtimeVersion));
167 void GHOST_XrContext::printAvailableAPILayersAndExtensionsInfo()
169 puts(
"Available OpenXR API-layers/extensions:");
170 for (XrApiLayerProperties &layer_info : m_oxr->layers) {
171 printf(
"Layer: %s\n", layer_info.layerName);
173 for (XrExtensionProperties &ext_info : m_oxr->extensions) {
174 printf(
"Extension: %s\n", ext_info.extensionName);
178 void GHOST_XrContext::printExtensionsAndAPILayersToEnable()
180 for (
const char *layer_name : m_enabled_layers) {
181 printf(
"Enabling OpenXR API-Layer: %s\n", layer_name);
183 for (
const char *ext_name : m_enabled_extensions) {
184 printf(
"Enabling OpenXR Extension: %s\n", ext_name);
189 XrDebugUtilsMessageTypeFlagsEXT ,
190 const XrDebugUtilsMessengerCallbackDataEXT *callbackData,
193 puts(
"OpenXR Debug Message:");
194 puts(callbackData->message);
198 void GHOST_XrContext::initDebugMessenger()
200 XrDebugUtilsMessengerCreateInfoEXT create_info = {XR_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT};
203 if (XR_FAILED(xrGetInstanceProcAddr(
205 "xrCreateDebugUtilsMessengerEXT",
206 (PFN_xrVoidFunction *)&m_oxr->s_xrCreateDebugUtilsMessengerEXT_fn)) ||
207 XR_FAILED(xrGetInstanceProcAddr(
209 "xrDestroyDebugUtilsMessengerEXT",
210 (PFN_xrVoidFunction *)&m_oxr->s_xrDestroyDebugUtilsMessengerEXT_fn))) {
211 m_oxr->s_xrCreateDebugUtilsMessengerEXT_fn =
nullptr;
212 m_oxr->s_xrDestroyDebugUtilsMessengerEXT_fn =
nullptr;
215 "Could not use XR_EXT_debug_utils to enable debug prints. Not a fatal error, "
216 "continuing without the messenger.\n");
220 create_info.messageSeverities = XR_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT |
221 XR_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT |
222 XR_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT |
223 XR_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT;
224 create_info.messageTypes = XR_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT |
225 XR_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT |
226 XR_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT;
229 if (XR_FAILED(m_oxr->s_xrCreateDebugUtilsMessengerEXT_fn(
230 m_oxr->instance, &create_info, &m_oxr->debug_messenger))) {
232 "Failed to create OpenXR debug messenger. Not a fatal error, continuing without the "
248 error.user_message = exception->m_msg.data();
249 error.customdata = s_error_handler_customdata;
253 "Error: \t%s\n\tOpenXR error value: %i\n",
255 exception->m_result);
259 s_error_handler(&
error);
264 s_error_handler = handler_fn;
265 s_error_handler_customdata = customdata;
277 void GHOST_XrContext::initExtensionsEx(std::vector<XrExtensionProperties> &extensions,
278 const char *layer_name)
283 CHECK_XR(xrEnumerateInstanceExtensionProperties(layer_name, 0, &extension_count,
nullptr),
284 "Failed to query OpenXR runtime information. Do you have an active runtime set up?");
286 if (extension_count == 0) {
291 for (
uint32_t i = 0; i < extension_count; i++) {
292 XrExtensionProperties ext = {XR_TYPE_EXTENSION_PROPERTIES};
293 extensions.push_back(ext);
297 CHECK_XR(xrEnumerateInstanceExtensionProperties(
298 layer_name, extension_count, &extension_count, extensions.data()),
299 "Failed to query OpenXR runtime information. Do you have an active runtime set up?");
302 void GHOST_XrContext::initExtensions()
304 initExtensionsEx(m_oxr->extensions,
nullptr);
307 void GHOST_XrContext::initApiLayers()
312 CHECK_XR(xrEnumerateApiLayerProperties(0, &layer_count,
nullptr),
313 "Failed to query OpenXR runtime information. Do you have an active runtime set up?");
315 if (layer_count == 0) {
320 m_oxr->layers = std::vector<XrApiLayerProperties>(layer_count);
321 for (XrApiLayerProperties &layer : m_oxr->layers) {
322 layer.type = XR_TYPE_API_LAYER_PROPERTIES;
326 CHECK_XR(xrEnumerateApiLayerProperties(layer_count, &layer_count, m_oxr->layers.data()),
327 "Failed to query OpenXR runtime information. Do you have an active runtime set up?");
328 for (XrApiLayerProperties &layer : m_oxr->layers) {
330 initExtensionsEx(m_oxr->extensions, layer.layerName);
335 const std::string &layer_name)
337 for (
const XrApiLayerProperties &layer_info : layers_info) {
338 if (layer_info.layerName == layer_name) {
347 const std::vector<XrExtensionProperties> &extensions_info,
348 const std::string_view &extension_name)
350 for (
const XrExtensionProperties &ext_info : extensions_info) {
351 if (ext_info.extensionName == extension_name) {
362 void GHOST_XrContext::getAPILayersToEnable(std::vector<const char *> &r_ext_names)
364 static std::vector<std::string> try_layers;
369 try_layers.push_back(
"XR_APILAYER_LUNARG_core_validation");
372 r_ext_names.reserve(try_layers.size());
374 for (
const std::string &layer : try_layers) {
376 r_ext_names.push_back(layer.data());
384 case GHOST_kXrGraphicsOpenGL:
385 return XR_KHR_OPENGL_ENABLE_EXTENSION_NAME;
387 case GHOST_kXrGraphicsD3D11:
388 return XR_KHR_D3D11_ENABLE_EXTENSION_NAME;
390 case GHOST_kXrGraphicsUnknown:
391 assert(!
"Could not identify graphics binding to choose.");
401 void GHOST_XrContext::getExtensionsToEnable(
402 const std::vector<GHOST_TXrGraphicsBinding> &graphics_binding_types,
403 std::vector<const char *> &r_ext_names)
405 std::vector<std::string_view> try_ext;
409 try_ext.push_back(XR_EXT_DEBUG_UTILS_EXTENSION_NAME);
413 try_ext.push_back(XR_EXT_HP_MIXED_REALITY_CONTROLLER_EXTENSION_NAME);
414 try_ext.push_back(XR_HTC_VIVE_COSMOS_CONTROLLER_INTERACTION_EXTENSION_NAME);
415 #ifdef XR_HTC_VIVE_FOCUS3_CONTROLLER_INTERACTION_EXTENSION_NAME
416 try_ext.push_back(XR_HTC_VIVE_FOCUS3_CONTROLLER_INTERACTION_EXTENSION_NAME);
418 try_ext.push_back(XR_HUAWEI_CONTROLLER_INTERACTION_EXTENSION_NAME);
421 try_ext.push_back(XR_MSFT_CONTROLLER_MODEL_EXTENSION_NAME);
424 try_ext.push_back(XR_VARJO_QUAD_VIEWS_EXTENSION_NAME);
427 try_ext.push_back(XR_VARJO_FOVEATED_RENDERING_EXTENSION_NAME);
429 r_ext_names.reserve(try_ext.size() + graphics_binding_types.size());
433 for (GHOST_TXrGraphicsBinding
type : graphics_binding_types) {
436 r_ext_names.push_back(gpu_binding);
439 #if defined(WITH_GHOST_X11) && defined(WITH_GL_EGL)
441 r_ext_names.push_back(XR_MNDX_EGL_ENABLE_EXTENSION_NAME);
444 for (
const std::string_view &ext : try_ext) {
446 r_ext_names.push_back(ext.data());
455 std::vector<GHOST_TXrGraphicsBinding> GHOST_XrContext::determineGraphicsBindingTypesToEnable(
456 const GHOST_XrContextCreateInfo *create_info)
458 std::vector<GHOST_TXrGraphicsBinding>
result;
459 assert(create_info->gpu_binding_candidates !=
NULL);
460 assert(create_info->gpu_binding_candidates_count > 0);
462 for (
uint32_t i = 0; i < create_info->gpu_binding_candidates_count; i++) {
463 assert(create_info->gpu_binding_candidates[i] != GHOST_kXrGraphicsUnknown);
465 create_info->gpu_binding_candidates[i]);
467 result.push_back(create_info->gpu_binding_candidates[i]);
478 GHOST_TXrGraphicsBinding GHOST_XrContext::determineGraphicsBindingTypeToUse(
479 const std::vector<GHOST_TXrGraphicsBinding> &enabled_types,
480 const GHOST_XrContextCreateInfo *create_info)
483 for (GHOST_TXrGraphicsBinding
type : enabled_types) {
488 ((create_info->context_flag & GHOST_kXrContextGpuNVIDIA) != 0)) {
495 assert(
type != GHOST_kXrGraphicsUnknown);
516 if (m_session ==
nullptr) {
517 m_session = std::make_unique<GHOST_XrSession>(*
this);
519 m_session->start(begin_info);
525 if (m_session->isRunning()) {
526 m_session->requestEnd();
536 return m_session && m_session->isRunning();
541 m_session->draw(draw_customdata);
565 return m_session.get();
570 return m_session.get();
574 GHOST_XrGraphicsContextUnbindFn unbind_fn)
577 m_session->unbindGraphicsContext();
592 return m_session->needsUpsideDownDrawing();
608 return m_custom_funcs;
613 return m_gpu_binding_type;
618 return m_oxr->instance;
633 bool contains = std::find(m_enabled_extensions.begin(), m_enabled_extensions.end(), ext) !=
634 m_enabled_extensions.end();
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 const char * openxr_ext_name_from_wm_gpu_binding(GHOST_TXrGraphicsBinding binding)
static bool openxr_extension_is_available(const std::vector< XrExtensionProperties > &extensions_info, const std::string_view &extension_name)
#define CHECK_XR_ASSERT(call)
#define CHECK_XR(call, error_msg)
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum type
XrInstance getInstance() const
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)
void initialize(const GHOST_XrContextCreateInfo *create_info)
static void setErrorHandler(GHOST_XrErrorHandlerFn handler_fn, void *customdata)
GHOST_XrSession * getSession() override
SyclQueue void void size_t num_bytes void
static void error(const char *str)
bool contains(const void *owner, const blender::bke::AttributeIDRef &attribute_id)
GHOST_XrDrawViewFn draw_view_fn
GHOST_XrSessionExitFn session_exit_fn
GHOST_XrSessionCreateFn session_create_fn
void * session_exit_customdata
GHOST_XrGraphicsContextUnbindFn gpu_ctx_unbind_fn
GHOST_XrGraphicsContextBindFn gpu_ctx_bind_fn
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