Module: Mesa
Branch: master
Commit: dec68e32ea09e3163c39ee270782682621301370
URL:    
http://cgit.freedesktop.org/mesa/mesa/commit/?id=dec68e32ea09e3163c39ee270782682621301370

Author: David Riley <[email protected]>
Date:   Wed Apr 24 16:12:48 2019 -0700

virgl: Re-use and extend queue transfers for intersecting buffer subdatas.

Small buffer subdatas which are essentially doing a memcpy were getting
bogged down by all the overhead of creating new transfers.

Signed-off-by: David Riley <[email protected]>
Reviewed-by: Gurchetan Singh <[email protected]>

---

 src/gallium/drivers/virgl/virgl_resource.c | 46 ++++++++++++++++++++++++++++++
 1 file changed, 46 insertions(+)

diff --git a/src/gallium/drivers/virgl/virgl_resource.c 
b/src/gallium/drivers/virgl/virgl_resource.c
index 5f0040c1db1..ef81f213f40 100644
--- a/src/gallium/drivers/virgl/virgl_resource.c
+++ b/src/gallium/drivers/virgl/virgl_resource.c
@@ -132,6 +132,43 @@ void virgl_init_screen_resource_functions(struct 
pipe_screen *screen)
     screen->resource_destroy = u_resource_destroy_vtbl;
 }
 
+static bool virgl_buffer_transfer_extend(struct pipe_context *ctx,
+                                         struct pipe_resource *resource,
+                                         unsigned usage,
+                                         const struct pipe_box *box,
+                                         const void *data)
+{
+   struct virgl_context *vctx = virgl_context(ctx);
+   struct virgl_resource *vbuf = virgl_resource(resource);
+   struct virgl_transfer dummy_trans = { 0 };
+   bool flush;
+   struct virgl_transfer *queued;
+
+   /*
+    * Attempts to short circuit the entire process of mapping and unmapping
+    * a resource if there is an existing transfer that can be extended.
+    * Pessimestically falls back if a flush is required.
+    */
+   dummy_trans.base.resource = resource;
+   dummy_trans.base.usage = usage;
+   dummy_trans.base.box = *box;
+   dummy_trans.base.stride = vbuf->metadata.stride[0];
+   dummy_trans.base.layer_stride = vbuf->metadata.layer_stride[0];
+   dummy_trans.offset = box->x;
+
+   flush = virgl_res_needs_flush(vctx, &dummy_trans);
+   if (flush)
+      return false;
+
+   queued = virgl_transfer_queue_extend(&vctx->queue, &dummy_trans);
+   if (!queued || !queued->hw_res_map)
+      return false;
+
+   memcpy(queued->hw_res_map + dummy_trans.offset, data, box->width);
+
+   return true;
+}
+
 static void virgl_buffer_subdata(struct pipe_context *pipe,
                                  struct pipe_resource *resource,
                                  unsigned usage, unsigned offset,
@@ -139,6 +176,11 @@ static void virgl_buffer_subdata(struct pipe_context *pipe,
 {
    struct pipe_box box;
 
+   assert(!(usage & PIPE_TRANSFER_READ));
+
+   /* the write flag is implicit by the nature of buffer_subdata */
+   usage |= PIPE_TRANSFER_WRITE;
+
    if (offset == 0 && size == resource->width0)
       usage |= PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE;
    else
@@ -146,6 +188,10 @@ static void virgl_buffer_subdata(struct pipe_context *pipe,
 
    u_box_1d(offset, size, &box);
 
+   if (usage & PIPE_TRANSFER_DISCARD_RANGE &&
+       virgl_buffer_transfer_extend(pipe, resource, usage, &box, data))
+      return;
+
    if (resource->width0 >= getpagesize())
       u_default_buffer_subdata(pipe, resource, usage, offset, size, data);
    else

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

Reply via email to