DRW: Add DRW_shgroup_call_procedural_triangles_indirect

Just like the name suggest, this adds a way to draw a series of proceduraly
positioned triangles using and indirect buffer.
This commit is contained in:
2022-07-30 13:30:59 +02:00
parent 710609a2e0
commit 9a52f1f720
5 changed files with 97 additions and 2 deletions

View File

@@ -454,6 +454,9 @@ void DRW_shgroup_call_compute_indirect(DRWShadingGroup *shgroup, GPUStorageBuf *
void DRW_shgroup_call_procedural_points(DRWShadingGroup *sh, Object *ob, uint point_count);
void DRW_shgroup_call_procedural_lines(DRWShadingGroup *sh, Object *ob, uint line_count);
void DRW_shgroup_call_procedural_triangles(DRWShadingGroup *sh, Object *ob, uint tri_count);
void DRW_shgroup_call_procedural_triangles_indirect(DRWShadingGroup *shgroup,
Object *ob,
GPUStorageBuf *indirect_buf);
/**
* \warning Only use with Shaders that have `IN_PLACE_INSTANCES` defined.
* TODO: Should be removed.

View File

@@ -188,6 +188,7 @@ typedef enum {
DRW_CMD_DRAW_INSTANCE = 2,
DRW_CMD_DRAW_INSTANCE_RANGE = 3,
DRW_CMD_DRAW_PROCEDURAL = 4,
DRW_CMD_DRAW_INDIRECT = 5,
/* Compute Commands. */
DRW_CMD_COMPUTE = 8,
@@ -203,7 +204,7 @@ typedef enum {
/* Needs to fit in 4bits */
} eDRWCommandType;
#define DRW_MAX_DRAW_CMD_TYPE DRW_CMD_DRAW_PROCEDURAL
#define DRW_MAX_DRAW_CMD_TYPE DRW_CMD_DRAW_INDIRECT
typedef struct DRWCommandDraw {
GPUBatch *batch;
@@ -232,6 +233,12 @@ typedef struct DRWCommandDrawInstanceRange {
uint inst_count;
} DRWCommandDrawInstanceRange;
typedef struct DRWCommandDrawIndirect {
GPUBatch *batch;
DRWResourceHandle handle;
GPUStorageBuf *indirect_buf;
} DRWCommandDrawIndirect;
typedef struct DRWCommandCompute {
int groups_x_len;
int groups_y_len;
@@ -286,6 +293,7 @@ typedef union DRWCommand {
DRWCommandDrawInstance instance;
DRWCommandDrawInstanceRange instance_range;
DRWCommandDrawProcedural procedural;
DRWCommandDrawIndirect draw_indirect;
DRWCommandCompute compute;
DRWCommandComputeRef compute_ref;
DRWCommandComputeIndirect compute_indirect;

View File

@@ -878,6 +878,17 @@ static void drw_command_draw_procedural(DRWShadingGroup *shgroup,
cmd->vert_count = vert_count;
}
static void drw_command_draw_indirect(DRWShadingGroup *shgroup,
GPUBatch *batch,
DRWResourceHandle handle,
GPUStorageBuf *indirect_buf)
{
DRWCommandDrawIndirect *cmd = drw_command_create(shgroup, DRW_CMD_DRAW_INDIRECT);
cmd->batch = batch;
cmd->handle = handle;
cmd->indirect_buf = indirect_buf;
}
static void drw_command_set_select_id(DRWShadingGroup *shgroup, GPUVertBuf *buf, uint select_id)
{
/* Only one can be valid. */
@@ -1005,6 +1016,7 @@ void DRW_shgroup_call_compute_indirect(DRWShadingGroup *shgroup, GPUStorageBuf *
drw_command_compute_indirect(shgroup, indirect_buf);
}
void DRW_shgroup_barrier(DRWShadingGroup *shgroup, eGPUBarrier type)
{
BLI_assert(GPU_compute_shader_support());
@@ -1044,6 +1056,18 @@ void DRW_shgroup_call_procedural_triangles(DRWShadingGroup *shgroup, Object *ob,
drw_shgroup_call_procedural_add_ex(shgroup, geom, ob, tri_count * 3);
}
void DRW_shgroup_call_procedural_triangles_indirect(DRWShadingGroup *shgroup,
Object *ob,
GPUStorageBuf *indirect_buf)
{
struct GPUBatch *geom = drw_cache_procedural_triangles_get();
if (G.f & G_FLAG_PICKSEL) {
drw_command_set_select_id(shgroup, NULL, DST.select_id);
}
DRWResourceHandle handle = drw_resource_handle(shgroup, ob ? ob->obmat : NULL, ob);
drw_command_draw_indirect(shgroup, geom, handle, indirect_buf);
}
void DRW_shgroup_call_instances(DRWShadingGroup *shgroup,
Object *ob,
struct GPUBatch *geom,

View File

@@ -874,6 +874,25 @@ static void draw_call_single_do(DRWShadingGroup *shgroup,
state->baseinst_loc);
}
/* Not to be mistaken with draw_indirect_call which does batch many drawcalls together. This one
* only execute an indirect drawcall with user indirect buffer. */
static void draw_call_indirect(DRWShadingGroup *shgroup,
DRWCommandsState *state,
GPUBatch *batch,
DRWResourceHandle handle,
GPUStorageBuf *indirect_buf)
{
draw_call_batching_flush(shgroup, state);
draw_call_resource_bind(state, &handle);
if (G.f & G_FLAG_PICKSEL) {
GPU_select_load_id(state->select_id);
}
GPU_batch_set_shader(batch, shgroup->shader);
GPU_batch_draw_indirect(batch, indirect_buf);
}
static void draw_call_batching_start(DRWCommandsState *state)
{
state->neg_scale = false;
@@ -996,12 +1015,13 @@ static void draw_shgroup(DRWShadingGroup *shgroup, DRWState pass_state)
while ((cmd = draw_command_iter_step(&iter, &cmd_type))) {
switch (cmd_type) {
case DRW_CMD_DRAW_PROCEDURAL:
case DRW_CMD_DRWSTATE:
case DRW_CMD_STENCIL:
draw_call_batching_flush(shgroup, &state);
break;
case DRW_CMD_DRAW:
case DRW_CMD_DRAW_PROCEDURAL:
case DRW_CMD_DRAW_INDIRECT:
case DRW_CMD_DRAW_INSTANCE:
if (draw_call_is_culled(&cmd->instance.handle, DST.view_active)) {
continue;
@@ -1055,6 +1075,13 @@ static void draw_shgroup(DRWShadingGroup *shgroup, DRWState pass_state)
1,
true);
break;
case DRW_CMD_DRAW_INDIRECT:
draw_call_indirect(shgroup,
&state,
cmd->draw_indirect.batch,
cmd->draw_indirect.handle,
cmd->draw_indirect.indirect_buf);
break;
case DRW_CMD_DRAW_INSTANCE:
draw_call_single_do(shgroup,
&state,

View File

@@ -11,6 +11,9 @@ typedef struct ObjectMatrices ObjectMatrices;
typedef struct ObjectInfos ObjectInfos;
typedef struct VolumeInfos VolumeInfos;
typedef struct CurvesInfos CurvesInfos;
typedef struct DrawCommand DrawCommand;
typedef struct DrawCommandIndexed DrawCommandIndexed;
typedef struct DispatchCommand DispatchCommand;
#endif
#define DRW_SHADER_SHARED_H
@@ -98,3 +101,33 @@ BLI_STATIC_ASSERT_ALIGN(CurvesInfos, 16)
#define OrcoTexCoFactors (drw_infos[resource_id].drw_OrcoTexCoFactors)
#define ObjectInfo (drw_infos[resource_id].drw_Infos)
#define ObjectColor (drw_infos[resource_id].drw_ObjectColor)
/* Indirect commands structures. */
struct DrawCommand {
uint v_count;
uint i_count;
uint v_first;
uint i_first;
};
BLI_STATIC_ASSERT_ALIGN(DrawCommand, 16)
struct DrawCommandIndexed {
uint v_count;
uint i_count;
uint v_first;
uint base_index;
uint i_first;
uint _pad0;
uint _pad1;
uint _pad2;
};
BLI_STATIC_ASSERT_ALIGN(DrawCommandIndexed, 16)
struct DispatchCommand {
uint num_groups_x;
uint num_groups_y;
uint num_groups_z;
uint _pad0;
};
BLI_STATIC_ASSERT_ALIGN(DispatchCommand, 16)