diff --git a/src/gallium/drivers/asahi/agx_state.c b/src/gallium/drivers/asahi/agx_state.c index 13171d5138f..0b93940fd4f 100644 --- a/src/gallium/drivers/asahi/agx_state.c +++ b/src/gallium/drivers/asahi/agx_state.c @@ -177,6 +177,8 @@ agx_set_shader_buffers(struct pipe_context *pctx, enum pipe_shader_type shader, count); ctx->stage[shader].dirty |= AGX_STAGE_DIRTY_SSBO; + ctx->stage[shader].ssbo_writable_mask &= ~(BITFIELD_MASK(count) << start); + ctx->stage[shader].ssbo_writable_mask |= writable_bitmask << start; } static void diff --git a/src/gallium/drivers/asahi/agx_state.h b/src/gallium/drivers/asahi/agx_state.h index c6543e41195..f8453c59f9f 100644 --- a/src/gallium/drivers/asahi/agx_state.h +++ b/src/gallium/drivers/asahi/agx_state.h @@ -261,6 +261,7 @@ struct agx_stage { uint32_t cb_mask; struct pipe_shader_buffer ssbo[PIPE_MAX_SHADER_BUFFERS]; + uint32_t ssbo_writable_mask; uint32_t ssbo_mask; struct pipe_image_view images[PIPE_MAX_SHADER_IMAGES]; diff --git a/src/gallium/drivers/asahi/agx_uniforms.c b/src/gallium/drivers/asahi/agx_uniforms.c index e2d64810de5..676f54074d7 100644 --- a/src/gallium/drivers/asahi/agx_uniforms.c +++ b/src/gallium/drivers/asahi/agx_uniforms.c @@ -6,6 +6,7 @@ #include "asahi/lib/agx_pack.h" #include "pipe/p_state.h" #include "util/format/u_format.h" +#include "util/macros.h" #include "agx_state.h" #include "pool.h" @@ -155,9 +156,12 @@ agx_upload_stage_uniforms(struct agx_batch *batch, uint64_t textures, if (sb->buffer && st->ssbo[cb].buffer_size) { struct agx_resource *rsrc = agx_resource(sb->buffer); - /* Assume SSBOs are written. TODO: Optimize read-only SSBOs */ - agx_batch_writes_range(batch, rsrc, sb->buffer_offset, - sb->buffer_size); + if (st->ssbo_writable_mask & BITFIELD_BIT(cb)) { + agx_batch_writes_range(batch, rsrc, sb->buffer_offset, + sb->buffer_size); + } else { + agx_batch_reads(batch, rsrc); + } uniforms.ssbo_base[cb] = rsrc->bo->ptr.gpu + sb->buffer_offset; uniforms.ssbo_size[cb] = st->ssbo[cb].buffer_size;