[Bf-blender-cvs] [5350015d519] soc-2019-openxr: Fix dark VR rendering on Windows Mixed Reality by appyling SRGB OETF

Julian Eisel noreply at git.blender.org
Wed Aug 7 12:30:58 CEST 2019


Commit: 5350015d519ec299b9a8937e4e035fe405001d8d
Author: Julian Eisel
Date:   Wed Aug 7 11:52:30 2019 +0200
Branches: soc-2019-openxr
https://developer.blender.org/rB5350015d519ec299b9a8937e4e035fe405001d8d

Fix dark VR rendering on Windows Mixed Reality by appyling SRGB OETF

Discussed this in length with @sobotka, and it seems WMR has an utterly
broken pixel color pipeline. So we apply a SRGB OETF for this specific
runtime to compensate.

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

M	intern/ghost/GHOST_Types.h
M	intern/ghost/intern/GHOST_XrSession.cpp
M	source/blender/gpu/GPU_shader.h
M	source/blender/gpu/GPU_viewport.h
M	source/blender/gpu/intern/gpu_shader.c
M	source/blender/gpu/intern/gpu_viewport.c
M	source/blender/windowmanager/intern/wm_draw.c
M	source/blender/windowmanager/intern/wm_xr.c
M	source/blender/windowmanager/wm.h

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

diff --git a/intern/ghost/GHOST_Types.h b/intern/ghost/GHOST_Types.h
index b7ccb59a3a5..ede2de1f6da 100644
--- a/intern/ghost/GHOST_Types.h
+++ b/intern/ghost/GHOST_Types.h
@@ -615,6 +615,9 @@ typedef struct {
     float angle_left, angle_right;
     float angle_up, angle_down;
   } fov;
+
+  /** Set if the buffer should be submitted with a srgb transfer applied. */
+  char expects_srgb_buffer;
 } GHOST_XrDrawViewInfo;
 
 typedef struct {
diff --git a/intern/ghost/intern/GHOST_XrSession.cpp b/intern/ghost/intern/GHOST_XrSession.cpp
index dee175632b5..f2f01a9b354 100644
--- a/intern/ghost/intern/GHOST_XrSession.cpp
+++ b/intern/ghost/intern/GHOST_XrSession.cpp
@@ -418,6 +418,13 @@ static void ghost_xr_draw_view_info_from_view(const XrView &view, GHOST_XrDrawVi
   r_info.fov.angle_down = view.fov.angleDown;
 }
 
+bool ghost_xr_draw_view_expects_srgb_buffer(const GHOST_XrContext *context)
+{
+  /* WMR seems to be faulty and doesn't do OETF transform correctly. So expect a SRGB buffer to
+   * compensate. */
+  return context->getOpenXRRuntimeID() == OPENXR_RUNTIME_WMR;
+}
+
 void GHOST_XrSession::drawView(XrSwapchain swapchain,
                                XrCompositionLayerProjectionView &proj_layer_view,
                                XrView &view,
@@ -447,6 +454,7 @@ void GHOST_XrSession::drawView(XrSwapchain swapchain,
 
   swapchain_image = m_oxr->swapchain_images[swapchain][swapchain_idx];
 
+  draw_view_info.expects_srgb_buffer = ghost_xr_draw_view_expects_srgb_buffer(m_context);
   draw_view_info.ofsx = proj_layer_view.subImage.imageRect.offset.x;
   draw_view_info.ofsy = proj_layer_view.subImage.imageRect.offset.y;
   draw_view_info.width = proj_layer_view.subImage.imageRect.extent.width;
diff --git a/source/blender/gpu/GPU_shader.h b/source/blender/gpu/GPU_shader.h
index 124f1f1ff8a..01b679453a7 100644
--- a/source/blender/gpu/GPU_shader.h
+++ b/source/blender/gpu/GPU_shader.h
@@ -185,6 +185,7 @@ typedef enum eGPUBuiltinShader {
   GPU_SHADER_3D_CLIPPED_UNIFORM_COLOR,
   /* basic image drawing */
   GPU_SHADER_2D_IMAGE_LINEAR_TO_SRGB,
+  GPU_SHADER_2D_IMAGE_RECT_LINEAR_TO_SRGB,
   GPU_SHADER_2D_IMAGE_SHUFFLE_COLOR,
   GPU_SHADER_2D_IMAGE_MASK_UNIFORM_COLOR,
   /**
diff --git a/source/blender/gpu/GPU_viewport.h b/source/blender/gpu/GPU_viewport.h
index e7600279d6f..00e6e018761 100644
--- a/source/blender/gpu/GPU_viewport.h
+++ b/source/blender/gpu/GPU_viewport.h
@@ -93,6 +93,7 @@ GPUViewport *GPU_viewport_create(void);
 void GPU_viewport_bind(GPUViewport *viewport, const rcti *rect);
 void GPU_viewport_unbind(GPUViewport *viewport);
 void GPU_viewport_draw_to_screen(GPUViewport *viewport, const rcti *rect);
+void GPU_viewport_draw_to_screen_ex(GPUViewport *viewport, const rcti *rect, bool to_srgb);
 void GPU_viewport_free(GPUViewport *viewport);
 
 GPUViewport *GPU_viewport_create_from_offscreen(struct GPUOffScreen *ofs);
diff --git a/source/blender/gpu/intern/gpu_shader.c b/source/blender/gpu/intern/gpu_shader.c
index 3e930d19696..35a479b05c0 100644
--- a/source/blender/gpu/intern/gpu_shader.c
+++ b/source/blender/gpu/intern/gpu_shader.c
@@ -1015,6 +1015,11 @@ static const GPUShaderStages builtin_shader_stages[GPU_SHADER_BUILTIN_LEN] = {
             .vert = datatoc_gpu_shader_2D_image_vert_glsl,
             .frag = datatoc_gpu_shader_image_linear_frag_glsl,
         },
+    [GPU_SHADER_2D_IMAGE_RECT_LINEAR_TO_SRGB] =
+        {
+            .vert = datatoc_gpu_shader_2D_image_rect_vert_glsl,
+            .frag = datatoc_gpu_shader_image_linear_frag_glsl,
+        },
     [GPU_SHADER_2D_IMAGE] =
         {
             .vert = datatoc_gpu_shader_2D_image_vert_glsl,
diff --git a/source/blender/gpu/intern/gpu_viewport.c b/source/blender/gpu/intern/gpu_viewport.c
index e3c13b0ec14..9d87922aa3c 100644
--- a/source/blender/gpu/intern/gpu_viewport.c
+++ b/source/blender/gpu/intern/gpu_viewport.c
@@ -505,7 +505,7 @@ void GPU_viewport_bind(GPUViewport *viewport, const rcti *rect)
   }
 }
 
-void GPU_viewport_draw_to_screen(GPUViewport *viewport, const rcti *rect)
+void GPU_viewport_draw_to_screen_ex(GPUViewport *viewport, const rcti *rect, bool to_srgb)
 {
   DefaultFramebufferList *dfbl = viewport->fbl;
 
@@ -532,7 +532,8 @@ void GPU_viewport_draw_to_screen(GPUViewport *viewport, const rcti *rect)
   float y1 = rect->ymin;
   float y2 = rect->ymin + h;
 
-  GPUShader *shader = GPU_shader_get_builtin_shader(GPU_SHADER_2D_IMAGE_RECT_COLOR);
+  GPUShader *shader = GPU_shader_get_builtin_shader(
+      to_srgb ? GPU_SHADER_2D_IMAGE_RECT_LINEAR_TO_SRGB : GPU_SHADER_2D_IMAGE_RECT_COLOR);
   GPU_shader_bind(shader);
 
   GPU_texture_bind(color, 0);
@@ -550,6 +551,11 @@ void GPU_viewport_draw_to_screen(GPUViewport *viewport, const rcti *rect)
   GPU_texture_unbind(color);
 }
 
+void GPU_viewport_draw_to_screen(GPUViewport *viewport, const rcti *rect)
+{
+  GPU_viewport_draw_to_screen_ex(viewport, rect, false);
+}
+
 void GPU_viewport_unbind(GPUViewport *UNUSED(viewport))
 {
   GPU_framebuffer_restore();
diff --git a/source/blender/windowmanager/intern/wm_draw.c b/source/blender/windowmanager/intern/wm_draw.c
index b0b89fa074f..3951644ec81 100644
--- a/source/blender/windowmanager/intern/wm_draw.c
+++ b/source/blender/windowmanager/intern/wm_draw.c
@@ -748,13 +748,13 @@ static void wm_draw_window_onscreen(bContext *C, wmWindow *win, int view)
   }
 }
 
-void wm_draw_upside_down(int sizex, int sizey)
+void wm_draw_upside_down(int sizex, int sizey, bool to_srgb)
 {
   GPUVertFormat *format = immVertexFormat();
   uint texcoord = GPU_vertformat_attr_add(format, "texCoord", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
   uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
 
-  immBindBuiltinProgram(GPU_SHADER_2D_IMAGE);
+  immBindBuiltinProgram(to_srgb ? GPU_SHADER_2D_IMAGE_LINEAR_TO_SRGB : GPU_SHADER_2D_IMAGE);
 
   /* wmOrtho for the screen has this same offset */
   const float halfx = GLA_PIXEL_OFS / sizex;
@@ -804,7 +804,7 @@ static void wm_draw_window_upside_down_onscreen(bContext *C, wmWindow *win)
     glActiveTexture(GL_TEXTURE0);
     glBindTexture(GL_TEXTURE_2D, GPU_texture_opengl_bindcode(texture));
 
-    wm_draw_upside_down(win->sizex, win->sizey);
+    wm_draw_upside_down(win->sizex, win->sizey, false);
 
     glBindTexture(GL_TEXTURE_2D, 0);
 
diff --git a/source/blender/windowmanager/intern/wm_xr.c b/source/blender/windowmanager/intern/wm_xr.c
index 22e6fb7b3bf..82d17b6cd6e 100644
--- a/source/blender/windowmanager/intern/wm_xr.c
+++ b/source/blender/windowmanager/intern/wm_xr.c
@@ -337,11 +337,11 @@ static GHOST_ContextHandle wm_xr_draw_view(const GHOST_XrDrawViewInfo *draw_view
   GPU_depth_test(false);
 
   wmViewport(&rect);
-  GPU_viewport_draw_to_screen(viewport, &rect);
+  GPU_viewport_draw_to_screen_ex(viewport, &rect, draw_view->expects_srgb_buffer);
   if (g_xr_surface->secondary_ghost_ctx &&
       GHOST_isUpsideDownContext(g_xr_surface->secondary_ghost_ctx)) {
     GPU_texture_bind(texture, 0);
-    wm_draw_upside_down(draw_view->width, draw_view->height);
+    wm_draw_upside_down(draw_view->width, draw_view->height, draw_view->expects_srgb_buffer);
     GPU_texture_unbind(texture);
   }
   GPU_viewport_unbind(viewport);
diff --git a/source/blender/windowmanager/wm.h b/source/blender/windowmanager/wm.h
index f28552916f2..a98c47b11c2 100644
--- a/source/blender/windowmanager/wm.h
+++ b/source/blender/windowmanager/wm.h
@@ -98,7 +98,7 @@ void wm_open_init_use_scripts(wmOperator *op, bool use_prefs);
 /* wm_draw.c */
 struct GPUOffScreen;
 void wm_draw_offscreen_texture_parameters(struct GPUOffScreen *offscreen);
-void wm_draw_upside_down(int sizex, int sizey);
+void wm_draw_upside_down(int sizex, int sizey, bool to_srgb);
 
 #ifdef WITH_OPENXR
 /* wm_xr.c */



More information about the Bf-blender-cvs mailing list