From 823e34f9388cde61057fbeb3f9bdf873b47834ce Mon Sep 17 00:00:00 2001 From: Emma Anholt Date: Wed, 4 Jan 2023 12:17:27 -0800 Subject: [PATCH] u_transfer_helper: Merge in-place and split z/s interleaved map handling. The paths were mostly the same, except that in-place was missing the appropriate layering for MSAA helper re-mapping. We can instead share more code, making the differences between the interleave packing clear, and have the MSAA resolve blit happen once before we do the split mappings. Reviewed-by: Mike Blumenkrantz Part-of: --- .../auxiliary/util/u_transfer_helper.c | 205 ++++++------------ 1 file changed, 68 insertions(+), 137 deletions(-) diff --git a/src/gallium/auxiliary/util/u_transfer_helper.c b/src/gallium/auxiliary/util/u_transfer_helper.c index dc011a09dbb..82ffa642ef3 100644 --- a/src/gallium/auxiliary/util/u_transfer_helper.c +++ b/src/gallium/auxiliary/util/u_transfer_helper.c @@ -39,8 +39,13 @@ struct u_transfer_helper { bool interleave_in_place; }; -static inline bool need_interleave_path(struct u_transfer_helper *helper, - enum pipe_format format) +/* If we need to take the path for PIPE_MAP_DEPTH/STENCIL_ONLY on the parent + * depth/stencil resource an interleaving those to/from a staging buffer. The + * other path for z/s interleave is when separate z and s resources are + * created at resource create time. + */ +static inline bool needs_in_place_zs_interleave(struct u_transfer_helper *helper, + enum pipe_format format) { if (!helper->interleave_in_place) return false; @@ -68,6 +73,9 @@ static inline bool handle_transfer(struct pipe_resource *prsc) if (helper->msaa_map && (prsc->nr_samples > 1)) return true; + if (needs_in_place_zs_interleave(helper, prsc->format)) + return true; + return false; } @@ -263,10 +271,9 @@ u_transfer_helper_transfer_map(struct pipe_context *pctx, enum pipe_format format = prsc->format; unsigned width = box->width; unsigned height = box->height; + bool in_place_zs_interleave = needs_in_place_zs_interleave(helper, format); - if (need_interleave_path(helper, format)) - return u_transfer_helper_deinterleave_transfer_map(pctx, prsc, level, usage, box, pptrans); - else if (!handle_transfer(prsc)) + if (!handle_transfer(prsc)) return helper->vtbl->transfer_map(pctx, prsc, level, usage, box, pptrans); if (helper->msaa_map && (prsc->nr_samples > 1)) @@ -290,15 +297,22 @@ u_transfer_helper_transfer_map(struct pipe_context *pctx, if (!trans->staging) goto fail; - trans->ptr = helper->vtbl->transfer_map(pctx, prsc, level, usage, box, - &trans->trans); + trans->ptr = helper->vtbl->transfer_map(pctx, prsc, level, + usage | (in_place_zs_interleave ? PIPE_MAP_DEPTH_ONLY : 0), + box, &trans->trans); if (!trans->ptr) goto fail; if (util_format_is_depth_and_stencil(prsc->format)) { - struct pipe_resource *stencil = helper->vtbl->get_stencil(prsc); + struct pipe_resource *stencil; + + if (in_place_zs_interleave) + stencil = prsc; + else + stencil = helper->vtbl->get_stencil(prsc); trans->ptr2 = helper->vtbl->transfer_map(pctx, stencil, level, - usage, box, &trans->trans2); + usage | (in_place_zs_interleave ? PIPE_MAP_STENCIL_ONLY : 0), + box, &trans->trans2); if (needs_pack(usage)) { switch (prsc->format) { @@ -315,27 +329,53 @@ u_transfer_helper_transfer_map(struct pipe_context *pctx, width, height); break; case PIPE_FORMAT_Z24_UNORM_S8_UINT: - if (helper->z24_in_z32f) { - util_format_z24_unorm_s8_uint_pack_z_float(trans->staging, - ptrans->stride, - trans->ptr, - trans->trans->stride, - width, height); - util_format_z24_unorm_s8_uint_pack_s_8uint(trans->staging, - ptrans->stride, - trans->ptr2, - trans->trans2->stride, - width, height); + if (in_place_zs_interleave) { + if (helper->z24_in_z32f) { + util_format_z24_unorm_s8_uint_pack_separate_z32(trans->staging, + ptrans->stride, + trans->ptr, + trans->trans->stride, + trans->ptr2, + trans->trans2->stride, + width, height); + } else { + util_format_z24_unorm_s8_uint_pack_separate(trans->staging, + ptrans->stride, + trans->ptr, + trans->trans->stride, + trans->ptr2, + trans->trans2->stride, + width, height); + } } else { - util_format_z24_unorm_s8_uint_pack_separate(trans->staging, - ptrans->stride, - trans->ptr, - trans->trans->stride, - trans->ptr2, - trans->trans2->stride, - width, height); + if (helper->z24_in_z32f) { + util_format_z24_unorm_s8_uint_pack_z_float(trans->staging, + ptrans->stride, + trans->ptr, + trans->trans->stride, + width, height); + util_format_z24_unorm_s8_uint_pack_s_8uint(trans->staging, + ptrans->stride, + trans->ptr2, + trans->trans2->stride, + width, height); + } else { + util_format_z24_unorm_s8_uint_pack_separate(trans->staging, + ptrans->stride, + trans->ptr, + trans->trans->stride, + trans->ptr2, + trans->trans2->stride, + width, height); + } } break; + case PIPE_FORMAT_Z24X8_UNORM: + assert(helper->z24_in_z32f); + util_format_z24x8_unorm_pack_z_float(trans->staging, ptrans->stride, + trans->ptr, trans->trans->stride, + width, height); + break; default: unreachable("Unexpected format"); } @@ -500,9 +540,8 @@ u_transfer_helper_transfer_unmap(struct pipe_context *pctx, struct pipe_transfer *ptrans) { struct u_transfer_helper *helper = pctx->screen->transfer_helper; - bool interleave = need_interleave_path(helper, ptrans->resource->format); - if (handle_transfer(ptrans->resource) || interleave) { + if (handle_transfer(ptrans->resource)) { struct u_transfer *trans = u_transfer(ptrans); if (!(ptrans->usage & PIPE_MAP_FLUSH_EXPLICIT)) { @@ -555,111 +594,3 @@ u_transfer_helper_destroy(struct u_transfer_helper *helper) { free(helper); } - - -/* these two functions 'deinterleave' are meant to be used without the corresponding - * resource_create/destroy hooks, as they perform the interleaving on-the-fly - * - * drivers should expect to be passed the same buffer repeatedly with the format changed - * to indicate which component is being mapped - */ -static void * -u_transfer_helper_deinterleave_transfer_map(struct pipe_context *pctx, - struct pipe_resource *prsc, - unsigned level, unsigned usage, - const struct pipe_box *box, - struct pipe_transfer **pptrans) -{ - struct u_transfer_helper *helper = pctx->screen->transfer_helper; - struct u_transfer *trans; - struct pipe_transfer *ptrans; - enum pipe_format format = prsc->format; - unsigned width = box->width; - unsigned height = box->height; - - assert(box->depth == 1); - - trans = calloc(1, sizeof(*trans)); - if (!trans) - return NULL; - - ptrans = &trans->base; - pipe_resource_reference(&ptrans->resource, prsc); - ptrans->level = level; - ptrans->usage = usage; - ptrans->box = *box; - ptrans->stride = util_format_get_stride(format, box->width); - ptrans->layer_stride = ptrans->stride * box->height; - - bool has_stencil = util_format_is_depth_and_stencil(format); - - trans->staging = malloc(ptrans->layer_stride); - if (!trans->staging) - goto fail; - - trans->ptr = helper->vtbl->transfer_map(pctx, prsc, level, usage | PIPE_MAP_DEPTH_ONLY, box, - &trans->trans); - if (!trans->ptr) - goto fail; - - trans->ptr2 = NULL; - if (has_stencil) - trans->ptr2 = helper->vtbl->transfer_map(pctx, prsc, level, - usage | PIPE_MAP_STENCIL_ONLY, box, &trans->trans2); - if (needs_pack(usage)) { - switch (prsc->format) { - case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT: - util_format_z32_float_s8x24_uint_pack_z_float(trans->staging, - ptrans->stride, - trans->ptr, - trans->trans->stride, - width, height); - util_format_z32_float_s8x24_uint_pack_s_8uint(trans->staging, - ptrans->stride, - trans->ptr2, - trans->trans2->stride, - width, height); - break; - case PIPE_FORMAT_Z24_UNORM_S8_UINT: - if (helper->z24_in_z32f) { - util_format_z24_unorm_s8_uint_pack_separate_z32(trans->staging, - ptrans->stride, - trans->ptr, - trans->trans->stride, - trans->ptr2, - trans->trans2->stride, - width, height); - } else { - util_format_z24_unorm_s8_uint_pack_separate(trans->staging, - ptrans->stride, - trans->ptr, - trans->trans->stride, - trans->ptr2, - trans->trans2->stride, - width, height); - } - break; - case PIPE_FORMAT_Z24X8_UNORM: - assert(helper->z24_in_z32f); - util_format_z24x8_unorm_pack_z_float(trans->staging, ptrans->stride, - trans->ptr, trans->trans->stride, - width, height); - break; - default: - unreachable("Unexpected format"); - } - } - - *pptrans = ptrans; - return trans->staging; - -fail: - if (trans->trans) - helper->vtbl->transfer_unmap(pctx, trans->trans); - if (trans->trans2) - helper->vtbl->transfer_unmap(pctx, trans->trans2); - pipe_resource_reference(&ptrans->resource, NULL); - free(trans->staging); - free(trans); - return NULL; -}