ac,radeonsi: don't export null from PS if it has no effect on gfx10+

We just need to pass the uses_discard flag to the epilog.

The hw skips the export anyway. This will hang if SPI registers declare
an output format or KILL_ENABLE is set because those cases require
an export with done=1.

Reviewed-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/16885>
This commit is contained in:
Marek Olšák 2022-05-15 02:17:20 -04:00 committed by Marge Bot
parent e4b7088779
commit bdf3797aeb
7 changed files with 21 additions and 8 deletions

View File

@ -1996,10 +1996,16 @@ void ac_build_export(struct ac_llvm_context *ctx, struct ac_export_args *a)
}
}
void ac_build_export_null(struct ac_llvm_context *ctx)
void ac_build_export_null(struct ac_llvm_context *ctx, bool uses_discard)
{
struct ac_export_args args;
/* Gfx10+ doesn't need to export anything if we don't need to export the EXEC mask
* for discard.
*/
if (ctx->gfx_level >= GFX10 && !uses_discard)
return;
args.enabled_channels = 0x0; /* enabled channels */
args.valid_mask = 1; /* whether the EXEC mask is valid */
args.done = 1; /* DONE bit */

View File

@ -342,7 +342,7 @@ struct ac_export_args {
void ac_build_export(struct ac_llvm_context *ctx, struct ac_export_args *a);
void ac_build_export_null(struct ac_llvm_context *ctx);
void ac_build_export_null(struct ac_llvm_context *ctx, bool uses_discard);
enum ac_image_opcode
{

View File

@ -1797,7 +1797,7 @@ handle_fs_outputs_post(struct radv_shader_context *ctx)
if (depth || stencil || samplemask)
radv_export_mrt_z(ctx, depth, stencil, samplemask);
else if (!index)
ac_build_export_null(&ctx->ac);
ac_build_export_null(&ctx->ac, ctx->shader_info->ps.can_discard);
}
static void

View File

@ -2222,6 +2222,7 @@ void si_get_ps_epilog_key(struct si_shader *shader, union si_shader_part_key *ke
struct si_shader_info *info = &shader->selector->info;
memset(key, 0, sizeof(*key));
key->ps_epilog.wave32 = shader->wave_size == 32;
key->ps_epilog.uses_discard = si_shader_uses_discard(shader);
key->ps_epilog.colors_written = info->colors_written;
key->ps_epilog.color_types = info->output_color_types;
key->ps_epilog.writes_z = info->writes_z;

View File

@ -642,6 +642,7 @@ union si_shader_part_key {
struct {
struct si_ps_epilog_bits states;
unsigned wave32 : 1;
unsigned uses_discard : 1;
unsigned colors_written : 8;
unsigned color_types : 16;
unsigned writes_z : 1;
@ -1053,6 +1054,14 @@ static inline bool si_shader_uses_streamout(struct si_shader *shader)
!shader->key.ge.opt.remove_streamout;
}
static inline bool si_shader_uses_discard(struct si_shader *shader)
{
/* Changes to this should also update ps_modifies_zs. */
return shader->selector->info.base.fs.uses_discard ||
shader->key.ps.part.prolog.poly_stipple ||
shader->key.ps.part.epilog.alpha_func != PIPE_FUNC_ALWAYS;
}
#ifdef __cplusplus
}
#endif

View File

@ -946,7 +946,7 @@ void si_llvm_build_ps_epilog(struct si_shader_context *ctx, union si_shader_part
for (unsigned i = 0; i < exp.num; i++)
ac_build_export(&ctx->ac, &exp.args[i]);
} else {
ac_build_export_null(&ctx->ac);
ac_build_export_null(&ctx->ac, key->ps_epilog.uses_discard);
}
/* Compile. */

View File

@ -1871,10 +1871,7 @@ static void si_shader_ps(struct si_screen *sscreen, struct si_shader *shader)
S_02880C_Z_EXPORT_ENABLE(info->writes_z) |
S_02880C_STENCIL_TEST_VAL_EXPORT_ENABLE(info->writes_stencil) |
S_02880C_MASK_EXPORT_ENABLE(info->writes_samplemask) |
/* Changes KILL_ENABLE should also update ps_modifies_zs. */
S_02880C_KILL_ENABLE(info->base.fs.uses_discard ||
shader->key.ps.part.prolog.poly_stipple ||
shader->key.ps.part.epilog.alpha_func != PIPE_FUNC_ALWAYS);
S_02880C_KILL_ENABLE(si_shader_uses_discard(shader));
switch (info->base.fs.depth_layout) {
case FRAG_DEPTH_LAYOUT_GREATER: