panvk: merge vm_bind ops in some cases

Some apps exhibit bind patterns that can be easily implemented in
terms of fewer vm_bind ops than we currently do.

For now let's only optimize the case when a vm_bind op is
contiguous wrt the previous one on the right, in both VA and
BO (if applicable) ranges. With this optimization alone we already
get a decent reduction in some CTS sparse tests.

Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/38986>
This commit is contained in:
Caterina Shablia 2026-01-23 14:49:03 +00:00 committed by Marge Bot
parent 5279eb7dfc
commit 09c2fadf90

View file

@ -174,11 +174,48 @@ panvk_bind_queue_submit_flush(struct panvk_bind_queue_submit *submit)
return ret;
}
static bool
panvk_try_merge_vm_bind_ops(struct drm_panthor_vm_bind_op *a,
const struct drm_panthor_vm_bind_op *b)
{
if (a->flags != b->flags)
return false;
/* See panvk_bind_queue_submit_vm_bind */
assert(b->syncs.count == 0);
enum drm_panthor_vm_bind_op_flags op_type = a->flags & DRM_PANTHOR_VM_BIND_OP_TYPE_MASK;
if (op_type != DRM_PANTHOR_VM_BIND_OP_TYPE_MAP &&
op_type != DRM_PANTHOR_VM_BIND_OP_TYPE_UNMAP)
return false;
if (a->va + a->size != b->va)
return false;
if (op_type == DRM_PANTHOR_VM_BIND_OP_TYPE_MAP &&
(a->bo_handle != b->bo_handle ||
a->bo_offset + a->size != b->bo_offset))
return false;
a->size += b->size;
return true;
}
static int
panvk_bind_queue_submit_vm_bind(
struct panvk_bind_queue_submit *submit,
const struct drm_panthor_vm_bind_op *op)
{
/* We handle all of the syncs here and in
* panvk_bind_queue_submit_process_signals */
assert(op->syncs.count == 0);
if (submit->bind_op_count > 0) {
struct drm_panthor_vm_bind_op *prev = &submit->bind_ops[submit->bind_op_count - 1];
if (panvk_try_merge_vm_bind_ops(prev, op))
return 0;
}
if (submit->bind_op_count == submit->bind_op_cap) {
int ret = panvk_bind_queue_submit_flush(submit);
if (ret)
@ -186,7 +223,6 @@ panvk_bind_queue_submit_vm_bind(
}
struct drm_panthor_vm_bind_op tmp = *op;
assert(!tmp.syncs.array);
if (submit->sync_ops.wait_count > 0) {
tmp.syncs = (struct drm_panthor_obj_array)DRM_PANTHOR_OBJ_ARRAY(
submit->sync_ops.wait_count, submit->sync_ops.waits);