diff --git a/src/venus/vkr_common.h b/src/venus/vkr_common.h index bf6b609..ce176d5 100644 --- a/src/venus/vkr_common.h +++ b/src/venus/vkr_common.h @@ -33,16 +33,6 @@ #include "vkr_renderer.h" -/* - * TODO what extensions do we need from the host driver? - * - * We don't check vkGetPhysicalDeviceExternalBufferProperties, etc. yet. Even - * if we did, silently adding external memory info to vkCreateBuffer or - * vkCreateImage could change the results of vkGetBufferMemoryRequirements or - * vkGetImageMemoryRequirements and confuse the guest. - */ -#define FORCE_ENABLE_DMABUF - #define VKR_DEBUG(category) (unlikely(vkr_debug_flags & VKR_DEBUG_##category)) /* define a type-safe cast function */ diff --git a/src/venus/vkr_device_memory.c b/src/venus/vkr_device_memory.c index 6ccadc7..8ec3e50 100644 --- a/src/venus/vkr_device_memory.c +++ b/src/venus/vkr_device_memory.c @@ -82,7 +82,8 @@ vkr_dispatch_vkAllocateMemory(struct vn_dispatch_context *dispatch, VkBaseInStructure *prev_of_res_info = NULL; VkImportMemoryResourceInfoMESA *res_info = NULL; VkImportMemoryFdInfoKHR local_import_info = { .fd = -1 }; - VkExportMemoryAllocateInfo *export_info = NULL; + VkExportMemoryAllocateInfo *export_info = vkr_find_struct( + args->pAllocateInfo->pNext, VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO); struct vkr_device_memory *mem = NULL; const uint32_t mem_type_index = args->pAllocateInfo->memoryTypeIndex; const uint32_t property_flags = @@ -103,25 +104,32 @@ vkr_dispatch_vkAllocateMemory(struct vn_dispatch_context *dispatch, prev_of_res_info->pNext = (const struct VkBaseInStructure *)&local_import_info; } - export_info = vkr_find_struct(args->pAllocateInfo->pNext, - VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO); - -#ifdef FORCE_ENABLE_DMABUF + /* XXX Force dma_buf export until: + * - a new extension that supports direct export from host visible memory + * - client capable of consuming opaque fd + * + * Most VkImage and VkBuffer are non-external while most VkDeviceMemory are external + * if allocated with a host visible memory type. We still violate the spec by binding + * external memory to non-external image or buffer, which needs spec changes with a + * new extension. + */ VkExportMemoryAllocateInfo local_export_info; - if (dev->physical_device->EXT_external_memory_dma_buf) { - if (export_info) { - export_info->handleTypes |= VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT; - } else { - local_export_info = (const VkExportMemoryAllocateInfo){ - .sType = VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO, - .pNext = args->pAllocateInfo->pNext, - .handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT, - }; - export_info = &local_export_info; - ((VkMemoryAllocateInfo *)args->pAllocateInfo)->pNext = &local_export_info; + if ((property_flags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) && + dev->physical_device->EXT_external_memory_dma_buf) { + if (dev->physical_device->is_memory_export_supported) { + if (export_info) { + export_info->handleTypes |= VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT; + } else { + local_export_info = (const VkExportMemoryAllocateInfo){ + .sType = VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO, + .pNext = args->pAllocateInfo->pNext, + .handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT, + }; + export_info = &local_export_info; + ((VkMemoryAllocateInfo *)args->pAllocateInfo)->pNext = &local_export_info; + } } } -#endif /* FORCE_ENABLE_DMABUF */ if (export_info) { if (export_info->handleTypes & VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT) diff --git a/src/venus/vkr_physical_device.c b/src/venus/vkr_physical_device.c index 3507390..60fb2df 100644 --- a/src/venus/vkr_physical_device.c +++ b/src/venus/vkr_physical_device.c @@ -95,6 +95,31 @@ vkr_physical_device_init_memory_properties(struct vkr_physical_device *physical_ * filter out VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT here if a memory type is * not always exportable. */ + + /* XXX is_memory_export_supported needs to be filled with a new extension + * which supports query fd export against the raw memory types. Currently, + * we workaround by checking external buffer properties before forcing + * enable dma_buf path of device memory allocation. + */ + if (!physical_dev->EXT_external_memory_dma_buf) + return; + + const VkPhysicalDeviceExternalBufferInfo info = { + .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_BUFFER_INFO, + .usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT, + .handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT, + }; + VkExternalBufferProperties props = { + .sType = VK_STRUCTURE_TYPE_EXTERNAL_BUFFER_PROPERTIES, + }; + vkGetPhysicalDeviceExternalBufferProperties(handle, &info, &props); + physical_dev->is_memory_export_supported = + (props.externalMemoryProperties.externalMemoryFeatures & + VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT) && + (props.externalMemoryProperties.exportFromImportedHandleTypes & + VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT) && + (props.externalMemoryProperties.exportFromImportedHandleTypes & + VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT); } static void diff --git a/src/venus/vkr_physical_device.h b/src/venus/vkr_physical_device.h index 0e84b5f..ec6241c 100644 --- a/src/venus/vkr_physical_device.h +++ b/src/venus/vkr_physical_device.h @@ -23,6 +23,7 @@ struct vkr_physical_device { bool KHR_external_fence_fd; VkPhysicalDeviceMemoryProperties memory_properties; + bool is_memory_export_supported; struct list_head devices; };