gallium/radeon: replace radeon_surf_info::dcc_enabled with num_dcc_levels
authorMarek Olšák <marek.olsak@amd.com>
Wed, 26 Oct 2016 15:43:19 +0000 (17:43 +0200)
committerMarek Olšák <marek.olsak@amd.com>
Tue, 1 Nov 2016 21:33:13 +0000 (22:33 +0100)
Reviewed-by: Nicolai Hähnle <nicolai.haehnle@amd.com>
src/gallium/drivers/radeon/r600_texture.c
src/gallium/drivers/radeon/radeon_winsys.h
src/gallium/drivers/radeonsi/si_blit.c
src/gallium/drivers/radeonsi/si_descriptors.c
src/gallium/drivers/radeonsi/si_state.c
src/gallium/winsys/amdgpu/drm/amdgpu_surface.c

index bc981da..46281cb 100644 (file)
@@ -73,8 +73,8 @@ bool r600_prepare_for_dma_blit(struct r600_common_context *rctx,
         *   src: Use the 3D path. DCC decompression is expensive.
         *   dst: Use the 3D path to compress the pixels with DCC.
         */
-       if ((rsrc->dcc_offset && rsrc->surface.level[src_level].dcc_enabled) ||
-           (rdst->dcc_offset && rdst->surface.level[dst_level].dcc_enabled))
+       if ((rsrc->dcc_offset && src_level < rsrc->surface.num_dcc_levels) ||
+           (rdst->dcc_offset && dst_level < rdst->surface.num_dcc_levels))
                return false;
 
        /* CMASK as:
@@ -940,7 +940,7 @@ void r600_print_texture_info(struct r600_texture *rtex, FILE *f)
                for (i = 0; i <= rtex->resource.b.b.last_level; i++)
                        fprintf(f, "  DCCLevel[%i]: enabled=%u, offset=%"PRIu64", "
                                "fast_clear_size=%"PRIu64"\n",
-                               i, rtex->surface.level[i].dcc_enabled,
+                               i, i < rtex->surface.num_dcc_levels,
                                rtex->surface.level[i].dcc_offset,
                                rtex->surface.level[i].dcc_fast_clear_size);
        }
@@ -1744,7 +1744,7 @@ void vi_dcc_disable_if_incompatible_format(struct r600_common_context *rctx,
        struct r600_texture *rtex = (struct r600_texture *)tex;
 
        if (rtex->dcc_offset &&
-           rtex->surface.level[level].dcc_enabled &&
+           level < rtex->surface.num_dcc_levels &&
            !vi_dcc_formats_compatible(tex->format, view_format))
                if (!r600_texture_disable_dcc(rctx, (struct r600_texture*)tex))
                        rctx->decompress_dcc(&rctx->b, rtex);
@@ -2096,7 +2096,7 @@ static void vi_separate_dcc_try_enable(struct r600_common_context *rctx,
        if (!vi_should_enable_separate_dcc(tex))
                return; /* stats show that DCC decompression is too expensive */
 
-       assert(tex->surface.level[0].dcc_enabled);
+       assert(tex->surface.num_dcc_levels);
        assert(!tex->dcc_separate_buffer);
 
        r600_texture_discard_cmask(rctx->screen, tex);
@@ -2311,7 +2311,7 @@ void vi_dcc_clear_level(struct r600_common_context *rctx,
        struct pipe_resource *dcc_buffer;
        uint64_t dcc_offset;
 
-       assert(rtex->dcc_offset && rtex->surface.level[level].dcc_enabled);
+       assert(rtex->dcc_offset && level < rtex->surface.num_dcc_levels);
 
        if (rtex->dcc_separate_buffer) {
                dcc_buffer = &rtex->dcc_separate_buffer->b.b;
@@ -2483,7 +2483,7 @@ void evergreen_do_fast_color_clear(struct r600_common_context *rctx,
                }
 
                /* Try to clear DCC first, otherwise try CMASK. */
-               if (tex->dcc_offset && tex->surface.level[0].dcc_enabled) {
+               if (tex->dcc_offset && tex->surface.num_dcc_levels) {
                        uint32_t reset_value;
                        bool clear_words_needed;
 
index 2330cdd..f5b9f10 100644 (file)
@@ -283,7 +283,6 @@ struct radeon_surf_level {
     uint16_t                    nblk_y;
     uint32_t                    pitch_bytes;
     enum radeon_surf_mode       mode;
-    bool                        dcc_enabled;
 };
 
 struct radeon_surf {
@@ -291,6 +290,11 @@ struct radeon_surf {
     unsigned                    blk_w:4;
     unsigned                    blk_h:4;
     unsigned                    bpe:5;
+    /* Number of mipmap levels where DCC is enabled starting from level 0.
+     * Non-zero levels may be disabled due to alignment constraints, but not
+     * the first level.
+     */
+    unsigned                    num_dcc_levels:4;
     uint32_t                    flags;
 
     /* These are return values. Some of them can be set by the caller, but
index db41f56..0f46d71 100644 (file)
@@ -429,7 +429,7 @@ static void si_blit_decompress_color(struct pipe_context *ctx,
                /* disable levels without DCC */
                for (int i = first_level; i <= last_level; i++) {
                        if (!rtex->dcc_offset ||
-                           !rtex->surface.level[i].dcc_enabled)
+                           i >= rtex->surface.num_dcc_levels)
                                level_mask &= ~(1 << i);
                }
        } else if (rtex->fmask.size) {
@@ -1029,7 +1029,7 @@ static bool do_hardware_msaa_resolve(struct pipe_context *ctx,
                 * This is still the fastest codepath even with this clear.
                 */
                if (dst->dcc_offset &&
-                   dst->surface.level[info->dst.level].dcc_enabled) {
+                   info->dst.level < dst->surface.num_dcc_levels) {
                        vi_dcc_clear_level(&sctx->b, dst, info->dst.level,
                                           0xFFFFFFFF);
                        dst->dirty_level_mask &= ~(1 << info->dst.level);
index 19cae65..9358542 100644 (file)
@@ -394,7 +394,7 @@ void si_set_mutable_tex_desc_fields(struct r600_texture *tex,
                                                             is_stencil));
        state[4] |= S_008F20_PITCH(pitch - 1);
 
-       if (tex->dcc_offset && tex->surface.level[first_level].dcc_enabled) {
+       if (tex->dcc_offset && first_level < tex->surface.num_dcc_levels) {
                state[6] |= S_008F28_COMPRESSION_EN(1);
                state[7] = ((!tex->dcc_separate_buffer ? tex->resource.gpu_address : 0) +
                            tex->dcc_offset +
@@ -669,7 +669,7 @@ static void si_set_shader_image(struct si_context *ctx,
                unsigned level = view->u.tex.level;
                unsigned width, height, depth;
                bool uses_dcc = tex->dcc_offset &&
-                               tex->surface.level[level].dcc_enabled;
+                               level < tex->surface.num_dcc_levels;
 
                assert(!tex->is_depth);
                assert(tex->fmask.size == 0);
index 0633b64..bf89d8b 100644 (file)
@@ -2500,7 +2500,7 @@ static void si_emit_framebuffer_state(struct si_context *sctx, struct r600_atom
 
                cb_color_info = cb->cb_color_info | tex->cb_color_info;
 
-               if (tex->dcc_offset && cb->level_info->dcc_enabled) {
+               if (tex->dcc_offset && cb->base.u.tex.level < tex->surface.num_dcc_levels) {
                        bool is_msaa_resolve_dst = state->cbufs[0] &&
                                                   state->cbufs[0]->texture->nr_samples > 1 &&
                                                   state->cbufs[1] == &cb->base &&
index 45edcc2..8c57287 100644 (file)
@@ -218,7 +218,6 @@ static int compute_level(struct amdgpu_winsys *ws,
 
    /* Clear DCC fields at the beginning. */
    surf_level->dcc_offset = 0;
-   surf_level->dcc_enabled = false;
 
    /* The previous level's flag tells us if we can use DCC for this level. */
    if (AddrSurfInfoIn->flags.dccCompatible &&
@@ -236,7 +235,7 @@ static int compute_level(struct amdgpu_winsys *ws,
       if (ret == ADDR_OK) {
          surf_level->dcc_offset = surf->dcc_size;
          surf_level->dcc_fast_clear_size = AddrDccOut->dccFastClearSize;
-         surf_level->dcc_enabled = true;
+         surf->num_dcc_levels = level + 1;
          surf->dcc_size = surf_level->dcc_offset + AddrDccOut->dccRamSize;
          surf->dcc_alignment = MAX2(surf->dcc_alignment, AddrDccOut->dccRamBaseAlign);
       }
@@ -488,6 +487,7 @@ static int amdgpu_surface_init(struct radeon_winsys *rws,
       }
    }
 
+   surf->num_dcc_levels = 0;
    surf->surf_size = 0;
    surf->dcc_size = 0;
    surf->dcc_alignment = 1;