mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-06-22 01:28:23 +02:00
panvk: Talk directly to pankmod when binding sparse resources
There's no longer need for the panvk_sparse library, or for panvk to care about whether the KMD can do native sparse mapping. Submit sparse VM bindings as a single operation and let pankmod handle the gory details. Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com> Signed-off-by: Adrián Larumbe <adrian.larumbe@collabora.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/40400>
This commit is contained in:
parent
19cf49f02f
commit
c95edade04
5 changed files with 26 additions and 164 deletions
|
|
@ -59,7 +59,6 @@ libpanvk_files = files(
|
|||
'panvk_mempool.c',
|
||||
'panvk_physical_device.c',
|
||||
'panvk_priv_bo.c',
|
||||
'panvk_sparse.c',
|
||||
'panvk_utrace.c',
|
||||
'panvk_wsi.c',
|
||||
)
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@
|
|||
#include "panvk_device.h"
|
||||
#include "panvk_device_memory.h"
|
||||
#include "panvk_entrypoints.h"
|
||||
#include "panvk_sparse.h"
|
||||
|
||||
#include "pan_props.h"
|
||||
|
||||
|
|
@ -130,10 +129,19 @@ panvk_CreateBuffer(VkDevice _device, const VkBufferCreateInfo *pCreateInfo,
|
|||
/* Map last so that we don't have a possibility of getting any more
|
||||
* errors, in which case we'd have to unmap.
|
||||
*/
|
||||
result = panvk_map_to_blackhole(device, buffer->vk.device_address,
|
||||
va_range);
|
||||
if (result != VK_SUCCESS) {
|
||||
result = panvk_error(device, result);
|
||||
struct pan_kmod_vm_op map = {
|
||||
.type = PAN_KMOD_VM_OP_TYPE_MAP,
|
||||
.va = {
|
||||
.start = buffer->vk.device_address,
|
||||
.size = va_range,
|
||||
},
|
||||
.flags = PAN_KMOD_VM_OP_OP_MAP_SPARSE,
|
||||
};
|
||||
|
||||
int ret = pan_kmod_vm_bind(device->kmod.vm,
|
||||
PAN_KMOD_VM_OP_MODE_IMMEDIATE, &map, 1);
|
||||
if (ret) {
|
||||
result = panvk_error(device, VK_ERROR_OUT_OF_DEVICE_MEMORY);
|
||||
goto err_free_va;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,7 +20,6 @@
|
|||
#include "panvk_image.h"
|
||||
#include "panvk_instance.h"
|
||||
#include "panvk_physical_device.h"
|
||||
#include "panvk_sparse.h"
|
||||
|
||||
#include "drm-uapi/drm_fourcc.h"
|
||||
#include "util/u_atomic.h"
|
||||
|
|
@ -721,10 +720,19 @@ panvk_CreateImage(VkDevice device, const VkImageCreateInfo *pCreateInfo,
|
|||
/* Map last so that we don't have a possibility of getting any more
|
||||
* errors, in which case we'd have to unmap.
|
||||
*/
|
||||
result = panvk_map_to_blackhole(dev, image->sparse.device_address,
|
||||
va_range);
|
||||
if (result != VK_SUCCESS) {
|
||||
result = panvk_error(dev, result);
|
||||
struct pan_kmod_vm_op map = {
|
||||
.type = PAN_KMOD_VM_OP_TYPE_MAP,
|
||||
.va = {
|
||||
.start = image->sparse.device_address,
|
||||
.size = va_range,
|
||||
},
|
||||
.flags = PAN_KMOD_VM_OP_OP_MAP_SPARSE,
|
||||
};
|
||||
|
||||
int ret = pan_kmod_vm_bind(dev->kmod.vm, PAN_KMOD_VM_OP_MODE_IMMEDIATE,
|
||||
&map, 1);
|
||||
if (ret) {
|
||||
result = panvk_error(device, VK_ERROR_OUT_OF_DEVICE_MEMORY);
|
||||
goto err_free_va;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,137 +0,0 @@
|
|||
/*
|
||||
* Copyright © 2025 Collabora Ltd.
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#include "panvk_device.h"
|
||||
#include "panvk_sparse.h"
|
||||
|
||||
#include "drm-uapi/panthor_drm.h"
|
||||
|
||||
static uint64_t
|
||||
panvk_choose_blackhole_size(const struct pan_kmod_vm *vm, uint64_t max_size)
|
||||
{
|
||||
uint64_t blackhole_size = 0;
|
||||
u_foreach_bit64(pgsize_bit, vm->pgsize_bitmap) {
|
||||
uint64_t pgsize = (uint64_t)1 << pgsize_bit;
|
||||
if (blackhole_size > 0 && pgsize > max_size)
|
||||
break;
|
||||
blackhole_size = pgsize;
|
||||
}
|
||||
|
||||
return blackhole_size;
|
||||
}
|
||||
|
||||
static void
|
||||
panvk_blackhole_init(const void *_dev)
|
||||
{
|
||||
struct panvk_device *dev = *(void *const *)_dev;
|
||||
|
||||
uint64_t blackhole_size = panvk_choose_blackhole_size(dev->kmod.vm, 0x200000);
|
||||
|
||||
dev->sparse_mem.blackhole =
|
||||
pan_kmod_bo_alloc(dev->kmod.dev, dev->kmod.vm, blackhole_size,
|
||||
PAN_KMOD_BO_FLAG_NO_MMAP);
|
||||
}
|
||||
|
||||
struct pan_kmod_bo *
|
||||
panvk_get_blackhole(struct panvk_device *dev)
|
||||
{
|
||||
util_call_once_data(&dev->sparse_mem.blackhole_once, panvk_blackhole_init, &dev);
|
||||
return dev->sparse_mem.blackhole;
|
||||
}
|
||||
|
||||
struct panvk_vm_binder {
|
||||
uint32_t drm_fd;
|
||||
uint32_t vm_id;
|
||||
|
||||
struct drm_panthor_vm_bind_op *ops;
|
||||
size_t op_count;
|
||||
size_t op_cap;
|
||||
};
|
||||
|
||||
static int
|
||||
panvk_vm_binder_flush(struct panvk_vm_binder *b)
|
||||
{
|
||||
if (b->op_count == 0)
|
||||
return 0;
|
||||
|
||||
struct drm_panthor_vm_bind req = {
|
||||
.vm_id = b->vm_id,
|
||||
.ops = DRM_PANTHOR_OBJ_ARRAY(b->op_count, b->ops),
|
||||
};
|
||||
int ret = pan_kmod_ioctl(b->drm_fd, DRM_IOCTL_PANTHOR_VM_BIND, &req);
|
||||
b->op_count = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
panvk_vm_binder_bind(struct panvk_vm_binder *b, const struct drm_panthor_vm_bind_op *op)
|
||||
{
|
||||
if (b->op_count == b->op_cap) {
|
||||
int ret = panvk_vm_binder_flush(b);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
assert(b->op_count < b->op_cap);
|
||||
b->ops[b->op_count++] = *op;
|
||||
return 0;
|
||||
}
|
||||
|
||||
VkResult
|
||||
panvk_map_to_blackhole(struct panvk_device *device, uint64_t address, uint64_t size)
|
||||
{
|
||||
struct pan_kmod_bo *blackhole = panvk_get_blackhole(device);
|
||||
uint64_t blackhole_size = blackhole->size;
|
||||
|
||||
struct drm_panthor_vm_bind_op ops[16] = {};
|
||||
struct panvk_vm_binder binder = {
|
||||
.drm_fd = device->drm_fd,
|
||||
.vm_id = device->kmod.vm->handle,
|
||||
|
||||
.ops = ops,
|
||||
.op_cap = ARRAY_SIZE(ops),
|
||||
};
|
||||
|
||||
uint64_t off = 0;
|
||||
while (off < size) {
|
||||
uint64_t va = address + off;
|
||||
uint64_t bo_offset = va & (blackhole_size - 1);
|
||||
uint64_t range = MIN2(blackhole_size - bo_offset, size - off);
|
||||
struct drm_panthor_vm_bind_op op = {
|
||||
.flags = DRM_PANTHOR_VM_BIND_OP_TYPE_MAP,
|
||||
.bo_handle = blackhole->handle,
|
||||
.bo_offset = bo_offset,
|
||||
.va = va,
|
||||
.size = range,
|
||||
};
|
||||
int ret = panvk_vm_binder_bind(&binder, &op);
|
||||
if (ret)
|
||||
goto err_unmap;
|
||||
|
||||
off += range;
|
||||
}
|
||||
assert(off == size);
|
||||
|
||||
int ret = panvk_vm_binder_flush(&binder);
|
||||
if (ret)
|
||||
goto err_unmap;
|
||||
|
||||
return VK_SUCCESS;
|
||||
|
||||
err_unmap:
|
||||
{
|
||||
struct pan_kmod_vm_op unmap = {
|
||||
.type = PAN_KMOD_VM_OP_TYPE_UNMAP,
|
||||
.va = {
|
||||
.start = address,
|
||||
.size = size,
|
||||
},
|
||||
};
|
||||
ASSERTED int ret = pan_kmod_vm_bind(
|
||||
device->kmod.vm, PAN_KMOD_VM_OP_MODE_IMMEDIATE, &unmap, 1);
|
||||
assert(!ret);
|
||||
}
|
||||
|
||||
return panvk_error(device, VK_ERROR_OUT_OF_DEVICE_MEMORY);
|
||||
}
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
/*
|
||||
* Copyright © 2025 Collabora Ltd.
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#ifndef PANVK_SPARSE_H
|
||||
#define PANVK_SPARSE_H
|
||||
|
||||
#include "vk_device.h"
|
||||
|
||||
VkResult panvk_map_to_blackhole(struct panvk_device *device,
|
||||
uint64_t address, uint64_t size);
|
||||
|
||||
struct pan_kmod_bo *panvk_get_blackhole(struct panvk_device *device);
|
||||
|
||||
#endif
|
||||
Loading…
Add table
Reference in a new issue