[Bf-blender-cvs] [52e69ce7471] tmp-overlay-engine: GPU: Batch: Add second instance buffer

Clément Foucault noreply at git.blender.org
Wed Nov 20 20:54:11 CET 2019


Commit: 52e69ce74716ac2640baf8a20826d259fd100d2c
Author: Clément Foucault
Date:   Tue Nov 19 21:06:21 2019 +0100
Branches: tmp-overlay-engine
https://developer.blender.org/rB52e69ce74716ac2640baf8a20826d259fd100d2c

GPU: Batch: Add second instance buffer

This is needed in one corner case. In an attempt to get rid of geometry
shader, we need to use instancing using pos and lnor vbos for edit mesh
normals overlay.

This is a bit hacky and quickly made. This should be do more thoroughly.

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

M	source/blender/draw/intern/draw_cache_impl_mesh.c
M	source/blender/draw/intern/draw_instance_data.c
M	source/blender/draw/intern/draw_instance_data.h
M	source/blender/draw/intern/draw_manager_data.c
M	source/blender/draw/intern/draw_manager_exec.c
M	source/blender/gpu/GPU_batch.h
M	source/blender/gpu/intern/gpu_batch.c
M	source/blender/gpu/intern/gpu_shader.c

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

diff --git a/source/blender/draw/intern/draw_cache_impl_mesh.c b/source/blender/draw/intern/draw_cache_impl_mesh.c
index ca185fa7d7d..4099ba7228a 100644
--- a/source/blender/draw/intern/draw_cache_impl_mesh.c
+++ b/source/blender/draw/intern/draw_cache_impl_mesh.c
@@ -1333,7 +1333,7 @@ void DRW_mesh_batch_cache_create_requested(
      * So we instead create the whole instancing batch here.
      * Note that we use GPU_PRIM_LINES instead of expected GPU_PRIM_LINE_STRIP
      * in order to mimic the old stipple pattern. */
-    cache->batch.edit_skin_roots->inst = cache->batch.edit_skin_roots->verts[0];
+    cache->batch.edit_skin_roots->inst[0] = cache->batch.edit_skin_roots->verts[0];
     cache->batch.edit_skin_roots->verts[0] = NULL;
     GPUBatch *circle = DRW_cache_screenspace_circle_get();
     GPU_batch_vertbuf_add(cache->batch.edit_skin_roots, circle->verts[0]);
diff --git a/source/blender/draw/intern/draw_instance_data.c b/source/blender/draw/intern/draw_instance_data.c
index 81b10e095c3..2e914962d31 100644
--- a/source/blender/draw/intern/draw_instance_data.c
+++ b/source/blender/draw/intern/draw_instance_data.c
@@ -134,13 +134,14 @@ GPUVertBuf *DRW_temp_buffer_request(DRWInstanceDataList *idatalist,
 /* NOTE: Does not return a valid drawable batch until DRW_instance_buffer_finish has run. */
 GPUBatch *DRW_temp_batch_instance_request(DRWInstanceDataList *idatalist,
                                           GPUVertBuf *buf,
+                                          GPUVertBuf *buf2, /* hack */
                                           GPUBatch *geom)
 {
   /* Do not call this with a batch that is already an instancing batch. */
   BLI_assert(geom->inst == NULL);
 
   GPUBatch *batch = BLI_memblock_alloc(idatalist->pool_instancing);
-  bool is_compatible = (batch->gl_prim_type == geom->gl_prim_type) && (batch->inst == buf) &&
+  bool is_compatible = (batch->gl_prim_type == geom->gl_prim_type) && (batch->inst[0] == buf) &&
                        (buf->vbo_id != 0) && (batch->phase == GPU_BATCH_READY_TO_DRAW) &&
                        (batch->elem == geom->elem);
   for (int i = 0; i < GPU_BATCH_VBO_MAX_LEN && is_compatible; i++) {
@@ -152,7 +153,8 @@ GPUBatch *DRW_temp_batch_instance_request(DRWInstanceDataList *idatalist,
   if (!is_compatible) {
     GPU_batch_clear(batch);
     /* Save args and init later */
-    batch->inst = buf;
+    batch->inst[0] = buf;
+    batch->inst[1] = buf2;
     batch->phase = GPU_BATCH_READY_TO_BUILD;
     batch->verts[0] = (void *)geom; /* HACK to save the pointer without other alloc. */
 
@@ -205,10 +207,14 @@ void DRW_instance_buffer_finish(DRWInstanceDataList *idatalist)
   BLI_memblock_iternew(idatalist->pool_instancing, &iter);
   while ((batch = BLI_memblock_iterstep(&iter))) {
     if (batch->phase == GPU_BATCH_READY_TO_BUILD) {
-      GPUVertBuf *inst = batch->inst;
+      GPUVertBuf *inst0 = batch->inst[0];
+      GPUVertBuf *inst1 = batch->inst[1];
       GPUBatch *geom = (void *)batch->verts[0]; /* HACK see DRW_temp_batch_instance_request. */
       GPU_batch_copy(batch, geom);
-      GPU_batch_instbuf_set(batch, inst, false);
+      GPU_batch_instbuf_add_ex(batch, inst0, false);
+      if (inst1) {
+        GPU_batch_instbuf_add_ex(batch, inst1, false);
+      }
     }
   }
   /* Resize pools and free unused. */
diff --git a/source/blender/draw/intern/draw_instance_data.h b/source/blender/draw/intern/draw_instance_data.h
index 524c4cd96d8..5bb481fdd09 100644
--- a/source/blender/draw/intern/draw_instance_data.h
+++ b/source/blender/draw/intern/draw_instance_data.h
@@ -43,6 +43,7 @@ GPUVertBuf *DRW_temp_buffer_request(DRWInstanceDataList *idatalist,
                                     int *vert_len);
 GPUBatch *DRW_temp_batch_instance_request(DRWInstanceDataList *idatalist,
                                           GPUVertBuf *buf,
+                                          GPUVertBuf *buf2,
                                           GPUBatch *geom);
 GPUBatch *DRW_temp_batch_request(DRWInstanceDataList *idatalist,
                                  GPUVertBuf *buf,
diff --git a/source/blender/draw/intern/draw_manager_data.c b/source/blender/draw/intern/draw_manager_data.c
index ff6fdde80a2..c0eb586056d 100644
--- a/source/blender/draw/intern/draw_manager_data.c
+++ b/source/blender/draw/intern/draw_manager_data.c
@@ -803,7 +803,8 @@ void DRW_shgroup_call_instances_with_attribs(DRWShadingGroup *shgroup,
   }
   DRWResourceHandle handle = drw_resource_handle(shgroup, ob ? ob->obmat : NULL, ob);
   GPUVertBuf *buf_inst = inst_attributes->verts[0];
-  GPUBatch *batch = DRW_temp_batch_instance_request(DST.idatalist, buf_inst, geom);
+  GPUVertBuf *buf_inst2 = inst_attributes->verts[1];
+  GPUBatch *batch = DRW_temp_batch_instance_request(DST.idatalist, buf_inst, buf_inst2, geom);
   drw_command_draw(shgroup, batch, handle);
 }
 
@@ -1027,7 +1028,7 @@ DRWCallBuffer *DRW_shgroup_call_buffer_instance(DRWShadingGroup *shgroup,
   }
 
   DRWResourceHandle handle = drw_resource_handle(shgroup, NULL, NULL);
-  GPUBatch *batch = DRW_temp_batch_instance_request(DST.idatalist, callbuf->buf, geom);
+  GPUBatch *batch = DRW_temp_batch_instance_request(DST.idatalist, callbuf->buf, NULL, geom);
   drw_command_draw(shgroup, batch, handle);
 
   return callbuf;
diff --git a/source/blender/draw/intern/draw_manager_exec.c b/source/blender/draw/intern/draw_manager_exec.c
index 21bd6a2e0fc..3ecf2ce1f92 100644
--- a/source/blender/draw/intern/draw_manager_exec.c
+++ b/source/blender/draw/intern/draw_manager_exec.c
@@ -1005,10 +1005,10 @@ BLI_INLINE void draw_select_buffer(DRWShadingGroup *shgroup,
                                    GPUBatch *batch,
                                    const DRWResourceHandle *handle)
 {
-  const bool is_instancing = (batch->inst != NULL);
+  const bool is_instancing = (batch->inst[0] != NULL);
   int start = 0;
   int count = 1;
-  int tot = is_instancing ? batch->inst->vertex_len : batch->verts[0]->vertex_len;
+  int tot = is_instancing ? batch->inst[0]->vertex_len : batch->verts[0]->vertex_len;
   /* Hack : get "vbo" data without actually drawing. */
   int *select_id = (void *)state->select_buf->data;
 
diff --git a/source/blender/gpu/GPU_batch.h b/source/blender/gpu/GPU_batch.h
index d7218e97bf0..3616189e673 100644
--- a/source/blender/gpu/GPU_batch.h
+++ b/source/blender/gpu/GPU_batch.h
@@ -41,6 +41,7 @@ typedef enum {
 } GPUBatchPhase;
 
 #define GPU_BATCH_VBO_MAX_LEN 6
+#define GPU_BATCH_INST_VBO_MAX_LEN 2
 #define GPU_BATCH_VAO_STATIC_LEN 3
 #define GPU_BATCH_VAO_DYN_ALLOC_COUNT 16
 
@@ -50,7 +51,7 @@ typedef struct GPUBatch {
   /** verts[0] is required, others can be NULL */
   GPUVertBuf *verts[GPU_BATCH_VBO_MAX_LEN];
   /** Instance attributes. */
-  GPUVertBuf *inst;
+  GPUVertBuf *inst[GPU_BATCH_INST_VBO_MAX_LEN];
   /** NULL if element list not needed */
   GPUIndexBuf *elem;
   uint32_t gl_prim_type;
@@ -117,6 +118,7 @@ void GPU_batch_callback_free_set(GPUBatch *, void (*callback)(GPUBatch *, void *
 void GPU_batch_instbuf_set(GPUBatch *, GPUVertBuf *, bool own_vbo); /* Instancing */
 void GPU_batch_elembuf_set(GPUBatch *batch, GPUIndexBuf *elem, bool own_ibo);
 
+int GPU_batch_instbuf_add_ex(GPUBatch *, GPUVertBuf *, bool own_vbo);
 int GPU_batch_vertbuf_add_ex(GPUBatch *, GPUVertBuf *, bool own_vbo);
 
 #define GPU_batch_vertbuf_add(batch, verts) GPU_batch_vertbuf_add_ex(batch, verts, false)
diff --git a/source/blender/gpu/intern/gpu_batch.c b/source/blender/gpu/intern/gpu_batch.c
index 168d741f92a..9c3d94a9353 100644
--- a/source/blender/gpu/intern/gpu_batch.c
+++ b/source/blender/gpu/intern/gpu_batch.c
@@ -103,7 +103,9 @@ void GPU_batch_init_ex(
   for (int v = 1; v < GPU_BATCH_VBO_MAX_LEN; v++) {
     batch->verts[v] = NULL;
   }
-  batch->inst = NULL;
+  for (int v = 0; v < GPU_BATCH_INST_VBO_MAX_LEN; v++) {
+    batch->inst[v] = NULL;
+  }
   batch->elem = elem;
   batch->gl_prim_type = convert_prim_type_to_gl(prim_type);
   batch->phase = GPU_BATCH_READY_TO_DRAW;
@@ -129,7 +131,8 @@ void GPU_batch_clear(GPUBatch *batch)
     GPU_indexbuf_discard(batch->elem);
   }
   if (batch->owns_flag & GPU_BATCH_OWNS_INSTANCES) {
-    GPU_vertbuf_discard(batch->inst);
+    GPU_vertbuf_discard(batch->inst[0]);
+    GPU_VERTBUF_DISCARD_SAFE(batch->inst[1]);
   }
   if ((batch->owns_flag & ~GPU_BATCH_OWNS_INDEX) != 0) {
     for (int v = 0; v < GPU_BATCH_VBO_MAX_LEN; v++) {
@@ -171,10 +174,11 @@ void GPU_batch_instbuf_set(GPUBatch *batch, GPUVertBuf *inst, bool own_vbo)
   /* redo the bindings */
   GPU_batch_vao_cache_clear(batch);
 
-  if (batch->inst != NULL && (batch->owns_flag & GPU_BATCH_OWNS_INSTANCES)) {
-    GPU_vertbuf_discard(batch->inst);
+  if (batch->inst[0] != NULL && (batch->owns_flag & GPU_BATCH_OWNS_INSTANCES)) {
+    GPU_vertbuf_discard(batch->inst[0]);
+    GPU_VERTBUF_DISCARD_SAFE(batch->inst[1]);
   }
-  batch->inst = inst;
+  batch->inst[0] = inst;
 
   if (own_vbo) {
     batch->owns_flag |= GPU_BATCH_OWNS_INSTANCES;
@@ -203,6 +207,36 @@ void GPU_batch_elembuf_set(GPUBatch *batch, GPUIndexBuf *elem, bool own_ibo)
   }
 }
 
+/* A bit of a quick hack. Should be streamlined as the vbos handling */
+int GPU_batch_instbuf_add_ex(GPUBatch *batch, GPUVertBuf *insts, bool own_vbo)
+{
+  /* redo the bindings */
+  GPU_batch_vao_cache_clear(batch);
+
+  for (uint v = 0; v < GPU_BATCH_INST_VBO_MAX_LEN; v++) {
+    if (batch->inst[v] == NULL) {
+#if TRUST_NO_ONE
+      /* for now all VertexBuffers must have same vertex_len */
+      if (batch->inst[0] != NULL) {
+        assert(insts->vertex_len == batch->inst[0]->vertex_len);
+        assert(own_vbo == (batch->owns_flag & GPU_BATCH_OWNS_INSTANCES) != 0);
+      }
+#endif
+      batch->inst[v] = insts;
+      if (own_vbo) {
+        batch->owns_flag |= GPU_BATCH_OWNS_INSTANCES;
+      }
+      return v;
+    }
+  }
+
+  /* we only make it this far if there is no room for another GPUVertBuf */
+#if TRUST_NO_ONE
+  assert(false);
+#endif
+  return -1;
+}
+
 /* Returns the index of verts in the batch. */
 int GPU_batch_vertbuf_add_ex(GPUBatch *batch, GPUVertBuf *verts, bool own_vbo)
 {
@@ -458,8 +492,10 @@ static void batch_update_program_bindings(GPUBatch *batch, uint i_first)
       create_bindings(batch->vert

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list