[Bf-blender-cvs] [b5890e96724] tmp-drw-callbatching: DRW: Make Call matrices and object infos into their own containers

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


Commit: b5890e96724dcf11cdf626942923c4a97bdeb7a9
Author: Clément Foucault
Date:   Fri May 31 01:45:41 2019 +0200
Branches: tmp-drw-callbatching
https://developer.blender.org/rBb5890e96724dcf11cdf626942923c4a97bdeb7a9

DRW: Make Call matrices and object infos into their own containers

This is in preparation of some bigger refactor that will put all
object matrices and infos into UBOs.

So this commit introduce a bit of performance penalty but it will
be claimed back!

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

M	source/blender/draw/engines/workbench/shaders/workbench_volume_frag.glsl
M	source/blender/draw/engines/workbench/shaders/workbench_volume_vert.glsl
M	source/blender/draw/intern/draw_manager.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
M	source/blender/gpu/GPU_shader_interface.h
M	source/blender/gpu/GPU_viewport.h
M	source/blender/gpu/intern/gpu_codegen.c
M	source/blender/gpu/intern/gpu_viewport.c

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

diff --git a/source/blender/draw/engines/workbench/shaders/workbench_volume_frag.glsl b/source/blender/draw/engines/workbench/shaders/workbench_volume_frag.glsl
index fd06c85747f..e189c00f3f6 100644
--- a/source/blender/draw/engines/workbench/shaders/workbench_volume_frag.glsl
+++ b/source/blender/draw/engines/workbench/shaders/workbench_volume_frag.glsl
@@ -1,5 +1,5 @@
 
-uniform vec3 OrcoTexCoFactors[2];
+uniform vec4 OrcoTexCoFactors[2];
 
 uniform sampler2D depthBuffer;
 
@@ -216,13 +216,13 @@ void main()
   vs_ray_dir /= abs(vs_ray_dir.z);
 
   /* TODO(fclem) Precompute the matrix/ */
-  vec3 ls_ray_dir = mat3(ViewMatrixInverse) * vs_ray_dir * OrcoTexCoFactors[1] * 2.0;
+  vec3 ls_ray_dir = mat3(ViewMatrixInverse) * vs_ray_dir * OrcoTexCoFactors[1].xyz * 2.0;
   ls_ray_dir = mat3(ModelMatrixInverse) * ls_ray_dir;
   vec3 ls_ray_ori = point_view_to_object(vs_ray_ori);
   vec3 ls_ray_end = point_view_to_object(vs_ray_end);
 
-  ls_ray_ori = (OrcoTexCoFactors[0] + ls_ray_ori * OrcoTexCoFactors[1]) * 2.0 - 1.0;
-  ls_ray_end = (OrcoTexCoFactors[0] + ls_ray_end * OrcoTexCoFactors[1]) * 2.0 - 1.0;
+  ls_ray_ori = (OrcoTexCoFactors[0].xyz + ls_ray_ori * OrcoTexCoFactors[1].xyz) * 2.0 - 1.0;
+  ls_ray_end = (OrcoTexCoFactors[0].xyz + ls_ray_end * OrcoTexCoFactors[1].xyz) * 2.0 - 1.0;
 
   /* TODO: Align rays to volume center so that it mimics old behaviour of slicing the volume. */
 
diff --git a/source/blender/draw/engines/workbench/shaders/workbench_volume_vert.glsl b/source/blender/draw/engines/workbench/shaders/workbench_volume_vert.glsl
index 6f0bb56fafd..55396e4d711 100644
--- a/source/blender/draw/engines/workbench/shaders/workbench_volume_vert.glsl
+++ b/source/blender/draw/engines/workbench/shaders/workbench_volume_vert.glsl
@@ -1,5 +1,5 @@
 
-uniform vec3 OrcoTexCoFactors[2];
+uniform vec4 OrcoTexCoFactors[2];
 uniform float slicePosition;
 uniform int sliceAxis; /* -1 is no slice, 0 is X, 1 is Y, 2 is Z. */
 
@@ -27,6 +27,6 @@ void main()
 #else
   vec3 final_pos = pos;
 #endif
-  final_pos = ((final_pos * 0.5 + 0.5) - OrcoTexCoFactors[0]) / OrcoTexCoFactors[1];
+  final_pos = ((final_pos * 0.5 + 0.5) - OrcoTexCoFactors[0].xyz) / OrcoTexCoFactors[1].xyz;
   gl_Position = point_object_to_ndc(final_pos);
 }
diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c
index b03240886ca..b0cea94e1ed 100644
--- a/source/blender/draw/intern/draw_manager.c
+++ b/source/blender/draw/intern/draw_manager.c
@@ -542,6 +542,8 @@ static void drw_viewport_cache_resize(void)
 
     BLI_memblock_clear(DST.vmempool->calls, NULL);
     BLI_memblock_clear(DST.vmempool->states, NULL);
+    BLI_memblock_clear(DST.vmempool->obmats, NULL);
+    BLI_memblock_clear(DST.vmempool->obinfos, NULL);
     BLI_memblock_clear(DST.vmempool->cullstates, NULL);
     BLI_memblock_clear(DST.vmempool->shgroups, NULL);
     BLI_memblock_clear(DST.vmempool->uniforms, NULL);
@@ -592,22 +594,24 @@ static void drw_context_state_init(void)
 static DRWCallState *draw_unit_state_create(void)
 {
   DRWCallState *state = BLI_memblock_alloc(DST.vmempool->states);
+  DRWObjectInfos *infos = state->ob_infos = BLI_memblock_alloc(DST.vmempool->obinfos);
+  DRWObjectMatrix *mats = state->ob_mats = BLI_memblock_alloc(DST.vmempool->obmats);
+  DRWCullingState *culling = state->culling = BLI_memblock_alloc(DST.vmempool->cullstates);
   state->flag = 0;
-  state->matflag = 0;
 
-  unit_m4(state->model);
-  unit_m4(state->modelinverse);
+  unit_m4(mats->model);
+  unit_m4(mats->modelinverse);
 
-  copy_v3_fl(state->orcotexfac[0], 0.0f);
-  copy_v3_fl(state->orcotexfac[1], 1.0f);
+  copy_v3_fl(infos->orcotexfac[0], 0.0f);
+  copy_v3_fl(infos->orcotexfac[1], 1.0f);
 
-  state->ob_index = 0;
-  state->ob_random = 0.0f;
+  infos->ob_index = 0;
+  infos->ob_random = 0.0f;
+  infos->ob_neg_scale = 1.0f;
 
   /* TODO(fclem) get rid of this. */
-  state->culling = BLI_memblock_alloc(DST.vmempool->cullstates);
-  state->culling->bsphere.radius = -1.0f;
-  state->culling->user_data = NULL;
+  culling->bsphere.radius = -1.0f;
+  culling->user_data = NULL;
 
   return state;
 }
@@ -640,6 +644,12 @@ static void drw_viewport_var_init(void)
     if (DST.vmempool->states == NULL) {
       DST.vmempool->states = BLI_memblock_create(sizeof(DRWCallState));
     }
+    if (DST.vmempool->obmats == NULL) {
+      DST.vmempool->obmats = BLI_memblock_create(sizeof(DRWObjectMatrix));
+    }
+    if (DST.vmempool->obinfos == NULL) {
+      DST.vmempool->obinfos = BLI_memblock_create(sizeof(DRWObjectInfos));
+    }
     if (DST.vmempool->cullstates == NULL) {
       DST.vmempool->cullstates = BLI_memblock_create(sizeof(DRWCullingState));
     }
diff --git a/source/blender/draw/intern/draw_manager.h b/source/blender/draw/intern/draw_manager.h
index f37e713e374..bd8137b2ef7 100644
--- a/source/blender/draw/intern/draw_manager.h
+++ b/source/blender/draw/intern/draw_manager.h
@@ -28,6 +28,7 @@
 #include "DRW_engine.h"
 #include "DRW_render.h"
 
+#include "BLI_assert.h"
 #include "BLI_linklist.h"
 #include "BLI_threads.h"
 
@@ -95,14 +96,6 @@ enum {
   DRW_CALL_NEGSCALE = (1 << 1),
 };
 
-/* Used by DRWCallState.matflag */
-enum {
-  DRW_CALL_MODELINVERSE = (1 << 0),
-  DRW_CALL_MODELVIEWPROJECTION = (1 << 1),
-  DRW_CALL_ORCOTEXFAC = (1 << 2),
-  DRW_CALL_OBJECTINFO = (1 << 3),
-};
-
 typedef struct DRWCullingState {
   uint32_t mask;
   /* Culling: Using Bounding Sphere for now for faster culling.
@@ -112,16 +105,27 @@ typedef struct DRWCullingState {
   void *user_data;
 } DRWCullingState;
 
-typedef struct DRWCallState {
-  DRWCullingState *culling;
-  uchar flag;
-  uchar matflag; /* Which matrices to compute. */
-  short ob_index;
-  /* Matrices */
+typedef struct DRWObjectMatrix {
   float model[4][4];
   float modelinverse[4][4];
-  float orcotexfac[2][3];
+} DRWObjectMatrix;
+
+typedef struct DRWObjectInfos {
+  float orcotexfac[2][4];
+  float ob_index;
+  float pad; /* UNUSED*/
   float ob_random;
+  float ob_neg_scale;
+} DRWObjectInfos;
+
+BLI_STATIC_ASSERT_ALIGN(DRWObjectMatrix, 16)
+BLI_STATIC_ASSERT_ALIGN(DRWObjectInfos, 16)
+
+typedef struct DRWCallState {
+  DRWCullingState *culling;
+  uchar flag;
+  DRWObjectMatrix *ob_mats;
+  DRWObjectInfos *ob_infos;
 } DRWCallState;
 
 typedef struct DRWCall {
@@ -196,7 +200,6 @@ struct DRWShadingGroup {
   int orcotexfac;
   int callid;
   int objectinfo;
-  uchar matflag; /* Matrices needed, same as DRWCall.flag */
 
   DRWPass *pass_parent; /* backlink to pass we're in */
 };
@@ -229,6 +232,8 @@ typedef struct DRWViewUboStorage {
   float viewcamtexcofac[4];
 } DRWViewUboStorage;
 
+BLI_STATIC_ASSERT_ALIGN(DRWViewUboStorage, 16)
+
 #define MAX_CULLED_VIEWS 32
 
 struct DRWView {
diff --git a/source/blender/draw/intern/draw_manager_data.c b/source/blender/draw/intern/draw_manager_data.c
index 99ab25645d2..5b956fbdf7d 100644
--- a/source/blender/draw/intern/draw_manager_data.c
+++ b/source/blender/draw/intern/draw_manager_data.c
@@ -308,7 +308,7 @@ void DRW_shgroup_uniform_vec2_copy(DRWShadingGroup *shgroup, const char *name, c
 /** \name Draw Call (DRW_calls)
  * \{ */
 
-static void drw_call_calc_orco(Object *ob, float (*r_orcofacs)[3])
+static void drw_call_calc_orco(Object *ob, float (*r_orcofacs)[4])
 {
   ID *ob_data = (ob) ? ob->data : NULL;
   float *texcoloc = NULL;
@@ -351,78 +351,67 @@ static void drw_call_calc_orco(Object *ob, float (*r_orcofacs)[3])
   }
 }
 
-static void drw_call_state_update_matflag(DRWCallState *state,
-                                          DRWShadingGroup *shgroup,
-                                          Object *ob)
+static void drw_call_obinfos_create(DRWCallState *state, Object *ob)
 {
-  uchar new_flags = ((state->matflag ^ shgroup->matflag) & shgroup->matflag);
-
-  /* HACK: Here we set the matflags bit to 1 when computing the value
-   * so that it's not recomputed for other drawcalls.
-   * This is the opposite of what draw_matrices_model_prepare() does. */
-  state->matflag |= shgroup->matflag;
+  BLI_assert(ob);
+  DRWObjectInfos *ob_infos = state->ob_infos = BLI_memblock_alloc(DST.vmempool->obinfos);
+  /* Index. */
+  ob_infos->ob_index = ob->index;
+  /* Orco factors. */
+  drw_call_calc_orco(ob, ob_infos->orcotexfac);
+  /* Random float value. */
+  uint random = (DST.dupli_source) ?
+                    DST.dupli_source->random_id :
+                    /* TODO(fclem) this is rather costly to do at runtime. Maybe we can
+                     * put it in ob->runtime and make depsgraph ensure it is up to date. */
+                    BLI_hash_int_2d(BLI_hash_string(ob->id.name + 2), 0);
+  ob_infos->ob_random = random * (1.0f / (float)0xFFFFFFFF);
+  /* Negative scalling. */
+  ob_infos->ob_neg_scale = (ob->transflag & OB_NEG_SCALE) ? -1.0f : 1.0f;
+}
 
-  if (new_flags & DRW_CALL_MODELINVERSE) {
-    if (ob) {
-      copy_m4_m4(state->modelinverse, ob->imat);
-    }
-    else {
-      invert_m4_m4(state->modelinverse, state->model);
-    }
-  }
+static void drw_call_culling_create(DRWCallState *state, Object *ob)
+{
+  DRWCullingState *cull = state->culling = BLI_memblock_alloc(DST.vmempool->cullstates);
 
-  /* Orco factors: We compute this at creation to not have to save the *ob_data */
-  if (new_flags & DRW_CALL_ORCOTEXFAC) {
-    drw_call_calc_orco(ob, state->orcotexfac);
+  BoundBox *bbox;
+  if (ob != NULL && (bbox = BKE_object_boundbox_get(ob))) {
+    float corner[3];
+    /* Get BoundSphere center and radius from the BoundBox. */
+    mid_v3_v3v3(cull->bsphere.center, bbox->vec[0], bbox->vec[6]);
+    mul_v3_m4v3(corner, ob->obmat, bbox->vec[0]);
+    mul_m4_v3(ob->obmat, cull->bsphere.center);
+    cull->bsphere.radius = len_v3v3(cull->bsphere.center, corner);
   }
-
-  if (new_flags & DRW_CALL_OBJECTINFO) {
-    state->ob_index = ob ? ob->index : 0;
-    uint random;
-    if (DST.dupli_source) {
-      random = DST.dupli_source->random_id;
-    }
-    else {
-      random = BLI_hash_int_2d(BLI_hash_string(ob->id.name + 2), 0);
-    }
-    state->ob_random = random * (1.0f / (float)0xFFFFFFFF);
+  else {
+    /* Bypass test. */
+    cull->bsphere.radius = -1.0f;
   }
 }
 
-static DRWCallState *drw_call_state_create(DRWShadingGroup *shgroup, float (*obmat)[4], Object *o

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list