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:
parent
e4b7088779
commit
bdf3797aeb
|
@ -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 */
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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:
|
||||
|
|
Loading…
Reference in New Issue