radeonsi: disable DCC on handle export if expecting write access
authorMarek Olšák <marek.olsak@amd.com>
Wed, 24 Feb 2016 21:04:47 +0000 (22:04 +0100)
committerMarek Olšák <marek.olsak@amd.com>
Wed, 9 Mar 2016 14:02:27 +0000 (15:02 +0100)
This should be okay except that sampler views and images are not re-set.

Reviewed-by: Michel Dänzer <michel.daenzer@amd.com>
Reviewed-by: Nicolai Hähnle <nicolai.haehnle@amd.com>
src/gallium/drivers/radeon/r600_pipe_common.h
src/gallium/drivers/radeon/r600_texture.c
src/gallium/drivers/radeonsi/si_blit.c

index 322139713706f44661f532d6cf70475d9756ed5b..31ec24de9a26518199e2654e209f9410a0ac0872 100644 (file)
@@ -476,6 +476,9 @@ struct r600_common_context {
                                      unsigned first_layer, unsigned last_layer,
                                      unsigned first_sample, unsigned last_sample);
 
+       void (*decompress_dcc)(struct pipe_context *ctx,
+                              struct r600_texture *rtex);
+
        /* Reallocate the buffer and update all resource bindings where
         * the buffer is bound, including all resource descriptors. */
        void (*invalidate_buffer)(struct pipe_context *ctx, struct pipe_resource *buf);
index 1fff33ef5b524a6a5012f09816d4f139bfbe3296..b8c4c795b3cab4318458c4f32dddfae4dbdfa985 100644 (file)
@@ -289,6 +289,31 @@ static void r600_texture_disable_cmask(struct r600_common_screen *rscreen,
        r600_dirty_all_framebuffer_states(rscreen);
 }
 
+static void r600_texture_disable_dcc(struct r600_common_screen *rscreen,
+                                    struct r600_texture *rtex)
+{
+       struct r600_common_context *rctx =
+               (struct r600_common_context *)rscreen->aux_context;
+
+       if (!rtex->dcc_offset)
+               return;
+
+       /* Decompress DCC. */
+       pipe_mutex_lock(rscreen->aux_context_lock);
+       rctx->decompress_dcc(&rctx->b, rtex);
+       rctx->b.flush(&rctx->b, NULL, 0);
+       pipe_mutex_unlock(rscreen->aux_context_lock);
+
+       /* Disable DCC. */
+       rtex->dcc_offset = 0;
+       rtex->cb_color_info &= ~VI_S_028C70_DCC_ENABLE(1);
+
+       /* Notify all contexts about the change. */
+       r600_dirty_all_framebuffer_states(rscreen);
+
+       /* TODO: re-set all sampler views and images, but how? */
+}
+
 static boolean r600_texture_get_handle(struct pipe_screen* screen,
                                       struct pipe_resource *resource,
                                       struct winsys_handle *whandle,
@@ -311,6 +336,13 @@ static boolean r600_texture_get_handle(struct pipe_screen* screen,
                res->external_usage = usage;
 
                if (resource->target != PIPE_BUFFER) {
+                       /* Since shader image stores don't support DCC on VI,
+                        * disable it for external clients that want write
+                        * access.
+                        */
+                       if (usage & PIPE_HANDLE_USAGE_WRITE)
+                               r600_texture_disable_dcc(rscreen, rtex);
+
                        if (!(usage & PIPE_HANDLE_USAGE_EXPLICIT_FLUSH)) {
                                /* Eliminate fast clear (both CMASK and DCC) */
                                r600_eliminate_fast_color_clear(rscreen, rtex);
@@ -321,6 +353,7 @@ static boolean r600_texture_get_handle(struct pipe_screen* screen,
                                r600_texture_disable_cmask(rscreen, rtex);
                        }
 
+                       /* Set metadata. */
                        r600_texture_init_metadata(rtex, &metadata);
                        rscreen->ws->buffer_set_metadata(res->buf, &metadata);
                }
index 198f57d542fd6e0e8ca484f262c8579726f0d5dd..d9c4f8fca1d1076da207bd694dfe562cd8340345 100644 (file)
@@ -777,6 +777,17 @@ static void si_flush_resource(struct pipe_context *ctx,
        }
 }
 
+static void si_decompress_dcc(struct pipe_context *ctx,
+                             struct r600_texture *rtex)
+{
+       if (!rtex->dcc_offset)
+               return;
+
+       si_blit_decompress_color(ctx, rtex, 0, rtex->resource.b.b.last_level,
+                                0, util_max_layer(&rtex->resource.b.b, 0),
+                                true);
+}
+
 static void si_pipe_clear_buffer(struct pipe_context *ctx,
                                 struct pipe_resource *dst,
                                 unsigned offset, unsigned size,
@@ -846,4 +857,5 @@ void si_init_blit_functions(struct si_context *sctx)
        sctx->b.b.blit = si_blit;
        sctx->b.b.flush_resource = si_flush_resource;
        sctx->b.blit_decompress_depth = si_blit_decompress_depth;
+       sctx->b.decompress_dcc = si_decompress_dcc;
 }