Commit: ea8eb348c3afb7566a84171aab1c945b145386d5
Author: Clément Foucault
Date: Fri Aug 16 17:15:13 2019 +0200
Branches: tmp-drw-callbatching
https://developer.blender.org/rBea8eb348c3afb7566a84171aab1c945b145386d5
DRW: Resource Handle: Use manual bitmasks and bitsifts
This is in order to avoid implementation dependant behavior.
===================================================================
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 66defdb6c89..6940ae6a7cb 100644
--- a/source/blender/draw/intern/draw_manager.c
+++ b/source/blender/draw/intern/draw_manager.c
@@ -612,7 +612,7 @@ static void draw_unit_state_create(void)
culling->bsphere.radius = -1.0f;
culling->user_data = NULL;
- INCREMENT_RESOURCE_HANDLE(DST.resource_handle);
+ DRW_handle_increment(&DST.resource_handle);
}
/* It also stores viewport variable to an immutable place: DST
@@ -675,8 +675,8 @@ static void drw_viewport_var_init(void)
DST.vmempool->images = BLI_memblock_create(sizeof(GPUTexture *));
}
- DST.resource_handle.value = 0;
- DST.pass_handle.value = 0;
+ DST.resource_handle = 0;
+ DST.pass_handle = 0;
draw_unit_state_create();
@@ -1121,7 +1121,7 @@ static void drw_engines_world_update(Scene *scene)
static void drw_engines_cache_populate(Object *ob)
{
- DST.ob_handle.value = 0;
+ DST.ob_handle = 0;
/* HACK: DrawData is copied by COW from the duplicated object.
* This is valid for IDs that cannot be instantiated but this
@@ -2085,7 +2085,7 @@ void DRW_render_object_iter(
if ((object_type_exclude_viewport & (1 << ob->type)) == 0) {
DST.dupli_parent = data_.dupli_parent;
DST.dupli_source = data_.dupli_object_current;
- DST.ob_handle.value = 0;
+ DST.ob_handle = 0;
drw_duplidata_load(DST.dupli_source);
if (!DST.dupli_source) {
diff --git a/source/blender/draw/intern/draw_manager.h
b/source/blender/draw/intern/draw_manager.h
index 154b35077a0..051d6a4549a 100644
--- a/source/blender/draw/intern/draw_manager.h
+++ b/source/blender/draw/intern/draw_manager.h
@@ -31,6 +31,7 @@
#include "BLI_assert.h"
#include "BLI_linklist.h"
#include "BLI_threads.h"
+#include "BLI_memblock.h"
#include "GPU_batch.h"
#include "GPU_context.h"
@@ -103,35 +104,60 @@ typedef struct DRWCullingState {
void *user_data;
} DRWCullingState;
-/* We count on the fact that unsigned integers wrap around whe overflowing. */
-#define INCREMENT_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.
* ((1 << 16) / sizeof(DRWObjectMatrix)) = 512
* Keep in sync with common_view_lib.glsl */
#define DRW_RESOURCE_CHUNK_LEN 512
-typedef struct DRWResourceHandle {
- union {
- /* TODO order correctly and make sure
- * endianness does not change anything. */
- struct {
- uint32_t negative_scale : 1;
- uint32_t id : 9;
- uint32_t chunk : 22;
- };
- /** Use this to read the whole handle value as one 32bit uint.
- * Useful for sorting and test.
- */
- uint32_t value;
- };
-} DRWResourceHandle;
+/**
+ * Identifier used to sort similar drawcalls together.
+ * Also used to reference elements inside memory blocks.
+ *
+ * From MSB to LSB
+ * 1 bit for negative scale.
+ * 22 bits for chunk id.
+ * 9 bits for resource id inside the chunk. (can go up to 511)
+ * |-|----------------------|---------|
+ *
+ * Use manual bitsift and mask instead of bitfields to avoid
+ * compiler dependant behavior that would mess the ordering of
+ * the members thus changing the sorting order.
+ */
+typedef uint32_t DRWResourceHandle;
+
+BLI_INLINE uint32_t DRW_handle_negative_scale_get(const DRWResourceHandle
*handle)
+{
+ return (*handle & 0x80000000) != 0;
+}
+
+BLI_INLINE uint32_t DRW_handle_chunk_get(const DRWResourceHandle *handle)
+{
+ return (*handle & 0x7FFFFFFF) >> 9;
+}
+
+BLI_INLINE uint32_t DRW_handle_id_get(const DRWResourceHandle *handle)
+{
+ return (*handle & 0x000001FF);
+}
+
+BLI_INLINE void DRW_handle_increment(DRWResourceHandle *handle)
+{
+ *handle += 1;
+}
+
+BLI_INLINE void DRW_handle_negative_scale_enable(DRWResourceHandle *handle)
+{
+ *handle |= 0x80000000;
+}
+
+BLI_INLINE void *DRW_memblock_elem_from_handle(struct BLI_memblock *memblock,
+ const DRWResourceHandle *handle)
+{
+ int elem = DRW_handle_id_get(handle);
+ int chunk = DRW_handle_chunk_get(handle);
+ return BLI_memblock_elem_get(memblock, chunk, elem);
+}
typedef struct DRWObjectMatrix {
float model[4][4];
diff --git a/source/blender/draw/intern/draw_manager_data.c
b/source/blender/draw/intern/draw_manager_data.c
index 301d2993bf2..6c91d8321a2 100644
--- a/source/blender/draw/intern/draw_manager_data.c
+++ b/source/blender/draw/intern/draw_manager_data.c
@@ -98,7 +98,9 @@ void DRW_uniformbuffer_free(GPUUniformBuffer *ubo)
void drw_resource_buffer_finish(ViewportMemoryPool *vmempool)
{
- int ubo_len = 1 + DST.resource_handle.chunk - ((DST.resource_handle.id == 0)
? 1 : 0);
+ int chunk_id = DRW_handle_chunk_get(&DST.resource_handle);
+ int elem_id = DRW_handle_id_get(&DST.resource_handle);
+ int ubo_len = 1 + chunk_id - ((elem_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
@@ -538,9 +540,11 @@ static DRWResourceHandle drw_resource_handle_new(float
(*obmat)[4], Object *ob)
UNUSED_VARS(ob_infos);
DRWResourceHandle handle = DST.resource_handle;
- INCREMENT_RESOURCE_HANDLE(DST.resource_handle);
+ DRW_handle_increment(&DST.resource_handle);
- handle.negative_scale = (ob && (ob->transflag & OB_NEG_SCALE)) ? 1 : 0;
+ if (ob && (ob->transflag & OB_NEG_SCALE)) {
+ DRW_handle_negative_scale_enable(&handle);
+ }
drw_call_matrix_init(ob_mats, ob, obmat);
drw_call_culling_init(culling, ob);
@@ -555,7 +559,7 @@ static DRWResourceHandle
drw_resource_handle(DRWShadingGroup *shgroup,
{
if (ob == NULL) {
if (obmat == NULL) {
- DRWResourceHandle handle = {.value = 0};
+ DRWResourceHandle handle = 0;
return handle;
}
else {
@@ -563,7 +567,7 @@ static DRWResourceHandle
drw_resource_handle(DRWShadingGroup *shgroup,
}
}
else {
- if (DST.ob_handle.value == 0) {
+ if (DST.ob_handle == 0) {
DST.ob_handle = drw_resource_handle_new(obmat, ob);
DST.ob_state_obinfo_init = false;
}
@@ -571,9 +575,8 @@ static DRWResourceHandle
drw_resource_handle(DRWShadingGroup *shgroup,
if (shgroup->objectinfo) {
if (!DST.ob_state_obinfo_init) {
DST.ob_state_obinfo_init = true;
-
- DRWObjectInfos *ob_infos = BLI_memblock_elem_get(
- DST.vmempool->obinfos, DST.ob_handle.chunk, DST.ob_handle.id);
+ DRWObjectInfos *ob_infos =
DRW_memblock_elem_from_handle(DST.vmempool->obinfos,
+
&DST.ob_handle);
drw_call_obinfos_init(ob_infos, ob);
}
@@ -700,8 +703,8 @@ void DRW_shgroup_call_ex(DRWShadingGroup *shgroup,
/* Culling data. */
if (user_data || bypass_culling) {
- DRWCullingState *culling = BLI_memblock_elem_get(
- DST.vmempool->cullstates, handle.chunk, handle.id);
+ DRWCullingState *culling =
DRW_memblock_elem_from_handle(DST.vmempool->cullstates,
+ &DST.ob_handle);
if (user_data) {
culling->user_data = user_data;
@@ -1248,7 +1251,7 @@ DRWShadingGroup *DRW_shgroup_get_next(DRWShadingGroup
*shgroup)
/* This is a workaround function waiting for the clearing operation to be
available inside the
* shgroups. */
-uint DRW_shgroup_stencil_mask_get(DRWShadingGroup *shgroup)
+uint DRW_shgroup_stencil_mask_get(DRWShadingGroup *UNUSED(shgroup))
{
/* TODO remove. This is broken. */
return 0;
@@ -1263,8 +1266,8 @@ DRWShadingGroup *DRW_shgroup_create_sub(DRWShadingGroup
*shgroup)
shgroup_new->cmd.first = NULL;
shgroup_new->cmd.last = NULL;
- DRWPass *parent_pass = BLI_memblock_elem_get(
- DST.vmempool->passes, shgroup->pass_handle.chunk,
shgroup->pass_handle.id);
+ DRWPass *parent_pass = DRW_memblock_elem_from_handle(DST.vmempool->passes,
+ &shgroup->pass_handle);
BLI_LINKS_INSERT_AFTER(&parent_pass->shgroups, shgroup, shgroup_new);
@@ -1762,7 +1765,7 @@ DRWPass *DRW_pass_create(const char *name, DRWState state)
pass->shgroups.first = NULL;
pass->shgroups.last = NULL;
pass->handle = DST.pass_handle;
- INCREMENT_RESOURCE_HANDLE(DST.pass_handle);
+ DRW_handle_increment(&DST.pass_handle);
return pass;
}
@@ -1854,20 +1857,20 @@ void DRW_pass_sort_shgroup_z(DRWPass *pass)
uint index = 0;
DRWShadingGroup *shgroup = pass->shgroups.first;
do {
- DRWResourceHandle handle = {.value = 0};
+ DRWResourceHandle handle = 0;
/* Find first DRWCommandDraw. */
DRWCommandChunk *cmd_chunk = shgroup->cmd.first;
- for (; cmd_chunk && handle.value == 0; cmd_chunk = cmd_chunk->next) {
- for (int i = 0; i < cmd_chunk->command_used && handle.value == 0; i++) {
+ for (; cmd_chunk && handle == 0; cmd_chunk = cmd_chunk->next) {
+ for (int i = 0; i < cmd_chunk->command_used && handle == 0; i++) {
if (DRW_CMD_DRAW == command_type_get(cmd_chunk->command_type, i)) {
handle = cmd_chunk->commands[i].draw.handle;
}
}
}
/* To be sorted a shgroup needs to have at least one draw command. */
- BLI_assert(handle.value != 0);
+ BLI_assert(handle != 0);
- DRWObjectMatrix *obmats = BLI_memblock_elem_get(DST.vmempool->obmats,
handle.chunk, handle.id);
+ DRWObjectMatrix *obmats =
DRW_memblock_elem_from_handle(DST.vmempool->obmats, &handle);
/* Compute distance to camera. */
float tmp[3];
diff --git a/source/blender/draw/intern/draw_manager_exec.c
b/source/blender/draw/intern/draw_manager_exec.c
index 34f45cfe13d..508768b4613 100644
--- a/source/blender/draw/intern/draw_manager_exec.c
+++ b/source/blender/draw/intern/draw_manager_exec.c
@@ -416,10 +416,9 @@ void DRW_state_reset(void)
/** \name Culling (DRW_culling)
* \{ */
-static bool draw_call_is_culled(DRWResourceHandle handle, DRWView *view)
+static bool draw_call_is_culled(const DRWResourceHandle *handle, DRWView *view)
{
- DRWCullingState *culling = BLI_memblock_elem_get(
- DST.vmempool->cullsta
@@ Diff output truncated at 10240 characters. @@
_______________________________________________
Bf-blender-cvs mailing list
[email protected]
https://lists.blender.org/mailman/listinfo/bf-blender-cvs