radeonsi: remove tabs
[mesa.git] / src / gallium / drivers / radeonsi / si_texture.c
index d84261d48e12a058d1cab63bd58a7af05e591c98..875341bf06e8a4ae5bf1dae942224a7694a52a43 100644 (file)
@@ -27,7 +27,7 @@
 #include "si_pipe.h"
 #include "si_query.h"
 #include "sid.h"
-#include "state_tracker/drm_driver.h"
+#include "frontend/drm_driver.h"
 #include "util/format/u_format.h"
 #include "util/os_time.h"
 #include "util/u_log.h"
@@ -74,6 +74,13 @@ bool si_prepare_for_dma_blit(struct si_context *sctx, struct si_texture *dst, un
    if (vi_dcc_enabled(src, src_level) || vi_dcc_enabled(dst, dst_level))
       return false;
 
+   /* TMZ: mixing encrypted and non-encrypted buffer in a single command
+    * doesn't seem supported.
+    */
+   if ((src->buffer.flags & RADEON_FLAG_ENCRYPTED) !=
+       (dst->buffer.flags & RADEON_FLAG_ENCRYPTED))
+      return false;
+
    /* CMASK as:
     *   src: Both texture and SDMA paths need decompression. Use SDMA.
     *   dst: If overwriting the whole texture, discard CMASK and use
@@ -250,7 +257,9 @@ static int si_init_surface(struct si_screen *sscreen, struct radeon_surf *surfac
    }
 
    if (sscreen->info.chip_class >= GFX8 &&
-       (ptex->flags & SI_RESOURCE_FLAG_DISABLE_DCC || ptex->format == PIPE_FORMAT_R9G9B9E5_FLOAT ||
+       (ptex->flags & SI_RESOURCE_FLAG_DISABLE_DCC ||
+        (sscreen->info.chip_class < GFX10_3 &&
+         ptex->format == PIPE_FORMAT_R9G9B9E5_FLOAT) ||
         (ptex->nr_samples >= 2 && !sscreen->dcc_msaa_allowed)))
       flags |= RADEON_SURF_DISABLE_DCC;
 
@@ -314,7 +323,8 @@ static int si_init_surface(struct si_screen *sscreen, struct radeon_surf *surfac
    return 0;
 }
 
-void si_eliminate_fast_color_clear(struct si_context *sctx, struct si_texture *tex)
+void si_eliminate_fast_color_clear(struct si_context *sctx, struct si_texture *tex,
+                                   bool *ctx_flushed)
 {
    struct si_screen *sscreen = sctx->screen;
    struct pipe_context *ctx = &sctx->b;
@@ -326,8 +336,14 @@ void si_eliminate_fast_color_clear(struct si_context *sctx, struct si_texture *t
    ctx->flush_resource(ctx, &tex->buffer.b.b);
 
    /* Flush only if any fast clear elimination took place. */
+   bool flushed = false;
    if (n != sctx->num_decompress_calls)
+   {
       ctx->flush(ctx, NULL, 0);
+      flushed = true;
+   }
+   if (ctx_flushed)
+      *ctx_flushed = flushed;
 
    if (ctx == sscreen->aux_context)
       simple_mtx_unlock(&sscreen->aux_context_lock);
@@ -705,9 +721,11 @@ static bool si_texture_get_handle(struct pipe_screen *screen, struct pipe_contex
       if (!(usage & PIPE_HANDLE_USAGE_EXPLICIT_FLUSH) &&
           (tex->cmask_buffer || tex->surface.dcc_offset)) {
          /* Eliminate fast clear (both CMASK and DCC) */
-         si_eliminate_fast_color_clear(sctx, tex);
-         /* eliminate_fast_color_clear flushes the context */
-         flush = false;
+         bool flushed;
+         si_eliminate_fast_color_clear(sctx, tex, &flushed);
+         /* eliminate_fast_color_clear sometimes flushes the context */
+         if (flushed)
+            flush = false;
 
          /* Disable CMASK if flush_resource isn't going
           * to be called.
@@ -784,13 +802,9 @@ static bool si_texture_get_handle(struct pipe_screen *screen, struct pipe_contex
 
 static void si_texture_destroy(struct pipe_screen *screen, struct pipe_resource *ptex)
 {
-   struct si_screen *sscreen = (struct si_screen *)screen;
    struct si_texture *tex = (struct si_texture *)ptex;
    struct si_resource *resource = &tex->buffer;
 
-   if (sscreen->info.chip_class >= GFX9)
-      free(tex->surface.u.gfx9.dcc_retile_map);
-
    si_texture_reference(&tex->flushed_depth_texture, NULL);
 
    if (tex->cmask_buffer != &tex->buffer) {
@@ -979,7 +993,15 @@ static struct si_texture *si_texture_create_object(struct pipe_screen *screen,
    /* don't include stencil-only formats which we don't support for rendering */
    tex->is_depth = util_format_has_depth(util_format_description(tex->buffer.b.b.format));
    tex->surface = *surface;
-   tex->tc_compatible_htile = false; /* This will be enabled on demand. */
+
+   /* On GFX8, HTILE uses different tiling depending on the TC_COMPATIBLE_HTILE
+    * setting, so we have to enable it if we enabled it at allocation.
+    *
+    * GFX9 and later use the same tiling for both, so TC-compatible HTILE can be
+    * enabled on demand.
+    */
+   tex->tc_compatible_htile = sscreen->info.chip_class == GFX8 &&
+                              tex->surface.flags & RADEON_SURF_TC_COMPATIBLE_HTILE;
 
    /* TC-compatible HTILE:
     * - GFX8 only supports Z32_FLOAT.
@@ -1137,20 +1159,14 @@ static struct si_texture *si_texture_create_object(struct pipe_screen *screen,
           */
          bool use_uint16 = tex->surface.u.gfx9.dcc_retile_use_uint16;
          unsigned num_elements = tex->surface.u.gfx9.dcc_retile_num_elements;
+         unsigned dcc_retile_map_size = num_elements * (use_uint16 ? 2 : 4);
          struct si_resource *buf = si_aligned_buffer_create(screen, 0, PIPE_USAGE_STREAM,
-                                                            num_elements * (use_uint16 ? 2 : 4),
+                                                            dcc_retile_map_size,
                                                             sscreen->info.tcc_cache_line_size);
-         uint32_t *ui = (uint32_t *)sscreen->ws->buffer_map(buf->buf, NULL, PIPE_TRANSFER_WRITE);
-         uint16_t *us = (uint16_t *)ui;
+         void *map = sscreen->ws->buffer_map(buf->buf, NULL, PIPE_TRANSFER_WRITE);
 
-         /* Upload the retile map into a staging buffer. */
-         if (use_uint16) {
-            for (unsigned i = 0; i < num_elements; i++)
-               us[i] = tex->surface.u.gfx9.dcc_retile_map[i];
-         } else {
-            for (unsigned i = 0; i < num_elements; i++)
-               ui[i] = tex->surface.u.gfx9.dcc_retile_map[i];
-         }
+         /* Upload the retile map into the staging buffer. */
+         memcpy(map, tex->surface.u.gfx9.dcc_retile_map, dcc_retile_map_size);
 
          /* Copy the staging buffer to the buffer backing the texture. */
          struct si_context *sctx = (struct si_context *)sscreen->aux_context;
@@ -1192,8 +1208,6 @@ static struct si_texture *si_texture_create_object(struct pipe_screen *screen,
 
 error:
    FREE(tex);
-   if (sscreen->info.chip_class >= GFX9)
-      free(surface->u.gfx9.dcc_retile_map);
    return NULL;
 }
 
@@ -1211,7 +1225,7 @@ static enum radeon_surf_mode si_choose_tiling(struct si_screen *sscreen,
       return RADEON_SURF_MODE_2D;
 
    /* Transfer resources should be linear. */
-   if (templ->flags & SI_RESOURCE_FLAG_TRANSFER)
+   if (templ->flags & SI_RESOURCE_FLAG_FORCE_LINEAR)
       return RADEON_SURF_MODE_LINEAR_ALIGNED;
 
    /* Avoid Z/S decompress blits by forcing TC-compatible HTILE on GFX8,
@@ -1267,7 +1281,7 @@ struct pipe_resource *si_texture_create(struct pipe_screen *screen,
 
    if (templ->nr_samples >= 2) {
       /* This is hackish (overwriting the const pipe_resource template),
-       * but should be harmless and state trackers can also see
+       * but should be harmless and gallium frontends can also see
        * the overriden number of samples in the created pipe_resource.
        */
       if (is_zs && sscreen->eqaa_force_z_samples) {
@@ -1279,8 +1293,8 @@ struct pipe_resource *si_texture_create(struct pipe_screen *screen,
       }
    }
 
-   bool is_flushed_depth =
-      templ->flags & SI_RESOURCE_FLAG_FLUSHED_DEPTH || templ->flags & SI_RESOURCE_FLAG_TRANSFER;
+   bool is_flushed_depth = templ->flags & SI_RESOURCE_FLAG_FLUSHED_DEPTH ||
+                           templ->flags & SI_RESOURCE_FLAG_FORCE_LINEAR;
    bool tc_compatible_htile =
       sscreen->info.chip_class >= GFX8 &&
       /* There are issues with TC-compatible HTILE on Tonga (and
@@ -1532,7 +1546,7 @@ bool si_init_flushed_depth_texture(struct pipe_context *ctx, struct pipe_resourc
  */
 static void si_init_temp_resource_from_box(struct pipe_resource *res, struct pipe_resource *orig,
                                            const struct pipe_box *box, unsigned level,
-                                           unsigned flags)
+                                           unsigned usage, unsigned flags)
 {
    memset(res, 0, sizeof(*res));
    res->format = orig->format;
@@ -1540,10 +1554,10 @@ static void si_init_temp_resource_from_box(struct pipe_resource *res, struct pip
    res->height0 = box->height;
    res->depth0 = 1;
    res->array_size = 1;
-   res->usage = flags & SI_RESOURCE_FLAG_TRANSFER ? PIPE_USAGE_STAGING : PIPE_USAGE_DEFAULT;
+   res->usage = usage;
    res->flags = flags;
 
-   if (flags & SI_RESOURCE_FLAG_TRANSFER && util_format_is_compressed(orig->format)) {
+   if (flags & SI_RESOURCE_FLAG_FORCE_LINEAR && util_format_is_compressed(orig->format)) {
       /* Transfer resources are allocated with linear tiling, which is
        * not supported for compressed formats.
        */
@@ -1609,7 +1623,7 @@ static void *si_texture_transfer_map(struct pipe_context *ctx, struct pipe_resou
    char *map;
    bool use_staging_texture = false;
 
-   assert(!(texture->flags & SI_RESOURCE_FLAG_TRANSFER));
+   assert(!(texture->flags & SI_RESOURCE_FLAG_FORCE_LINEAR));
    assert(box->width && box->height && box->depth);
 
    /* If we are uploading into FP16 or R11G11B10_FLOAT via a blit, CB clobbers NaNs,
@@ -1651,7 +1665,7 @@ static void *si_texture_transfer_map(struct pipe_context *ctx, struct pipe_resou
        * Use the staging texture for uploads if the underlying BO
        * is busy.
        */
-      if (!tex->surface.is_linear)
+      if (!tex->surface.is_linear || (tex->buffer.flags & RADEON_FLAG_ENCRYPTED))
          use_staging_texture = true;
       else if (usage & PIPE_TRANSFER_READ)
          use_staging_texture =
@@ -1678,9 +1692,24 @@ static void *si_texture_transfer_map(struct pipe_context *ctx, struct pipe_resou
    if (use_staging_texture) {
       struct pipe_resource resource;
       struct si_texture *staging;
+      unsigned bo_usage = usage & PIPE_TRANSFER_READ ? PIPE_USAGE_STAGING : PIPE_USAGE_STREAM;
+      unsigned bo_flags = SI_RESOURCE_FLAG_FORCE_LINEAR;
 
-      si_init_temp_resource_from_box(&resource, texture, box, level, SI_RESOURCE_FLAG_TRANSFER);
-      resource.usage = (usage & PIPE_TRANSFER_READ) ? PIPE_USAGE_STAGING : PIPE_USAGE_STREAM;
+      /* The pixel shader has a bad access pattern for linear textures.
+       * If a pixel shader is used to blit to/from staging, don't disable caches.
+       *
+       * MSAA, depth/stencil textures, and compressed textures use the pixel shader
+       * to blit.
+       */
+      if (texture->nr_samples <= 1 &&
+          !tex->is_depth &&
+          !util_format_is_compressed(texture->format) &&
+          /* Texture uploads with DCC use the pixel shader to blit */
+          (!(usage & PIPE_TRANSFER_WRITE) || !vi_dcc_enabled(tex, level)))
+         bo_flags |= SI_RESOURCE_FLAG_UNCACHED;
+
+      si_init_temp_resource_from_box(&resource, texture, box, level, bo_usage,
+                                     bo_flags);
 
       /* Since depth-stencil textures don't support linear tiling,
        * blit from ZS to color and vice versa. u_blitter will do