diff --git a/src/amd/compiler/aco_instruction_selection.cpp b/src/amd/compiler/aco_instruction_selection.cpp index e12bfc2d735..eb790a5dc77 100644 --- a/src/amd/compiler/aco_instruction_selection.cpp +++ b/src/amd/compiler/aco_instruction_selection.cpp @@ -12114,55 +12114,6 @@ store_tess_factor_to_tess_ring(isel_context* ctx, Temp tess_ring_desc, Temp fact memory_sync_info(storage_vmem_output), true, false, false); } -Temp -build_fast_udiv_nuw(isel_context* ctx, Temp num, Temp multiplier, Temp pre_shift, Temp post_shift, - Temp increment) -{ - Builder bld(ctx->program, ctx->block); - - num = bld.vop2(aco_opcode::v_lshrrev_b32, bld.def(v1), pre_shift, num); - num = bld.nuw().vadd32(bld.def(v1), num, increment); - num = bld.vop3(aco_opcode::v_mul_hi_u32, bld.def(v1), num, multiplier); - return bld.vop2(aco_opcode::v_lshrrev_b32, bld.def(v1), post_shift, num); -} - -Temp -get_gl_vs_prolog_vertex_index(isel_context* ctx, const struct aco_gl_vs_prolog_info* vinfo, - unsigned input_index, Temp instance_divisor_constbuf) -{ - bool divisor_is_one = vinfo->instance_divisor_is_one & (1u << input_index); - bool divisor_is_fetched = vinfo->instance_divisor_is_fetched & (1u << input_index); - - Builder bld(ctx->program, ctx->block); - - Temp index; - if (divisor_is_one) { - index = get_arg(ctx, ctx->args->instance_id); - } else if (divisor_is_fetched) { - Temp instance_id = get_arg(ctx, ctx->args->instance_id); - - Temp udiv_factors = bld.smem(aco_opcode::s_buffer_load_dwordx4, bld.def(s4), - instance_divisor_constbuf, Operand::c32(input_index * 16)); - emit_split_vector(ctx, udiv_factors, 4); - - index = build_fast_udiv_nuw(ctx, instance_id, emit_extract_vector(ctx, udiv_factors, 0, s1), - emit_extract_vector(ctx, udiv_factors, 1, s1), - emit_extract_vector(ctx, udiv_factors, 2, s1), - emit_extract_vector(ctx, udiv_factors, 3, s1)); - } - - if (divisor_is_one || divisor_is_fetched) { - Temp start_instance = get_arg(ctx, ctx->args->start_instance); - index = bld.vadd32(bld.def(v1), index, start_instance); - } else { - Temp base_vertex = get_arg(ctx, ctx->args->base_vertex); - Temp vertex_id = get_arg(ctx, ctx->args->vertex_id); - index = bld.vadd32(bld.def(v1), base_vertex, vertex_id); - } - - return index; -} - void emit_polygon_stipple(isel_context* ctx, const struct aco_ps_prolog_info* finfo) { @@ -13348,56 +13299,6 @@ select_tcs_epilog(Program* program, void* pinfo, ac_shader_config* config, finish_program(&ctx); } -void -select_gl_vs_prolog(Program* program, void* pinfo, ac_shader_config* config, - const struct aco_compiler_options* options, const struct aco_shader_info* info, - const struct ac_shader_args* args) -{ - const struct aco_gl_vs_prolog_info* vinfo = (const struct aco_gl_vs_prolog_info*)pinfo; - isel_context ctx = - setup_isel_context(program, 0, NULL, config, options, info, args, SWStage::VS); - - ctx.block->fp_mode = program->next_fp_mode; - - add_startpgm(&ctx); - append_logical_start(ctx.block); - - Builder bld(ctx.program, ctx.block); - - bld.sopp(aco_opcode::s_setprio, -1u, 0x3u); - - if (vinfo->as_ls && options->has_ls_vgpr_init_bug) - fix_ls_vgpr_init_bug(&ctx); - - std::vector regs; - passthrough_all_args(&ctx, regs); - - Temp instance_divisor_constbuf; - - if (vinfo->instance_divisor_is_fetched) { - Temp list = get_arg(&ctx, vinfo->internal_bindings); - list = convert_pointer_to_64_bit(&ctx, list); - - instance_divisor_constbuf = bld.smem(aco_opcode::s_load_dwordx4, bld.def(s4), list, - Operand::c32(vinfo->instance_diviser_buf_offset)); - } - - unsigned vgpr = 256 + ctx.args->num_vgprs_used; - - for (unsigned i = 0; i < vinfo->num_inputs; i++) { - Temp index = get_gl_vs_prolog_vertex_index(&ctx, vinfo, i, instance_divisor_constbuf); - regs.emplace_back(Operand(index, PhysReg{vgpr + i})); - } - - program->config->float_mode = program->blocks[0].fp_mode.val; - - append_logical_end(ctx.block); - - build_end_with_regs(&ctx, regs); - - finish_program(&ctx); -} - void select_ps_prolog(Program* program, void* pinfo, ac_shader_config* config, const struct aco_compiler_options* options, const struct aco_shader_info* info, diff --git a/src/amd/compiler/aco_interface.cpp b/src/amd/compiler/aco_interface.cpp index f6bc400b444..c42bcb8724a 100644 --- a/src/amd/compiler/aco_interface.cpp +++ b/src/amd/compiler/aco_interface.cpp @@ -417,17 +417,6 @@ aco_compile_tcs_epilog(const struct aco_compiler_options* options, binary); } -void -aco_compile_gl_vs_prolog(const struct aco_compiler_options* options, - const struct aco_shader_info* info, - const struct aco_gl_vs_prolog_info* pinfo, - const struct ac_shader_args* args, aco_shader_part_callback* build_prolog, - void** binary) -{ - aco_compile_shader_part(options, info, args, aco::select_gl_vs_prolog, (void*)pinfo, - build_prolog, binary, true); -} - void aco_compile_ps_prolog(const struct aco_compiler_options* options, const struct aco_shader_info* info, const struct aco_ps_prolog_info* pinfo, diff --git a/src/amd/compiler/aco_interface.h b/src/amd/compiler/aco_interface.h index 15e5398416b..1275091cb18 100644 --- a/src/amd/compiler/aco_interface.h +++ b/src/amd/compiler/aco_interface.h @@ -88,12 +88,6 @@ void aco_compile_tcs_epilog(const struct aco_compiler_options* options, const struct ac_shader_args* args, aco_shader_part_callback* build_epilog, void** binary); -void aco_compile_gl_vs_prolog(const struct aco_compiler_options* options, - const struct aco_shader_info* info, - const struct aco_gl_vs_prolog_info* pinfo, - const struct ac_shader_args* args, - aco_shader_part_callback* build_prolog, void** binary); - void aco_compile_ps_prolog(const struct aco_compiler_options* options, const struct aco_shader_info* info, const struct aco_ps_prolog_info* pinfo, diff --git a/src/amd/compiler/aco_ir.h b/src/amd/compiler/aco_ir.h index 3863cf11b72..bd9bb19a5ac 100644 --- a/src/amd/compiler/aco_ir.h +++ b/src/amd/compiler/aco_ir.h @@ -2203,10 +2203,6 @@ void select_tcs_epilog(Program* program, void* pinfo, ac_shader_config* config, const struct aco_compiler_options* options, const struct aco_shader_info* info, const struct ac_shader_args* args); -void select_gl_vs_prolog(Program* program, void* pinfo, ac_shader_config* config, - const struct aco_compiler_options* options, - const struct aco_shader_info* info, const struct ac_shader_args* args); - void select_ps_prolog(Program* program, void* pinfo, ac_shader_config* config, const struct aco_compiler_options* options, const struct aco_shader_info* info, const struct ac_shader_args* args); diff --git a/src/amd/compiler/aco_shader_info.h b/src/amd/compiler/aco_shader_info.h index bfe8071dee2..3da781a2837 100644 --- a/src/amd/compiler/aco_shader_info.h +++ b/src/amd/compiler/aco_shader_info.h @@ -105,16 +105,6 @@ struct aco_tcs_epilog_info { struct ac_arg tcs_offchip_layout; }; -struct aco_gl_vs_prolog_info { - uint16_t instance_divisor_is_one; - uint16_t instance_divisor_is_fetched; - unsigned instance_diviser_buf_offset; - unsigned num_inputs; - bool as_ls; - - struct ac_arg internal_bindings; -}; - struct aco_ps_prolog_info { bool poly_stipple; unsigned poly_stipple_buf_offset; diff --git a/src/gallium/drivers/radeonsi/gfx10_shader_ngg.c b/src/gallium/drivers/radeonsi/gfx10_shader_ngg.c index 255f6c8f379..35c173f6039 100644 --- a/src/gallium/drivers/radeonsi/gfx10_shader_ngg.c +++ b/src/gallium/drivers/radeonsi/gfx10_shader_ngg.c @@ -140,8 +140,8 @@ retry_select_mode: bool uses_primitive_id = gs_sel->info.uses_primid; if (gs_stage == MESA_SHADER_VERTEX) { uses_instance_id |= - shader->key.ge.part.vs.prolog.instance_divisor_is_one || - shader->key.ge.part.vs.prolog.instance_divisor_is_fetched; + shader->key.ge.mono.instance_divisor_is_one || + shader->key.ge.mono.instance_divisor_is_fetched; } else { uses_primitive_id |= shader->key.ge.mono.u.vs_export_prim_id; } diff --git a/src/gallium/drivers/radeonsi/meson.build b/src/gallium/drivers/radeonsi/meson.build index 3c3903044f4..ed76ef822b1 100644 --- a/src/gallium/drivers/radeonsi/meson.build +++ b/src/gallium/drivers/radeonsi/meson.build @@ -136,7 +136,6 @@ if with_llvm 'si_shader_llvm_gs.c', 'si_shader_llvm_ps.c', 'si_shader_llvm_tess.c', - 'si_shader_llvm_vs.c', ) radeonsi_include_dirs += [inc_amd_common_llvm] diff --git a/src/gallium/drivers/radeonsi/si_nir_lower_vs_inputs.c b/src/gallium/drivers/radeonsi/si_nir_lower_vs_inputs.c index 723dade2002..fb737ddb281 100644 --- a/src/gallium/drivers/radeonsi/si_nir_lower_vs_inputs.c +++ b/src/gallium/drivers/radeonsi/si_nir_lower_vs_inputs.c @@ -37,15 +37,14 @@ fast_udiv_nuw(nir_builder *b, nir_def *num, nir_def *divisor) } static nir_def * -get_vertex_index_for_mono_shader(nir_builder *b, int input_index, - struct lower_vs_inputs_state *s) +get_vertex_index(nir_builder *b, int input_index, struct lower_vs_inputs_state *s) { const union si_shader_key *key = &s->shader->key; bool divisor_is_one = - key->ge.part.vs.prolog.instance_divisor_is_one & (1u << input_index); + key->ge.mono.instance_divisor_is_one & (1u << input_index); bool divisor_is_fetched = - key->ge.part.vs.prolog.instance_divisor_is_fetched & (1u << input_index); + key->ge.mono.instance_divisor_is_fetched & (1u << input_index); if (divisor_is_one || divisor_is_fetched) { nir_def *instance_id = nir_load_instance_id(b); @@ -77,13 +76,6 @@ get_vertex_index_for_mono_shader(nir_builder *b, int input_index, } } -static nir_def * -get_vertex_index_for_part_shader(nir_builder *b, int input_index, - struct lower_vs_inputs_state *s) -{ - return ac_nir_load_arg_at_offset(b, &s->args->ac, s->args->vertex_index0, input_index); -} - static void get_vertex_index_for_all_inputs(nir_shader *nir, struct lower_vs_inputs_state *s) { @@ -95,16 +87,13 @@ get_vertex_index_for_all_inputs(nir_shader *nir, struct lower_vs_inputs_state *s const struct si_shader_selector *sel = s->shader->selector; const union si_shader_key *key = &s->shader->key; - if (key->ge.part.vs.prolog.instance_divisor_is_fetched) { + if (key->ge.mono.instance_divisor_is_fetched) { s->instance_divisor_constbuf = si_nir_load_internal_binding(b, s->args, SI_VS_CONST_INSTANCE_DIVISORS, 4); } - for (int i = 0; i < sel->info.num_inputs; i++) { - s->vertex_index[i] = s->shader->is_monolithic ? - get_vertex_index_for_mono_shader(b, i, s) : - get_vertex_index_for_part_shader(b, i, s); - } + for (int i = 0; i < sel->info.num_inputs; i++) + s->vertex_index[i] = get_vertex_index(b, i, s); } static void diff --git a/src/gallium/drivers/radeonsi/si_pipe.c b/src/gallium/drivers/radeonsi/si_pipe.c index 5ddc3266527..3433385cf54 100644 --- a/src/gallium/drivers/radeonsi/si_pipe.c +++ b/src/gallium/drivers/radeonsi/si_pipe.c @@ -787,16 +787,11 @@ static struct pipe_context *si_create_context(struct pipe_screen *screen, unsign if (sctx->gfx_level >= GFX9) { /* The LS output / HS input layout can be communicated * directly instead of via user SGPRs for merged LS-HS. - * This also enables jumping over the VS prolog for HS-only waves. - * - * When the LS VGPR fix is needed, monolithic shaders can: - * - avoid initializing EXEC in both the LS prolog - * and the LS main part when !vs_needs_prolog - * - remove the fixup for unused input VGPRs + * This also enables jumping over the VS for HS-only waves. */ sctx->shader.tcs.key.ge.opt.prefer_mono = 1; - /* This enables jumping over the VS prolog for GS-only waves. */ + /* This enables jumping over the VS for GS-only waves. */ sctx->shader.gs.key.ge.opt.prefer_mono = 1; } @@ -962,8 +957,8 @@ static struct pipe_context *si_pipe_create_context(struct pipe_screen *screen, v static void si_destroy_screen(struct pipe_screen *pscreen) { struct si_screen *sscreen = (struct si_screen *)pscreen; - struct si_shader_part *parts[] = {sscreen->vs_prologs, sscreen->tcs_epilogs, - sscreen->ps_prologs, sscreen->ps_epilogs}; + struct si_shader_part *parts[] = {sscreen->tcs_epilogs, sscreen->ps_prologs, + sscreen->ps_epilogs}; unsigned i; if (!sscreen->ws->unref(sscreen->ws)) diff --git a/src/gallium/drivers/radeonsi/si_pipe.h b/src/gallium/drivers/radeonsi/si_pipe.h index 361e3a88bfc..8a94fe97a81 100644 --- a/src/gallium/drivers/radeonsi/si_pipe.h +++ b/src/gallium/drivers/radeonsi/si_pipe.h @@ -670,7 +670,6 @@ struct si_screen { } barrier_flags; simple_mtx_t shader_parts_mutex; - struct si_shader_part *vs_prologs; struct si_shader_part *tcs_epilogs; struct si_shader_part *ps_prologs; struct si_shader_part *ps_epilogs; diff --git a/src/gallium/drivers/radeonsi/si_shader.c b/src/gallium/drivers/radeonsi/si_shader.c index 869c6439797..7f1191f2567 100644 --- a/src/gallium/drivers/radeonsi/si_shader.c +++ b/src/gallium/drivers/radeonsi/si_shader.c @@ -251,8 +251,7 @@ static void declare_vb_descriptor_input_sgprs(struct si_shader_args *args, } } -static void declare_vs_input_vgprs(struct si_shader_args *args, struct si_shader *shader, - unsigned *num_prolog_vgprs) +static void declare_vs_input_vgprs(struct si_shader_args *args, struct si_shader *shader) { ac_add_arg(&args->ac, AC_ARG_VGPR, 1, AC_ARG_INT, &args->ac.vertex_id); if (shader->key.ge.as_ls) { @@ -280,16 +279,6 @@ static void declare_vs_input_vgprs(struct si_shader_args *args, struct si_shader ac_add_arg(&args->ac, AC_ARG_VGPR, 1, AC_ARG_INT, &args->ac.vs_prim_id); ac_add_arg(&args->ac, AC_ARG_VGPR, 1, AC_ARG_INT, NULL); /* unused */ } - - if (!shader->is_gs_copy_shader) { - /* Vertex load indices. */ - if (shader->selector->info.num_inputs) { - ac_add_arg(&args->ac, AC_ARG_VGPR, 1, AC_ARG_INT, &args->vertex_index0); - for (unsigned i = 1; i < shader->selector->info.num_inputs; i++) - ac_add_arg(&args->ac, AC_ARG_VGPR, 1, AC_ARG_INT, NULL); - } - *num_prolog_vgprs += shader->selector->info.num_inputs; - } } static void declare_vs_blit_inputs(struct si_shader *shader, struct si_shader_args *args) @@ -394,7 +383,7 @@ void si_init_shader_args(struct si_shader *shader, struct si_shader_args *args) ac_add_arg(&args->ac, AC_ARG_SGPR, 1, AC_ARG_INT, &args->ac.scratch_offset); /* VGPRs */ - declare_vs_input_vgprs(args, shader, &num_prolog_vgprs); + declare_vs_input_vgprs(args, shader); break; @@ -459,7 +448,7 @@ void si_init_shader_args(struct si_shader *shader, struct si_shader_args *args) ac_add_arg(&args->ac, AC_ARG_VGPR, 1, AC_ARG_INT, &args->ac.tcs_rel_ids); if (stage == MESA_SHADER_VERTEX) { - declare_vs_input_vgprs(args, shader, &num_prolog_vgprs); + declare_vs_input_vgprs(args, shader); /* Need to keep LS/HS arg index same for shared args when ACO, * so this is not able to be before shared VGPRs. @@ -567,7 +556,7 @@ void si_init_shader_args(struct si_shader *shader, struct si_shader_args *args) ac_add_arg(&args->ac, AC_ARG_VGPR, 1, AC_ARG_INT, &args->ac.gs_vtx_offset[2]); if (stage == MESA_SHADER_VERTEX) { - declare_vs_input_vgprs(args, shader, &num_prolog_vgprs); + declare_vs_input_vgprs(args, shader); /* Need to keep ES/GS arg index same for shared args when ACO, * so this is not able to be before shared VGPRs. @@ -1443,15 +1432,11 @@ void si_shader_dump(struct si_screen *sscreen, struct si_shader *shader, } } -static void si_dump_shader_key_vs(const union si_shader_key *key, - const struct si_vs_prolog_bits *prolog, const char *prefix, - FILE *f) +static void si_dump_shader_key_vs(const union si_shader_key *key, FILE *f) { - fprintf(f, " %s.instance_divisor_is_one = %u\n", prefix, prolog->instance_divisor_is_one); - fprintf(f, " %s.instance_divisor_is_fetched = %u\n", prefix, - prolog->instance_divisor_is_fetched); - fprintf(f, " %s.ls_vgpr_fix = %u\n", prefix, prolog->ls_vgpr_fix); - + fprintf(f, " mono.instance_divisor_is_one = %u\n", key->ge.mono.instance_divisor_is_one); + fprintf(f, " mono.instance_divisor_is_fetched = %u\n", + key->ge.mono.instance_divisor_is_fetched); fprintf(f, " mono.vs.fetch_opencode = %x\n", key->ge.mono.vs_fetch_opencode); fprintf(f, " mono.vs.fix_fetch = {"); for (int i = 0; i < SI_MAX_ATTRIBS; i++) { @@ -1479,7 +1464,7 @@ static void si_dump_shader_key(const struct si_shader *shader, FILE *f) switch (stage) { case MESA_SHADER_VERTEX: - si_dump_shader_key_vs(key, &key->ge.part.vs.prolog, "part.vs.prolog", f); + si_dump_shader_key_vs(key, f); fprintf(f, " as_es = %u\n", key->ge.as_es); fprintf(f, " as_ls = %u\n", key->ge.as_ls); fprintf(f, " as_ngg = %u\n", key->ge.as_ngg); @@ -1487,9 +1472,9 @@ static void si_dump_shader_key(const struct si_shader *shader, FILE *f) break; case MESA_SHADER_TESS_CTRL: - if (shader->selector->screen->info.gfx_level >= GFX9) { - si_dump_shader_key_vs(key, &key->ge.part.tcs.ls_prolog, "part.tcs.ls_prolog", f); - } + if (shader->selector->screen->info.gfx_level >= GFX9) + si_dump_shader_key_vs(key, f); + fprintf(f, " part.tcs.epilog.prim_mode = %u\n", key->ge.part.tcs.epilog.prim_mode); fprintf(f, " opt.prefer_mono = %u\n", key->ge.opt.prefer_mono); fprintf(f, " opt.same_patch_vertices = %u\n", key->ge.opt.same_patch_vertices); @@ -1506,9 +1491,9 @@ static void si_dump_shader_key(const struct si_shader *shader, FILE *f) break; if (shader->selector->screen->info.gfx_level >= GFX9 && - key->ge.part.gs.es->stage == MESA_SHADER_VERTEX) { - si_dump_shader_key_vs(key, &key->ge.part.gs.vs_prolog, "part.gs.vs_prolog", f); - } + key->ge.part.gs.es->stage == MESA_SHADER_VERTEX) + si_dump_shader_key_vs(key, f); + fprintf(f, " mono.u.gs_tri_strip_adj_fix = %u\n", key->ge.mono.u.gs_tri_strip_adj_fix); fprintf(f, " as_ngg = %u\n", key->ge.as_ngg); break; @@ -1600,62 +1585,6 @@ static void si_dump_shader_key(const struct si_shader *shader, FILE *f) } } -bool si_vs_needs_prolog(const struct si_shader_selector *sel, - const struct si_vs_prolog_bits *prolog_key) -{ - assert(sel->stage == MESA_SHADER_VERTEX); - - /* VGPR initialization fixup for Vega10 and Raven is always done in the - * VS prolog. */ - return sel->info.vs_needs_prolog || prolog_key->ls_vgpr_fix; -} - -/** - * Compute the VS prolog key, which contains all the information needed to - * build the VS prolog function, and set shader->info bits where needed. - * - * \param info Shader info of the vertex shader. - * \param num_input_sgprs Number of input SGPRs for the vertex shader. - * \param prolog_key Key of the VS prolog - * \param shader_out The vertex shader, or the next shader if merging LS+HS or ES+GS. - * \param key Output shader part key. - */ -void si_get_vs_prolog_key(const struct si_shader_info *info, unsigned num_input_sgprs, - const struct si_vs_prolog_bits *prolog_key, - struct si_shader *shader_out, union si_shader_part_key *key) -{ - memset(key, 0, sizeof(*key)); - key->vs_prolog.states = *prolog_key; - key->vs_prolog.wave32 = shader_out->wave_size == 32; - key->vs_prolog.num_input_sgprs = num_input_sgprs; - key->vs_prolog.num_inputs = info->num_inputs; - key->vs_prolog.as_ls = shader_out->key.ge.as_ls; - key->vs_prolog.as_es = shader_out->key.ge.as_es; - key->vs_prolog.as_ngg = shader_out->key.ge.as_ngg; - - if (shader_out->selector->stage == MESA_SHADER_TESS_CTRL) { - key->vs_prolog.as_ls = 1; - key->vs_prolog.num_merged_next_stage_vgprs = 2; - } else if (shader_out->selector->stage == MESA_SHADER_GEOMETRY) { - key->vs_prolog.as_es = 1; - key->vs_prolog.num_merged_next_stage_vgprs = 5; - } else if (shader_out->key.ge.as_ngg) { - key->vs_prolog.num_merged_next_stage_vgprs = 5; - } - - /* Only one of these combinations can be set. as_ngg can be set with as_es. */ - assert(key->vs_prolog.as_ls + key->vs_prolog.as_ngg + - (key->vs_prolog.as_es && !key->vs_prolog.as_ngg) <= 1); - - /* Enable loading the InstanceID VGPR. */ - uint16_t input_mask = u_bit_consecutive(0, info->num_inputs); - - if ((key->vs_prolog.states.instance_divisor_is_one | - key->vs_prolog.states.instance_divisor_is_fetched) & - input_mask) - shader_out->info.uses_instanceid = true; -} - /* TODO: convert to nir_shader_instructions_pass */ static bool si_nir_kill_outputs(nir_shader *nir, const union si_shader_key *key) { @@ -1951,9 +1880,8 @@ static void si_lower_ngg(struct si_shader *shader, nir_shader *nir) unsigned instance_rate_inputs = 0; if (nir->info.stage == MESA_SHADER_VERTEX) { - instance_rate_inputs = - key->ge.part.vs.prolog.instance_divisor_is_one | - key->ge.part.vs.prolog.instance_divisor_is_fetched; + instance_rate_inputs = key->ge.mono.instance_divisor_is_one | + key->ge.mono.instance_divisor_is_fetched; /* Manually mark the instance ID used, so the shader can repack it. */ if (instance_rate_inputs) @@ -3125,35 +3053,6 @@ si_get_shader_part(struct si_screen *sscreen, struct si_shader_part **list, return result; } -static bool si_get_vs_prolog(struct si_screen *sscreen, struct ac_llvm_compiler *compiler, - struct si_shader *shader, struct util_debug_callback *debug, - struct si_shader *main_part, const struct si_vs_prolog_bits *key) -{ - struct si_shader_selector *vs = main_part->selector; - - if (!si_vs_needs_prolog(vs, key)) - return true; - - /* Get the prolog. */ - union si_shader_part_key prolog_key; - si_get_vs_prolog_key(&vs->info, main_part->info.num_input_sgprs, key, shader, - &prolog_key); - - shader->prolog = - si_get_shader_part(sscreen, &sscreen->vs_prologs, MESA_SHADER_VERTEX, true, &prolog_key, - compiler, debug, "Vertex Shader Prolog"); - return shader->prolog != NULL; -} - -/** - * Select and compile (or reuse) vertex shader parts (prolog & epilog). - */ -static bool si_shader_select_vs_parts(struct si_screen *sscreen, struct ac_llvm_compiler *compiler, - struct si_shader *shader, struct util_debug_callback *debug) -{ - return si_get_vs_prolog(sscreen, compiler, shader, debug, shader, &shader->key.ge.part.vs.prolog); -} - void si_get_tcs_epilog_key(struct si_shader *shader, union si_shader_part_key *key) { memset(key, 0, sizeof(*key)); @@ -3171,15 +3070,8 @@ void si_get_tcs_epilog_key(struct si_shader *shader, union si_shader_part_key *k static bool si_shader_select_tcs_parts(struct si_screen *sscreen, struct ac_llvm_compiler *compiler, struct si_shader *shader, struct util_debug_callback *debug) { - if (sscreen->info.gfx_level >= GFX9) { - struct si_shader *ls_main_part = shader->key.ge.part.tcs.ls->main_shader_part_ls; - - if (!si_get_vs_prolog(sscreen, compiler, shader, debug, ls_main_part, - &shader->key.ge.part.tcs.ls_prolog)) - return false; - - shader->previous_stage = ls_main_part; - } + if (sscreen->info.gfx_level >= GFX9) + shader->previous_stage = shader->key.ge.part.tcs.ls->main_shader_part_ls; /* Get the epilog. */ union si_shader_part_key epilog_key; @@ -3198,19 +3090,10 @@ static bool si_shader_select_gs_parts(struct si_screen *sscreen, struct ac_llvm_ struct si_shader *shader, struct util_debug_callback *debug) { if (sscreen->info.gfx_level >= GFX9) { - struct si_shader *es_main_part; - if (shader->key.ge.as_ngg) - es_main_part = shader->key.ge.part.gs.es->main_shader_part_ngg_es; + shader->previous_stage = shader->key.ge.part.gs.es->main_shader_part_ngg_es; else - es_main_part = shader->key.ge.part.gs.es->main_shader_part_es; - - if (shader->key.ge.part.gs.es->stage == MESA_SHADER_VERTEX && - !si_get_vs_prolog(sscreen, compiler, shader, debug, es_main_part, - &shader->key.ge.part.gs.vs_prolog)) - return false; - - shader->previous_stage = es_main_part; + shader->previous_stage = shader->key.ge.part.gs.es->main_shader_part_es; } return true; @@ -3479,16 +3362,10 @@ bool si_create_shader_variant(struct si_screen *sscreen, struct ac_llvm_compiler /* Select prologs and/or epilogs. */ switch (sel->stage) { - case MESA_SHADER_VERTEX: - if (!si_shader_select_vs_parts(sscreen, compiler, shader, debug)) - return false; - break; case MESA_SHADER_TESS_CTRL: if (!si_shader_select_tcs_parts(sscreen, compiler, shader, debug)) return false; break; - case MESA_SHADER_TESS_EVAL: - break; case MESA_SHADER_GEOMETRY: if (!si_shader_select_gs_parts(sscreen, compiler, shader, debug)) return false; @@ -3593,18 +3470,18 @@ bool si_create_shader_variant(struct si_screen *sscreen, struct ac_llvm_compiler if (sel->stage == MESA_SHADER_VERTEX) { shader->uses_base_instance = sel->info.uses_base_instance || - shader->key.ge.part.vs.prolog.instance_divisor_is_one || - shader->key.ge.part.vs.prolog.instance_divisor_is_fetched; + shader->key.ge.mono.instance_divisor_is_one || + shader->key.ge.mono.instance_divisor_is_fetched; } else if (sel->stage == MESA_SHADER_TESS_CTRL) { shader->uses_base_instance = shader->previous_stage_sel && (shader->previous_stage_sel->info.uses_base_instance || - shader->key.ge.part.tcs.ls_prolog.instance_divisor_is_one || - shader->key.ge.part.tcs.ls_prolog.instance_divisor_is_fetched); + shader->key.ge.mono.instance_divisor_is_one || + shader->key.ge.mono.instance_divisor_is_fetched); } else if (sel->stage == MESA_SHADER_GEOMETRY) { shader->uses_base_instance = shader->previous_stage_sel && (shader->previous_stage_sel->info.uses_base_instance || - shader->key.ge.part.gs.vs_prolog.instance_divisor_is_one || - shader->key.ge.part.gs.vs_prolog.instance_divisor_is_fetched); + shader->key.ge.mono.instance_divisor_is_one || + shader->key.ge.mono.instance_divisor_is_fetched); } si_fix_resource_usage(sscreen, shader); @@ -3659,13 +3536,11 @@ nir_shader *si_get_prev_stage_nir_shader(struct si_shader *shader, struct si_shader_selector *ls = key->ge.part.tcs.ls; prev_shader->selector = ls; - prev_shader->key.ge.part.vs.prolog = key->ge.part.tcs.ls_prolog; prev_shader->key.ge.as_ls = 1; } else { struct si_shader_selector *es = key->ge.part.gs.es; prev_shader->selector = es; - prev_shader->key.ge.part.vs.prolog = key->ge.part.gs.vs_prolog; prev_shader->key.ge.as_es = 1; prev_shader->key.ge.as_ngg = key->ge.as_ngg; } @@ -3754,50 +3629,6 @@ void si_get_tcs_epilog_args(enum amd_gfx_level gfx_level, ac_add_arg(&args->ac, AC_ARG_VGPR, 1, AC_ARG_INT, &tess_factors[i]); } -void si_get_vs_prolog_args(enum amd_gfx_level gfx_level, - struct si_shader_args *args, - const union si_shader_part_key *key) -{ - memset(args, 0, sizeof(*args)); - - unsigned num_input_sgprs = key->vs_prolog.num_input_sgprs; - unsigned num_input_vgprs = key->vs_prolog.num_merged_next_stage_vgprs + 4; - - struct ac_arg input_sgprs[num_input_sgprs]; - for (unsigned i = 0; i < num_input_sgprs; i++) - ac_add_arg(&args->ac, AC_ARG_SGPR, 1, AC_ARG_INT, input_sgprs + i); - - struct ac_arg input_vgprs[num_input_vgprs]; - for (unsigned i = 0; i < num_input_vgprs; i++) - ac_add_arg(&args->ac, AC_ARG_VGPR, 1, AC_ARG_INT, input_vgprs + i); - - if (key->vs_prolog.num_merged_next_stage_vgprs) - args->ac.merged_wave_info = input_sgprs[3]; - - unsigned first_vs_vgpr = key->vs_prolog.num_merged_next_stage_vgprs; - unsigned vertex_id_vgpr = first_vs_vgpr; - unsigned instance_id_vgpr = gfx_level >= GFX10 ? - first_vs_vgpr + 3 : first_vs_vgpr + (key->vs_prolog.as_ls ? 2 : 1); - - args->ac.vertex_id = input_vgprs[vertex_id_vgpr]; - args->ac.instance_id = input_vgprs[instance_id_vgpr]; - - if (key->vs_prolog.as_ls) { - if (gfx_level < GFX11) - args->ac.vs_rel_patch_id = input_vgprs[first_vs_vgpr + 1]; - - if (gfx_level >= GFX9) { - args->ac.tcs_patch_id = input_vgprs[0]; - args->ac.tcs_rel_ids = input_vgprs[1]; - } - } - - unsigned user_sgpr_base = key->vs_prolog.num_merged_next_stage_vgprs ? 8 : 0; - args->internal_bindings = input_sgprs[user_sgpr_base + SI_SGPR_INTERNAL_BINDINGS]; - args->ac.start_instance = input_sgprs[user_sgpr_base + SI_SGPR_START_INSTANCE]; - args->ac.base_vertex = input_sgprs[user_sgpr_base + SI_SGPR_BASE_VERTEX]; -} - void si_get_ps_prolog_args(struct si_shader_args *args, const union si_shader_part_key *key) { diff --git a/src/gallium/drivers/radeonsi/si_shader.h b/src/gallium/drivers/radeonsi/si_shader.h index df64fc01d44..97b753e5f1b 100644 --- a/src/gallium/drivers/radeonsi/si_shader.h +++ b/src/gallium/drivers/radeonsi/si_shader.h @@ -66,7 +66,6 @@ * shader parts per shader increased. The complete new list of shader parts is: * - 1st shader: prolog part * - 1st shader: main part - * - 2nd shader: prolog part * - 2nd shader: main part * - 2nd shader: epilog part */ @@ -482,7 +481,6 @@ struct si_shader_info { uint8_t colors_read; /**< which color components are read by the FS */ uint8_t colors_written; uint16_t output_color_types; /**< Each bit pair is enum si_color_output_type */ - bool vs_needs_prolog; bool color0_writes_all_cbufs; /**< gl_FragColor */ bool reads_samplemask; /**< does fragment shader read sample mask? */ bool reads_tess_factors; /**< If TES reads TESSINNER or TESSOUTER */ @@ -626,19 +624,6 @@ struct si_shader_selector { */ #pragma pack(push, 1) -/* Common VS bits between the shader key and the prolog key. */ -struct si_vs_prolog_bits { - /* - If neither "is_one" nor "is_fetched" has a bit set, the instance - * divisor is 0. - * - If "is_one" has a bit set, the instance divisor is 1. - * - If "is_fetched" has a bit set, the instance divisor will be loaded - * from the constant buffer. - */ - uint16_t instance_divisor_is_one; /* bitmask of inputs */ - uint16_t instance_divisor_is_fetched; /* bitmask of inputs */ - unsigned ls_vgpr_fix : 1; -}; - /* Common TCS bits between the shader key and the epilog key. */ struct si_tcs_epilog_bits { unsigned prim_mode : 3; @@ -676,17 +661,6 @@ struct si_ps_epilog_bits { }; union si_shader_part_key { - struct { - struct si_vs_prolog_bits states; - unsigned wave32 : 1; - unsigned num_input_sgprs : 6; - /* For merged stages such as LS-HS, HS input VGPRs are first. */ - unsigned num_merged_next_stage_vgprs : 3; - unsigned num_inputs : 5; - unsigned as_ls : 1; - unsigned as_es : 1; - unsigned as_ngg : 1; - } vs_prolog; struct { struct si_tcs_epilog_bits states; unsigned wave32 : 1; @@ -721,15 +695,10 @@ struct si_shader_key_ge { /* Prolog and epilog flags. */ union { struct { - struct si_vs_prolog_bits prolog; - } vs; - struct { - struct si_vs_prolog_bits ls_prolog; /* for merged LS-HS */ struct si_shader_selector *ls; /* for merged LS-HS */ struct si_tcs_epilog_bits epilog; } tcs; /* tessellation control shader */ struct { - struct si_vs_prolog_bits vs_prolog; /* for merged ES-GS */ struct si_shader_selector *es; /* for merged ES-GS */ } gs; } part; @@ -744,6 +713,15 @@ struct si_shader_key_ge { /* Flags for monolithic compilation only. */ struct { + /* - If neither "is_one" nor "is_fetched" has a bit set, the instance + * divisor is 0. + * - If "is_one" has a bit set, the instance divisor is 1. + * - If "is_fetched" has a bit set, the instance divisor will be loaded + * from the constant buffer. + */ + uint16_t instance_divisor_is_one; /* bitmask of inputs */ + uint16_t instance_divisor_is_fetched; /* bitmask of inputs */ + /* Whether fetch should be opencoded according to vs_fix_fetch. * Otherwise, if vs_fix_fetch is non-zero, buffer_load_format_xyzw * with minimal fixups is used. */ diff --git a/src/gallium/drivers/radeonsi/si_shader_aco.c b/src/gallium/drivers/radeonsi/si_shader_aco.c index 4dee0284fbc..b03bbc0a118 100644 --- a/src/gallium/drivers/radeonsi/si_shader_aco.c +++ b/src/gallium/drivers/radeonsi/si_shader_aco.c @@ -85,16 +85,6 @@ si_fill_aco_shader_info(struct si_shader *shader, struct aco_shader_info *info, } switch (stage) { - case MESA_SHADER_VERTEX: - /* Only part mode VS may have prolog, mono mode VS will embed prolog in nir. - * But we don't know exactly if part mode VS needs prolog because it also depends - * on shader select key ls_vgpr_fix which is not known when VS main part compile. - * Now just assume ls_vgpr_fix is always false, which just cause ACO to add extra - * s_setprio and exec init code when it's finally combined with prolog. - */ - if (!shader->is_gs_copy_shader && !shader->is_monolithic) - info->vs.has_prolog = si_vs_needs_prolog(sel, &key->ge.part.vs.prolog); - break; case MESA_SHADER_TESS_CTRL: info->vs.tcs_in_out_eq = key->ge.opt.same_patch_vertices; info->vs.tcs_temp_only_input_mask = sel->info.tcs_vgpr_only_inputs; @@ -315,43 +305,6 @@ si_aco_build_tcs_epilog(struct si_screen *screen, return true; } -static bool -si_aco_build_vs_prolog(struct si_screen *screen, - struct aco_compiler_options *options, - struct si_shader_part *result) -{ - const union si_shader_part_key *key = &result->key; - - struct si_shader_args args; - si_get_vs_prolog_args(screen->info.gfx_level, &args, key); - - struct aco_gl_vs_prolog_info pinfo = { - .instance_divisor_is_one = key->vs_prolog.states.instance_divisor_is_one, - .instance_divisor_is_fetched = key->vs_prolog.states.instance_divisor_is_fetched, - .instance_diviser_buf_offset = SI_VS_CONST_INSTANCE_DIVISORS * 16, - .num_inputs = key->vs_prolog.num_inputs, - .as_ls = key->vs_prolog.as_ls, - - .internal_bindings = args.internal_bindings, - }; - - struct aco_shader_info info = {0}; - info.workgroup_size = info.wave_size = key->vs_prolog.wave32 ? 32 : 64; - - if (key->vs_prolog.as_ngg) - info.hw_stage = AC_HW_NEXT_GEN_GEOMETRY_SHADER; - else if (key->vs_prolog.as_es) - info.hw_stage = options->gfx_level >= GFX9 ? AC_HW_LEGACY_GEOMETRY_SHADER : AC_HW_EXPORT_SHADER; - else if (key->vs_prolog.as_ls) - info.hw_stage = options->gfx_level >= GFX9 ? AC_HW_HULL_SHADER : AC_HW_LOCAL_SHADER; - else - info.hw_stage = AC_HW_VERTEX_SHADER; - - aco_compile_gl_vs_prolog(options, &info, &pinfo, &args.ac, - si_aco_build_shader_part_binary, (void **)result); - return true; -} - static bool si_aco_build_ps_prolog(struct aco_compiler_options *options, struct si_shader_part *result) @@ -437,8 +390,6 @@ si_aco_build_shader_part(struct si_screen *screen, gl_shader_stage stage, bool p si_fill_aco_options(screen, stage, &options, debug); switch (stage) { - case MESA_SHADER_VERTEX: - return si_aco_build_vs_prolog(screen, &options, result); case MESA_SHADER_TESS_CTRL: return si_aco_build_tcs_epilog(screen, &options, result); break; diff --git a/src/gallium/drivers/radeonsi/si_shader_info.c b/src/gallium/drivers/radeonsi/si_shader_info.c index dca3984f7d0..09b00aaf2a7 100644 --- a/src/gallium/drivers/radeonsi/si_shader_info.c +++ b/src/gallium/drivers/radeonsi/si_shader_info.c @@ -794,9 +794,6 @@ void si_nir_scan_shader(struct si_screen *sscreen, const struct nir_shader *nir, nir->info.stage == MESA_SHADER_VERTEX && !info->base.vs.blit_sgprs_amd ? info->num_inputs : 0; unsigned num_vbos_in_sgprs = si_num_vbos_in_user_sgprs_inline(sscreen->info.gfx_level); info->num_vbos_in_user_sgprs = MIN2(info->num_vs_inputs, num_vbos_in_sgprs); - - /* The prolog is a no-op if there are no inputs. */ - info->vs_needs_prolog = info->num_inputs && !info->base.vs.blit_sgprs_amd; } if (nir->info.stage == MESA_SHADER_VERTEX || diff --git a/src/gallium/drivers/radeonsi/si_shader_internal.h b/src/gallium/drivers/radeonsi/si_shader_internal.h index c86cd0d0edf..215c143a509 100644 --- a/src/gallium/drivers/radeonsi/si_shader_internal.h +++ b/src/gallium/drivers/radeonsi/si_shader_internal.h @@ -45,7 +45,6 @@ struct si_shader_args { struct ac_arg gs_attr_address; /* API VS */ struct ac_arg vb_descriptors[5]; - struct ac_arg vertex_index0; /* VS state bits. See the VS_STATE_* and GS_STATE_* definitions. */ struct ac_arg vs_state_bits; struct ac_arg vs_blit_inputs; @@ -94,11 +93,6 @@ void si_add_arg_checked(struct ac_shader_args *args, enum ac_arg_regfile file, u enum ac_arg_type type, struct ac_arg *arg, unsigned idx); void si_init_shader_args(struct si_shader *shader, struct si_shader_args *args); unsigned si_get_max_workgroup_size(const struct si_shader *shader); -bool si_vs_needs_prolog(const struct si_shader_selector *sel, - const struct si_vs_prolog_bits *prolog_key); -void si_get_vs_prolog_key(const struct si_shader_info *info, unsigned num_input_sgprs, - const struct si_vs_prolog_bits *prolog_key, - struct si_shader *shader_out, union si_shader_part_key *key); struct nir_shader *si_get_nir_shader(struct si_shader *shader, struct si_shader_args *args, bool *free_nir, uint64_t tcs_vgpr_only_inputs, ac_nir_gs_output_info *output_info); @@ -119,9 +113,6 @@ void si_get_tcs_epilog_args(enum amd_gfx_level gfx_level, struct ac_arg *invocation_id, struct ac_arg *tf_lds_offset, struct ac_arg tess_factors[6]); -void si_get_vs_prolog_args(enum amd_gfx_level gfx_level, - struct si_shader_args *args, - const union si_shader_part_key *key); void si_get_ps_prolog_args(struct si_shader_args *args, const union si_shader_part_key *key); void si_get_ps_epilog_args(struct si_shader_args *args, diff --git a/src/gallium/drivers/radeonsi/si_shader_llvm.c b/src/gallium/drivers/radeonsi/si_shader_llvm.c index cfb837a8564..2e2e858494c 100644 --- a/src/gallium/drivers/radeonsi/si_shader_llvm.c +++ b/src/gallium/drivers/radeonsi/si_shader_llvm.c @@ -223,10 +223,8 @@ void si_llvm_create_main_func(struct si_shader_context *ctx) if (ctx->args->ac.vs_rel_patch_id.used) ctx->abi.vs_rel_patch_id = ac_get_arg(&ctx->ac, ctx->args->ac.vs_rel_patch_id); - /* Non-monolithic shaders apply the LS-HS input VGPR hw bug workaround in - * the VS prolog, while monolithic shaders apply it here. - */ - if (shader->is_monolithic && shader->key.ge.part.vs.prolog.ls_vgpr_fix) + /* Apply the LS-HS input VGPR hw bug workaround. */ + if (shader->key.ge.as_ls && ctx->screen->info.has_ls_vgpr_init_bug) ac_fixup_ls_hs_input_vgprs(&ctx->ac, &ctx->abi, &ctx->args->ac); } } @@ -655,9 +653,7 @@ static bool si_llvm_translate_nir(struct si_shader_context *ctx, struct si_shade if (!shader->key.ge.as_ls && !shader->key.ge.as_es) ac_init_exec_full_mask(&ctx->ac); } else { - /* If the prolog is present, EXEC is set there instead. */ - if (!si_vs_needs_prolog(sel, &shader->key.ge.part.vs.prolog)) - ac_init_exec_full_mask(&ctx->ac); + ac_init_exec_full_mask(&ctx->ac); } } @@ -904,12 +900,6 @@ bool si_llvm_build_shader_part(struct si_screen *sscreen, gl_shader_stage stage, bool exports_mrtz = false; switch (stage) { - case MESA_SHADER_VERTEX: - shader.key.ge.as_ls = key->vs_prolog.as_ls; - shader.key.ge.as_es = key->vs_prolog.as_es; - shader.key.ge.as_ngg = key->vs_prolog.as_ngg; - wave32 = key->vs_prolog.wave32; - break; case MESA_SHADER_TESS_CTRL: assert(!prolog); shader.key.ge.part.tcs.epilog = key->tcs_epilog.states; @@ -947,9 +937,6 @@ bool si_llvm_build_shader_part(struct si_screen *sscreen, gl_shader_stage stage, void (*build)(struct si_shader_context *, union si_shader_part_key *); switch (stage) { - case MESA_SHADER_VERTEX: - build = si_llvm_build_vs_prolog; - break; case MESA_SHADER_TESS_CTRL: build = si_llvm_build_tcs_epilog; break; diff --git a/src/gallium/drivers/radeonsi/si_shader_llvm.h b/src/gallium/drivers/radeonsi/si_shader_llvm.h index 7538e6c7a74..646b8f0e65b 100644 --- a/src/gallium/drivers/radeonsi/si_shader_llvm.h +++ b/src/gallium/drivers/radeonsi/si_shader_llvm.h @@ -92,7 +92,4 @@ void si_llvm_build_ps_prolog(struct si_shader_context *ctx, union si_shader_part void si_llvm_build_ps_epilog(struct si_shader_context *ctx, union si_shader_part_key *key); void si_llvm_ps_build_end(struct si_shader_context *ctx); -/* si_shader_llvm_vs.c */ -void si_llvm_build_vs_prolog(struct si_shader_context *ctx, union si_shader_part_key *key); - #endif diff --git a/src/gallium/drivers/radeonsi/si_shader_llvm_vs.c b/src/gallium/drivers/radeonsi/si_shader_llvm_vs.c deleted file mode 100644 index 32ae6dc3c71..00000000000 --- a/src/gallium/drivers/radeonsi/si_shader_llvm_vs.c +++ /dev/null @@ -1,158 +0,0 @@ -/* - * Copyright 2020 Advanced Micro Devices, Inc. - * - * SPDX-License-Identifier: MIT - */ - -#include "si_pipe.h" -#include "si_shader_internal.h" -#include "si_shader_llvm.h" -#include "sid.h" -#include "util/u_memory.h" -#include "ac_nir.h" - -static LLVMValueRef get_vertex_index(struct si_shader_context *ctx, - struct si_vs_prolog_bits *key, unsigned input_index, - LLVMValueRef instance_divisor_constbuf) -{ - LLVMValueRef instance_id = ctx->abi.instance_id; - LLVMValueRef vertex_id = ctx->abi.vertex_id; - - bool divisor_is_one = key->instance_divisor_is_one & (1u << input_index); - bool divisor_is_fetched =key->instance_divisor_is_fetched & (1u << input_index); - - LLVMValueRef index = NULL; - if (divisor_is_one) - index = instance_id; - else if (divisor_is_fetched) { - LLVMValueRef udiv_factors[4]; - - for (unsigned j = 0; j < 4; j++) { - udiv_factors[j] = si_buffer_load_const( - ctx, instance_divisor_constbuf, - LLVMConstInt(ctx->ac.i32, input_index * 16 + j * 4, 0)); - udiv_factors[j] = ac_to_integer(&ctx->ac, udiv_factors[j]); - } - - /* The faster NUW version doesn't work when InstanceID == UINT_MAX. - * Such InstanceID might not be achievable in a reasonable time though. - */ - index = ac_build_fast_udiv_nuw( - &ctx->ac, instance_id, udiv_factors[0], - udiv_factors[1], udiv_factors[2], udiv_factors[3]); - } - - if (divisor_is_one || divisor_is_fetched) { - /* Add StartInstance. */ - LLVMValueRef start_instance = ac_get_arg(&ctx->ac, ctx->args->ac.start_instance); - index = LLVMBuildAdd(ctx->ac.builder, index, start_instance, ""); - } else { - /* VertexID + BaseVertex */ - LLVMValueRef base_vertex = ac_get_arg(&ctx->ac, ctx->args->ac.base_vertex); - index = LLVMBuildAdd(ctx->ac.builder, vertex_id, base_vertex, ""); - } - - return index; -} - -/** - * Build the vertex shader prolog function. - * - * The inputs are the same as VS (a lot of SGPRs and 4 VGPR system values). - * All inputs are returned unmodified. The vertex load indices are - * stored after them, which will be used by the API VS for fetching inputs. - * - * For example, the expected outputs for instance_divisors[] = {0, 1, 2} are: - * input_v0, - * input_v1, - * input_v2, - * input_v3, - * (VertexID + BaseVertex), - * (InstanceID + StartInstance), - * (InstanceID / 2 + StartInstance) - */ -void si_llvm_build_vs_prolog(struct si_shader_context *ctx, union si_shader_part_key *key) -{ - struct si_shader_args *args = ctx->args; - si_get_vs_prolog_args(ctx->screen->info.gfx_level, args, key); - - const unsigned num_input_sgprs = args->ac.num_sgprs_used; - const unsigned num_input_vgprs = args->ac.num_vgprs_used; - - /* 4 preloaded VGPRs + vertex load indices as prolog outputs */ - const unsigned num_output_gprs = - num_input_sgprs + num_input_vgprs + key->vs_prolog.num_inputs; - LLVMTypeRef returns[num_output_gprs]; - int num_returns = 0; - - /* Output SGPRs. */ - for (int i = 0; i < num_input_sgprs; i++) - returns[num_returns++] = ctx->ac.i32; - - /* Output VGPRs */ - for (int i = 0; i < num_input_vgprs; i++) - returns[num_returns++] = ctx->ac.f32; - - /* Vertex load indices. */ - for (int i = 0; i < key->vs_prolog.num_inputs; i++) - returns[num_returns++] = ctx->ac.f32; - - /* Create the function. */ - si_llvm_create_func(ctx, "vs_prolog", returns, num_returns, 0); - LLVMValueRef func = ctx->main_fn.value; - - LLVMValueRef input_vgprs[num_input_vgprs]; - for (int i = 0; i < num_input_vgprs; i++) - input_vgprs[i] = LLVMGetParam(func, num_input_sgprs + i); - - if (key->vs_prolog.num_merged_next_stage_vgprs) { - ac_init_exec_full_mask(&ctx->ac); - - if (key->vs_prolog.as_ls && ctx->screen->info.has_ls_vgpr_init_bug) { - /* If there are no HS threads, SPI loads the LS VGPRs - * starting at VGPR 0. Shift them back to where they - * belong. - */ - LLVMValueRef hs_thread_count = - si_unpack_param(ctx, args->ac.merged_wave_info, 8, 8); - LLVMValueRef has_hs_threads = - LLVMBuildICmp(ctx->ac.builder, LLVMIntNE, hs_thread_count, ctx->ac.i32_0, ""); - - for (int i = 4; i > 0; --i) { - input_vgprs[i + 1] = LLVMBuildSelect(ctx->ac.builder, has_hs_threads, - input_vgprs[i + 1], input_vgprs[i - 1], ""); - } - } - } - - ctx->abi.vertex_id = input_vgprs[args->ac.vertex_id.arg_index - num_input_sgprs]; - ctx->abi.instance_id = input_vgprs[args->ac.instance_id.arg_index - num_input_sgprs]; - - /* Copy inputs to outputs. This should be no-op, as the registers match, - * but it will prevent the compiler from overwriting them unintentionally. - */ - LLVMValueRef ret = ctx->return_value; - for (int i = 0; i < num_input_sgprs; i++) { - LLVMValueRef p = LLVMGetParam(func, i); - ret = LLVMBuildInsertValue(ctx->ac.builder, ret, p, i, ""); - } - for (int i = 0; i < num_input_vgprs; i++) { - LLVMValueRef p = ac_to_float(&ctx->ac, input_vgprs[i]); - ret = LLVMBuildInsertValue(ctx->ac.builder, ret, p, num_input_sgprs + i, ""); - } - - /* Compute vertex load indices from instance divisors. */ - LLVMValueRef instance_divisor_constbuf = - key->vs_prolog.states.instance_divisor_is_fetched ? - si_prolog_get_internal_binding_slot(ctx, SI_VS_CONST_INSTANCE_DIVISORS) : NULL; - - for (int i = 0; i < key->vs_prolog.num_inputs; i++) { - LLVMValueRef index = get_vertex_index(ctx, &key->vs_prolog.states, i, - instance_divisor_constbuf); - - index = ac_to_float(&ctx->ac, index); - ret = LLVMBuildInsertValue(ctx->ac.builder, ret, index, args->ac.arg_count + i, ""); - } - - si_llvm_build_ret(ctx, ret); -} diff --git a/src/gallium/drivers/radeonsi/si_state.h b/src/gallium/drivers/radeonsi/si_state.h index 096f94cee39..3f7c8c64e4f 100644 --- a/src/gallium/drivers/radeonsi/si_state.h +++ b/src/gallium/drivers/radeonsi/si_state.h @@ -657,8 +657,6 @@ void si_get_active_slot_masks(struct si_screen *sscreen, const struct si_shader_ uint64_t *const_and_shader_buffers, uint64_t *samplers_and_images); int si_shader_select(struct pipe_context *ctx, struct si_shader_ctx_state *state); void si_vs_key_update_inputs(struct si_context *sctx); -void si_get_vs_key_inputs(struct si_context *sctx, union si_shader_key *key, - struct si_vs_prolog_bits *prolog_key); void si_update_ps_inputs_read_or_disabled(struct si_context *sctx); void si_update_vrs_flat_shading(struct si_context *sctx); unsigned si_get_input_prim(const struct si_shader_selector *gs, const union si_shader_key *key); diff --git a/src/gallium/drivers/radeonsi/si_state_draw.cpp b/src/gallium/drivers/radeonsi/si_state_draw.cpp index 01d210520ba..95b6201c216 100644 --- a/src/gallium/drivers/radeonsi/si_state_draw.cpp +++ b/src/gallium/drivers/radeonsi/si_state_draw.cpp @@ -2131,13 +2131,12 @@ static void si_draw(struct pipe_context *ctx, if (IS_DRAW_VERTEX_STATE) { /* draw_vertex_state doesn't use the current vertex buffers and vertex elements, - * so disable any non-trivial VS prolog that is based on them, such as vertex - * format lowering. + * so disable all VS input lowering. */ if (!sctx->force_trivial_vs_inputs) { sctx->force_trivial_vs_inputs = true; - /* Update shaders to disable the non-trivial VS prolog. */ + /* Update shaders to disable VS input lowering. */ if (sctx->uses_nontrivial_vs_inputs) { si_vs_key_update_inputs(sctx); sctx->do_update_shaders = true; @@ -2147,7 +2146,7 @@ static void si_draw(struct pipe_context *ctx, if (sctx->force_trivial_vs_inputs) { sctx->force_trivial_vs_inputs = false; - /* Update shaders to enable the non-trivial VS prolog. */ + /* Update shaders to possibly enable VS input lowering. */ if (sctx->uses_nontrivial_vs_inputs) { si_vs_key_update_inputs(sctx); sctx->do_update_shaders = true; diff --git a/src/gallium/drivers/radeonsi/si_state_shaders.cpp b/src/gallium/drivers/radeonsi/si_state_shaders.cpp index b0549aab025..bd5c3e0bae0 100644 --- a/src/gallium/drivers/radeonsi/si_state_shaders.cpp +++ b/src/gallium/drivers/radeonsi/si_state_shaders.cpp @@ -2110,11 +2110,10 @@ static void si_shader_init_pm4_state(struct si_screen *sscreen, struct si_shader assert(!(sscreen->debug_flags & DBG(SQTT)) || shader->pm4.spi_shader_pgm_lo_reg != 0); } -static void si_clear_vs_key_inputs(struct si_context *sctx, union si_shader_key *key, - struct si_vs_prolog_bits *prolog_key) +static void si_clear_vs_key_inputs(union si_shader_key *key) { - prolog_key->instance_divisor_is_one = 0; - prolog_key->instance_divisor_is_fetched = 0; + key->ge.mono.instance_divisor_is_one = 0; + key->ge.mono.instance_divisor_is_fetched = 0; key->ge.mono.vs_fetch_opencode = 0; memset(key->ge.mono.vs_fix_fetch, 0, sizeof(key->ge.mono.vs_fix_fetch)); } @@ -2129,7 +2128,7 @@ void si_vs_key_update_inputs(struct si_context *sctx) return; if (vs->info.base.vs.blit_sgprs_amd) { - si_clear_vs_key_inputs(sctx, key, &key->ge.part.vs.prolog); + si_clear_vs_key_inputs(key); key->ge.opt.prefer_mono = 0; sctx->uses_nontrivial_vs_inputs = false; return; @@ -2140,8 +2139,8 @@ void si_vs_key_update_inputs(struct si_context *sctx) if (elts->instance_divisor_is_one || elts->instance_divisor_is_fetched) uses_nontrivial_vs_inputs = true; - key->ge.part.vs.prolog.instance_divisor_is_one = elts->instance_divisor_is_one; - key->ge.part.vs.prolog.instance_divisor_is_fetched = elts->instance_divisor_is_fetched; + key->ge.mono.instance_divisor_is_one = elts->instance_divisor_is_one; + key->ge.mono.instance_divisor_is_fetched = elts->instance_divisor_is_fetched; key->ge.opt.prefer_mono = elts->instance_divisor_is_fetched; unsigned count_mask = (1 << vs->info.num_inputs) - 1; @@ -2179,25 +2178,22 @@ void si_vs_key_update_inputs(struct si_context *sctx) sctx->uses_nontrivial_vs_inputs = uses_nontrivial_vs_inputs; - /* draw_vertex_state (display lists) requires a trivial VS prolog that ignores - * the current vertex buffers and vertex elements. + /* draw_vertex_state (display lists) requires that all VS input lowering is disabled + * because its vertex elements never need any lowering. * - * We just computed the prolog key because we needed to set uses_nontrivial_vs_inputs, - * so that we know whether the VS prolog should be updated when we switch from - * draw_vertex_state to draw_vbo. Now clear the VS prolog for draw_vertex_state. - * This should happen rarely because the VS prolog should be trivial in most - * cases. + * We just computed the key because we needed to set uses_nontrivial_vs_inputs, so that we know + * whether the VS should be updated when we switch from draw_vertex_state to draw_vbo. Now + * clear the VS input bits for draw_vertex_state. This should happen rarely because VS inputs + * don't usually need any lowering. */ if (uses_nontrivial_vs_inputs && sctx->force_trivial_vs_inputs) - si_clear_vs_key_inputs(sctx, key, &key->ge.part.vs.prolog); + si_clear_vs_key_inputs(key); } -void si_get_vs_key_inputs(struct si_context *sctx, union si_shader_key *key, - struct si_vs_prolog_bits *prolog_key) +static void si_get_vs_key_inputs(struct si_context *sctx, union si_shader_key *key) { - prolog_key->instance_divisor_is_one = sctx->shader.vs.key.ge.part.vs.prolog.instance_divisor_is_one; - prolog_key->instance_divisor_is_fetched = sctx->shader.vs.key.ge.part.vs.prolog.instance_divisor_is_fetched; - + key->ge.mono.instance_divisor_is_one = sctx->shader.vs.key.ge.mono.instance_divisor_is_one; + key->ge.mono.instance_divisor_is_fetched = sctx->shader.vs.key.ge.mono.instance_divisor_is_fetched; key->ge.mono.vs_fetch_opencode = sctx->shader.vs.key.ge.mono.vs_fetch_opencode; memcpy(key->ge.mono.vs_fix_fetch, sctx->shader.vs.key.ge.mono.vs_fix_fetch, sizeof(key->ge.mono.vs_fix_fetch)); @@ -2624,7 +2620,7 @@ static inline void si_shader_selector_key(struct pipe_context *ctx, struct si_sh break; case MESA_SHADER_TESS_CTRL: if (sctx->gfx_level >= GFX9) { - si_get_vs_key_inputs(sctx, key, &key->ge.part.tcs.ls_prolog); + si_get_vs_key_inputs(sctx, key); key->ge.part.tcs.ls = sctx->shader.vs.cso; } break; @@ -2637,10 +2633,10 @@ static inline void si_shader_selector_key(struct pipe_context *ctx, struct si_sh case MESA_SHADER_GEOMETRY: if (sctx->gfx_level >= GFX9) { if (sctx->shader.tes.cso) { - si_clear_vs_key_inputs(sctx, key, &key->ge.part.gs.vs_prolog); + si_clear_vs_key_inputs(key); key->ge.part.gs.es = sctx->shader.tes.cso; } else { - si_get_vs_key_inputs(sctx, key, &key->ge.part.gs.vs_prolog); + si_get_vs_key_inputs(sctx, key); key->ge.part.gs.es = sctx->shader.vs.cso; } @@ -4451,28 +4447,12 @@ static void si_update_tess_in_out_patch_vertices(struct si_context *sctx) sctx->shader.tcs.key.ge.opt.same_patch_vertices = same_patch_vertices; sctx->do_update_shaders = true; } - - if (sctx->gfx_level == GFX9 && sctx->screen->info.has_ls_vgpr_init_bug) { - /* Determine whether the LS VGPR fix should be applied. - * - * It is only required when num input CPs > num output CPs, - * which cannot happen with the fixed function TCS. - */ - bool ls_vgpr_fix = - sctx->patch_vertices > tcs->info.base.tess.tcs_vertices_out; - - if (ls_vgpr_fix != sctx->shader.tcs.key.ge.part.tcs.ls_prolog.ls_vgpr_fix) { - sctx->shader.tcs.key.ge.part.tcs.ls_prolog.ls_vgpr_fix = ls_vgpr_fix; - sctx->do_update_shaders = true; - } - } } else { /* These fields are static for fixed function TCS. So no need to set * do_update_shaders between fixed-TCS draws. As fixed-TCS to user-TCS * or opposite, do_update_shaders should already be set by bind state. */ sctx->shader.tcs.key.ge.opt.same_patch_vertices = sctx->gfx_level >= GFX9; - sctx->shader.tcs.key.ge.part.tcs.ls_prolog.ls_vgpr_fix = false; /* User may only change patch vertices, needs to update fixed func TCS. */ if (sctx->shader.tcs.cso &&