vk/pass: Add input attachment location info
For drivers using the render pass emulation provided by the runtime, it's important to express the mapping between depth/stencil/color attachments and input attachments using VkRenderingInputAttachmentIndexInfoKHR, otherwise those drivers have to special-case emulated render passes in their CmdBeginRendering() implementation. Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com> Reviewed-by: Lars-Ivar Hesselberg Simonsen <lars-ivar.simonsen@arm.com> Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/32540>
This commit is contained in:
committed by
Marge Bot
parent
38e546c202
commit
be2532fc00
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user