cmd_buffer->state.last_drawid = -1;
cmd_buffer->state.last_vertex_offset = -1;
- /* Note: firstTask/firstVertex is not supported by this draw packet. */
- uint32_t xyz_dim_reg = (base_reg + 4 - SI_SH_REG_OFFSET) >> 2;
- uint32_t draw_id_reg = (base_reg + 16 - SI_SH_REG_OFFSET) >> 2;
+ uint32_t xyz_dim_reg = (base_reg - SI_SH_REG_OFFSET) >> 2;
+ uint32_t draw_id_reg = (base_reg + 12 - SI_SH_REG_OFFSET) >> 2;
uint32_t draw_id_enable = !!cmd_buffer->state.graphics_pipeline->uses_drawid;
uint32_t xyz_dim_enable = 1; /* TODO: disable XYZ_DIM when unneeded */
assert(ring_entry_loc->sgpr_idx != -1);
uint32_t base_reg = cmd_buffer->state.graphics_pipeline->vtx_base_sgpr;
- uint32_t xyz_dim_reg = ((base_reg + 4) - SI_SH_REG_OFFSET) >> 2;
+ uint32_t xyz_dim_reg = (base_reg - SI_SH_REG_OFFSET) >> 2;
uint32_t ring_entry_reg = ((base_reg + ring_entry_loc->sgpr_idx * 4) - SI_SH_REG_OFFSET) >> 2;
uint32_t xyz_dim_en = 1; /* TODO: disable XYZ_DIM when unneeded */
uint32_t mode1_en = 1; /* legacy fast launch mode */
ALWAYS_INLINE static void
radv_emit_userdata_mesh(struct radv_cmd_buffer *cmd_buffer,
- const uint32_t x, const uint32_t y, const uint32_t z,
- const uint32_t first_task)
+ const uint32_t x, const uint32_t y, const uint32_t z)
{
struct radv_cmd_state *state = &cmd_buffer->state;
struct radeon_cmdbuf *cs = cmd_buffer->cs;
const bool uses_drawid = state->graphics_pipeline->uses_drawid;
radeon_set_sh_reg_seq(cs, state->graphics_pipeline->vtx_base_sgpr, state->graphics_pipeline->vtx_emit_num);
- radeon_emit(cs, first_task);
radeon_emit(cs, x);
radeon_emit(cs, y);
radeon_emit(cs, z);
}
ALWAYS_INLINE static void
-radv_emit_userdata_mesh_first_task_0_draw_id_0(struct radv_cmd_buffer *cmd_buffer)
+radv_emit_userdata_mesh_draw_id_0(struct radv_cmd_buffer *cmd_buffer)
{
struct radv_cmd_state *state = &cmd_buffer->state;
struct radeon_cmdbuf *cs = cmd_buffer->cs;
struct radv_graphics_pipeline *pipeline = state->graphics_pipeline;
const bool uses_drawid = pipeline->uses_drawid;
- radeon_set_sh_reg_seq(cs, pipeline->vtx_base_sgpr, 1);
- radeon_emit(cs, 0);
-
if (uses_drawid) {
radeon_set_sh_reg_seq(cs, pipeline->vtx_base_sgpr + (pipeline->vtx_emit_num - 1) * 4, 1);
radeon_emit(cs, 0);
}
ALWAYS_INLINE static void
-radv_emit_userdata_task_ib_only(struct radv_cmd_buffer *cmd_buffer, uint64_t ib_va,
- uint32_t ib_stride)
-{
- struct radv_shader *task_shader = cmd_buffer->state.shaders[MESA_SHADER_TASK];
- struct radeon_cmdbuf *cs = cmd_buffer->ace_internal.cs;
-
- const struct radv_userdata_info *task_ib_loc = radv_get_user_sgpr(task_shader, AC_UD_CS_TASK_IB);
-
- if (task_ib_loc->sgpr_idx != -1) {
- assert(task_ib_loc->num_sgprs == 3);
- unsigned task_ib_reg = R_00B900_COMPUTE_USER_DATA_0 + task_ib_loc->sgpr_idx * 4;
-
- radeon_set_sh_reg_seq(cs, task_ib_reg, 3);
- radeon_emit(cs, ib_va);
- radeon_emit(cs, ib_va >> 32);
- radeon_emit(cs, ib_stride);
- }
-}
-
-ALWAYS_INLINE static void
radv_emit_userdata_task(struct radv_cmd_buffer *cmd_buffer, uint32_t x, uint32_t y, uint32_t z,
- uint32_t draw_id, uint32_t first_task, uint64_t ib_va)
+ uint32_t draw_id)
{
struct radv_shader *task_shader = cmd_buffer->state.shaders[MESA_SHADER_TASK];
struct radeon_cmdbuf *cs = cmd_buffer->ace_internal.cs;
radeon_set_sh_reg_seq(cs, draw_id_reg, 1);
radeon_emit(cs, draw_id);
}
-
- radv_emit_userdata_task_ib_only(cmd_buffer, ib_va, first_task ? 8 : 0);
}
/* Bind an internal index buffer for GPUs that hang with 0-sized index buffers to handle robustness2
ALWAYS_INLINE static void
radv_emit_direct_mesh_draw_packet(struct radv_cmd_buffer *cmd_buffer,
- uint32_t x, uint32_t y, uint32_t z,
- uint32_t first_task)
+ uint32_t x, uint32_t y, uint32_t z)
{
const uint32_t view_mask = cmd_buffer->state.render.view_mask;
const uint32_t count = x * y * z;
- radv_emit_userdata_mesh(cmd_buffer, x, y, z, first_task);
+ radv_emit_userdata_mesh(cmd_buffer, x, y, z);
if (!view_mask) {
radv_cs_emit_draw_packet(cmd_buffer, count, 0);
radeon_emit(cs, va);
radeon_emit(cs, va >> 32);
- radv_emit_userdata_mesh_first_task_0_draw_id_0(cmd_buffer);
+ radv_emit_userdata_mesh_draw_id_0(cmd_buffer);
if (!state->render.view_mask) {
radv_cs_emit_indirect_mesh_draw_packet(cmd_buffer, info->count, count_va, info->stride);
ALWAYS_INLINE static void
radv_emit_direct_taskmesh_draw_packets(struct radv_cmd_buffer *cmd_buffer, uint32_t x, uint32_t y,
- uint32_t z, uint32_t first_task)
+ uint32_t z)
{
- uint64_t fake_ib_va = 0;
const uint32_t view_mask = cmd_buffer->state.render.view_mask;
const unsigned num_views = MAX2(1, util_bitcount(view_mask));
unsigned ace_predication_size = num_views * 6; /* DISPATCH_TASKMESH_DIRECT_ACE size */
- if (first_task) {
- /* Pass this as the IB to the shader for emulating firstTask in task shaders. */
- uint32_t fake_ib_dwords[2] = {x, first_task};
- unsigned fake_ib_offset;
- radv_cmd_buffer_upload_data(cmd_buffer, 8, fake_ib_dwords, &fake_ib_offset);
- fake_ib_va = radv_buffer_get_va(cmd_buffer->upload.upload_bo) + fake_ib_offset;
- }
-
- radv_emit_userdata_task(cmd_buffer, x, y, z, 0, first_task, fake_ib_va);
- radv_emit_userdata_mesh_first_task_0_draw_id_0(cmd_buffer);
+ radv_emit_userdata_task(cmd_buffer, x, y, z, 0);
+ radv_emit_userdata_mesh_draw_id_0(cmd_buffer);
radv_cs_emit_compute_predication(&cmd_buffer->state, cmd_buffer->ace_internal.cs,
cmd_buffer->mec_inv_pred_va, &cmd_buffer->mec_inv_pred_emitted,
ace_predication_size);
static void
radv_emit_indirect_taskmesh_draw_packets(struct radv_cmd_buffer *cmd_buffer,
- const struct radv_draw_info *info, uint64_t nv_ib_va,
- uint32_t nv_ib_stride)
+ const struct radv_draw_info *info)
{
const uint32_t view_mask = cmd_buffer->state.render.view_mask;
struct radeon_winsys *ws = cmd_buffer->device->ws;
}
radv_cs_add_buffer(ws, cmd_buffer->ace_internal.cs, info->indirect->bo);
- radv_emit_userdata_task_ib_only(cmd_buffer, nv_ib_va, nv_ib_stride);
- radv_emit_userdata_mesh_first_task_0_draw_id_0(cmd_buffer);
+ radv_emit_userdata_mesh_draw_id_0(cmd_buffer);
radv_cs_emit_compute_predication(&cmd_buffer->state, cmd_buffer->ace_internal.cs,
cmd_buffer->mec_inv_pred_va, &cmd_buffer->mec_inv_pred_emitted,
ace_predication_size);
return;
if (radv_cmdbuf_has_stage(cmd_buffer, MESA_SHADER_TASK)) {
- radv_emit_direct_taskmesh_draw_packets(cmd_buffer, x, y, z, 0);
+ radv_emit_direct_taskmesh_draw_packets(cmd_buffer, x, y, z);
} else {
- radv_emit_direct_mesh_draw_packet(cmd_buffer, x, y, z, 0);
+ radv_emit_direct_mesh_draw_packet(cmd_buffer, x, y, z);
}
radv_after_draw(cmd_buffer);
return;
if (radv_cmdbuf_has_stage(cmd_buffer, MESA_SHADER_TASK)) {
- radv_emit_indirect_taskmesh_draw_packets(cmd_buffer, &info, 0, 0);
+ radv_emit_indirect_taskmesh_draw_packets(cmd_buffer, &info);
} else {
radv_emit_indirect_mesh_draw_packets(cmd_buffer, &info);
}
return;
if (radv_cmdbuf_has_stage(cmd_buffer, MESA_SHADER_TASK)) {
- radv_emit_indirect_taskmesh_draw_packets(cmd_buffer, &info, 0, 0);
+ radv_emit_indirect_taskmesh_draw_packets(cmd_buffer, &info);
} else {
radv_emit_indirect_mesh_draw_packets(cmd_buffer, &info);
}
return progress;
}
-/* Emulates NV_mesh_shader first_task using first_vertex. */
-static bool
-radv_lower_ms_workgroup_id(nir_shader *nir)
-{
- nir_function_impl *impl = nir_shader_get_entrypoint(nir);
- bool progress = false;
- nir_builder b;
- nir_builder_init(&b, impl);
-
- nir_foreach_block(block, impl) {
- nir_foreach_instr_safe(instr, block) {
- if (instr->type != nir_instr_type_intrinsic)
- continue;
-
- nir_intrinsic_instr *intrin = nir_instr_as_intrinsic(instr);
- if (intrin->intrinsic != nir_intrinsic_load_workgroup_id)
- continue;
-
- progress = true;
- b.cursor = nir_after_instr(instr);
- nir_ssa_def *x = nir_channel(&b, &intrin->dest.ssa, 0);
- nir_ssa_def *x_full = nir_iadd(&b, x, nir_load_first_vertex(&b));
- nir_ssa_def *v = nir_vector_insert_imm(&b, &intrin->dest.ssa, x_full, 0);
- nir_ssa_def_rewrite_uses_after(&intrin->dest.ssa, v, v->parent_instr);
- }
- }
-
- nir_metadata preserved =
- progress ? (nir_metadata_block_index | nir_metadata_dominance) : nir_metadata_all;
- nir_metadata_preserve(impl, preserved);
- return progress;
-}
-
static bool
is_sincos(const nir_instr *instr, const void *_)
{
NIR_PASS(_, nir, nir_lower_compute_system_values, &csv_options);
if (nir->info.stage == MESA_SHADER_MESH) {
- /* NV_mesh_shader: include first_task (aka. first_vertex) in workgroup ID. */
- NIR_PASS(_, nir, radv_lower_ms_workgroup_id);
-
/* Mesh shaders only have a 1D "vertex index" which we use
* as "workgroup index" to emulate the 3D workgroup ID.
*/
device->physical_device->rad_info.gfx_level, false);
return true;
} else if (nir->info.stage == MESA_SHADER_TASK) {
- ac_nir_apply_first_task_to_task_shader(nir);
ac_nir_lower_task_outputs_to_mem(nir, AC_TASK_PAYLOAD_ENTRY_BYTES,
device->physical_device->task_info.num_entries);
return true;
static uint8_t
count_ms_user_sgprs(const struct radv_shader_info *info)
{
- uint8_t count = 1 + 3; /* firstTask + num_work_groups[3] */
+ uint8_t count = 3; /* num_work_groups[3] */
if (info->vs.needs_draw_id)
count++;
static void
declare_ms_input_sgprs(const struct radv_shader_info *info, struct radv_shader_args *args)
{
- ac_add_arg(&args->ac, AC_ARG_SGPR, 1, AC_ARG_INT, &args->ac.base_vertex);
ac_add_arg(&args->ac, AC_ARG_SGPR, 3, AC_ARG_INT, &args->ac.num_work_groups);
if (info->vs.needs_draw_id) {
ac_add_arg(&args->ac, AC_ARG_SGPR, 1, AC_ARG_INT, &args->ac.draw_id);
set_ms_input_locs(struct radv_shader_args *args, uint8_t *user_sgpr_idx)
{
unsigned vs_num =
- args->ac.base_vertex.used + 3 * args->ac.num_work_groups.used + args->ac.draw_id.used;
+ 3 * args->ac.num_work_groups.used + args->ac.draw_id.used;
set_loc_shader(args, AC_UD_VS_BASE_VERTEX_START_INSTANCE, user_sgpr_idx, vs_num);
if (args->ac.task_ring_entry.used)
if (stage == MESA_SHADER_TASK) {
ac_add_arg(&args->ac, AC_ARG_SGPR, 1, AC_ARG_INT, &args->ac.task_ring_entry);
- ac_add_arg(&args->ac, AC_ARG_SGPR, 2, AC_ARG_INT, &args->task_ib_addr);
- ac_add_arg(&args->ac, AC_ARG_SGPR, 1, AC_ARG_INT, &args->task_ib_stride);
}
for (int i = 0; i < 3; i++) {
if (args->ac.task_ring_entry.used) {
set_loc_shader(args, AC_UD_TASK_RING_ENTRY, &user_sgpr_idx, 1);
}
- if (args->task_ib_addr.used) {
- assert(args->task_ib_stride.used);
- set_loc_shader(args, AC_UD_CS_TASK_IB, &user_sgpr_idx, 3);
- }
break;
case MESA_SHADER_VERTEX:
if (args->ac.view_index.used)