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,
 };

Reply via email to