[Bf-blender-cvs] [184b01c5099] tmp-drw-callbatching: DRW: Upload model matrices via UBO
Clément Foucault
noreply at git.blender.org
Sat Aug 17 14:49:11 CEST 2019
Commit: 184b01c50998ed757b735008bcb585069c43e674
Author: Clément Foucault
Date: Fri May 31 19:42:03 2019 +0200
Branches: tmp-drw-callbatching
https://developer.blender.org/rB184b01c50998ed757b735008bcb585069c43e674
DRW: Upload model matrices via UBO
The UBO is still not used so nothing should fail for now.
===================================================================
M source/blender/blenlib/BLI_memblock.h
M source/blender/blenlib/intern/BLI_memblock.c
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/editors/mesh/editmesh_intersect.c
M source/blender/gpu/GPU_viewport.h
M source/blender/gpu/intern/gpu_viewport.c
===================================================================
diff --git a/source/blender/blenlib/BLI_memblock.h b/source/blender/blenlib/BLI_memblock.h
index c5ef26ffb91..a4d665a4cfd 100644
--- a/source/blender/blenlib/BLI_memblock.h
+++ b/source/blender/blenlib/BLI_memblock.h
@@ -30,16 +30,21 @@ extern "C" {
#include "BLI_compiler_attrs.h"
+#define BLI_MEM_BLOCK_CHUNK_SIZE (1 << 15) /* 32KiB */
+
struct BLI_memblock;
typedef struct BLI_memblock BLI_memblock;
typedef void (*MemblockValFreeFP)(void *val);
-BLI_memblock *BLI_memblock_create(uint elem_size) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT;
+BLI_memblock *BLI_memblock_create_ex(uint elem_size,
+ uint chunk_size) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT;
void *BLI_memblock_alloc(BLI_memblock *mblk) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1);
void BLI_memblock_clear(BLI_memblock *mblk, MemblockValFreeFP valfreefp) ATTR_NONNULL(1);
void BLI_memblock_destroy(BLI_memblock *mblk, MemblockValFreeFP free_callback) ATTR_NONNULL(1);
+#define BLI_memblock_create(elem_size) BLI_memblock_create_ex(elem_size, BLI_MEM_BLOCK_CHUNK_SIZE)
+
typedef struct BLI_memblock_iter {
void **chunk_list;
int cur_index;
@@ -53,6 +58,9 @@ typedef struct BLI_memblock_iter {
void BLI_memblock_iternew(BLI_memblock *pool, BLI_memblock_iter *iter) ATTR_NONNULL();
void *BLI_memblock_iterstep(BLI_memblock_iter *iter) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
+void *BLI_memblock_elem_get(BLI_memblock *mblk, int chunk, int elem) ATTR_WARN_UNUSED_RESULT
+ ATTR_NONNULL();
+
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/blenlib/intern/BLI_memblock.c b/source/blender/blenlib/intern/BLI_memblock.c
index f26860afe77..b357c5ed4eb 100644
--- a/source/blender/blenlib/intern/BLI_memblock.c
+++ b/source/blender/blenlib/intern/BLI_memblock.c
@@ -37,7 +37,6 @@
#include "BLI_strict_flags.h" /* keep last */
-#define BLI_MEM_BLOCK_CHUNK_SIZE (1 << 15) /* 32KiB */
#define CHUNK_LIST_SIZE 16
struct BLI_memblock {
@@ -61,15 +60,15 @@ struct BLI_memblock {
int chunk_len;
};
-BLI_memblock *BLI_memblock_create(uint elem_size)
+BLI_memblock *BLI_memblock_create_ex(uint elem_size, uint chunk_size)
{
- BLI_assert(elem_size < BLI_MEM_BLOCK_CHUNK_SIZE);
+ BLI_assert(elem_size < chunk_size);
BLI_memblock *mblk = MEM_mallocN(sizeof(BLI_memblock), "BLI_memblock");
mblk->elem_size = (int)elem_size;
mblk->elem_next = 0;
mblk->elem_last = -1;
- mblk->chunk_size = BLI_MEM_BLOCK_CHUNK_SIZE;
+ mblk->chunk_size = (int)chunk_size;
mblk->chunk_len = CHUNK_LIST_SIZE;
mblk->chunk_list = MEM_callocN(sizeof(void *) * (uint)mblk->chunk_len, "chunk list");
mblk->chunk_list[0] = MEM_callocN((uint)mblk->chunk_size, "BLI_memblock chunk");
@@ -180,3 +179,11 @@ void *BLI_memblock_iterstep(BLI_memblock_iter *iter)
}
return ptr;
}
+
+/* Direct access. elem is element index inside the chosen chunk. */
+void *BLI_memblock_elem_get(BLI_memblock *mblk, int chunk, int elem)
+{
+ BLI_assert(chunk < mblk->chunk_len);
+ BLI_assert(elem < (mblk->chunk_size / mblk->elem_size));
+ return (char *)(mblk->chunk_list[chunk]) + mblk->elem_size * elem;
+}
diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c
index b0cea94e1ed..db492404584 100644
--- a/source/blender/draw/intern/draw_manager.c
+++ b/source/blender/draw/intern/draw_manager.c
@@ -613,6 +613,8 @@ static DRWCallState *draw_unit_state_create(void)
culling->bsphere.radius = -1.0f;
culling->user_data = NULL;
+ DRW_NEXT_RESOURCE_HANDLE(DST.resource_handle);
+
return state;
}
@@ -645,10 +647,12 @@ static void drw_viewport_var_init(void)
DST.vmempool->states = BLI_memblock_create(sizeof(DRWCallState));
}
if (DST.vmempool->obmats == NULL) {
- DST.vmempool->obmats = BLI_memblock_create(sizeof(DRWObjectMatrix));
+ uint chunk_len = sizeof(DRWObjectMatrix) * DRW_RESOURCE_CHUNK_LEN;
+ DST.vmempool->obmats = BLI_memblock_create_ex(sizeof(DRWObjectMatrix), chunk_len);
}
if (DST.vmempool->obinfos == NULL) {
- DST.vmempool->obinfos = BLI_memblock_create(sizeof(DRWObjectInfos));
+ uint chunk_len = sizeof(DRWObjectInfos) * DRW_RESOURCE_CHUNK_LEN;
+ DST.vmempool->obinfos = BLI_memblock_create_ex(sizeof(DRWObjectInfos), chunk_len);
}
if (DST.vmempool->cullstates == NULL) {
DST.vmempool->cullstates = BLI_memblock_create(sizeof(DRWCullingState));
@@ -669,7 +673,9 @@ static void drw_viewport_var_init(void)
DST.vmempool->images = BLI_memblock_create(sizeof(GPUTexture *));
}
- /* Alloc default unit state */
+ DST.resource_handle.id = 0;
+ DST.resource_handle.chunk = 0;
+
DST.unit_state = draw_unit_state_create();
DST.idatalist = GPU_viewport_instance_data_list_get(DST.viewport);
@@ -2182,6 +2188,7 @@ void DRW_render_instance_buffer_finish(void)
BLI_assert(!DST.buffer_finish_called && "DRW_render_instance_buffer_finish called twice!");
DST.buffer_finish_called = true;
DRW_instance_buffer_finish(DST.idatalist);
+ drw_resource_buffer_finish(DST.vmempool);
}
/**
diff --git a/source/blender/draw/intern/draw_manager.h b/source/blender/draw/intern/draw_manager.h
index bd8137b2ef7..e8ca365a480 100644
--- a/source/blender/draw/intern/draw_manager.h
+++ b/source/blender/draw/intern/draw_manager.h
@@ -105,6 +105,23 @@ typedef struct DRWCullingState {
void *user_data;
} DRWCullingState;
+/* We count on the fact that unsigned integers wrap around whe overflowing. */
+#define DRW_NEXT_RESOURCE_HANDLE(handle) \
+ do { \
+ if ((handle).id++ == 511) { \
+ (handle).chunk++; \
+ } \
+ } while (0)
+
+/* Minimum max UBO size is 64KiB. We take the largest
+ * UBO struct and alloc the max number. */
+#define DRW_RESOURCE_CHUNK_LEN ((1 << 16) / sizeof(DRWObjectMatrix))
+
+typedef struct DRWResourceHandle {
+ uint32_t id : 9;
+ uint32_t chunk : 23;
+} DRWResourceHandle;
+
typedef struct DRWObjectMatrix {
float model[4][4];
float modelinverse[4][4];
@@ -287,16 +304,23 @@ typedef struct DRWManager {
/* Cache generation */
ViewportMemoryPool *vmempool;
DRWInstanceDataList *idatalist;
- DRWInstanceData *object_instance_data[MAX_INSTANCE_DATA_SIZE];
/* Default Unit model matrix state without culling. */
DRWCallState *unit_state;
/* State of the object being evaluated if already allocated. */
DRWCallState *ob_state;
+ /** Handle of current object resource in object resource arrays (DRWObjectMatrices/Infos). */
+ DRWResourceHandle resource_handle;
+
+ /** Dupli state. NULL if not dupli. */
struct DupliObject *dupli_source;
struct Object *dupli_parent;
struct Object *dupli_origin;
+ /** Ghash containing original objects. */
struct GHash *dupli_ghash;
- void **dupli_datas; /* Array of dupli_data (one for each enabled engine) to handle duplis. */
+ /** TODO(fclem) try to remove usage of this. */
+ DRWInstanceData *object_instance_data[MAX_INSTANCE_DATA_SIZE];
+ /* Array of dupli_data (one for each enabled engine) to handle duplis. */
+ void **dupli_datas;
/* Rendering state */
GPUShader *shader;
@@ -402,6 +426,8 @@ void drw_debug_init(void);
void drw_batch_cache_validate(Object *ob);
void drw_batch_cache_generate_requested(struct Object *ob);
+void drw_resource_buffer_finish(ViewportMemoryPool *vmempool);
+
/* Procedural Drawing */
GPUBatch *drw_cache_procedural_points_get(void);
GPUBatch *drw_cache_procedural_lines_get(void);
diff --git a/source/blender/draw/intern/draw_manager_data.c b/source/blender/draw/intern/draw_manager_data.c
index 5b956fbdf7d..bad6971f208 100644
--- a/source/blender/draw/intern/draw_manager_data.c
+++ b/source/blender/draw/intern/draw_manager_data.c
@@ -66,6 +66,49 @@ void DRW_uniformbuffer_free(GPUUniformBuffer *ubo)
GPU_uniformbuffer_free(ubo);
}
+void drw_resource_buffer_finish(ViewportMemoryPool *vmempool)
+{
+ int ubo_len = 1 + DST.resource_handle.chunk - ((DST.resource_handle.id == 0) ? 1 : 0);
+ size_t list_size = sizeof(GPUUniformBuffer *) * ubo_len;
+
+ /* TODO find a better system. currently a lot of obinfos UBO are going to be unused
+ * if not rendering with Eevee. */
+
+ if (vmempool->matrices_ubo == NULL) {
+ vmempool->matrices_ubo = MEM_callocN(list_size, __func__);
+ vmempool->obinfos_ubo = MEM_callocN(list_size, __func__);
+ vmempool->ubo_len = ubo_len;
+ }
+
+ /* Remove unecessary buffers */
+ for (int i = ubo_len; i < vmempool->ubo_len; i++) {
+ GPU_uniformbuffer_free(vmempool->matrices_ubo[i]);
+ GPU_uniformbuffer_free(vmempool->obinfos_ubo[i]);
+ }
+
+ if (ubo_len != vmempool->ubo_len) {
+ vmempool->matrices_ubo = MEM_recallocN(vmempool->matrices_ubo, list_size);
+ vmempool->obinfos_ubo = MEM_recallocN(vmempool->obinfos_ubo, list_size);
+ vmempool->ubo_len = ubo_len;
+ }
+
+ /* Create/Update buffers. */
+ for (int i = 0; i < ubo_len; i++) {
+ void *data_obmat = BLI_memblock_elem_get(vmempool->obmats, i, 0);
+ void *data_infos = BLI_memblock_elem_get(vmempool->obinfos, i, 0);
+ if (vmempool->matrices_ubo[i] == NULL) {
+ vmempool->matrices_ubo[i] = GPU_uniformbuffer_create(
+ sizeof(DRWObjectMatrix) * DRW_RESOURCE_CHUNK_LEN, data_obmat, NULL);
+ vmempool->obinfos_ubo[i] = GPU_uniformbuffer_create(
+ sizeof(DRWObjectInfos) * DRW_RESOURCE_CHUNK_LEN, data_infos, NULL);
+ }
+ else {
+ GPU_uniformbuffer_update(vmempool->matrices_ubo[i], data_obmat);
+ GPU_uniformbuffer_update(vmempool->obinfos_ubo[i], data_infos);
+ }
+ }
+}
+
/** \} */
/* -------------------------------------------------------------------- */
@@ -354,7 +397,7 @@ static void drw_call_calc_orco(Object *ob, float (*r_orcofacs)[4])
static void drw_call_obinfos_create(DRWCallState *state, Object *ob)
{
BLI_assert(ob);
- DRWObjectInfos *ob_infos = state->ob_infos = BLI_memblock_alloc(DST.vmempool->obinfos);
+ DRWObjectInfos *ob_infos = state->ob_infos;
/* Index. */
ob_infos->ob_index = ob->index;
/* Orco factors. */
@@ -372,7 +415,7 @@ static void drw_call_obinfos_create(DRWCallState *state, Object *ob)
static void drw_call_culling_create(DRWCallState *state, Object *ob)
{
- DRWCullingState *cull = state->culling = BLI_memblock_alloc(DST
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list