iris: Return idle status from iris_invalidate_buffer, skip busy checks
authorKenneth Graunke <kenneth@whitecape.org>
Fri, 30 Sep 2022 00:56:29 +0000 (17:56 -0700)
committerMarge Bot <emma+marge@anholt.net>
Fri, 9 Dec 2022 21:46:03 +0000 (21:46 +0000)
If we successfully replace the backing storage for a buffer, we know
that it's idle, and the transfer map code can mark it unsynchronized
right away, letting us skip redundant resource_is_busy() checks.

Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/19209>

src/gallium/drivers/iris/iris_resource.c

index 5e994fd..c620ef4 100644 (file)
@@ -1914,47 +1914,54 @@ iris_replace_buffer_storage(struct pipe_context *ctx,
    iris_bo_unreference(old_bo);
 }
 
-static void
-iris_invalidate_resource(struct pipe_context *ctx,
-                         struct pipe_resource *resource)
+/**
+ * Discard a buffer's contents and replace it's backing storage with a
+ * fresh, idle buffer if necessary.
+ *
+ * Returns true if the storage can be considered idle.
+ */
+static bool
+iris_invalidate_buffer(struct iris_context *ice, struct iris_resource *res)
 {
-   struct iris_screen *screen = (void *) ctx->screen;
-   struct iris_context *ice = (void *) ctx;
-   struct iris_resource *res = (void *) resource;
+   struct iris_screen *screen = (void *) ice->ctx.screen;
 
-   if (resource->target != PIPE_BUFFER)
-      return;
+   if (res->base.b.target != PIPE_BUFFER)
+      return false;
 
-   /* If it's already invalidated, don't bother doing anything. */
+   /* If it's already invalidated, don't bother doing anything.
+    * We consider the storage to be idle, because either it was freshly
+    * allocated (and not busy), or a previous call here was what cleared
+    * the range, and that call replaced the storage with an idle buffer.
+    */
    if (res->valid_buffer_range.start > res->valid_buffer_range.end)
-      return;
+      return true;
 
    if (!resource_is_busy(ice, res)) {
       /* The resource is idle, so just mark that it contains no data and
        * keep using the same underlying buffer object.
        */
       util_range_set_empty(&res->valid_buffer_range);
-      return;
+      return true;
    }
 
    /* Otherwise, try and replace the backing storage with a new BO. */
 
    /* We can't reallocate memory we didn't allocate in the first place. */
    if (res->bo->gem_handle && res->bo->real.userptr)
-      return;
+      return false;
 
    /* Nor can we allocate buffers we imported or exported. */
    if (iris_bo_is_external(res->bo))
-      return;
+      return false;
 
    struct iris_bo *old_bo = res->bo;
    struct iris_bo *new_bo =
-      iris_bo_alloc(screen->bufmgr, res->bo->name, resource->width0,
-                    iris_buffer_alignment(resource->width0),
+      iris_bo_alloc(screen->bufmgr, res->bo->name, res->base.b.width0,
+                    iris_buffer_alignment(res->base.b.width0),
                     iris_memzone_for_address(old_bo->address),
                     old_bo->real.protected ? BO_ALLOC_PROTECTED : 0);
    if (!new_bo)
-      return;
+      return false;
 
    /* Swap out the backing storage */
    res->bo = new_bo;
@@ -1967,6 +1974,19 @@ iris_invalidate_resource(struct pipe_context *ctx,
    util_range_set_empty(&res->valid_buffer_range);
 
    iris_bo_unreference(old_bo);
+
+   /* The new buffer is idle. */
+   return true;
+}
+
+static void
+iris_invalidate_resource(struct pipe_context *ctx,
+                         struct pipe_resource *resource)
+{
+   struct iris_context *ice = (void *) ctx;
+   struct iris_resource *res = (void *) resource;
+
+   iris_invalidate_buffer(ice, res);
 }
 
 static void
@@ -2399,9 +2419,9 @@ iris_transfer_map(struct pipe_context *ctx,
 
    if (usage & PIPE_MAP_DISCARD_WHOLE_RESOURCE) {
       /* Replace the backing storage with a fresh buffer for non-async maps */
-      if (!(usage & (PIPE_MAP_UNSYNCHRONIZED |
-                     TC_TRANSFER_MAP_NO_INVALIDATE)))
-         iris_invalidate_resource(ctx, resource);
+      if (!(usage & (PIPE_MAP_UNSYNCHRONIZED | TC_TRANSFER_MAP_NO_INVALIDATE))
+          && iris_invalidate_buffer(ice, res))
+         usage |= PIPE_MAP_UNSYNCHRONIZED;
 
       /* If we can discard the whole resource, we can discard the range. */
       usage |= PIPE_MAP_DISCARD_RANGE;