Re: [Mesa-dev] [PATCH 1/2] gallium/util: add u_transfer_helper
Rob Clarkwrites: > 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. Update on changes between versions? > > Signed-off-by: Rob Clark > --- > src/gallium/auxiliary/Makefile.sources | 2 + > src/gallium/auxiliary/meson.build | 2 + > src/gallium/auxiliary/util/u_transfer_helper.c | 499 > + > src/gallium/auxiliary/util/u_transfer_helper.h | 135 +++ > src/gallium/include/pipe/p_screen.h| 8 +- > 5 files changed, 645 insertions(+), 1 deletion(-) > create mode 100644 src/gallium/auxiliary/util/u_transfer_helper.c > create mode 100644 src/gallium/auxiliary/util/u_transfer_helper.h > > diff --git a/src/gallium/auxiliary/Makefile.sources > b/src/gallium/auxiliary/Makefile.sources > index f40c4723fae..a2dae04698c 100644 > --- a/src/gallium/auxiliary/Makefile.sources > +++ b/src/gallium/auxiliary/Makefile.sources > @@ -304,6 +304,8 @@ C_SOURCES := \ > util/u_tile.h \ > util/u_transfer.c \ > util/u_transfer.h \ > + util/u_transfer_helper.c \ > + util/u_transfer_helper.h \ > util/u_threaded_context.c \ > util/u_threaded_context.h \ > util/u_threaded_context_calls.h \ > diff --git a/src/gallium/auxiliary/meson.build > b/src/gallium/auxiliary/meson.build > index 3e623fd099f..8c242ec1a05 100644 > --- a/src/gallium/auxiliary/meson.build > +++ b/src/gallium/auxiliary/meson.build > @@ -324,6 +324,8 @@ files_libgallium = files( >'util/u_tile.h', >'util/u_transfer.c', >'util/u_transfer.h', > + 'util/u_transfer_helper.c', > + 'util/u_transfer_helper.h', >'util/u_threaded_context.c', >'util/u_threaded_context.h', >'util/u_threaded_context_calls.h', > diff --git a/src/gallium/auxiliary/util/u_transfer_helper.c > b/src/gallium/auxiliary/util/u_transfer_helper.c > new file mode 100644 > index 000..c987a35b36c > --- /dev/null > +++ b/src/gallium/auxiliary/util/u_transfer_helper.c > @@ -0,0 +1,499 @@ > +/* > + * 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. > + */ > + > +#include "pipe/p_screen.h" > + > +#include "util/u_box.h" > +#include "util/u_format.h" > +#include "util/u_format_rgtc.h" > +#include "util/u_format_zs.h" > +#include "util/u_inlines.h" > +#include "util/u_transfer_helper.h" > + > + > +struct u_transfer_helper { > + const struct u_transfer_vtbl *vtbl; > + bool separate_z32s8; > + bool fake_rgtc; > + bool msaa_map; > +}; > + > +static inline bool handle_transfer(struct pipe_resource *prsc) > +{ > + struct u_transfer_helper *helper = prsc->screen->transfer_helper; > + > + if (helper->vtbl->get_internal_format) { > + enum pipe_format internal_format = > +helper->vtbl->get_internal_format(prsc); > + if (internal_format != prsc->format) > + return true; > + } > + > + if (helper->msaa_map && (prsc->nr_samples > 1)) > + return true; > + > + return false; > +} > + > +/* The
[Mesa-dev] [PATCH 1/2] gallium/util: add u_transfer_helper
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. Signed-off-by: Rob Clark--- src/gallium/auxiliary/Makefile.sources | 2 + src/gallium/auxiliary/meson.build | 2 + src/gallium/auxiliary/util/u_transfer_helper.c | 499 + src/gallium/auxiliary/util/u_transfer_helper.h | 135 +++ src/gallium/include/pipe/p_screen.h| 8 +- 5 files changed, 645 insertions(+), 1 deletion(-) create mode 100644 src/gallium/auxiliary/util/u_transfer_helper.c create mode 100644 src/gallium/auxiliary/util/u_transfer_helper.h diff --git a/src/gallium/auxiliary/Makefile.sources b/src/gallium/auxiliary/Makefile.sources index f40c4723fae..a2dae04698c 100644 --- a/src/gallium/auxiliary/Makefile.sources +++ b/src/gallium/auxiliary/Makefile.sources @@ -304,6 +304,8 @@ C_SOURCES := \ util/u_tile.h \ util/u_transfer.c \ util/u_transfer.h \ + util/u_transfer_helper.c \ + util/u_transfer_helper.h \ util/u_threaded_context.c \ util/u_threaded_context.h \ util/u_threaded_context_calls.h \ diff --git a/src/gallium/auxiliary/meson.build b/src/gallium/auxiliary/meson.build index 3e623fd099f..8c242ec1a05 100644 --- a/src/gallium/auxiliary/meson.build +++ b/src/gallium/auxiliary/meson.build @@ -324,6 +324,8 @@ files_libgallium = files( 'util/u_tile.h', 'util/u_transfer.c', 'util/u_transfer.h', + 'util/u_transfer_helper.c', + 'util/u_transfer_helper.h', 'util/u_threaded_context.c', 'util/u_threaded_context.h', 'util/u_threaded_context_calls.h', diff --git a/src/gallium/auxiliary/util/u_transfer_helper.c b/src/gallium/auxiliary/util/u_transfer_helper.c new file mode 100644 index 000..c987a35b36c --- /dev/null +++ b/src/gallium/auxiliary/util/u_transfer_helper.c @@ -0,0 +1,499 @@ +/* + * 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. + */ + +#include "pipe/p_screen.h" + +#include "util/u_box.h" +#include "util/u_format.h" +#include "util/u_format_rgtc.h" +#include "util/u_format_zs.h" +#include "util/u_inlines.h" +#include "util/u_transfer_helper.h" + + +struct u_transfer_helper { + const struct u_transfer_vtbl *vtbl; + bool separate_z32s8; + bool fake_rgtc; + bool msaa_map; +}; + +static inline bool handle_transfer(struct pipe_resource *prsc) +{ + struct u_transfer_helper *helper = prsc->screen->transfer_helper; + + if (helper->vtbl->get_internal_format) { + enum pipe_format internal_format = +helper->vtbl->get_internal_format(prsc); + if (internal_format != prsc->format) + return true; + } + + if (helper->msaa_map && (prsc->nr_samples > 1)) + return true; + + return false; +} + +/* The pipe_transfer ptr could either be the driver's, or u_transfer, + * depending on whether we are intervening or not. Check handle_transfer() + * before dereferencing. + */ +struct u_transfer { + struct pipe_transfer base; + /* Note that in case of MSAA resolve for transfer plus z32s8 or fake rgtc +* we
[Mesa-dev] [PATCH 1/2] gallium/util: add u_transfer_helper
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. Signed-off-by: Rob Clark--- src/gallium/auxiliary/Makefile.sources | 2 + src/gallium/auxiliary/meson.build | 2 + src/gallium/auxiliary/util/u_transfer_helper.c | 486 + src/gallium/auxiliary/util/u_transfer_helper.h | 132 +++ src/gallium/include/pipe/p_screen.h| 8 +- 5 files changed, 629 insertions(+), 1 deletion(-) create mode 100644 src/gallium/auxiliary/util/u_transfer_helper.c create mode 100644 src/gallium/auxiliary/util/u_transfer_helper.h diff --git a/src/gallium/auxiliary/Makefile.sources b/src/gallium/auxiliary/Makefile.sources index f40c4723fae..a2dae04698c 100644 --- a/src/gallium/auxiliary/Makefile.sources +++ b/src/gallium/auxiliary/Makefile.sources @@ -304,6 +304,8 @@ C_SOURCES := \ util/u_tile.h \ util/u_transfer.c \ util/u_transfer.h \ + util/u_transfer_helper.c \ + util/u_transfer_helper.h \ util/u_threaded_context.c \ util/u_threaded_context.h \ util/u_threaded_context_calls.h \ diff --git a/src/gallium/auxiliary/meson.build b/src/gallium/auxiliary/meson.build index 3e623fd099f..8c242ec1a05 100644 --- a/src/gallium/auxiliary/meson.build +++ b/src/gallium/auxiliary/meson.build @@ -324,6 +324,8 @@ files_libgallium = files( 'util/u_tile.h', 'util/u_transfer.c', 'util/u_transfer.h', + 'util/u_transfer_helper.c', + 'util/u_transfer_helper.h', 'util/u_threaded_context.c', 'util/u_threaded_context.h', 'util/u_threaded_context_calls.h', diff --git a/src/gallium/auxiliary/util/u_transfer_helper.c b/src/gallium/auxiliary/util/u_transfer_helper.c new file mode 100644 index 000..6f7a36a5f6d --- /dev/null +++ b/src/gallium/auxiliary/util/u_transfer_helper.c @@ -0,0 +1,486 @@ +/* + * 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. + */ + +#include "pipe/p_screen.h" + +#include "util/u_box.h" +#include "util/u_format.h" +#include "util/u_format_rgtc.h" +#include "util/u_format_zs.h" +#include "util/u_inlines.h" +#include "util/u_transfer_helper.h" + + +struct u_transfer_helper { + const struct u_transfer_vtbl *vtbl; + bool separate_z32s8; + bool fake_rgtc; + bool msaa_map; +}; + +static inline bool handle_transfer(struct pipe_resource *prsc) +{ + struct u_transfer_helper *helper = prsc->screen->transfer_helper; + + if (helper->vtbl->get_internal_format) { + enum pipe_format internal_format = +helper->vtbl->get_internal_format(prsc); + if (internal_format != prsc->format) + return true; + } + + if (helper->msaa_map && (prsc->nr_samples > 1)) + return true; + + return false; +} + +/* The pipe_transfer ptr could either be the driver's, or u_transfer, + * depending on whether we are intervening or not. Check handle_transfer() + * before dereferencing. + */ +struct u_transfer { + struct pipe_transfer base; + /* Note that in case of MSAA resolve for transfer plus z32s8 or fake rgtc +* we
Re: [Mesa-dev] [PATCH 1/2] gallium/util: add u_transfer_helper
On Wed, Dec 6, 2017 at 4:48 PM, Eric Anholtwrote: > Rob Clark 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. oh, whoops.. and I guess in theory I should use those dimensions for the MSAA blit too.. > That said, I don't think you can reach flush_region with explicit flush > for non-buffer resources? hmm, not 100% sure about the APIs on the GL side of things, but I think if that were the case mesa/st would dtrt. (I guess it could be different w/ gallium9, not that I have a big collection of windows arm games to play :-P) >> + >> + if (!(ptrans->usage & PIPE_TRANSFER_WRITE)) >> + return; >> + >> + if (trans->ss) { >> + struct pipe_blit_info blit; >> + memset(, 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, ); >> + >> + 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: >> +
Re: [Mesa-dev] [PATCH 1/2] gallium/util: add u_transfer_helper
Rob Clarkwrites: > 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(, 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, ); > + > + 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 000..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
[Mesa-dev] [PATCH 1/2] gallium/util: add u_transfer_helper
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. Signed-off-by: Rob Clark--- src/gallium/auxiliary/Makefile.sources | 2 + src/gallium/auxiliary/meson.build | 2 + src/gallium/auxiliary/util/u_transfer_helper.c | 486 + src/gallium/auxiliary/util/u_transfer_helper.h | 132 +++ src/gallium/include/pipe/p_screen.h| 8 +- 5 files changed, 629 insertions(+), 1 deletion(-) create mode 100644 src/gallium/auxiliary/util/u_transfer_helper.c create mode 100644 src/gallium/auxiliary/util/u_transfer_helper.h diff --git a/src/gallium/auxiliary/Makefile.sources b/src/gallium/auxiliary/Makefile.sources index f40c4723fae..a2dae04698c 100644 --- a/src/gallium/auxiliary/Makefile.sources +++ b/src/gallium/auxiliary/Makefile.sources @@ -304,6 +304,8 @@ C_SOURCES := \ util/u_tile.h \ util/u_transfer.c \ util/u_transfer.h \ + util/u_transfer_helper.c \ + util/u_transfer_helper.h \ util/u_threaded_context.c \ util/u_threaded_context.h \ util/u_threaded_context_calls.h \ diff --git a/src/gallium/auxiliary/meson.build b/src/gallium/auxiliary/meson.build index 3e623fd099f..8c242ec1a05 100644 --- a/src/gallium/auxiliary/meson.build +++ b/src/gallium/auxiliary/meson.build @@ -324,6 +324,8 @@ files_libgallium = files( 'util/u_tile.h', 'util/u_transfer.c', 'util/u_transfer.h', + 'util/u_transfer_helper.c', + 'util/u_transfer_helper.h', 'util/u_threaded_context.c', 'util/u_threaded_context.h', 'util/u_threaded_context_calls.h', diff --git a/src/gallium/auxiliary/util/u_transfer_helper.c b/src/gallium/auxiliary/util/u_transfer_helper.c new file mode 100644 index 000..6f7a36a5f6d --- /dev/null +++ b/src/gallium/auxiliary/util/u_transfer_helper.c @@ -0,0 +1,486 @@ +/* + * 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. + */ + +#include "pipe/p_screen.h" + +#include "util/u_box.h" +#include "util/u_format.h" +#include "util/u_format_rgtc.h" +#include "util/u_format_zs.h" +#include "util/u_inlines.h" +#include "util/u_transfer_helper.h" + + +struct u_transfer_helper { + const struct u_transfer_vtbl *vtbl; + bool separate_z32s8; + bool fake_rgtc; + bool msaa_map; +}; + +static inline bool handle_transfer(struct pipe_resource *prsc) +{ + struct u_transfer_helper *helper = prsc->screen->transfer_helper; + + if (helper->vtbl->get_internal_format) { + enum pipe_format internal_format = +helper->vtbl->get_internal_format(prsc); + if (internal_format != prsc->format) + return true; + } + + if (helper->msaa_map && (prsc->nr_samples > 1)) + return true; + + return false; +} + +/* The pipe_transfer ptr could either be the driver's, or u_transfer, + * depending on whether we are intervening or not. Check handle_transfer() + * before dereferencing. + */ +struct u_transfer { + struct pipe_transfer base; + /* Note that in case of MSAA resolve for transfer plus z32s8 or fake rgtc +* we
Re: [Mesa-dev] [PATCH 1/2] gallium/util: add u_transfer_helper
On Thu, Nov 30, 2017 at 10:33 AM, Rob Clarkwrote: > On Thu, Nov 30, 2017 at 10:04 AM, Nicolai Hähnle wrote: >> On 29.11.2017 14:48, Rob Clark wrote: >>> >>> 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 >>> >>> This could be possibly extended to handle MSAA resolve in map/unmap. >> >> >> This looks mostly fine (though the MSAA thing needs to be resolved one way > > I was hoping if Eric was interested in using this, that maybe he could > add in the MSAA resolve bits.. otherwise that might have to wait until > I implement non-fake MSAA. > >> or the other), except there's a clash if you ever want to use threaded >> contexts, which have their own threaded_resource and threaded_transfer. >> >> I haven't really given any thought yet to how to reconcile those. > > hmm, ok, I see the issue.. maybe it is ok though, if the driver > installs the u_transfer_helper_* pipe fxns in the threaded_context > that wraps the real context, and the vtbl used by u_transfer_helper > has the threaded_context fxns instead of actual driver fxns. (Since > the transfer_helper is installed into the pipe_screen, it means you > couldn't mix threaded and non-threaded contexts under a single > screen.. not sure if there is ever a reason to do that?) hmm, so the issue actually is there but not w/ threaded_transfer vs u_transfer.. instead with threaded_resource vs u_transfer_resource. :-/ u_transfer_helper really only needs to track the additional stencil buffer and internal_format (although maybe adding MSAA resolves could add more to that).. possibly I could track that a different way (setter/getter fxns in vtbl?) BR, -R > There are two cases with the transfer-helper: > > 1) the transfer is passed directly through to the driver and not > intercepted. In which case the pipe_transfer returned from > ->transfer_map() is the driver's transfer_map (which doesn't subclass > u_transfer.. which I should probably move to the .c file) > > 2) the transfer is handled by the helper, in which case the helper > calls the driver's original ->transfer_map() via vtbl. In this case > the pipe_transfer passed back to st is u_transfer, but it has pointers > to the driver's real pipe_transfer(s). The pointers to the real > pipe_transfer's could just as well be threaded_transfer's. > > In either case, the driver doesn't need to subclass u_transfer.. which > I should move to .c to make move obvious, I guess. > > So possibly threaded_context_create() might need to gain a 'bool > use_transfer_helper' arg, or something like that. But doesn't seem > like a major problem. > > BR, > -R > >> Cheers, >> Nicolai >> >> >> >>> >>> Signed-off-by: Rob Clark >>> --- >>> src/gallium/auxiliary/Makefile.sources | 2 + >>> src/gallium/auxiliary/meson.build | 2 + >>> src/gallium/auxiliary/util/u_transfer_helper.c | 364 >>> + >>> src/gallium/auxiliary/util/u_transfer_helper.h | 121 >>> src/gallium/include/pipe/p_screen.h| 8 +- >>> 5 files changed, 496 insertions(+), 1 deletion(-) >>> create mode 100644 src/gallium/auxiliary/util/u_transfer_helper.c >>> create mode 100644 src/gallium/auxiliary/util/u_transfer_helper.h >>> >>> diff --git a/src/gallium/auxiliary/Makefile.sources >>> b/src/gallium/auxiliary/Makefile.sources >>> index f40c4723fae..a2dae04698c 100644 >>> --- a/src/gallium/auxiliary/Makefile.sources >>> +++ b/src/gallium/auxiliary/Makefile.sources >>> @@ -304,6 +304,8 @@ C_SOURCES := \ >>> util/u_tile.h \ >>> util/u_transfer.c \ >>> util/u_transfer.h \ >>> + util/u_transfer_helper.c \ >>> + util/u_transfer_helper.h \ >>> util/u_threaded_context.c \ >>> util/u_threaded_context.h \ >>> util/u_threaded_context_calls.h \ >>> diff --git a/src/gallium/auxiliary/meson.build >>> b/src/gallium/auxiliary/meson.build >>> index 3e623fd099f..8c242ec1a05 100644 >>> --- a/src/gallium/auxiliary/meson.build >>> +++ b/src/gallium/auxiliary/meson.build >>> @@ -324,6 +324,8 @@ files_libgallium = files( >>> 'util/u_tile.h', >>> 'util/u_transfer.c', >>> 'util/u_transfer.h', >>> + 'util/u_transfer_helper.c', >>> + 'util/u_transfer_helper.h', >>> 'util/u_threaded_context.c', >>> 'util/u_threaded_context.h', >>>
Re: [Mesa-dev] [PATCH 1/2] gallium/util: add u_transfer_helper
On Thu, Nov 30, 2017 at 10:04 AM, Nicolai Hähnlewrote: > On 29.11.2017 14:48, Rob Clark wrote: >> >> 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 >> >> This could be possibly extended to handle MSAA resolve in map/unmap. > > > This looks mostly fine (though the MSAA thing needs to be resolved one way I was hoping if Eric was interested in using this, that maybe he could add in the MSAA resolve bits.. otherwise that might have to wait until I implement non-fake MSAA. > or the other), except there's a clash if you ever want to use threaded > contexts, which have their own threaded_resource and threaded_transfer. > > I haven't really given any thought yet to how to reconcile those. hmm, ok, I see the issue.. maybe it is ok though, if the driver installs the u_transfer_helper_* pipe fxns in the threaded_context that wraps the real context, and the vtbl used by u_transfer_helper has the threaded_context fxns instead of actual driver fxns. (Since the transfer_helper is installed into the pipe_screen, it means you couldn't mix threaded and non-threaded contexts under a single screen.. not sure if there is ever a reason to do that?) There are two cases with the transfer-helper: 1) the transfer is passed directly through to the driver and not intercepted. In which case the pipe_transfer returned from ->transfer_map() is the driver's transfer_map (which doesn't subclass u_transfer.. which I should probably move to the .c file) 2) the transfer is handled by the helper, in which case the helper calls the driver's original ->transfer_map() via vtbl. In this case the pipe_transfer passed back to st is u_transfer, but it has pointers to the driver's real pipe_transfer(s). The pointers to the real pipe_transfer's could just as well be threaded_transfer's. In either case, the driver doesn't need to subclass u_transfer.. which I should move to .c to make move obvious, I guess. So possibly threaded_context_create() might need to gain a 'bool use_transfer_helper' arg, or something like that. But doesn't seem like a major problem. BR, -R > Cheers, > Nicolai > > > >> >> Signed-off-by: Rob Clark >> --- >> src/gallium/auxiliary/Makefile.sources | 2 + >> src/gallium/auxiliary/meson.build | 2 + >> src/gallium/auxiliary/util/u_transfer_helper.c | 364 >> + >> src/gallium/auxiliary/util/u_transfer_helper.h | 121 >> src/gallium/include/pipe/p_screen.h| 8 +- >> 5 files changed, 496 insertions(+), 1 deletion(-) >> create mode 100644 src/gallium/auxiliary/util/u_transfer_helper.c >> create mode 100644 src/gallium/auxiliary/util/u_transfer_helper.h >> >> diff --git a/src/gallium/auxiliary/Makefile.sources >> b/src/gallium/auxiliary/Makefile.sources >> index f40c4723fae..a2dae04698c 100644 >> --- a/src/gallium/auxiliary/Makefile.sources >> +++ b/src/gallium/auxiliary/Makefile.sources >> @@ -304,6 +304,8 @@ C_SOURCES := \ >> util/u_tile.h \ >> util/u_transfer.c \ >> util/u_transfer.h \ >> + util/u_transfer_helper.c \ >> + util/u_transfer_helper.h \ >> util/u_threaded_context.c \ >> util/u_threaded_context.h \ >> util/u_threaded_context_calls.h \ >> diff --git a/src/gallium/auxiliary/meson.build >> b/src/gallium/auxiliary/meson.build >> index 3e623fd099f..8c242ec1a05 100644 >> --- a/src/gallium/auxiliary/meson.build >> +++ b/src/gallium/auxiliary/meson.build >> @@ -324,6 +324,8 @@ files_libgallium = files( >> 'util/u_tile.h', >> 'util/u_transfer.c', >> 'util/u_transfer.h', >> + 'util/u_transfer_helper.c', >> + 'util/u_transfer_helper.h', >> 'util/u_threaded_context.c', >> 'util/u_threaded_context.h', >> 'util/u_threaded_context_calls.h', >> diff --git a/src/gallium/auxiliary/util/u_transfer_helper.c >> b/src/gallium/auxiliary/util/u_transfer_helper.c >> new file mode 100644 >> index 000..fb4024db35b >> --- /dev/null >> +++ b/src/gallium/auxiliary/util/u_transfer_helper.c >> @@ -0,0 +1,364 @@ >> +/* >> + * 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
Re: [Mesa-dev] [PATCH 1/2] gallium/util: add u_transfer_helper
On 29.11.2017 14:48, Rob Clark wrote: 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 This could be possibly extended to handle MSAA resolve in map/unmap. This looks mostly fine (though the MSAA thing needs to be resolved one way or the other), except there's a clash if you ever want to use threaded contexts, which have their own threaded_resource and threaded_transfer. I haven't really given any thought yet to how to reconcile those. Cheers, Nicolai Signed-off-by: Rob Clark--- src/gallium/auxiliary/Makefile.sources | 2 + src/gallium/auxiliary/meson.build | 2 + src/gallium/auxiliary/util/u_transfer_helper.c | 364 + src/gallium/auxiliary/util/u_transfer_helper.h | 121 src/gallium/include/pipe/p_screen.h| 8 +- 5 files changed, 496 insertions(+), 1 deletion(-) create mode 100644 src/gallium/auxiliary/util/u_transfer_helper.c create mode 100644 src/gallium/auxiliary/util/u_transfer_helper.h diff --git a/src/gallium/auxiliary/Makefile.sources b/src/gallium/auxiliary/Makefile.sources index f40c4723fae..a2dae04698c 100644 --- a/src/gallium/auxiliary/Makefile.sources +++ b/src/gallium/auxiliary/Makefile.sources @@ -304,6 +304,8 @@ C_SOURCES := \ util/u_tile.h \ util/u_transfer.c \ util/u_transfer.h \ + util/u_transfer_helper.c \ + util/u_transfer_helper.h \ util/u_threaded_context.c \ util/u_threaded_context.h \ util/u_threaded_context_calls.h \ diff --git a/src/gallium/auxiliary/meson.build b/src/gallium/auxiliary/meson.build index 3e623fd099f..8c242ec1a05 100644 --- a/src/gallium/auxiliary/meson.build +++ b/src/gallium/auxiliary/meson.build @@ -324,6 +324,8 @@ files_libgallium = files( 'util/u_tile.h', 'util/u_transfer.c', 'util/u_transfer.h', + 'util/u_transfer_helper.c', + 'util/u_transfer_helper.h', 'util/u_threaded_context.c', 'util/u_threaded_context.h', 'util/u_threaded_context_calls.h', diff --git a/src/gallium/auxiliary/util/u_transfer_helper.c b/src/gallium/auxiliary/util/u_transfer_helper.c new file mode 100644 index 000..fb4024db35b --- /dev/null +++ b/src/gallium/auxiliary/util/u_transfer_helper.c @@ -0,0 +1,364 @@ +/* + * 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. + */ + +#include "pipe/p_screen.h" + +#include "util/u_box.h" +#include "util/u_format.h" +#include "util/u_format_rgtc.h" +#include "util/u_format_zs.h" +#include "util/u_inlines.h" +#include "util/u_transfer_helper.h" + + +struct u_transfer_helper { + const struct u_transfer_vtbl *vtbl; + bool separate_z32s8; + bool fake_rgtc; + bool msaa_map; +}; + +static inline bool handle_transfer(struct pipe_resource *prsc) +{ + struct u_transfer_helper *helper = prsc->screen->transfer_helper; + struct u_transfer_resource *rsc = u_transfer_resource(prsc); + return (rsc->internal_format != prsc->format) || + (helper->msaa_map && (prsc->nr_samples > 1)); +} + +/* The pipe_transfer ptr could either be the driver's, or u_transfer, + * depending on whether we are intervening or not. Check handle_transfer() + * before dereferencing. + */ +struct u_transfer { + struct pipe_transfer base; + struct pipe_transfer *trans; /* driver's transfer */
[Mesa-dev] [PATCH 1/2] gallium/util: add u_transfer_helper
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 This could be possibly extended to handle MSAA resolve in map/unmap. Signed-off-by: Rob Clark--- src/gallium/auxiliary/Makefile.sources | 2 + src/gallium/auxiliary/meson.build | 2 + src/gallium/auxiliary/util/u_transfer_helper.c | 364 + src/gallium/auxiliary/util/u_transfer_helper.h | 121 src/gallium/include/pipe/p_screen.h| 8 +- 5 files changed, 496 insertions(+), 1 deletion(-) create mode 100644 src/gallium/auxiliary/util/u_transfer_helper.c create mode 100644 src/gallium/auxiliary/util/u_transfer_helper.h diff --git a/src/gallium/auxiliary/Makefile.sources b/src/gallium/auxiliary/Makefile.sources index f40c4723fae..a2dae04698c 100644 --- a/src/gallium/auxiliary/Makefile.sources +++ b/src/gallium/auxiliary/Makefile.sources @@ -304,6 +304,8 @@ C_SOURCES := \ util/u_tile.h \ util/u_transfer.c \ util/u_transfer.h \ + util/u_transfer_helper.c \ + util/u_transfer_helper.h \ util/u_threaded_context.c \ util/u_threaded_context.h \ util/u_threaded_context_calls.h \ diff --git a/src/gallium/auxiliary/meson.build b/src/gallium/auxiliary/meson.build index 3e623fd099f..8c242ec1a05 100644 --- a/src/gallium/auxiliary/meson.build +++ b/src/gallium/auxiliary/meson.build @@ -324,6 +324,8 @@ files_libgallium = files( 'util/u_tile.h', 'util/u_transfer.c', 'util/u_transfer.h', + 'util/u_transfer_helper.c', + 'util/u_transfer_helper.h', 'util/u_threaded_context.c', 'util/u_threaded_context.h', 'util/u_threaded_context_calls.h', diff --git a/src/gallium/auxiliary/util/u_transfer_helper.c b/src/gallium/auxiliary/util/u_transfer_helper.c new file mode 100644 index 000..fb4024db35b --- /dev/null +++ b/src/gallium/auxiliary/util/u_transfer_helper.c @@ -0,0 +1,364 @@ +/* + * 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. + */ + +#include "pipe/p_screen.h" + +#include "util/u_box.h" +#include "util/u_format.h" +#include "util/u_format_rgtc.h" +#include "util/u_format_zs.h" +#include "util/u_inlines.h" +#include "util/u_transfer_helper.h" + + +struct u_transfer_helper { + const struct u_transfer_vtbl *vtbl; + bool separate_z32s8; + bool fake_rgtc; + bool msaa_map; +}; + +static inline bool handle_transfer(struct pipe_resource *prsc) +{ + struct u_transfer_helper *helper = prsc->screen->transfer_helper; + struct u_transfer_resource *rsc = u_transfer_resource(prsc); + return (rsc->internal_format != prsc->format) || + (helper->msaa_map && (prsc->nr_samples > 1)); +} + +/* The pipe_transfer ptr could either be the driver's, or u_transfer, + * depending on whether we are intervening or not. Check handle_transfer() + * before dereferencing. + */ +struct u_transfer { + struct pipe_transfer base; + struct pipe_transfer *trans; /* driver's transfer */ + struct pipe_transfer *trans2; /* 2nd transfer for z32s8 */ + void *ptr, *ptr2; /* ptr to trans, and trans2 */ + void *staging; /* staging buffer */ +}; + +static inline struct u_transfer * +u_transfer(struct pipe_transfer *ptrans) +{ + debug_assert(handle_transfer(ptrans->resource)); + return (struct u_transfer *)ptrans; +} +