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