[Bf-blender-cvs] [fe492d922d6] blender-v2.83-release: Fix/workaround graphics issues breaking SteamVR use with Blender

Julian Eisel noreply at git.blender.org
Wed Aug 26 11:57:21 CEST 2020


Commit: fe492d922d6d2f13bd04369c8a349c87e0b59233
Author: Julian Eisel
Date:   Fri Aug 14 15:38:49 2020 +0200
Branches: blender-v2.83-release
https://developer.blender.org/rBfe492d922d6d2f13bd04369c8a349c87e0b59233

Fix/workaround graphics issues breaking SteamVR use with Blender

Windows only workaround. I'll have to investigate Linux separately.

Steam's OpenGL compatibility is still new and doesn't work for us yet
(neither does it for standard OpenXR examples from what I've heard and
seen myself). We can work around that by falling back to our DirectX
compatibility layer.
Note that this DirectX compatibility still doesn't work for some
systems, see T76082.

Implementation note: Since the graphics binding extensions have to be
enabled before we can find out which runtime is in use (e.g. SteamVR vs.
Oculus, etc), we can now enable multiple graphics binding extensions but
settle for a single one to use later.

Once the SteamVR OpenGL backend works, we can remove this workaround
again.

Fixes T78267.

===================================================================

M	intern/ghost/intern/GHOST_XrContext.cpp
M	intern/ghost/intern/GHOST_XrContext.h
M	intern/ghost/intern/GHOST_XrSwapchain.cpp

===================================================================

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<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 +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<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> try_ext;
 
   /* Try enabling debug extension. */
 #ifndef WIN32
@@ -408,12 +413,15 @@ void GHOST_XrContext::getExtensionsToEnable(std::vector<const char *> &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<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);
 
@@ -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<GHOST_TXrGraphicsBinding> &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<GHOST_TXrGraphicsBinding> &graphics_binding_types);
   void storeInstanceProperties();
   void initDebugMessenger();
 
@@ -126,9 +126,12 @@ class GHOST_XrContext : public GHOST_IXrContext {
   void initExtensions();
   void initExtensionsEx(std::vector<XrExtensionProperties> &extensions, const char *layer_name);
   void getAPILayersToEnable(std::vector<const char *> &r_ext_names);
-  void getExtensionsToEnable(std::vector<const char *> &r_ext_names);
-  GHOST_TXrGraphicsBinding determineGraphicsBindingTypeToEnable(
+  void getExtensionsToEnable(const std::vector<GHOST_TXrGraphicsBinding> &graphics_binding_types,
+                             std::vector<const char *> &r_ext_names);
+  std::vector<GHOST_TXrGraphicsBinding> determineGraphicsBindingTypesToEnable(
       const GHOST_XrContextCreateInfo *create_info);
+  GHOST_TXrGraphicsBinding determineGraphicsBindingTypeToUse(
+      const std::vector<GHOST_TXrGraphicsBinding> &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;



More information about the Bf-blender-cvs mailing list