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:
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user