DRW: Add DRW_CALL_PROCEDURAL DRWCall type.

This mimics the behaviour of DRW_shgroup_empty_tri_batch_create and will
replace it eventually.

The advantage is that it's compatible with transform feedback.
This commit is contained in:
Clément Foucault 2018-05-25 12:43:02 +02:00
parent 7b9a0ed8c4
commit 3bc0cb08b8
4 changed files with 46 additions and 0 deletions

View File

@ -329,6 +329,7 @@ DRWShadingGroup *DRW_shgroup_empty_tri_batch_create(
DRWShadingGroup *DRW_shgroup_transform_feedback_create(
struct GPUShader *shader, DRWPass *pass, struct Gwn_VertBuf *tf_target);
typedef void (DRWCallGenerateFn)(
DRWShadingGroup *shgroup,
void (*draw_fn)(DRWShadingGroup *shgroup, struct Gwn_Batch *geom),
@ -344,6 +345,9 @@ void DRW_shgroup_instance_batch(DRWShadingGroup *shgroup, struct Gwn_Batch *batc
void DRW_shgroup_free(struct DRWShadingGroup *shgroup);
void DRW_shgroup_call_add(DRWShadingGroup *shgroup, struct Gwn_Batch *geom, float (*obmat)[4]);
void DRW_shgroup_call_object_add(DRWShadingGroup *shgroup, struct Gwn_Batch *geom, struct Object *ob);
void DRW_shgroup_call_procedural_points_add(DRWShadingGroup *shgroup, unsigned int point_count, float (*obmat)[4]);
void DRW_shgroup_call_procedural_lines_add(DRWShadingGroup *shgroup, unsigned int line_count, float (*obmat)[4]);
void DRW_shgroup_call_procedural_triangles_add(DRWShadingGroup *shgroup, unsigned int tria_count, float (*obmat)[4]);
void DRW_shgroup_call_object_add_with_callback(
DRWShadingGroup *shgroup, struct Gwn_Batch *geom, struct Object *ob,
DRWCallVisibilityFn *callback, void *user_data);

View File

@ -127,6 +127,7 @@ typedef enum {
DRW_CALL_SINGLE, /* A single batch */
DRW_CALL_INSTANCES, /* Draw instances without any instancing attribs. */
DRW_CALL_GENERATE, /* Uses a callback to draw with any number of batches. */
DRW_CALL_PROCEDURAL, /* Generate a drawcall without any Gwn_Batch. */
} DRWCallType;
typedef struct DRWCall {
@ -146,6 +147,10 @@ typedef struct DRWCall {
DRWCallGenerateFn *geometry_fn;
void *user_data;
} generate;
struct { /* type == DRW_CALL_PROCEDURAL */
unsigned int prim_count;
Gwn_PrimType prim_type;
} procedural;
};
DRWCallType type;

View File

@ -366,6 +366,39 @@ void DRW_shgroup_call_add(DRWShadingGroup *shgroup, Gwn_Batch *geom, float (*obm
BLI_LINKS_APPEND(&shgroup->calls, call);
}
static void drw_shgroup_call_procedural_add_ex(
DRWShadingGroup *shgroup, Gwn_PrimType prim_type, unsigned int prim_count, float (*obmat)[4])
{
BLI_assert(ELEM(shgroup->type, DRW_SHG_NORMAL, DRW_SHG_FEEDBACK_TRANSFORM));
DRWCall *call = BLI_mempool_alloc(DST.vmempool->calls);
call->state = drw_call_state_create(shgroup, obmat, NULL);
call->type = DRW_CALL_PROCEDURAL;
call->procedural.prim_type = prim_type;
call->procedural.prim_count = prim_count;
#ifdef USE_GPU_SELECT
call->select_id = DST.select_id;
#endif
BLI_LINKS_APPEND(&shgroup->calls, call);
}
void DRW_shgroup_call_procedural_points_add(DRWShadingGroup *shgroup, unsigned int point_count, float (*obmat)[4])
{
drw_shgroup_call_procedural_add_ex(shgroup, GWN_PRIM_POINTS, point_count, obmat);
}
void DRW_shgroup_call_procedural_lines_add(DRWShadingGroup *shgroup, unsigned int line_count, float (*obmat)[4])
{
drw_shgroup_call_procedural_add_ex(shgroup, GWN_PRIM_LINES, line_count, obmat);
}
void DRW_shgroup_call_procedural_triangles_add(DRWShadingGroup *shgroup, unsigned int tria_count, float (*obmat)[4])
{
drw_shgroup_call_procedural_add_ex(shgroup, GWN_PRIM_TRIS, tria_count, obmat);
}
/* These calls can be culled and are optimized for redraw */
void DRW_shgroup_call_object_add(DRWShadingGroup *shgroup, Gwn_Batch *geom, Object *ob)
{

View File

@ -820,6 +820,7 @@ static void draw_geometry_execute_ex(
DRWShadingGroup *shgroup, Gwn_Batch *geom, uint start, uint count, bool draw_instance)
{
/* Special case: empty drawcall, placement is done via shader, don't bind anything. */
/* TODO use DRW_CALL_PROCEDURAL instead */
if (geom == NULL) {
BLI_assert(shgroup->type == DRW_SHG_TRIANGLE_BATCH); /* Add other type if needed. */
/* Shader is already bound. */
@ -1147,6 +1148,9 @@ static void draw_shgroup(DRWShadingGroup *shgroup, DRWState pass_state)
case DRW_CALL_GENERATE:
call->generate.geometry_fn(shgroup, draw_geometry_execute, call->generate.user_data);
break;
case DRW_CALL_PROCEDURAL:
GWN_draw_primitive(call->procedural.prim_type, call->procedural.prim_count);
break;
default:
BLI_assert(0);
}