freedreno: Extract out helper for transfer-map flag munging
authorRob Clark <robdclark@chromium.org>
Thu, 4 Mar 2021 20:27:13 +0000 (12:27 -0800)
committerMarge Bot <eric+marge@anholt.net>
Thu, 11 Mar 2021 04:42:16 +0000 (04:42 +0000)
Split out the usage simplification from main part of transfer_map and
handle the threaded-context specific TC_TRANSFER_x flags.

Signed-off-by: Rob Clark <robdclark@chromium.org>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/9323>

src/gallium/drivers/freedreno/freedreno_resource.c

index 0958794..d2115bf 100644 (file)
@@ -729,19 +729,9 @@ resource_transfer_map(struct pipe_context *pctx,
                }
        }
 
-       if (ctx->in_shadow && !(usage & PIPE_MAP_READ))
-               usage |= PIPE_MAP_UNSYNCHRONIZED;
-
        if (usage & PIPE_MAP_DISCARD_WHOLE_RESOURCE) {
                invalidate_resource(rsc, usage);
-       } else if ((usage & PIPE_MAP_WRITE) &&
-                          prsc->target == PIPE_BUFFER &&
-                          !util_ranges_intersect(&rsc->valid_buffer_range,
-                                                                         box->x, box->x + box->width)) {
-               /* We are trying to write to a previously uninitialized range. No need
-                * to wait.
-                */
-       } else if (!(usage & PIPE_MAP_UNSYNCHRONIZED)) {
+       } else {
                struct fd_batch *write_batch = NULL;
 
                /* hold a reference, so it doesn't disappear under us: */
@@ -772,6 +762,8 @@ resource_transfer_map(struct pipe_context *pctx,
                 */
                if (ctx->screen->reorder && busy && !(usage & PIPE_MAP_READ) &&
                                (usage & PIPE_MAP_DISCARD_RANGE)) {
+                       assert(!(usage & TC_TRANSFER_MAP_NO_INVALIDATE));
+
                        /* try shadowing only if it avoids a flush, otherwise staging would
                         * be better:
                         */
@@ -834,6 +826,40 @@ resource_transfer_map(struct pipe_context *pctx,
        return resource_transfer_map_unsync(pctx, prsc, level, usage, box, trans);
 }
 
+static unsigned
+improve_transfer_map_usage(struct fd_context *ctx, struct fd_resource *rsc,
+               unsigned usage, const struct pipe_box *box)
+       /* Not *strictly* true, but the access to things that must only be in driver-
+        * thread are protected by !(usage & TC_TRANSFER_MAP_THREADED_UNSYNC):
+        */
+       in_dt
+{
+       if (usage & TC_TRANSFER_MAP_NO_INVALIDATE) {
+               usage &= ~PIPE_MAP_DISCARD_WHOLE_RESOURCE;
+               usage &= ~PIPE_MAP_DISCARD_RANGE;
+       }
+
+       if (usage & TC_TRANSFER_MAP_THREADED_UNSYNC)
+               usage |= PIPE_MAP_UNSYNCHRONIZED;
+
+       if (!(usage & (TC_TRANSFER_MAP_NO_INFER_UNSYNCHRONIZED |
+                       PIPE_MAP_UNSYNCHRONIZED))) {
+               if (ctx->in_shadow && !(usage & PIPE_MAP_READ)) {
+                       usage |= PIPE_MAP_UNSYNCHRONIZED;
+               } else if ((usage & PIPE_MAP_WRITE) &&
+                                  (rsc->b.b.target == PIPE_BUFFER) &&
+                                  !util_ranges_intersect(&rsc->valid_buffer_range,
+                                                                                 box->x, box->x + box->width)) {
+                       /* We are trying to write to a previously uninitialized range. No need
+                        * to synchronize.
+                        */
+                       usage |= PIPE_MAP_UNSYNCHRONIZED;
+               }
+       }
+
+       return usage;
+}
+
 static void *
 fd_resource_transfer_map(struct pipe_context *pctx,
                struct pipe_resource *prsc,
@@ -862,6 +888,8 @@ fd_resource_transfer_map(struct pipe_context *pctx,
        trans = fd_transfer(ptrans);
        memset(trans, 0, sizeof(*trans));
 
+       usage = improve_transfer_map_usage(ctx, rsc, usage, box);
+
        pipe_resource_reference(&ptrans->resource, prsc);
        ptrans->level = level;
        ptrans->usage = usage;
@@ -870,7 +898,7 @@ fd_resource_transfer_map(struct pipe_context *pctx,
        ptrans->layer_stride = fd_resource_layer_stride(rsc, level);
 
        void *ret;
-       if (usage & (PIPE_MAP_UNSYNCHRONIZED | TC_TRANSFER_MAP_THREADED_UNSYNC)) {
+       if (usage & PIPE_MAP_UNSYNCHRONIZED) {
                ret = resource_transfer_map_unsync(pctx, prsc, level, usage, box, trans);
        } else {
                ret = resource_transfer_map(pctx, prsc, level, usage, box, trans);