[Bf-blender-cvs] [377915b0814] blender2.8: DRW: Make use of DRWInstanceData.
Clément Foucault
noreply at git.blender.org
Tue Jan 9 15:17:27 CET 2018
Commit: 377915b08144e0945ed1984338def3dcad267a6d
Author: Clément Foucault
Date: Tue Jan 9 14:21:55 2018 +0100
Branches: blender2.8
https://developer.blender.org/rB377915b08144e0945ed1984338def3dcad267a6d
DRW: Make use of DRWInstanceData.
This modify the selection code quite a bit but it's for the better.
When using selection we use the same batching / instancing process but we draw each element at a time using a an offset to the first element we want to draw and by drawing only one element.
This result much less memory allocation and better draw time.
===================================================================
M source/blender/draw/intern/draw_manager.c
M source/blender/draw/modes/object_mode.c
===================================================================
diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c
index eda2f775028..9aead1d4c33 100644
--- a/source/blender/draw/intern/draw_manager.c
+++ b/source/blender/draw/intern/draw_manager.c
@@ -88,6 +88,8 @@
/* only for callbacks */
#include "draw_cache_impl.h"
+#include "draw_instance_data.h"
+
#include "draw_mode_engines.h"
#include "engines/clay/clay_engine.h"
#include "engines/eevee/eevee_engine.h"
@@ -221,6 +223,12 @@ struct DRWInterface {
/* Dynamic batch */
Gwn_Batch *instance_batch; /* contains instances attributes */
GLuint instance_vbo; /* same as instance_batch but generated from DRWCalls */
+ struct DRWInstanceData *inst_data;
+#ifdef USE_GPU_SELECT
+ struct DRWInstanceData *inst_selectid;
+ /* Override for single object instances. */
+ int override_selectid;
+#endif
int instance_count;
Gwn_VertFormat vbo_format;
};
@@ -328,6 +336,7 @@ static struct DRWGlobalState {
DRWCallGenerate *last_callgenerate;
DRWCallDynamic *last_calldynamic;
DRWShadingGroup *last_shgroup;
+ DRWInstanceDataList *idatalist;
/* Rendering state */
GPUShader *shader;
@@ -686,12 +695,14 @@ static void drw_interface_create(DRWInterface *interface, GPUShader *shader)
interface->attribs_stride = 0;
interface->instance_vbo = 0;
interface->instance_batch = NULL;
+ interface->inst_data = NULL;
+ interface->uniforms = NULL;
+#ifdef USE_GPU_SELECT
+ interface->inst_selectid = NULL;
+ interface->override_selectid = -1;
+#endif
memset(&interface->vbo_format, 0, sizeof(Gwn_VertFormat));
-
- interface->uniforms = NULL;
- interface->attribs = NULL;
- interface->attribs_first = NULL;
}
@@ -729,14 +740,22 @@ static void drw_interface_uniform(DRWShadingGroup *shgroup, const char *name,
shgroup->interface.uniforms = uni;
}
-static void drw_interface_attrib(DRWShadingGroup *shgroup, const char *name, DRWAttribType type, int size, bool dummy)
+static void drw_interface_attrib(DRWShadingGroup *shgroup, const char *name, DRWAttribType UNUSED(type), int size, bool dummy)
{
- DRWAttrib *attrib = BLI_mempool_alloc(DST.vmempool->attribs);
+ unsigned int attrib_id = shgroup->interface.attribs_count;
GLuint program = GPU_shader_get_program(shgroup->shader);
- attrib->location = glGetAttribLocation(program, name);
- attrib->type = type;
- attrib->size = size;
+ shgroup->interface.attribs_loc[attrib_id] = glGetAttribLocation(program, name);
+ shgroup->interface.attribs_size[attrib_id] = size;
+ shgroup->interface.attribs_stride += size;
+ shgroup->interface.attribs_count += 1;
+
+ if (shgroup->type != DRW_SHG_INSTANCE) {
+ BLI_assert(size <= 4); /* Matrices are not supported by Gawain. */
+ GWN_vertformat_attr_add(&shgroup->interface.vbo_format, name, GWN_COMP_F32, size, GWN_FETCH_FLOAT);
+ }
+
+ BLI_assert(shgroup->interface.attribs_count < MAX_ATTRIB_COUNT);
/* Adding attribute even if not found for now (to keep memory alignment).
* Should ideally take vertex format automatically from batch eventually */
@@ -751,23 +770,6 @@ static void drw_interface_attrib(DRWShadingGroup *shgroup, const char *name, DRW
#else
UNUSED_VARS(dummy);
#endif
-
- BLI_assert(BLI_strnlen(name, 32) < 32);
- BLI_strncpy(attrib->name, name, 32);
-
- shgroup->interface.attribs_count += 1;
- BLI_assert(shgroup->interface.attribs_count < MAX_ATTRIB_COUNT);
-
- /* Prepend */
- if (shgroup->interface.attribs == NULL) {
- shgroup->interface.attribs = attrib;
- shgroup->interface.attribs_first = attrib;
- }
- else {
- shgroup->interface.attribs->prev = attrib;
- shgroup->interface.attribs = attrib;
- }
- attrib->prev = NULL;
}
/** \} */
@@ -965,14 +967,6 @@ void DRW_shgroup_free(struct DRWShadingGroup *shgroup)
GWN_BATCH_DISCARD_SAFE(shgroup->batch_geom);
}
-void DRW_shgroup_instance_batch(DRWShadingGroup *shgroup, struct Gwn_Batch *instances)
-{
- BLI_assert(shgroup->type == DRW_SHG_INSTANCE);
- BLI_assert(shgroup->interface.instance_batch == NULL);
-
- shgroup->interface.instance_batch = instances;
-}
-
#define CALL_PREPEND(shgroup, call) { \
if (shgroup->calls == NULL) { \
shgroup->calls = call; \
@@ -985,10 +979,25 @@ void DRW_shgroup_instance_batch(DRWShadingGroup *shgroup, struct Gwn_Batch *inst
call->head.prev = NULL; \
} ((void)0)
+void DRW_shgroup_instance_batch(DRWShadingGroup *shgroup, struct Gwn_Batch *instances)
+{
+ BLI_assert(shgroup->type == DRW_SHG_INSTANCE);
+ BLI_assert(shgroup->interface.instance_batch == NULL);
+
+ shgroup->interface.instance_batch = instances;
+
+#ifdef USE_GPU_SELECT
+ DRWCall *call = BLI_mempool_alloc(DST.vmempool->calls);
+ call->head.select_id = g_DRW_select_id;
+
+ CALL_PREPEND(shgroup, call);
+#endif
+}
void DRW_shgroup_call_add(DRWShadingGroup *shgroup, Gwn_Batch *geom, float (*obmat)[4])
{
BLI_assert(geom != NULL);
+ BLI_assert(shgroup->type == DRW_SHG_NORMAL);
DRWCall *call = BLI_mempool_alloc(DST.vmempool->calls);
@@ -1010,6 +1019,7 @@ void DRW_shgroup_call_add(DRWShadingGroup *shgroup, Gwn_Batch *geom, float (*obm
void DRW_shgroup_call_object_add(DRWShadingGroup *shgroup, Gwn_Batch *geom, Object *ob)
{
BLI_assert(geom != NULL);
+ BLI_assert(shgroup->type == DRW_SHG_NORMAL);
DRWCall *call = BLI_mempool_alloc(DST.vmempool->calls);
@@ -1031,6 +1041,7 @@ void DRW_shgroup_call_generate_add(
float (*obmat)[4])
{
BLI_assert(geometry_fn != NULL);
+ BLI_assert(shgroup->type == DRW_SHG_NORMAL);
DRWCallGenerate *call = BLI_mempool_alloc(DST.vmempool->calls_generate);
@@ -1074,43 +1085,30 @@ void DRW_shgroup_call_dynamic_add_array(DRWShadingGroup *shgroup, const void *at
DRWInterface *interface = &shgroup->interface;
#ifdef USE_GPU_SELECT
- if ((G.f & G_PICKSEL) && (interface->instance_count > 0)) {
- DRWShadingGroup *original_shgroup = shgroup;
- shgroup = BLI_mempool_alloc(DST.vmempool->shgroups);
- memcpy(shgroup, original_shgroup, sizeof(DRWShadingGroup));
-
- shgroup->calls = NULL;
- shgroup->calls_first = NULL;
-
- interface = &shgroup->interface;
- interface->instance_count = 0;
-
- /* Append */
- if (shgroup->pass_parent->shgroups != NULL) {
- shgroup->pass_parent->shgroups_last->next = shgroup;
- }
- else {
- shgroup->pass_parent->shgroups = shgroup;
+ if (G.f & G_PICKSEL) {
+ if (interface->inst_selectid == NULL) {
+ interface->inst_selectid = DRW_instance_data_request(DST.idatalist, 1, 128);
}
- shgroup->pass_parent->shgroups_last = shgroup;
- shgroup->next = NULL;
+
+ int *select_id = DRW_instance_data_next(interface->inst_selectid);
+ *select_id = g_DRW_select_id;
}
#endif
- DRWCallDynamic *call = BLI_mempool_alloc(DST.vmempool->calls_dynamic);
-
- CALL_PREPEND(shgroup, call);
-
BLI_assert(attr_len == interface->attribs_count);
UNUSED_VARS_NDEBUG(attr_len);
- call->head.type = DRW_CALL_DYNAMIC;
-#ifdef USE_GPU_SELECT
- call->head.select_id = g_DRW_select_id;
-#endif
+ if (interface->attribs_stride > 0) {
+ if (interface->inst_data == NULL) {
+ interface->inst_data = DRW_instance_data_request(DST.idatalist, interface->attribs_stride, 16);
+ }
+
+ float *data = DRW_instance_data_next(interface->inst_data);
- if (interface->attribs_count != 0) {
- memcpy((void *)call->data, attr, sizeof(void *) * interface->attribs_count);
+ for (int i = 0; i < interface->attribs_count; ++i) {
+ memcpy(data, attr[i], sizeof(float) * interface->attribs_size[i]);
+ data = data + interface->attribs_size[i];
+ }
}
interface->instance_count += 1;
@@ -1121,8 +1119,15 @@ void DRW_shgroup_set_instance_count(DRWShadingGroup *shgroup, int count)
{
DRWInterface *interface = &shgroup->interface;
+ BLI_assert(interface->instance_count == 0);
BLI_assert(interface->attribs_count == 0);
+#ifdef USE_GPU_SELECT
+ if (G.f & G_PICKSEL) {
+ interface->override_selectid = g_DRW_select_id;
+ }
+#endif
+
interface->instance_count = count;
}
@@ -1238,33 +1243,8 @@ static void shgroup_dynamic_batch(DRWShadingGroup *shgroup)
return;
/* Upload Data */
- if (interface->vbo_format.attrib_ct == 0) {
- for (DRWAttrib *attrib = interface->attribs_first; attrib; attrib = attrib->prev) {
- BLI_assert(attrib->size <= 4); /* matrices have no place here for now */
- if (attrib->type == DRW_ATTRIB_FLOAT) {
- attrib->format_id = GWN_vertformat_attr_add(
- &interface->vbo_format, attrib->name, GWN_COMP_F32, attrib->size, GWN_FETCH_FLOAT);
- }
- else if (attrib->type == DRW_ATTRIB_INT) {
- attrib->format_id = GWN_vertformat_attr_add(
- &interface->vbo_format, attrib->name, GWN_COMP_I8, attrib->size, GWN_FETCH_INT);
- }
- else {
- BLI_assert(false);
- }
- }
- }
-
Gwn_VertBuf *vbo = GWN_vertbuf_create_with_format(&interface->vbo_format);
- GWN_vertbuf_data_alloc(vbo, nbr);
-
- int j = 0;
- for (DRWCallDynamic *call = shgroup->calls_first; call; call = call->head.prev, j++) {
- int i = 0;
- for (DRWAttrib *attrib = interface->attribs_first; attrib; attrib = attrib->prev, i++) {
- GWN_vertbuf_attr_set(vbo, attrib->format_id, j, call->data[i]);
- }
- }
+ GWN_vertbuf_data_set(vbo, nbr, DRW_instance_data_get(interface->inst_data), false);
/* TODO make the batch dynamic instead of freeing it every times */
if (shgroup->batch_geom)
@@ -1275,10 +1255,9 @@ static void shgroup_dynamic_batch(DRWShadingGroup *shgroup)
static void shgroup_dynamic_instance(DRWShadingGroup *shgroup)
{
- int i = 0;
- int offset = 0;
DRWInterface *interface = &shgroup->interface;
int buffer_size = 0;
+ void *data = NULL;
if (interface->instance_batch != NULL) {
return;
@@ -1293,26 +1272,8 @@ static void shgroup_dynamic_instance(DRWShadingGroup *shgroup)
return;
}
- /* only once */
- if (interface->attribs_stride == 0) {
- for (DRWAttrib *attrib = interface->attribs_first; attrib; attrib = attrib->prev, i++) {
- BLI_assert(attrib->type == DRW_ATTRIB_FLOAT); /* Only float for now */
- interface->attribs_stride += attrib->size;
- interface->attribs_size[i] = attrib->size;
- interface->attribs_loc[i] = attrib->location;
- }
- }
-
/* Gather Data */
buffer_size = sizeof(float) * interface->attribs_stride * interface->instance_count;
- float *data = MEM_mallocN(buffer_size, "Instance VBO data");
-
- for (DRWCallDynamic *call = shg
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list