lavapipe: add vk1.1 image swapchain support
authorDave Airlie <airlied@redhat.com>
Thu, 8 Apr 2021 06:37:04 +0000 (16:37 +1000)
committerMarge Bot <eric+marge@anholt.net>
Thu, 8 Apr 2021 20:02:26 +0000 (20:02 +0000)
Adding support to create images from memory in the swapchain.
Just missed this in my pass of 1.1 features

Reviewed-By: Mike Blumenkrantz <michael.blumenkrantz@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/10099>

src/gallium/frontends/lavapipe/lvp_device.c
src/gallium/frontends/lavapipe/lvp_image.c
src/gallium/frontends/lavapipe/lvp_private.h

index cbb7501..a6e2c60 100644 (file)
@@ -1543,13 +1543,41 @@ VKAPI_ATTR VkResult VKAPI_CALL lvp_BindImageMemory2(VkDevice _device,
 {
    LVP_FROM_HANDLE(lvp_device, device, _device);
    for (uint32_t i = 0; i < bindInfoCount; ++i) {
-      LVP_FROM_HANDLE(lvp_device_memory, mem, pBindInfos[i].memory);
-      LVP_FROM_HANDLE(lvp_image, image, pBindInfos[i].image);
+      const VkBindImageMemoryInfo *bind_info = &pBindInfos[i];
+      LVP_FROM_HANDLE(lvp_device_memory, mem, bind_info->memory);
+      LVP_FROM_HANDLE(lvp_image, image, bind_info->image);
+      bool did_bind = false;
+
+      vk_foreach_struct_const(s, bind_info->pNext) {
+         switch (s->sType) {
+         case VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_SWAPCHAIN_INFO_KHR: {
+            const VkBindImageMemorySwapchainInfoKHR *swapchain_info =
+               (const VkBindImageMemorySwapchainInfoKHR *) s;
+            struct lvp_image *swapchain_image =
+               lvp_swapchain_get_image(swapchain_info->swapchain,
+                                       swapchain_info->imageIndex);
+
+            image->pmem = swapchain_image->pmem;
+            image->memory_offset = swapchain_image->memory_offset;
+            device->pscreen->resource_bind_backing(device->pscreen,
+                                                   image->bo,
+                                                   image->pmem,
+                                                   image->memory_offset);
+            did_bind = true;
+         }
+         default:
+            break;
+         }
+      }
 
-      device->pscreen->resource_bind_backing(device->pscreen,
-                                             image->bo,
-                                             mem->pmem,
-                                             pBindInfos[i].memoryOffset);
+      if (!did_bind) {
+         image->pmem = mem->pmem;
+         image->memory_offset = bind_info->memoryOffset;
+         device->pscreen->resource_bind_backing(device->pscreen,
+                                                image->bo,
+                                                mem->pmem,
+                                                bind_info->memoryOffset);
+      }
    }
    return VK_SUCCESS;
 }
index 457969e..e889a17 100644 (file)
@@ -98,12 +98,65 @@ lvp_image_create(VkDevice _device,
    return VK_SUCCESS;
 }
 
+struct lvp_image *
+lvp_swapchain_get_image(VkSwapchainKHR swapchain,
+                        uint32_t index)
+{
+   uint32_t n_images = index + 1;
+   VkImage *images = malloc(sizeof(*images) * n_images);
+   VkResult result = wsi_common_get_images(swapchain, &n_images, images);
+
+   if (result != VK_SUCCESS && result != VK_INCOMPLETE) {
+      free(images);
+      return NULL;
+   }
+
+   LVP_FROM_HANDLE(lvp_image, image, images[index]);
+   free(images);
+
+   return image;
+}
+
+static VkResult
+lvp_image_from_swapchain(VkDevice device,
+                         const VkImageCreateInfo *pCreateInfo,
+                         const VkImageSwapchainCreateInfoKHR *swapchain_info,
+                         const VkAllocationCallbacks *pAllocator,
+                         VkImage *pImage)
+{
+   struct lvp_image *swapchain_image = lvp_swapchain_get_image(swapchain_info->swapchain, 0);
+   assert(swapchain_image);
+
+   assert(swapchain_image->type == pCreateInfo->imageType);
+
+   VkImageCreateInfo local_create_info;
+   local_create_info = *pCreateInfo;
+   local_create_info.pNext = NULL;
+   /* The following parameters are implictly selected by the wsi code. */
+   local_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
+   local_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
+   local_create_info.usage |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
+
+   assert(!(local_create_info.usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT));
+   return lvp_image_create(device,
+      &(struct lvp_image_create_info) {
+         .vk_info = &local_create_info,
+      },
+      pAllocator,
+      pImage);
+}
+
 VKAPI_ATTR VkResult VKAPI_CALL
 lvp_CreateImage(VkDevice device,
                 const VkImageCreateInfo *pCreateInfo,
                 const VkAllocationCallbacks *pAllocator,
                 VkImage *pImage)
 {
+   const VkImageSwapchainCreateInfoKHR *swapchain_info =
+      vk_find_struct_const(pCreateInfo->pNext, IMAGE_SWAPCHAIN_CREATE_INFO_KHR);
+   if (swapchain_info && swapchain_info->swapchain != VK_NULL_HANDLE)
+      return lvp_image_from_swapchain(device, pCreateInfo, swapchain_info,
+                                      pAllocator, pImage);
    return lvp_image_create(device,
       &(struct lvp_image_create_info) {
          .vk_info = pCreateInfo,
index 3733f69..d1e0b27 100644 (file)
@@ -209,6 +209,8 @@ struct lvp_image {
    VkImageType type;
    VkDeviceSize size;
    uint32_t alignment;
+   struct pipe_memory_allocation *pmem;
+   unsigned memory_offset;
    struct pipe_resource *bo;
 };
 
@@ -1104,6 +1106,8 @@ VkResult lvp_execute_cmds(struct lvp_device *device,
                           struct lvp_fence *fence,
                           struct lvp_cmd_buffer *cmd_buffer);
 
+struct lvp_image *lvp_swapchain_get_image(VkSwapchainKHR swapchain,
+                                         uint32_t index);
 enum pipe_format vk_format_to_pipe(VkFormat format);
 
 static inline VkImageAspectFlags