[Mesa-dev] [PATCH v2 4/5] gallium: Make a helper for doing Z32_FLOAT_S8X24_UINT mappings.

Eric Anholt eric at anholt.net
Tue Nov 21 21:13:07 UTC 2017


v2: Remove the callback, leave avoiding the recursion up to the caller
    (probably by rewriting the vtbl either in pctx or u_resource_vtbl)
---
 src/gallium/auxiliary/util/u_transfer.c | 114 ++++++++++++++++++++++++++++++++
 src/gallium/auxiliary/util/u_transfer.h |  11 +++
 2 files changed, 125 insertions(+)

diff --git a/src/gallium/auxiliary/util/u_transfer.c b/src/gallium/auxiliary/util/u_transfer.c
index 104d0505aaa8..2d219721dcf8 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,116 @@ 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 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.
+ *
+ * In both the map and unmap paths, the driver will need to be careful to
+ * unwrap its transfer_map()/unmap() method that would call us, so that it
+ * doesn't recurse when we call back into it.
+ */
+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)
+{
+   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 = pctx->transfer_map(pctx, z, level, usage, box,
+                                 &trans->z_ptrans);
+   if (!trans->z)
+      goto fail_unref;
+   trans->s = pctx->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)
+{
+   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);
+   }
+
+   pctx->transfer_unmap(pctx, trans->s_ptrans);
+   pctx->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..0a8a649df1f5 100644
--- a/src/gallium/auxiliary/util/u_transfer.h
+++ b/src/gallium/auxiliary/util/u_transfer.h
@@ -24,6 +24,17 @@ 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 u_transfer_unmap_z32f_s8_helper(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