anv: Emit a EXECUTE_INDIRECT_DISPATCH when available

On newer platforms (Arrowlake and above) we can issue a
EXECUTE_INDIRECT_DISPATCH that allows us to:
  * Skip issuing mi load/store instructions for indirect parameters

Signed-off-by: Rohan Garg <rohan.garg@intel.com>
Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/26421>
This commit is contained in:
Rohan Garg 2022-06-24 16:53:42 +02:00 committed by Marge Bot
parent 6d4f43f0d6
commit 580728564e

View file

@ -5863,6 +5863,47 @@ get_interface_descriptor_data(struct anv_cmd_buffer *cmd_buffer,
};
}
static inline void
emit_indirect_compute_walker(struct anv_cmd_buffer *cmd_buffer,
const struct anv_shader_bin *shader,
const struct brw_cs_prog_data *prog_data,
struct anv_address indirect_addr)
{
const struct intel_device_info *devinfo = cmd_buffer->device->info;
assert(devinfo->has_indirect_unroll);
struct anv_cmd_compute_state *comp_state = &cmd_buffer->state.compute;
bool predicate = cmd_buffer->state.conditional_render_enabled;
const struct brw_cs_dispatch_info dispatch =
brw_cs_get_dispatch_info(devinfo, prog_data, NULL);
const int dispatch_size = dispatch.simd_size / 16;
struct GENX(COMPUTE_WALKER_BODY) body = {
.SIMDSize = dispatch_size,
.MessageSIMD = dispatch_size,
.IndirectDataStartAddress = comp_state->push_data.offset,
.IndirectDataLength = comp_state->push_data.alloc_size,
.LocalXMaximum = prog_data->local_size[0] - 1,
.LocalYMaximum = prog_data->local_size[1] - 1,
.LocalZMaximum = prog_data->local_size[2] - 1,
.ExecutionMask = dispatch.right_mask,
.PostSync.MOCS = anv_mocs(cmd_buffer->device, NULL, 0),
.InterfaceDescriptor =
get_interface_descriptor_data(cmd_buffer, shader, prog_data,
&dispatch),
};
anv_batch_emit(&cmd_buffer->batch, GENX(EXECUTE_INDIRECT_DISPATCH), ind) {
ind.PredicateEnable = predicate;
ind.MaxCount = 1;
ind.COMPUTE_WALKER_BODY = body;
ind.ArgumentBufferStartAddress = indirect_addr;
ind.MOCS = anv_mocs(cmd_buffer->device,
indirect_addr.bo, 0);
}
}
static inline void
emit_compute_walker(struct anv_cmd_buffer *cmd_buffer,
const struct anv_compute_pipeline *pipeline, bool indirect,
@ -5946,6 +5987,14 @@ emit_cs_walker(struct anv_cmd_buffer *cmd_buffer,
{
bool is_indirect = !anv_address_is_null(indirect_addr);
#if GFX_VERx10 >= 125
if (is_indirect && cmd_buffer->device->info->has_indirect_unroll) {
emit_indirect_compute_walker(cmd_buffer, pipeline->cs, prog_data,
indirect_addr);
return;
}
#endif
if (is_indirect)
compute_load_indirect_params(cmd_buffer, indirect_addr);