DRW: Add compute_ref calls, barriers calls, and vertex_buffer_ref

- Compute ref let the size of dispatch be modified just before drawing.
- Barrier call makes it possible to chain multiple compute passes in one pass.
- DRW_shgroup_vertex_buffer_ref is the analog of DRW_shgroup_uniform_block_ref.
This commit is contained in:
2022-02-04 18:32:40 +01:00
parent 665997f1cd
commit 9aa25ff53d
4 changed files with 82 additions and 1 deletions

View File

@@ -468,6 +468,10 @@ void DRW_shgroup_call_compute(DRWShadingGroup *shgroup,
int groups_x_len,
int groups_y_len,
int groups_z_len);
/**
* \warning this keeps the ref to groups_ref until it actually dispatch.
*/
void DRW_shgroup_call_compute_ref(DRWShadingGroup *shgroup, int groups_ref[3]);
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);
@@ -533,6 +537,11 @@ void DRW_shgroup_stencil_set(DRWShadingGroup *shgroup,
*/
void DRW_shgroup_stencil_mask(DRWShadingGroup *shgroup, uint mask);
/**
* Issue a barrier command.
*/
void DRW_shgroup_barrier(DRWShadingGroup *shgroup, eGPUBarrier type);
/**
* Issue a clear command.
*/
@@ -627,6 +636,9 @@ void DRW_shgroup_uniform_vec4_array_copy(DRWShadingGroup *shgroup,
void DRW_shgroup_vertex_buffer(DRWShadingGroup *shgroup,
const char *name,
struct GPUVertBuf *vertex_buffer);
void DRW_shgroup_vertex_buffer_ref(DRWShadingGroup *shgroup,
const char *name,
struct GPUVertBuf **vertex_buffer);
bool DRW_shgroup_is_empty(DRWShadingGroup *shgroup);

View File

@@ -205,8 +205,10 @@ typedef enum {
/* Compute Commands. */
DRW_CMD_COMPUTE = 8,
DRW_CMD_COMPUTE_REF = 9,
/* Other Commands */
DRW_CMD_BARRIER = 11,
DRW_CMD_CLEAR = 12,
DRW_CMD_DRWSTATE = 13,
DRW_CMD_STENCIL = 14,
@@ -249,6 +251,14 @@ typedef struct DRWCommandCompute {
int groups_z_len;
} DRWCommandCompute;
typedef struct DRWCommandComputeRef {
int *groups_ref;
} DRWCommandComputeRef;
typedef struct DRWCommandBarrier {
eGPUBarrier type;
} DRWCommandBarrier;
typedef struct DRWCommandDrawProcedural {
GPUBatch *batch;
DRWResourceHandle handle;
@@ -286,6 +296,8 @@ typedef union DRWCommand {
DRWCommandDrawInstanceRange instance_range;
DRWCommandDrawProcedural procedural;
DRWCommandCompute compute;
DRWCommandComputeRef compute_ref;
DRWCommandBarrier barrier;
DRWCommandSetMutableState state;
DRWCommandSetStencil stencil;
DRWCommandSetSelectID select_id;
@@ -314,6 +326,7 @@ typedef enum {
DRW_UNIFORM_BLOCK_REF,
DRW_UNIFORM_TFEEDBACK_TARGET,
DRW_UNIFORM_VERTEX_BUFFER_AS_STORAGE,
DRW_UNIFORM_VERTEX_BUFFER_AS_STORAGE_REF,
/** Per drawcall uniforms/UBO */
DRW_UNIFORM_BLOCK_OBMATS,
DRW_UNIFORM_BLOCK_OBINFOS,
@@ -345,6 +358,11 @@ struct DRWUniform {
GPUUniformBuf *block;
GPUUniformBuf **block_ref;
};
/* DRW_UNIFORM_VERTEX_BUFFER_AS_STORAGE */
union {
GPUVertBuf *vertbuf;
GPUVertBuf **vertbuf_ref;
};
/* DRW_UNIFORM_FLOAT_COPY */
float fvalue[4];
/* DRW_UNIFORM_INT_COPY */

View File

@@ -460,6 +460,19 @@ void DRW_shgroup_vertex_buffer(DRWShadingGroup *shgroup,
shgroup, location, DRW_UNIFORM_VERTEX_BUFFER_AS_STORAGE, vertex_buffer, 0, 0, 1);
}
void DRW_shgroup_vertex_buffer_ref(DRWShadingGroup *shgroup,
const char *name,
GPUVertBuf **vertex_buffer)
{
int location = GPU_shader_get_ssbo(shgroup->shader, name);
if (location == -1) {
BLI_assert_msg(0, "Unable to locate binding of shader storage buffer objects.");
return;
}
drw_shgroup_uniform_create_ex(
shgroup, location, DRW_UNIFORM_VERTEX_BUFFER_AS_STORAGE_REF, vertex_buffer, 0, 0, 1);
}
/** \} */
/* -------------------------------------------------------------------- */
@@ -730,6 +743,18 @@ static void drw_command_compute(DRWShadingGroup *shgroup,
cmd->groups_z_len = groups_z_len;
}
static void drw_command_compute_ref(DRWShadingGroup *shgroup, int groups_ref[3])
{
DRWCommandComputeRef *cmd = drw_command_create(shgroup, DRW_CMD_COMPUTE_REF);
cmd->groups_ref = groups_ref;
}
static void drw_command_barrier(DRWShadingGroup *shgroup, eGPUBarrier type)
{
DRWCommandBarrier *cmd = drw_command_create(shgroup, DRW_CMD_BARRIER);
cmd->type = type;
}
static void drw_command_draw_procedural(DRWShadingGroup *shgroup,
GPUBatch *batch,
DRWResourceHandle handle,
@@ -855,6 +880,20 @@ void DRW_shgroup_call_compute(DRWShadingGroup *shgroup,
drw_command_compute(shgroup, groups_x_len, groups_y_len, groups_z_len);
}
void DRW_shgroup_call_compute_ref(DRWShadingGroup *shgroup, int groups_ref[3])
{
BLI_assert(GPU_compute_shader_support());
drw_command_compute_ref(shgroup, groups_ref);
}
void DRW_shgroup_barrier(DRWShadingGroup *shgroup, eGPUBarrier type)
{
BLI_assert(GPU_compute_shader_support());
drw_command_barrier(shgroup, type);
}
static void drw_shgroup_call_procedural_add_ex(DRWShadingGroup *shgroup,
GPUBatch *geom,
Object *ob,

View File

@@ -662,8 +662,11 @@ static void draw_update_uniforms(DRWShadingGroup *shgroup,
*use_tfeedback = GPU_shader_transform_feedback_enable(shgroup->shader,
((GPUVertBuf *)uni->pvalue));
break;
case DRW_UNIFORM_VERTEX_BUFFER_AS_STORAGE_REF:
GPU_vertbuf_bind_as_ssbo(*uni->vertbuf_ref, uni->location);
break;
case DRW_UNIFORM_VERTEX_BUFFER_AS_STORAGE:
GPU_vertbuf_bind_as_ssbo((GPUVertBuf *)uni->pvalue, uni->location);
GPU_vertbuf_bind_as_ssbo(uni->vertbuf, uni->location);
break;
/* Legacy/Fallback support. */
case DRW_UNIFORM_BASE_INSTANCE:
@@ -1049,6 +1052,15 @@ static void draw_shgroup(DRWShadingGroup *shgroup, DRWState pass_state)
cmd->compute.groups_y_len,
cmd->compute.groups_z_len);
break;
case DRW_CMD_COMPUTE_REF:
GPU_compute_dispatch(shgroup->shader,
cmd->compute_ref.groups_ref[0],
cmd->compute_ref.groups_ref[1],
cmd->compute_ref.groups_ref[2]);
break;
case DRW_CMD_BARRIER:
GPU_memory_barrier(cmd->barrier.type);
break;
}
}