xref: /aosp_15_r20/external/mesa3d/src/vulkan/runtime/vk_render_pass.h (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1 /*
2  * Copyright © 2021 Intel Corporation
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21  * IN THE SOFTWARE.
22  */
23 #ifndef VK_RENDER_PASS_H
24 #define VK_RENDER_PASS_H
25 
26 #include "vk_object.h"
27 
28 #ifdef __cplusplus
29 extern "C" {
30 #endif
31 
32 struct vk_command_buffer;
33 struct vk_image;
34 
35 /* Mesa-specific dynamic rendering flag to indicate that legacy RPs don't use
36  * input attachments with concurrent writes (aka. feedback loops).
37  */
38 #define VK_RENDERING_INPUT_ATTACHMENT_NO_CONCURRENT_WRITES_BIT_MESA 0x80000000
39 
40 /**
41  * Pseudo-extension struct that may be chained into VkRenderingAttachmentInfo
42  * to indicate an initial layout for the attachment.  This is only allowed if
43  * all of the following conditions are met:
44  *
45  *    1. VkRenderingAttachmentInfo::loadOp == LOAD_OP_CLEAR
46  *
47  *    2. VkRenderingInfo::renderArea is the entire image view LOD
48  *
49  *    3. For 3D image attachments, VkRenderingInfo::viewMask == 0 AND
50  *       VkRenderingInfo::layerCount references the entire bound image view
51  *       OR VkRenderingInfo::viewMask is dense (no holes) and references the
52  *       entire bound image view.  (2D and 2D array images have no such
53  *       requirement.)
54  *
55  * If this struct is included in the pNext chain of a
56  * VkRenderingAttachmentInfo, the driver is responsible for transitioning the
57  * bound region of the image from
58  * VkRenderingAttachmentInitialLayoutInfoMESA::initialLayout to
59  * VkRenderingAttachmentInfo::imageLayout prior to rendering.
60  */
61 typedef struct VkRenderingAttachmentInitialLayoutInfoMESA {
62     VkStructureType    sType;
63 #define VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INITIAL_LAYOUT_INFO_MESA (VkStructureType)1000044901
64 #define VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INITIAL_LAYOUT_INFO_MESA_cast VkRenderingAttachmentInitialLayoutInfoMESA
65     const void*        pNext;
66 
67     /** Initial layout of the attachment */
68     VkImageLayout      initialLayout;
69 } VkRenderingAttachmentInitialLayoutInfoMESA;
70 
71 /***/
72 struct vk_subpass_attachment {
73    /** VkAttachmentReference2::attachment */
74    uint32_t attachment;
75 
76    /** Aspects referenced by this attachment
77     *
78     * For an input attachment, this is VkAttachmentReference2::aspectMask.
79     * For all others, it's equal to the vk_render_pass_attachment::aspects.
80     */
81    VkImageAspectFlags aspects;
82 
83    /** Usage for this attachment
84     *
85     * This is a single VK_IMAGE_USAGE_* describing the usage of this subpass
86     * attachment.  Resolve attachments are VK_IMAGE_USAGE_TRANSFER_DST_BIT.
87     */
88    VkImageUsageFlagBits usage;
89 
90    /** VkAttachmentReference2::layout */
91    VkImageLayout layout;
92 
93    /** VkAttachmentReferenceStencilLayout::stencilLayout
94     *
95     * If VK_KHR_separate_depth_stencil_layouts is not used, this will be
96     * layout if the attachment contains stencil and VK_IMAGE_LAYOUT_UNDEFINED
97     * otherwise.
98     */
99    VkImageLayout stencil_layout;
100 
101    /** A per-view mask for if this is the last use of this attachment
102     *
103     * If the same render pass attachment is used multiple ways within a
104     * subpass, corresponding last_subpass bits will be set in all of them.
105     * For the non-multiview case, only the first bit is used.
106     */
107    uint32_t last_subpass;
108 
109    /** Resolve attachment, if any */
110    struct vk_subpass_attachment *resolve;
111 };
112 
113 /***/
114 struct vk_subpass {
115    /** Count of all attachments referenced by this subpass */
116    uint32_t attachment_count;
117 
118    /** Array of all attachments referenced by this subpass */
119    struct vk_subpass_attachment *attachments;
120 
121    /** VkSubpassDescription2::inputAttachmentCount */
122    uint32_t input_count;
123 
124    /** VkSubpassDescription2::pInputAttachments */
125    struct vk_subpass_attachment *input_attachments;
126 
127    /** VkSubpassDescription2::colorAttachmentCount */
128    uint32_t color_count;
129 
130    /** VkSubpassDescription2::pColorAttachments */
131    struct vk_subpass_attachment *color_attachments;
132 
133    /** VkSubpassDescription2::colorAttachmentCount or zero */
134    uint32_t color_resolve_count;
135 
136    /** VkSubpassDescription2::pResolveAttachments */
137    struct vk_subpass_attachment *color_resolve_attachments;
138 
139    /** VkSubpassDescription2::pDepthStencilAttachment */
140    struct vk_subpass_attachment *depth_stencil_attachment;
141 
142    /** VkSubpassDescriptionDepthStencilResolve::pDepthStencilResolveAttachment */
143    struct vk_subpass_attachment *depth_stencil_resolve_attachment;
144 
145    /** VkFragmentShadingRateAttachmentInfoKHR::pFragmentShadingRateAttachment */
146    struct vk_subpass_attachment *fragment_shading_rate_attachment;
147 
148    /** VkSubpassDescription2::viewMask or 1 for non-multiview
149     *
150     * For all view masks in the vk_render_pass data structure, we use a mask
151     * of 1 for non-multiview instead of a mask of 0.  To determine if the
152     * render pass is multiview or not, see vk_render_pass::is_multiview.
153     */
154    uint32_t view_mask;
155 
156    /** VkSubpassDescriptionDepthStencilResolve::depthResolveMode */
157    VkResolveModeFlagBits depth_resolve_mode;
158 
159    /** VkSubpassDescriptionDepthStencilResolve::stencilResolveMode */
160    VkResolveModeFlagBits stencil_resolve_mode;
161 
162    /** VkFragmentShadingRateAttachmentInfoKHR::shadingRateAttachmentTexelSize */
163    VkExtent2D fragment_shading_rate_attachment_texel_size;
164 
165    /** Extra VkPipelineCreateFlags for this subpass */
166    VkPipelineCreateFlagBits2KHR pipeline_flags;
167 
168    /** VkAttachmentSampleCountInfoAMD for this subpass
169     *
170     * This is in the pNext chain of pipeline_info and inheritance_info.
171     */
172    VkAttachmentSampleCountInfoAMD sample_count_info_amd;
173 
174    /** VkPipelineRenderingCreateInfo for this subpass
175     *
176     * Returned by vk_get_pipeline_rendering_create_info() if
177     * VkGraphicsPipelineCreateInfo::renderPass != VK_NULL_HANDLE.
178     */
179    VkPipelineRenderingCreateInfo pipeline_info;
180 
181    /** VkCommandBufferInheritanceRenderingInfo for this subpass
182     *
183     * Returned by vk_get_command_buffer_inheritance_rendering_info() if
184     * VkCommandBufferInheritanceInfo::renderPass != VK_NULL_HANDLE.
185     */
186    VkCommandBufferInheritanceRenderingInfo inheritance_info;
187 
188    /** VkMultisampledRenderToSingleSampledInfoEXT for this subpass */
189    VkMultisampledRenderToSingleSampledInfoEXT mrtss;
190 
191    /** True if legacy dithering is enabled for this subpass. */
192    bool legacy_dithering_enabled;
193 };
194 
195 /***/
196 struct vk_render_pass_attachment {
197    /** VkAttachmentDescription2::format */
198    VkFormat format;
199 
200    /** Aspects contained in format */
201    VkImageAspectFlags aspects;
202 
203    /** VkAttachmentDescription2::samples */
204    uint32_t samples;
205 
206    /** Views in which this attachment is used, 0 for unused
207     *
208     * For non-multiview, this will be 1 if the attachment is used.
209     */
210    uint32_t view_mask;
211 
212    /** VkAttachmentDescription2::loadOp */
213    VkAttachmentLoadOp load_op;
214 
215    /** VkAttachmentDescription2::storeOp */
216    VkAttachmentStoreOp store_op;
217 
218    /** VkAttachmentDescription2::stencilLoadOp */
219    VkAttachmentLoadOp stencil_load_op;
220 
221    /** VkAttachmentDescription2::stencilStoreOp */
222    VkAttachmentStoreOp stencil_store_op;
223 
224    /** VkAttachmentDescription2::initialLayout */
225    VkImageLayout initial_layout;
226 
227    /** VkAttachmentDescription2::finalLayout */
228    VkImageLayout final_layout;
229 
230    /** VkAttachmentDescriptionStencilLayout::stencilInitialLayout
231     *
232     * If VK_KHR_separate_depth_stencil_layouts is not used, this will be
233     * initial_layout if format contains stencil and VK_IMAGE_LAYOUT_UNDEFINED
234     * otherwise.
235     */
236    VkImageLayout initial_stencil_layout;
237 
238    /** VkAttachmentDescriptionStencilLayout::stencilFinalLayout
239     *
240     * If VK_KHR_separate_depth_stencil_layouts is not used, this will be
241     * final_layout if format contains stencil and VK_IMAGE_LAYOUT_UNDEFINED
242     * otherwise.
243     */
244    VkImageLayout final_stencil_layout;
245 };
246 
247 /***/
248 struct vk_subpass_dependency {
249    /** VkSubpassDependency2::dependencyFlags */
250    VkDependencyFlags flags;
251 
252    /** VkSubpassDependency2::srcSubpass */
253    uint32_t src_subpass;
254 
255    /** VkSubpassDependency2::dstSubpass */
256    uint32_t dst_subpass;
257 
258    /** VkSubpassDependency2::srcStageMask */
259    VkPipelineStageFlags2 src_stage_mask;
260 
261    /** VkSubpassDependency2::dstStageMask */
262    VkPipelineStageFlags2 dst_stage_mask;
263 
264    /** VkSubpassDependency2::srcAccessMask */
265    VkAccessFlags2 src_access_mask;
266 
267    /** VkSubpassDependency2::dstAccessMask */
268    VkAccessFlags2 dst_access_mask;
269 
270    /** VkSubpassDependency2::viewOffset */
271    int32_t view_offset;
272 };
273 
274 /***/
275 struct vk_render_pass {
276    struct vk_object_base base;
277 
278    /** True if this render pass uses multiview
279     *
280     * This is true if all subpasses have viewMask != 0.
281     */
282    bool is_multiview;
283 
284    /** Views used by this render pass or 1 for non-multiview */
285    uint32_t view_mask;
286 
287    /** VkRenderPassCreateInfo2::attachmentCount */
288    uint32_t attachment_count;
289 
290    /** VkRenderPassCreateInfo2::pAttachments */
291    struct vk_render_pass_attachment *attachments;
292 
293    /** VkRenderPassCreateInfo2::subpassCount */
294    uint32_t subpass_count;
295 
296    /** VkRenderPassCreateInfo2::subpasses */
297    struct vk_subpass *subpasses;
298 
299    /** VkRenderPassCreateInfo2::dependencyCount */
300    uint32_t dependency_count;
301 
302    /** VkRenderPassFragmentDensityMapCreateInfoEXT::fragmentDensityMapAttachment */
303    VkAttachmentReference fragment_density_map;
304 
305    /** VkRenderPassCreateInfo2::pDependencies */
306    struct vk_subpass_dependency *dependencies;
307 };
308 
309 VK_DEFINE_NONDISP_HANDLE_CASTS(vk_render_pass, base, VkRenderPass,
310                                VK_OBJECT_TYPE_RENDER_PASS);
311 
312 /** Returns the VkPipelineRenderingCreateInfo for a graphics pipeline
313  *
314  * For render-pass-free drivers, this can be used in the implementation of
315  * vkCreateGraphicsPipelines to get the VkPipelineRenderingCreateInfo.  If
316  * VkGraphicsPipelineCreateInfo::renderPass is not VK_NULL_HANDLE, it will
317  * return a representation of the specified subpass as a
318  * VkPipelineRenderingCreateInfo.  If VkGraphicsPipelineCreateInfo::renderPass
319  * is VK_NULL_HANDLE and there is a VkPipelineRenderingCreateInfo in the pNext
320  * chain of VkGraphicsPipelineCreateInfo, it will return that.
321  *
322  * :param info: |in|  One of the pCreateInfos from vkCreateGraphicsPipelines
323  */
324 const VkPipelineRenderingCreateInfo *
325 vk_get_pipeline_rendering_create_info(const VkGraphicsPipelineCreateInfo *info);
326 
327 /** Returns any extra VkPipelineCreateFlags from the render pass
328  *
329  * For render-pass-free drivers, this can be used to get any extra pipeline
330  * create flags implied by the render pass.  In particular, a render pass may
331  * want to add one or both of the following:
332  *
333  *  - VK_PIPELINE_CREATE_COLOR_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT
334  *  - VK_PIPELINE_CREATE_DEPTH_STENCIL_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT
335  *  - VK_PIPELINE_CREATE_RENDERING_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR
336  *  - VK_PIPELINE_CREATE_RENDERING_FRAGMENT_DENSITY_MAP_ATTACHMENT_BIT_EXT
337  *
338  * If VkGraphicsPipelineCreateInfo::renderPass is VK_NULL_HANDLE, the relevant
339  * flags from VkGraphicsPipelineCreateInfo::flags will be returned.
340  *
341  * :param info: |in|  One of the pCreateInfos from vkCreateGraphicsPipelines
342  */
343 VkPipelineCreateFlags2KHR
344 vk_get_pipeline_rendering_flags(const VkGraphicsPipelineCreateInfo *info);
345 
346 /** Returns the VkAttachmentSampleCountInfoAMD for a graphics pipeline
347  *
348  * For render-pass-free drivers, this can be used in the implementation of
349  * vkCreateGraphicsPipelines to get the VkAttachmentSampleCountInfoAMD.  If
350  * VkGraphicsPipelineCreateInfo::renderPass is not VK_NULL_HANDLE, it will
351  * return the sample counts from the specified subpass as a
352  * VkAttachmentSampleCountInfoAMD.  If VkGraphicsPipelineCreateInfo::renderPass
353  * is VK_NULL_HANDLE and there is a VkAttachmentSampleCountInfoAMD in the pNext
354  * chain of VkGraphicsPipelineCreateInfo, it will return that.
355  *
356  * :param info: |in|  One of the pCreateInfos from vkCreateGraphicsPipelines
357  */
358 const VkAttachmentSampleCountInfoAMD *
359 vk_get_pipeline_sample_count_info_amd(const VkGraphicsPipelineCreateInfo *info);
360 
361 /**
362  * Returns the VkCommandBufferInheritanceRenderingInfo for secondary command
363  * buffer execution
364  *
365  * For render-pass-free drivers, this can be used in the implementation of
366  * vkCmdExecuteCommands to get the VkCommandBufferInheritanceRenderingInfo.
367  * If VkCommandBufferInheritanceInfo::renderPass is not VK_NULL_HANDLE, it
368  * will return a representation of the specified subpass as a
369  * VkCommandBufferInheritanceRenderingInfo.  If
370  * VkCommandBufferInheritanceInfo::renderPass is not VK_NULL_HANDLE and there
371  * is a VkCommandBufferInheritanceRenderingInfo in the pNext chain of
372  * VkCommandBufferBeginInfo, it will return that.
373  *
374  * :param level:        |in|  The nesting level of this command buffer
375  * :param pBeginInfo:   |in|  The pBeginInfo from vkBeginCommandBuffer
376  */
377 const VkCommandBufferInheritanceRenderingInfo *
378 vk_get_command_buffer_inheritance_rendering_info(
379    VkCommandBufferLevel level,
380    const VkCommandBufferBeginInfo *pBeginInfo);
381 
382 struct vk_gcbiarr_data {
383    VkRenderingInfo rendering;
384    VkRenderingFragmentShadingRateAttachmentInfoKHR fsr_att;
385    VkRenderingAttachmentInfo attachments[];
386 };
387 
388 #define VK_GCBIARR_DATA_SIZE(max_color_rts) (\
389    sizeof(struct vk_gcbiarr_data) + \
390    sizeof(VkRenderingAttachmentInfo) * ((max_color_rts) + 2) \
391 )
392 
393 /**
394  * Constructs a VkRenderingInfo for the inheritance rendering info
395  *
396  * For render-pass-free drivers, this can be used in the implementation of
397  * vkCmdExecuteCommands to get a VkRenderingInfo representing the subpass and
398  * framebuffer provided via the inheritance info for a command buffer created
399  * with VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT.  The mental model
400  * here is that VkExecuteCommands() implicitly suspends the render pass and
401  * VkBeginCommandBuffer() resumes it.  If a VkRenderingInfo cannot be
402  * constructed due to a missing framebuffer or similar, NULL will be
403  * returned.
404  *
405  * :param level:        |in|  The nesting level of this command buffer
406  * :param pBeginInfo:   |in|  The pBeginInfo from vkBeginCommandBuffer
407  * :param stack_data:   |out| An opaque blob of data which will be overwritten by
408  *                            this function, passed in from the caller to avoid
409  *                            heap allocations.  It must be at least
410  *                            VK_GCBIARR_DATA_SIZE(max_color_rts) bytes.
411  */
412 const VkRenderingInfo *
413 vk_get_command_buffer_inheritance_as_rendering_resume(
414    VkCommandBufferLevel level,
415    const VkCommandBufferBeginInfo *pBeginInfo,
416    void *stack_data);
417 
418 const VkRenderingAttachmentLocationInfoKHR *
419 vk_get_command_buffer_rendering_attachment_location_info(
420    VkCommandBufferLevel level,
421    const VkCommandBufferBeginInfo *pBeginInfo);
422 /**
423  * Return true if the subpass dependency is framebuffer-local.
424  */
425 static bool
vk_subpass_dependency_is_fb_local(const VkSubpassDependency2 * dep,VkPipelineStageFlags2 src_stage_mask,VkPipelineStageFlags2 dst_stage_mask)426 vk_subpass_dependency_is_fb_local(const VkSubpassDependency2 *dep,
427                                   VkPipelineStageFlags2 src_stage_mask,
428                                   VkPipelineStageFlags2 dst_stage_mask)
429 {
430    if (dep->srcSubpass == VK_SUBPASS_EXTERNAL ||
431        dep->dstSubpass == VK_SUBPASS_EXTERNAL)
432       return true;
433 
434   /* This is straight from the Vulkan 1.2 spec, section 7.1.4 "Framebuffer
435    * Region Dependencies":
436    */
437    const VkPipelineStageFlags2 framebuffer_space_stages =
438       VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT |
439       VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT |
440       VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT |
441       VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT;
442 
443    const VkPipelineStageFlags2 src_framebuffer_space_stages =
444       framebuffer_space_stages | VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT;
445    const VkPipelineStageFlags2 dst_framebuffer_space_stages =
446       framebuffer_space_stages | VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT;
447 
448    /* Check for frambuffer-space dependency. */
449    if ((src_stage_mask & ~src_framebuffer_space_stages) ||
450        (dst_stage_mask & ~dst_framebuffer_space_stages))
451       return false;
452 
453    /* Check for framebuffer-local dependency. */
454    return dep->dependencyFlags & VK_DEPENDENCY_BY_REGION_BIT;
455 }
456 
457 uint32_t
458 vk_command_buffer_get_attachment_layout(const struct vk_command_buffer *cmd_buffer,
459                                         const struct vk_image *image,
460                                         VkImageLayout *out_layout,
461                                         VkImageLayout *out_stencil_layout);
462 
463 void
464 vk_command_buffer_set_attachment_layout(struct vk_command_buffer *cmd_buffer,
465                                         uint32_t att_idx,
466                                         VkImageLayout layout,
467                                         VkImageLayout stencil_layout);
468 
469 #ifdef __cplusplus
470 }
471 #endif
472 
473 #endif /* VK_RENDER_PASS_H */
474