diff --git a/src/amd/common/ac_nir.h b/src/amd/common/ac_nir.h index 5e9f2abff27..03cffec8603 100644 --- a/src/amd/common/ac_nir.h +++ b/src/amd/common/ac_nir.h @@ -199,9 +199,6 @@ ac_nir_lower_ngg_ms(nir_shader *shader, unsigned wave_size, bool multiview); -void -ac_nir_apply_first_task_to_task_shader(nir_shader *shader); - void ac_nir_lower_task_outputs_to_mem(nir_shader *shader, unsigned task_payload_entry_bytes, diff --git a/src/amd/common/ac_nir_lower_taskmesh_io_to_mem.c b/src/amd/common/ac_nir_lower_taskmesh_io_to_mem.c index a0584abba23..038462362f8 100644 --- a/src/amd/common/ac_nir_lower_taskmesh_io_to_mem.c +++ b/src/amd/common/ac_nir_lower_taskmesh_io_to_mem.c @@ -40,109 +40,6 @@ typedef struct { unsigned num_entries; } lower_tsms_io_state; -typedef struct { - nir_ssa_def *hw_workgroup_id; - nir_ssa_def *api_workgroup_id; -} add_first_task_to_workgroup_id_state; - -static bool filter_workgroup_id(const nir_instr *instr, - UNUSED const void *state) -{ - if (instr->type != nir_instr_type_intrinsic) - return false; - - nir_intrinsic_instr *intrin = nir_instr_as_intrinsic(instr); - return intrin->intrinsic == nir_intrinsic_load_workgroup_id; -} - -static nir_ssa_def * -replace_workgroup_id_use_first_task(nir_builder *b, - nir_instr *instr, - void *state) -{ - add_first_task_to_workgroup_id_state *s = (add_first_task_to_workgroup_id_state *) state; - nir_intrinsic_instr *intrin = nir_instr_as_intrinsic(instr); - - assert(s->hw_workgroup_id); - - if (s->hw_workgroup_id == &intrin->dest.ssa) - return NULL; - - return s->api_workgroup_id; -} - -void -ac_nir_apply_first_task_to_task_shader(nir_shader *shader) -{ - /* The draw packets on RDNA2 GPUs don't support adding an offset to the task shader - * workgroups, so we have to emulate the firstTask feature for NV_mesh_shader. - * - * 1. Pass the address of the IB (indirect buffer) from the NV_mesh_shader draw call - * to the shader in an SGPR argument (2 SGPRs for address, 1 SGPR for stride). - * 2. Create a descriptor for the IB in the shader. - * 3. Load the firstTask value from the IB - * 4. Add the firstTask value the workgroup ID and use the result instead of the - * workgroup ID generated by the HW. - * - * NOTE: This pass must run _before_ lowering the task shader outputs to memory - * accesses. The lowering uses the workgroup ID and that must be unchanged - * because it has to be the real HW workgroup ID. - */ - - /* If the shader doesn't use workgroup ID, nothing to do here. */ - if (!BITSET_TEST(shader->info.system_values_read, SYSTEM_VALUE_WORKGROUP_ID)) - return; - - nir_function_impl *impl = nir_shader_get_entrypoint(shader); - assert(impl); - - nir_builder builder; - nir_builder *b = &builder; /* This is to avoid the & */ - nir_builder_init(b, impl); - b->cursor = nir_before_cf_list(&impl->body); - - /* This is the stride passed to vkCmdDrawMeshTasksIndirectNV */ - nir_ssa_def *ib_stride = nir_load_task_ib_stride(b); - nir_ssa_def *zero = nir_imm_int(b, 0); - nir_ssa_def *first_task = NULL; - - /* If the stride is zero, we assume that firstTask is also 0. */ - nir_if *if_stride = nir_push_if(b, nir_ine(b, ib_stride, zero)); - { - /* Address of the IB (indirect buffer) used by the current draw call. */ - nir_ssa_def *ib_addr = nir_load_task_ib_addr(b); - - /* Compose a 64-bit address from the IB address. */ - nir_ssa_def *addr = nir_pack_64_2x32_split(b, nir_channel(b, ib_addr, 0), nir_channel(b, ib_addr, 1)); - /* The IB needs to be addressed by draw ID * stride. */ - addr = nir_iadd(b, addr, nir_u2u64(b, nir_imul(b, nir_load_draw_id(b), ib_stride))); - /* Byte offset of the firstTask field in VkDrawMeshTasksIndirectCommandNV. */ - addr = nir_iadd_imm(b, addr, 4); - - first_task = nir_build_load_global(b, 1, 32, addr, .access = ACCESS_NON_WRITEABLE | ACCESS_COHERENT); - } - nir_pop_if(b, if_stride); - first_task = nir_if_phi(b, first_task, zero); - - /* NV_mesh_shader workgroups are 1 dimensional. - * Apply firstTask to the X dimension, but leave Y and Z intact. - */ - nir_ssa_def *hw_workgroup_id = nir_load_workgroup_id(b, 32); - nir_ssa_def *api_workgroup_id_x = nir_iadd(b, nir_channel(b, hw_workgroup_id, 0), first_task); - nir_ssa_def *api_workgroup_id = nir_vector_insert_imm(b, hw_workgroup_id, api_workgroup_id_x, 0); - - add_first_task_to_workgroup_id_state state = { - .hw_workgroup_id = hw_workgroup_id, - .api_workgroup_id = api_workgroup_id, - }; - nir_shader_lower_instructions(shader, - filter_workgroup_id, - replace_workgroup_id_use_first_task, - &state); - - nir_validate_shader(shader, "after including firstTask in the task shader workgroup ID"); -} - static nir_ssa_def * task_workgroup_index(nir_builder *b, lower_tsms_io_state *s)