From 777966a7cd402248a06603691ec89eb3bf3bade8 Mon Sep 17 00:00:00 2001 From: Natalie Vock Date: Sat, 20 Jun 2026 13:09:19 +0200 Subject: [PATCH] radv: VK_EXT_pageable_device_local_memory This relies on a feature that is only present in custom-built kernels. When running under an incompatible kernel, the ioctl will fail and priority manipulation becomes a no-op. --- include/drm-uapi/amdgpu_drm.h | 1 + src/amd/vulkan/radv_device_memory.c | 9 ++++++ src/amd/vulkan/radv_physical_device.c | 4 +++ src/amd/vulkan/radv_radeon_winsys.h | 2 ++ src/amd/vulkan/winsys/amdgpu/radv_amdgpu_bo.c | 30 +++++++++++++++++++ 5 files changed, 46 insertions(+) diff --git a/include/drm-uapi/amdgpu_drm.h b/include/drm-uapi/amdgpu_drm.h index 056e2ab8a875..b7cbfcd8941f 100644 --- a/include/drm-uapi/amdgpu_drm.h +++ b/include/drm-uapi/amdgpu_drm.h @@ -801,6 +801,7 @@ union drm_amdgpu_wait_fences { #define AMDGPU_GEM_OP_GET_GEM_CREATE_INFO 0 #define AMDGPU_GEM_OP_SET_PLACEMENT 1 +#define AMDGPU_GEM_OP_SET_PRIORITY 3 /* Sets or returns a value associated with a buffer. */ struct drm_amdgpu_gem_op { diff --git a/src/amd/vulkan/radv_device_memory.c b/src/amd/vulkan/radv_device_memory.c index 4c5213db4268..3735b343eb2e 100644 --- a/src/amd/vulkan/radv_device_memory.c +++ b/src/amd/vulkan/radv_device_memory.c @@ -411,3 +411,12 @@ radv_GetDeviceMemoryCommitment(VkDevice device, VkDeviceMemory memory, VkDeviceS { *pCommittedMemoryInBytes = 0; } + +VKAPI_ATTR void VKAPI_CALL +radv_SetDeviceMemoryPriorityEXT(VkDevice _device, VkDeviceMemory _memory, float priority) +{ + VK_FROM_HANDLE(radv_device, device, _device); + VK_FROM_HANDLE(radv_device_memory, memory, _memory); + + device->ws->buffer_set_priority(device->ws, memory->bo, priority); +} diff --git a/src/amd/vulkan/radv_physical_device.c b/src/amd/vulkan/radv_physical_device.c index fddd0bb21f17..a874c3ac86bd 100644 --- a/src/amd/vulkan/radv_physical_device.c +++ b/src/amd/vulkan/radv_physical_device.c @@ -890,6 +890,7 @@ radv_physical_device_get_supported_extensions(const struct radv_physical_device .EXT_mutable_descriptor_type = true, /* Trivial promotion from VALVE. */ .EXT_nested_command_buffer = true, .EXT_non_seamless_cube_map = true, + .EXT_pageable_device_local_memory = true, .EXT_pci_bus_info = true, #ifndef _WIN32 .EXT_physical_device_drm = true, @@ -1455,6 +1456,9 @@ radv_physical_device_get_features(const struct radv_physical_device *pdev, struc /* VK_EXT_pipeline_robustness */ .pipelineRobustness = true, + /* VK_EXT_pageable_device_local_memory */ + .pageableDeviceLocalMemory = true, + /* VK_KHR_maintenance5 */ .maintenance5 = true, diff --git a/src/amd/vulkan/radv_radeon_winsys.h b/src/amd/vulkan/radv_radeon_winsys.h index f4b47f81b616..c1934fcbb4f4 100644 --- a/src/amd/vulkan/radv_radeon_winsys.h +++ b/src/amd/vulkan/radv_radeon_winsys.h @@ -241,6 +241,8 @@ struct radeon_winsys { void (*buffer_destroy)(struct radeon_winsys *ws, struct radeon_winsys_bo *bo); void *(*buffer_map)(struct radeon_winsys *ws, struct radeon_winsys_bo *bo, bool use_fixed_addr, void *fixed_addr); + void (*buffer_set_priority)(struct radeon_winsys *ws, struct radeon_winsys_bo *bo, float priority); + VkResult (*buffer_from_ptr)(struct radeon_winsys *ws, void *pointer, uint64_t size, unsigned priority, struct radeon_winsys_bo **out_bo); diff --git a/src/amd/vulkan/winsys/amdgpu/radv_amdgpu_bo.c b/src/amd/vulkan/winsys/amdgpu/radv_amdgpu_bo.c index 8e66ef80e79a..b370a9bc780c 100644 --- a/src/amd/vulkan/winsys/amdgpu/radv_amdgpu_bo.c +++ b/src/amd/vulkan/winsys/amdgpu/radv_amdgpu_bo.c @@ -30,6 +30,32 @@ static void radv_amdgpu_winsys_bo_destroy(struct radeon_winsys *_ws, struct radeon_winsys_bo *_bo); +static uint32_t +vk_prio_to_amdgpu(float vk) +{ + return (uint32_t)((double)vk * (double)(UINT32_MAX - 1u)); +} + +static void +radv_amdgpu_winsys_bo_set_priority(struct radeon_winsys *_ws, struct radeon_winsys_bo *_bo, float prio) +{ + struct radv_amdgpu_winsys *ws = radv_amdgpu_winsys(_ws); + struct radv_amdgpu_winsys_bo *bo = radv_amdgpu_winsys_bo(_bo); + struct drm_amdgpu_gem_op args; + + if (!bo->base.is_local) { + bo->priority = (int)(prio * 31.0f); + return; + } + + memset(&args, 0, sizeof(args)); + args.handle = bo->bo_handle; + args.op = AMDGPU_GEM_OP_SET_PRIORITY; + args.value = vk_prio_to_amdgpu(prio); + + drmCommandWriteRead(ws->fd, DRM_AMDGPU_GEM_OP, &args, sizeof(args)); +} + static int radv_amdgpu_bo_va_op(struct radv_amdgpu_winsys *ws, uint32_t bo_handle, uint64_t offset, uint64_t size, uint64_t addr, uint32_t bo_flags, uint64_t internal_flags, uint32_t ops) @@ -685,6 +711,9 @@ radv_amdgpu_winsys_bo_create(struct radeon_winsys *_ws, uint64_t size, unsigned } } + if (bo->base.is_local) + radv_amdgpu_winsys_bo_set_priority(&ws->base, &bo->base, priority / 31.0f); + if (initial_domain & RADEON_DOMAIN_GTT) p_atomic_add(&ws->alloc_tracker->allocated_gtt, align64(bo->base.size, ws->info.gart_page_size)); @@ -1314,6 +1343,7 @@ radv_amdgpu_bo_init_functions(struct radv_amdgpu_winsys *ws) ws->base.buffer_create = radv_amdgpu_winsys_bo_create; ws->base.buffer_destroy = radv_amdgpu_winsys_bo_destroy; ws->base.buffer_map = radv_amdgpu_winsys_bo_map; + ws->base.buffer_set_priority = radv_amdgpu_winsys_bo_set_priority; ws->base.buffer_unmap = radv_amdgpu_winsys_bo_unmap; ws->base.buffer_from_ptr = radv_amdgpu_winsys_bo_from_ptr; ws->base.buffer_from_fd = radv_amdgpu_winsys_bo_from_fd; -- GitLab