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