[Mesa-dev] [PATCH 4/5] gallium: Make a helper for doing Z32_FLOAT_S8X24_UINT mappings.
Rob Clark
robdclark at gmail.com
Tue Nov 21 16:18:28 UTC 2017
On Thu, Nov 16, 2017 at 9:19 PM, Eric Anholt <eric at anholt.net> wrote:
> ---
> src/gallium/auxiliary/util/u_transfer.c | 118 ++++++++++++++++++++++++++++++++
> src/gallium/auxiliary/util/u_transfer.h | 18 +++++
> 2 files changed, 136 insertions(+)
>
> diff --git a/src/gallium/auxiliary/util/u_transfer.c b/src/gallium/auxiliary/util/u_transfer.c
> index 3d3c5eb42cd4..f941e648b33b 100644
> --- a/src/gallium/auxiliary/util/u_transfer.c
> +++ b/src/gallium/auxiliary/util/u_transfer.c
> @@ -1,4 +1,5 @@
> #include "pipe/p_context.h"
> +#include "util/u_format_zs.h"
> #include "util/u_surface.h"
> #include "util/u_inlines.h"
> #include "util/u_transfer.h"
> @@ -272,3 +273,120 @@ void u_transfer_unmap_msaa_helper(struct pipe_context *pctx,
> pipe_resource_reference(&trans->ss, NULL);
> free(trans);
> }
> +
> +struct u_transfer_z32f_s8_helper {
> + struct pipe_transfer base;
> + struct pipe_transfer *z_ptrans;
> + struct pipe_transfer *s_ptrans;
> + void *z, *s;
> + void *merged;
> +};
> +
> +/**
> + * Helper to implement the PIPE_FORMAT_Z32_FLOAT_S8X24_UINT mappings when the
> + * driver stores the Z and S in separate resources.
> + *
> + * We malloc temporary storage, map each resource, and use the CPU to pack the
> + * values into the temporary. Note that a callback is used, so the triver can
> + * avoid recursing.
> + *
> + * Note that the driver's unmap will be called with our ptrans: They need to
> + * detect it and call u_transfer_unmap_z32f_s8_helper() and return
> + * immediately.
> + */
> +void *
> +u_transfer_map_z32f_s8_helper(struct pipe_context *pctx,
> + struct pipe_resource *z,
> + struct pipe_resource *s,
> + unsigned level, unsigned usage,
> + const struct pipe_box *box,
> + struct pipe_transfer **pptrans,
> + void *(*transfer_map)(struct pipe_context *pctx,
> + struct pipe_resource *prsc,
> + unsigned level, unsigned usage,
> + const struct pipe_box *box,
> + struct pipe_transfer **pptrans))
one one idea to avoid the callback would be to build this into u_resource...
ie. add driver's actual transfer_map/transfer_unmap functions to
u_resource_vtbl, and then have u_resource_transfer_map/unmap which
driver can plug into pipe_context.. Hmm, well actually vtbl already
has ->transfer_map/unmap()..
Possibly u_resource_vtbl should have flags/bitmask for what "lowering" to do..
BR,
-R
> +{
> + struct u_transfer_z32f_s8_helper *trans = calloc(1, sizeof(*trans));
> + if (!trans)
> + return NULL;
> + struct pipe_transfer *ptrans = &trans->base;
> +
> + pipe_resource_reference(&ptrans->resource, z);
> + ptrans->level = level;
> + ptrans->usage = usage;
> + ptrans->box = *box;
> +
> + trans->z = transfer_map(pctx, z, level, usage, box,
> + &trans->z_ptrans);
> + if (!trans->z)
> + goto fail_unref;
> + trans->s = transfer_map(pctx, s, level, usage, box,
> + &trans->s_ptrans);
> + if (!trans->s)
> + goto fail_unmap_z;
> +
> + ptrans->stride = 8 * box->width;
> + trans->merged = malloc(ptrans->stride * box->height);
> + if (!trans->merged)
> + goto fail_unmap_s;
> +
> + if (usage & PIPE_TRANSFER_READ) {
> + util_format_z32_float_s8x24_uint_pack_z_float(trans->merged,
> + ptrans->stride,
> + trans->z,
> + trans->z_ptrans->stride,
> + box->width,
> + box->height);
> + util_format_z32_float_s8x24_uint_pack_s_8uint(trans->merged,
> + ptrans->stride,
> + trans->s,
> + trans->s_ptrans->stride,
> + box->width,
> + box->height);
> + }
> +
> + *pptrans = ptrans;
> + return trans->merged;
> +
> + fail_unmap_s:
> + pctx->transfer_unmap(pctx, trans->s_ptrans);
> + fail_unmap_z:
> + pctx->transfer_unmap(pctx, trans->z_ptrans);
> + fail_unref:
> + pipe_resource_reference(&ptrans->resource, NULL);
> + free(trans);
> + return NULL;
> +}
> +
> +void u_transfer_unmap_z32f_s8_helper(struct pipe_context *pctx,
> + struct pipe_transfer *ptrans,
> + void (*transfer_unmap)(struct pipe_context *pctx,
> + struct pipe_transfer *ptrans))
> +{
> + struct u_transfer_z32f_s8_helper *trans =
> + (struct u_transfer_z32f_s8_helper *)ptrans;
> +
> + if (ptrans->usage & PIPE_TRANSFER_WRITE) {
> + uint32_t width = ptrans->box.width;
> + uint32_t height = ptrans->box.height;
> +
> + util_format_z32_float_s8x24_uint_unpack_z_float(trans->z,
> + trans->z_ptrans->stride,
> + trans->merged,
> + ptrans->stride,
> + width, height);
> + util_format_z32_float_s8x24_uint_unpack_s_8uint(trans->s,
> + trans->s_ptrans->stride,
> + trans->merged,
> + ptrans->stride,
> + width, height);
> + }
> +
> + transfer_unmap(pctx, trans->s_ptrans);
> + transfer_unmap(pctx, trans->z_ptrans);
> +
> + pipe_resource_reference(&ptrans->resource, NULL);
> + free(trans->merged);
> + free(trans);
> +}
> diff --git a/src/gallium/auxiliary/util/u_transfer.h b/src/gallium/auxiliary/util/u_transfer.h
> index 237930c06007..292899e4475f 100644
> --- a/src/gallium/auxiliary/util/u_transfer.h
> +++ b/src/gallium/auxiliary/util/u_transfer.h
> @@ -24,6 +24,24 @@ u_transfer_map_msaa_helper(struct pipe_context *pctx,
> void u_transfer_unmap_msaa_helper(struct pipe_context *pctx,
> struct pipe_transfer *ptrans);
>
> +void *
> +u_transfer_map_z32f_s8_helper(struct pipe_context *pctx,
> + struct pipe_resource *z,
> + struct pipe_resource *s,
> + unsigned level, unsigned usage,
> + const struct pipe_box *box,
> + struct pipe_transfer **pptrans,
> + void *(*callback)(struct pipe_context *pctx,
> + struct pipe_resource *prsc,
> + unsigned level, unsigned usage,
> + const struct pipe_box *box,
> + struct pipe_transfer **pptrans));
> +
> +void u_transfer_unmap_z32f_s8_helper(struct pipe_context *pctx,
> + struct pipe_transfer *ptrans,
> + void (*callback)(struct pipe_context *pctx,
> + struct pipe_transfer *ptrans));
> +
> boolean u_default_resource_get_handle(struct pipe_screen *screen,
> struct pipe_resource *resource,
> struct winsys_handle *handle);
> --
> 2.15.0
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/mesa-dev
More information about the mesa-dev
mailing list