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