Module: Mesa Branch: main Commit: b8df7069d3e16be20f4c08537ca1ac389b7bb68d URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=b8df7069d3e16be20f4c08537ca1ac389b7bb68d
Author: Rob Clark <[email protected]> Date: Sat Oct 28 08:15:24 2023 -0700 tu: Add metadata support for dedicated allocations In the case of a dedicated image allocation, stash the layout metadata on the backing GEM object, so that when imported the metadata can be retrieved in order to properly interpret the imported memobj. Signed-off-by: Rob Clark <[email protected]> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/25945> --- src/freedreno/vulkan/tu_device.cc | 30 +++++++++++++++++++++++++ src/freedreno/vulkan/tu_device.h | 3 +++ src/freedreno/vulkan/tu_knl.cc | 18 +++++++++++++++ src/freedreno/vulkan/tu_knl.h | 9 ++++++++ src/freedreno/vulkan/tu_knl_drm_msm.cc | 41 ++++++++++++++++++++++++++++++++++ 5 files changed, 101 insertions(+) diff --git a/src/freedreno/vulkan/tu_device.cc b/src/freedreno/vulkan/tu_device.cc index eab62f8fa40..96af807661f 100644 --- a/src/freedreno/vulkan/tu_device.cc +++ b/src/freedreno/vulkan/tu_device.cc @@ -9,6 +9,8 @@ #include "tu_device.h" +#include "drm-uapi/drm_fourcc.h" +#include "fdl/freedreno_layout.h" #include <fcntl.h> #include <poll.h> #include <sys/sysinfo.h> @@ -2812,6 +2814,14 @@ tu_AllocateMemory(VkDevice _device, mtx_unlock(&device->bo_mutex); } + const VkMemoryDedicatedAllocateInfo *dedicate_info = + vk_find_struct_const(pAllocateInfo->pNext, MEMORY_DEDICATED_ALLOCATE_INFO); + if (dedicate_info) { + mem->image = tu_image_from_handle(dedicate_info->image); + } else { + mem->image = NULL; + } + *pMem = tu_device_memory_to_handle(mem); return VK_SUCCESS; @@ -3343,6 +3353,26 @@ tu_GetMemoryFdKHR(VkDevice _device, return vk_error(device, VK_ERROR_OUT_OF_DEVICE_MEMORY); *pFd = prime_fd; + + if (memory->image) { + struct fdl_layout *l = &memory->image->layout[0]; + uint64_t modifier; + if (l->ubwc) { + modifier = DRM_FORMAT_MOD_QCOM_COMPRESSED; + } else if (l->tile_mode == 2) { + modifier = DRM_FORMAT_MOD_QCOM_TILED2; + } else if (l->tile_mode == 3) { + modifier = DRM_FORMAT_MOD_QCOM_TILED3; + } else { + assert(!l->tile_mode); + modifier = DRM_FORMAT_MOD_LINEAR; + } + struct fdl_metadata metadata = { + .modifier = modifier, + }; + tu_bo_set_metadata(device, memory->bo, &metadata, sizeof(metadata)); + } + return VK_SUCCESS; } diff --git a/src/freedreno/vulkan/tu_device.h b/src/freedreno/vulkan/tu_device.h index e376ce5ca8b..bd7e715807c 100644 --- a/src/freedreno/vulkan/tu_device.h +++ b/src/freedreno/vulkan/tu_device.h @@ -405,6 +405,9 @@ struct tu_device_memory struct vk_object_base base; struct tu_bo *bo; + + /* for dedicated allocations */ + struct tu_image *image; }; VK_DEFINE_NONDISP_HANDLE_CASTS(tu_device_memory, base, VkDeviceMemory, VK_OBJECT_TYPE_DEVICE_MEMORY) diff --git a/src/freedreno/vulkan/tu_knl.cc b/src/freedreno/vulkan/tu_knl.cc index 61eb09bbe0e..422a65b4600 100644 --- a/src/freedreno/vulkan/tu_knl.cc +++ b/src/freedreno/vulkan/tu_knl.cc @@ -65,6 +65,24 @@ void tu_bo_allow_dump(struct tu_device *dev, struct tu_bo *bo) dev->instance->knl->bo_allow_dump(dev, bo); } +void +tu_bo_set_metadata(struct tu_device *dev, struct tu_bo *bo, + void *metadata, uint32_t metadata_size) +{ + if (!dev->instance->knl->bo_set_metadata) + return; + dev->instance->knl->bo_set_metadata(dev, bo, metadata, metadata_size); +} + +int +tu_bo_get_metadata(struct tu_device *dev, struct tu_bo *bo, + void *metadata, uint32_t metadata_size) +{ + if (!dev->instance->knl->bo_get_metadata) + return -ENOSYS; + return dev->instance->knl->bo_get_metadata(dev, bo, metadata, metadata_size); +} + VkResult tu_drm_device_init(struct tu_device *dev) { diff --git a/src/freedreno/vulkan/tu_knl.h b/src/freedreno/vulkan/tu_knl.h index 78cb442dc93..e9293e3d08b 100644 --- a/src/freedreno/vulkan/tu_knl.h +++ b/src/freedreno/vulkan/tu_knl.h @@ -74,6 +74,10 @@ struct tu_knl { VkResult (*bo_map)(struct tu_device *dev, struct tu_bo *bo); void (*bo_allow_dump)(struct tu_device *dev, struct tu_bo *bo); void (*bo_finish)(struct tu_device *dev, struct tu_bo *bo); + void (*bo_set_metadata)(struct tu_device *dev, struct tu_bo *bo, + void *metadata, uint32_t metadata_size); + int (*bo_get_metadata)(struct tu_device *dev, struct tu_bo *bo, + void *metadata, uint32_t metadata_size); VkResult (*device_wait_u_trace)(struct tu_device *dev, struct tu_u_trace_syncobj *syncobj); VkResult (*queue_submit)(struct tu_queue *queue, @@ -139,6 +143,11 @@ tu_bo_map(struct tu_device *dev, struct tu_bo *bo); void tu_bo_allow_dump(struct tu_device *dev, struct tu_bo *bo); +void tu_bo_set_metadata(struct tu_device *dev, struct tu_bo *bo, + void *metadata, uint32_t metadata_size); +int tu_bo_get_metadata(struct tu_device *dev, struct tu_bo *bo, + void *metadata, uint32_t metadata_size); + static inline struct tu_bo * tu_bo_get_ref(struct tu_bo *bo) { diff --git a/src/freedreno/vulkan/tu_knl_drm_msm.cc b/src/freedreno/vulkan/tu_knl_drm_msm.cc index e8fe7a9f82c..581a65e0e5b 100644 --- a/src/freedreno/vulkan/tu_knl_drm_msm.cc +++ b/src/freedreno/vulkan/tu_knl_drm_msm.cc @@ -651,6 +651,45 @@ msm_bo_allow_dump(struct tu_device *dev, struct tu_bo *bo) mtx_unlock(&dev->bo_mutex); } + +static void +msm_bo_set_metadata(struct tu_device *dev, struct tu_bo *bo, + void *metadata, uint32_t metadata_size) +{ + struct drm_msm_gem_info req = { + .handle = bo->gem_handle, + .info = MSM_INFO_SET_METADATA, + .value = (uintptr_t)(void *)metadata, + .len = metadata_size, + }; + + int ret = drmCommandWrite(dev->fd, DRM_MSM_GEM_INFO, &req, sizeof(req)); + if (ret) { + mesa_logw_once("Failed to set BO metadata with DRM_MSM_GEM_INFO: %d", + ret); + } +} + +static int +msm_bo_get_metadata(struct tu_device *dev, struct tu_bo *bo, + void *metadata, uint32_t metadata_size) +{ + struct drm_msm_gem_info req = { + .handle = bo->gem_handle, + .info = MSM_INFO_GET_METADATA, + .value = (uintptr_t)(void *)metadata, + .len = metadata_size, + }; + + int ret = drmCommandWrite(dev->fd, DRM_MSM_GEM_INFO, &req, sizeof(req)); + if (ret) { + mesa_logw_once("Failed to get BO metadata with DRM_MSM_GEM_INFO: %d", + ret); + } + + return ret; +} + static VkResult tu_queue_submit_create_locked(struct tu_queue *queue, struct vk_queue_submit *vk_submit, @@ -1071,6 +1110,8 @@ static const struct tu_knl msm_knl_funcs = { .bo_map = msm_bo_map, .bo_allow_dump = msm_bo_allow_dump, .bo_finish = tu_drm_bo_finish, + .bo_set_metadata = msm_bo_set_metadata, + .bo_get_metadata = msm_bo_get_metadata, .device_wait_u_trace = msm_device_wait_u_trace, .queue_submit = msm_queue_submit, };
