[Bf-blender-cvs] [af48712d88d] tmp-drw-callbatching: Cleanup: DRW: Make drawcall render control flow a more easier to follow.

Clément Foucault noreply at git.blender.org
Sat Aug 17 14:50:42 CEST 2019


Commit: af48712d88dfe2a499a746b35d7bec29f9deeda2
Author: Clément Foucault
Date:   Sat Jun 22 00:24:30 2019 +0200
Branches: tmp-drw-callbatching
https://developer.blender.org/rBaf48712d88dfe2a499a746b35d7bec29f9deeda2

Cleanup: DRW: Make drawcall render control flow a more easier to follow.

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

M	source/blender/draw/intern/draw_hair.c
M	source/blender/draw/intern/draw_manager.h
M	source/blender/draw/intern/draw_manager_data.c
M	source/blender/draw/intern/draw_manager_exec.c

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

diff --git a/source/blender/draw/intern/draw_hair.c b/source/blender/draw/intern/draw_hair.c
index fa1f1f2aab4..b8fe01fb860 100644
--- a/source/blender/draw/intern/draw_hair.c
+++ b/source/blender/draw/intern/draw_hair.c
@@ -201,30 +201,33 @@ static DRWShadingGroup *drw_shgroup_create_hair_procedural_ex(Object *object,
   /* Transform Feedback subdiv. */
   if (need_ft_update) {
     int final_points_len = hair_cache->final[subdiv].strands_res * hair_cache->strands_len;
-    GPUShader *tf_shader = hair_refine_shader_get(PART_REFINE_CATMULL_ROM);
+    if (final_points_len) {
+      GPUShader *tf_shader = hair_refine_shader_get(PART_REFINE_CATMULL_ROM);
 
 #ifdef USE_TRANSFORM_FEEDBACK
-    DRWShadingGroup *tf_shgrp = DRW_shgroup_transform_feedback_create(
-        tf_shader, g_tf_pass, hair_cache->final[subdiv].proc_buf);
+      DRWShadingGroup *tf_shgrp = DRW_shgroup_transform_feedback_create(
+          tf_shader, g_tf_pass, hair_cache->final[subdiv].proc_buf);
 #else
-    DRWShadingGroup *tf_shgrp = DRW_shgroup_create(tf_shader, g_tf_pass);
-
-    ParticleRefineCall *pr_call = MEM_mallocN(sizeof(*pr_call), __func__);
-    pr_call->next = g_tf_calls;
-    pr_call->vbo = hair_cache->final[subdiv].proc_buf;
-    pr_call->shgrp = tf_shgrp;
-    pr_call->vert_len = final_points_len;
-    g_tf_calls = pr_call;
-    DRW_shgroup_uniform_int(tf_shgrp, "targetHeight", &g_tf_target_height, 1);
-    DRW_shgroup_uniform_int(tf_shgrp, "targetWidth", &g_tf_target_width, 1);
-    DRW_shgroup_uniform_int(tf_shgrp, "idOffset", &g_tf_id_offset, 1);
+      DRWShadingGroup *tf_shgrp = DRW_shgroup_create(tf_shader, g_tf_pass);
+
+      ParticleRefineCall *pr_call = MEM_mallocN(sizeof(*pr_call), __func__);
+      pr_call->next = g_tf_calls;
+      pr_call->vbo = hair_cache->final[subdiv].proc_buf;
+      pr_call->shgrp = tf_shgrp;
+      pr_call->vert_len = final_points_len;
+      g_tf_calls = pr_call;
+      DRW_shgroup_uniform_int(tf_shgrp, "targetHeight", &g_tf_target_height, 1);
+      DRW_shgroup_uniform_int(tf_shgrp, "targetWidth", &g_tf_target_width, 1);
+      DRW_shgroup_uniform_int(tf_shgrp, "idOffset", &g_tf_id_offset, 1);
 #endif
 
-    DRW_shgroup_uniform_texture(tf_shgrp, "hairPointBuffer", hair_cache->point_tex);
-    DRW_shgroup_uniform_texture(tf_shgrp, "hairStrandBuffer", hair_cache->strand_tex);
-    DRW_shgroup_uniform_texture(tf_shgrp, "hairStrandSegBuffer", hair_cache->strand_seg_tex);
-    DRW_shgroup_uniform_int(tf_shgrp, "hairStrandsRes", &hair_cache->final[subdiv].strands_res, 1);
-    DRW_shgroup_call_procedural_points(tf_shgrp, NULL, final_points_len);
+      DRW_shgroup_uniform_texture(tf_shgrp, "hairPointBuffer", hair_cache->point_tex);
+      DRW_shgroup_uniform_texture(tf_shgrp, "hairStrandBuffer", hair_cache->strand_tex);
+      DRW_shgroup_uniform_texture(tf_shgrp, "hairStrandSegBuffer", hair_cache->strand_seg_tex);
+      DRW_shgroup_uniform_int(
+          tf_shgrp, "hairStrandsRes", &hair_cache->final[subdiv].strands_res, 1);
+      DRW_shgroup_call_procedural_points(tf_shgrp, NULL, final_points_len);
+    }
   }
 
   return shgrp;
diff --git a/source/blender/draw/intern/draw_manager.h b/source/blender/draw/intern/draw_manager.h
index 1b4cb06a59c..9ab8daa1b09 100644
--- a/source/blender/draw/intern/draw_manager.h
+++ b/source/blender/draw/intern/draw_manager.h
@@ -45,7 +45,7 @@
 #define USE_GPU_SELECT
 
 /* Use drawcall batching using instanced rendering. */
-#define USE_BATCHING
+#define USE_BATCHING 1
 
 // #define DRW_DEBUG_CULLING
 #define DRW_DEBUG_USE_UNIFORM_NAME 0
diff --git a/source/blender/draw/intern/draw_manager_data.c b/source/blender/draw/intern/draw_manager_data.c
index ce54af2b6eb..92588e4dd5c 100644
--- a/source/blender/draw/intern/draw_manager_data.c
+++ b/source/blender/draw/intern/draw_manager_data.c
@@ -636,7 +636,7 @@ static void drw_shgroup_call_procedural_add_ex(DRWShadingGroup *shgroup,
                                                Object *ob,
                                                uint vert_count)
 {
-
+  BLI_assert(vert_count > 0);
   DRWCall *call = drw_call_create(shgroup);
   call->handle = drw_call_handle_object(shgroup, ob ? ob->obmat : NULL, ob);
   call->batch = geom;
diff --git a/source/blender/draw/intern/draw_manager_exec.c b/source/blender/draw/intern/draw_manager_exec.c
index e140d005796..d61eef3e728 100644
--- a/source/blender/draw/intern/draw_manager_exec.c
+++ b/source/blender/draw/intern/draw_manager_exec.c
@@ -648,6 +648,9 @@ BLI_INLINE void draw_indirect_call(DRWShadingGroup *shgroup,
                                    int inst_count,
                                    int baseinst_loc)
 {
+  if (inst_count == 0) {
+    return;
+  }
   if (baseinst_loc == -1) {
     /* bind vertex array */
     if (DST.batch != geom) {
@@ -657,7 +660,7 @@ BLI_INLINE void draw_indirect_call(DRWShadingGroup *shgroup,
     GPU_draw_list_command_add(DST.draw_list, vert_first, vert_count, inst_first, inst_count);
   }
   /* Fallback when unsupported */
-  else if (inst_count > 0) {
+  else {
     draw_geometry_execute(
         shgroup, geom, vert_first, vert_count, inst_first, inst_count, baseinst_loc);
   }
@@ -941,12 +944,9 @@ static void draw_update_uniforms(DRWShadingGroup *shgroup,
   BLI_assert(ubo_bindings_validate(shgroup));
 }
 
-BLI_INLINE bool draw_select_do_call(DRWShadingGroup *shgroup, DRWCall *call, int baseinst_loc)
+BLI_INLINE void draw_select_do_call(DRWShadingGroup *shgroup, DRWCall *call, int baseinst_loc)
 {
 #ifdef USE_GPU_SELECT
-  if ((G.f & G_FLAG_PICKSEL) == 0) {
-    return false;
-  }
   if (call->inst_selectid != NULL) {
     const bool is_instancing = (call->inst_count != -1);
     int start = 0;
@@ -979,14 +979,11 @@ BLI_INLINE bool draw_select_do_call(DRWShadingGroup *shgroup, DRWCall *call, int
       }
       start += count;
     }
-    return true;
   }
   else {
     GPU_select_load_id(call->select_id);
-    return false;
+    draw_geometry_execute(shgroup, call->batch, 0, 0, call->handle.id, 0, baseinst_loc);
   }
-#else
-  return false;
 #endif
 }
 
@@ -1018,13 +1015,12 @@ static DRWCall *draw_call_iter_step(DRWCallIterator *iter)
 }
 
 typedef struct DRWCommandsState {
-  int callid;
+  GPUBatch *batch;
   int resource_chunk;
   int base_inst;
   int inst_count;
   int v_first;
   int v_count;
-  GPUBatch *batch;
   bool neg_scale;
 } DRWCommandsState;
 
@@ -1056,40 +1052,75 @@ static void draw_call_resource_bind(DRWCommandsState *state,
   }
 }
 
-#ifdef USE_BATCHING
-/* Return true if the given drawcall can be batched with following calls. */
-static bool draw_call_do_batching(DRWShadingGroup *shgroup,
+static void draw_call_batching_start(DRWCommandsState *state, GPUBatch *first_batch)
+{
+  state->neg_scale = false;
+  state->resource_chunk = 0;
+  state->base_inst = 0;
+  state->inst_count = 0;
+  state->v_first = 0;
+  state->v_count = 0;
+  state->batch = first_batch;
+
+  if (first_batch) {
+    GPU_draw_list_init(DST.draw_list, first_batch);
+    state->v_count = first_batch->elem ? first_batch->elem->index_len :
+                                         first_batch->verts[0]->vertex_len;
+  }
+}
+
+static void draw_call_batching_do(DRWShadingGroup *shgroup,
                                   DRWCommandsState *state,
                                   DRWCall *call,
                                   int obmats_loc,
                                   int obinfos_loc,
                                   int baseinst_loc,
+                                  int obmat_loc,
+                                  int obinv_loc,
+                                  int mvp_loc,
                                   int chunkid_loc)
 {
-  if (call->inst_count != -1 || call->vert_first > 0 || call->vert_count > 0 || obmats_loc == -1 ||
-      G.f & G_FLAG_PICKSEL) {
-    /* Safety guard. Batching should not happen in a shgroup
-     * where any if the above condition are true. */
-    BLI_assert(state->inst_count == 0);
-    if (state->inst_count > 0) {
-      /* We need to draw the pending instances. */
-      draw_indirect_call(shgroup,
-                         state->batch,
-                         state->v_first,
-                         state->v_count,
-                         state->base_inst,
-                         state->inst_count,
-                         baseinst_loc);
-    }
+  /* Regular rendering */
+  if (!USE_BATCHING || call->inst_count != -1 || obmats_loc == -1 || call->vert_first > 0 ||
+      call->vert_count > 0 || (G.f & G_FLAG_PICKSEL)) {
+    /* We need to draw the pending instances. */
+    draw_indirect_call(shgroup,
+                       state->batch,
+                       state->v_first,
+                       state->v_count,
+                       state->base_inst,
+                       state->inst_count,
+                       baseinst_loc);
     /* Submit the pending commands. */
-    /* NOTE/TODO: We could allow command list usage in this case. */
     GPU_draw_list_submit(DST.draw_list);
-    /* We cannot pack in this situation. */
-    state->inst_count = 0;
-    state->base_inst = 0;
+
     state->batch = call->batch;
-    return false;
+    state->v_first = 0;
+    state->v_count = 0;
+    state->inst_count = 0;
+    state->base_inst = -1;
+
+    draw_call_resource_bind(state, call->handle, obmats_loc, obinfos_loc, chunkid_loc);
+
+    /* TODO This is Legacy. Need to be removed. */
+    if (obmats_loc == -1 && (obmat_loc != -1 || obinv_loc != -1 || mvp_loc != -1)) {
+      draw_legacy_matrix_update(shgroup, call->handle, obmat_loc, obinv_loc, mvp_loc);
+    }
+
+    if (G.f & G_FLAG_PICKSEL) {
+      draw_select_do_call(shgroup, call, baseinst_loc);
+    }
+    else {
+      draw_geometry_execute(shgroup,
+                            call->batch,
+                            call->vert_first,
+                            call->vert_count,
+                            call->handle.id,
+                            call->inst_count,
+                            baseinst_loc);
+    }
   }
+  /* Draw Call Batching/Packing */
   else {
     /* See if any condition requires to interupt the packing. */
     if ((call->handle.negative_scale != state->neg_scale) || /* Need to change state. */
@@ -1134,29 +1165,38 @@ stat

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list