[Mesa-dev] [PATCH 4/5] gallium: Make a helper for doing Z32_FLOAT_S8X24_UINT mappings.
Eric Anholt
eric at anholt.net
Fri Nov 17 02:19:58 UTC 2017
---
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
More information about the mesa-dev
mailing list