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

Author: Dave Airlie <airl...@redhat.com>
Date:   Thu Apr  8 16:37:04 2021 +1000

lavapipe: add vk1.1 image swapchain support

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.blumenkra...@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/10099>

---

 src/gallium/frontends/lavapipe/lvp_device.c  | 40 +++++++++++++++++----
 src/gallium/frontends/lavapipe/lvp_image.c   | 53 ++++++++++++++++++++++++++++
 src/gallium/frontends/lavapipe/lvp_private.h |  4 +++
 3 files changed, 91 insertions(+), 6 deletions(-)

diff --git a/src/gallium/frontends/lavapipe/lvp_device.c 
b/src/gallium/frontends/lavapipe/lvp_device.c
index cbb750145d0..a6e2c60852a 100644
--- a/src/gallium/frontends/lavapipe/lvp_device.c
+++ b/src/gallium/frontends/lavapipe/lvp_device.c
@@ -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;
 }
diff --git a/src/gallium/frontends/lavapipe/lvp_image.c 
b/src/gallium/frontends/lavapipe/lvp_image.c
index 457969e073c..e889a1754af 100644
--- a/src/gallium/frontends/lavapipe/lvp_image.c
+++ b/src/gallium/frontends/lavapipe/lvp_image.c
@@ -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,
diff --git a/src/gallium/frontends/lavapipe/lvp_private.h 
b/src/gallium/frontends/lavapipe/lvp_private.h
index 3733f6974c7..d1e0b27ce31 100644
--- a/src/gallium/frontends/lavapipe/lvp_private.h
+++ b/src/gallium/frontends/lavapipe/lvp_private.h
@@ -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

_______________________________________________
mesa-commit mailing list
mesa-commit@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-commit

Reply via email to