summaryrefslogtreecommitdiff
path: root/lib/mesa/src/gallium/auxiliary/util/u_transfer_helper.c
diff options
context:
space:
mode:
authorJonathan Gray <jsg@cvs.openbsd.org>2021-07-22 10:17:30 +0000
committerJonathan Gray <jsg@cvs.openbsd.org>2021-07-22 10:17:30 +0000
commitca11beabae33eb59fb981b8adf50b1d47a2a98f0 (patch)
tree3e4691a396e6e54cd54224a190663d5cf976625b /lib/mesa/src/gallium/auxiliary/util/u_transfer_helper.c
parent27c8a50e8bbde7d28b1fc46d715a4c469e24f2c4 (diff)
Import Mesa 21.1.5
Diffstat (limited to 'lib/mesa/src/gallium/auxiliary/util/u_transfer_helper.c')
-rw-r--r--lib/mesa/src/gallium/auxiliary/util/u_transfer_helper.c137
1 files changed, 130 insertions, 7 deletions
diff --git a/lib/mesa/src/gallium/auxiliary/util/u_transfer_helper.c b/lib/mesa/src/gallium/auxiliary/util/u_transfer_helper.c
index 0ba8abdf7..47898e0bd 100644
--- a/lib/mesa/src/gallium/auxiliary/util/u_transfer_helper.c
+++ b/lib/mesa/src/gallium/auxiliary/util/u_transfer_helper.c
@@ -148,8 +148,8 @@ u_transfer_helper_resource_destroy(struct pipe_screen *pscreen,
static bool needs_pack(unsigned usage)
{
- return (usage & PIPE_TRANSFER_READ) &&
- !(usage & (PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE | PIPE_TRANSFER_DISCARD_RANGE));
+ return (usage & PIPE_MAP_READ) &&
+ !(usage & (PIPE_MAP_DISCARD_WHOLE_RESOURCE | PIPE_MAP_DISCARD_RANGE));
}
/* In the case of transfer_map of a multi-sample resource, call back into
@@ -351,13 +351,14 @@ flush_region(struct pipe_context *pctx, struct pipe_transfer *ptrans,
const struct pipe_box *box)
{
struct u_transfer_helper *helper = pctx->screen->transfer_helper;
- struct u_transfer *trans = u_transfer(ptrans);
+ /* using the function here hits an assert for the deinterleave cases */
+ struct u_transfer *trans = (struct u_transfer *)ptrans;
enum pipe_format iformat, format = ptrans->resource->format;
unsigned width = box->width;
unsigned height = box->height;
void *src, *dst;
- if (!(ptrans->usage & PIPE_TRANSFER_WRITE))
+ if (!(ptrans->usage & PIPE_MAP_WRITE))
return;
if (trans->ss) {
@@ -401,7 +402,7 @@ flush_region(struct pipe_context *pctx, struct pipe_transfer *ptrans,
src,
ptrans->stride,
width, height);
- /* fallthru */
+ FALLTHROUGH;
case PIPE_FORMAT_X32_S8X24_UINT:
dst = (uint8_t *)trans->ptr2 +
(box->y * trans->trans2->stride) +
@@ -418,7 +419,7 @@ flush_region(struct pipe_context *pctx, struct pipe_transfer *ptrans,
util_format_z32_unorm_unpack_z_32unorm(dst, trans->trans->stride,
src, ptrans->stride,
width, height);
- /* fallthru */
+ FALLTHROUGH;
case PIPE_FORMAT_X24S8_UINT:
dst = (uint8_t *)trans->ptr2 +
(box->y * trans->trans2->stride) +
@@ -494,7 +495,7 @@ u_transfer_helper_transfer_unmap(struct pipe_context *pctx,
if (handle_transfer(ptrans->resource)) {
struct u_transfer *trans = u_transfer(ptrans);
- if (!(ptrans->usage & PIPE_TRANSFER_FLUSH_EXPLICIT)) {
+ if (!(ptrans->usage & PIPE_MAP_FLUSH_EXPLICIT)) {
struct pipe_box box;
u_box_2d(0, 0, ptrans->box.width, ptrans->box.height, &box);
flush_region(pctx, ptrans, &box);
@@ -544,3 +545,125 @@ u_transfer_helper_destroy(struct u_transfer_helper *helper)
{
free(helper);
}
+
+
+/* these two functions 'deinterleave' are meant to be used without the corresponding
+ * resource_create/destroy hooks, as they perform the interleaving on-the-fly
+ *
+ * drivers should expect to be passed the same buffer repeatedly with the format changed
+ * to indicate which component is being mapped
+ */
+void *
+u_transfer_helper_deinterleave_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_helper *helper = pctx->screen->transfer_helper;
+ struct u_transfer *trans;
+ struct pipe_transfer *ptrans;
+ enum pipe_format format = prsc->format;
+ unsigned width = box->width;
+ unsigned height = box->height;
+
+ if (!((helper->separate_stencil && util_format_is_depth_and_stencil(format)) ||
+ (format == PIPE_FORMAT_Z32_FLOAT_S8X24_UINT && helper->separate_z32s8)))
+ return helper->vtbl->transfer_map(pctx, prsc, level, usage, box, pptrans);
+
+ debug_assert(box->depth == 1);
+
+ trans = calloc(1, sizeof(*trans));
+ if (!trans)
+ return NULL;
+
+ ptrans = &trans->base;
+ pipe_resource_reference(&ptrans->resource, prsc);
+ ptrans->level = level;
+ ptrans->usage = usage;
+ ptrans->box = *box;
+ ptrans->stride = util_format_get_stride(format, box->width);
+ ptrans->layer_stride = ptrans->stride * box->height;
+
+ trans->staging = malloc(ptrans->layer_stride);
+ if (!trans->staging)
+ goto fail;
+
+ trans->ptr = helper->vtbl->transfer_map(pctx, prsc, level, usage | PIPE_MAP_DEPTH_ONLY, box,
+ &trans->trans);
+ if (!trans->ptr)
+ goto fail;
+
+ trans->ptr2 = helper->vtbl->transfer_map(pctx, prsc, level,
+ usage | PIPE_MAP_STENCIL_ONLY, box, &trans->trans2);
+ if (needs_pack(usage)) {
+ switch (prsc->format) {
+ case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT:
+ util_format_z32_float_s8x24_uint_pack_z_float(trans->staging,
+ ptrans->stride,
+ trans->ptr,
+ trans->trans->stride,
+ width, height);
+ util_format_z32_float_s8x24_uint_pack_s_8uint(trans->staging,
+ ptrans->stride,
+ trans->ptr2,
+ trans->trans2->stride,
+ width, height);
+ break;
+ case PIPE_FORMAT_Z24_UNORM_S8_UINT:
+ util_format_z24_unorm_s8_uint_pack_separate(trans->staging,
+ ptrans->stride,
+ trans->ptr,
+ trans->trans->stride,
+ trans->ptr2,
+ trans->trans2->stride,
+ width, height);
+ break;
+ default:
+ unreachable("Unexpected format");
+ }
+ }
+
+ *pptrans = ptrans;
+ return trans->staging;
+
+fail:
+ if (trans->trans)
+ helper->vtbl->transfer_unmap(pctx, trans->trans);
+ if (trans->trans2)
+ helper->vtbl->transfer_unmap(pctx, trans->trans2);
+ pipe_resource_reference(&ptrans->resource, NULL);
+ free(trans->staging);
+ free(trans);
+ return NULL;
+}
+
+void
+u_transfer_helper_deinterleave_transfer_unmap(struct pipe_context *pctx,
+ struct pipe_transfer *ptrans)
+{
+ struct u_transfer_helper *helper = pctx->screen->transfer_helper;
+ enum pipe_format format = ptrans->resource->format;
+
+ if ((helper->separate_stencil && util_format_is_depth_and_stencil(format)) ||
+ (format == PIPE_FORMAT_Z32_FLOAT_S8X24_UINT && helper->separate_z32s8)) {
+ struct u_transfer *trans = (struct u_transfer *)ptrans;
+
+ if (!(ptrans->usage & PIPE_MAP_FLUSH_EXPLICIT)) {
+ struct pipe_box box;
+ u_box_2d(0, 0, ptrans->box.width, ptrans->box.height, &box);
+ flush_region(pctx, ptrans, &box);
+ }
+
+ helper->vtbl->transfer_unmap(pctx, trans->trans);
+ if (trans->trans2)
+ helper->vtbl->transfer_unmap(pctx, trans->trans2);
+
+ pipe_resource_reference(&ptrans->resource, NULL);
+
+ free(trans->staging);
+ free(trans);
+ } else {
+ helper->vtbl->transfer_unmap(pctx, ptrans);
+ }
+}