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 <robdclark@chromium.org>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/25945>
This commit is contained in:
Rob Clark
2023-10-28 08:15:24 -07:00
committed by Marge Bot
parent 0105c2e2eb
commit b8df7069d3
5 changed files with 101 additions and 0 deletions
+30
View File
@@ -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;
}
+3
View File
@@ -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)
+18
View File
@@ -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)
{
+9
View File
@@ -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)
{
+41
View File
@@ -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,
};