diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_image.c b/src/gallium/drivers/freedreno/a6xx/fd6_image.c index 0059539d924..dc50b085aad 100644 --- a/src/gallium/drivers/freedreno/a6xx/fd6_image.c +++ b/src/gallium/drivers/freedreno/a6xx/fd6_image.c @@ -203,7 +203,26 @@ fd6_set_shader_images(struct pipe_context *pctx, enum pipe_shader_type shader, if (!buf->resource) continue; - fd6_validate_format(ctx, fd_resource(buf->resource), buf->format); + struct fd_resource *rsc = fd_resource(buf->resource); + + if (buf->shader_access & (PIPE_IMAGE_ACCESS_COHERENT | + PIPE_IMAGE_ACCESS_VOLATILE)) { + /* UBWC compression cannot be used with coherent/volatile access + * due to the extra caching (CCU) involved: + */ + if (rsc->layout.ubwc) { + bool linear = fd6_valid_tiling(rsc, buf->format); + + perf_debug_ctx(ctx, + "%" PRSC_FMT ": demoted to %suncompressed due to coherent/volatile use as %s", + PRSC_ARGS(&rsc->b.b), linear ? "linear+" : "", + util_format_short_name(buf->format)); + + fd_resource_uncompress(ctx, rsc, linear); + } + } else { + fd6_validate_format(ctx, rsc, buf->format); + } } } diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_resource.c b/src/gallium/drivers/freedreno/a6xx/fd6_resource.c index 34eab33a62e..24f87c2f424 100644 --- a/src/gallium/drivers/freedreno/a6xx/fd6_resource.c +++ b/src/gallium/drivers/freedreno/a6xx/fd6_resource.c @@ -160,6 +160,24 @@ is_r8g8(enum pipe_format format) (util_format_get_nr_components(format) == 2); } +/** + * Can a rsc be accessed tiled with the specified format, or does it need to + * be linearized? + */ +bool +fd6_valid_tiling(struct fd_resource *rsc, enum pipe_format format) +{ + enum pipe_format orig_format = rsc->b.b.format; + + if (orig_format == format) + return true; + + if (rsc->layout.tile_mode && (is_r8g8(orig_format) != is_r8g8(format))) + return false; + + return true; +} + /** * Ensure the rsc is in an ok state to be used with the specified format. * This handles the case of UBWC buffers used with non-UBWC compatible @@ -176,7 +194,7 @@ fd6_validate_format(struct fd_context *ctx, struct fd_resource *rsc, if (orig_format == format) return; - if (rsc->layout.tile_mode && (is_r8g8(orig_format) != is_r8g8(format))) { + if (!fd6_valid_tiling(rsc, format)) { perf_debug_ctx(ctx, "%" PRSC_FMT ": demoted to linear+uncompressed due to use as %s", PRSC_ARGS(&rsc->b.b), util_format_short_name(format)); diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_resource.h b/src/gallium/drivers/freedreno/a6xx/fd6_resource.h index e367f53895c..33d24ebce3d 100644 --- a/src/gallium/drivers/freedreno/a6xx/fd6_resource.h +++ b/src/gallium/drivers/freedreno/a6xx/fd6_resource.h @@ -30,6 +30,7 @@ #include "freedreno_resource.h" +bool fd6_valid_tiling(struct fd_resource *rsc, enum pipe_format format); void fd6_validate_format(struct fd_context *ctx, struct fd_resource *rsc, enum pipe_format format) assert_dt; void fd6_emit_flag_reference(struct fd_ringbuffer *ring,