diff --git a/src/gallium/drivers/asahi/agx_pipe.c b/src/gallium/drivers/asahi/agx_pipe.c index 8ccdc642d8a..f461dcb6e26 100644 --- a/src/gallium/drivers/asahi/agx_pipe.c +++ b/src/gallium/drivers/asahi/agx_pipe.c @@ -1119,6 +1119,19 @@ transition_resource(struct pipe_context *pctx, struct agx_resource *rsrc, pipe_resource_reference((struct pipe_resource **)&new_res, NULL); } +void +agx_decompress(struct agx_context *ctx, struct agx_resource *rsrc, + const char *reason) +{ + assert(rsrc->layout.tiling == AIL_TILING_TWIDDLED_COMPRESSED); + perf_debug_ctx(ctx, "Decompressing resource due to %s", reason); + + struct pipe_resource templ = rsrc->base; + assert(!(templ.bind & PIPE_BIND_SHADER_IMAGE) && "currently compressed"); + templ.bind |= PIPE_BIND_SHADER_IMAGE /* forces off compression */; + transition_resource(&ctx->base, rsrc, &templ); +} + static void agx_flush_resource(struct pipe_context *pctx, struct pipe_resource *pres) { diff --git a/src/gallium/drivers/asahi/agx_state.c b/src/gallium/drivers/asahi/agx_state.c index ca464c0acbd..394b01aa0a8 100644 --- a/src/gallium/drivers/asahi/agx_state.c +++ b/src/gallium/drivers/asahi/agx_state.c @@ -72,6 +72,16 @@ agx_set_shader_images(struct pipe_context *pctx, enum pipe_shader_type shader, continue; } + /* Images writeable with pixel granularity are incompatible with + * compression. Decompress if necessary. + */ + struct agx_resource *rsrc = agx_resource(image->resource); + if (rsrc->layout.tiling == AIL_TILING_TWIDDLED_COMPRESSED && + (image->shader_access & PIPE_IMAGE_ACCESS_WRITE)) { + + agx_decompress(ctx, rsrc, "Shader image"); + } + /* FIXME: Decompress here once we have texture compression */ util_copy_image_view(&ctx->stage[shader].images[start_slot + i], image); } diff --git a/src/gallium/drivers/asahi/agx_state.h b/src/gallium/drivers/asahi/agx_state.h index d612ff91ee0..80b9f7172e4 100644 --- a/src/gallium/drivers/asahi/agx_state.h +++ b/src/gallium/drivers/asahi/agx_state.h @@ -634,6 +634,9 @@ agx_map_texture_gpu(struct agx_resource *rsrc, unsigned z) (uint64_t)ail_get_layer_offset_B(&rsrc->layout, z); } +void agx_decompress(struct agx_context *ctx, struct agx_resource *rsrc, + const char *reason); + struct agx_transfer { struct pipe_transfer base; void *map;