diff --git a/intern/ghost/intern/GHOST_XrContext.cpp b/intern/ghost/intern/GHOST_XrContext.cpp index 3aab420a9b6..a33c7bc6a30 100644 --- a/intern/ghost/intern/GHOST_XrContext.cpp +++ b/intern/ghost/intern/GHOST_XrContext.cpp @@ -88,18 +88,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 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 &graphics_binding_types) { XrInstanceCreateInfo create_info = {XR_TYPE_INSTANCE_CREATE_INFO}; @@ -108,7 +116,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(); @@ -392,14 +400,11 @@ 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 &r_ext_names) +void GHOST_XrContext::getExtensionsToEnable( + const std::vector &graphics_binding_types, + std::vector &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 try_ext; - - try_ext.clear(); + std::vector try_ext; /* Try enabling debug extension. */ #ifndef WIN32 @@ -408,12 +413,15 @@ void GHOST_XrContext::getExtensionsToEnable(std::vector &r_ext_nam } #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) { if (openxr_extension_is_available(m_oxr->extensions, ext)) { @@ -426,9 +434,10 @@ void GHOST_XrContext::getExtensionsToEnable(std::vector &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_XrContext::determineGraphicsBindingTypesToEnable( const GHOST_XrContextCreateInfo *create_info) { + std::vector result; assert(create_info->gpu_binding_candidates != NULL); assert(create_info->gpu_binding_candidates_count > 0); @@ -437,11 +446,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 &enabled_types) +{ + /* Return the first working type. */ + for (GHOST_TXrGraphicsBinding type : enabled_types) { +#if 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 */ diff --git a/intern/ghost/intern/GHOST_XrContext.h b/intern/ghost/intern/GHOST_XrContext.h index 7dbd0a0d011..47a22003daf 100644 --- a/intern/ghost/intern/GHOST_XrContext.h +++ b/intern/ghost/intern/GHOST_XrContext.h @@ -114,7 +114,7 @@ class GHOST_XrContext : public GHOST_IXrContext { bool m_debug = false; bool m_debug_time = false; - void createOpenXRInstance(); + void createOpenXRInstance(const std::vector &graphics_binding_types); void storeInstanceProperties(); void initDebugMessenger(); @@ -126,9 +126,12 @@ class GHOST_XrContext : public GHOST_IXrContext { void initExtensions(); void initExtensionsEx(std::vector &extensions, const char *layer_name); void getAPILayersToEnable(std::vector &r_ext_names); - void getExtensionsToEnable(std::vector &r_ext_names); - GHOST_TXrGraphicsBinding determineGraphicsBindingTypeToEnable( + void getExtensionsToEnable(const std::vector &graphics_binding_types, + std::vector &r_ext_names); + std::vector determineGraphicsBindingTypesToEnable( const GHOST_XrContextCreateInfo *create_info); + GHOST_TXrGraphicsBinding determineGraphicsBindingTypeToUse( + const std::vector &enabled_types); }; #endif // __GHOST_XRCONTEXT_H__ diff --git a/intern/ghost/intern/GHOST_XrSwapchain.cpp b/intern/ghost/intern/GHOST_XrSwapchain.cpp index f7808c20112..2f900c853ba 100644 --- a/intern/ghost/intern/GHOST_XrSwapchain.cpp +++ b/intern/ghost/intern/GHOST_XrSwapchain.cpp @@ -95,7 +95,8 @@ GHOST_XrSwapchain::GHOST_XrSwapchain(GHOST_IXrGraphicsBinding &gpu_binding, GHOST_XrSwapchain::GHOST_XrSwapchain(GHOST_XrSwapchain &&other) : m_oxr(std::move(other.m_oxr)), m_image_width(other.m_image_width), - m_image_height(other.m_image_height) + m_image_height(other.m_image_height), + m_is_srgb_buffer(other.m_is_srgb_buffer) { /* Prevent xrDestroySwapchain call for the moved out item. */ other.m_oxr = nullptr;