[Mesa-dev] [PATCH 1/3] radeonsi: don't invoke DCC decompression in update_all_texture_descriptors

Edmondo Tommasina edmondo.tommasina at gmail.com
Mon Jan 30 16:26:07 UTC 2017


This patch fixes the bug uncovered.

Tested-by: Edmondo Tommasina <edmondo.tommasina at gmail.com>

Thanks
edmondo


On Mon, Jan 30, 2017 at 1:33 AM, Marek Olšák <maraeo at gmail.com> wrote:
> From: Marek Olšák <marek.olsak at amd.com>
>
> This fixes a bug uncovered by the 17-part patch series, specifically:
>   "gallium/radeon: merge dirty_fb_counter and dirty_tex_descriptor_counter"
>
> If dirty_tex_counter has been updated and set_shader_image invokes DCC
> decompression, the DCC decompression itself checks the counter and updates
> descriptors, which in turn invokes the same DCC decompression. The blitter
> can't handle the recursion and the driver eventually crashes.
>
> Cc: 17.0 <mesa-stable at lists.freedesktop.org>
> ---
>  src/gallium/drivers/radeonsi/si_descriptors.c | 11 ++++++-----
>  1 file changed, 6 insertions(+), 5 deletions(-)
>
> diff --git a/src/gallium/drivers/radeonsi/si_descriptors.c b/src/gallium/drivers/radeonsi/si_descriptors.c
> index 4a5407a..f0c0fc4 100644
> --- a/src/gallium/drivers/radeonsi/si_descriptors.c
> +++ b/src/gallium/drivers/radeonsi/si_descriptors.c
> @@ -653,21 +653,22 @@ si_mark_image_range_valid(const struct pipe_image_view *view)
>
>         assert(res && res->b.b.target == PIPE_BUFFER);
>
>         util_range_add(&res->valid_buffer_range,
>                        view->u.buf.offset,
>                        view->u.buf.offset + view->u.buf.size);
>  }
>
>  static void si_set_shader_image(struct si_context *ctx,
>                                 unsigned shader,
> -                               unsigned slot, const struct pipe_image_view *view)
> +                               unsigned slot, const struct pipe_image_view *view,
> +                               bool skip_decompress)
>  {
>         struct si_screen *screen = ctx->screen;
>         struct si_images_info *images = &ctx->images[shader];
>         struct si_descriptors *descs = si_image_descriptors(ctx, shader);
>         struct r600_resource *res;
>         uint32_t *desc = descs->list + slot * 8;
>
>         if (!view || !view->resource) {
>                 si_disable_shader_image(ctx, shader, slot);
>                 return;
> @@ -695,21 +696,21 @@ static void si_set_shader_image(struct si_context *ctx,
>                 static const unsigned char swizzle[4] = { 0, 1, 2, 3 };
>                 struct r600_texture *tex = (struct r600_texture *)res;
>                 unsigned level = view->u.tex.level;
>                 unsigned width, height, depth;
>                 bool uses_dcc = tex->dcc_offset &&
>                                 level < tex->surface.num_dcc_levels;
>
>                 assert(!tex->is_depth);
>                 assert(tex->fmask.size == 0);
>
> -               if (uses_dcc &&
> +               if (uses_dcc && !skip_decompress &&
>                     (view->access & PIPE_IMAGE_ACCESS_WRITE ||
>                      !vi_dcc_formats_compatible(res->b.b.format, view->format))) {
>                         /* If DCC can't be disabled, at least decompress it.
>                          * The decompression is relatively cheap if the surface
>                          * has been decompressed already.
>                          */
>                         if (r600_texture_disable_dcc(&ctx->b, tex))
>                                 uses_dcc = false;
>                         else
>                                 ctx->b.decompress_dcc(&ctx->b.b, tex);
> @@ -769,24 +770,24 @@ si_set_shader_images(struct pipe_context *pipe,
>
>         assert(shader < SI_NUM_SHADERS);
>
>         if (!count)
>                 return;
>
>         assert(start_slot + count <= SI_NUM_IMAGES);
>
>         if (views) {
>                 for (i = 0, slot = start_slot; i < count; ++i, ++slot)
> -                       si_set_shader_image(ctx, shader, slot, &views[i]);
> +                       si_set_shader_image(ctx, shader, slot, &views[i], false);
>         } else {
>                 for (i = 0, slot = start_slot; i < count; ++i, ++slot)
> -                       si_set_shader_image(ctx, shader, slot, NULL);
> +                       si_set_shader_image(ctx, shader, slot, NULL, false);
>         }
>
>         si_update_compressed_tex_shader_mask(ctx, shader);
>  }
>
>  static void
>  si_images_update_compressed_colortex_mask(struct si_images_info *images)
>  {
>         unsigned mask = images->enabled_mask;
>
> @@ -1706,21 +1707,21 @@ void si_update_all_texture_descriptors(struct si_context *sctx)
>                 /* Images. */
>                 mask = images->enabled_mask;
>                 while (mask) {
>                         unsigned i = u_bit_scan(&mask);
>                         struct pipe_image_view *view = &images->views[i];
>
>                         if (!view->resource ||
>                             view->resource->target == PIPE_BUFFER)
>                                 continue;
>
> -                       si_set_shader_image(sctx, shader, i, view);
> +                       si_set_shader_image(sctx, shader, i, view, true);
>                 }
>
>                 /* Sampler views. */
>                 mask = samplers->enabled_mask;
>                 while (mask) {
>                         unsigned i = u_bit_scan(&mask);
>                         struct pipe_sampler_view *view = samplers->views[i];
>
>                         if (!view ||
>                             !view->texture ||
> --
> 2.7.4
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/mesa-dev


More information about the mesa-dev mailing list