radeonsi: support texture resource commit
authorQiang Yu <yuq825@gmail.com>
Fri, 10 Dec 2021 10:33:38 +0000 (18:33 +0800)
committerQiang Yu <yuq825@gmail.com>
Thu, 30 Dec 2021 08:11:19 +0000 (16:11 +0800)
Reviewed-by: Marek Olšák <marek.olsak@amd.com>
Signed-off-by: Qiang Yu <yuq825@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/14223>

src/gallium/drivers/radeonsi/si_buffer.c
src/gallium/drivers/radeonsi/si_pipe.h
src/gallium/drivers/radeonsi/si_texture.c

index c66c525..9c199c8 100644 (file)
@@ -694,6 +694,12 @@ static struct pipe_resource *si_resource_create(struct pipe_screen *screen,
    }
 }
 
+static bool si_buffer_commit(struct si_context *ctx, struct si_resource *res,
+                             struct pipe_box *box, bool commit)
+{
+   return ctx->ws->buffer_commit(ctx->ws, res->buf, box->x, box->width, commit);
+}
+
 static bool si_resource_commit(struct pipe_context *pctx, struct pipe_resource *resource,
                                unsigned level, struct pipe_box *box, bool commit)
 {
@@ -713,9 +719,10 @@ static bool si_resource_commit(struct pipe_context *pctx, struct pipe_resource *
    }
    ctx->ws->cs_sync_flush(&ctx->gfx_cs);
 
-   assert(resource->target == PIPE_BUFFER);
-
-   return ctx->ws->buffer_commit(ctx->ws, res->buf, box->x, box->width, commit);
+   if (resource->target == PIPE_BUFFER)
+      return si_buffer_commit(ctx, res, box, commit);
+   else
+      return si_texture_commit(ctx, res, level, box, commit);
 }
 
 void si_init_screen_buffer_functions(struct si_screen *sscreen)
index c47add0..5d67056 100644 (file)
@@ -1566,6 +1566,8 @@ void si_print_texture_info(struct si_screen *sscreen, struct si_texture *tex,
                            struct u_log_context *log);
 struct pipe_resource *si_texture_create(struct pipe_screen *screen,
                                         const struct pipe_resource *templ);
+bool si_texture_commit(struct si_context *ctx, struct si_resource *res, unsigned level,
+                       struct pipe_box *box, bool commit);
 bool vi_dcc_formats_compatible(struct si_screen *sscreen, enum pipe_format format1,
                                enum pipe_format format2);
 bool vi_dcc_formats_are_incompatible(struct pipe_resource *tex, unsigned level,
index e06e178..0fe177a 100644 (file)
@@ -1315,6 +1315,49 @@ struct pipe_resource *si_texture_create(struct pipe_screen *screen,
    return si_texture_create_with_modifier(screen, templ, DRM_FORMAT_MOD_INVALID);
 }
 
+bool si_texture_commit(struct si_context *ctx, struct si_resource *res, unsigned level,
+                       struct pipe_box *box, bool commit)
+{
+   struct si_texture *tex = (struct si_texture *)res;
+   struct radeon_surf *surface = &tex->surface;
+   enum pipe_format format = res->b.b.format;
+   unsigned blks = util_format_get_blocksize(format);
+
+   assert(ctx->chip_class >= GFX9);
+
+   unsigned row_pitch = surface->u.gfx9.prt_level_pitch[level] *
+      surface->prt_tile_height * surface->prt_tile_depth * blks;
+   unsigned depth_pitch = surface->u.gfx9.surf_slice_size * surface->prt_tile_depth;
+
+   unsigned x = box->x / surface->prt_tile_width;
+   unsigned y = box->y / surface->prt_tile_height;
+   unsigned z = box->z / surface->prt_tile_depth;
+
+   unsigned w = DIV_ROUND_UP(box->width, surface->prt_tile_width);
+   unsigned h = DIV_ROUND_UP(box->height, surface->prt_tile_height);
+   unsigned d = DIV_ROUND_UP(box->depth, surface->prt_tile_depth);
+
+   /* Align to tile block base, for levels in mip tail whose offset is inside
+    * a tile block.
+    */
+   unsigned level_base = ROUND_DOWN_TO(surface->u.gfx9.prt_level_offset[level],
+                                       RADEON_SPARSE_PAGE_SIZE);
+   unsigned commit_base = level_base +
+      x * RADEON_SPARSE_PAGE_SIZE + y * row_pitch + z * depth_pitch;
+
+   unsigned size = w * RADEON_SPARSE_PAGE_SIZE;
+   for (int i = 0; i < d; i++) {
+      unsigned base = commit_base + i * depth_pitch;
+      for (int j = 0; j < h; j++) {
+         unsigned offset = base + j * row_pitch;
+         if (!ctx->ws->buffer_commit(ctx->ws, res->buf, offset, size, commit))
+            return false;
+      }
+   }
+
+   return true;
+}
+
 static void si_query_dmabuf_modifiers(struct pipe_screen *screen,
                                       enum pipe_format format,
                                       int max,