From 5a844f87a1f2b341f2d086b21363b1ba4b01460a Mon Sep 17 00:00:00 2001 From: Qiang Yu Date: Fri, 10 Dec 2021 18:33:38 +0800 Subject: [PATCH] radeonsi: support texture resource commit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed-by: Marek Olšák Signed-off-by: Qiang Yu Part-of: --- src/gallium/drivers/radeonsi/si_buffer.c | 13 +++++-- src/gallium/drivers/radeonsi/si_pipe.h | 2 ++ src/gallium/drivers/radeonsi/si_texture.c | 43 +++++++++++++++++++++++ 3 files changed, 55 insertions(+), 3 deletions(-) diff --git a/src/gallium/drivers/radeonsi/si_buffer.c b/src/gallium/drivers/radeonsi/si_buffer.c index c66c52557bc..9c199c84d50 100644 --- a/src/gallium/drivers/radeonsi/si_buffer.c +++ b/src/gallium/drivers/radeonsi/si_buffer.c @@ -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) diff --git a/src/gallium/drivers/radeonsi/si_pipe.h b/src/gallium/drivers/radeonsi/si_pipe.h index c47add085c8..5d6705659e0 100644 --- a/src/gallium/drivers/radeonsi/si_pipe.h +++ b/src/gallium/drivers/radeonsi/si_pipe.h @@ -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, diff --git a/src/gallium/drivers/radeonsi/si_texture.c b/src/gallium/drivers/radeonsi/si_texture.c index e06e178da00..0fe177a4bfe 100644 --- a/src/gallium/drivers/radeonsi/si_texture.c +++ b/src/gallium/drivers/radeonsi/si_texture.c @@ -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,