st/nine: Track pending MANAGED buffer uploads
authorAxel Davy <davyaxel0@gmail.com>
Fri, 5 Mar 2021 17:23:22 +0000 (18:23 +0100)
committerMarge Bot <eric+marge@anholt.net>
Sat, 13 Mar 2021 21:23:24 +0000 (21:23 +0000)
The tracking enables to avoid flushing the csmt thread
when locking repeatedly the same buffer, as long
as the locks are non-overlapping.

Signed-off-by: Axel Davy <davyaxel0@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/9451>

src/gallium/frontends/nine/buffer9.c
src/gallium/frontends/nine/buffer9.h

index 9f02667..3fde6a7 100644 (file)
@@ -255,10 +255,14 @@ NineBuffer9_Lock( struct NineBuffer9 *This,
                 assert(list_is_empty(&This->managed.list));
                 This->managed.dirty = TRUE;
                 This->managed.dirty_box = box;
-                if (p_atomic_read(&This->managed.pending_upload))
-                    nine_csmt_process(This->base.base.device);
+                /* Flush if regions pending to be uploaded would be dirtied */
+                if (p_atomic_read(&This->managed.pending_upload)) {
+                    u_box_intersect_1d(&box, &box, &This->managed.upload_pending_regions);
+                    if (box.width != 0)
+                        nine_csmt_process(This->base.base.device);
+                }
             } else
-                u_box_union_2d(&This->managed.dirty_box, &This->managed.dirty_box, &box);
+                u_box_union_1d(&This->managed.dirty_box, &This->managed.dirty_box, &box);
             /* Tests trying to draw while the buffer is locked show that
              * MANAGED buffers are made dirty at Lock time */
             BASEBUF_REGISTER_UPDATE(This);
index b3dec7f..8b2bcc8 100644 (file)
@@ -31,6 +31,7 @@
 #include "pipe/p_context.h"
 #include "pipe/p_state.h"
 #include "util/list.h"
+#include "util/u_box.h"
 
 struct pipe_screen;
 struct pipe_context;
@@ -63,7 +64,8 @@ struct NineBuffer9
     struct {
         void *data;
         boolean dirty;
-        struct pipe_box dirty_box;
+        struct pipe_box dirty_box; /* region in the resource to update */
+        struct pipe_box upload_pending_regions; /* region with uploads pending */
         struct list_head list; /* for update_buffers */
         struct list_head list2; /* for managed_buffers */
         unsigned pending_upload; /* for uploads */
@@ -105,6 +107,13 @@ NineBuffer9_Upload( struct NineBuffer9 *This )
     struct NineDevice9 *device = This->base.base.device;
 
     assert(This->base.pool != D3DPOOL_DEFAULT && This->managed.dirty);
+    if (This->managed.pending_upload) {
+        u_box_union_1d(&This->managed.upload_pending_regions,
+                       &This->managed.upload_pending_regions,
+                       &This->managed.dirty_box);
+    } else {
+        This->managed.upload_pending_regions = This->managed.dirty_box;
+    }
     nine_context_range_upload(device, &This->managed.pending_upload,
                               (struct NineUnknown *)This,
                               This->base.resource,