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 <davidriley@chromium.org> Reviewed-by: Gurchetan Singh <gurchetansingh@chromium.org>
This commit is contained in:
committed by
Gurchetan Singh
parent
e94a9a7f38
commit
a54c231b56
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user