From 3a16c722cf3e5c41c9228b7021754a085746dc4d Mon Sep 17 00:00:00 2001 From: Samuel Pitoiset Date: Sun, 8 Jul 2018 17:47:52 +0200 Subject: [PATCH] radv: add support for VK_KHR_create_renderpass2 VkCreateRenderPass2KHR() is quite similar to VkCreateRenderPass() but refactoring the code is a bit painful. Signed-off-by: Samuel Pitoiset Reviewed-by: Bas Nieuwenhuizen --- src/amd/vulkan/radv_cmd_buffer.c | 24 +++++ src/amd/vulkan/radv_extensions.py | 1 + src/amd/vulkan/radv_pass.c | 169 ++++++++++++++++++++++++++++++ 3 files changed, 194 insertions(+) diff --git a/src/amd/vulkan/radv_cmd_buffer.c b/src/amd/vulkan/radv_cmd_buffer.c index d771c1ccd2c..168361d8d5e 100644 --- a/src/amd/vulkan/radv_cmd_buffer.c +++ b/src/amd/vulkan/radv_cmd_buffer.c @@ -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 diff --git a/src/amd/vulkan/radv_extensions.py b/src/amd/vulkan/radv_extensions.py index c36559f48ef..094ed3bce3e 100644 --- a/src/amd/vulkan/radv_extensions.py +++ b/src/amd/vulkan/radv_extensions.py @@ -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), diff --git a/src/amd/vulkan/radv_pass.c b/src/amd/vulkan/radv_pass.c index 0e0f7677510..2191093391c 100644 --- a/src/amd/vulkan/radv_pass.c +++ b/src/amd/vulkan/radv_pass.c @@ -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, -- 2.30.2