diff --git a/src/asahi/lib/agx_linker.c b/src/asahi/lib/agx_linker.c index 7591095704f..445b939f777 100644 --- a/src/asahi/lib/agx_linker.c +++ b/src/asahi/lib/agx_linker.c @@ -209,6 +209,7 @@ agx_fast_link(struct agx_linked_shader *linked, struct agx_device *dev, if (tag_write_disable) { reads_tib = false; writes_sample_mask = false; + linked->no_op = true; } agx_pack(&linked->fragment_control, FRAGMENT_CONTROL, cfg) { diff --git a/src/asahi/lib/agx_linker.h b/src/asahi/lib/agx_linker.h index bc7dc3caaee..9532fa6b80f 100644 --- a/src/asahi/lib/agx_linker.h +++ b/src/asahi/lib/agx_linker.h @@ -26,6 +26,9 @@ struct agx_linked_shader { */ bool uses_txf; + /* Whether the program is a no-op and can be skipped. */ + bool no_op; + /* Coefficient register bindings */ struct agx_varyings_fs cf; diff --git a/src/asahi/vulkan/hk_cmd_draw.c b/src/asahi/vulkan/hk_cmd_draw.c index e8aa7557565..8d5ae5b3b89 100644 --- a/src/asahi/vulkan/hk_cmd_draw.c +++ b/src/asahi/vulkan/hk_cmd_draw.c @@ -2374,6 +2374,8 @@ hk_flush_ppp_state(struct hk_cmd_buffer *cmd, struct hk_cs *cs, uint8_t **out) .viewport_count = 1, /* irrelevant */ }; + dirty.fragment_shader &= !linked_fs->b.no_op; + /* Calculate the update size. If it equals the header, there is nothing to * update so early-exit. */ diff --git a/src/gallium/drivers/asahi/agx_state.c b/src/gallium/drivers/asahi/agx_state.c index 3101eb28e6f..300c776a75f 100644 --- a/src/gallium/drivers/asahi/agx_state.c +++ b/src/gallium/drivers/asahi/agx_state.c @@ -3561,7 +3561,8 @@ agx_encode_state(struct agx_batch *batch, uint8_t *out) .cull = IS_DIRTY(RS), .cull_2 = varyings_dirty, .fragment_shader = - IS_DIRTY(FS) || varyings_dirty || IS_DIRTY(SAMPLE_MASK), + (IS_DIRTY(FS) || varyings_dirty || IS_DIRTY(SAMPLE_MASK)) && + !ctx->linked.fs->no_op, .occlusion_query = IS_DIRTY(QUERY), .output_size = IS_DIRTY(VS_PROG), .viewport_count = 1, /* irrelevant */