From: Connor Abbott Date: Thu, 30 Mar 2023 17:14:21 +0000 (-0500) Subject: vk/render_pass: Support VK_EXT_fragment_density_map X-Git-Tag: upstream/23.3.3~10581 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=f4b534d50f2b527365d5cde561b95ff49e0bf88e;p=platform%2Fupstream%2Fmesa.git vk/render_pass: Support VK_EXT_fragment_density_map Support emulating "classic" FDM with dynamic rendering. Reviewed-by: Faith Ekstrand Reviewed-by: Emma Anholt Reviewed-by: Lionel Landwerlin Reviewed-by: Connor Abbott Part-of: --- diff --git a/src/vulkan/runtime/vk_render_pass.c b/src/vulkan/runtime/vk_render_pass.c index c7d2a90..4b029c9 100644 --- a/src/vulkan/runtime/vk_render_pass.c +++ b/src/vulkan/runtime/vk_render_pass.c @@ -108,6 +108,10 @@ vk_common_CreateRenderPass(VkDevice _device, multiview_info = (const VkRenderPassMultiviewCreateInfo*) ext; break; + case VK_STRUCTURE_TYPE_RENDER_PASS_FRAGMENT_DENSITY_MAP_CREATE_INFO_EXT: + /* pass this through to CreateRenderPass2 */ + break; + default: mesa_logd("%s: ignored VkStructureType %u\n", __func__, ext->sType); break; @@ -822,6 +826,16 @@ vk_common_CreateRenderPass2(VkDevice _device, } } + const VkRenderPassFragmentDensityMapCreateInfoEXT *fdm_info = + vk_find_struct_const(pCreateInfo->pNext, + RENDER_PASS_FRAGMENT_DENSITY_MAP_CREATE_INFO_EXT); + if (fdm_info) { + pass->fragment_density_map = fdm_info->fragmentDensityMapAttachment; + } else { + pass->fragment_density_map.attachment = VK_ATTACHMENT_UNUSED; + pass->fragment_density_map.layout = VK_IMAGE_LAYOUT_UNDEFINED; + } + *pRenderPass = vk_render_pass_to_handle(pass); return VK_SUCCESS; @@ -849,8 +863,12 @@ vk_get_pipeline_rendering_flags(const VkGraphicsPipelineCreateInfo *info) VK_PIPELINE_CREATE_RENDERING_FRAGMENT_DENSITY_MAP_ATTACHMENT_BIT_EXT); VK_FROM_HANDLE(vk_render_pass, render_pass, info->renderPass); - if (render_pass != NULL) + if (render_pass != NULL) { rendering_flags |= render_pass->subpasses[info->subpass].pipeline_flags; + if (render_pass->fragment_density_map.attachment != VK_ATTACHMENT_UNUSED) + rendering_flags |= + VK_PIPELINE_CREATE_RENDERING_FRAGMENT_DENSITY_MAP_ATTACHMENT_BIT_EXT; + } return rendering_flags; } @@ -1999,6 +2017,8 @@ begin_subpass(struct vk_command_buffer *cmd_buffer, max_image_barrier_count += util_bitcount(subpass->view_mask) * util_bitcount(rp_att->aspects); } + if (pass->fragment_density_map.attachment != VK_ATTACHMENT_UNUSED) + max_image_barrier_count += util_bitcount(subpass->view_mask); STACK_ARRAY(VkImageMemoryBarrier2, image_barriers, max_image_barrier_count); uint32_t image_barrier_count = 0; @@ -2017,6 +2037,15 @@ begin_subpass(struct vk_command_buffer *cmd_buffer, max_image_barrier_count, image_barriers); } + if (pass->fragment_density_map.attachment != VK_ATTACHMENT_UNUSED) { + transition_attachment(cmd_buffer, pass->fragment_density_map.attachment, + subpass->view_mask, + pass->fragment_density_map.layout, + VK_IMAGE_LAYOUT_UNDEFINED, + &image_barrier_count, + max_image_barrier_count, + image_barriers); + } assert(image_barrier_count <= max_image_barrier_count); if (needs_mem_barrier || image_barrier_count > 0) { @@ -2091,6 +2120,32 @@ begin_subpass(struct vk_command_buffer *cmd_buffer, __vk_append_struct(&rendering, &fsr_attachment); } + VkRenderingFragmentDensityMapAttachmentInfoEXT fdm_attachment; + if (pass->fragment_density_map.attachment != VK_ATTACHMENT_UNUSED) { + assert(pass->fragment_density_map.attachment < pass->attachment_count); + struct vk_attachment_state *att_state = + &cmd_buffer->attachments[pass->fragment_density_map.attachment]; + + /* From the Vulkan 1.3.125 spec: + * + * VUID-VkRenderPassFragmentDensityMapCreateInfoEXT-fragmentDensityMapAttachment-02550 + * + * If fragmentDensityMapAttachment is not VK_ATTACHMENT_UNUSED, + * fragmentDensityMapAttachment must reference an attachment with a + * loadOp equal to VK_ATTACHMENT_LOAD_OP_LOAD or + * VK_ATTACHMENT_LOAD_OP_DONT_CARE + * + * This means we don't have to implement the load op. + */ + + fdm_attachment = (VkRenderingFragmentDensityMapAttachmentInfoEXT) { + .sType = VK_STRUCTURE_TYPE_RENDERING_FRAGMENT_DENSITY_MAP_ATTACHMENT_INFO_EXT, + .imageView = vk_image_view_to_handle(att_state->image_view), + .imageLayout = pass->fragment_density_map.layout, + }; + __vk_append_struct(&rendering, &fdm_attachment); + } + VkSampleLocationsInfoEXT sample_locations_tmp; if (sample_locations) { sample_locations_tmp = *sample_locations; diff --git a/src/vulkan/runtime/vk_render_pass.h b/src/vulkan/runtime/vk_render_pass.h index fe4453f..a4ecb4b 100644 --- a/src/vulkan/runtime/vk_render_pass.h +++ b/src/vulkan/runtime/vk_render_pass.h @@ -310,6 +310,9 @@ struct vk_render_pass { /** VkRenderPassCreateInfo2::dependencyCount */ uint32_t dependency_count; + /** VkRenderPassFragmentDensityMapCreateInfoEXT::fragmentDensityMapAttachment */ + VkAttachmentReference fragment_density_map; + /** VkRenderPassCreateInfo2::pDependencies */ struct vk_subpass_dependency *dependencies; }; @@ -341,6 +344,7 @@ vk_get_pipeline_rendering_create_info(const VkGraphicsPipelineCreateInfo *info); * - VK_PIPELINE_CREATE_COLOR_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT * - VK_PIPELINE_CREATE_DEPTH_STENCIL_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT * - VK_PIPELINE_CREATE_RENDERING_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR + * - VK_PIPELINE_CREATE_RENDERING_FRAGMENT_DENSITY_MAP_ATTACHMENT_BIT_EXT * * If VkGraphicsPipelineCreateInfo::renderPass is VK_NULL_HANDLE, the relevant * flags from VkGraphicsPipelineCreateInfo::flags will be returned.