[Bf-blender-cvs] [8b02f761d99] greasepencil-refactor: GPencil: Refactor: Allocate GPU framebuffers only if necessary

Clément Foucault noreply at git.blender.org
Fri Jan 17 01:12:42 CET 2020


Commit: 8b02f761d99e787b64d39fe697d78cbfd874b446
Author: Clément Foucault
Date:   Fri Jan 17 01:11:48 2020 +0100
Branches: greasepencil-refactor
https://developer.blender.org/rB8b02f761d99e787b64d39fe697d78cbfd874b446

GPencil: Refactor: Allocate GPU framebuffers only if necessary

Also use signed format only if needed.

Note that you cannot see subtractive, overlay and divide blend modes in
the viewport because of the srgb hack AND the current viewport framebuffer
format.

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

M	source/blender/draw/engines/gpencil/gpencil_cache_utils.c
M	source/blender/draw/engines/gpencil/gpencil_engine.c
M	source/blender/draw/engines/gpencil/gpencil_engine.h
M	source/blender/draw/engines/gpencil/gpencil_shader_fx.c

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

diff --git a/source/blender/draw/engines/gpencil/gpencil_cache_utils.c b/source/blender/draw/engines/gpencil/gpencil_cache_utils.c
index e18512af565..9871da45130 100644
--- a/source/blender/draw/engines/gpencil/gpencil_cache_utils.c
+++ b/source/blender/draw/engines/gpencil/gpencil_cache_utils.c
@@ -171,6 +171,8 @@ GPENCIL_tLayer *gpencil_layer_cache_add(GPENCIL_PrivateData *pd, Object *ob, bGP
     DRW_shgroup_state_enable(grp, DRW_STATE_BLEND_ADD_FULL);
     DRW_shgroup_uniform_int_copy(grp, "isFirstPass", false);
     DRW_shgroup_call_procedural_triangles(grp, NULL, 1);
+
+    pd->use_mask_fb = true;
   }
   else if ((gpl->blend_mode != eGplBlendMode_Regular) || (gpl->opacity < 1.0f)) {
     DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_STENCIL_EQUAL;
@@ -182,22 +184,20 @@ GPENCIL_tLayer *gpencil_layer_cache_add(GPENCIL_PrivateData *pd, Object *ob, bGP
         state |= DRW_STATE_BLEND_ADD_FULL;
         break;
       case eGplBlendMode_Subtract:
-        /* Caveat. This effect only propagates if target buffer has
-         * a signed floating point color buffer.
-         * i.e: This will not be conserved after this blending step.
-         * TODO(fclem) To make things consistent, we might create a dummy vfx
-         * for objects that use this blend type to always avoid the subtract
-         * affecting other objects. */
         state |= DRW_STATE_BLEND_SUB;
         break;
       case eGplBlendMode_Multiply:
       case eGplBlendMode_Divide:
-        /* Same Caveat as Subtract. This is conserved until there is a blend with a LDR buffer. */
       case eGplBlendMode_Overlay:
         state |= DRW_STATE_BLEND_MUL;
         break;
     }
 
+    if (ELEM(gpl->blend_mode, eGplBlendMode_Subtract, eGplBlendMode_Overlay)) {
+      /* For these effect to propagate, we need a signed floating point buffer. */
+      pd->use_signed_fb = true;
+    }
+
     tgp_layer->blend_ps = DRW_pass_create("GPencil Blend Layer", state);
 
     GPUShader *sh = GPENCIL_shader_layer_blend_get();
@@ -218,6 +218,8 @@ GPENCIL_tLayer *gpencil_layer_cache_add(GPENCIL_PrivateData *pd, Object *ob, bGP
       DRW_shgroup_uniform_int_copy(grp, "blendMode", 999);
       DRW_shgroup_call_procedural_triangles(grp, NULL, 1);
     }
+
+    pd->use_layer_fb = true;
   }
   else {
     tgp_layer->blend_ps = NULL;
diff --git a/source/blender/draw/engines/gpencil/gpencil_engine.c b/source/blender/draw/engines/gpencil/gpencil_engine.c
index 0210b289344..4860ad4152d 100644
--- a/source/blender/draw/engines/gpencil/gpencil_engine.c
+++ b/source/blender/draw/engines/gpencil/gpencil_engine.c
@@ -168,6 +168,10 @@ void GPENCIL_cache_init(void *ved)
 
   const DRWContextState *draw_ctx = DRW_context_state_get();
   pd->cfra = (int)DEG_get_ctime(draw_ctx->depsgraph);
+  pd->use_layer_fb = false;
+  pd->use_object_fb = false;
+  pd->use_mask_fb = false;
+  pd->use_signed_fb = false;
 
   if (draw_ctx->v3d) {
     const bool hide_overlay = ((draw_ctx->v3d->flag2 & V3D_HIDE_OVERLAYS) != 0);
@@ -620,18 +624,13 @@ void GPENCIL_cache_finish(void *ved)
 
   /* Create framebuffers only if needed. */
   if (pd->tobjects.first) {
-    /* TODO(fclem) Detect use of layers and vfx. */
-    bool use_layer_fb = true;
-    bool use_mask_fb = true;
-    bool use_object_fb = true;
+    eGPUTextureFormat format = pd->use_signed_fb ? GPU_RGBA16F : GPU_R11F_G11F_B10F;
 
     const float *size = DRW_viewport_size_get();
     pd->depth_tx = DRW_texture_pool_query_2d(
         size[0], size[1], GPU_DEPTH24_STENCIL8, &draw_engine_gpencil_type);
-    pd->color_tx = DRW_texture_pool_query_2d(
-        size[0], size[1], GPU_R11F_G11F_B10F, &draw_engine_gpencil_type);
-    pd->reveal_tx = DRW_texture_pool_query_2d(
-        size[0], size[1], GPU_R11F_G11F_B10F, &draw_engine_gpencil_type);
+    pd->color_tx = DRW_texture_pool_query_2d(size[0], size[1], format, &draw_engine_gpencil_type);
+    pd->reveal_tx = DRW_texture_pool_query_2d(size[0], size[1], format, &draw_engine_gpencil_type);
 
     GPU_framebuffer_ensure_config(&fbl->gpencil_fb,
                                   {
@@ -640,11 +639,11 @@ void GPENCIL_cache_finish(void *ved)
                                       GPU_ATTACHMENT_TEXTURE(pd->reveal_tx),
                                   });
 
-    if (use_layer_fb) {
+    if (pd->use_layer_fb) {
       pd->color_layer_tx = DRW_texture_pool_query_2d(
-          size[0], size[1], GPU_R11F_G11F_B10F, &draw_engine_gpencil_type);
+          size[0], size[1], format, &draw_engine_gpencil_type);
       pd->reveal_layer_tx = DRW_texture_pool_query_2d(
-          size[0], size[1], GPU_R11F_G11F_B10F, &draw_engine_gpencil_type);
+          size[0], size[1], format, &draw_engine_gpencil_type);
 
       GPU_framebuffer_ensure_config(&fbl->layer_fb,
                                     {
@@ -654,11 +653,11 @@ void GPENCIL_cache_finish(void *ved)
                                     });
     };
 
-    if (use_object_fb) {
+    if (pd->use_object_fb) {
       pd->color_object_tx = DRW_texture_pool_query_2d(
-          size[0], size[1], GPU_R11F_G11F_B10F, &draw_engine_gpencil_type);
+          size[0], size[1], format, &draw_engine_gpencil_type);
       pd->reveal_object_tx = DRW_texture_pool_query_2d(
-          size[0], size[1], GPU_R11F_G11F_B10F, &draw_engine_gpencil_type);
+          size[0], size[1], format, &draw_engine_gpencil_type);
 
       GPU_framebuffer_ensure_config(&fbl->object_fb,
                                     {
@@ -668,12 +667,12 @@ void GPENCIL_cache_finish(void *ved)
                                     });
     }
 
-    if (use_mask_fb) {
+    if (pd->use_mask_fb) {
       /* We need to separate all the masked layer together in order to correctly mix them. */
       pd->color_masked_tx = DRW_texture_pool_query_2d(
-          size[0], size[1], GPU_RGBA16F, &draw_engine_gpencil_type);
+          size[0], size[1], format, &draw_engine_gpencil_type);
       pd->reveal_masked_tx = DRW_texture_pool_query_2d(
-          size[0], size[1], GPU_RGBA16F, &draw_engine_gpencil_type);
+          size[0], size[1], format, &draw_engine_gpencil_type);
 
       GPU_framebuffer_ensure_config(&fbl->masked_fb,
                                     {
diff --git a/source/blender/draw/engines/gpencil/gpencil_engine.h b/source/blender/draw/engines/gpencil/gpencil_engine.h
index f50c7aaf555..daef1cbdffe 100644
--- a/source/blender/draw/engines/gpencil/gpencil_engine.h
+++ b/source/blender/draw/engines/gpencil/gpencil_engine.h
@@ -317,6 +317,13 @@ typedef struct GPENCIL_PrivateData {
   bool use_lighting;
   /* Use physical lights or just ambient lighting. */
   bool use_lights;
+  /* Do we need additional framebuffers? */
+  bool use_layer_fb;
+  bool use_object_fb;
+  bool use_mask_fb;
+  /* Some blend mode needs to add negative values.
+   * This is only supported if target texture is signed. */
+  bool use_signed_fb;
 } GPENCIL_PrivateData;
 
 /* geometry batch cache functions */
diff --git a/source/blender/draw/engines/gpencil/gpencil_shader_fx.c b/source/blender/draw/engines/gpencil/gpencil_shader_fx.c
index e81169f011b..6e1eb4bfc47 100644
--- a/source/blender/draw/engines/gpencil/gpencil_shader_fx.c
+++ b/source/blender/draw/engines/gpencil/gpencil_shader_fx.c
@@ -615,5 +615,7 @@ void gpencil_vfx_cache_populate(GPENCIL_Data *vedata, Object *ob, GPENCIL_tObjec
     DRW_shgroup_state_enable(grp, DRW_STATE_BLEND_ADD_FULL);
     DRW_shgroup_uniform_int_copy(grp, "isFirstPass", false);
     DRW_shgroup_call_procedural_triangles(grp, NULL, 1);
+
+    pd->use_object_fb = true;
   }
 }



More information about the Bf-blender-cvs mailing list