From: Asahi Lina Date: Sun, 26 Feb 2023 06:00:45 +0000 (+0900) Subject: asahi: Make agx_flush_resource reallocate non-shareable resources X-Git-Tag: upstream/23.3.3~11527 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=c41f10eb9ebf82f9d37f83ec0a182215600327cd;p=platform%2Fupstream%2Fmesa.git asahi: Make agx_flush_resource reallocate non-shareable resources It's not legal to share a resource that isn't PIPE_BIND_SHARED, but flush_resource needs to prepare a resource for potential sharing. Let's allocate a new resource and blit it over when this happens. See also: https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/13154 Signed-off-by: Asahi Lina Part-of: --- diff --git a/src/gallium/drivers/asahi/agx_pipe.c b/src/gallium/drivers/asahi/agx_pipe.c index 5d825e6..5556c69 100644 --- a/src/gallium/drivers/asahi/agx_pipe.c +++ b/src/gallium/drivers/asahi/agx_pipe.c @@ -940,9 +940,64 @@ agx_clear(struct pipe_context *pctx, unsigned buffers, } static void -agx_flush_resource(struct pipe_context *ctx, struct pipe_resource *resource) +agx_flush_resource(struct pipe_context *pctx, struct pipe_resource *pres) { - agx_flush_writer(agx_context(ctx), agx_resource(resource), "flush_resource"); + struct agx_resource *rsrc = agx_resource(pres); + + /* flush_resource is used to prepare resources for sharing, so if this is not + * already a shareabe resource, make it so + */ + struct agx_bo *old = rsrc->bo; + if (!(old->flags & AGX_BO_SHAREABLE)) { + assert(rsrc->layout.levels == 1 && + "Shared resources must not be mipmapped"); + assert(rsrc->layout.sample_count_sa == 1 && + "Shared resources must not be multisampled"); + assert(rsrc->bo); + assert(!(pres->bind & PIPE_BIND_SHARED)); + + 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); + } else { + /* Otherwise just claim it's already shared */ + pres->bind |= PIPE_BIND_SHARED; + agx_flush_writer(agx_context(pctx), rsrc, "flush_resource"); + } + } /*