[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