mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-05 03:08:05 +02:00
radv: enable virtio native context support
No big code changes are needed to support virtio. The main caveat with radv is about buffer allocations. Allocating a cpu visible buffer requires the host process (eg qemu) to create a dmabuf, mmap it, then map the host CPU address into the guest application CPU address space. The first issue is about the number of dmabuf created because we might hit the number of open file limit. The host process limit can be raised but we would hit the second issue - at least on qemu: there's a limit on how many sections can be mapped and ultimately we hit this assert: assert(map->sections_nb < TARGET_PAGE_SIZE); (the third issue is a performance one: these operations have a cost, and this increases some Vulkan app loading times) radeonsi is not really affected because it's using pb_slab to suballocate small buffers from larger ones. radv on the other hand doesn't, so if an app decides to allocate lots of cpu visible small buffers, we're likely to fail. Earlier versions of the amdgpu nctx code had a suballoctor, but it was removed to simplified the code. It could be restored later; or radv could be modified to use a suballocator (like anv does AFAICT). Acked-by: Samuel Pitoiset <samuel.pitoiset@gmail.com> Tested-by: Dmitry Osipenko <dmitry.osipenko@collabora.com> Reviewed-by: Dmitry Osipenko <dmitry.osipenko@collabora.com> Reviewed-by: Marek Olšák <marek.olsak@amd.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/21658>
This commit is contained in:
parent
612774c4a6
commit
9de728c4d0
6 changed files with 64 additions and 11 deletions
|
|
@ -198,6 +198,10 @@ subdir('layers')
|
|||
radv_deps = []
|
||||
radv_flags = cc.get_supported_arguments(['-Wimplicit-fallthrough', '-Wshadow'])
|
||||
|
||||
if with_amdgpu_virtio
|
||||
radv_flags += '-DHAVE_AMDGPU_VIRTIO'
|
||||
endif
|
||||
|
||||
if with_platform_x11
|
||||
radv_deps += dep_xcb_dri3
|
||||
endif
|
||||
|
|
@ -224,13 +228,14 @@ libvulkan_radeon = shared_library(
|
|||
[libradv_files, radv_entrypoints, sha1_h, radix_sort_spv, bvh_spv, radv_annotate_layer],
|
||||
vs_module_defs : vulkan_api_def,
|
||||
include_directories : [
|
||||
inc_include, inc_src, inc_amd, inc_amd_common, inc_amd_common_llvm, inc_util,
|
||||
inc_include, inc_src, inc_amd, inc_amd_common, inc_amd_common_llvm,
|
||||
inc_util, inc_virtio_gpu
|
||||
],
|
||||
link_with : [
|
||||
libamd_common, libamd_common_llvm, libamdgpu_addrlib,
|
||||
],
|
||||
dependencies : [
|
||||
dep_llvm, dep_libdrm_amdgpu, dep_thread, dep_elf, dep_dl, dep_m,
|
||||
dep_llvm, dep_thread, dep_elf, dep_dl, dep_m,
|
||||
dep_valgrind, radv_deps, idep_aco,
|
||||
idep_mesautil, idep_nir, idep_vulkan_util, idep_vulkan_wsi,
|
||||
idep_vulkan_runtime, idep_amdgfxregs_h, idep_xmlconfig,
|
||||
|
|
|
|||
|
|
@ -12,6 +12,9 @@
|
|||
#define RADV_CONSTANTS_H
|
||||
|
||||
#define ATI_VENDOR_ID 0x1002
|
||||
#ifdef HAVE_AMDGPU_VIRTIO
|
||||
#define VIRTGPU_PCI_VENDOR_ID 0x1af4
|
||||
#endif
|
||||
|
||||
#define MAX_VBS 32
|
||||
#define MAX_VERTEX_ATTRIBS 32
|
||||
|
|
|
|||
|
|
@ -2018,7 +2018,15 @@ radv_physical_device_try_create(struct radv_instance *instance, drmDevicePtr drm
|
|||
"Could not get the kernel driver version for device %s: %m", path);
|
||||
}
|
||||
|
||||
if (strcmp(version->name, "amdgpu")) {
|
||||
if (!strcmp(version->name, "amdgpu")) {
|
||||
/* nothing to do. */
|
||||
} else
|
||||
#ifdef HAVE_AMDGPU_VIRTIO
|
||||
if (!strcmp(version->name, "virtio_gpu")) {
|
||||
is_virtio = true;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
drmFreeVersion(version);
|
||||
close(fd);
|
||||
|
||||
|
|
@ -2054,7 +2062,8 @@ radv_physical_device_try_create(struct radv_instance *instance, drmDevicePtr drm
|
|||
if (drm_device) {
|
||||
bool reserve_vmid = instance->vk.trace_mode & RADV_TRACE_MODE_RGP;
|
||||
|
||||
pdev->ws = radv_amdgpu_winsys_create(fd, instance->debug_flags, instance->perftest_flags, reserve_vmid);
|
||||
pdev->ws =
|
||||
radv_amdgpu_winsys_create(fd, instance->debug_flags, instance->perftest_flags, reserve_vmid, is_virtio);
|
||||
} else {
|
||||
pdev->ws = radv_null_winsys_create();
|
||||
}
|
||||
|
|
@ -2308,8 +2317,18 @@ VkResult
|
|||
create_drm_physical_device(struct vk_instance *vk_instance, struct _drmDevice *device, struct vk_physical_device **out)
|
||||
{
|
||||
#ifndef _WIN32
|
||||
if (!(device->available_nodes & (1 << DRM_NODE_RENDER)) || device->bustype != DRM_BUS_PCI ||
|
||||
device->deviceinfo.pci->vendor_id != ATI_VENDOR_ID)
|
||||
bool supported_device = false;
|
||||
|
||||
if (!(device->available_nodes & (1 << DRM_NODE_RENDER)) || device->bustype != DRM_BUS_PCI)
|
||||
return VK_ERROR_INCOMPATIBLE_DRIVER;
|
||||
|
||||
#ifdef HAVE_AMDGPU_VIRTIO
|
||||
supported_device |= device->deviceinfo.pci->vendor_id == VIRTGPU_PCI_VENDOR_ID;
|
||||
#endif
|
||||
|
||||
supported_device |= device->deviceinfo.pci->vendor_id == ATI_VENDOR_ID;
|
||||
|
||||
if (!supported_device)
|
||||
return VK_ERROR_INCOMPATIBLE_DRIVER;
|
||||
|
||||
return radv_physical_device_try_create((struct radv_instance *)vk_instance, device,
|
||||
|
|
|
|||
|
|
@ -492,7 +492,10 @@ radv_amdgpu_winsys_bo_create(struct radeon_winsys *_ws, uint64_t size, unsigned
|
|||
request.flags |= AMDGPU_GEM_CREATE_EXPLICIT_SYNC;
|
||||
if ((initial_domain & RADEON_DOMAIN_VRAM_GTT) && (flags & RADEON_FLAG_NO_INTERPROCESS_SHARING) &&
|
||||
((ws->perftest & RADV_PERFTEST_LOCAL_BOS) || (flags & RADEON_FLAG_PREFER_LOCAL_BO))) {
|
||||
if (request.flags & AMDGPU_GEM_CREATE_NO_CPU_ACCESS) {
|
||||
/* virtio needs to be able to create a dmabuf if CPU access is required but a
|
||||
* dmabuf cannot be created if VM_ALWAYS_VALID is used.
|
||||
*/
|
||||
if (!ws->info.is_virtio || (request.flags & AMDGPU_GEM_CREATE_NO_CPU_ACCESS)) {
|
||||
bo->base.is_local = true;
|
||||
request.flags |= AMDGPU_GEM_CREATE_VM_ALWAYS_VALID;
|
||||
}
|
||||
|
|
@ -583,6 +586,22 @@ radv_amdgpu_winsys_bo_map(struct radeon_winsys *_ws, struct radeon_winsys_bo *_b
|
|||
|
||||
assert(!bo->cpu_map);
|
||||
|
||||
#if HAVE_AMDGPU_VIRTIO
|
||||
struct radv_amdgpu_winsys *ws = radv_amdgpu_winsys(_ws);
|
||||
if (ws->info.is_virtio) {
|
||||
/* We can't use DRM_AMDGPU_GEM_MMAP directly on virtio. Instead use bo_cpu_map since
|
||||
* the virtio version will map the buffer at the given address (if not NULL).
|
||||
*/
|
||||
void *data = NULL;
|
||||
if (use_fixed_addr)
|
||||
data = fixed_addr;
|
||||
|
||||
if (ac_drm_bo_cpu_map(ws->dev, bo->bo, &data))
|
||||
return NULL;
|
||||
return data;
|
||||
}
|
||||
#endif
|
||||
|
||||
union drm_amdgpu_gem_mmap args;
|
||||
memset(&args, 0, sizeof(args));
|
||||
args.in.handle = bo->bo_handle;
|
||||
|
|
@ -613,7 +632,13 @@ radv_amdgpu_winsys_bo_unmap(struct radeon_winsys *_ws, struct radeon_winsys_bo *
|
|||
if (replace) {
|
||||
(void)mmap(bo->cpu_map, bo->base.size, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0);
|
||||
} else {
|
||||
munmap(bo->cpu_map, bo->base.size);
|
||||
#if HAVE_AMDGPU_VIRTIO
|
||||
struct radv_amdgpu_winsys *ws = radv_amdgpu_winsys(_ws);
|
||||
if (ws->info.is_virtio)
|
||||
ac_drm_bo_cpu_unmap(ws->dev, bo->bo);
|
||||
else
|
||||
#endif
|
||||
munmap(bo->cpu_map, bo->base.size);
|
||||
}
|
||||
bo->cpu_map = NULL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -196,13 +196,13 @@ radv_amdgpu_winsys_get_sync_types(struct radeon_winsys *rws)
|
|||
}
|
||||
|
||||
struct radeon_winsys *
|
||||
radv_amdgpu_winsys_create(int fd, uint64_t debug_flags, uint64_t perftest_flags, bool reserve_vmid)
|
||||
radv_amdgpu_winsys_create(int fd, uint64_t debug_flags, uint64_t perftest_flags, bool reserve_vmid, bool is_virtio)
|
||||
{
|
||||
uint32_t drm_major, drm_minor, r;
|
||||
ac_drm_device *dev;
|
||||
struct radv_amdgpu_winsys *ws = NULL;
|
||||
|
||||
r = ac_drm_device_initialize(fd, false, &drm_major, &drm_minor, &dev);
|
||||
r = ac_drm_device_initialize(fd, is_virtio, &drm_major, &drm_minor, &dev);
|
||||
if (r) {
|
||||
fprintf(stderr, "radv/amdgpu: failed to initialize device.\n");
|
||||
return NULL;
|
||||
|
|
@ -251,6 +251,7 @@ radv_amdgpu_winsys_create(int fd, uint64_t debug_flags, uint64_t perftest_flags,
|
|||
ws->fd = ac_drm_device_get_fd(dev);
|
||||
ws->info.drm_major = drm_major;
|
||||
ws->info.drm_minor = drm_minor;
|
||||
ws->info.is_virtio = is_virtio;
|
||||
if (!do_winsys_init(ws, fd))
|
||||
goto winsys_fail;
|
||||
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@
|
|||
#define RADV_AMDGPU_WINSYS_PUBLIC_H
|
||||
|
||||
struct radeon_winsys *radv_amdgpu_winsys_create(int fd, uint64_t debug_flags, uint64_t perftest_flags,
|
||||
bool reserve_vmid);
|
||||
bool reserve_vmid, bool is_virtio);
|
||||
|
||||
struct radeon_winsys *radv_dummy_winsys_create(void);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue