[Mesa-dev] [PATCH 1/2] gallium/util: add u_transfer_helper
Eric Anholt
eric at anholt.net
Wed Dec 6 21:48:34 UTC 2017
Rob Clark <robdclark at gmail.com> writes:
> Add a new helper that drivers can use to emulate various things that
> need special handling in particular in transfer_map:
>
> 1) z32_s8x24.. gl/gallium treats this as a single buffer with depth
> and stencil interleaved but hardware frequently treats this as
> separate z32 and s8 buffers. Special pack/unpack handling is
> needed in transfer_map/unmap to pack/unpack the exposed buffer
>
> 2) fake RGTC.. GPUs designed with GLES in mind, but which can other-
> wise do GL3, if native RGTC is not supported it can be emulated
> by converting to uncompressed internally, but needs pack/unpack
> in transfer_map/unmap
>
> 3) MSAA resolves in the transfer_map() case
>
> v2: add MSAA resolve based on Eric's "gallium: Add helpers for MSAA
> resolves in pipe_transfer_map()/unmap()." patch; avoid wrapping
> pipe_resource, to make it possible for drivers to use both this
> and threaded_context.
The driver side is clean enough with this layer that I'm pretty happy
now. Just one significant review comment, then I think we'll be
ready...
> +static void
> +flush_region(struct pipe_context *pctx, struct pipe_transfer *ptrans,
> + const struct pipe_box *box)
> +{
> + struct u_transfer *trans = u_transfer(ptrans);
> + enum pipe_format format = ptrans->resource->format;
> + unsigned width = ptrans->box.width;
> + unsigned height = ptrans->box.height;
It seems silly to be implementing flush_region and ignoring the box
argument to flush the entire mapped region on every call. We should
either drop this implementation in favor of the no-op and flush at
unmap, or actually use the box in the flushes.
That said, I don't think you can reach flush_region with explicit flush
for non-buffer resources?
> +
> + if (!(ptrans->usage & PIPE_TRANSFER_WRITE))
> + return;
> +
> + if (trans->ss) {
> + struct pipe_blit_info blit;
> + memset(&blit, 0, sizeof(blit));
> +
> + blit.src.resource = trans->ss;
> + blit.src.format = trans->ss->format;
> + blit.src.box.width = ptrans->box.width;
> + blit.src.box.height = ptrans->box.height;
> + blit.src.box.depth = 1;
> +
> + blit.dst.resource = ptrans->resource;
> + blit.dst.format = ptrans->resource->format;
> + blit.dst.level = ptrans->level;
> + blit.dst.box = ptrans->box;
> +
> + blit.mask = util_format_get_mask(ptrans->resource->format);
> + blit.filter = PIPE_TEX_FILTER_NEAREST;
> +
> + pctx->blit(pctx, &blit);
> +
> + return;
> + }
> +
> + switch (format) {
> + case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT:
> + util_format_z32_float_s8x24_uint_unpack_z_float(trans->ptr,
> + trans->trans->stride,
> + trans->staging,
> + ptrans->stride,
> + width, height);
> + /* fallthru */
> + case PIPE_FORMAT_X32_S8X24_UINT:
> + util_format_z32_float_s8x24_uint_unpack_s_8uint(trans->ptr2,
> + trans->trans2->stride,
> + trans->staging,
> + ptrans->stride,
> + width, height);
> + break;
> + case PIPE_FORMAT_RGTC1_UNORM:
> + case PIPE_FORMAT_RGTC1_SNORM:
> + case PIPE_FORMAT_LATC1_UNORM:
> + case PIPE_FORMAT_LATC1_SNORM:
> + util_format_rgtc1_unorm_unpack_rgba_8unorm(trans->ptr,
> + trans->trans->stride,
> + trans->staging,
> + ptrans->stride,
> + width, height);
> + break;
> + case PIPE_FORMAT_RGTC2_UNORM:
> + case PIPE_FORMAT_RGTC2_SNORM:
> + case PIPE_FORMAT_LATC2_UNORM:
> + case PIPE_FORMAT_LATC2_SNORM:
> + util_format_rgtc2_unorm_unpack_rgba_8unorm(trans->ptr,
> + trans->trans->stride,
> + trans->staging,
> + ptrans->stride,
> + width, height);
> + break;
> + default:
> + assert(!"Unexpected staging transfer type");
> + break;
> + }
> +}
> diff --git a/src/gallium/auxiliary/util/u_transfer_helper.h b/src/gallium/auxiliary/util/u_transfer_helper.h
> new file mode 100644
> index 00000000000..392b34f0697
> --- /dev/null
> +++ b/src/gallium/auxiliary/util/u_transfer_helper.h
> @@ -0,0 +1,132 @@
> +/*
> + * Copyright © 2017 Red Hat
> + *
> + * Permission is hereby granted, free of charge, to any person obtaining a
> + * copy of this software and associated documentation files (the "Software"),
> + * to deal in the Software without restriction, including without limitation
> + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
> + * and/or sell copies of the Software, and to permit persons to whom the
> + * Software is furnished to do so, subject to the following conditions:
> + *
> + * The above copyright notice and this permission notice (including the next
> + * paragraph) shall be included in all copies or substantial portions of the
> + * Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
> + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
> + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
> + * SOFTWARE.
> + */
> +
> +#ifndef _U_TRANSFER_HELPER_H
> +#define _U_TRANSFER_HELPER_H
> +
> +#include "pipe/p_state.h"
> +#include "pipe/p_context.h"
> +
> +#ifdef __cplusplus
> +extern "C" {
> +#endif
> +
> +/* A helper to implement various "lowering" for transfers:
> + *
> + * - exposing separate z32 and s8 as z32x24s8
> + * - fake RGTC support for GLES class hardware which needs it to expose GL3+
> + * - MSAA resolves
> + *
> + * To use this, drivers should:
> + *
> + * 1) populate u_transfer_vtbl and plug that into pipe_screen::transfer_helper
> + * 2) plug the the transfer helpers into pipe_screen/pipe_context
s/the the/the/
> + *
> + * To avoid subclassing pipe_resource (and conflicting with threaded_context)
> + * the vtbl contains setter/getter methods used for fake_rgct & separate_stencil
> + * to access the internal_format and separate stencil buffer.
> + */
> +
> +struct u_transfer_vtbl {
> + /* NOTE I am not expecting resource_create_from_handle() or
> + * resource_create_with_modifiers() paths to be creating any
> + * resources that need special handling. Otherwise they would
> + * need to be wrapped too.
> + */
> + struct pipe_resource * (*resource_create)(struct pipe_screen *pscreen,
> + const struct pipe_resource *templ);
> +
> + void (*resource_destroy)(struct pipe_screen *pscreen,
> + struct pipe_resource *prsc);
> +
> + void *(*transfer_map)(struct pipe_context *pctx,
> + struct pipe_resource *prsc,
> + unsigned level,
> + unsigned usage,
> + const struct pipe_box *box,
> + struct pipe_transfer **pptrans);
> +
> +
> + void (*transfer_flush_region)(struct pipe_context *pctx,
> + struct pipe_transfer *ptrans,
> + const struct pipe_box *box);
> +
> + void (*transfer_unmap)(struct pipe_context *pctx,
> + struct pipe_transfer *ptrans);
> +
> + /*
> + * auxiliary methods to access internal format, stencil:
> + */
> +
> + /**
> + * Must be implemented if separate_z32s8 or fake_rgtc is used. The
> + * internal_format is the format the resource was created with. In
> + * the case of separate_z32s8 or fake_rgtc, prsc->format is set back
> + * to the state tracker visible format (Z32_FLOAT_S8X24_UINT or
> + * PIPE_FORMAT_{RTGC,LATC}* after the resource is created.
> + */
> + enum pipe_format (*get_internal_format)(struct pipe_resource *prsc);
> +
> + /**
> + * Must be implemented if separate_z32s8 is used. Used to set/get
> + * the separate s8 stencil buffer.
> + */
> + void (*set_stencil)(struct pipe_resource *prsc, struct pipe_resource *stencil);
> + struct pipe_resource *(*get_stencil)(struct pipe_resource *prsc);
Maybe we should note that these two ops are intended to be pointer
assignments, not refcounted?
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 832 bytes
Desc: not available
URL: <https://lists.freedesktop.org/archives/mesa-dev/attachments/20171206/599115f4/attachment.sig>
More information about the mesa-dev
mailing list