On 28.11.2017 15:01, Rob Clark wrote:
On Tue, Nov 21, 2017 at 4:13 PM, Eric Anholt <[email protected]> wrote:
v2: Remove the callback, leave avoiding the recursion up to the caller
     (probably by rewriting the vtbl either in pctx or u_resource_vtbl)

hmm, that is still a bit ugly..  and looking at the equiv thing that
Ilia implemented in freedreno, I think there is also so special
handling needed for ->transfer_flush_region()..

If you don't want to add it in u_resource/_vtbl (and I agree, a per
rsc vtbl is kinda unneeded), maybe we could introduce in a similar
way, u_transfer_vtbl/u_transfer_resource/u_transfer, ie.

   struct u_transfer_resource {
      struct pipe_resource b;
      struct pipe_resource *stencil; /* holds separate stencil buffer
for z32x24s8 */
   }

   struct u_transfer {
      struct pipe_transfer b;
      void *staging;
   }

   struct u_transfer_vtbl {
      struct pipe_resource (*resource_create)(...);
      void (*resource_destroy)(...);
      void *(*transfer_map)(...);
      void (*transfer_flush_region)(...);
      void (*transfer_unmap)(...);
      bool lower_z32s8;
      bool lower_rgtc;
   }

I think this makes sense.

Keep in mind that u_threaded_context also has a threaded_transfer wrapper of pipe_transfer. It doesn't really do anything for textures, but it might be useful to stay compatible. It's unlikely that radeonsi will start using these helpers, but other drivers may want to use Gallium threading.

Cheers,
Nicolai



Note that I had schemes to move the rgtc handling that freedreno does
over to this new scheme too.  Probably the MSAA resolve stuff could be
folded into this same scheme, I haven't thought about that yet.

The vtbl ptr doesn't have to be global.  I think we can just stash a
pointer in pipe_context like what is done for draw module and a few
other things.

If you want, I can take a stab at this approach, since I'm also
messing w/ a staging buffer approach for uploads to flushed but busy
buffers/textures to avoid a stall, and that gets easier once the
staging stuff is separated ;-)

BR,
-R

---
  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

_______________________________________________
mesa-dev mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/mesa-dev
_______________________________________________
mesa-dev mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/mesa-dev



--
Lerne, wie die Welt wirklich ist,
Aber vergiss niemals, wie sie sein sollte.
_______________________________________________
mesa-dev mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to