[Bf-blender-cvs] [4d7fba508d3] tmp-drw-callbatching: DRW: Put DRWCalls into DRWCallChunks
Clément Foucault
noreply at git.blender.org
Sat Aug 17 14:49:52 CEST 2019
Commit: 4d7fba508d3a2434a0c03df14924703f1198685d
Author: Clément Foucault
Date: Sun Jun 2 20:02:35 2019 +0200
Branches: tmp-drw-callbatching
https://developer.blender.org/rB4d7fba508d3a2434a0c03df14924703f1198685d
DRW: Put DRWCalls into DRWCallChunks
This is in order to improve cache coherence and make it possible
to sort and merge drawcalls in the future.
===================================================================
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
===================================================================
diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c
index eb75abaa8af..8a43ddbc4d5 100644
--- a/source/blender/draw/intern/draw_manager.c
+++ b/source/blender/draw/intern/draw_manager.c
@@ -636,7 +636,7 @@ static void drw_viewport_var_init(void)
DST.vmempool = GPU_viewport_mempool_get(DST.viewport);
if (DST.vmempool->calls == NULL) {
- DST.vmempool->calls = BLI_memblock_create(sizeof(DRWCall));
+ DST.vmempool->calls = BLI_memblock_create(sizeof(DRWCallChunk));
}
if (DST.vmempool->obmats == NULL) {
uint chunk_len = sizeof(DRWObjectMatrix) * DRW_RESOURCE_CHUNK_LEN;
@@ -2202,7 +2202,7 @@ void DRW_draw_select_loop(struct Depsgraph *depsgraph,
Object *obact = OBACT(view_layer);
Object *obedit = OBEDIT_FROM_OBACT(obact);
#ifndef USE_GPU_SELECT
- UNUSED_VARS(vc, scene, view_layer, v3d, ar, rect);
+ UNUSED_VARS(scene, view_layer, v3d, ar, rect);
#else
RegionView3D *rv3d = ar->regiondata;
diff --git a/source/blender/draw/intern/draw_manager.h b/source/blender/draw/intern/draw_manager.h
index b150cb3cbc3..712fa712ec6 100644
--- a/source/blender/draw/intern/draw_manager.h
+++ b/source/blender/draw/intern/draw_manager.h
@@ -150,8 +150,6 @@ BLI_STATIC_ASSERT_ALIGN(DRWObjectMatrix, 16)
BLI_STATIC_ASSERT_ALIGN(DRWObjectInfos, 16)
typedef struct DRWCall {
- struct DRWCall *next;
-
GPUBatch *batch;
uint vert_first;
uint vert_count;
@@ -203,11 +201,11 @@ struct DRWShadingGroup {
GPUShader *shader; /* Shader to bind */
struct DRWUniformChunk *uniforms; /* Uniforms pointers */
-
- uint32_t uniform_count;
+ uint32_t uniform_count; /* Index of next uniform inside DRWUniformChunk. */
struct {
- DRWCall *first, *last; /* Linked list of DRWCall */
+ /* Chunks of draw calls. */
+ struct DRWCallChunk *first, *last;
} calls;
/** TODO Maybe remove from here */
@@ -305,6 +303,22 @@ typedef struct DRWUniformChunk {
DRWUniform uniforms[5];
} DRWUniformChunk;
+typedef struct DRWCallChunk {
+ struct DRWCallChunk *next; /* single-linked list */
+ uchar chunk_len;
+ uchar call_used;
+ DRWCall calls[63];
+} DRWCallChunk;
+
+typedef struct DRWCallSmallChunk {
+ struct DRWCallChunk *next; /* single-linked list */
+ uchar chunk_len;
+ uchar call_used;
+ /* Small chunk to avoid wasting too much memory
+ * on small shading groups. */
+ DRWCall calls[5];
+} DRWCallSmallChunk;
+
/* ------------- DRAW DEBUG ------------ */
typedef struct DRWDebugLine {
diff --git a/source/blender/draw/intern/draw_manager_data.c b/source/blender/draw/intern/draw_manager_data.c
index 8262937ea58..e918c395e17 100644
--- a/source/blender/draw/intern/draw_manager_data.c
+++ b/source/blender/draw/intern/draw_manager_data.c
@@ -518,6 +518,28 @@ static DRWResourceHandle drw_call_handle_object(DRWShadingGroup *shgroup,
}
}
+static DRWCall *drw_call_create(DRWShadingGroup *shgroup)
+{
+ DRWCallChunk *chunk = shgroup->calls.last;
+
+ if (chunk == NULL) {
+ /* TODO Create another pool to reduce memory usage of the first chunk. */
+ DRWCallSmallChunk *smallchunk = BLI_memblock_alloc(DST.vmempool->calls);
+ smallchunk->chunk_len = ARRAY_SIZE(smallchunk->calls);
+ smallchunk->call_used = 0;
+ chunk = (DRWCallChunk *)smallchunk;
+ BLI_LINKS_APPEND(&shgroup->calls, chunk);
+ }
+ else if (chunk->call_used == chunk->chunk_len) {
+ chunk = BLI_memblock_alloc(DST.vmempool->calls);
+ chunk->chunk_len = ARRAY_SIZE(chunk->calls);
+ chunk->call_used = 0;
+ BLI_LINKS_APPEND(&shgroup->calls, chunk);
+ }
+
+ return chunk->calls + chunk->call_used++;
+}
+
void DRW_shgroup_call_ex(DRWShadingGroup *shgroup,
Object *ob,
float (*obmat)[4],
@@ -529,9 +551,7 @@ void DRW_shgroup_call_ex(DRWShadingGroup *shgroup,
{
BLI_assert(geom != NULL);
- DRWCall *call = BLI_memblock_alloc(DST.vmempool->calls);
- BLI_LINKS_APPEND(&shgroup->calls, call);
-
+ DRWCall *call = drw_call_create(shgroup);
call->handle = drw_call_handle_object(shgroup, ob ? ob->obmat : obmat, ob);
call->batch = geom;
call->vert_first = v_sta;
@@ -562,9 +582,7 @@ static void drw_shgroup_call_procedural_add_ex(DRWShadingGroup *shgroup,
uint vert_count)
{
- DRWCall *call = BLI_memblock_alloc(DST.vmempool->calls);
- BLI_LINKS_APPEND(&shgroup->calls, call);
-
+ DRWCall *call = drw_call_create(shgroup);
call->handle = drw_call_handle_object(shgroup, ob ? ob->obmat : NULL, ob);
call->batch = geom;
call->vert_first = 0;
@@ -601,9 +619,7 @@ void DRW_shgroup_call_instances(DRWShadingGroup *shgroup,
{
BLI_assert(geom != NULL);
- DRWCall *call = BLI_memblock_alloc(DST.vmempool->calls);
- BLI_LINKS_APPEND(&shgroup->calls, call);
-
+ DRWCall *call = drw_call_create(shgroup);
call->handle = drw_call_handle_object(shgroup, ob ? ob->obmat : NULL, ob);
call->batch = geom;
call->vert_first = 0;
@@ -625,9 +641,7 @@ void DRW_shgroup_call_instances_with_attribs(DRWShadingGroup *shgroup,
GPUVertBuf *buf_inst = inst_attributes->verts[0];
- DRWCall *call = BLI_memblock_alloc(DST.vmempool->calls);
- BLI_LINKS_APPEND(&shgroup->calls, call);
-
+ DRWCall *call = drw_call_create(shgroup);
call->handle = drw_call_handle_object(shgroup, ob ? ob->obmat : NULL, ob);
call->batch = DRW_temp_batch_instance_request(DST.idatalist, buf_inst, geom);
call->vert_first = 0;
@@ -789,9 +803,7 @@ DRWCallBuffer *DRW_shgroup_call_buffer(DRWShadingGroup *shgroup,
BLI_assert(ELEM(prim_type, GPU_PRIM_POINTS, GPU_PRIM_LINES, GPU_PRIM_TRI_FAN));
BLI_assert(format != NULL);
- DRWCall *call = BLI_memblock_alloc(DST.vmempool->calls);
- BLI_LINKS_APPEND(&shgroup->calls, call);
-
+ DRWCall *call = drw_call_create(shgroup);
call->handle = drw_call_handle_object(shgroup, NULL, NULL);
GPUVertBuf *buf = DRW_temp_buffer_request(DST.idatalist, format, &call->vert_count);
call->batch = DRW_temp_batch_request(DST.idatalist, buf, prim_type);
@@ -819,9 +831,7 @@ DRWCallBuffer *DRW_shgroup_call_buffer_instance(DRWShadingGroup *shgroup,
BLI_assert(geom != NULL);
BLI_assert(format != NULL);
- DRWCall *call = BLI_memblock_alloc(DST.vmempool->calls);
- BLI_LINKS_APPEND(&shgroup->calls, call);
-
+ DRWCall *call = drw_call_create(shgroup);
call->handle = drw_call_handle_object(shgroup, NULL, NULL);
GPUVertBuf *buf = DRW_temp_buffer_request(DST.idatalist, format, &call->inst_count);
call->batch = DRW_temp_batch_instance_request(DST.idatalist, buf, geom);
@@ -1653,8 +1663,8 @@ static int pass_shgroup_dist_sort(void *thunk, const void *a, const void *b)
const DRWShadingGroup *shgrp_a = (const DRWShadingGroup *)a;
const DRWShadingGroup *shgrp_b = (const DRWShadingGroup *)b;
- const DRWCall *call_a = (DRWCall *)shgrp_a->calls.first;
- const DRWCall *call_b = (DRWCall *)shgrp_b->calls.first;
+ const DRWCall *call_a = &((DRWCallChunk *)shgrp_a->calls.first)->calls[0];
+ const DRWCall *call_b = &((DRWCallChunk *)shgrp_b->calls.first)->calls[0];
if (call_a == NULL) {
return -1;
diff --git a/source/blender/draw/intern/draw_manager_exec.c b/source/blender/draw/intern/draw_manager_exec.c
index 51562df2268..09de805cfc5 100644
--- a/source/blender/draw/intern/draw_manager_exec.c
+++ b/source/blender/draw/intern/draw_manager_exec.c
@@ -37,13 +37,13 @@
# include "GPU_select.h"
#endif
-#ifdef USE_GPU_SELECT
void DRW_select_load_id(uint id)
{
+#ifdef USE_GPU_SELECT
BLI_assert(G.f & G_FLAG_PICKSEL);
DST.select_id = id;
-}
#endif
+}
#define DEBUG_UBO_BINDING
@@ -931,6 +931,33 @@ BLI_INLINE bool draw_select_do_call(DRWShadingGroup *shgroup, DRWCall *call, uin
#endif
}
+typedef struct DRWCallIterator {
+ int call_index;
+ DRWCallChunk *curr_chunk;
+} DRWCallIterator;
+
+static void draw_call_iter_begin(DRWCallIterator *iter, DRWShadingGroup *shgroup)
+{
+ iter->curr_chunk = shgroup->calls.first;
+ iter->call_index = 0;
+}
+
+static DRWCall *draw_call_iter_step(DRWCallIterator *iter)
+{
+ if (iter->curr_chunk) {
+ if (iter->call_index == iter->curr_chunk->chunk_len) {
+ iter->curr_chunk = iter->curr_chunk->next;
+ iter->call_index = 0;
+ }
+ if (iter->curr_chunk) {
+ if (iter->call_index < iter->curr_chunk->call_used) {
+ return iter->curr_chunk->calls + iter->call_index++;
+ }
+ }
+ }
+ return NULL;
+}
+
static void draw_shgroup(DRWShadingGroup *shgroup, DRWState pass_state)
{
BLI_assert(shgroup->shader);
@@ -969,7 +996,12 @@ static void draw_shgroup(DRWShadingGroup *shgroup, DRWState pass_state)
uint resource_chunk = 0;
uint base_inst = 0;
int callid = 0;
- for (DRWCall *call = shgroup->calls.first; call; call = call->next) {
+
+ DRWCallIterator iter;
+ draw_call_iter_begin(&iter, shgroup);
+ DRWCall *call;
+
+ while ((call = draw_call_iter_step(&iter))) {
DRWResourceHandle handle = call->handle;
if (draw_call_is_culled(call, DST.view_active)) {
@@ -996,7 +1028,7 @@ static void draw_shgroup(DRWShadingGroup *shgroup, DRWState pass_state)
}
if (obinfos_loc != -1) {
GPU_uniformbuffer_unbind(DST.vmempool->obinfos_ubo[resource_chunk]);
- GPU_uniformbuffer_bind(DST.vmempool->obinfos_ubo[handle.chunk], 0);
+ GPU_uniformbuffer_bind(DST.vmempool->obinfos_ubo[handle.chunk], 1);
}
resource_chunk = handle.chunk;
}
More information about the Bf-blender-cvs
mailing list