summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/virgl
diff options
context:
space:
mode:
authorDavid Riley <[email protected]>2019-04-24 16:11:37 -0700
committerGurchetan Singh <[email protected]>2019-05-01 15:48:46 -0700
commita54c231b56005f172cbd744fb7c592922b077526 (patch)
treed340c4868716b43269ad6bea6a94f3e490055728 /src/gallium/drivers/virgl
parente94a9a7f38de13230d1fb8767c45e6c8f4e59c64 (diff)
virgl: Allow transfer queue entries to be found and extended.
Intersecting transfer queue entries allow for the possibility of extending an existing transfer instead of creating a new one (and all the associated mappign/unmapping). Signed-off-by: David Riley <[email protected]> Reviewed-by: Gurchetan Singh <[email protected]>
Diffstat (limited to 'src/gallium/drivers/virgl')
-rw-r--r--src/gallium/drivers/virgl/virgl_transfer_queue.c51
-rw-r--r--src/gallium/drivers/virgl/virgl_transfer_queue.h7
2 files changed, 58 insertions, 0 deletions
diff --git a/src/gallium/drivers/virgl/virgl_transfer_queue.c b/src/gallium/drivers/virgl/virgl_transfer_queue.c
index 6551d6a2cdb..4831cbd235c 100644
--- a/src/gallium/drivers/virgl/virgl_transfer_queue.c
+++ b/src/gallium/drivers/virgl/virgl_transfer_queue.c
@@ -106,6 +106,14 @@ static void set_true(UNUSED struct virgl_transfer_queue *queue,
*val = true;
}
+static void set_queued(UNUSED struct virgl_transfer_queue *queue,
+ struct list_action_args *args)
+{
+ struct virgl_transfer *queued = args->queued;
+ struct virgl_transfer **val = args->data;
+ *val = queued;
+}
+
static void remove_transfer(struct virgl_transfer_queue *queue,
struct list_action_args *args)
{
@@ -175,6 +183,26 @@ static void compare_and_perform_action(struct virgl_transfer_queue *queue,
}
}
+static void intersect_and_set_queued_once(struct virgl_transfer_queue *queue,
+ struct list_iteration_args *iter)
+{
+ struct list_action_args args;
+ struct virgl_transfer *queued, *tmp;
+ enum virgl_transfer_queue_lists type = iter->type;
+
+ memset(&args, 0, sizeof(args));
+ args.current = iter->current;
+ args.data = iter->data;
+
+ LIST_FOR_EACH_ENTRY_SAFE(queued, tmp, &queue->lists[type], queue_link) {
+ if (transfers_intersect(queued, iter->current)) {
+ args.queued = queued;
+ set_queued(queue, &args);
+ return;
+ }
+ }
+}
+
static void perform_action(struct virgl_transfer_queue *queue,
struct list_iteration_args *iter)
{
@@ -331,3 +359,26 @@ bool virgl_transfer_queue_is_queued(struct virgl_transfer_queue *queue,
return queued;
}
+
+struct virgl_transfer *
+virgl_transfer_queue_extend(struct virgl_transfer_queue *queue,
+ struct virgl_transfer *transfer)
+{
+ struct virgl_transfer *queued = NULL;
+ struct list_iteration_args iter;
+
+ if (transfer->base.resource->target == PIPE_BUFFER) {
+ memset(&iter, 0, sizeof(iter));
+ iter.current = transfer;
+ iter.data = &queued;
+ iter.type = PENDING_LIST;
+ intersect_and_set_queued_once(queue, &iter);
+ }
+
+ if (queued) {
+ u_box_union_2d(&queued->base.box, &queued->base.box, &transfer->base.box);
+ queued->offset = queued->base.box.x;
+ }
+
+ return queued;
+}
diff --git a/src/gallium/drivers/virgl/virgl_transfer_queue.h b/src/gallium/drivers/virgl/virgl_transfer_queue.h
index 3aebae0620b..403a0f1f4d7 100644
--- a/src/gallium/drivers/virgl/virgl_transfer_queue.h
+++ b/src/gallium/drivers/virgl/virgl_transfer_queue.h
@@ -51,3 +51,10 @@ int virgl_transfer_queue_clear(struct virgl_transfer_queue *queue,
bool virgl_transfer_queue_is_queued(struct virgl_transfer_queue *queue,
struct virgl_transfer *transfer);
+
+/*
+ * Search the transfer queue for a transfer suitable for extension and
+ * extend it to include the new transfer.
+ */
+struct virgl_transfer * virgl_transfer_queue_extend(
+ struct virgl_transfer_queue *queue, struct virgl_transfer *transfer);