From 531247cf31a440643df066769d184e5f8274f043 Mon Sep 17 00:00:00 2001 From: Alyssa Rosenzweig Date: Fri, 19 May 2023 15:59:54 -0400 Subject: [PATCH] asahi: Extract transition_resource helper We'll reuse this logic for images. Extract it out and generalize it. Signed-off-by: Alyssa Rosenzweig Part-of: --- src/gallium/drivers/asahi/agx_pipe.c | 79 ++++++++++++++++------------ 1 file changed, 45 insertions(+), 34 deletions(-) diff --git a/src/gallium/drivers/asahi/agx_pipe.c b/src/gallium/drivers/asahi/agx_pipe.c index 3def67dc2d9..8ccdc642d8a 100644 --- a/src/gallium/drivers/asahi/agx_pipe.c +++ b/src/gallium/drivers/asahi/agx_pipe.c @@ -1075,6 +1075,50 @@ agx_clear(struct pipe_context *pctx, unsigned buffers, assert((batch->draw & slowclear) == slowclear); } +static void +transition_resource(struct pipe_context *pctx, struct agx_resource *rsrc, + struct pipe_resource *templ) +{ + struct agx_resource *new_res = + agx_resource(pctx->screen->resource_create(pctx->screen, templ)); + + assert(new_res); + + int level; + BITSET_FOREACH_SET(level, rsrc->data_valid, PIPE_MAX_TEXTURE_LEVELS) { + /* Blit each valid level */ + struct pipe_blit_info blit = {0}; + + u_box_3d(0, 0, 0, rsrc->layout.width_px, rsrc->layout.height_px, + rsrc->layout.depth_px, &blit.dst.box); + blit.src.box = blit.dst.box; + + blit.dst.resource = &new_res->base; + blit.dst.format = new_res->base.format; + blit.dst.level = level; + blit.src.resource = &rsrc->base; + blit.src.format = rsrc->base.format; + blit.src.level = level; + blit.mask = util_format_get_mask(blit.src.format); + blit.filter = PIPE_TEX_FILTER_NEAREST; + agx_blit(pctx, &blit); + } + + /* Flush the blits out, to make sure the old resource is no longer used */ + agx_flush_writer(agx_context(pctx), new_res, "flush_resource"); + + /* Copy the bind flags and swap the BOs */ + struct agx_bo *old = rsrc->bo; + rsrc->base.bind = new_res->base.bind; + rsrc->layout = new_res->layout; + rsrc->modifier = new_res->modifier; + rsrc->bo = new_res->bo; + new_res->bo = old; + + /* Free the new resource, which now owns the old BO */ + pipe_resource_reference((struct pipe_resource **)&new_res, NULL); +} + static void agx_flush_resource(struct pipe_context *pctx, struct pipe_resource *pres) { @@ -1094,40 +1138,7 @@ agx_flush_resource(struct pipe_context *pctx, struct pipe_resource *pres) struct pipe_resource templ = *pres; templ.bind |= PIPE_BIND_SHARED; - - /* Create a new shareable resource */ - struct agx_resource *new_res = - agx_resource(pctx->screen->resource_create(pctx->screen, &templ)); - - assert(new_res); - - /* Blit it over */ - struct pipe_blit_info blit = {0}; - - u_box_3d(0, 0, 0, rsrc->layout.width_px, rsrc->layout.height_px, - rsrc->layout.depth_px, &blit.dst.box); - blit.src.box = blit.dst.box; - - blit.dst.resource = &new_res->base; - blit.dst.format = new_res->base.format; - blit.dst.level = 0; - blit.src.resource = pres; - blit.src.format = pres->format; - blit.src.level = 0; - blit.mask = util_format_get_mask(blit.src.format); - blit.filter = PIPE_TEX_FILTER_NEAREST; - agx_blit(pctx, &blit); - - /* Flush the blit out, to make sure the old resource is no longer used */ - agx_flush_writer(agx_context(pctx), new_res, "flush_resource"); - - /* Copy the bind flags and swap the BOs */ - rsrc->base.bind = new_res->base.bind; - rsrc->bo = new_res->bo; - new_res->bo = old; - - /* Free the new resource, which now owns the old BO */ - pipe_resource_reference((struct pipe_resource **)&new_res, NULL); + transition_resource(pctx, rsrc, &templ); } else { /* Otherwise just claim it's already shared */ pres->bind |= PIPE_BIND_SHARED;