diff --git a/src/vulkan/runtime/vk_graphics_state.c b/src/vulkan/runtime/vk_graphics_state.c index 550cc3f154c..722a93c0b5b 100644 --- a/src/vulkan/runtime/vk_graphics_state.c +++ b/src/vulkan/runtime/vk_graphics_state.c @@ -1752,7 +1752,10 @@ vk_graphics_pipeline_state_fill(const struct vk_device *device, vk_find_struct_const(info->pNext, PIPELINE_FRAGMENT_SHADING_RATE_STATE_CREATE_INFO_KHR); const VkRenderingInputAttachmentIndexInfoKHR *ial_info = - vk_find_struct_const(info->pNext, RENDERING_INPUT_ATTACHMENT_INDEX_INFO_KHR); + !driver_rp ? vk_get_pipeline_rendering_ial_info(info) + : vk_find_struct_const( + info->pNext, RENDERING_INPUT_ATTACHMENT_INDEX_INFO_KHR); + const VkRenderingAttachmentLocationInfoKHR *cal_info = vk_find_struct_const(info->pNext, RENDERING_ATTACHMENT_LOCATION_INFO_KHR); diff --git a/src/vulkan/runtime/vk_render_pass.c b/src/vulkan/runtime/vk_render_pass.c index 97733274e60..bccb8822a80 100644 --- a/src/vulkan/runtime/vk_render_pass.c +++ b/src/vulkan/runtime/vk_render_pass.c @@ -683,6 +683,9 @@ vk_common_CreateRenderPass2(VkDevice _device, next_subpass_color_samples += desc->colorAttachmentCount; } + subpass->ial.depth = VK_ATTACHMENT_UNUSED; + subpass->ial.stencil = VK_ATTACHMENT_UNUSED; + VkFormat depth_format = VK_FORMAT_UNDEFINED; VkFormat stencil_format = VK_FORMAT_UNDEFINED; VkSampleCountFlagBits depth_stencil_samples = VK_SAMPLE_COUNT_1_BIT; @@ -691,11 +694,22 @@ vk_common_CreateRenderPass2(VkDevice _device, if (ref->attachment < pCreateInfo->attachmentCount) { const VkAttachmentDescription2 *att = &pCreateInfo->pAttachments[ref->attachment]; + uint32_t ia_idx = VK_ATTACHMENT_UNUSED; - if (vk_format_has_depth(att->format)) + for (uint32_t j = 0; j < subpass->input_count; j++) { + if (subpass->input_attachments[j].attachment == ref->attachment) + ia_idx = j; + } + + if (vk_format_has_depth(att->format)) { depth_format = att->format; - if (vk_format_has_stencil(att->format)) + subpass->ial.depth = ia_idx; + } + + if (vk_format_has_stencil(att->format)) { stencil_format = att->format; + subpass->ial.stencil = ia_idx; + } depth_stencil_samples = att->samples; @@ -711,9 +725,47 @@ vk_common_CreateRenderPass2(VkDevice _device, .depthStencilAttachmentSamples = depth_stencil_samples, }; + subpass->ial.info = (VkRenderingInputAttachmentIndexInfo) { + .sType = VK_STRUCTURE_TYPE_RENDERING_INPUT_ATTACHMENT_INDEX_INFO, + .pNext = &subpass->sample_count_info_amd, + .colorAttachmentCount = subpass->color_count, + .pColorAttachmentInputIndices = subpass->ial.colors, + /* From the Vulkan 1.3.204 spec: + * + * VUID-vkCmdDraw-OpTypeImage-07468 + * + * "If any shader executed by this pipeline accesses an OpTypeImage + * variable with a Dim operand of SubpassData, it must be decorated + * with an InputAttachmentIndex that corresponds to a valid input + * attachment in the current subpass." + * + * So we don't have to worry about the missing InputAttachmentIndex + * decoration (AKA NO_INDEX) here, the depth/stencil attachment is + * either not used as an input attachment, or it has an explicit + * index. + */ + .pDepthInputAttachmentIndex = &subpass->ial.depth, + .pStencilInputAttachmentIndex = &subpass->ial.stencil, + }; + + /* Build the color -> input attachment map. */ + for (uint32_t i = 0; i < subpass->color_count; i++) { + subpass->ial.colors[i] = VK_ATTACHMENT_UNUSED; + + if (subpass->color_attachments[i].attachment == VK_ATTACHMENT_UNUSED) + continue; + + for (uint32_t j = 0; j < subpass->input_count; j++) { + if (subpass->input_attachments[j].attachment == + subpass->color_attachments[i].attachment) { + subpass->ial.colors[i] = j; + } + } + } + subpass->pipeline_info = (VkPipelineRenderingCreateInfo) { .sType = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO, - .pNext = &subpass->sample_count_info_amd, + .pNext = &subpass->ial.info, .viewMask = desc->viewMask, .colorAttachmentCount = desc->colorAttachmentCount, .pColorAttachmentFormats = color_formats, @@ -723,7 +775,7 @@ vk_common_CreateRenderPass2(VkDevice _device, subpass->inheritance_info = (VkCommandBufferInheritanceRenderingInfo) { .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_RENDERING_INFO, - .pNext = &subpass->sample_count_info_amd, + .pNext = &subpass->ial.info, /* If we're inheriting, the contents are clearly in secondaries */ .flags = VK_RENDERING_CONTENTS_SECONDARY_COMMAND_BUFFERS_BIT, .viewMask = desc->viewMask, @@ -846,6 +898,19 @@ vk_get_pipeline_rendering_create_info(const VkGraphicsPipelineCreateInfo *info) return vk_find_struct_const(info->pNext, PIPELINE_RENDERING_CREATE_INFO); } +const VkRenderingInputAttachmentIndexInfo * +vk_get_pipeline_rendering_ial_info(const VkGraphicsPipelineCreateInfo *info) +{ + VK_FROM_HANDLE(vk_render_pass, render_pass, info->renderPass); + if (render_pass != NULL) { + assert(info->subpass < render_pass->subpass_count); + return &render_pass->subpasses[info->subpass].ial.info; + } + + return vk_find_struct_const(info->pNext, + RENDERING_INPUT_ATTACHMENT_INDEX_INFO_KHR); +} + VkPipelineCreateFlags2KHR vk_get_pipeline_rendering_flags(const VkGraphicsPipelineCreateInfo *info) { @@ -2244,6 +2309,35 @@ begin_subpass(struct vk_command_buffer *cmd_buffer, disp->CmdBeginRendering(vk_command_buffer_to_handle(cmd_buffer), &rendering); + if (disp->CmdSetRenderingInputAttachmentIndices) { + /* From the Vulkan 1.4.312 spec: + * " + * Until this command is called, mappings in the command buffer state + * are treated as each color attachment specified in vkCmdBeginRendering + * mapping to subpass inputs with a InputAttachmentIndex equal to its + * index in VkRenderingInfo::pColorAttachments, and depth/stencil + * attachments mapping to input attachments without these decorations. + * This state is reset whenever vkCmdBeginRendering is called. + * " + * + * In practice, CmdBindPipeline() should apply exactly the same + * state to the vk_command_buffer dynamic state, and that's exactly + * what the Vulkan spec wants: + * + * " + * This command sets the input attachment index mappings for subsequent + * drawing commands, and must match the mappings provided to the bound + * pipeline, if one is bound, which can be set by chaining + * VkRenderingInputAttachmentIndexInfo to VkGraphicsPipelineCreateInfo. + * " + * + * So I'm not sure this CmdSetRenderingInputAttachmentIndices() is + * really needed, but let's keep it to play by the rules. + */ + disp->CmdSetRenderingInputAttachmentIndices(vk_command_buffer_to_handle(cmd_buffer), + &subpass->ial.info); + } + STACK_ARRAY_FINISH(color_attachments); STACK_ARRAY_FINISH(color_attachment_initial_layouts); } diff --git a/src/vulkan/runtime/vk_render_pass.h b/src/vulkan/runtime/vk_render_pass.h index 93a6b55f043..4cac6f33ae8 100644 --- a/src/vulkan/runtime/vk_render_pass.h +++ b/src/vulkan/runtime/vk_render_pass.h @@ -23,6 +23,7 @@ #ifndef VK_RENDER_PASS_H #define VK_RENDER_PASS_H +#include "vk_limits.h" #include "vk_object.h" #ifdef __cplusplus @@ -171,6 +172,20 @@ struct vk_subpass { */ VkAttachmentSampleCountInfoAMD sample_count_info_amd; + /** VkRenderingInputAttachmentIndexInfo for this subpass + * + * This is in the pNext chain of pipeline_info and inheritance_info. + * + * Also returned by vk_get_pipeline_rendering_ial_info() if + * VkGraphicsPipelineCreateInfo::renderPass != VK_NULL_HANDLE. + */ + struct { + VkRenderingInputAttachmentIndexInfo info; + uint32_t colors[MESA_VK_MAX_COLOR_ATTACHMENTS]; + uint32_t depth; + uint32_t stencil; + } ial; + /** VkPipelineRenderingCreateInfo for this subpass * * Returned by vk_get_pipeline_rendering_create_info() if @@ -324,6 +339,22 @@ VK_DEFINE_NONDISP_HANDLE_CASTS(vk_render_pass, base, VkRenderPass, const VkPipelineRenderingCreateInfo * vk_get_pipeline_rendering_create_info(const VkGraphicsPipelineCreateInfo *info); +/** Returns the VkRenderingInputAttachmentIndexInfo for a graphics pipeline + * + * For render-pass-free drivers, this can be used in the implementation of + * vkCreateGraphicsPipelines to get the VkRenderingInputAttachmentIndexInfo. + * If VkGraphicsPipelineCreateInfo::renderPass is not VK_NULL_HANDLE, it will + * return a representation of the specified subpass as a + * VkRenderingInputAttachmentIndexInfo. If + * VkGraphicsPipelineCreateInfo::renderPass + * is VK_NULL_HANDLE and there is a VkRenderingInputAttachmentIndexInfo in the + * pNext chain of VkGraphicsPipelineCreateInfo, it will return that. + * + * :param info: |in| One of the pCreateInfos from vkCreateGraphicsPipelines + */ +const VkRenderingInputAttachmentIndexInfo * +vk_get_pipeline_rendering_ial_info(const VkGraphicsPipelineCreateInfo *info); + /** Returns any extra VkPipelineCreateFlags from the render pass * * For render-pass-free drivers, this can be used to get any extra pipeline