Mesa (master): lavapipe: add support for VK_KHR_create_renderpass2

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Sun Mar 14 20:14:06 UTC 2021


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

Author: Dave Airlie <airlied at redhat.com>
Date:   Thu Dec 24 14:09:28 2020 +1000

lavapipe: add support for VK_KHR_create_renderpass2

Also move to the common code for create renderpass

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

---

 docs/features.txt                               |   2 +-
 src/gallium/frontends/lavapipe/lvp_cmd_buffer.c |  24 +++++
 src/gallium/frontends/lavapipe/lvp_device.c     |   1 +
 src/gallium/frontends/lavapipe/lvp_pass.c       | 131 ++++++++++++++++++++++++
 4 files changed, 157 insertions(+), 1 deletion(-)

diff --git a/docs/features.txt b/docs/features.txt
index ca30050be35..7294cca09b1 100644
--- a/docs/features.txt
+++ b/docs/features.txt
@@ -449,7 +449,7 @@ Vulkan 1.2 -- all DONE: anv
 
   VK_KHR_8bit_storage                                   DONE (anv/gen8+, radv)
   VK_KHR_buffer_device_address                          DONE (anv/gen8+, radv)
-  VK_KHR_create_renderpass2                             DONE (anv, radv, tu)
+  VK_KHR_create_renderpass2                             DONE (anv, lvp, radv, tu)
   VK_KHR_depth_stencil_resolve                          DONE (anv, radv, tu)
   VK_KHR_draw_indirect_count                            DONE (anv, lvp, radv, tu)
   VK_KHR_driver_properties                              DONE (anv, lvp, radv)
diff --git a/src/gallium/frontends/lavapipe/lvp_cmd_buffer.c b/src/gallium/frontends/lavapipe/lvp_cmd_buffer.c
index aa85d27b74b..ca5db81cdcf 100644
--- a/src/gallium/frontends/lavapipe/lvp_cmd_buffer.c
+++ b/src/gallium/frontends/lavapipe/lvp_cmd_buffer.c
@@ -350,6 +350,15 @@ VKAPI_ATTR void VKAPI_CALL lvp_CmdBeginRenderPass(
    cmd_buf_queue(cmd_buffer, cmd);
 }
 
+VKAPI_ATTR void VKAPI_CALL lvp_CmdBeginRenderPass2(
+    VkCommandBuffer                             commandBuffer,
+    const VkRenderPassBeginInfo*                pRenderPassBeginInfo,
+    const VkSubpassBeginInfo*                   pSubpassBeginInfo)
+{
+   lvp_CmdBeginRenderPass(commandBuffer, pRenderPassBeginInfo,
+                          pSubpassBeginInfo->contents);
+}
+
 VKAPI_ATTR void VKAPI_CALL lvp_CmdNextSubpass(
    VkCommandBuffer                             commandBuffer,
    VkSubpassContents                           contents)
@@ -366,6 +375,14 @@ VKAPI_ATTR void VKAPI_CALL lvp_CmdNextSubpass(
    cmd_buf_queue(cmd_buffer, cmd);
 }
 
+VKAPI_ATTR void VKAPI_CALL lvp_CmdNextSubpass2(
+    VkCommandBuffer                             commandBuffer,
+    const VkSubpassBeginInfo*                   pSubpassBeginInfo,
+    const VkSubpassEndInfo*                     pSubpassEndInfo)
+{
+   lvp_CmdNextSubpass(commandBuffer, pSubpassBeginInfo->contents);
+}
+
 VKAPI_ATTR void VKAPI_CALL lvp_CmdBindVertexBuffers(
    VkCommandBuffer                             commandBuffer,
    uint32_t                                    firstBinding,
@@ -498,6 +515,13 @@ VKAPI_ATTR void VKAPI_CALL lvp_CmdEndRenderPass(
    cmd_buf_queue(cmd_buffer, cmd);
 }
 
+VKAPI_ATTR void VKAPI_CALL lvp_CmdEndRenderPass2(
+   VkCommandBuffer                             commandBuffer,
+   const VkSubpassEndInfo*                     pSubpassEndInfo)
+{
+   lvp_CmdEndRenderPass(commandBuffer);
+}
+
 VKAPI_ATTR void VKAPI_CALL lvp_CmdSetViewport(
    VkCommandBuffer                             commandBuffer,
    uint32_t                                    firstViewport,
diff --git a/src/gallium/frontends/lavapipe/lvp_device.c b/src/gallium/frontends/lavapipe/lvp_device.c
index 3ab23a65d19..10ed9eeda36 100644
--- a/src/gallium/frontends/lavapipe/lvp_device.c
+++ b/src/gallium/frontends/lavapipe/lvp_device.c
@@ -90,6 +90,7 @@ static const struct vk_instance_extension_table lvp_instance_extensions_supporte
 
 static const struct vk_device_extension_table lvp_device_extensions_supported = {
    .KHR_bind_memory2                      = true,
+   .KHR_create_renderpass2                = true,
    .KHR_dedicated_allocation              = true,
    .KHR_descriptor_update_template        = true,
    .KHR_device_group                      = true,
diff --git a/src/gallium/frontends/lavapipe/lvp_pass.c b/src/gallium/frontends/lavapipe/lvp_pass.c
index 0e366f79866..62c7e441646 100644
--- a/src/gallium/frontends/lavapipe/lvp_pass.c
+++ b/src/gallium/frontends/lavapipe/lvp_pass.c
@@ -282,6 +282,137 @@ VKAPI_ATTR VkResult VKAPI_CALL lvp_CreateRenderPass(
    return VK_SUCCESS;
 }
 
+static unsigned
+lvp_num_subpass_attachments2(const VkSubpassDescription2 *desc)
+{
+   return desc->inputAttachmentCount +
+      desc->colorAttachmentCount +
+      (desc->pResolveAttachments ? desc->colorAttachmentCount : 0) +
+      (desc->pDepthStencilAttachment != NULL);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL lvp_CreateRenderPass2(
+    VkDevice                                    _device,
+    const VkRenderPassCreateInfo2*              pCreateInfo,
+    const VkAllocationCallbacks*                pAllocator,
+    VkRenderPass*                               pRenderPass)
+{
+   LVP_FROM_HANDLE(lvp_device, device, _device);
+   struct lvp_render_pass *pass;
+   size_t attachments_offset;
+   size_t size;
+
+   size = sizeof(*pass);
+   size += pCreateInfo->subpassCount * sizeof(pass->subpasses[0]);
+   attachments_offset = size;
+   size += pCreateInfo->attachmentCount * sizeof(pass->attachments[0]);
+
+   pass = vk_alloc2(&device->vk.alloc, pAllocator, size, 8,
+                    VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
+   if (pass == NULL)
+      return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
+
+   /* Clear the subpasses along with the parent pass. This required because
+    * each array member of lvp_subpass must be a valid pointer if not NULL.
+    */
+   memset(pass, 0, size);
+
+   vk_object_base_init(&device->vk, &pass->base,
+                       VK_OBJECT_TYPE_RENDER_PASS);
+   pass->attachment_count = pCreateInfo->attachmentCount;
+   pass->subpass_count = pCreateInfo->subpassCount;
+   pass->attachments = (struct lvp_render_pass_attachment *)((char *)pass + attachments_offset);
+
+   for (uint32_t i = 0; i < pCreateInfo->attachmentCount; i++) {
+      struct lvp_render_pass_attachment *att = &pass->attachments[i];
+
+      att->format = pCreateInfo->pAttachments[i].format;
+      att->samples = pCreateInfo->pAttachments[i].samples;
+      att->load_op = pCreateInfo->pAttachments[i].loadOp;
+      att->stencil_load_op = pCreateInfo->pAttachments[i].stencilLoadOp;
+      att->final_layout = pCreateInfo->pAttachments[i].finalLayout;
+      att->first_subpass_idx = UINT32_MAX;
+   }
+   uint32_t subpass_attachment_count = 0;
+   for (uint32_t i = 0; i < pCreateInfo->subpassCount; i++) {
+      subpass_attachment_count += lvp_num_subpass_attachments2(&pCreateInfo->pSubpasses[i]);
+   }
+
+   if (subpass_attachment_count) {
+      pass->subpass_attachments =
+         vk_alloc2(&device->vk.alloc, pAllocator,
+                   subpass_attachment_count * sizeof(struct lvp_subpass_attachment), 8,
+                   VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
+      if (pass->subpass_attachments == NULL) {
+         vk_free2(&device->vk.alloc, pAllocator, pass);
+         return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
+      }
+   } else
+      pass->subpass_attachments = NULL;
+
+   struct lvp_subpass_attachment *p = pass->subpass_attachments;
+   for (uint32_t i = 0; i < pCreateInfo->subpassCount; i++) {
+      const VkSubpassDescription2 *desc = &pCreateInfo->pSubpasses[i];
+      struct lvp_subpass *subpass = &pass->subpasses[i];
+
+      subpass->input_count = desc->inputAttachmentCount;
+      subpass->color_count = desc->colorAttachmentCount;
+      subpass->attachment_count = lvp_num_subpass_attachments2(desc);
+      subpass->attachments = p;
+      subpass->view_mask = desc->viewMask;
+
+      if (desc->inputAttachmentCount > 0) {
+         subpass->input_attachments = p;
+         p += desc->inputAttachmentCount;
+
+         for (uint32_t j = 0; j < desc->inputAttachmentCount; j++) {
+            subpass->input_attachments[j] = (struct lvp_subpass_attachment) {
+               .attachment = desc->pInputAttachments[j].attachment,
+               .layout = desc->pInputAttachments[j].layout,
+            };
+         }
+      }
+
+      if (desc->colorAttachmentCount > 0) {
+         subpass->color_attachments = p;
+         p += desc->colorAttachmentCount;
+
+         for (uint32_t j = 0; j < desc->colorAttachmentCount; j++) {
+            subpass->color_attachments[j] = (struct lvp_subpass_attachment) {
+               .attachment = desc->pColorAttachments[j].attachment,
+               .layout = desc->pColorAttachments[j].layout,
+            };
+         }
+      }
+
+      if (desc->pResolveAttachments) {
+         subpass->resolve_attachments = p;
+         p += desc->colorAttachmentCount;
+
+         for (uint32_t j = 0; j < desc->colorAttachmentCount; j++) {
+            subpass->resolve_attachments[j] = (struct lvp_subpass_attachment) {
+               .attachment = desc->pResolveAttachments[j].attachment,
+               .layout = desc->pResolveAttachments[j].layout,
+            };
+         }
+      }
+
+      if (desc->pDepthStencilAttachment) {
+         subpass->depth_stencil_attachment = p++;
+
+         *subpass->depth_stencil_attachment = (struct lvp_subpass_attachment) {
+            .attachment = desc->pDepthStencilAttachment->attachment,
+            .layout = desc->pDepthStencilAttachment->layout,
+         };
+      }
+   }
+
+   lvp_render_pass_compile(pass);
+   *pRenderPass = lvp_render_pass_to_handle(pass);
+
+   return VK_SUCCESS;
+}
+
 VKAPI_ATTR void VKAPI_CALL lvp_DestroyRenderPass(
    VkDevice                                    _device,
    VkRenderPass                                _pass,



More information about the mesa-commit mailing list