diff --git a/src/gallium/drivers/radeonsi/si_shader.c b/src/gallium/drivers/radeonsi/si_shader.c index d2cca025bc4..99b2910a470 100644 --- a/src/gallium/drivers/radeonsi/si_shader.c +++ b/src/gallium/drivers/radeonsi/si_shader.c @@ -1898,14 +1898,22 @@ struct nir_shader *si_get_nir_shader(struct si_shader *shader, struct si_shader_ bool opt_offsets = si_lower_io_to_mem(shader, nir, tcs_vgpr_only_inputs); - /* Assign param export indices. */ - if (is_last_vgt_stage) + if (is_last_vgt_stage) { + /* Assign param export indices. */ si_assign_param_offsets(nir, shader); - /* Only lower last VGT NGG shader stage. */ - if (sel->stage <= MESA_SHADER_GEOMETRY && key->ge.as_ngg && !key->ge.as_es) { - si_lower_ngg(shader, nir); - opt_offsets = true; + if (key->ge.as_ngg) { + /* Lower last VGT NGG shader stage. */ + si_lower_ngg(shader, nir); + opt_offsets = true; + } else if (sel->stage == MESA_SHADER_VERTEX || sel->stage == MESA_SHADER_TESS_EVAL) { + /* Lower last VGT none-NGG VS/TES shader stage. */ + int primitive_id_location = + shader->key.ge.mono.u.vs_export_prim_id ? sel->info.num_outputs : -1; + + NIR_PASS_V(nir, ac_nir_lower_legacy_vs, primitive_id_location, + key->ge.opt.remove_streamout); + } } NIR_PASS(progress2, nir, si_nir_lower_abi, shader, args); @@ -1952,6 +1960,7 @@ void si_update_shader_binary_info(struct si_shader *shader, nir_shader *nir) bool si_compile_shader(struct si_screen *sscreen, struct ac_llvm_compiler *compiler, struct si_shader *shader, struct util_debug_callback *debug) { + bool ret = true; struct si_shader_selector *sel = shader->selector; struct si_shader_args args; @@ -1960,11 +1969,6 @@ bool si_compile_shader(struct si_screen *sscreen, struct ac_llvm_compiler *compi bool free_nir; struct nir_shader *nir = si_get_nir_shader(shader, &args, &free_nir, 0); - struct pipe_stream_output_info so = {}; - /* NGG streamout has been lowered to buffer store in nir. */ - if (!sscreen->use_ngg_streamout && si_shader_uses_streamout(shader)) - nir_gather_stream_output_info(nir, &so); - /* Dump NIR before doing NIR->LLVM conversion in case the * conversion fails. */ if (si_can_dump_shader(sscreen, sel->stage) && @@ -2016,17 +2020,24 @@ bool si_compile_shader(struct si_screen *sscreen, struct ac_llvm_compiler *compi * with PS and NGG VS), but monolithic shaders should be compiled * by LLVM due to more complicated compilation. */ - if (!si_llvm_compile_shader(sscreen, compiler, shader, &args, &so, debug, nir, free_nir)) - return false; + if (!si_llvm_compile_shader(sscreen, compiler, shader, &args, debug, nir)) { + ret = false; + goto out; + } shader->config.float_mode = float_mode; /* The GS copy shader is compiled next. */ if (sel->stage == MESA_SHADER_GEOMETRY && !shader->key.ge.as_ngg) { + struct pipe_stream_output_info so = {}; + if (si_shader_uses_streamout(shader)) + nir_gather_stream_output_info(nir, &so); + shader->gs_copy_shader = si_generate_gs_copy_shader(sscreen, compiler, sel, &so, debug); if (!shader->gs_copy_shader) { fprintf(stderr, "radeonsi: can't create GS copy shader\n"); - return false; + ret = false; + goto out; } } @@ -2111,7 +2122,12 @@ bool si_compile_shader(struct si_screen *sscreen, struct ac_llvm_compiler *compi si_calculate_max_simd_waves(shader); si_shader_dump_stats_for_shader_db(sscreen, shader, debug); - return true; + +out: + if (free_nir) + ralloc_free(nir); + + return ret; } /** diff --git a/src/gallium/drivers/radeonsi/si_shader_internal.h b/src/gallium/drivers/radeonsi/si_shader_internal.h index 2d9ba9b6ef7..ede39887c29 100644 --- a/src/gallium/drivers/radeonsi/si_shader_internal.h +++ b/src/gallium/drivers/radeonsi/si_shader_internal.h @@ -229,9 +229,7 @@ bool si_llvm_translate_nir(struct si_shader_context *ctx, struct si_shader *shad struct nir_shader *nir, bool free_nir); bool si_llvm_compile_shader(struct si_screen *sscreen, struct ac_llvm_compiler *compiler, struct si_shader *shader, struct si_shader_args *args, - const struct pipe_stream_output_info *so, - struct util_debug_callback *debug, struct nir_shader *nir, - bool free_nir); + struct util_debug_callback *debug, struct nir_shader *nir); /* si_shader_llvm_gs.c */ LLVMValueRef si_is_es_thread(struct si_shader_context *ctx); @@ -269,7 +267,6 @@ void si_llvm_emit_streamout(struct si_shader_context *ctx, struct si_shader_outp unsigned noutput, unsigned stream); void si_llvm_build_vs_exports(struct si_shader_context *ctx, struct si_shader_output_values *outputs, unsigned noutput); -void si_llvm_vs_build_end(struct si_shader_context *ctx); void si_llvm_build_vs_prolog(struct si_shader_context *ctx, union si_shader_part_key *key); void si_llvm_init_vs_callbacks(struct si_shader_context *ctx); diff --git a/src/gallium/drivers/radeonsi/si_shader_llvm.c b/src/gallium/drivers/radeonsi/si_shader_llvm.c index b6a978e73b6..3c1d344f6a4 100644 --- a/src/gallium/drivers/radeonsi/si_shader_llvm.c +++ b/src/gallium/drivers/radeonsi/si_shader_llvm.c @@ -1020,8 +1020,8 @@ bool si_llvm_translate_nir(struct si_shader_context *ctx, struct si_shader *shad ctx->abi.disable_aniso_single_level = true; unsigned num_outputs = info->num_outputs; - /* need extra output to hold primitive id added by nir ngg lower */ - if (ctx->stage <= MESA_SHADER_GEOMETRY && shader->key.ge.as_ngg && + /* need extra output to hold primitive id added by nir lower */ + if (ctx->stage <= MESA_SHADER_GEOMETRY && ctx->shader->key.ge.mono.u.vs_export_prim_id) num_outputs++; @@ -1048,8 +1048,6 @@ bool si_llvm_translate_nir(struct si_shader_context *ctx, struct si_shader *shad si_llvm_ls_build_end(ctx); else if (shader->key.ge.as_es) si_llvm_es_build_end(ctx); - else if (!shader->key.ge.as_ngg) - si_llvm_vs_build_end(ctx); break; case MESA_SHADER_TESS_CTRL: @@ -1059,8 +1057,6 @@ bool si_llvm_translate_nir(struct si_shader_context *ctx, struct si_shader *shad case MESA_SHADER_TESS_EVAL: if (ctx->shader->key.ge.as_es) si_llvm_es_build_end(ctx); - else if (!ctx->shader->key.ge.as_ngg) - si_llvm_vs_build_end(ctx); break; case MESA_SHADER_GEOMETRY: @@ -1099,9 +1095,7 @@ static bool si_should_optimize_less(struct ac_llvm_compiler *compiler, bool si_llvm_compile_shader(struct si_screen *sscreen, struct ac_llvm_compiler *compiler, struct si_shader *shader, struct si_shader_args *args, - const struct pipe_stream_output_info *so, - struct util_debug_callback *debug, struct nir_shader *nir, - bool free_nir) + struct util_debug_callback *debug, struct nir_shader *nir) { struct si_shader_selector *sel = shader->selector; struct si_shader_context ctx; @@ -1112,10 +1106,9 @@ bool si_llvm_compile_shader(struct si_screen *sscreen, struct ac_llvm_compiler * exports_color_null = si_shader_uses_discard(shader) || sscreen->info.gfx_level < GFX10; si_llvm_context_init(&ctx, sscreen, compiler, shader->wave_size, exports_color_null, exports_mrtz); - ctx.so = *so; ctx.args = args; - if (!si_llvm_translate_nir(&ctx, shader, nir, free_nir)) { + if (!si_llvm_translate_nir(&ctx, shader, nir, false)) { si_llvm_dispose(&ctx); return false; } @@ -1168,6 +1161,8 @@ bool si_llvm_compile_shader(struct si_screen *sscreen, struct ac_llvm_compiler * shader_ls.is_monolithic = true; si_init_shader_args(&shader_ls, ctx.args); + + bool free_nir; nir = si_get_nir_shader(&shader_ls, ctx.args, &free_nir, sel->info.tcs_vgpr_only_inputs); si_update_shader_binary_info(shader, nir); @@ -1240,6 +1235,8 @@ bool si_llvm_compile_shader(struct si_screen *sscreen, struct ac_llvm_compiler * shader_es.is_monolithic = true; si_init_shader_args(&shader_es, ctx.args); + + bool free_nir; nir = si_get_nir_shader(&shader_es, ctx.args, &free_nir, 0); si_update_shader_binary_info(shader, nir); diff --git a/src/gallium/drivers/radeonsi/si_shader_llvm_vs.c b/src/gallium/drivers/radeonsi/si_shader_llvm_vs.c index 734a15504b8..1aadd00b360 100644 --- a/src/gallium/drivers/radeonsi/si_shader_llvm_vs.c +++ b/src/gallium/drivers/radeonsi/si_shader_llvm_vs.c @@ -724,44 +724,6 @@ void si_llvm_build_vs_exports(struct si_shader_context *ctx, ac_build_export(&ctx->ac, ¶m_exports[i]); } -void si_llvm_vs_build_end(struct si_shader_context *ctx) -{ - struct si_shader_info *info = &ctx->shader->selector->info; - struct si_shader_output_values *outputs = NULL; - LLVMValueRef *addrs = ctx->abi.outputs; - int i, j; - - assert(!ctx->shader->is_gs_copy_shader); - assert(info->num_outputs <= AC_LLVM_MAX_OUTPUTS); - - outputs = MALLOC((info->num_outputs + 1) * sizeof(outputs[0])); - - for (i = 0; i < info->num_outputs; i++) { - outputs[i].semantic = info->output_semantic[i]; - - for (j = 0; j < 4; j++) { - outputs[i].values[j] = LLVMBuildLoad2(ctx->ac.builder, ctx->ac.f32, addrs[4 * i + j], ""); - outputs[i].vertex_streams = info->output_streams[i]; - } - } - - if (!ctx->screen->use_ngg_streamout && ctx->so.num_outputs) - si_llvm_emit_streamout(ctx, outputs, i, 0); - - /* Export PrimitiveID. */ - if (ctx->shader->key.ge.mono.u.vs_export_prim_id) { - outputs[i].semantic = VARYING_SLOT_PRIMITIVE_ID; - outputs[i].vertex_streams = 0; - outputs[i].values[0] = ac_to_float(&ctx->ac, si_get_primitive_id(ctx, 0)); - for (j = 1; j < 4; j++) - outputs[i].values[j] = LLVMConstReal(ctx->ac.f32, 0); - i++; - } - - si_llvm_build_vs_exports(ctx, outputs, i); - FREE(outputs); -} - /** * Build the vertex shader prolog function. *