[Mesa-dev] [PATCH v2 4/5] gallium: Make a helper for doing Z32_FLOAT_S8X24_UINT mappings.
Rob Clark
robdclark at gmail.com
Tue Nov 28 14:01:31 UTC 2017
On Tue, Nov 21, 2017 at 4:13 PM, Eric Anholt <eric at anholt.net> wrote:
> v2: Remove the callback, leave avoiding the recursion up to the caller
> (probably by rewriting the vtbl either in pctx or u_resource_vtbl)
hmm, that is still a bit ugly.. and looking at the equiv thing that
Ilia implemented in freedreno, I think there is also so special
handling needed for ->transfer_flush_region()..
If you don't want to add it in u_resource/_vtbl (and I agree, a per
rsc vtbl is kinda unneeded), maybe we could introduce in a similar
way, u_transfer_vtbl/u_transfer_resource/u_transfer, ie.
struct u_transfer_resource {
struct pipe_resource b;
struct pipe_resource *stencil; /* holds separate stencil buffer
for z32x24s8 */
}
struct u_transfer {
struct pipe_transfer b;
void *staging;
}
struct u_transfer_vtbl {
struct pipe_resource (*resource_create)(...);
void (*resource_destroy)(...);
void *(*transfer_map)(...);
void (*transfer_flush_region)(...);
void (*transfer_unmap)(...);
bool lower_z32s8;
bool lower_rgtc;
}
Note that I had schemes to move the rgtc handling that freedreno does
over to this new scheme too. Probably the MSAA resolve stuff could be
folded into this same scheme, I haven't thought about that yet.
The vtbl ptr doesn't have to be global. I think we can just stash a
pointer in pipe_context like what is done for draw module and a few
other things.
If you want, I can take a stab at this approach, since I'm also
messing w/ a staging buffer approach for uploads to flushed but busy
buffers/textures to avoid a stall, and that gets easier once the
staging stuff is separated ;-)
BR,
-R
> ---
> src/gallium/auxiliary/util/u_transfer.c | 114 ++++++++++++++++++++++++++++++++
> src/gallium/auxiliary/util/u_transfer.h | 11 +++
> 2 files changed, 125 insertions(+)
>
> diff --git a/src/gallium/auxiliary/util/u_transfer.c b/src/gallium/auxiliary/util/u_transfer.c
> index 104d0505aaa8..2d219721dcf8 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,116 @@ 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 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.
> + *
> + * In both the map and unmap paths, the driver will need to be careful to
> + * unwrap its transfer_map()/unmap() method that would call us, so that it
> + * doesn't recurse when we call back into it.
> + */
> +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)
> +{
> + 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 = pctx->transfer_map(pctx, z, level, usage, box,
> + &trans->z_ptrans);
> + if (!trans->z)
> + goto fail_unref;
> + trans->s = pctx->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)
> +{
> + 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);
> + }
> +
> + pctx->transfer_unmap(pctx, trans->s_ptrans);
> + pctx->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..0a8a649df1f5 100644
> --- a/src/gallium/auxiliary/util/u_transfer.h
> +++ b/src/gallium/auxiliary/util/u_transfer.h
> @@ -24,6 +24,17 @@ 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 u_transfer_unmap_z32f_s8_helper(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