--- 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)) +{ + 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@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev