[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