[Bf-blender-cvs] [e94cd5eeed6] temp-T94900-gpu-viewport-default-layers: T94900: Sequence drawing errors on selected platforms.

Jeroen Bakker noreply at git.blender.org
Wed Jan 26 13:40:25 CET 2022


Commit: e94cd5eeed63905661dfeda2d06f21cd089ea78d
Author: Jeroen Bakker
Date:   Wed Jan 26 13:36:52 2022 +0100
Branches: temp-T94900-gpu-viewport-default-layers
https://developer.blender.org/rBe94cd5eeed63905661dfeda2d06f21cd089ea78d

T94900: Sequence drawing errors on selected platforms.

The VSE only uses an overlay texture to draw to the screen. The
GPUViewport assumes that drivers would clear textures when created, but
they do not on selected platforms. What would lead to drawing from
uncleared memory.

By selecting which layers would contain correct data allows us to use
dummy textures in these cases that would eliminate the drawing
artifacts.

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

M	source/blender/editors/space_sequencer/sequencer_draw.c
M	source/blender/gpu/GPU_viewport.h
M	source/blender/gpu/intern/gpu_viewport.c
M	source/blender/windowmanager/wm_draw.h
M	source/blender/windowmanager/xr/intern/wm_xr_draw.c

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

diff --git a/source/blender/editors/space_sequencer/sequencer_draw.c b/source/blender/editors/space_sequencer/sequencer_draw.c
index 6dffc0bc2a4..64cf45b5c81 100644
--- a/source/blender/editors/space_sequencer/sequencer_draw.c
+++ b/source/blender/editors/space_sequencer/sequencer_draw.c
@@ -2700,6 +2700,7 @@ void draw_timeline_seq(const bContext *C, ARegion *region)
   seq_prefetch_wm_notify(C, scene);
 
   GPUViewport *viewport = WM_draw_region_get_viewport(region);
+  GPU_viewport_default_layers_set(viewport, GPU_VIEWPORT_LAYER_OVERLAY);
   GPUFrameBuffer *framebuffer_overlay = GPU_viewport_framebuffer_overlay_get(viewport);
   GPU_framebuffer_bind_no_srgb(framebuffer_overlay);
   GPU_depth_test(GPU_DEPTH_NONE);
diff --git a/source/blender/gpu/GPU_viewport.h b/source/blender/gpu/GPU_viewport.h
index 917b87efeaa..6e520b5ec20 100644
--- a/source/blender/gpu/GPU_viewport.h
+++ b/source/blender/gpu/GPU_viewport.h
@@ -40,6 +40,12 @@ extern "C" {
 typedef struct GHash GHash;
 typedef struct GPUViewport GPUViewport;
 
+typedef enum eGPUViewportLayer {
+  GPU_VIEWPORT_LAYER_COLOR_AND_OVERLAY = 0,
+  GPU_VIEWPORT_LAYER_COLOR = 1,
+  GPU_VIEWPORT_LAYER_OVERLAY = 2
+} eGPUViewportLayer;
+
 struct DRWData;
 struct DefaultFramebufferList;
 struct DefaultTextureList;
@@ -49,6 +55,7 @@ GPUViewport *GPU_viewport_create(void);
 GPUViewport *GPU_viewport_stereo_create(void);
 void GPU_viewport_bind(GPUViewport *viewport, int view, const rcti *rect);
 void GPU_viewport_unbind(GPUViewport *viewport);
+void GPU_viewport_default_layers_set(GPUViewport *viewport, eGPUViewportLayer active_layer);
 /**
  * Merge and draw the buffers of \a viewport into the currently active framebuffer, performing
  * color transform to display space.
@@ -65,7 +72,7 @@ void GPU_viewport_draw_to_screen_ex(GPUViewport *viewport,
                                     int view,
                                     const rcti *rect,
                                     bool display_colorspace,
-                                    bool do_overlay_merge);
+                                    eGPUViewportLayer active_layers);
 /**
  * Must be executed inside Draw-manager OpenGL Context.
  */
diff --git a/source/blender/gpu/intern/gpu_viewport.c b/source/blender/gpu/intern/gpu_viewport.c
index c604859fa94..790203d455a 100644
--- a/source/blender/gpu/intern/gpu_viewport.c
+++ b/source/blender/gpu/intern/gpu_viewport.c
@@ -93,6 +93,8 @@ struct GPUViewport {
   /* TODO(fclem): the uvimage display use the viewport but do not set any view transform for the
    * moment. The end goal would be to let the GPUViewport do the color management. */
   bool do_color_management;
+  /** The default layers to use when drawing to screen. */
+  eGPUViewportLayer default_layers;
   struct GPUViewportBatch batch;
 };
 
@@ -113,6 +115,11 @@ bool GPU_viewport_do_update(GPUViewport *viewport)
   return ret;
 }
 
+void GPU_viewport_default_layers_set(GPUViewport *viewport, eGPUViewportLayer default_layers)
+{
+  viewport->default_layers = default_layers;
+}
+
 GPUViewport *GPU_viewport_create(void)
 {
   GPUViewport *viewport = MEM_callocN(sizeof(GPUViewport), "GPUViewport");
@@ -403,11 +410,23 @@ static void gpu_viewport_draw_colormanaged(GPUViewport *viewport,
                                            const rctf *rect_pos,
                                            const rctf *rect_uv,
                                            bool display_colorspace,
-                                           bool do_overlay_merge)
+                                           eGPUViewportLayer active_layers)
 {
   GPUTexture *color = viewport->color_render_tx[view];
   GPUTexture *color_overlay = viewport->color_overlay_tx[view];
 
+  /* When drawing only the overlay it needs to be drawn on top of an empty texture. Some platforms
+   * do not clear textures when allocating what leads to scrambled parts of the display.
+   *
+   * See T94900 for more information. */
+  const bool do_overlay = ELEM(
+      active_layers, GPU_VIEWPORT_LAYER_COLOR_AND_OVERLAY, GPU_VIEWPORT_LAYER_OVERLAY);
+  const bool use_dummy_texture = viewport->default_layers == GPU_VIEWPORT_LAYER_OVERLAY;
+  if (use_dummy_texture) {
+    static float data[4] = {0.0f, 0.0f, 0.0f, 0.0f};
+    color = GPU_texture_create_2d(__func__, 1, 1, 0, GPU_RGBA16F, data);
+  }
+
   bool use_ocio = false;
 
   if (viewport->do_color_management && display_colorspace) {
@@ -424,7 +443,7 @@ static void gpu_viewport_draw_colormanaged(GPUViewport *viewport,
                                                               NULL,
                                                               viewport->dither,
                                                               false,
-                                                              do_overlay_merge);
+                                                              do_overlay);
   }
 
   GPUBatch *batch = gpu_viewport_batch_get(viewport, rect_pos, rect_uv);
@@ -433,7 +452,7 @@ static void gpu_viewport_draw_colormanaged(GPUViewport *viewport,
   }
   else {
     GPU_batch_program_set_builtin(batch, GPU_SHADER_2D_IMAGE_OVERLAYS_MERGE);
-    GPU_batch_uniform_1i(batch, "overlay", do_overlay_merge);
+    GPU_batch_uniform_1i(batch, "overlay", do_overlay);
     GPU_batch_uniform_1i(batch, "display_transform", display_colorspace);
     GPU_batch_uniform_1i(batch, "image_texture", 0);
     GPU_batch_uniform_1i(batch, "overlays_texture", 1);
@@ -448,13 +467,18 @@ static void gpu_viewport_draw_colormanaged(GPUViewport *viewport,
   if (use_ocio) {
     IMB_colormanagement_finish_glsl_draw();
   }
+
+  if (use_dummy_texture) {
+    GPU_texture_free(color);
+    color = NULL;
+  }
 }
 
 void GPU_viewport_draw_to_screen_ex(GPUViewport *viewport,
                                     int view,
                                     const rcti *rect,
                                     bool display_colorspace,
-                                    bool do_overlay_merge)
+                                    eGPUViewportLayer active_layers)
 {
   GPUTexture *color = viewport->color_render_tx[view];
 
@@ -499,12 +523,12 @@ void GPU_viewport_draw_to_screen_ex(GPUViewport *viewport,
   }
 
   gpu_viewport_draw_colormanaged(
-      viewport, view, &pos_rect, &uv_rect, display_colorspace, do_overlay_merge);
+      viewport, view, &pos_rect, &uv_rect, display_colorspace, active_layers);
 }
 
 void GPU_viewport_draw_to_screen(GPUViewport *viewport, int view, const rcti *rect)
 {
-  GPU_viewport_draw_to_screen_ex(viewport, view, rect, true, true);
+  GPU_viewport_draw_to_screen_ex(viewport, view, rect, true, viewport->default_layers);
 }
 
 void GPU_viewport_unbind_from_offscreen(GPUViewport *viewport,
@@ -533,8 +557,13 @@ void GPU_viewport_unbind_from_offscreen(GPUViewport *viewport,
       .ymax = 1.0f,
   };
 
-  gpu_viewport_draw_colormanaged(
-      viewport, 0, &pos_rect, &uv_rect, display_colorspace, do_overlay_merge);
+  gpu_viewport_draw_colormanaged(viewport,
+                                 0,
+                                 &pos_rect,
+                                 &uv_rect,
+                                 display_colorspace,
+                                 do_overlay_merge ? GPU_VIEWPORT_LAYER_COLOR_AND_OVERLAY :
+                                                    GPU_VIEWPORT_LAYER_COLOR);
 
   /* This one is from the offscreen. Don't free it with the viewport. */
   viewport->depth_tx = NULL;
diff --git a/source/blender/windowmanager/wm_draw.h b/source/blender/windowmanager/wm_draw.h
index 4997361b485..a16852c9247 100644
--- a/source/blender/windowmanager/wm_draw.h
+++ b/source/blender/windowmanager/wm_draw.h
@@ -23,9 +23,7 @@
 
 #pragma once
 
-struct GPUOffScreen;
-struct GPUTexture;
-struct GPUViewport;
+#include "GPU_viewport.h"
 
 #ifdef __cplusplus
 extern "C" {
diff --git a/source/blender/windowmanager/xr/intern/wm_xr_draw.c b/source/blender/windowmanager/xr/intern/wm_xr_draw.c
index 5d0163af5e1..a4b12d83c02 100644
--- a/source/blender/windowmanager/xr/intern/wm_xr_draw.c
+++ b/source/blender/windowmanager/xr/intern/wm_xr_draw.c
@@ -136,7 +136,11 @@ static void wm_xr_draw_viewport_buffers_to_active_framebuffer(
   if (is_upside_down) {
     SWAP(int, rect.ymin, rect.ymax);
   }
-  GPU_viewport_draw_to_screen_ex(vp->viewport, 0, &rect, draw_view->expects_srgb_buffer, true);
+  GPU_viewport_draw_to_screen_ex(vp->viewport,
+                                 0,
+                                 &rect,
+                                 draw_view->expects_srgb_buffer,
+                                 GPU_VIEWPORT_LAYER_COLOR_AND_OVERLAY);
 }
 
 void wm_xr_draw_view(const GHOST_XrDrawViewInfo *draw_view, void *customdata)



More information about the Bf-blender-cvs mailing list