mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-04-27 06:40:38 +02:00
vk/render_pass: Support VK_EXT_fragment_density_map
Support emulating "classic" FDM with dynamic rendering. Reviewed-by: Faith Ekstrand <faith@gfxstrand.net> Reviewed-by: Emma Anholt <emma@anholt.net> Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com> Reviewed-by: Connor Abbott <cwabbott0@gmail.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/22191>
This commit is contained in:
parent
df9694e98e
commit
f4b534d50f
2 changed files with 60 additions and 1 deletions
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue