lavapipe: support VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT

Co-authored-by: Mike Blumenkrantz <michael.blumenkrantz@gmail.com>

Reviewed-By: Mike Blumenkrantz <michael.blumenkrantz@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/27805>
This commit is contained in:
Lucas Fryzek 2024-02-26 18:31:30 -05:00 committed by Marge Bot
parent eb64f56b59
commit c1657de63c
3 changed files with 53 additions and 11 deletions

View File

@ -250,6 +250,7 @@ assert_memhandle_type(VkExternalMemoryHandleTypeFlags type)
{
switch (type) {
case VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT:
case VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT:
break;
default:
mesa_loge("lavapipe: unimplemented external memory type %u", type);
@ -1787,32 +1788,39 @@ VKAPI_ATTR VkResult VKAPI_CALL lvp_AllocateMemory(
mem->memory_type = LVP_DEVICE_MEMORY_TYPE_USER_PTR;
}
#ifdef PIPE_MEMORY_FD
else if(import_info) {
else if(import_info && import_info->handleType) {
bool dmabuf = import_info->handleType == VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT;
uint64_t size;
if(!device->pscreen->import_memory_fd(device->pscreen, import_info->fd, &mem->pmem, &size, false)) {
if(!device->pscreen->import_memory_fd(device->pscreen, import_info->fd, (struct pipe_memory_allocation**)&mem->alloc, &size, dmabuf)) {
close(import_info->fd);
error = VK_ERROR_INVALID_EXTERNAL_HANDLE;
goto fail;
}
if(size < pAllocateInfo->allocationSize) {
device->pscreen->free_memory_fd(device->pscreen, mem->pmem);
device->pscreen->free_memory_fd(device->pscreen, (struct pipe_memory_allocation*)mem->alloc);
close(import_info->fd);
goto fail;
}
if (export_info && export_info->handleTypes) {
if (export_info && export_info->handleTypes == import_info->handleType) {
mem->backed_fd = import_info->fd;
}
else {
close(import_info->fd);
}
mem->memory_type = LVP_DEVICE_MEMORY_TYPE_OPAQUE_FD;
mem->size = size;
mem->pmem = mem->alloc->data;
mem->memory_type = dmabuf ? LVP_DEVICE_MEMORY_TYPE_DMA_BUF : LVP_DEVICE_MEMORY_TYPE_OPAQUE_FD;
}
else if (export_info && export_info->handleTypes) {
mem->pmem = device->pscreen->allocate_memory_fd(device->pscreen, pAllocateInfo->allocationSize, &mem->backed_fd, false);
if (!mem->pmem || mem->backed_fd < 0) {
goto fail;
bool dmabuf = export_info->handleTypes == VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT;
mem->alloc = (struct llvmpipe_memory_fd_alloc*)device->pscreen->allocate_memory_fd(device->pscreen, pAllocateInfo->allocationSize, &mem->backed_fd, dmabuf);
if (!mem->alloc || mem->backed_fd < 0) {
goto fail;
}
mem->memory_type = LVP_DEVICE_MEMORY_TYPE_OPAQUE_FD;
mem->pmem = mem->alloc->data;
mem->memory_type = dmabuf ? LVP_DEVICE_MEMORY_TYPE_DMA_BUF : LVP_DEVICE_MEMORY_TYPE_OPAQUE_FD;
}
#endif
else {
@ -1853,8 +1861,9 @@ VKAPI_ATTR void VKAPI_CALL lvp_FreeMemory(
device->pscreen->free_memory(device->pscreen, mem->pmem);
break;
#ifdef PIPE_MEMORY_FD
case LVP_DEVICE_MEMORY_TYPE_DMA_BUF:
case LVP_DEVICE_MEMORY_TYPE_OPAQUE_FD:
device->pscreen->free_memory_fd(device->pscreen, mem->pmem);
device->pscreen->free_memory_fd(device->pscreen, (struct pipe_memory_allocation*)mem->alloc);
if(mem->backed_fd >= 0)
close(mem->backed_fd);
break;
@ -2207,7 +2216,7 @@ lvp_GetMemoryFdPropertiesKHR(VkDevice _device,
assert(pMemoryFdProperties->sType == VK_STRUCTURE_TYPE_MEMORY_FD_PROPERTIES_KHR);
if(handleType == VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT) {
if (assert_memhandle_type(handleType)) {
// There is only one memoryType so select this one
pMemoryFdProperties->memoryTypeBits = 1;
}

View File

@ -443,6 +443,18 @@ VKAPI_ATTR VkResult VKAPI_CALL lvp_GetPhysicalDeviceImageFormatProperties2(
VkExternalMemoryHandleTypeFlags compat_flags = 0;
switch (external_info->handleType) {
#ifdef HAVE_LIBDRM
case VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT: {
int params = physical_device->pscreen->get_param(physical_device->pscreen, PIPE_CAP_DMABUF);
flags = VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT;
if (params & DRM_PRIME_CAP_EXPORT)
flags |= VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT;
export_flags = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT;
compat_flags = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT;
break;
}
#endif
#ifdef PIPE_MEMORY_FD
case VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT:
flags = VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT | VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT;
@ -501,6 +513,19 @@ VKAPI_ATTR void VKAPI_CALL lvp_GetPhysicalDeviceExternalBufferProperties(
VkExternalMemoryHandleTypeFlags export_flags = 0;
VkExternalMemoryHandleTypeFlags compat_flags = 0;
switch (pExternalBufferInfo->handleType) {
#ifdef HAVE_LIBDRM
case VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT: {
LVP_FROM_HANDLE(lvp_physical_device, physical_device, physicalDevice);
int params = physical_device->pscreen->get_param(physical_device->pscreen, PIPE_CAP_DMABUF);
flags = VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT;
if (params & DRM_PRIME_CAP_EXPORT)
flags |= VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT;
export_flags = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT;
compat_flags = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT;
break;
}
#endif
#ifdef PIPE_MEMORY_FD
case VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT:
flags = VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT | VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT;

View File

@ -216,6 +216,7 @@ enum lvp_device_memory_type {
LVP_DEVICE_MEMORY_TYPE_DEFAULT,
LVP_DEVICE_MEMORY_TYPE_USER_PTR,
LVP_DEVICE_MEMORY_TYPE_OPAQUE_FD,
LVP_DEVICE_MEMORY_TYPE_DMA_BUF,
};
struct lvp_device_memory {
@ -227,6 +228,9 @@ struct lvp_device_memory {
void * map;
enum lvp_device_memory_type memory_type;
int backed_fd;
#ifdef PIPE_MEMORY_FD
struct llvmpipe_memory_fd_alloc *alloc;
#endif
};
struct lvp_pipe_sync {
@ -706,6 +710,10 @@ static inline uint8_t
lvp_image_aspects_to_plane(ASSERTED const struct lvp_image *image,
VkImageAspectFlags aspectMask)
{
/* If we are requesting the first plane of image with only one plane, return that */
if (image->vk.aspects == VK_IMAGE_ASPECT_COLOR_BIT && aspectMask == VK_IMAGE_ASPECT_MEMORY_PLANE_0_BIT_EXT)
return 0;
/* Verify that the aspects are actually in the image */
assert(!(aspectMask & ~image->vk.aspects));