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 /**
33  * Pseudo-extension struct that may be chained into VkRenderingAttachmentInfo
34  * to indicate an initial layout for the attachment.  This is only allowed if
35  * all of the following conditions are met:
36  *
37  *    1. VkRenderingAttachmentInfo::loadOp == LOAD_OP_CLEAR
38  *
39  *    2. VkRenderingInfo::renderArea is tne entire image view LOD
40  *
41  *    3. For 3D image attachments, VkRenderingInfo::viewMask == 0 AND
42  *       VkRenderingInfo::layerCount references the entire bound image view
43  *       OR VkRenderingInfo::viewMask is dense (no holes) and references the
44  *       entire bound image view.  (2D and 2D array images have no such
45  *       requirement.)
46  *
47  * If this struct is included in the pNext chain of a
48  * VkRenderingAttachmentInfo, the driver is responsible for transitioning the
49  * bound region of the image from
50  * VkRenderingAttachmentInitialLayoutInfoMESA::initialLayout to
51  * VkRenderingAttachmentInfo::imageLayout prior to rendering.
52  */
53 typedef struct VkRenderingAttachmentInitialLayoutInfoMESA {
54     VkStructureType    sType;
55 #define VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INITIAL_LAYOUT_INFO_MESA (VkStructureType)1000044901
56 #define VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INITIAL_LAYOUT_INFO_MESA_cast VkRenderingAttachmentInitialLayoutInfoMESA
57     const void*        pNext;
58 
59     /** Initial layout of the attachment */
60     VkImageLayout      initialLayout;
61 } VkRenderingAttachmentInitialLayoutInfoMESA;
62 
63 struct vk_subpass_attachment {
64    /** VkAttachmentReference2::attachment */
65    uint32_t attachment;
66 
67    /** Aspects referenced by this attachment
68     *
69     * For an input attachment, this is VkAttachmentReference2::aspectMask.
70     * For all others, it's equal to the vk_render_pass_attachment::aspects.
71     */
72    VkImageAspectFlags aspects;
73 
74    /** Usage for this attachment
75     *
76     * This is a single VK_IMAGE_USAGE_* describing the usage of this subpass
77     * attachment.  Resolve attachments are VK_IMAGE_USAGE_TRANSFER_DST_BIT.
78     */
79    VkImageUsageFlagBits usage;
80 
81    /** VkAttachmentReference2::layout */
82    VkImageLayout layout;
83 
84    /** VkAttachmentReferenceStencilLayout::stencilLayout
85     *
86     * If VK_KHR_separate_depth_stencil_layouts is not used, this will be
87     * layout if the attachment contains stencil and VK_IMAGE_LAYOUT_UNDEFINED
88     * otherwise.
89     */
90    VkImageLayout stencil_layout;
91 
92    /** A per-view mask for if this is the last use of this attachment
93     *
94     * If the same render pass attachment is used multiple ways within a
95     * subpass, corresponding last_subpass bits will be set in all of them.
96     * For the non-multiview case, only the first bit is used.
97     */
98    uint32_t last_subpass;
99 
100    /** Resolve attachment, if any */
101    struct vk_subpass_attachment *resolve;
102 };
103 
104 struct vk_subpass {
105    /** Count of all attachments referenced by this subpass */
106    uint32_t attachment_count;
107 
108    /** Array of all attachments referenced by this subpass */
109    struct vk_subpass_attachment *attachments;
110 
111    /** VkSubpassDescription2::inputAttachmentCount */
112    uint32_t input_count;
113 
114    /** VkSubpassDescription2::pInputAttachments */
115    struct vk_subpass_attachment *input_attachments;
116 
117    /** VkSubpassDescription2::colorAttachmentCount */
118    uint32_t color_count;
119 
120    /** VkSubpassDescription2::pColorAttachments */
121    struct vk_subpass_attachment *color_attachments;
122 
123    /** VkSubpassDescription2::colorAttachmentCount or zero */
124    uint32_t color_resolve_count;
125 
126    /** VkSubpassDescription2::pResolveAttachments */
127    struct vk_subpass_attachment *color_resolve_attachments;
128 
129    /** VkSubpassDescription2::pDepthStencilAttachment */
130    struct vk_subpass_attachment *depth_stencil_attachment;
131 
132    /** VkSubpassDescriptionDepthStencilResolve::pDepthStencilResolveAttachment */
133    struct vk_subpass_attachment *depth_stencil_resolve_attachment;
134 
135    /** VkFragmentShadingRateAttachmentInfoKHR::pFragmentShadingRateAttachment */
136    struct vk_subpass_attachment *fragment_shading_rate_attachment;
137 
138    /** VkSubpassDescription2::viewMask or 1 for non-multiview
139     *
140     * For all view masks in the vk_render_pass data structure, we use a mask
141     * of 1 for non-multiview instead of a mask of 0.  To determine if the
142     * render pass is multiview or not, see vk_render_pass::is_multiview.
143     */
144    uint32_t view_mask;
145 
146    /** VkSubpassDescriptionDepthStencilResolve::depthResolveMode */
147    VkResolveModeFlagBits depth_resolve_mode;
148 
149    /** VkSubpassDescriptionDepthStencilResolve::stencilResolveMode */
150    VkResolveModeFlagBits stencil_resolve_mode;
151 
152    /** VkFragmentShadingRateAttachmentInfoKHR::shadingRateAttachmentTexelSize */
153    VkExtent2D fragment_shading_rate_attachment_texel_size;
154 
155    /** Extra VkPipelineCreateFlags for this subpass */
156    VkPipelineCreateFlagBits pipeline_flags;
157 
158    /** VkAttachmentSampleCountInfoAMD for this subpass
159     *
160     * This is in the pNext chain of pipeline_info and inheritance_info.
161     */
162    VkAttachmentSampleCountInfoAMD sample_count_info_amd;
163 
164    /** VkPipelineRenderingCreateInfo for this subpass
165     *
166     * Returned by vk_get_pipeline_rendering_create_info() if
167     * VkGraphicsPipelineCreateInfo::renderPass != VK_NULL_HANDLE.
168     */
169    VkPipelineRenderingCreateInfo pipeline_info;
170 
171    /** VkCommandBufferInheritanceRenderingInfo for this subpass
172     *
173     * Returned by vk_get_command_buffer_inheritance_rendering_info() if
174     * VkCommandBufferInheritanceInfo::renderPass != VK_NULL_HANDLE.
175     */
176    VkCommandBufferInheritanceRenderingInfo inheritance_info;
177 
178    /** VkMultisampledRenderToSingleSampledInfoEXT for this subpass */
179    VkMultisampledRenderToSingleSampledInfoEXT mrtss;
180 };
181 
182 struct vk_render_pass_attachment {
183    /** VkAttachmentDescription2::format */
184    VkFormat format;
185 
186    /** Aspects contained in format */
187    VkImageAspectFlags aspects;
188 
189    /** VkAttachmentDescription2::samples */
190    uint32_t samples;
191 
192    /** Views in which this attachment is used, 0 for unused
193     *
194     * For non-multiview, this will be 1 if the attachment is used.
195     */
196    uint32_t view_mask;
197 
198    /** VkAttachmentDescription2::loadOp */
199    VkAttachmentLoadOp load_op;
200 
201    /** VkAttachmentDescription2::storeOp */
202    VkAttachmentStoreOp store_op;
203 
204    /** VkAttachmentDescription2::stencilLoadOp */
205    VkAttachmentLoadOp stencil_load_op;
206 
207    /** VkAttachmentDescription2::stencilStoreOp */
208    VkAttachmentStoreOp stencil_store_op;
209 
210    /** VkAttachmentDescription2::initialLayout */
211    VkImageLayout initial_layout;
212 
213    /** VkAttachmentDescription2::finalLayout */
214    VkImageLayout final_layout;
215 
216    /** VkAttachmentDescriptionStencilLayout::stencilInitialLayout
217     *
218     * If VK_KHR_separate_depth_stencil_layouts is not used, this will be
219     * initial_layout if format contains stencil and VK_IMAGE_LAYOUT_UNDEFINED
220     * otherwise.
221     */
222    VkImageLayout initial_stencil_layout;
223 
224    /** VkAttachmentDescriptionStencilLayout::stencilFinalLayout
225     *
226     * If VK_KHR_separate_depth_stencil_layouts is not used, this will be
227     * final_layout if format contains stencil and VK_IMAGE_LAYOUT_UNDEFINED
228     * otherwise.
229     */
230    VkImageLayout final_stencil_layout;
231 };
232 
233 struct vk_subpass_dependency {
234    /** VkSubpassDependency2::dependencyFlags */
235    VkDependencyFlags flags;
236 
237    /** VkSubpassDependency2::srcSubpass */
238    uint32_t src_subpass;
239 
240    /** VkSubpassDependency2::dstSubpass */
241    uint32_t dst_subpass;
242 
243    /** VkSubpassDependency2::srcStageMask */
244    VkPipelineStageFlags2 src_stage_mask;
245 
246    /** VkSubpassDependency2::dstStageMask */
247    VkPipelineStageFlags2 dst_stage_mask;
248 
249    /** VkSubpassDependency2::srcAccessMask */
250    VkAccessFlags2 src_access_mask;
251 
252    /** VkSubpassDependency2::dstAccessMask */
253    VkAccessFlags2 dst_access_mask;
254 
255    /** VkSubpassDependency2::viewOffset */
256    int32_t view_offset;
257 };
258 
259 struct vk_render_pass {
260    struct vk_object_base base;
261 
262    /** True if this render pass uses multiview
263     *
264     * This is true if all subpasses have viewMask != 0.
265     */
266    bool is_multiview;
267 
268    /** Views used by this render pass or 1 for non-multiview */
269    uint32_t view_mask;
270 
271    /** VkRenderPassCreateInfo2::attachmentCount */
272    uint32_t attachment_count;
273 
274    /** VkRenderPassCreateInfo2::pAttachments */
275    struct vk_render_pass_attachment *attachments;
276 
277    /** VkRenderPassCreateInfo2::subpassCount */
278    uint32_t subpass_count;
279 
280    /** VkRenderPassCreateInfo2::subpasses */
281    struct vk_subpass *subpasses;
282 
283    /** VkRenderPassCreateInfo2::dependencyCount */
284    uint32_t dependency_count;
285 
286    /** VkRenderPassFragmentDensityMapCreateInfoEXT::fragmentDensityMapAttachment */
287    VkAttachmentReference fragment_density_map;
288 
289    /** VkRenderPassCreateInfo2::pDependencies */
290    struct vk_subpass_dependency *dependencies;
291 };
292 
293 VK_DEFINE_NONDISP_HANDLE_CASTS(vk_render_pass, base, VkRenderPass,
294                                VK_OBJECT_TYPE_RENDER_PASS);
295 
296 /** Returns the VkPipelineRenderingCreateInfo for a graphics pipeline
297  *
298  * For render-pass-free drivers, this can be used in the implementation of
299  * vkCreateGraphicsPipelines to get the VkPipelineRenderingCreateInfo.  If
300  * VkGraphicsPipelineCreateInfo::renderPass is not VK_NULL_HANDLE, it will
301  * return a representation of the specified subpass as a
302  * VkPipelineRenderingCreateInfo.  If VkGraphicsPipelineCreateInfo::renderPass
303  * is VK_NULL_HANDLE and there is a VkPipelineRenderingCreateInfo in the pNext
304  * chain of VkGraphicsPipelineCreateInfo, it will return that.
305  *
306  * @param[in]  info  One of the pCreateInfos from vkCreateGraphicsPipelines
307  */
308 const VkPipelineRenderingCreateInfo *
309 vk_get_pipeline_rendering_create_info(const VkGraphicsPipelineCreateInfo *info);
310 
311 /** Returns any extra VkPipelineCreateFlags from the render pass
312  *
313  * For render-pass-free drivers, this can be used to get any extra pipeline
314  * create flags implied by the render pass.  In particular, a render pass may
315  * want to add one or both of the following:
316  *
317  *  - VK_PIPELINE_CREATE_COLOR_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT
318  *  - VK_PIPELINE_CREATE_DEPTH_STENCIL_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT
319  *  - VK_PIPELINE_CREATE_RENDERING_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR
320  *  - VK_PIPELINE_CREATE_RENDERING_FRAGMENT_DENSITY_MAP_ATTACHMENT_BIT_EXT
321  *
322  * If VkGraphicsPipelineCreateInfo::renderPass is VK_NULL_HANDLE, the relevant
323  * flags from VkGraphicsPipelineCreateInfo::flags will be returned.
324  *
325  * @param[in]  info  One of the pCreateInfos from vkCreateGraphicsPipelines
326  */
327 VkPipelineCreateFlags
328 vk_get_pipeline_rendering_flags(const VkGraphicsPipelineCreateInfo *info);
329 
330 /** Returns the VkAttachmentSampleCountInfoAMD for a graphics pipeline
331  *
332  * For render-pass-free drivers, this can be used in the implementaiton of
333  * vkCreateGraphicsPipelines to get the VkAttachmentSampleCountInfoAMD.  If
334  * VkGraphicsPipelineCreateInfo::renderPass is not VK_NULL_HANDLE, it will
335  * return the sample counts from the specified subpass as a
336  * VkAttachmentSampleCountInfoAMD.  If VkGraphicsPipelineCreateInfo::renderPass
337  * is VK_NULL_HANDLE and there is a VkAttachmentSampleCountInfoAMD in the pNext
338  * chain of VkGraphicsPipelineCreateInfo, it will return that.
339  *
340  * @param[in]  info  One of the pCreateInfos from vkCreateGraphicsPipelines
341  */
342 const VkAttachmentSampleCountInfoAMD *
343 vk_get_pipeline_sample_count_info_amd(const VkGraphicsPipelineCreateInfo *info);
344 
345 /**
346  * Returns the VkCommandBufferInheritanceRenderingInfo for secondary command
347  * buffer execution
348  *
349  * For render-pass-free drivers, this can be used in the implementation of
350  * vkCmdExecuteCommands to get the VkCommandBufferInheritanceRenderingInfo.
351  * If VkCommandBufferInheritanceInfo::renderPass is not VK_NULL_HANDLE, it
352  * will return a representation of the specified subpass as a
353  * VkCommandBufferInheritanceRenderingInfo.  If
354  * VkCommandBufferInheritanceInfo::renderPass is not VK_NULL_HANDLE and there
355  * is a VkCommandBufferInheritanceRenderingInfo in the pNext chain of
356  * VkCommandBufferBeginInfo, it will return that.
357  *
358  * @param[in]  level       The nesting level of this command buffer
359  * @param[in]  pBeginInfo  The pBeginInfo from vkBeginCommandBuffer
360  */
361 const VkCommandBufferInheritanceRenderingInfo *
362 vk_get_command_buffer_inheritance_rendering_info(
363    VkCommandBufferLevel level,
364    const VkCommandBufferBeginInfo *pBeginInfo);
365 
366 struct vk_gcbiarr_data {
367    VkRenderingInfo rendering;
368    VkRenderingFragmentShadingRateAttachmentInfoKHR fsr_att;
369    VkRenderingAttachmentInfo attachments[];
370 };
371 
372 #define VK_GCBIARR_DATA_SIZE(max_color_rts) (\
373    sizeof(struct vk_gcbiarr_data) + \
374    sizeof(VkRenderingAttachmentInfo) * ((max_color_rts) + 2) \
375 )
376 
377 /**
378  * Constructs a VkRenderingInfo for the inheritance rendering info
379  *
380  * For render-pass-free drivers, this can be used in the implementaiton of
381  * vkCmdExecuteCommands to get a VkRenderingInfo representing the subpass and
382  * framebuffer provided via the inheritance info for a command buffer created
383  * with VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT.  The mental model
384  * here is that VkExecuteCommands() implicitly suspends the render pass and
385  * VkBeginCommandBuffer() resumes it.  If a VkRenderingInfo cannot be
386  * constructed due to a missing framebuffer or similar, NULL will be
387  * returned.
388  *
389  * @param[in]  level       The nesting level of this command buffer
390  * @param[in]  pBeginInfo  The pBeginInfo from vkBeginCommandBuffer
391  * @param[out] stack_data  An opaque blob of data which will be overwritten by
392  *                         this function, passed in from the caller to avoid
393  *                         heap allocations.  It must be at least
394  *                         VK_GCBIARR_DATA_SIZE(max_color_rts) bytes.
395  */
396 const VkRenderingInfo *
397 vk_get_command_buffer_inheritance_as_rendering_resume(
398    VkCommandBufferLevel level,
399    const VkCommandBufferBeginInfo *pBeginInfo,
400    void *stack_data);
401 
402 #ifdef __cplusplus
403 }
404 #endif
405 
406 #endif /* VK_RENDER_PASS_H */
407