v3dv: implement vk{Create,Destroy}RenderPass
authorIago Toral Quiroga <itoral@igalia.com>
Mon, 9 Dec 2019 11:16:35 +0000 (12:16 +0100)
committerMarge Bot <eric+marge@anholt.net>
Tue, 13 Oct 2020 21:21:25 +0000 (21:21 +0000)
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6766>

src/broadcom/vulkan/v3dv_pass.c
src/broadcom/vulkan/v3dv_private.h

index 7c8184b..7ec389e 100644 (file)
 
 #include "v3dv_private.h"
 
+static uint32_t
+num_subpass_attachments(const VkSubpassDescription *desc)
+{
+   return desc->inputAttachmentCount +
+          desc->colorAttachmentCount +
+          (desc->pResolveAttachments ? desc->colorAttachmentCount : 0) +
+          (desc->pDepthStencilAttachment != NULL);
+}
+
 VkResult
-v3dv_CreateRenderPass(VkDevice device,
+v3dv_CreateRenderPass(VkDevice _device,
                       const VkRenderPassCreateInfo *pCreateInfo,
                       const VkAllocationCallbacks *pAllocator,
                       VkRenderPass *pRenderPass)
 {
+   V3DV_FROM_HANDLE(v3dv_device, device, _device);
+   struct v3dv_render_pass *pass;
+
+   assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO);
+
+   size_t size = sizeof(*pass);
+   size_t subpasses_offset = size;
+   size += pCreateInfo->subpassCount * sizeof(pass->subpasses[0]);
+   size_t attachments_offset = size;
+   size += pCreateInfo->attachmentCount * sizeof(pass->attachments[0]);
+
+   pass = vk_alloc2(&device->alloc, pAllocator, size, 8,
+                    VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
+   if (pass == NULL)
+      return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
+
+   memset(pass, 0, size);
+   pass->attachment_count = pCreateInfo->attachmentCount;
+   pass->attachments = (void *) pass + attachments_offset;
+   pass->subpass_count = pCreateInfo->subpassCount;
+   pass->subpasses = (void *) pass + subpasses_offset;
+
+   for (uint32_t i = 0; i < pCreateInfo->attachmentCount; i++)
+      pass->attachments[i].desc = pCreateInfo->pAttachments[i];
+
+   uint32_t subpass_attachment_count = 0;
+   for (uint32_t i = 0; i < pCreateInfo->subpassCount; i++) {
+      const VkSubpassDescription *desc = &pCreateInfo->pSubpasses[i];
+      subpass_attachment_count += num_subpass_attachments(desc);
+   }
+
+   if (subpass_attachment_count) {
+      const size_t subpass_attachment_bytes =
+         subpass_attachment_count * sizeof(struct v3dv_subpass_attachment);
+      pass->subpass_attachments =
+         vk_alloc2(&device->alloc, pAllocator, subpass_attachment_bytes, 8,
+                   VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
+      if (pass->subpass_attachments == NULL) {
+         vk_free2(&device->alloc, pAllocator, pass);
+         return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
+      }
+   } else {
+      pass->subpass_attachments = NULL;
+   }
+
+   struct v3dv_subpass_attachment *p = pass->subpass_attachments;
+   for (uint32_t i = 0; i < pCreateInfo->subpassCount; i++) {
+      const VkSubpassDescription *desc = &pCreateInfo->pSubpasses[i];
+      struct v3dv_subpass *subpass = &pass->subpasses[i];
+
+      subpass->input_count = desc->inputAttachmentCount;
+      subpass->color_count = desc->colorAttachmentCount;
+
+      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 v3dv_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 v3dv_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 v3dv_subpass_attachment) {
+               .attachment = desc->pResolveAttachments[j].attachment,
+               .layout = desc->pResolveAttachments[j].layout,
+            };
+         }
+      }
+
+      if (desc->pDepthStencilAttachment) {
+         subpass->ds_attachment = (struct v3dv_subpass_attachment) {
+            .attachment = desc->pDepthStencilAttachment->attachment,
+            .layout = desc->pDepthStencilAttachment->layout,
+         };
+      } else {
+         subpass->ds_attachment.attachment = VK_ATTACHMENT_UNUSED;
+      }
+   }
+
+   /* FIXME: handle subpass dependencies */
+
+   *pRenderPass = v3dv_render_pass_to_handle(pass);
+
    return VK_SUCCESS;
 }
+
+void
+v3dv_DestroyRenderPass(VkDevice _device,
+                       VkRenderPass _pass,
+                       const VkAllocationCallbacks *pAllocator)
+{
+   V3DV_FROM_HANDLE(v3dv_device, device, _device);
+   V3DV_FROM_HANDLE(v3dv_render_pass, pass, _pass);
+
+   if (!_pass)
+      return;
+
+   vk_free2(&device->alloc, pAllocator, pass->subpass_attachments);
+   vk_free2(&device->alloc, pAllocator, pass);
+}
index 991561f..7abc252 100644 (file)
@@ -304,6 +304,36 @@ struct v3dv_buffer {
    VkDeviceSize mem_offset;
 };
 
+struct v3dv_subpass_attachment {
+   uint32_t attachment;
+   VkImageLayout layout;
+};
+
+struct v3dv_subpass {
+   uint32_t input_count;
+   struct v3dv_subpass_attachment *input_attachments;
+
+   uint32_t color_count;
+   struct v3dv_subpass_attachment *color_attachments;
+   struct v3dv_subpass_attachment *resolve_attachments;
+
+   struct v3dv_subpass_attachment ds_attachment;
+};
+
+struct v3dv_render_pass_attachment {
+   VkAttachmentDescription desc;
+};
+
+struct v3dv_render_pass {
+   uint32_t attachment_count;
+   struct v3dv_render_pass_attachment *attachments;
+
+   uint32_t subpass_count;
+   struct v3dv_subpass *subpasses;
+
+   struct v3dv_subpass_attachment *subpass_attachments;
+};
+
 struct v3dv_shader_module {
    unsigned char sha1[20];
    uint32_t size;