diff options
Diffstat (limited to 'intern/ghost/intern/GHOST_XrContext.cpp')
-rw-r--r-- | intern/ghost/intern/GHOST_XrContext.cpp | 91 |
1 files changed, 62 insertions, 29 deletions
diff --git a/intern/ghost/intern/GHOST_XrContext.cpp b/intern/ghost/intern/GHOST_XrContext.cpp index 16687c34679..583bda9731a 100644 --- a/intern/ghost/intern/GHOST_XrContext.cpp +++ b/intern/ghost/intern/GHOST_XrContext.cpp @@ -23,6 +23,7 @@ #include <cassert> #include <sstream> #include <string> +#include <string_view> #include "GHOST_Types.h" #include "GHOST_XrException.h" @@ -58,7 +59,7 @@ void *GHOST_XrContext::s_error_handler_customdata = nullptr; * \{ */ GHOST_XrContext::GHOST_XrContext(const GHOST_XrContextCreateInfo *create_info) - : m_oxr(new OpenXRInstanceData()), + : m_oxr(std::make_unique<OpenXRInstanceData>()), m_debug(create_info->context_flag & GHOST_kXrContextDebug), m_debug_time(create_info->context_flag & GHOST_kXrContextDebugTime) { @@ -88,18 +89,26 @@ void GHOST_XrContext::initialize(const GHOST_XrContextCreateInfo *create_info) printAvailableAPILayersAndExtensionsInfo(); } - m_gpu_binding_type = determineGraphicsBindingTypeToEnable(create_info); + /* Multiple graphics binding extensions can be enabled, but only one will actually be used + * (determined later on). */ + const std::vector<GHOST_TXrGraphicsBinding> graphics_binding_types = + determineGraphicsBindingTypesToEnable(create_info); assert(m_oxr->instance == XR_NULL_HANDLE); - createOpenXRInstance(); + createOpenXRInstance(graphics_binding_types); storeInstanceProperties(); + + /* Multiple bindings may be enabled. Now that we know the runtime in use, settle for one. */ + m_gpu_binding_type = determineGraphicsBindingTypeToUse(graphics_binding_types); + printInstanceInfo(); if (isDebugMode()) { initDebugMessenger(); } } -void GHOST_XrContext::createOpenXRInstance() +void GHOST_XrContext::createOpenXRInstance( + const std::vector<GHOST_TXrGraphicsBinding> &graphics_binding_types) { XrInstanceCreateInfo create_info = {XR_TYPE_INSTANCE_CREATE_INFO}; @@ -108,7 +117,7 @@ void GHOST_XrContext::createOpenXRInstance() create_info.applicationInfo.apiVersion = XR_CURRENT_API_VERSION; getAPILayersToEnable(m_enabled_layers); - getExtensionsToEnable(m_enabled_extensions); + getExtensionsToEnable(graphics_binding_types, m_enabled_extensions); create_info.enabledApiLayerCount = m_enabled_layers.size(); create_info.enabledApiLayerNames = m_enabled_layers.data(); create_info.enabledExtensionCount = m_enabled_extensions.size(); @@ -327,7 +336,7 @@ void GHOST_XrContext::initApiLayers() } } -static bool openxr_layer_is_available(const std::vector<XrApiLayerProperties> layers_info, +static bool openxr_layer_is_available(const std::vector<XrApiLayerProperties> &layers_info, const std::string &layer_name) { for (const XrApiLayerProperties &layer_info : layers_info) { @@ -339,8 +348,9 @@ static bool openxr_layer_is_available(const std::vector<XrApiLayerProperties> la return false; } -static bool openxr_extension_is_available(const std::vector<XrExtensionProperties> extensions_info, - const std::string &extension_name) +static bool openxr_extension_is_available( + const std::vector<XrExtensionProperties> &extensions_info, + const std::string_view &extension_name) { for (const XrExtensionProperties &ext_info : extensions_info) { if (ext_info.extensionName == extension_name) { @@ -393,32 +403,30 @@ static const char *openxr_ext_name_from_wm_gpu_binding(GHOST_TXrGraphicsBinding /** * Gather an array of names for the extensions to enable. */ -void GHOST_XrContext::getExtensionsToEnable(std::vector<const char *> &r_ext_names) +void GHOST_XrContext::getExtensionsToEnable( + const std::vector<GHOST_TXrGraphicsBinding> &graphics_binding_types, + std::vector<const char *> &r_ext_names) { - assert(m_gpu_binding_type != GHOST_kXrGraphicsUnknown); - - const char *gpu_binding = openxr_ext_name_from_wm_gpu_binding(m_gpu_binding_type); - static std::vector<std::string> try_ext; - - try_ext.clear(); + std::vector<std::string_view> try_ext; /* Try enabling debug extension. */ -#ifndef WIN32 if (isDebugMode()) { try_ext.push_back(XR_EXT_DEBUG_UTILS_EXTENSION_NAME); } -#endif - r_ext_names.reserve(try_ext.size() + 1); /* + 1 for graphics binding extension. */ + r_ext_names.reserve(try_ext.size() + graphics_binding_types.size()); - /* Add graphics binding extension. */ - assert(gpu_binding); - assert(openxr_extension_is_available(m_oxr->extensions, gpu_binding)); - r_ext_names.push_back(gpu_binding); + /* Add graphics binding extensions (may be multiple ones, we'll settle for one to use later, once + * we have more info about the runtime). */ + for (GHOST_TXrGraphicsBinding type : graphics_binding_types) { + const char *gpu_binding = openxr_ext_name_from_wm_gpu_binding(type); + assert(openxr_extension_is_available(m_oxr->extensions, gpu_binding)); + r_ext_names.push_back(gpu_binding); + } - for (const std::string &ext : try_ext) { + for (const std::string_view &ext : try_ext) { if (openxr_extension_is_available(m_oxr->extensions, ext)) { - r_ext_names.push_back(ext.c_str()); + r_ext_names.push_back(ext.data()); } } } @@ -427,9 +435,10 @@ void GHOST_XrContext::getExtensionsToEnable(std::vector<const char *> &r_ext_nam * Decide which graphics binding extension to use based on * #GHOST_XrContextCreateInfo.gpu_binding_candidates and available extensions. */ -GHOST_TXrGraphicsBinding GHOST_XrContext::determineGraphicsBindingTypeToEnable( +std::vector<GHOST_TXrGraphicsBinding> GHOST_XrContext::determineGraphicsBindingTypesToEnable( const GHOST_XrContextCreateInfo *create_info) { + std::vector<GHOST_TXrGraphicsBinding> result; assert(create_info->gpu_binding_candidates != NULL); assert(create_info->gpu_binding_candidates_count > 0); @@ -438,11 +447,35 @@ GHOST_TXrGraphicsBinding GHOST_XrContext::determineGraphicsBindingTypeToEnable( const char *ext_name = openxr_ext_name_from_wm_gpu_binding( create_info->gpu_binding_candidates[i]); if (openxr_extension_is_available(m_oxr->extensions, ext_name)) { - return create_info->gpu_binding_candidates[i]; + result.push_back(create_info->gpu_binding_candidates[i]); } } - return GHOST_kXrGraphicsUnknown; + if (result.empty()) { + throw GHOST_XrException("No supported graphics binding found."); + } + + return result; +} + +GHOST_TXrGraphicsBinding GHOST_XrContext::determineGraphicsBindingTypeToUse( + const std::vector<GHOST_TXrGraphicsBinding> &enabled_types) +{ + /* Return the first working type. */ + for (GHOST_TXrGraphicsBinding type : enabled_types) { +#ifdef WIN32 + /* The SteamVR OpenGL backend fails currently. Disable it and allow falling back to the DirectX + * one. */ + if ((m_runtime_id == OPENXR_RUNTIME_STEAMVR) && (type == GHOST_kXrGraphicsOpenGL)) { + continue; + } +#endif + + assert(type != GHOST_kXrGraphicsUnknown); + return type; + } + + throw GHOST_XrException("Failed to determine a graphics binding to use."); } /** \} */ /* OpenXR API-Layers and Extensions */ @@ -459,7 +492,7 @@ void GHOST_XrContext::startSession(const GHOST_XrSessionBeginInfo *begin_info) m_custom_funcs.session_exit_customdata = begin_info->exit_customdata; if (m_session == nullptr) { - m_session = std::unique_ptr<GHOST_XrSession>(new GHOST_XrSession(this)); + m_session = std::make_unique<GHOST_XrSession>(*this); } m_session->start(begin_info); } @@ -489,7 +522,7 @@ void GHOST_XrContext::drawSessionViews(void *draw_customdata) /** * Delegates event to session, allowing context to destruct the session if needed. */ -void GHOST_XrContext::handleSessionStateChange(const XrEventDataSessionStateChanged *lifecycle) +void GHOST_XrContext::handleSessionStateChange(const XrEventDataSessionStateChanged &lifecycle) { if (m_session && m_session->handleStateChangeEvent(lifecycle) == GHOST_XrSession::SESSION_DESTROY) { |