[Bf-blender-cvs] [b468023aa1b] master: VR: Properly support outputting sRGB swapchain buffers

Julian Eisel noreply at git.blender.org
Wed Jun 24 18:43:27 CEST 2020


Commit: b468023aa1b51b2cdef38cd651c7487b9f4d34c4
Author: Julian Eisel
Date:   Wed Jun 24 18:26:51 2020 +0200
Branches: master
https://developer.blender.org/rBb468023aa1b51b2cdef38cd651c7487b9f4d34c4

VR: Properly support outputting sRGB swapchain buffers

Latest SteamVR OpenXR updates brought OpenGL support, but only with sRGB
buffers. I think for DirectX it's the same now.
It's not a big issue for us to use sRGB buffers, so that's what I will
do for now. That way we shouldn't need hardcoded exceptions for specific
runtimes that don't transform linear buffers correctly.

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

M	intern/ghost/intern/GHOST_IXrGraphicsBinding.h
M	intern/ghost/intern/GHOST_XrGraphicsBinding.cpp
M	intern/ghost/intern/GHOST_XrSession.cpp
M	intern/ghost/intern/GHOST_XrSwapchain.cpp
M	intern/ghost/intern/GHOST_XrSwapchain.h

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

diff --git a/intern/ghost/intern/GHOST_IXrGraphicsBinding.h b/intern/ghost/intern/GHOST_IXrGraphicsBinding.h
index 5794a682023..b199c5f9b28 100644
--- a/intern/ghost/intern/GHOST_IXrGraphicsBinding.h
+++ b/intern/ghost/intern/GHOST_IXrGraphicsBinding.h
@@ -56,7 +56,8 @@ class GHOST_IXrGraphicsBinding {
                                         std::string *r_requirement_info) const = 0;
   virtual void initFromGhostContext(class GHOST_Context *ghost_ctx) = 0;
   virtual bool chooseSwapchainFormat(const std::vector<int64_t> &runtime_formats,
-                                     int64_t *r_result) const = 0;
+                                     int64_t &r_result,
+                                     bool &r_is_rgb_format) const = 0;
   virtual std::vector<XrSwapchainImageBaseHeader *> createSwapchainImages(
       uint32_t image_count) = 0;
   virtual void submitToSwapchainImage(XrSwapchainImageBaseHeader *swapchain_image,
diff --git a/intern/ghost/intern/GHOST_XrGraphicsBinding.cpp b/intern/ghost/intern/GHOST_XrGraphicsBinding.cpp
index 71e6af3fa4f..7d7405a974d 100644
--- a/intern/ghost/intern/GHOST_XrGraphicsBinding.cpp
+++ b/intern/ghost/intern/GHOST_XrGraphicsBinding.cpp
@@ -36,7 +36,7 @@
 
 static bool choose_swapchain_format_from_candidates(std::vector<int64_t> gpu_binding_formats,
                                                     std::vector<int64_t> runtime_formats,
-                                                    int64_t *r_result)
+                                                    int64_t &r_result)
 {
   if (gpu_binding_formats.empty()) {
     return false;
@@ -50,7 +50,7 @@ static bool choose_swapchain_format_from_candidates(std::vector<int64_t> gpu_bin
     return false;
   }
 
-  *r_result = *res;
+  r_result = *res;
   return true;
 }
 
@@ -132,10 +132,20 @@ class GHOST_XrGraphicsBindingOpenGL : public GHOST_IXrGraphicsBinding {
   }
 
   bool chooseSwapchainFormat(const std::vector<int64_t> &runtime_formats,
-                             int64_t *r_result) const override
+                             int64_t &r_result,
+                             bool &r_is_srgb_format) const override
   {
-    std::vector<int64_t> gpu_binding_formats = {GL_RGBA8};
-    return choose_swapchain_format_from_candidates(gpu_binding_formats, runtime_formats, r_result);
+    std::vector<int64_t> gpu_binding_formats = {
+        GL_RGBA8,
+        GL_SRGB8_ALPHA8,
+    };
+
+    if (choose_swapchain_format_from_candidates(gpu_binding_formats, runtime_formats, r_result)) {
+      r_is_srgb_format = (r_result == GL_SRGB8_ALPHA8);
+      return true;
+    }
+
+    return false;
   }
 
   std::vector<XrSwapchainImageBaseHeader *> createSwapchainImages(uint32_t image_count) override
@@ -248,10 +258,19 @@ class GHOST_XrGraphicsBindingD3D : public GHOST_IXrGraphicsBinding {
   }
 
   bool chooseSwapchainFormat(const std::vector<int64_t> &runtime_formats,
-                             int64_t *r_result) const override
+                             int64_t &r_result,
+                             bool &r_is_srgb_format) const override
   {
-    std::vector<int64_t> gpu_binding_formats = {DXGI_FORMAT_R8G8B8A8_UNORM};
-    return choose_swapchain_format_from_candidates(gpu_binding_formats, runtime_formats, r_result);
+    std::vector<int64_t> gpu_binding_formats = {
+        DXGI_FORMAT_R8G8B8A8_UNORM,
+        DXGI_FORMAT_R8G8B8A8_UNORM_SRGB,
+    };
+
+    if (choose_swapchain_format_from_candidates(gpu_binding_formats, runtime_formats, r_result)) {
+      r_is_srgb_format = (r_result == DXGI_FORMAT_R8G8B8A8_UNORM_SRGB);
+      return true;
+    }
+    return false;
   }
 
   std::vector<XrSwapchainImageBaseHeader *> createSwapchainImages(uint32_t image_count) override
diff --git a/intern/ghost/intern/GHOST_XrSession.cpp b/intern/ghost/intern/GHOST_XrSession.cpp
index 7ae819dbfb2..5a747b1e787 100644
--- a/intern/ghost/intern/GHOST_XrSession.cpp
+++ b/intern/ghost/intern/GHOST_XrSession.cpp
@@ -375,15 +375,6 @@ static void ghost_xr_draw_view_info_from_view(const XrView &view, GHOST_XrDrawVi
   r_info.fov.angle_down = view.fov.angleDown;
 }
 
-static bool ghost_xr_draw_view_expects_srgb_buffer(const GHOST_XrContext *context)
-{
-  /* Monado seems to be faulty and doesn't do OETF transform correctly. So expect a SRGB buffer to
-   * compensate. You get way too dark rendering without this, it's pretty obvious (even in the
-   * default startup scene). */
-  GHOST_TXrOpenXRRuntimeID runtime_id = context->getOpenXRRuntimeID();
-  return (runtime_id == OPENXR_RUNTIME_MONADO) || (runtime_id == OPENXR_RUNTIME_STEAMVR);
-}
-
 void GHOST_XrSession::drawView(GHOST_XrSwapchain &swapchain,
                                XrCompositionLayerProjectionView &r_proj_layer_view,
                                XrSpaceLocation &view_location,
@@ -398,7 +389,7 @@ void GHOST_XrSession::drawView(GHOST_XrSwapchain &swapchain,
   r_proj_layer_view.fov = view.fov;
   swapchain.updateCompositionLayerProjectViewSubImage(r_proj_layer_view.subImage);
 
-  draw_view_info.expects_srgb_buffer = ghost_xr_draw_view_expects_srgb_buffer(m_context);
+  draw_view_info.expects_srgb_buffer = swapchain.isBufferSRGB();
   draw_view_info.ofsx = r_proj_layer_view.subImage.imageRect.offset.x;
   draw_view_info.ofsy = r_proj_layer_view.subImage.imageRect.offset.y;
   draw_view_info.width = r_proj_layer_view.subImage.imageRect.extent.width;
diff --git a/intern/ghost/intern/GHOST_XrSwapchain.cpp b/intern/ghost/intern/GHOST_XrSwapchain.cpp
index f50cfde0687..f7808c20112 100644
--- a/intern/ghost/intern/GHOST_XrSwapchain.cpp
+++ b/intern/ghost/intern/GHOST_XrSwapchain.cpp
@@ -68,7 +68,7 @@ GHOST_XrSwapchain::GHOST_XrSwapchain(GHOST_IXrGraphicsBinding &gpu_binding,
            "Failed to get swapchain image formats.");
   assert(swapchain_formats.size() == format_count);
 
-  if (!gpu_binding.chooseSwapchainFormat(swapchain_formats, &chosen_format)) {
+  if (!gpu_binding.chooseSwapchainFormat(swapchain_formats, chosen_format, m_is_srgb_buffer)) {
     throw GHOST_XrException(
         "Error: No format matching OpenXR runtime supported swapchain formats found.");
   }
@@ -132,6 +132,11 @@ void GHOST_XrSwapchain::updateCompositionLayerProjectViewSubImage(XrSwapchainSub
   r_sub_image.imageRect.extent = {m_image_width, m_image_height};
 }
 
+bool GHOST_XrSwapchain::isBufferSRGB()
+{
+  return m_is_srgb_buffer;
+}
+
 void GHOST_XrSwapchain::releaseImage()
 {
   XrSwapchainImageReleaseInfo release_info = {XR_TYPE_SWAPCHAIN_IMAGE_RELEASE_INFO};
diff --git a/intern/ghost/intern/GHOST_XrSwapchain.h b/intern/ghost/intern/GHOST_XrSwapchain.h
index ab0a6736c9c..7a3e7fcea68 100644
--- a/intern/ghost/intern/GHOST_XrSwapchain.h
+++ b/intern/ghost/intern/GHOST_XrSwapchain.h
@@ -38,9 +38,12 @@ class GHOST_XrSwapchain {
 
   void updateCompositionLayerProjectViewSubImage(XrSwapchainSubImage &r_sub_image);
 
+  bool isBufferSRGB();
+
  private:
   std::unique_ptr<OpenXRSwapchainData> m_oxr; /* Could use stack, but PImpl is preferable. */
   int32_t m_image_width, m_image_height;
+  bool m_is_srgb_buffer = false;
 };
 
 #endif  // GHOST_XRSWAPCHAIN_H



More information about the Bf-blender-cvs mailing list