[Mesa-dev] [PATCH 7/7] anv: Implement VK_KHX_external_memory_fd (v2)
Chad Versace
chadversary at chromium.org
Tue Feb 28 18:58:40 UTC 2017
From: Jason Ekstrand <jason.ekstrand at intel.com>
v2 (chadv):
- Rebase.
- Fix vkGetPhysicalDeviceImageFormatProperties2KHR when
handleType == 0.
- Move handleType-independency comments out of handleType-switch, in
vkGetPhysicalDeviceExternalBufferPropertiesKHX. Reduces diff in
future dma_buf patches.
Co-authored-with: Chad Versace <chadversary at chromium.org>
---
On my branch wip/anv-external-memory.
http://git.kiwitree.net/cgit/~chadv/mesa/log/?h=wip/anv-external-memory
src/intel/vulkan/anv_device.c | 90 +++++++++++++++++++++++++++++----
src/intel/vulkan/anv_entrypoints_gen.py | 1 +
src/intel/vulkan/anv_formats.c | 59 ++++++++++++++++++---
3 files changed, 133 insertions(+), 17 deletions(-)
diff --git a/src/intel/vulkan/anv_device.c b/src/intel/vulkan/anv_device.c
index 024e19f91b9..ec88547368a 100644
--- a/src/intel/vulkan/anv_device.c
+++ b/src/intel/vulkan/anv_device.c
@@ -310,6 +310,10 @@ static const VkExtensionProperties device_extensions[] = {
.extensionName = VK_KHX_EXTERNAL_MEMORY_EXTENSION_NAME,
.specVersion = 1,
},
+ {
+ .extensionName = VK_KHX_EXTERNAL_MEMORY_FD_EXTENSION_NAME,
+ .specVersion = 1,
+ },
};
static void *
@@ -1400,7 +1404,7 @@ VkResult anv_AllocateMemory(
{
ANV_FROM_HANDLE(anv_device, device, _device);
struct anv_device_memory *mem;
- VkResult result;
+ VkResult result = VK_SUCCESS;
assert(pAllocateInfo->sType == VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO);
@@ -1418,18 +1422,50 @@ VkResult anv_AllocateMemory(
if (mem == NULL)
return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
- /* The kernel is going to give us whole pages anyway */
- uint64_t alloc_size = align_u64(pAllocateInfo->allocationSize, 4096);
-
- result = anv_bo_init_new(&mem->bo, device, alloc_size);
- if (result != VK_SUCCESS)
- goto fail;
-
mem->type_index = pAllocateInfo->memoryTypeIndex;
-
mem->map = NULL;
mem->map_size = 0;
+ const VkImportMemoryFdInfoKHX *fd_info =
+ vk_find_struct_const(pAllocateInfo->pNext, IMPORT_MEMORY_FD_INFO_KHX);
+
+ /* The Vulkan spec permits handleType to be 0, in which case the struct is
+ * ignored.
+ */
+ if (fd_info && fd_info->handleType) {
+ /* At the moment, we only support the OPAQUE_FD memory type which is
+ * just a GEM buffer.
+ */
+ assert(fd_info->handleType ==
+ VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHX);
+
+ uint32_t gem_handle = anv_gem_fd_to_handle(device, fd_info->fd);
+ if (!gem_handle) {
+ result = vk_error(VK_ERROR_INVALID_EXTERNAL_HANDLE_KHX);
+ goto fail;
+ }
+
+ /* From the Vulkan spec:
+ *
+ * "Importing memory from a file descriptor transfers ownership of
+ * the file descriptor from the application to the Vulkan
+ * implementation. The application must not perform any operations on
+ * the file descriptor after a successful import."
+ *
+ * If the import fails, we leave the file descriptor open.
+ */
+ close(fd_info->fd);
+
+ anv_bo_init(&mem->bo, gem_handle, pAllocateInfo->allocationSize);
+ } else {
+ /* The kernel is going to give us whole pages anyway */
+ uint64_t alloc_size = align_u64(pAllocateInfo->allocationSize, 4096);
+
+ result = anv_bo_init_new(&mem->bo, device, alloc_size);
+ if (result != VK_SUCCESS)
+ goto fail;
+ }
+
*pMem = anv_device_memory_to_handle(mem);
return VK_SUCCESS;
@@ -1440,6 +1476,42 @@ VkResult anv_AllocateMemory(
return result;
}
+VkResult anv_GetMemoryFdKHX(
+ VkDevice device_h,
+ VkDeviceMemory memory_h,
+ VkExternalMemoryHandleTypeFlagBitsKHX handleType,
+ int* pFd)
+{
+ ANV_FROM_HANDLE(anv_device, dev, device_h);
+ ANV_FROM_HANDLE(anv_device_memory, mem, memory_h);
+
+ /* We support only one handle type. */
+ assert(handleType == VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHX);
+
+ int fd = anv_gem_handle_to_fd(dev, mem->bo.gem_handle);
+ if (fd == -1)
+ return vk_error(VK_ERROR_INVALID_EXTERNAL_HANDLE_KHX);
+
+ *pFd = fd;
+
+ return VK_SUCCESS;
+}
+
+VkResult anv_GetMemoryFdPropertiesKHX(
+ VkDevice device_h,
+ VkExternalMemoryHandleTypeFlagBitsKHX handleType,
+ int fd,
+ VkMemoryFdPropertiesKHX* pMemoryFdProperties)
+{
+ /* The valid usage section for this function says:
+ *
+ * "handleType must not be one of the handle types defined as opaque."
+ *
+ * Since we only handle opaque handles for now, there are no FD properties.
+ */
+ return VK_ERROR_INVALID_EXTERNAL_HANDLE_KHX;
+}
+
void anv_FreeMemory(
VkDevice _device,
VkDeviceMemory _mem,
diff --git a/src/intel/vulkan/anv_entrypoints_gen.py b/src/intel/vulkan/anv_entrypoints_gen.py
index d8816a581a2..530163c9eff 100644
--- a/src/intel/vulkan/anv_entrypoints_gen.py
+++ b/src/intel/vulkan/anv_entrypoints_gen.py
@@ -39,6 +39,7 @@ supported_extensions = [
'VK_KHR_xlib_surface',
'VK_KHX_external_memory',
'VK_KHX_external_memory_capabilities',
+ 'VK_KHX_external_memory_fd',
]
# We generate a static hash table for entry point lookup
diff --git a/src/intel/vulkan/anv_formats.c b/src/intel/vulkan/anv_formats.c
index f91ba437f1e..196a7516dfa 100644
--- a/src/intel/vulkan/anv_formats.c
+++ b/src/intel/vulkan/anv_formats.c
@@ -656,6 +656,17 @@ VkResult anv_GetPhysicalDeviceImageFormatProperties(
pImageFormatProperties);
}
+static const VkExternalMemoryPropertiesKHX prime_fd_props = {
+ /* If we can handle external, then we can both import and export it. */
+ .externalMemoryFeatures = VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT_KHX |
+ VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT_KHX,
+ /* For the moment, let's not support mixing and matching */
+ .exportFromImportedHandleTypes =
+ VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHX,
+ .compatibleHandleTypes =
+ VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHX,
+};
+
VkResult anv_GetPhysicalDeviceImageFormatProperties2KHR(
VkPhysicalDevice physicalDevice,
const VkPhysicalDeviceImageFormatInfo2KHR* base_info,
@@ -702,13 +713,23 @@ VkResult anv_GetPhysicalDeviceImageFormatProperties2KHR(
* present and VkExternalImageFormatPropertiesKHX will be ignored.
*/
if (external_info->handleType != 0) {
- /* FINISHME: Support at least one external memory type for images. */
- (void) external_props;
-
- result = vk_errorf(VK_ERROR_FORMAT_NOT_SUPPORTED,
- "unsupported VkExternalMemoryTypeFlagBitsKHX 0x%x",
- external_info->handleType);
- goto fail;
+ switch (external_info->handleType) {
+ case VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHX:
+ external_props->externalMemoryProperties = prime_fd_props;
+ break;
+ default:
+ /* From the Vulkan 1.0.42 spec:
+ *
+ * If handleType is not compatible with the [parameters] specified
+ * in VkPhysicalDeviceImageFormatInfo2KHR, then
+ * vkGetPhysicalDeviceImageFormatProperties2KHR returns
+ * VK_ERROR_FORMAT_NOT_SUPPORTED.
+ */
+ result = vk_errorf(VK_ERROR_FORMAT_NOT_SUPPORTED,
+ "unsupported VkExternalMemoryTypeFlagBitsKHX 0x%x",
+ external_info->handleType);
+ goto fail;
+ }
}
return VK_SUCCESS;
@@ -757,8 +778,30 @@ void anv_GetPhysicalDeviceExternalBufferPropertiesKHX(
const VkPhysicalDeviceExternalBufferInfoKHX* pExternalBufferInfo,
VkExternalBufferPropertiesKHX* pExternalBufferProperties)
{
- anv_finishme("Handle external buffers");
+ /* The Vulkan 1.0.42 spec says "handleType must be a valid
+ * VkExternalMemoryHandleTypeFlagBitsKHX value" in
+ * VkPhysicalDeviceExternalBufferInfoKHX. This differs from
+ * VkPhysicalDeviceExternalImageFormatInfoKHX, which surprisingly permits
+ * handleType == 0.
+ */
+ assert(pExternalBufferInfo->handleType != 0);
+
+ /* All of the current flags are for sparse which we don't support yet.
+ * Even when we do support it, doing sparse on external memory sounds
+ * sketchy. Also, just disallowing flags is the safe option.
+ */
+ if (pExternalBufferInfo->flags)
+ goto unsupported;
+
+ switch (pExternalBufferInfo->handleType) {
+ case VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHX:
+ pExternalBufferProperties->externalMemoryProperties = prime_fd_props;
+ return;
+ default:
+ goto unsupported;
+ }
+ unsupported:
pExternalBufferProperties->externalMemoryProperties =
(VkExternalMemoryPropertiesKHX) {0};
}
--
2.11.1
More information about the mesa-dev
mailing list