Mesa (master): venus: rework external memory capability queries

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Wed Apr 28 20:49:15 UTC 2021


Module: Mesa
Branch: master
Commit: efa185ed5cd6dfa4be7783c9095cbbe12f0f09b3
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=efa185ed5cd6dfa4be7783c9095cbbe12f0f09b3

Author: Chia-I Wu <olvaffe at gmail.com>
Date:   Wed Apr 21 12:43:33 2021 -0700

venus: rework external memory capability queries

The idea is to allow the renderer to use a completely different external
memory handle type (e.g., OPAQUE_WIN32!?) than the driver (always
OPAQUE_FD and DMA_BUF).  It hides the mismatch by doing translations in
vkGetPhysicalDevice*.

Signed-off-by: Chia-I Wu <olvaffe at gmail.com>
Reviewed-by: Yiwei Zhang <zzyiwei at chromium.org>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/10437>

---

 src/virtio/vulkan/vn_common.h |   1 +
 src/virtio/vulkan/vn_device.c | 139 +++++++++++++++++++++++++++++++++++-------
 src/virtio/vulkan/vn_device.h |   6 +-
 3 files changed, 122 insertions(+), 24 deletions(-)

diff --git a/src/virtio/vulkan/vn_common.h b/src/virtio/vulkan/vn_common.h
index 629e15365f6..b0a33f1a7ba 100644
--- a/src/virtio/vulkan/vn_common.h
+++ b/src/virtio/vulkan/vn_common.h
@@ -24,6 +24,7 @@
 
 #include "c11/threads.h"
 #include "util/bitscan.h"
+#include "util/compiler.h"
 #include "util/list.h"
 #include "util/macros.h"
 #include "util/os_time.h"
diff --git a/src/virtio/vulkan/vn_device.c b/src/virtio/vulkan/vn_device.c
index d5ca2341b5f..1199e49ed07 100644
--- a/src/virtio/vulkan/vn_device.c
+++ b/src/virtio/vulkan/vn_device.c
@@ -1331,21 +1331,39 @@ vn_physical_device_init_memory_properties(
 }
 
 static void
-vn_physical_device_init_external_memory_handles(
+vn_physical_device_init_external_memory(
    struct vn_physical_device *physical_dev)
 {
+   /* When a renderer VkDeviceMemory is exportable, we can create a
+    * vn_renderer_bo from it.  The vn_renderer_bo can be freely exported as an
+    * opaque fd or a dma-buf.
+    *
+    * However, to know if a rendender VkDeviceMemory is exportable, we have to
+    * start from VkPhysicalDeviceExternalImageFormatInfo (or
+    * vkGetPhysicalDeviceExternalBufferProperties).  That means we need to
+    * know the handle type that the renderer will use to make those queries.
+    *
+    * XXX We also assume that a vn_renderer_bo can be created as long as the
+    * renderer VkDeviceMemory has a mappable memory type.  That is plain
+    * wrong.  It is impossible to fix though until some new extension is
+    * created and supported by the driver, and that the renderer switches to
+    * the extension.
+    */
+
    if (!physical_dev->instance->renderer_info.has_dmabuf_import)
       return;
 
-   /* We have export support but we don't advertise it.  It is for WSI only at
-    * the moment.  For import support, we need to be able to serialize
-    * vkGetMemoryFdPropertiesKHR and VkImportMemoryFdInfoKHR.  We can
-    * serialize fd to bo->res_id, but we probably want to add new
-    * commands/structs first (using VK_MESA_venus_protocol).
-    *
-    * We also create a BO when a vn_device_memory is mappable.  We don't know
-    * which handle type the renderer uses.  That seems fine though.
+   /* TODO We assume the renderer uses dma-bufs here.  This should be
+    * negotiated by adding a new function to VK_MESA_venus_protocol.
     */
+   if (physical_dev->renderer_extensions.EXT_external_memory_dma_buf) {
+      physical_dev->external_memory.renderer_handle_type =
+         VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT;
+
+      physical_dev->external_memory.supported_handle_types =
+         VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT |
+         VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT;
+   }
 }
 
 static void
@@ -1618,7 +1636,7 @@ vn_physical_device_init(struct vn_physical_device *physical_dev)
 
    vn_physical_device_init_memory_properties(physical_dev);
 
-   vn_physical_device_init_external_memory_handles(physical_dev);
+   vn_physical_device_init_external_memory(physical_dev);
    vn_physical_device_init_external_fence_handles(physical_dev);
    vn_physical_device_init_external_semaphore_handles(physical_dev);
 
@@ -2635,6 +2653,55 @@ vn_GetPhysicalDeviceFormatProperties2(VkPhysicalDevice physicalDevice,
       physical_dev->instance, physicalDevice, format, pFormatProperties);
 }
 
+struct vn_physical_device_image_format_info {
+   VkPhysicalDeviceImageFormatInfo2 format;
+   VkPhysicalDeviceExternalImageFormatInfo external;
+   VkImageFormatListCreateInfo list;
+   VkImageStencilUsageCreateInfo stencil_usage;
+};
+
+static const VkPhysicalDeviceImageFormatInfo2 *
+vn_physical_device_fix_image_format_info(
+   struct vn_physical_device *physical_dev,
+   const VkPhysicalDeviceImageFormatInfo2 *info,
+   struct vn_physical_device_image_format_info *local_info)
+{
+   local_info->format = *info;
+   VkBaseOutStructure *dst = (void *)&local_info->format;
+
+   /* we should generate deep copy functions... */
+   vk_foreach_struct_const(src, info->pNext) {
+      void *pnext = NULL;
+      switch (src->sType) {
+      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO:
+         memcpy(&local_info->external, src, sizeof(local_info->external));
+         local_info->external.handleType =
+            physical_dev->external_memory.renderer_handle_type;
+         pnext = &local_info->external;
+         break;
+      case VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO:
+         memcpy(&local_info->list, src, sizeof(local_info->list));
+         pnext = &local_info->list;
+         break;
+      case VK_STRUCTURE_TYPE_IMAGE_STENCIL_USAGE_CREATE_INFO_EXT:
+         memcpy(&local_info->stencil_usage, src,
+                sizeof(local_info->stencil_usage));
+         pnext = &local_info->stencil_usage;
+         break;
+      default:
+         break;
+      }
+
+      if (pnext) {
+         dst->pNext = pnext;
+         dst = pnext;
+      }
+   }
+
+   dst->pNext = NULL;
+   return &local_info->format;
+}
+
 VkResult
 vn_GetPhysicalDeviceImageFormatProperties2(
    VkPhysicalDevice physicalDevice,
@@ -2643,6 +2710,10 @@ vn_GetPhysicalDeviceImageFormatProperties2(
 {
    struct vn_physical_device *physical_dev =
       vn_physical_device_from_handle(physicalDevice);
+   const VkExternalMemoryHandleTypeFlagBits renderer_handle_type =
+      physical_dev->external_memory.renderer_handle_type;
+   const VkExternalMemoryHandleTypeFlags supported_handle_types =
+      physical_dev->external_memory.supported_handle_types;
 
    const VkPhysicalDeviceExternalImageFormatInfo *external_info =
       vk_find_struct_const(pImageFormatInfo->pNext,
@@ -2650,9 +2721,18 @@ vn_GetPhysicalDeviceImageFormatProperties2(
    if (external_info && !external_info->handleType)
       external_info = NULL;
 
-   if (external_info &&
-       !(external_info->handleType & physical_dev->external_memory_handles))
-      return vn_error(physical_dev->instance, VK_ERROR_FORMAT_NOT_SUPPORTED);
+   struct vn_physical_device_image_format_info local_info;
+   if (external_info) {
+      if (!(external_info->handleType & supported_handle_types)) {
+         return vn_error(physical_dev->instance,
+                         VK_ERROR_FORMAT_NOT_SUPPORTED);
+      }
+
+      if (external_info->handleType != renderer_handle_type) {
+         pImageFormatInfo = vn_physical_device_fix_image_format_info(
+            physical_dev, pImageFormatInfo, &local_info);
+      }
+   }
 
    VkResult result;
    /* TODO per-device cache */
@@ -2666,10 +2746,11 @@ vn_GetPhysicalDeviceImageFormatProperties2(
       VkExternalMemoryProperties *mem_props =
          &img_props->externalMemoryProperties;
 
-      mem_props->compatibleHandleTypes &=
-         physical_dev->external_memory_handles;
-      mem_props->exportFromImportedHandleTypes &=
-         physical_dev->external_memory_handles;
+      mem_props->compatibleHandleTypes = supported_handle_types;
+      mem_props->exportFromImportedHandleTypes =
+         (mem_props->exportFromImportedHandleTypes & renderer_handle_type)
+            ? supported_handle_types
+            : 0;
    }
 
    return vn_result(physical_dev->instance, result);
@@ -2699,25 +2780,37 @@ vn_GetPhysicalDeviceExternalBufferProperties(
 {
    struct vn_physical_device *physical_dev =
       vn_physical_device_from_handle(physicalDevice);
+   const VkExternalMemoryHandleTypeFlagBits renderer_handle_type =
+      physical_dev->external_memory.renderer_handle_type;
+   const VkExternalMemoryHandleTypeFlags supported_handle_types =
+      physical_dev->external_memory.supported_handle_types;
+
    VkExternalMemoryProperties *props =
       &pExternalBufferProperties->externalMemoryProperties;
-
-   if (!(pExternalBufferInfo->handleType &
-         physical_dev->external_memory_handles)) {
+   if (!(pExternalBufferInfo->handleType & supported_handle_types)) {
       props->compatibleHandleTypes = pExternalBufferInfo->handleType;
       props->exportFromImportedHandleTypes = 0;
       props->externalMemoryFeatures = 0;
       return;
    }
 
+   VkPhysicalDeviceExternalBufferInfo local_info;
+   if (pExternalBufferInfo->handleType != renderer_handle_type) {
+      local_info = *pExternalBufferInfo;
+      local_info.handleType = renderer_handle_type;
+      pExternalBufferInfo = &local_info;
+   }
+
    /* TODO per-device cache */
    vn_call_vkGetPhysicalDeviceExternalBufferProperties(
       physical_dev->instance, physicalDevice, pExternalBufferInfo,
       pExternalBufferProperties);
 
-   props->compatibleHandleTypes &= physical_dev->external_memory_handles;
-   props->exportFromImportedHandleTypes &=
-      physical_dev->external_memory_handles;
+   props->compatibleHandleTypes = supported_handle_types;
+   props->exportFromImportedHandleTypes =
+      (props->exportFromImportedHandleTypes & renderer_handle_type)
+         ? supported_handle_types
+         : 0;
 }
 
 void
diff --git a/src/virtio/vulkan/vn_device.h b/src/virtio/vulkan/vn_device.h
index c4c9b9f24c7..554c23fb7e1 100644
--- a/src/virtio/vulkan/vn_device.h
+++ b/src/virtio/vulkan/vn_device.h
@@ -85,7 +85,11 @@ struct vn_physical_device {
 
    VkPhysicalDeviceMemoryProperties2 memory_properties;
 
-   VkExternalMemoryHandleTypeFlags external_memory_handles;
+   struct {
+      VkExternalMemoryHandleTypeFlagBits renderer_handle_type;
+      VkExternalMemoryHandleTypeFlags supported_handle_types;
+   } external_memory;
+
    VkExternalFenceHandleTypeFlags external_fence_handles;
    VkExternalSemaphoreHandleTypeFlags external_binary_semaphore_handles;
    VkExternalSemaphoreHandleTypeFlags external_timeline_semaphore_handles;



More information about the mesa-commit mailing list