diff options
author | David Riley <[email protected]> | 2019-04-24 16:11:37 -0700 |
---|---|---|
committer | Gurchetan Singh <[email protected]> | 2019-05-01 15:48:46 -0700 |
commit | a54c231b56005f172cbd744fb7c592922b077526 (patch) | |
tree | d340c4868716b43269ad6bea6a94f3e490055728 /src/gallium/drivers/virgl | |
parent | e94a9a7f38de13230d1fb8767c45e6c8f4e59c64 (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.c | 51 | ||||
-rw-r--r-- | src/gallium/drivers/virgl/virgl_transfer_queue.h | 7 |
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); |