diff --git a/src/amd/compiler/aco_instruction_selection.cpp b/src/amd/compiler/aco_instruction_selection.cpp index 25e3b565256..ab7b1891cd2 100644 --- a/src/amd/compiler/aco_instruction_selection.cpp +++ b/src/amd/compiler/aco_instruction_selection.cpp @@ -11272,6 +11272,31 @@ merged_wave_info_to_mask(isel_context* ctx, unsigned i) return lanecount_to_mask(ctx, count); } +static void +insert_rt_jump_next(isel_context& ctx, const struct ac_shader_args* args) +{ + append_logical_end(ctx.block); + ctx.block->kind |= block_kind_uniform; + + unsigned src_count = ctx.args->arg_count; + Pseudo_instruction* ret = + create_instruction(aco_opcode::p_return, Format::PSEUDO, src_count, 0); + ctx.block->instructions.emplace_back(ret); + + for (unsigned i = 0; i < src_count; i++) { + enum ac_arg_regfile file = ctx.args->args[i].file; + unsigned size = ctx.args->args[i].size; + unsigned reg = ctx.args->args[i].offset + (file == AC_ARG_SGPR ? 0 : 256); + RegClass type = RegClass(file == AC_ARG_SGPR ? RegType::sgpr : RegType::vgpr, size); + Operand op = ctx.arg_temps[i].id() ? Operand(ctx.arg_temps[i], PhysReg{reg}) + : Operand(PhysReg{reg}, type); + ret->operands[i] = op; + } + + Builder bld(ctx.program, ctx.block); + bld.sop1(aco_opcode::s_setpc_b64, get_arg(&ctx, ctx.args->rt.uniform_shader_addr)); +} + void select_program_rt(isel_context& ctx, unsigned shader_count, struct nir_shader* const* shaders, const struct ac_shader_args* args) @@ -11291,24 +11316,11 @@ select_program_rt(isel_context& ctx, unsigned shader_count, struct nir_shader* c split_arguments(&ctx, startpgm); visit_cf_list(&ctx, &nir_shader_get_entrypoint(nir)->body); - /* Fix output registers and jump to next shader */ - append_logical_end(ctx.block); - ctx.block->kind |= block_kind_uniform; - Builder bld(ctx.program, ctx.block); - unsigned src_count = ctx.args->arg_count; - Pseudo_instruction* ret = - create_instruction(aco_opcode::p_return, Format::PSEUDO, src_count, 0); - ctx.block->instructions.emplace_back(ret); - for (unsigned j = 0; j < src_count; j++) { - enum ac_arg_regfile file = ctx.args->args[j].file; - unsigned size = ctx.args->args[j].size; - unsigned reg = ctx.args->args[j].offset + (file == AC_ARG_SGPR ? 0 : 256); - RegClass type = RegClass(file == AC_ARG_SGPR ? RegType::sgpr : RegType::vgpr, size); - Operand op = ctx.arg_temps[j].id() ? Operand(ctx.arg_temps[j], PhysReg{reg}) - : Operand(PhysReg{reg}, type); - ret->operands[j] = op; - } - bld.sop1(aco_opcode::s_setpc_b64, get_arg(&ctx, ctx.args->rt.uniform_shader_addr)); + /* Fix output registers and jump to next shader. We can skip this when dealing with a raygen + * shader without shader calls. + */ + if (shader_count > 1 || shaders[i]->info.stage != MESA_SHADER_RAYGEN) + insert_rt_jump_next(ctx, args); cleanup_context(&ctx); }