radv: add support for VK_KHR_create_renderpass2
authorSamuel Pitoiset <samuel.pitoiset@gmail.com>
Sun, 8 Jul 2018 15:47:52 +0000 (17:47 +0200)
committerSamuel Pitoiset <samuel.pitoiset@gmail.com>
Thu, 12 Jul 2018 08:20:10 +0000 (10:20 +0200)
VkCreateRenderPass2KHR() is quite similar to VkCreateRenderPass()
but refactoring the code is a bit painful.

Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
Reviewed-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
src/amd/vulkan/radv_cmd_buffer.c
src/amd/vulkan/radv_extensions.py
src/amd/vulkan/radv_pass.c

index d771c1ccd2ce801f07d458ffe67fcfb4fe633442..168361d8d5e7c638fbde6a693bd187f33c7729ee 100644 (file)
@@ -3061,6 +3061,15 @@ void radv_CmdBeginRenderPass(
        radv_cmd_buffer_clear_subpass(cmd_buffer);
 }
 
+void radv_CmdBeginRenderPass2KHR(
+    VkCommandBuffer                             commandBuffer,
+    const VkRenderPassBeginInfo*                pRenderPassBeginInfo,
+    const VkSubpassBeginInfoKHR*                pSubpassBeginInfo)
+{
+       radv_CmdBeginRenderPass(commandBuffer, pRenderPassBeginInfo,
+                               pSubpassBeginInfo->contents);
+}
+
 void radv_CmdNextSubpass(
     VkCommandBuffer                             commandBuffer,
     VkSubpassContents                           contents)
@@ -3076,6 +3085,14 @@ void radv_CmdNextSubpass(
        radv_cmd_buffer_clear_subpass(cmd_buffer);
 }
 
+void radv_CmdNextSubpass2KHR(
+    VkCommandBuffer                             commandBuffer,
+    const VkSubpassBeginInfoKHR*                pSubpassBeginInfo,
+    const VkSubpassEndInfoKHR*                  pSubpassEndInfo)
+{
+       radv_CmdNextSubpass(commandBuffer, pSubpassBeginInfo->contents);
+}
+
 static void radv_emit_view_index(struct radv_cmd_buffer *cmd_buffer, unsigned index)
 {
        struct radv_pipeline *pipeline = cmd_buffer->state.pipeline;
@@ -3956,6 +3973,13 @@ void radv_CmdEndRenderPass(
        cmd_buffer->state.framebuffer = NULL;
 }
 
+void radv_CmdEndRenderPass2KHR(
+    VkCommandBuffer                             commandBuffer,
+    const VkSubpassEndInfoKHR*                  pSubpassEndInfo)
+{
+       radv_CmdEndRenderPass(commandBuffer);
+}
+
 /*
  * For HTILE we have the following interesting clear words:
  *   0xfffff30f: Uncompressed, full depth range, for depth+stencil HTILE
index c36559f48eff5d88dc8e0debdd705ceac8993272..094ed3bce3ebb24a59985940a874ad0da898dd65 100644 (file)
@@ -52,6 +52,7 @@ class Extension:
 EXTENSIONS = [
     Extension('VK_ANDROID_native_buffer',                 5, 'ANDROID && device->rad_info.has_syncobj_wait_for_submit'),
     Extension('VK_KHR_bind_memory2',                      1, True),
+    Extension('VK_KHR_create_renderpass2',                1, True),
     Extension('VK_KHR_dedicated_allocation',              1, True),
     Extension('VK_KHR_descriptor_update_template',        1, True),
     Extension('VK_KHR_device_group',                      1, True),
index 0e0f767751014a25eff0d8d3e90786101a56437b..2191093391c85655c5dbb0c55f68db280422221b 100644 (file)
@@ -197,6 +197,175 @@ VkResult radv_CreateRenderPass(
        return VK_SUCCESS;
 }
 
+VkResult radv_CreateRenderPass2KHR(
+    VkDevice                                    _device,
+    const VkRenderPassCreateInfo2KHR*           pCreateInfo,
+    const VkAllocationCallbacks*                pAllocator,
+    VkRenderPass*                               pRenderPass)
+{
+       RADV_FROM_HANDLE(radv_device, device, _device);
+       struct radv_render_pass *pass;
+       size_t size;
+       size_t attachments_offset;
+       VkRenderPassMultiviewCreateInfoKHR *multiview_info = NULL;
+
+       assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2_KHR);
+
+       size = sizeof(*pass);
+       size += pCreateInfo->subpassCount * sizeof(pass->subpasses[0]);
+       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->subpass_count = pCreateInfo->subpassCount;
+       pass->attachments = (void *) pass + attachments_offset;
+
+       vk_foreach_struct(ext, pCreateInfo->pNext) {
+               switch(ext->sType) {
+               case  VK_STRUCTURE_TYPE_RENDER_PASS_MULTIVIEW_CREATE_INFO_KHR:
+                       multiview_info = ( VkRenderPassMultiviewCreateInfoKHR*)ext;
+                       break;
+               default:
+                       break;
+               }
+       }
+
+       for (uint32_t i = 0; i < pCreateInfo->attachmentCount; i++) {
+               struct radv_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->initial_layout =  pCreateInfo->pAttachments[i].initialLayout;
+               att->final_layout =  pCreateInfo->pAttachments[i].finalLayout;
+               // att->store_op = pCreateInfo->pAttachments[i].storeOp;
+               // att->stencil_store_op = pCreateInfo->pAttachments[i].stencilStoreOp;
+       }
+       uint32_t subpass_attachment_count = 0;
+       struct radv_subpass_attachment *p;
+       for (uint32_t i = 0; i < pCreateInfo->subpassCount; i++) {
+               const VkSubpassDescription2KHR *desc = &pCreateInfo->pSubpasses[i];
+
+               subpass_attachment_count +=
+                       desc->inputAttachmentCount +
+                       desc->colorAttachmentCount +
+                       (desc->pResolveAttachments ? desc->colorAttachmentCount : 0) +
+                       (desc->pDepthStencilAttachment != NULL);
+       }
+
+       if (subpass_attachment_count) {
+               pass->subpass_attachments =
+                       vk_alloc2(&device->alloc, pAllocator,
+                                   subpass_attachment_count * sizeof(struct radv_subpass_attachment), 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;
+
+       p = pass->subpass_attachments;
+       for (uint32_t i = 0; i < pCreateInfo->subpassCount; i++) {
+               const VkSubpassDescription2KHR *desc = &pCreateInfo->pSubpasses[i];
+               uint32_t color_sample_count = 1, depth_sample_count = 1;
+               struct radv_subpass *subpass = &pass->subpasses[i];
+
+               subpass->input_count = desc->inputAttachmentCount;
+               subpass->color_count = desc->colorAttachmentCount;
+               if (multiview_info)
+                       subpass->view_mask = multiview_info->pViewMasks[i];
+
+               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 radv_subpass_attachment) {
+                                       .attachment = desc->pInputAttachments[j].attachment,
+                                       .layout = desc->pInputAttachments[j].layout,
+                               };
+                               if (desc->pInputAttachments[j].attachment != VK_ATTACHMENT_UNUSED)
+                                       pass->attachments[desc->pInputAttachments[j].attachment].view_mask |= subpass->view_mask;
+                       }
+               }
+
+               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 radv_subpass_attachment) {
+                                       .attachment = desc->pColorAttachments[j].attachment,
+                                       .layout = desc->pColorAttachments[j].layout,
+                               };
+                               if (desc->pColorAttachments[j].attachment != VK_ATTACHMENT_UNUSED) {
+                                       pass->attachments[desc->pColorAttachments[j].attachment].view_mask |= subpass->view_mask;
+                                       color_sample_count = pCreateInfo->pAttachments[desc->pColorAttachments[j].attachment].samples;
+                               }
+                       }
+               }
+
+               subpass->has_resolve = false;
+               if (desc->pResolveAttachments) {
+                       subpass->resolve_attachments = p;
+                       p += desc->colorAttachmentCount;
+
+                       for (uint32_t j = 0; j < desc->colorAttachmentCount; j++) {
+                               uint32_t a = desc->pResolveAttachments[j].attachment;
+                               subpass->resolve_attachments[j] = (struct radv_subpass_attachment) {
+                                       .attachment = desc->pResolveAttachments[j].attachment,
+                                       .layout = desc->pResolveAttachments[j].layout,
+                               };
+                               if (a != VK_ATTACHMENT_UNUSED) {
+                                       subpass->has_resolve = true;
+                                       pass->attachments[desc->pResolveAttachments[j].attachment].view_mask |= subpass->view_mask;
+                               }
+                       }
+               }
+
+               if (desc->pDepthStencilAttachment) {
+                       subpass->depth_stencil_attachment = (struct radv_subpass_attachment) {
+                               .attachment = desc->pDepthStencilAttachment->attachment,
+                               .layout = desc->pDepthStencilAttachment->layout,
+                       };
+                       if (desc->pDepthStencilAttachment->attachment != VK_ATTACHMENT_UNUSED) {
+                               pass->attachments[desc->pDepthStencilAttachment->attachment].view_mask |= subpass->view_mask;
+                               depth_sample_count = pCreateInfo->pAttachments[desc->pDepthStencilAttachment->attachment].samples;
+                       }
+               } else {
+                       subpass->depth_stencil_attachment.attachment = VK_ATTACHMENT_UNUSED;
+               }
+
+               subpass->max_sample_count = MAX2(color_sample_count,
+                                                depth_sample_count);
+       }
+
+       for (unsigned i = 0; i < pCreateInfo->dependencyCount; ++i) {
+               uint32_t dst = pCreateInfo->pDependencies[i].dstSubpass;
+               if (dst == VK_SUBPASS_EXTERNAL) {
+                       pass->end_barrier.src_stage_mask = pCreateInfo->pDependencies[i].srcStageMask;
+                       pass->end_barrier.src_access_mask = pCreateInfo->pDependencies[i].srcAccessMask;
+                       pass->end_barrier.dst_access_mask = pCreateInfo->pDependencies[i].dstAccessMask;
+               } else {
+                       pass->subpasses[dst].start_barrier.src_stage_mask = pCreateInfo->pDependencies[i].srcStageMask;
+                       pass->subpasses[dst].start_barrier.src_access_mask = pCreateInfo->pDependencies[i].srcAccessMask;
+                       pass->subpasses[dst].start_barrier.dst_access_mask = pCreateInfo->pDependencies[i].dstAccessMask;
+               }
+       }
+
+       *pRenderPass = radv_render_pass_to_handle(pass);
+
+       return VK_SUCCESS;
+}
+
 void radv_DestroyRenderPass(
        VkDevice                                    _device,
        VkRenderPass                                _pass,