radeonsi: remove r600_pipe_common::decompress_dcc
[mesa.git] / src / gallium / drivers / radeon / r600_texture.c
index 2aa47b55d592bacd78485e35c295b5ccef3592d8..86955561e242bc4398d509e95a236c5ad837f3e8 100644 (file)
@@ -36,8 +36,6 @@
 #include "state_tracker/drm_driver.h"
 #include "amd/common/sid.h"
 
-static void r600_texture_discard_cmask(struct si_screen *sscreen,
-                                      struct r600_texture *rtex);
 static enum radeon_surf_mode
 r600_choose_tiling(struct si_screen *sscreen,
                   const struct pipe_resource *templ);
@@ -90,7 +88,7 @@ bool si_prepare_for_dma_blit(struct r600_common_context *rctx,
                                                      src_box->height, src_box->depth))
                        return false;
 
-               r600_texture_discard_cmask(rctx->screen, rdst);
+               si_texture_discard_cmask(rctx->screen, rdst);
        }
 
        /* All requirements are met. Prepare textures for SDMA. */
@@ -242,7 +240,7 @@ static int r600_init_surface(struct si_screen *sscreen,
                bpe = 4; /* stencil is allocated separately on evergreen */
        } else {
                bpe = util_format_get_blocksize(ptex->format);
-               assert(util_is_power_of_two(bpe));
+               assert(util_is_power_of_two_or_zero(bpe));
        }
 
        if (!is_flushed_depth && is_depth) {
@@ -298,11 +296,21 @@ static int r600_init_surface(struct si_screen *sscreen,
                return r;
        }
 
+       unsigned pitch = pitch_in_bytes_override / bpe;
+
        if (sscreen->info.chip_class >= GFX9) {
-               assert(!pitch_in_bytes_override ||
-                      pitch_in_bytes_override == surface->u.gfx9.surf_pitch * bpe);
+               if (pitch) {
+                       surface->u.gfx9.surf_pitch = pitch;
+                       surface->u.gfx9.surf_slice_size =
+                               (uint64_t)pitch * surface->u.gfx9.surf_height * bpe;
+               }
                surface->u.gfx9.surf_offset = offset;
        } else {
+               if (pitch) {
+                       surface->u.legacy.level[0].nblk_x = pitch;
+                       surface->u.legacy.level[0].slice_size_dw =
+                               ((uint64_t)pitch * surface->u.legacy.level[0].nblk_y * bpe) / 4;
+               }
                if (offset) {
                        for (i = 0; i < ARRAY_SIZE(surface->u.legacy.level); ++i)
                                surface->u.legacy.level[i].offset += offset;
@@ -372,8 +380,8 @@ static void r600_surface_import_metadata(struct si_screen *sscreen,
        }
 }
 
-static void r600_eliminate_fast_color_clear(struct r600_common_context *rctx,
-                                           struct r600_texture *rtex)
+void si_eliminate_fast_color_clear(struct r600_common_context *rctx,
+                                  struct r600_texture *rtex)
 {
        struct si_screen *sscreen = rctx->screen;
        struct pipe_context *ctx = &rctx->b;
@@ -381,15 +389,19 @@ static void r600_eliminate_fast_color_clear(struct r600_common_context *rctx,
        if (ctx == sscreen->aux_context)
                mtx_lock(&sscreen->aux_context_lock);
 
+       unsigned n = rctx->num_decompress_calls;
        ctx->flush_resource(ctx, &rtex->resource.b.b);
-       ctx->flush(ctx, NULL, 0);
+
+       /* Flush only if any fast clear elimination took place. */
+       if (n != rctx->num_decompress_calls)
+               ctx->flush(ctx, NULL, 0);
 
        if (ctx == sscreen->aux_context)
                mtx_unlock(&sscreen->aux_context_lock);
 }
 
-static void r600_texture_discard_cmask(struct si_screen *sscreen,
-                                      struct r600_texture *rtex)
+void si_texture_discard_cmask(struct si_screen *sscreen,
+                             struct r600_texture *rtex)
 {
        if (!rtex->cmask.size)
                return;
@@ -468,7 +480,7 @@ bool si_texture_disable_dcc(struct r600_common_context *rctx,
                mtx_lock(&sscreen->aux_context_lock);
 
        /* Decompress DCC. */
-       rctx->decompress_dcc(&rctx->b, rtex);
+       si_decompress_dcc(&rctx->b, rtex);
        rctx->b.flush(&rctx->b, NULL, 0);
 
        if (&rctx->b == sscreen->aux_context)
@@ -513,7 +525,7 @@ static void r600_reallocate_texture_inplace(struct r600_common_context *rctx,
 
                        u_box_3d(0, 0, 0,
                                 u_minify(templ.width0, i), u_minify(templ.height0, i),
-                                util_max_layer(&templ, i) + 1, &box);
+                                util_num_layers(&templ, i), &box);
 
                        rctx->dma_copy(&rctx->b, &new_tex->resource.b.b, i, 0, 0, 0,
                                       &rtex->resource.b.b, i, &box);
@@ -521,7 +533,7 @@ static void r600_reallocate_texture_inplace(struct r600_common_context *rctx,
        }
 
        if (new_bind_flag == PIPE_BIND_LINEAR) {
-               r600_texture_discard_cmask(rctx->screen, rtex);
+               si_texture_discard_cmask(rctx->screen, rtex);
                r600_texture_discard_dcc(rctx->screen, rtex);
        }
 
@@ -582,7 +594,7 @@ static void si_query_opaque_metadata(struct si_screen *sscreen,
                PIPE_SWIZZLE_W
        };
        uint32_t desc[8], i;
-       bool is_array = util_resource_is_array_texture(res);
+       bool is_array = util_texture_is_array(res->target);
 
        /* DRM 2.x.x doesn't support this. */
        if (sscreen->info.drm_major != 3)
@@ -689,6 +701,7 @@ static boolean r600_texture_get_handle(struct pipe_screen* screen,
                if (sscreen->ws->buffer_is_suballocated(res->buf) ||
                    rtex->surface.tile_swizzle ||
                    (rtex->resource.flags & RADEON_FLAG_NO_INTERPROCESS_SHARING &&
+                    sscreen->info.has_local_buffers &&
                     whandle->type != DRM_API_HANDLE_TYPE_KMS)) {
                        assert(!res->b.is_shared);
                        r600_reallocate_texture_inplace(rctx, rtex,
@@ -715,7 +728,7 @@ static boolean r600_texture_get_handle(struct pipe_screen* screen,
                if (!(usage & PIPE_HANDLE_USAGE_EXPLICIT_FLUSH) &&
                    (rtex->cmask.size || rtex->dcc_offset)) {
                        /* Eliminate fast clear (both CMASK and DCC) */
-                       r600_eliminate_fast_color_clear(rctx, rtex);
+                       si_eliminate_fast_color_clear(rctx, rtex);
                        /* eliminate_fast_color_clear flushes the context */
                        flush = false;
 
@@ -723,7 +736,7 @@ static boolean r600_texture_get_handle(struct pipe_screen* screen,
                         * to be called.
                         */
                        if (rtex->cmask.size)
-                               r600_texture_discard_cmask(sscreen, rtex);
+                               si_texture_discard_cmask(sscreen, rtex);
                }
 
                /* Set metadata. */
@@ -746,8 +759,12 @@ static boolean r600_texture_get_handle(struct pipe_screen* screen,
                        slice_size = (uint64_t)rtex->surface.u.legacy.level[0].slice_size_dw * 4;
                }
        } else {
+               /* Buffer exports are for the OpenCL interop. */
                /* Move a suballocated buffer into a non-suballocated allocation. */
-               if (sscreen->ws->buffer_is_suballocated(res->buf)) {
+               if (sscreen->ws->buffer_is_suballocated(res->buf) ||
+                   /* A DMABUF export always fails if the BO is local. */
+                   (rtex->resource.flags & RADEON_FLAG_NO_INTERPROCESS_SHARING &&
+                    sscreen->info.has_local_buffers)) {
                        assert(!res->b.is_shared);
 
                        /* Allocate a new buffer with PIPE_BIND_SHARED. */
@@ -833,6 +850,7 @@ void si_texture_get_fmask_info(struct si_screen *sscreen,
        if (sscreen->info.chip_class >= GFX9) {
                out->alignment = rtex->surface.u.gfx9.fmask_alignment;
                out->size = rtex->surface.u.gfx9.fmask_size;
+               out->tile_swizzle = rtex->surface.u.gfx9.fmask_tile_swizzle;
                return;
        }
 
@@ -932,7 +950,7 @@ void si_texture_get_cmask_info(struct si_screen *sscreen,
                out->slice_tile_max -= 1;
 
        out->alignment = MAX2(256, base_align);
-       out->size = (util_max_layer(&rtex->resource.b.b, 0) + 1) *
+       out->size = util_num_layers(&rtex->resource.b.b, 0) *
                    align(slice_bytes, base_align);
 }
 
@@ -1011,7 +1029,7 @@ static void r600_texture_get_htile_size(struct si_screen *sscreen,
 
        rtex->surface.htile_alignment = base_align;
        rtex->surface.htile_size =
-               (util_max_layer(&rtex->resource.b.b, 0) + 1) *
+               util_num_layers(&rtex->resource.b.b, 0) *
                align(slice_bytes, base_align);
 }
 
@@ -1250,12 +1268,13 @@ r600_texture_create_object(struct pipe_screen *screen,
                                r600_texture_allocate_htile(sscreen, rtex);
                }
        } else {
-               if (base->nr_samples > 1) {
-                       if (!buf) {
-                               r600_texture_allocate_fmask(sscreen, rtex);
-                               r600_texture_allocate_cmask(sscreen, rtex);
-                               rtex->cmask_buffer = &rtex->resource;
-                       }
+               if (base->nr_samples > 1 &&
+                   !buf &&
+                   !(sscreen->debug_flags & DBG(NO_FMASK))) {
+                       r600_texture_allocate_fmask(sscreen, rtex);
+                       r600_texture_allocate_cmask(sscreen, rtex);
+                       rtex->cmask_buffer = &rtex->resource;
+
                        if (!rtex->fmask.size || !rtex->cmask.size) {
                                FREE(rtex);
                                return NULL;
@@ -1330,7 +1349,7 @@ r600_texture_create_object(struct pipe_screen *screen,
                fprintf(stderr, "VM start=0x%"PRIX64"  end=0x%"PRIX64" | Texture %ix%ix%i, %i levels, %i samples, %s\n",
                        rtex->resource.gpu_address,
                        rtex->resource.gpu_address + rtex->resource.buf->size,
-                       base->width0, base->height0, util_max_layer(base, 0)+1, base->last_level+1,
+                       base->width0, base->height0, util_num_layers(base, 0), base->last_level+1,
                        base->nr_samples ? base->nr_samples : 1, util_format_short_name(base->format));
        }
 
@@ -1844,7 +1863,7 @@ static void r600_texture_transfer_unmap(struct pipe_context *ctx,
         * The result is that the kernel memory manager is never a bottleneck.
         */
        if (rctx->num_alloc_tex_transfer_bytes > rctx->screen->info.gart_size / 4) {
-               rctx->gfx.flush(rctx, PIPE_FLUSH_ASYNC, NULL);
+               si_flush_gfx_cs(rctx, PIPE_FLUSH_ASYNC, NULL);
                rctx->num_alloc_tex_transfer_bytes = 0;
        }
 
@@ -1864,15 +1883,12 @@ static const struct u_resource_vtbl r600_texture_vtbl =
 /* DCC channel type categories within which formats can be reinterpreted
  * while keeping the same DCC encoding. The swizzle must also match. */
 enum dcc_channel_type {
-       dcc_channel_float32,
-       dcc_channel_uint32,
-       dcc_channel_sint32,
-       dcc_channel_float16,
-       dcc_channel_uint16,
-       dcc_channel_sint16,
+       dcc_channel_float,
+       /* uint and sint can be merged if we never use TC-compatible DCC clear
+        * encoding with the clear value of 1. */
+       dcc_channel_uint,
+       dcc_channel_sint,
        dcc_channel_uint_10_10_10_2,
-       dcc_channel_uint8,
-       dcc_channel_sint8,
        dcc_channel_incompatible,
 };
 
@@ -1891,23 +1907,15 @@ vi_get_dcc_channel_type(const struct util_format_description *desc)
 
        switch (desc->channel[i].size) {
        case 32:
-               if (desc->channel[i].type == UTIL_FORMAT_TYPE_FLOAT)
-                       return dcc_channel_float32;
-               if (desc->channel[i].type == UTIL_FORMAT_TYPE_UNSIGNED)
-                       return dcc_channel_uint32;
-               return dcc_channel_sint32;
        case 16:
+       case 8:
                if (desc->channel[i].type == UTIL_FORMAT_TYPE_FLOAT)
-                       return dcc_channel_float16;
+                       return dcc_channel_float;
                if (desc->channel[i].type == UTIL_FORMAT_TYPE_UNSIGNED)
-                       return dcc_channel_uint16;
-               return dcc_channel_sint16;
+                       return dcc_channel_uint;
+               return dcc_channel_sint;
        case 10:
                return dcc_channel_uint_10_10_10_2;
-       case 8:
-               if (desc->channel[i].type == UTIL_FORMAT_TYPE_UNSIGNED)
-                       return dcc_channel_uint8;
-               return dcc_channel_sint8;
        default:
                return dcc_channel_incompatible;
        }
@@ -1966,7 +1974,7 @@ void vi_disable_dcc_if_incompatible_format(struct r600_common_context *rctx,
 
        if (vi_dcc_formats_are_incompatible(tex, level, view_format))
                if (!si_texture_disable_dcc(rctx, (struct r600_texture*)tex))
-                       rctx->decompress_dcc(&rctx->b, rtex);
+                       si_decompress_dcc(&rctx->b, rtex);
 }
 
 struct pipe_surface *si_create_surface_custom(struct pipe_context *pipe,
@@ -2257,7 +2265,7 @@ void vi_separate_dcc_try_enable(struct r600_common_context *rctx,
        assert(tex->surface.num_dcc_levels);
        assert(!tex->dcc_separate_buffer);
 
-       r600_texture_discard_cmask(rctx->screen, tex);
+       si_texture_discard_cmask(rctx->screen, tex);
 
        /* Get a DCC buffer. */
        if (tex->last_dcc_separate_buffer) {