<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Tue, Feb 28, 2017 at 10:58 AM, Chad Versace <span dir="ltr"><<a href="mailto:chadversary@chromium.org" target="_blank">chadversary@chromium.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">From: Jason Ekstrand <<a href="mailto:jason.ekstrand@intel.com">jason.ekstrand@intel.com</a>><br>
<br>
<br>
v2 (chadv):<br>
- Rebase.<br>
- Fix vkGetPhysicalDeviceImageFormat<wbr>Properties2KHR when<br>
handleType == 0.<br>
- Move handleType-independency comments out of handleType-switch, in<br>
vkGetPhysicalDeviceExternalBuf<wbr>ferPropertiesKHX. Reduces diff in<br>
future dma_buf patches.<br>
<br>
Co-authored-with: Chad Versace <<a href="mailto:chadversary@chromium.org">chadversary@chromium.org</a>><br>
---<br>
<br>
On my branch wip/anv-external-memory.<br>
<a href="http://git.kiwitree.net/cgit/~chadv/mesa/log/?h=wip/anv-external-memory" rel="noreferrer" target="_blank">http://git.kiwitree.net/cgit/~<wbr>chadv/mesa/log/?h=wip/anv-<wbr>external-memory</a><br>
<br>
src/intel/vulkan/anv_device.c | 90 +++++++++++++++++++++++++++++-<wbr>---<br>
src/intel/vulkan/anv_<wbr>entrypoints_gen.py | 1 +<br>
src/intel/vulkan/anv_formats.c | 59 ++++++++++++++++++---<br>
3 files changed, 133 insertions(+), 17 deletions(-)<br>
<br>
diff --git a/src/intel/vulkan/anv_device.<wbr>c b/src/intel/vulkan/anv_device.<wbr>c<br>
index 024e19f91b9..ec88547368a 100644<br>
--- a/src/intel/vulkan/anv_device.<wbr>c<br>
+++ b/src/intel/vulkan/anv_device.<wbr>c<br>
@@ -310,6 +310,10 @@ static const VkExtensionProperties device_extensions[] = {<br>
.extensionName = VK_KHX_EXTERNAL_MEMORY_<wbr>EXTENSION_NAME,<br>
.specVersion = 1,<br>
},<br>
+ {<br>
+ .extensionName = VK_KHX_EXTERNAL_MEMORY_FD_<wbr>EXTENSION_NAME,<br>
+ .specVersion = 1,<br>
+ },<br>
};<br>
<br>
static void *<br>
@@ -1400,7 +1404,7 @@ VkResult anv_AllocateMemory(<br>
{<br>
ANV_FROM_HANDLE(anv_device, device, _device);<br>
struct anv_device_memory *mem;<br>
- VkResult result;<br>
+ VkResult result = VK_SUCCESS;<br>
<br>
assert(pAllocateInfo->sType == VK_STRUCTURE_TYPE_MEMORY_<wbr>ALLOCATE_INFO);<br>
<br>
@@ -1418,18 +1422,50 @@ VkResult anv_AllocateMemory(<br>
if (mem == NULL)<br>
return vk_error(VK_ERROR_OUT_OF_HOST_<wbr>MEMORY);<br>
<br>
- /* The kernel is going to give us whole pages anyway */<br>
- uint64_t alloc_size = align_u64(pAllocateInfo-><wbr>allocationSize, 4096);<br>
-<br>
- result = anv_bo_init_new(&mem->bo, device, alloc_size);<br>
- if (result != VK_SUCCESS)<br>
- goto fail;<br>
-<br>
mem->type_index = pAllocateInfo-><wbr>memoryTypeIndex;<br>
-<br>
mem->map = NULL;<br>
mem->map_size = 0;<br>
<br>
+ const VkImportMemoryFdInfoKHX *fd_info =<br>
+ vk_find_struct_const(<wbr>pAllocateInfo->pNext, IMPORT_MEMORY_FD_INFO_KHX);<br>
+<br>
+ /* The Vulkan spec permits handleType to be 0, in which case the struct is<br>
+ * ignored.<br>
+ */<br>
+ if (fd_info && fd_info->handleType) {<br>
+ /* At the moment, we only support the OPAQUE_FD memory type which is<br>
+ * just a GEM buffer.<br>
+ */<br>
+ assert(fd_info->handleType ==<br>
+ VK_EXTERNAL_MEMORY_HANDLE_<wbr>TYPE_OPAQUE_FD_BIT_KHX);<br>
+<br>
+ uint32_t gem_handle = anv_gem_fd_to_handle(device, fd_info->fd);<br>
+ if (!gem_handle) {<br>
+ result = vk_error(VK_ERROR_INVALID_<wbr>EXTERNAL_HANDLE_KHX);<br>
+ goto fail;<br>
+ }<br>
+<br>
+ /* From the Vulkan spec:<br>
+ *<br>
+ * "Importing memory from a file descriptor transfers ownership of<br>
+ * the file descriptor from the application to the Vulkan<br>
+ * implementation. The application must not perform any operations on<br>
+ * the file descriptor after a successful import."<br>
+ *<br>
+ * If the import fails, we leave the file descriptor open.<br>
+ */<br>
+ close(fd_info->fd);<br>
+<br>
+ anv_bo_init(&mem->bo, gem_handle, pAllocateInfo->allocationSize)<wbr>;<br>
+ } else {<br>
+ /* The kernel is going to give us whole pages anyway */<br>
+ uint64_t alloc_size = align_u64(pAllocateInfo-><wbr>allocationSize, 4096);<br>
+<br>
+ result = anv_bo_init_new(&mem->bo, device, alloc_size);<br>
+ if (result != VK_SUCCESS)<br>
+ goto fail;<br>
+ }<br>
+<br>
*pMem = anv_device_memory_to_handle(<wbr>mem);<br>
<br>
return VK_SUCCESS;<br>
@@ -1440,6 +1476,42 @@ VkResult anv_AllocateMemory(<br>
return result;<br>
}<br>
<br>
+VkResult anv_GetMemoryFdKHX(<br>
+ VkDevice device_h,<br>
+ VkDeviceMemory memory_h,<br>
+ VkExternalMemoryHandleTypeFlag<wbr>BitsKHX handleType,<br>
+ int* pFd)<br>
+{<br>
+ ANV_FROM_HANDLE(anv_device, dev, device_h);<br>
+ ANV_FROM_HANDLE(anv_device_<wbr>memory, mem, memory_h);<br>
+<br>
+ /* We support only one handle type. */<br>
+ assert(handleType == VK_EXTERNAL_MEMORY_HANDLE_<wbr>TYPE_OPAQUE_FD_BIT_KHX);<br>
+<br>
+ int fd = anv_gem_handle_to_fd(dev, mem->bo.gem_handle);<br>
+ if (fd == -1)<br>
+ return vk_error(VK_ERROR_INVALID_<wbr>EXTERNAL_HANDLE_KHX);<br>
+<br>
+ *pFd = fd;<br>
+<br>
+ return VK_SUCCESS;<br>
+}<br>
+<br>
+VkResult anv_GetMemoryFdPropertiesKHX(<br>
+ VkDevice device_h,<br>
+ VkExternalMemoryHandleTypeFlag<wbr>BitsKHX handleType,<br>
+ int fd,<br>
+ VkMemoryFdPropertiesKHX* pMemoryFdProperties)<br>
+{<br>
+ /* The valid usage section for this function says:<br>
+ *<br>
+ * "handleType must not be one of the handle types defined as opaque."<br>
+ *<br>
+ * Since we only handle opaque handles for now, there are no FD properties.<br>
+ */<br>
+ return VK_ERROR_INVALID_EXTERNAL_<wbr>HANDLE_KHX;<br>
+}<br>
+<br>
void anv_FreeMemory(<br>
VkDevice _device,<br>
VkDeviceMemory _mem,<br>
diff --git a/src/intel/vulkan/anv_<wbr>entrypoints_gen.py b/src/intel/vulkan/anv_<wbr>entrypoints_gen.py<br>
index d8816a581a2..530163c9eff 100644<br>
--- a/src/intel/vulkan/anv_<wbr>entrypoints_gen.py<br>
+++ b/src/intel/vulkan/anv_<wbr>entrypoints_gen.py<br>
@@ -39,6 +39,7 @@ supported_extensions = [<br>
'VK_KHR_xlib_surface',<br>
'VK_KHX_external_memory',<br>
'VK_KHX_external_memory_<wbr>capabilities',<br>
+ 'VK_KHX_external_memory_fd',<br>
]<br>
<br>
# We generate a static hash table for entry point lookup<br>
diff --git a/src/intel/vulkan/anv_<wbr>formats.c b/src/intel/vulkan/anv_<wbr>formats.c<br>
index f91ba437f1e..196a7516dfa 100644<br>
--- a/src/intel/vulkan/anv_<wbr>formats.c<br>
+++ b/src/intel/vulkan/anv_<wbr>formats.c<br>
@@ -656,6 +656,17 @@ VkResult anv_<wbr>GetPhysicalDeviceImageFormatPr<wbr>operties(<br>
pImageFormatProperties);<br>
}<br>
<br>
+static const VkExternalMemoryPropertiesKHX prime_fd_props = {<br>
+ /* If we can handle external, then we can both import and export it. */<br>
+ .externalMemoryFeatures = VK_EXTERNAL_MEMORY_FEATURE_<wbr>EXPORTABLE_BIT_KHX |<br>
+ VK_EXTERNAL_MEMORY_FEATURE_<wbr>IMPORTABLE_BIT_KHX,<br>
+ /* For the moment, let's not support mixing and matching */<br>
+ .exportFromImportedHandleTypes =<br>
+ VK_EXTERNAL_MEMORY_HANDLE_<wbr>TYPE_OPAQUE_FD_BIT_KHX,<br>
+ .compatibleHandleTypes =<br>
+ VK_EXTERNAL_MEMORY_HANDLE_<wbr>TYPE_OPAQUE_FD_BIT_KHX,<br>
+};<br>
+<br>
VkResult anv_<wbr>GetPhysicalDeviceImageFormatPr<wbr>operties2KHR(<br>
VkPhysicalDevice physicalDevice,<br>
const VkPhysicalDeviceImageFormatInf<wbr>o2KHR* base_info,<br>
@@ -702,13 +713,23 @@ VkResult anv_<wbr>GetPhysicalDeviceImageFormatPr<wbr>operties2KHR(<br>
* present and VkExternalImageFormatPropertie<wbr>sKHX will be ignored.<br>
*/<br>
if (external_info->handleType != 0) {<br>
- /* FINISHME: Support at least one external memory type for images. */<br>
- (void) external_props;<br>
-<br>
- result = vk_errorf(VK_ERROR_FORMAT_NOT_<wbr>SUPPORTED,<br>
- "unsupported VkExternalMemoryTypeFlagBitsKH<wbr>X 0x%x",<br>
- external_info->handleType);<br>
- goto fail;<br>
+ switch (external_info->handleType) {<br>
+ case VK_EXTERNAL_MEMORY_HANDLE_<wbr>TYPE_OPAQUE_FD_BIT_KHX:<br>
+ external_props-><wbr>externalMemoryProperties = prime_fd_props;<br>
+ break;<br>
+ default:<br>
+ /* From the Vulkan 1.0.42 spec:<br>
+ *<br>
+ * If handleType is not compatible with the [parameters] specified<br>
+ * in VkPhysicalDeviceImageFormatInf<wbr>o2KHR, then<br>
+ * vkGetPhysicalDeviceImageFormat<wbr>Properties2KHR returns<br>
+ * VK_ERROR_FORMAT_NOT_SUPPORTED.<br>
+ */<br>
+ result = vk_errorf(VK_ERROR_FORMAT_NOT_<wbr>SUPPORTED,<br>
+ "unsupported VkExternalMemoryTypeFlagBitsKH<wbr>X 0x%x",<br>
+ external_info->handleType);<br>
+ goto fail;<br>
+ }<br>
}<br>
<br>
return VK_SUCCESS;<br>
@@ -757,8 +778,30 @@ void anv_<wbr>GetPhysicalDeviceExternalBuffe<wbr>rPropertiesKHX(<br>
const VkPhysicalDeviceExternalBuffer<wbr>InfoKHX* pExternalBufferInfo,<br>
VkExternalBufferPropertiesKHX* pExternalBufferProperties)<br>
{<br>
- anv_finishme("Handle external buffers");<br>
+ /* The Vulkan 1.0.42 spec says "handleType must be a valid<br>
+ * VkExternalMemoryHandleTypeFlag<wbr>BitsKHX value" in<br>
+ * VkPhysicalDeviceExternalBuffer<wbr>InfoKHX. This differs from<br>
+ * VkPhysicalDeviceExternalImageF<wbr>ormatInfoKHX, which surprisingly permits<br>
+ * handleType == 0.<br></blockquote><div><br></div><div>It's not that surprising. It lets the user just always chain in the struct but makes it behave as if it weren't there if handleType == 0. For this entrypoint, they won't be calling it unless they actually want to query something.<br><br></div><div>Changes look good to me. I'll pull this patch into my tree.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+ */<br>
+ assert(pExternalBufferInfo-><wbr>handleType != 0);<br>
+<br>
+ /* All of the current flags are for sparse which we don't support yet.<br>
+ * Even when we do support it, doing sparse on external memory sounds<br>
+ * sketchy. Also, just disallowing flags is the safe option.<br>
+ */<br>
+ if (pExternalBufferInfo->flags)<br>
+ goto unsupported;<br>
+<br>
+ switch (pExternalBufferInfo-><wbr>handleType) {<br>
+ case VK_EXTERNAL_MEMORY_HANDLE_<wbr>TYPE_OPAQUE_FD_BIT_KHX:<br>
+ pExternalBufferProperties-><wbr>externalMemoryProperties = prime_fd_props;<br>
+ return;<br>
+ default:<br>
+ goto unsupported;<br>
+ }<br>
<br>
+ unsupported:<br>
pExternalBufferProperties-><wbr>externalMemoryProperties =<br>
(<wbr>VkExternalMemoryPropertiesKHX) {0};<br>
}<br>
<span class="HOEnZb"><font color="#888888">--<br>
2.11.1<br>
<br>
______________________________<wbr>_________________<br>
mesa-dev mailing list<br>
<a href="mailto:mesa-dev@lists.freedesktop.org">mesa-dev@lists.freedesktop.org</a><br>
<a href="https://lists.freedesktop.org/mailman/listinfo/mesa-dev" rel="noreferrer" target="_blank">https://lists.freedesktop.org/<wbr>mailman/listinfo/mesa-dev</a><br>
</font></span></blockquote></div><br></div></div>