radeonsi: allocate DCC in the same backing buffer as the texture
authorMarek Olšák <marek.olsak@amd.com>
Sun, 21 Feb 2016 21:49:38 +0000 (22:49 +0100)
committerMarek Olšák <marek.olsak@amd.com>
Wed, 9 Mar 2016 14:02:27 +0000 (15:02 +0100)
To allow sharing textures with DCC enabled.

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/cik_sdma.c
src/gallium/drivers/radeonsi/si_blit.c
src/gallium/drivers/radeonsi/si_descriptors.c
src/gallium/drivers/radeonsi/si_dma.c
src/gallium/drivers/radeonsi/si_pipe.h
src/gallium/drivers/radeonsi/si_state.c

index 7763ea307776b4733119f52b0fe1e38566725960..322139713706f44661f532d6cf70475d9756ed5b 100644 (file)
@@ -222,7 +222,7 @@ struct r600_texture {
        struct r600_fmask_info          fmask;
        struct r600_cmask_info          cmask;
        struct r600_resource            *cmask_buffer;
-       struct r600_resource            *dcc_buffer;
+       unsigned                        dcc_offset; /* 0 = disabled */
        unsigned                        cb_color_info; /* fast clear enable bit */
        unsigned                        color_clear_value[2];
 
index 65b17a01dc3ce685cfc268213e073dfa7b1346cb..1fff33ef5b524a6a5012f09816d4f139bfbe3296 100644 (file)
@@ -346,7 +346,6 @@ static void r600_texture_destroy(struct pipe_screen *screen,
        if (rtex->cmask_buffer != &rtex->resource) {
            pipe_resource_reference((struct pipe_resource**)&rtex->cmask_buffer, NULL);
        }
-       pipe_resource_reference((struct pipe_resource**)&rtex->dcc_buffer, NULL);
        pb_reference(&resource->buf, NULL);
        FREE(rtex);
 }
@@ -569,25 +568,6 @@ static void r600_texture_alloc_cmask_separate(struct r600_common_screen *rscreen
                rtex->cb_color_info |= EG_S_028C70_FAST_CLEAR(1);
 }
 
-static void vi_texture_alloc_dcc_separate(struct r600_common_screen *rscreen,
-                                             struct r600_texture *rtex)
-{
-       if (rscreen->debug_flags & DBG_NO_DCC)
-               return;
-
-       rtex->dcc_buffer = (struct r600_resource *)
-               r600_aligned_buffer_create(&rscreen->b, PIPE_BIND_CUSTOM,
-                                  PIPE_USAGE_DEFAULT, rtex->surface.dcc_size, rtex->surface.dcc_alignment);
-       if (rtex->dcc_buffer == NULL) {
-               return;
-       }
-
-       r600_screen_clear_buffer(rscreen, &rtex->dcc_buffer->b.b, 0, rtex->surface.dcc_size,
-                                0xFFFFFFFF, true);
-
-       rtex->cb_color_info |= VI_S_028C70_DCC_ENABLE(1);
-}
-
 static unsigned r600_texture_get_htile_size(struct r600_common_screen *rscreen,
                                            struct r600_texture *rtex)
 {
@@ -722,10 +702,10 @@ void r600_print_texture_info(struct r600_texture *rtex, FILE *f)
                        rtex->htile_buffer->buf->alignment, rtex->htile.pitch,
                        rtex->htile.height, rtex->htile.xalign, rtex->htile.yalign);
 
-       if (rtex->dcc_buffer) {
-               fprintf(f, "  DCC: size=%u, alignment=%u\n",
-                       rtex->dcc_buffer->b.b.width0,
-                       rtex->dcc_buffer->buf->alignment);
+       if (rtex->dcc_offset) {
+               fprintf(f, "  DCC: offset=%u, size=%"PRIu64", alignment=%"PRIu64"\n",
+                       rtex->dcc_offset, rtex->surface.dcc_size,
+                       rtex->surface.dcc_alignment);
                for (i = 0; i <= rtex->surface.last_level; i++)
                        fprintf(f, "  DCCLevel[%i]: offset=%"PRIu64"\n",
                                i, rtex->surface.level[i].dcc_offset);
@@ -823,8 +803,14 @@ r600_texture_create_object(struct pipe_screen *screen,
                                return NULL;
                        }
                }
-               if (rtex->surface.dcc_size)
-                       vi_texture_alloc_dcc_separate(rscreen, rtex);
+
+               if (!buf && rtex->surface.dcc_size &&
+                   !(rscreen->debug_flags & DBG_NO_DCC)) {
+                       /* Reserve space for the DCC buffer. */
+                       rtex->dcc_offset = align(rtex->size, rtex->surface.dcc_alignment);
+                       rtex->size = rtex->dcc_offset + rtex->surface.dcc_size;
+                       rtex->cb_color_info |= VI_S_028C70_DCC_ENABLE(1);
+               }
        }
 
        /* Now create the backing buffer. */
@@ -846,6 +832,12 @@ r600_texture_create_object(struct pipe_screen *screen,
                                         rtex->cmask.offset, rtex->cmask.size,
                                         0xCCCCCCCC, true);
        }
+       if (rtex->dcc_offset) {
+               r600_screen_clear_buffer(rscreen, &rtex->resource.b.b,
+                                        rtex->dcc_offset,
+                                        rtex->surface.dcc_size,
+                                        0xFFFFFFFF, true);
+       }
 
        /* Initialize the CMASK base register value. */
        rtex->cmask.base_address_reg =
@@ -1553,7 +1545,7 @@ void evergreen_do_fast_color_clear(struct r600_common_context *rctx,
                        continue;
                }
 
-               if (tex->dcc_buffer) {
+               if (tex->dcc_offset) {
                        uint32_t reset_value;
                        bool clear_words_needed;
 
@@ -1562,8 +1554,9 @@ void evergreen_do_fast_color_clear(struct r600_common_context *rctx,
 
                        vi_get_fast_clear_parameters(fb->cbufs[i]->format, color, &reset_value, &clear_words_needed);
 
-                       rctx->clear_buffer(&rctx->b, &tex->dcc_buffer->b.b,
-                                       0, tex->surface.dcc_size, reset_value, true);
+                       rctx->clear_buffer(&rctx->b, &tex->resource.b.b,
+                                          tex->dcc_offset, tex->surface.dcc_size,
+                                          reset_value, true);
 
                        if (clear_words_needed)
                                tex->dirty_level_mask |= 1 << fb->cbufs[i]->u.tex.level;
index 76913914b3877ba4449d2e38f81deb19a6656403..6eb62dcc8903195e53e66597e7bfc6cb13d0951a 100644 (file)
@@ -243,7 +243,7 @@ void cik_sdma_copy(struct pipe_context *ctx,
        if (src->format != dst->format ||
            rdst->surface.nsamples > 1 || rsrc->surface.nsamples > 1 ||
            (rdst->dirty_level_mask | rdst->stencil_dirty_level_mask) & (1 << dst_level) ||
-           rdst->dcc_buffer || rsrc->dcc_buffer) {
+           rdst->dcc_offset || rsrc->dcc_offset) {
                goto fallback;
        }
 
index 53c67055a5ec78646509f9e18bd42456d2b7a27d..60b9f7b6a708827df9ff03b091a8e07a88053003 100644 (file)
@@ -330,7 +330,7 @@ void si_decompress_color_textures(struct si_context *sctx,
                assert(view);
 
                tex = (struct r600_texture *)view->texture;
-               assert(tex->cmask.size || tex->fmask.size || tex->dcc_buffer);
+               assert(tex->cmask.size || tex->fmask.size || tex->dcc_offset);
 
                si_blit_decompress_color(&sctx->b.b, tex,
                                         view->u.tex.first_level, view->u.tex.last_level,
@@ -483,7 +483,7 @@ static void si_decompress_subresource(struct pipe_context *ctx,
                        si_blit_decompress_depth_in_place(sctx, rtex, true,
                                                          level, level,
                                                          first_layer, last_layer);
-       } else if (rtex->fmask.size || rtex->cmask.size || rtex->dcc_buffer) {
+       } else if (rtex->fmask.size || rtex->cmask.size || rtex->dcc_offset) {
                si_blit_decompress_color(ctx, rtex, level, level,
                                         first_layer, last_layer);
        }
@@ -712,7 +712,7 @@ static bool do_hardware_msaa_resolve(struct pipe_context *ctx,
            dst->surface.level[info->dst.level].mode >= RADEON_SURF_MODE_1D &&
            !(dst->surface.flags & RADEON_SURF_SCANOUT) &&
            (!dst->cmask.size || !dst->dirty_level_mask) && /* dst cannot be fast-cleared */
-           !dst->dcc_buffer) {
+           !dst->dcc_offset) {
                si_blitter_begin(ctx, SI_COLOR_RESOLVE |
                                 (info->render_condition_enable ? 0 : SI_DISABLE_RENDER_COND));
                util_blitter_custom_resolve_color(sctx->blitter,
@@ -761,7 +761,7 @@ static void si_flush_resource(struct pipe_context *ctx,
 
        assert(res->target != PIPE_BUFFER);
 
-       if (!rtex->is_depth && (rtex->cmask.size || rtex->dcc_buffer)) {
+       if (!rtex->is_depth && (rtex->cmask.size || rtex->dcc_offset)) {
                si_blit_decompress_color(ctx, rtex, 0, res->last_level,
                                         0, util_max_layer(res, 0));
        }
index 345f2bbc3814d9817a46aa1810bbedbead844701..ba4a770079c3bbbff6c5770ba9cf16c13d9945f0 100644 (file)
@@ -158,12 +158,6 @@ static void si_sampler_view_add_buffers(struct si_context *sctx,
                        rview->resource, RADEON_USAGE_READ,
                        r600_get_sampler_view_priority(rview->resource));
        }
-
-       if (rview->dcc_buffer && rview->dcc_buffer != rview->resource) {
-               radeon_add_to_buffer_list(&sctx->b, &sctx->b.gfx,
-                       rview->dcc_buffer, RADEON_USAGE_READ,
-                       RADEON_PRIO_DCC);
-       }
 }
 
 static void si_sampler_views_begin_new_cs(struct si_context *sctx,
@@ -263,7 +257,7 @@ static void si_set_sampler_views(struct pipe_context *ctx,
                                samplers->depth_texture_mask &= ~(1 << slot);
                        }
                        if (rtex->cmask.size || rtex->fmask.size ||
-                           (rtex->dcc_buffer && rtex->dirty_level_mask)) {
+                           (rtex->dcc_offset && rtex->dirty_level_mask)) {
                                samplers->compressed_colortex_mask |= 1 << slot;
                        } else {
                                samplers->compressed_colortex_mask &= ~(1 << slot);
index 240d96190a9c1daa1dc4f3f5f88b7b354cb6d5b5..0efca19395168fb7bdd3afa797d2fe34fc902605 100644 (file)
@@ -249,7 +249,7 @@ void si_dma_copy(struct pipe_context *ctx,
            (rdst->dirty_level_mask | rdst->stencil_dirty_level_mask) & (1 << dst_level) ||
            rdst->cmask.size || rdst->fmask.size ||
            rsrc->cmask.size || rsrc->fmask.size ||
-           rdst->dcc_buffer || rsrc->dcc_buffer) {
+           rdst->dcc_offset || rsrc->dcc_offset) {
                goto fallback;
        }
 
index ef860a58b836de82e3c5b490896f5355e38a2a87..e6f92a31f9682095608ad02c58d770e8ec02b4bd 100644 (file)
@@ -121,7 +121,6 @@ struct si_sampler_view {
        struct pipe_sampler_view        base;
        struct list_head                list;
        struct r600_resource            *resource;
-       struct r600_resource            *dcc_buffer;
         /* [0..7] = image descriptor
          * [4..7] = buffer descriptor */
        uint32_t                        state[8];
index 15732a6c25414364efd9109f458bbb443fa7f05e..08a6505b0b3e699297db01a9ee6c02c312f05879 100644 (file)
@@ -2318,9 +2318,8 @@ static void si_initialize_color_surface(struct si_context *sctx,
        surf->cb_color_info = color_info;
        surf->cb_color_attrib = color_attrib;
 
-       if (sctx->b.chip_class >= VI && rtex->dcc_buffer) {
+       if (sctx->b.chip_class >= VI && rtex->dcc_offset) {
                unsigned max_uncompressed_block_size = 2;
-               uint64_t dcc_offset = rtex->surface.level[level].dcc_offset;
 
                if (rtex->surface.nsamples > 1) {
                        if (rtex->surface.bpe == 1)
@@ -2331,7 +2330,9 @@ static void si_initialize_color_surface(struct si_context *sctx,
 
                surf->cb_dcc_control = S_028C78_MAX_UNCOMPRESSED_BLOCK_SIZE(max_uncompressed_block_size) |
                                       S_028C78_INDEPENDENT_64B_BLOCKS(1);
-               surf->cb_dcc_base = (rtex->dcc_buffer->gpu_address + dcc_offset) >> 8;
+               surf->cb_dcc_base = (rtex->resource.gpu_address +
+                                    rtex->dcc_offset +
+                                    rtex->surface.level[level].dcc_offset) >> 8;
        }
 
        if (rtex->fmask.size) {
@@ -2670,12 +2671,6 @@ static void si_emit_framebuffer_state(struct si_context *sctx, struct r600_atom
                                RADEON_PRIO_CMASK);
                }
 
-               if (tex->dcc_buffer && tex->dcc_buffer != &tex->resource) {
-                       radeon_add_to_buffer_list(&sctx->b, &sctx->b.gfx,
-                               tex->dcc_buffer, RADEON_USAGE_READWRITE,
-                               RADEON_PRIO_DCC);
-               }
-
                radeon_set_context_reg_seq(cs, R_028C60_CB_COLOR0_BASE + i * 0x3C,
                                           sctx->b.chip_class >= VI ? 14 : 13);
                radeon_emit(cs, cb->cb_color_base);     /* R_028C60_CB_COLOR0_BASE */
@@ -3069,13 +3064,13 @@ si_create_sampler_view_custom(struct pipe_context *ctx,
        view->state[5] = (S_008F24_BASE_ARRAY(state->u.tex.first_layer) |
                          S_008F24_LAST_ARRAY(last_layer));
 
-       if (tmp->dcc_buffer) {
-               uint64_t dcc_offset = surflevel[base_level].dcc_offset;
+       if (tmp->dcc_offset) {
                unsigned swap = r600_translate_colorswap(pipe_format);
 
                view->state[6] = S_008F28_COMPRESSION_EN(1) | S_008F28_ALPHA_IS_ON_MSB(swap <= 1);
-               view->state[7] = (tmp->dcc_buffer->gpu_address + dcc_offset) >> 8;
-               view->dcc_buffer = tmp->dcc_buffer;
+               view->state[7] = (tmp->resource.gpu_address +
+                                 tmp->dcc_offset +
+                                 surflevel[base_level].dcc_offset) >> 8;
        } else {
                view->state[6] = 0;
                view->state[7] = 0;