1 /*
2 * Copyright © 2020 Valve 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
24 #include "vk_render_pass.h"
25
26 #include "vk_alloc.h"
27 #include "vk_command_buffer.h"
28 #include "vk_common_entrypoints.h"
29 #include "vk_device.h"
30 #include "vk_format.h"
31 #include "vk_framebuffer.h"
32 #include "vk_image.h"
33 #include "vk_util.h"
34
35 #include "util/log.h"
36
37 static void
translate_references(VkAttachmentReference2 ** reference_ptr,uint32_t reference_count,const VkAttachmentReference * reference,const VkRenderPassCreateInfo * pass_info,bool is_input_attachment)38 translate_references(VkAttachmentReference2 **reference_ptr,
39 uint32_t reference_count,
40 const VkAttachmentReference *reference,
41 const VkRenderPassCreateInfo *pass_info,
42 bool is_input_attachment)
43 {
44 VkAttachmentReference2 *reference2 = *reference_ptr;
45 *reference_ptr += reference_count;
46 for (uint32_t i = 0; i < reference_count; i++) {
47 reference2[i] = (VkAttachmentReference2) {
48 .sType = VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2,
49 .pNext = NULL,
50 .attachment = reference[i].attachment,
51 .layout = reference[i].layout,
52 };
53
54 if (is_input_attachment &&
55 reference2[i].attachment != VK_ATTACHMENT_UNUSED) {
56 assert(reference2[i].attachment < pass_info->attachmentCount);
57 const VkAttachmentDescription *att =
58 &pass_info->pAttachments[reference2[i].attachment];
59 reference2[i].aspectMask = vk_format_aspects(att->format);
60 }
61 }
62 }
63
64 VKAPI_ATTR VkResult VKAPI_CALL
vk_common_CreateRenderPass(VkDevice _device,const VkRenderPassCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkRenderPass * pRenderPass)65 vk_common_CreateRenderPass(VkDevice _device,
66 const VkRenderPassCreateInfo *pCreateInfo,
67 const VkAllocationCallbacks *pAllocator,
68 VkRenderPass *pRenderPass)
69 {
70 VK_FROM_HANDLE(vk_device, device, _device);
71
72 uint32_t reference_count = 0;
73 for (uint32_t i = 0; i < pCreateInfo->subpassCount; i++) {
74 reference_count += pCreateInfo->pSubpasses[i].inputAttachmentCount;
75 reference_count += pCreateInfo->pSubpasses[i].colorAttachmentCount;
76 if (pCreateInfo->pSubpasses[i].pResolveAttachments)
77 reference_count += pCreateInfo->pSubpasses[i].colorAttachmentCount;
78 if (pCreateInfo->pSubpasses[i].pDepthStencilAttachment)
79 reference_count += 1;
80 }
81
82 VK_MULTIALLOC(ma);
83 VK_MULTIALLOC_DECL(&ma, VkRenderPassCreateInfo2, create_info, 1);
84 VK_MULTIALLOC_DECL(&ma, VkSubpassDescription2, subpasses,
85 pCreateInfo->subpassCount);
86 VK_MULTIALLOC_DECL(&ma, VkAttachmentDescription2, attachments,
87 pCreateInfo->attachmentCount);
88 VK_MULTIALLOC_DECL(&ma, VkSubpassDependency2, dependencies,
89 pCreateInfo->dependencyCount);
90 VK_MULTIALLOC_DECL(&ma, VkAttachmentReference2, references,
91 reference_count);
92 if (!vk_multialloc_alloc2(&ma, &device->alloc, pAllocator,
93 VK_SYSTEM_ALLOCATION_SCOPE_COMMAND))
94 return VK_ERROR_OUT_OF_HOST_MEMORY;
95
96 VkAttachmentReference2 *reference_ptr = references;
97
98 const VkRenderPassMultiviewCreateInfo *multiview_info = NULL;
99 const VkRenderPassInputAttachmentAspectCreateInfo *aspect_info = NULL;
100 vk_foreach_struct_const(ext, pCreateInfo->pNext) {
101 switch (ext->sType) {
102 case VK_STRUCTURE_TYPE_RENDER_PASS_INPUT_ATTACHMENT_ASPECT_CREATE_INFO:
103 aspect_info = (const VkRenderPassInputAttachmentAspectCreateInfo *)ext;
104 /* We don't care about this information */
105 break;
106
107 case VK_STRUCTURE_TYPE_RENDER_PASS_MULTIVIEW_CREATE_INFO:
108 multiview_info = (const VkRenderPassMultiviewCreateInfo*) ext;
109 break;
110
111 case VK_STRUCTURE_TYPE_RENDER_PASS_FRAGMENT_DENSITY_MAP_CREATE_INFO_EXT:
112 /* pass this through to CreateRenderPass2 */
113 break;
114
115 default:
116 mesa_logd("%s: ignored VkStructureType %u\n", __func__, ext->sType);
117 break;
118 }
119 }
120
121 for (uint32_t i = 0; i < pCreateInfo->attachmentCount; i++) {
122 attachments[i] = (VkAttachmentDescription2) {
123 .sType = VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2,
124 .pNext = NULL,
125 .flags = pCreateInfo->pAttachments[i].flags,
126 .format = pCreateInfo->pAttachments[i].format,
127 .samples = pCreateInfo->pAttachments[i].samples,
128 .loadOp = pCreateInfo->pAttachments[i].loadOp,
129 .storeOp = pCreateInfo->pAttachments[i].storeOp,
130 .stencilLoadOp = pCreateInfo->pAttachments[i].stencilLoadOp,
131 .stencilStoreOp = pCreateInfo->pAttachments[i].stencilStoreOp,
132 .initialLayout = pCreateInfo->pAttachments[i].initialLayout,
133 .finalLayout = pCreateInfo->pAttachments[i].finalLayout,
134 };
135 }
136
137 for (uint32_t i = 0; i < pCreateInfo->subpassCount; i++) {
138 subpasses[i] = (VkSubpassDescription2) {
139 .sType = VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2,
140 .pNext = NULL,
141 .flags = pCreateInfo->pSubpasses[i].flags,
142 .pipelineBindPoint = pCreateInfo->pSubpasses[i].pipelineBindPoint,
143 .viewMask = 0,
144 .inputAttachmentCount = pCreateInfo->pSubpasses[i].inputAttachmentCount,
145 .colorAttachmentCount = pCreateInfo->pSubpasses[i].colorAttachmentCount,
146 .preserveAttachmentCount = pCreateInfo->pSubpasses[i].preserveAttachmentCount,
147 .pPreserveAttachments = pCreateInfo->pSubpasses[i].pPreserveAttachments,
148 };
149
150 if (multiview_info && multiview_info->subpassCount) {
151 assert(multiview_info->subpassCount == pCreateInfo->subpassCount);
152 subpasses[i].viewMask = multiview_info->pViewMasks[i];
153 }
154
155 subpasses[i].pInputAttachments = reference_ptr;
156 translate_references(&reference_ptr,
157 subpasses[i].inputAttachmentCount,
158 pCreateInfo->pSubpasses[i].pInputAttachments,
159 pCreateInfo, true);
160 subpasses[i].pColorAttachments = reference_ptr;
161 translate_references(&reference_ptr,
162 subpasses[i].colorAttachmentCount,
163 pCreateInfo->pSubpasses[i].pColorAttachments,
164 pCreateInfo, false);
165 subpasses[i].pResolveAttachments = NULL;
166 if (pCreateInfo->pSubpasses[i].pResolveAttachments) {
167 subpasses[i].pResolveAttachments = reference_ptr;
168 translate_references(&reference_ptr,
169 subpasses[i].colorAttachmentCount,
170 pCreateInfo->pSubpasses[i].pResolveAttachments,
171 pCreateInfo, false);
172 }
173 subpasses[i].pDepthStencilAttachment = NULL;
174 if (pCreateInfo->pSubpasses[i].pDepthStencilAttachment) {
175 subpasses[i].pDepthStencilAttachment = reference_ptr;
176 translate_references(&reference_ptr, 1,
177 pCreateInfo->pSubpasses[i].pDepthStencilAttachment,
178 pCreateInfo, false);
179 }
180 }
181
182 assert(reference_ptr == references + reference_count);
183
184 if (aspect_info != NULL) {
185 for (uint32_t i = 0; i < aspect_info->aspectReferenceCount; i++) {
186 const VkInputAttachmentAspectReference *ref =
187 &aspect_info->pAspectReferences[i];
188
189 assert(ref->subpass < pCreateInfo->subpassCount);
190 VkSubpassDescription2 *subpass = &subpasses[ref->subpass];
191
192 assert(ref->inputAttachmentIndex < subpass->inputAttachmentCount);
193 VkAttachmentReference2 *att = (VkAttachmentReference2 *)
194 &subpass->pInputAttachments[ref->inputAttachmentIndex];
195
196 att->aspectMask = ref->aspectMask;
197 }
198 }
199
200 for (uint32_t i = 0; i < pCreateInfo->dependencyCount; i++) {
201 dependencies[i] = (VkSubpassDependency2) {
202 .sType = VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2,
203 .pNext = NULL,
204 .srcSubpass = pCreateInfo->pDependencies[i].srcSubpass,
205 .dstSubpass = pCreateInfo->pDependencies[i].dstSubpass,
206 .srcStageMask = pCreateInfo->pDependencies[i].srcStageMask,
207 .dstStageMask = pCreateInfo->pDependencies[i].dstStageMask,
208 .srcAccessMask = pCreateInfo->pDependencies[i].srcAccessMask,
209 .dstAccessMask = pCreateInfo->pDependencies[i].dstAccessMask,
210 .dependencyFlags = pCreateInfo->pDependencies[i].dependencyFlags,
211 .viewOffset = 0,
212 };
213
214 if (multiview_info && multiview_info->dependencyCount) {
215 assert(multiview_info->dependencyCount == pCreateInfo->dependencyCount);
216 dependencies[i].viewOffset = multiview_info->pViewOffsets[i];
217 }
218 }
219
220 *create_info = (VkRenderPassCreateInfo2) {
221 .sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2,
222 .pNext = pCreateInfo->pNext,
223 .flags = pCreateInfo->flags,
224 .attachmentCount = pCreateInfo->attachmentCount,
225 .pAttachments = attachments,
226 .subpassCount = pCreateInfo->subpassCount,
227 .pSubpasses = subpasses,
228 .dependencyCount = pCreateInfo->dependencyCount,
229 .pDependencies = dependencies,
230 };
231
232 if (multiview_info && multiview_info->correlationMaskCount > 0) {
233 create_info->correlatedViewMaskCount = multiview_info->correlationMaskCount;
234 create_info->pCorrelatedViewMasks = multiview_info->pCorrelationMasks;
235 }
236
237 VkResult result =
238 device->dispatch_table.CreateRenderPass2(_device, create_info,
239 pAllocator, pRenderPass);
240
241 vk_free2(&device->alloc, pAllocator, create_info);
242
243 return result;
244 }
245
246 VKAPI_ATTR void VKAPI_CALL
vk_common_CmdBeginRenderPass(VkCommandBuffer commandBuffer,const VkRenderPassBeginInfo * pRenderPassBegin,VkSubpassContents contents)247 vk_common_CmdBeginRenderPass(VkCommandBuffer commandBuffer,
248 const VkRenderPassBeginInfo* pRenderPassBegin,
249 VkSubpassContents contents)
250 {
251 /* We don't have a vk_command_buffer object but we can assume, since we're
252 * using common dispatch, that it's a vk_object of some sort.
253 */
254 struct vk_object_base *disp = (struct vk_object_base *)commandBuffer;
255
256 VkSubpassBeginInfo info = {
257 .sType = VK_STRUCTURE_TYPE_SUBPASS_BEGIN_INFO,
258 .contents = contents,
259 };
260
261 disp->device->dispatch_table.CmdBeginRenderPass2(commandBuffer,
262 pRenderPassBegin, &info);
263 }
264
265 VKAPI_ATTR void VKAPI_CALL
vk_common_CmdEndRenderPass(VkCommandBuffer commandBuffer)266 vk_common_CmdEndRenderPass(VkCommandBuffer commandBuffer)
267 {
268 /* We don't have a vk_command_buffer object but we can assume, since we're
269 * using common dispatch, that it's a vk_object of some sort.
270 */
271 struct vk_object_base *disp = (struct vk_object_base *)commandBuffer;
272
273 VkSubpassEndInfo info = {
274 .sType = VK_STRUCTURE_TYPE_SUBPASS_END_INFO,
275 };
276
277 disp->device->dispatch_table.CmdEndRenderPass2(commandBuffer, &info);
278 }
279
280 VKAPI_ATTR void VKAPI_CALL
vk_common_CmdNextSubpass(VkCommandBuffer commandBuffer,VkSubpassContents contents)281 vk_common_CmdNextSubpass(VkCommandBuffer commandBuffer,
282 VkSubpassContents contents)
283 {
284 /* We don't have a vk_command_buffer object but we can assume, since we're
285 * using common dispatch, that it's a vk_object of some sort.
286 */
287 struct vk_object_base *disp = (struct vk_object_base *)commandBuffer;
288
289 VkSubpassBeginInfo begin_info = {
290 .sType = VK_STRUCTURE_TYPE_SUBPASS_BEGIN_INFO,
291 .contents = contents,
292 };
293
294 VkSubpassEndInfo end_info = {
295 .sType = VK_STRUCTURE_TYPE_SUBPASS_END_INFO,
296 };
297
298 disp->device->dispatch_table.CmdNextSubpass2(commandBuffer, &begin_info,
299 &end_info);
300 }
301
302 static unsigned
num_subpass_attachments2(const VkSubpassDescription2 * desc)303 num_subpass_attachments2(const VkSubpassDescription2 *desc)
304 {
305 bool has_depth_stencil_attachment =
306 desc->pDepthStencilAttachment != NULL &&
307 desc->pDepthStencilAttachment->attachment != VK_ATTACHMENT_UNUSED;
308
309 const VkSubpassDescriptionDepthStencilResolve *ds_resolve =
310 vk_find_struct_const(desc->pNext,
311 SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE);
312
313 bool has_depth_stencil_resolve_attachment =
314 ds_resolve != NULL && ds_resolve->pDepthStencilResolveAttachment &&
315 ds_resolve->pDepthStencilResolveAttachment->attachment != VK_ATTACHMENT_UNUSED;
316
317 const VkFragmentShadingRateAttachmentInfoKHR *fsr_att_info =
318 vk_find_struct_const(desc->pNext,
319 FRAGMENT_SHADING_RATE_ATTACHMENT_INFO_KHR);
320
321 bool has_fragment_shading_rate_attachment =
322 fsr_att_info && fsr_att_info->pFragmentShadingRateAttachment &&
323 fsr_att_info->pFragmentShadingRateAttachment->attachment != VK_ATTACHMENT_UNUSED;
324
325 return desc->inputAttachmentCount +
326 desc->colorAttachmentCount +
327 (desc->pResolveAttachments ? desc->colorAttachmentCount : 0) +
328 has_depth_stencil_attachment +
329 has_depth_stencil_resolve_attachment +
330 has_fragment_shading_rate_attachment;
331 }
332
333 static void
vk_render_pass_attachment_init(struct vk_render_pass_attachment * att,const VkAttachmentDescription2 * desc)334 vk_render_pass_attachment_init(struct vk_render_pass_attachment *att,
335 const VkAttachmentDescription2 *desc)
336 {
337 *att = (struct vk_render_pass_attachment) {
338 .format = desc->format,
339 .aspects = vk_format_aspects(desc->format),
340 .samples = desc->samples,
341 .view_mask = 0,
342 .load_op = desc->loadOp,
343 .store_op = desc->storeOp,
344 .stencil_load_op = desc->stencilLoadOp,
345 .stencil_store_op = desc->stencilStoreOp,
346 .initial_layout = desc->initialLayout,
347 .final_layout = desc->finalLayout,
348 .initial_stencil_layout = vk_att_desc_stencil_layout(desc, false),
349 .final_stencil_layout = vk_att_desc_stencil_layout(desc, true),
350 };
351 }
352
353 static void
vk_subpass_attachment_init(struct vk_subpass_attachment * att,struct vk_render_pass * pass,uint32_t subpass_idx,const VkAttachmentReference2 * ref,const VkAttachmentDescription2 * attachments,VkImageUsageFlagBits usage)354 vk_subpass_attachment_init(struct vk_subpass_attachment *att,
355 struct vk_render_pass *pass,
356 uint32_t subpass_idx,
357 const VkAttachmentReference2 *ref,
358 const VkAttachmentDescription2 *attachments,
359 VkImageUsageFlagBits usage)
360 {
361 if (ref->attachment >= pass->attachment_count) {
362 assert(ref->attachment == VK_ATTACHMENT_UNUSED);
363 *att = (struct vk_subpass_attachment) {
364 .attachment = VK_ATTACHMENT_UNUSED,
365 };
366 return;
367 }
368
369 struct vk_render_pass_attachment *pass_att =
370 &pass->attachments[ref->attachment];
371
372 *att = (struct vk_subpass_attachment) {
373 .attachment = ref->attachment,
374 .aspects = vk_format_aspects(pass_att->format),
375 .usage = usage,
376 .layout = ref->layout,
377 .stencil_layout = vk_att_ref_stencil_layout(ref, attachments),
378 };
379
380 switch (usage) {
381 case VK_IMAGE_USAGE_TRANSFER_DST_BIT:
382 break; /* No special aspect requirements */
383
384 case VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT:
385 /* From the Vulkan 1.2.184 spec:
386 *
387 * "aspectMask is ignored when this structure is used to describe
388 * anything other than an input attachment reference."
389 */
390 assert(!(ref->aspectMask & ~att->aspects));
391 att->aspects = ref->aspectMask;
392 break;
393
394 case VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT:
395 case VK_IMAGE_USAGE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR:
396 assert(att->aspects == VK_IMAGE_ASPECT_COLOR_BIT);
397 break;
398
399 case VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT:
400 assert(!(att->aspects & ~(VK_IMAGE_ASPECT_DEPTH_BIT |
401 VK_IMAGE_ASPECT_STENCIL_BIT)));
402 break;
403
404 default:
405 unreachable("Invalid subpass attachment usage");
406 }
407 }
408
409 static void
vk_subpass_attachment_link_resolve(struct vk_subpass_attachment * att,struct vk_subpass_attachment * resolve,const VkRenderPassCreateInfo2 * info)410 vk_subpass_attachment_link_resolve(struct vk_subpass_attachment *att,
411 struct vk_subpass_attachment *resolve,
412 const VkRenderPassCreateInfo2 *info)
413 {
414 if (resolve->attachment == VK_ATTACHMENT_UNUSED)
415 return;
416
417 assert(att->attachment != VK_ATTACHMENT_UNUSED);
418 att->resolve = resolve;
419 }
420
421 VKAPI_ATTR VkResult VKAPI_CALL
vk_common_CreateRenderPass2(VkDevice _device,const VkRenderPassCreateInfo2 * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkRenderPass * pRenderPass)422 vk_common_CreateRenderPass2(VkDevice _device,
423 const VkRenderPassCreateInfo2 *pCreateInfo,
424 const VkAllocationCallbacks *pAllocator,
425 VkRenderPass *pRenderPass)
426 {
427 VK_FROM_HANDLE(vk_device, device, _device);
428
429 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2);
430
431 VK_MULTIALLOC(ma);
432 VK_MULTIALLOC_DECL(&ma, struct vk_render_pass, pass, 1);
433 VK_MULTIALLOC_DECL(&ma, struct vk_render_pass_attachment, attachments,
434 pCreateInfo->attachmentCount);
435 VK_MULTIALLOC_DECL(&ma, struct vk_subpass, subpasses,
436 pCreateInfo->subpassCount);
437 VK_MULTIALLOC_DECL(&ma, struct vk_subpass_dependency, dependencies,
438 pCreateInfo->dependencyCount);
439
440 uint32_t subpass_attachment_count = 0;
441 uint32_t subpass_color_attachment_count = 0;
442 for (uint32_t i = 0; i < pCreateInfo->subpassCount; i++) {
443 subpass_attachment_count +=
444 num_subpass_attachments2(&pCreateInfo->pSubpasses[i]);
445 subpass_color_attachment_count +=
446 pCreateInfo->pSubpasses[i].colorAttachmentCount;
447 }
448 VK_MULTIALLOC_DECL(&ma, struct vk_subpass_attachment, subpass_attachments,
449 subpass_attachment_count);
450 VK_MULTIALLOC_DECL(&ma, VkFormat, subpass_color_formats,
451 subpass_color_attachment_count);
452 VK_MULTIALLOC_DECL(&ma, VkSampleCountFlagBits, subpass_color_samples,
453 subpass_color_attachment_count);
454
455 if (!vk_object_multizalloc(device, &ma, pAllocator,
456 VK_OBJECT_TYPE_RENDER_PASS))
457 return VK_ERROR_OUT_OF_HOST_MEMORY;
458
459 pass->attachment_count = pCreateInfo->attachmentCount;
460 pass->attachments = attachments;
461 pass->subpass_count = pCreateInfo->subpassCount;
462 pass->subpasses = subpasses;
463 pass->dependency_count = pCreateInfo->dependencyCount;
464 pass->dependencies = dependencies;
465
466 for (uint32_t a = 0; a < pCreateInfo->attachmentCount; a++) {
467 vk_render_pass_attachment_init(&pass->attachments[a],
468 &pCreateInfo->pAttachments[a]);
469 }
470
471 struct vk_subpass_attachment *next_subpass_attachment = subpass_attachments;
472 VkFormat *next_subpass_color_format = subpass_color_formats;
473 VkSampleCountFlagBits *next_subpass_color_samples = subpass_color_samples;
474 for (uint32_t s = 0; s < pCreateInfo->subpassCount; s++) {
475 const VkSubpassDescription2 *desc = &pCreateInfo->pSubpasses[s];
476 struct vk_subpass *subpass = &pass->subpasses[s];
477 const VkMultisampledRenderToSingleSampledInfoEXT *mrtss =
478 vk_find_struct_const(desc->pNext, MULTISAMPLED_RENDER_TO_SINGLE_SAMPLED_INFO_EXT);
479 if (mrtss && !mrtss->multisampledRenderToSingleSampledEnable)
480 mrtss = NULL;
481
482 subpass->attachment_count = num_subpass_attachments2(desc);
483 subpass->attachments = next_subpass_attachment;
484
485 /* From the Vulkan 1.3.204 spec:
486 *
487 * VUID-VkRenderPassCreateInfo2-viewMask-03058
488 *
489 * "The VkSubpassDescription2::viewMask member of all elements of
490 * pSubpasses must either all be 0, or all not be 0"
491 */
492 if (desc->viewMask)
493 pass->is_multiview = true;
494 assert(pass->is_multiview == (desc->viewMask != 0));
495
496 /* For all view masks in the vk_render_pass data structure, we use a
497 * mask of 1 for non-multiview instead of a mask of 0.
498 */
499 subpass->view_mask = desc->viewMask ? desc->viewMask : 1;
500 pass->view_mask |= subpass->view_mask;
501
502 subpass->input_count = desc->inputAttachmentCount;
503 if (desc->inputAttachmentCount > 0) {
504 subpass->input_attachments = next_subpass_attachment;
505 next_subpass_attachment += desc->inputAttachmentCount;
506
507 for (uint32_t a = 0; a < desc->inputAttachmentCount; a++) {
508 vk_subpass_attachment_init(&subpass->input_attachments[a],
509 pass, s,
510 &desc->pInputAttachments[a],
511 pCreateInfo->pAttachments,
512 VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT);
513 }
514 }
515
516 subpass->color_count = desc->colorAttachmentCount;
517 if (desc->colorAttachmentCount > 0) {
518 subpass->color_attachments = next_subpass_attachment;
519 next_subpass_attachment += desc->colorAttachmentCount;
520
521 for (uint32_t a = 0; a < desc->colorAttachmentCount; a++) {
522 vk_subpass_attachment_init(&subpass->color_attachments[a],
523 pass, s,
524 &desc->pColorAttachments[a],
525 pCreateInfo->pAttachments,
526 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
527 }
528 }
529
530 if (desc->pResolveAttachments) {
531 subpass->color_resolve_count = desc->colorAttachmentCount;
532 subpass->color_resolve_attachments = next_subpass_attachment;
533 next_subpass_attachment += desc->colorAttachmentCount;
534
535 for (uint32_t a = 0; a < desc->colorAttachmentCount; a++) {
536 vk_subpass_attachment_init(&subpass->color_resolve_attachments[a],
537 pass, s,
538 &desc->pResolveAttachments[a],
539 pCreateInfo->pAttachments,
540 VK_IMAGE_USAGE_TRANSFER_DST_BIT);
541 vk_subpass_attachment_link_resolve(&subpass->color_attachments[a],
542 &subpass->color_resolve_attachments[a],
543 pCreateInfo);
544 }
545 }
546
547 if (desc->pDepthStencilAttachment &&
548 desc->pDepthStencilAttachment->attachment != VK_ATTACHMENT_UNUSED) {
549 subpass->depth_stencil_attachment = next_subpass_attachment++;
550
551 vk_subpass_attachment_init(subpass->depth_stencil_attachment,
552 pass, s,
553 desc->pDepthStencilAttachment,
554 pCreateInfo->pAttachments,
555 VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT);
556 }
557
558 const VkSubpassDescriptionDepthStencilResolve *ds_resolve =
559 vk_find_struct_const(desc->pNext,
560 SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE);
561
562 if (ds_resolve) {
563 if (ds_resolve->pDepthStencilResolveAttachment &&
564 ds_resolve->pDepthStencilResolveAttachment->attachment != VK_ATTACHMENT_UNUSED) {
565 subpass->depth_stencil_resolve_attachment = next_subpass_attachment++;
566
567 vk_subpass_attachment_init(subpass->depth_stencil_resolve_attachment,
568 pass, s,
569 ds_resolve->pDepthStencilResolveAttachment,
570 pCreateInfo->pAttachments,
571 VK_IMAGE_USAGE_TRANSFER_DST_BIT);
572 vk_subpass_attachment_link_resolve(subpass->depth_stencil_attachment,
573 subpass->depth_stencil_resolve_attachment,
574 pCreateInfo);
575 }
576 if (subpass->depth_stencil_resolve_attachment || mrtss) {
577 /* From the Vulkan 1.3.204 spec:
578 *
579 * VUID-VkSubpassDescriptionDepthStencilResolve-pDepthStencilResolveAttachment-03178
580 *
581 * "If pDepthStencilResolveAttachment is not NULL and does not
582 * have the value VK_ATTACHMENT_UNUSED, depthResolveMode and
583 * stencilResolveMode must not both be VK_RESOLVE_MODE_NONE"
584 */
585 assert(ds_resolve->depthResolveMode != VK_RESOLVE_MODE_NONE ||
586 ds_resolve->stencilResolveMode != VK_RESOLVE_MODE_NONE);
587
588 subpass->depth_resolve_mode = ds_resolve->depthResolveMode;
589 subpass->stencil_resolve_mode = ds_resolve->stencilResolveMode;
590 }
591 }
592
593 const VkFragmentShadingRateAttachmentInfoKHR *fsr_att_info =
594 vk_find_struct_const(desc->pNext,
595 FRAGMENT_SHADING_RATE_ATTACHMENT_INFO_KHR);
596
597 if (fsr_att_info && fsr_att_info->pFragmentShadingRateAttachment &&
598 fsr_att_info->pFragmentShadingRateAttachment->attachment != VK_ATTACHMENT_UNUSED) {
599 subpass->fragment_shading_rate_attachment = next_subpass_attachment++;
600 vk_subpass_attachment_init(subpass->fragment_shading_rate_attachment,
601 pass, s,
602 fsr_att_info->pFragmentShadingRateAttachment,
603 pCreateInfo->pAttachments,
604 VK_IMAGE_USAGE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR);
605 subpass->fragment_shading_rate_attachment_texel_size =
606 fsr_att_info->shadingRateAttachmentTexelSize;
607 subpass->pipeline_flags |=
608 VK_PIPELINE_CREATE_RENDERING_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR;
609 }
610
611 /* Figure out any self-dependencies */
612 assert(desc->colorAttachmentCount <= 32);
613 for (uint32_t a = 0; a < desc->inputAttachmentCount; a++) {
614 if (desc->pInputAttachments[a].attachment == VK_ATTACHMENT_UNUSED)
615 continue;
616
617 for (uint32_t c = 0; c < desc->colorAttachmentCount; c++) {
618 if (desc->pColorAttachments[c].attachment ==
619 desc->pInputAttachments[a].attachment) {
620 subpass->input_attachments[a].layout =
621 VK_IMAGE_LAYOUT_ATTACHMENT_FEEDBACK_LOOP_OPTIMAL_EXT;
622 subpass->color_attachments[c].layout =
623 VK_IMAGE_LAYOUT_ATTACHMENT_FEEDBACK_LOOP_OPTIMAL_EXT;
624 subpass->pipeline_flags |=
625 VK_PIPELINE_CREATE_COLOR_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT;
626 }
627 }
628
629 if (desc->pDepthStencilAttachment != NULL &&
630 desc->pDepthStencilAttachment->attachment ==
631 desc->pInputAttachments[a].attachment) {
632 VkImageAspectFlags aspects =
633 subpass->input_attachments[a].aspects;
634 if (aspects & VK_IMAGE_ASPECT_DEPTH_BIT) {
635 subpass->input_attachments[a].layout =
636 VK_IMAGE_LAYOUT_ATTACHMENT_FEEDBACK_LOOP_OPTIMAL_EXT;
637 subpass->depth_stencil_attachment->layout =
638 VK_IMAGE_LAYOUT_ATTACHMENT_FEEDBACK_LOOP_OPTIMAL_EXT;
639 subpass->pipeline_flags |=
640 VK_PIPELINE_CREATE_DEPTH_STENCIL_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT;
641 }
642 if (aspects & VK_IMAGE_ASPECT_STENCIL_BIT) {
643 subpass->input_attachments[a].stencil_layout =
644 VK_IMAGE_LAYOUT_ATTACHMENT_FEEDBACK_LOOP_OPTIMAL_EXT;
645 subpass->depth_stencil_attachment->stencil_layout =
646 VK_IMAGE_LAYOUT_ATTACHMENT_FEEDBACK_LOOP_OPTIMAL_EXT;
647 subpass->pipeline_flags |=
648 VK_PIPELINE_CREATE_DEPTH_STENCIL_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT;
649 }
650 }
651 }
652
653 VkFormat *color_formats = NULL;
654 VkSampleCountFlagBits *color_samples = NULL;
655 VkSampleCountFlagBits samples = 0;
656 if (desc->colorAttachmentCount > 0) {
657 color_formats = next_subpass_color_format;
658 color_samples = next_subpass_color_samples;
659 for (uint32_t a = 0; a < desc->colorAttachmentCount; a++) {
660 const VkAttachmentReference2 *ref = &desc->pColorAttachments[a];
661 if (ref->attachment >= pCreateInfo->attachmentCount) {
662 color_formats[a] = VK_FORMAT_UNDEFINED;
663 color_samples[a] = VK_SAMPLE_COUNT_1_BIT;
664 } else {
665 const VkAttachmentDescription2 *att =
666 &pCreateInfo->pAttachments[ref->attachment];
667
668 color_formats[a] = att->format;
669 color_samples[a] = att->samples;
670
671 samples |= att->samples;
672 }
673 }
674 next_subpass_color_format += desc->colorAttachmentCount;
675 next_subpass_color_samples += desc->colorAttachmentCount;
676 }
677
678 VkFormat depth_format = VK_FORMAT_UNDEFINED;
679 VkFormat stencil_format = VK_FORMAT_UNDEFINED;
680 VkSampleCountFlagBits depth_stencil_samples = VK_SAMPLE_COUNT_1_BIT;
681 if (desc->pDepthStencilAttachment != NULL) {
682 const VkAttachmentReference2 *ref = desc->pDepthStencilAttachment;
683 if (ref->attachment < pCreateInfo->attachmentCount) {
684 const VkAttachmentDescription2 *att =
685 &pCreateInfo->pAttachments[ref->attachment];
686
687 if (vk_format_has_depth(att->format))
688 depth_format = att->format;
689 if (vk_format_has_stencil(att->format))
690 stencil_format = att->format;
691
692 depth_stencil_samples = att->samples;
693
694 samples |= att->samples;
695 }
696 }
697
698 subpass->sample_count_info_amd = (VkAttachmentSampleCountInfoAMD) {
699 .sType = VK_STRUCTURE_TYPE_ATTACHMENT_SAMPLE_COUNT_INFO_AMD,
700 .pNext = NULL,
701 .colorAttachmentCount = desc->colorAttachmentCount,
702 .pColorAttachmentSamples = color_samples,
703 .depthStencilAttachmentSamples = depth_stencil_samples,
704 };
705
706 subpass->pipeline_info = (VkPipelineRenderingCreateInfo) {
707 .sType = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO,
708 .pNext = &subpass->sample_count_info_amd,
709 .viewMask = desc->viewMask,
710 .colorAttachmentCount = desc->colorAttachmentCount,
711 .pColorAttachmentFormats = color_formats,
712 .depthAttachmentFormat = depth_format,
713 .stencilAttachmentFormat = stencil_format,
714 };
715
716 subpass->inheritance_info = (VkCommandBufferInheritanceRenderingInfo) {
717 .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_RENDERING_INFO,
718 .pNext = &subpass->sample_count_info_amd,
719 /* If we're inheriting, the contents are clearly in secondaries */
720 .flags = VK_RENDERING_CONTENTS_SECONDARY_COMMAND_BUFFERS_BIT,
721 .viewMask = desc->viewMask,
722 .colorAttachmentCount = desc->colorAttachmentCount,
723 .pColorAttachmentFormats = color_formats,
724 .depthAttachmentFormat = depth_format,
725 .stencilAttachmentFormat = stencil_format,
726 .rasterizationSamples = samples,
727 };
728
729 if (mrtss) {
730 assert(mrtss->multisampledRenderToSingleSampledEnable);
731 subpass->mrtss = (VkMultisampledRenderToSingleSampledInfoEXT) {
732 .sType = VK_STRUCTURE_TYPE_MULTISAMPLED_RENDER_TO_SINGLE_SAMPLED_INFO_EXT,
733 .multisampledRenderToSingleSampledEnable = VK_TRUE,
734 .rasterizationSamples = mrtss->rasterizationSamples,
735 };
736 }
737 }
738 assert(next_subpass_attachment ==
739 subpass_attachments + subpass_attachment_count);
740 assert(next_subpass_color_format ==
741 subpass_color_formats + subpass_color_attachment_count);
742 assert(next_subpass_color_samples ==
743 subpass_color_samples + subpass_color_attachment_count);
744
745 /* Walk backwards over the subpasses to compute view masks and
746 * last_subpass masks for all attachments.
747 */
748 for (uint32_t s = 0; s < pCreateInfo->subpassCount; s++) {
749 struct vk_subpass *subpass =
750 &pass->subpasses[(pCreateInfo->subpassCount - 1) - s];
751
752 /* First, compute last_subpass for all the attachments */
753 for (uint32_t a = 0; a < subpass->attachment_count; a++) {
754 struct vk_subpass_attachment *att = &subpass->attachments[a];
755 if (att->attachment == VK_ATTACHMENT_UNUSED)
756 continue;
757
758 assert(att->attachment < pass->attachment_count);
759 const struct vk_render_pass_attachment *pass_att =
760 &pass->attachments[att->attachment];
761
762 att->last_subpass = subpass->view_mask & ~pass_att->view_mask;
763 }
764
765 /* Then compute pass_att->view_mask. We do the two separately so that
766 * we end up with the right last_subpass even if the same attachment is
767 * used twice within a subpass.
768 */
769 for (uint32_t a = 0; a < subpass->attachment_count; a++) {
770 const struct vk_subpass_attachment *att = &subpass->attachments[a];
771 if (att->attachment == VK_ATTACHMENT_UNUSED)
772 continue;
773
774 assert(att->attachment < pass->attachment_count);
775 struct vk_render_pass_attachment *pass_att =
776 &pass->attachments[att->attachment];
777
778 pass_att->view_mask |= subpass->view_mask;
779 }
780 }
781
782 pass->dependency_count = pCreateInfo->dependencyCount;
783 for (uint32_t d = 0; d < pCreateInfo->dependencyCount; d++) {
784 const VkSubpassDependency2 *dep = &pCreateInfo->pDependencies[d];
785
786 pass->dependencies[d] = (struct vk_subpass_dependency) {
787 .flags = dep->dependencyFlags,
788 .src_subpass = dep->srcSubpass,
789 .dst_subpass = dep->dstSubpass,
790 .src_stage_mask = (VkPipelineStageFlags2)dep->srcStageMask,
791 .dst_stage_mask = (VkPipelineStageFlags2)dep->dstStageMask,
792 .src_access_mask = (VkAccessFlags2)dep->srcAccessMask,
793 .dst_access_mask = (VkAccessFlags2)dep->dstAccessMask,
794 .view_offset = dep->viewOffset,
795 };
796
797 /* From the Vulkan 1.3.204 spec:
798 *
799 * "If a VkMemoryBarrier2 is included in the pNext chain,
800 * srcStageMask, dstStageMask, srcAccessMask, and dstAccessMask
801 * parameters are ignored. The synchronization and access scopes
802 * instead are defined by the parameters of VkMemoryBarrier2."
803 */
804 const VkMemoryBarrier2 *barrier =
805 vk_find_struct_const(dep->pNext, MEMORY_BARRIER_2);
806 if (barrier != NULL) {
807 pass->dependencies[d].src_stage_mask = barrier->srcStageMask;
808 pass->dependencies[d].dst_stage_mask = barrier->dstStageMask;
809 pass->dependencies[d].src_access_mask = barrier->srcAccessMask;
810 pass->dependencies[d].dst_access_mask = barrier->dstAccessMask;
811 }
812 }
813
814 const VkRenderPassFragmentDensityMapCreateInfoEXT *fdm_info =
815 vk_find_struct_const(pCreateInfo->pNext,
816 RENDER_PASS_FRAGMENT_DENSITY_MAP_CREATE_INFO_EXT);
817 if (fdm_info) {
818 pass->fragment_density_map = fdm_info->fragmentDensityMapAttachment;
819 } else {
820 pass->fragment_density_map.attachment = VK_ATTACHMENT_UNUSED;
821 pass->fragment_density_map.layout = VK_IMAGE_LAYOUT_UNDEFINED;
822 }
823
824 *pRenderPass = vk_render_pass_to_handle(pass);
825
826 return VK_SUCCESS;
827 }
828
829 const VkPipelineRenderingCreateInfo *
vk_get_pipeline_rendering_create_info(const VkGraphicsPipelineCreateInfo * info)830 vk_get_pipeline_rendering_create_info(const VkGraphicsPipelineCreateInfo *info)
831 {
832 VK_FROM_HANDLE(vk_render_pass, render_pass, info->renderPass);
833 if (render_pass != NULL) {
834 assert(info->subpass < render_pass->subpass_count);
835 return &render_pass->subpasses[info->subpass].pipeline_info;
836 }
837
838 return vk_find_struct_const(info->pNext, PIPELINE_RENDERING_CREATE_INFO);
839 }
840
841 VkPipelineCreateFlags2KHR
vk_get_pipeline_rendering_flags(const VkGraphicsPipelineCreateInfo * info)842 vk_get_pipeline_rendering_flags(const VkGraphicsPipelineCreateInfo *info)
843 {
844 VkPipelineCreateFlags2KHR rendering_flags = 0;
845
846 VK_FROM_HANDLE(vk_render_pass, render_pass, info->renderPass);
847 if (render_pass != NULL) {
848 rendering_flags |= render_pass->subpasses[info->subpass].pipeline_flags;
849 if (render_pass->fragment_density_map.attachment != VK_ATTACHMENT_UNUSED)
850 rendering_flags |=
851 VK_PIPELINE_CREATE_RENDERING_FRAGMENT_DENSITY_MAP_ATTACHMENT_BIT_EXT;
852 }
853
854 return rendering_flags;
855 }
856
857 const VkAttachmentSampleCountInfoAMD *
vk_get_pipeline_sample_count_info_amd(const VkGraphicsPipelineCreateInfo * info)858 vk_get_pipeline_sample_count_info_amd(const VkGraphicsPipelineCreateInfo *info)
859 {
860 VK_FROM_HANDLE(vk_render_pass, render_pass, info->renderPass);
861 if (render_pass != NULL) {
862 assert(info->subpass < render_pass->subpass_count);
863 return &render_pass->subpasses[info->subpass].sample_count_info_amd;
864 }
865
866 return vk_find_struct_const(info->pNext, ATTACHMENT_SAMPLE_COUNT_INFO_AMD);
867 }
868
869 const VkCommandBufferInheritanceRenderingInfo *
vk_get_command_buffer_inheritance_rendering_info(VkCommandBufferLevel level,const VkCommandBufferBeginInfo * pBeginInfo)870 vk_get_command_buffer_inheritance_rendering_info(
871 VkCommandBufferLevel level,
872 const VkCommandBufferBeginInfo *pBeginInfo)
873 {
874 /* From the Vulkan 1.3.204 spec:
875 *
876 * "VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT specifies that a
877 * secondary command buffer is considered to be entirely inside a render
878 * pass. If this is a primary command buffer, then this bit is ignored."
879 *
880 * Since we're only concerned with the continue case here, we can ignore
881 * any primary command buffers.
882 */
883 if (level == VK_COMMAND_BUFFER_LEVEL_PRIMARY)
884 return NULL;
885
886 if (!(pBeginInfo->flags & VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT))
887 return NULL;
888
889 const VkCommandBufferInheritanceInfo *inheritance =
890 pBeginInfo->pInheritanceInfo;
891
892 /* From the Vulkan 1.3.204 spec:
893 *
894 * "If VkCommandBufferInheritanceInfo::renderPass is not VK_NULL_HANDLE,
895 * or VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT is not specified
896 * in VkCommandBufferBeginInfo::flags, parameters of this structure are
897 * ignored."
898 *
899 * If we have a render pass that wins, even if a
900 * VkCommandBufferInheritanceRenderingInfo struct is included in the pNext
901 * chain.
902 */
903 VK_FROM_HANDLE(vk_render_pass, render_pass, inheritance->renderPass);
904 if (render_pass != NULL) {
905 assert(inheritance->subpass < render_pass->subpass_count);
906 return &render_pass->subpasses[inheritance->subpass].inheritance_info;
907 }
908
909 return vk_find_struct_const(inheritance->pNext,
910 COMMAND_BUFFER_INHERITANCE_RENDERING_INFO);
911 }
912
913 const VkRenderingInfo *
vk_get_command_buffer_inheritance_as_rendering_resume(VkCommandBufferLevel level,const VkCommandBufferBeginInfo * pBeginInfo,void * stack_data)914 vk_get_command_buffer_inheritance_as_rendering_resume(
915 VkCommandBufferLevel level,
916 const VkCommandBufferBeginInfo *pBeginInfo,
917 void *stack_data)
918 {
919 struct vk_gcbiarr_data *data = stack_data;
920
921 /* From the Vulkan 1.3.204 spec:
922 *
923 * "VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT specifies that a
924 * secondary command buffer is considered to be entirely inside a render
925 * pass. If this is a primary command buffer, then this bit is ignored."
926 *
927 * Since we're only concerned with the continue case here, we can ignore
928 * any primary command buffers.
929 */
930 if (level == VK_COMMAND_BUFFER_LEVEL_PRIMARY)
931 return NULL;
932
933 if (!(pBeginInfo->flags & VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT))
934 return NULL;
935
936 const VkCommandBufferInheritanceInfo *inheritance =
937 pBeginInfo->pInheritanceInfo;
938
939 VK_FROM_HANDLE(vk_render_pass, pass, inheritance->renderPass);
940 if (pass == NULL)
941 return NULL;
942
943 assert(inheritance->subpass < pass->subpass_count);
944 const struct vk_subpass *subpass = &pass->subpasses[inheritance->subpass];
945
946 VK_FROM_HANDLE(vk_framebuffer, fb, inheritance->framebuffer);
947 if (fb == NULL || (fb->flags & VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT))
948 return NULL;
949
950 data->rendering = (VkRenderingInfo) {
951 .sType = VK_STRUCTURE_TYPE_RENDERING_INFO,
952 .flags = VK_RENDERING_RESUMING_BIT,
953 .renderArea = {
954 .offset = { 0, 0 },
955 .extent = { fb->width, fb->height },
956 },
957 .layerCount = fb->layers,
958 .viewMask = pass->is_multiview ? subpass->view_mask : 0,
959 };
960
961 VkRenderingAttachmentInfo *attachments = data->attachments;
962
963 for (unsigned i = 0; i < subpass->color_count; i++) {
964 const struct vk_subpass_attachment *sp_att =
965 &subpass->color_attachments[i];
966 if (sp_att->attachment == VK_ATTACHMENT_UNUSED) {
967 attachments[i] = (VkRenderingAttachmentInfo) {
968 .imageView = VK_NULL_HANDLE,
969 };
970 continue;
971 }
972
973 assert(sp_att->attachment < pass->attachment_count);
974 attachments[i] = (VkRenderingAttachmentInfo) {
975 .sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO,
976 .imageView = fb->attachments[sp_att->attachment],
977 .imageLayout = sp_att->layout,
978 .loadOp = VK_ATTACHMENT_LOAD_OP_LOAD,
979 .storeOp = VK_ATTACHMENT_STORE_OP_STORE,
980 };
981 }
982 data->rendering.colorAttachmentCount = subpass->color_count;
983 data->rendering.pColorAttachments = attachments;
984 attachments += subpass->color_count;
985
986 if (subpass->depth_stencil_attachment) {
987 const struct vk_subpass_attachment *sp_att =
988 subpass->depth_stencil_attachment;
989 assert(sp_att->attachment < pass->attachment_count);
990
991 VK_FROM_HANDLE(vk_image_view, iview, fb->attachments[sp_att->attachment]);
992 if (iview->image->aspects & VK_IMAGE_ASPECT_DEPTH_BIT) {
993 *attachments = (VkRenderingAttachmentInfo) {
994 .sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO,
995 .imageView = vk_image_view_to_handle(iview),
996 .imageLayout = sp_att->layout,
997 .loadOp = VK_ATTACHMENT_LOAD_OP_LOAD,
998 .storeOp = VK_ATTACHMENT_STORE_OP_STORE,
999 };
1000 data->rendering.pDepthAttachment = attachments++;
1001 }
1002
1003 if (iview->image->aspects & VK_IMAGE_ASPECT_STENCIL_BIT) {
1004 *attachments = (VkRenderingAttachmentInfo) {
1005 .sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO,
1006 .imageView = vk_image_view_to_handle(iview),
1007 .imageLayout = sp_att->stencil_layout,
1008 .loadOp = VK_ATTACHMENT_LOAD_OP_LOAD,
1009 .storeOp = VK_ATTACHMENT_STORE_OP_STORE,
1010 };
1011 data->rendering.pStencilAttachment = attachments++;
1012 }
1013 }
1014
1015 if (subpass->fragment_shading_rate_attachment) {
1016 const struct vk_subpass_attachment *sp_att =
1017 subpass->fragment_shading_rate_attachment;
1018 assert(sp_att->attachment < pass->attachment_count);
1019
1020 data->fsr_att = (VkRenderingFragmentShadingRateAttachmentInfoKHR) {
1021 .sType = VK_STRUCTURE_TYPE_RENDERING_FRAGMENT_SHADING_RATE_ATTACHMENT_INFO_KHR,
1022 .imageView = fb->attachments[sp_att->attachment],
1023 .imageLayout = sp_att->layout,
1024 .shadingRateAttachmentTexelSize =
1025 subpass->fragment_shading_rate_attachment_texel_size,
1026 };
1027 __vk_append_struct(&data->rendering, &data->fsr_att);
1028 }
1029
1030 /* Append this one last because it lives in the subpass and we don't want
1031 * to be changed by appending other structures later.
1032 */
1033 if (subpass->mrtss.multisampledRenderToSingleSampledEnable)
1034 __vk_append_struct(&data->rendering, (void *)&subpass->mrtss);
1035
1036 return &data->rendering;
1037 }
1038
1039 VKAPI_ATTR void VKAPI_CALL
vk_common_DestroyRenderPass(VkDevice _device,VkRenderPass renderPass,const VkAllocationCallbacks * pAllocator)1040 vk_common_DestroyRenderPass(VkDevice _device,
1041 VkRenderPass renderPass,
1042 const VkAllocationCallbacks *pAllocator)
1043 {
1044 VK_FROM_HANDLE(vk_device, device, _device);
1045 VK_FROM_HANDLE(vk_render_pass, pass, renderPass);
1046
1047 if (!pass)
1048 return;
1049
1050 vk_object_free(device, pAllocator, pass);
1051 }
1052
1053 VKAPI_ATTR void VKAPI_CALL
vk_common_GetRenderAreaGranularity(VkDevice device,VkRenderPass renderPass,VkExtent2D * pGranularity)1054 vk_common_GetRenderAreaGranularity(VkDevice device,
1055 VkRenderPass renderPass,
1056 VkExtent2D *pGranularity)
1057 {
1058 *pGranularity = (VkExtent2D){1, 1};
1059 }
1060
1061 VKAPI_ATTR void VKAPI_CALL
vk_common_GetRenderingAreaGranularityKHR(VkDevice _device,const VkRenderingAreaInfoKHR * pRenderingAreaInfo,VkExtent2D * pGranularity)1062 vk_common_GetRenderingAreaGranularityKHR(
1063 VkDevice _device, const VkRenderingAreaInfoKHR *pRenderingAreaInfo,
1064 VkExtent2D *pGranularity)
1065 {
1066 *pGranularity = (VkExtent2D) { 1, 1 };
1067 }
1068
1069 static VkRenderPassSampleLocationsBeginInfoEXT *
clone_rp_sample_locations(const VkRenderPassSampleLocationsBeginInfoEXT * loc)1070 clone_rp_sample_locations(const VkRenderPassSampleLocationsBeginInfoEXT *loc)
1071 {
1072 uint32_t sl_count = 0;
1073
1074 for (uint32_t i = 0; i < loc->attachmentInitialSampleLocationsCount; i++) {
1075 const VkAttachmentSampleLocationsEXT *att_sl_in =
1076 &loc->pAttachmentInitialSampleLocations[i];
1077 sl_count += att_sl_in->sampleLocationsInfo.sampleLocationsCount;
1078 }
1079 for (uint32_t i = 0; i < loc->postSubpassSampleLocationsCount; i++) {
1080 const VkSubpassSampleLocationsEXT *sp_sl_in =
1081 &loc->pPostSubpassSampleLocations[i];
1082 sl_count += sp_sl_in->sampleLocationsInfo.sampleLocationsCount;
1083 }
1084
1085 VK_MULTIALLOC(ma);
1086 VK_MULTIALLOC_DECL(&ma, VkRenderPassSampleLocationsBeginInfoEXT, new_loc, 1);
1087 VK_MULTIALLOC_DECL(&ma, VkAttachmentSampleLocationsEXT, new_att_sl,
1088 loc->attachmentInitialSampleLocationsCount);
1089 VK_MULTIALLOC_DECL(&ma, VkSubpassSampleLocationsEXT, new_sp_sl,
1090 loc->postSubpassSampleLocationsCount);
1091 VK_MULTIALLOC_DECL(&ma, VkSampleLocationEXT, sl, sl_count);
1092 if (!vk_multialloc_alloc(&ma, vk_default_allocator(),
1093 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT))
1094 return NULL;
1095
1096 VkSampleLocationEXT *next_sl = sl;
1097 for (uint32_t i = 0; i < loc->attachmentInitialSampleLocationsCount; i++) {
1098 const VkAttachmentSampleLocationsEXT *att_sl_in =
1099 &loc->pAttachmentInitialSampleLocations[i];
1100 const VkSampleLocationsInfoEXT *sli_in = &att_sl_in->sampleLocationsInfo;
1101
1102 typed_memcpy(next_sl, sli_in->pSampleLocations,
1103 sli_in->sampleLocationsCount);
1104
1105 new_att_sl[i] = (VkAttachmentSampleLocationsEXT) {
1106 .attachmentIndex = att_sl_in->attachmentIndex,
1107 .sampleLocationsInfo = {
1108 .sType = VK_STRUCTURE_TYPE_SAMPLE_LOCATIONS_INFO_EXT,
1109 .sampleLocationsPerPixel = sli_in->sampleLocationsPerPixel,
1110 .sampleLocationGridSize = sli_in->sampleLocationGridSize,
1111 .sampleLocationsCount = sli_in->sampleLocationsCount,
1112 .pSampleLocations = next_sl,
1113 },
1114 };
1115
1116 next_sl += sli_in->sampleLocationsCount;
1117 }
1118
1119 for (uint32_t i = 0; i < loc->postSubpassSampleLocationsCount; i++) {
1120 const VkSubpassSampleLocationsEXT *sp_sl_in =
1121 &loc->pPostSubpassSampleLocations[i];
1122 const VkSampleLocationsInfoEXT *sli_in = &sp_sl_in->sampleLocationsInfo;
1123
1124 typed_memcpy(next_sl, sli_in->pSampleLocations,
1125 sli_in->sampleLocationsCount);
1126
1127 new_sp_sl[i] = (VkSubpassSampleLocationsEXT) {
1128 .subpassIndex = sp_sl_in->subpassIndex,
1129 .sampleLocationsInfo = {
1130 .sType = VK_STRUCTURE_TYPE_SAMPLE_LOCATIONS_INFO_EXT,
1131 .sampleLocationsPerPixel = sli_in->sampleLocationsPerPixel,
1132 .sampleLocationGridSize = sli_in->sampleLocationGridSize,
1133 .sampleLocationsCount = sli_in->sampleLocationsCount,
1134 .pSampleLocations = next_sl,
1135 },
1136 };
1137
1138 next_sl += sli_in->sampleLocationsCount;
1139 }
1140
1141 assert(next_sl == sl + sl_count);
1142
1143 *new_loc = (VkRenderPassSampleLocationsBeginInfoEXT) {
1144 .sType = VK_STRUCTURE_TYPE_RENDER_PASS_SAMPLE_LOCATIONS_BEGIN_INFO_EXT,
1145 .attachmentInitialSampleLocationsCount = loc->attachmentInitialSampleLocationsCount,
1146 .pAttachmentInitialSampleLocations = new_att_sl,
1147 .postSubpassSampleLocationsCount = loc->postSubpassSampleLocationsCount,
1148 .pPostSubpassSampleLocations = new_sp_sl,
1149 };
1150
1151 return new_loc;
1152 }
1153
1154 static const VkSampleLocationsInfoEXT *
get_subpass_sample_locations(const VkRenderPassSampleLocationsBeginInfoEXT * loc,uint32_t subpass_idx)1155 get_subpass_sample_locations(const VkRenderPassSampleLocationsBeginInfoEXT *loc,
1156 uint32_t subpass_idx)
1157 {
1158 for (uint32_t i = 0; i < loc->postSubpassSampleLocationsCount; i++) {
1159 if (loc->pPostSubpassSampleLocations[i].subpassIndex == subpass_idx)
1160 return &loc->pPostSubpassSampleLocations[i].sampleLocationsInfo;
1161 }
1162
1163 return NULL;
1164 }
1165
1166 static bool
vk_image_layout_supports_input_attachment(VkImageLayout layout)1167 vk_image_layout_supports_input_attachment(VkImageLayout layout)
1168 {
1169 switch (layout) {
1170 case VK_IMAGE_LAYOUT_GENERAL:
1171 case VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL:
1172 case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL:
1173 case VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL:
1174 case VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL:
1175 case VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL:
1176 case VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL:
1177 case VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR:
1178 case VK_IMAGE_LAYOUT_ATTACHMENT_FEEDBACK_LOOP_OPTIMAL_EXT:
1179 return true;
1180 default:
1181 return false;
1182 }
1183 }
1184
1185 struct stage_access {
1186 VkPipelineStageFlagBits2 stages;
1187 VkAccessFlagBits2 access;
1188 };
1189
1190 static bool
vk_image_layout_are_all_aspects_read_only(VkImageLayout layout,VkImageAspectFlags aspects)1191 vk_image_layout_are_all_aspects_read_only(VkImageLayout layout,
1192 VkImageAspectFlags aspects)
1193 {
1194 u_foreach_bit(a, aspects) {
1195 VkImageAspectFlagBits aspect = 1u << a;
1196 if (!vk_image_layout_is_read_only(layout, aspect))
1197 return false;
1198 }
1199 return true;
1200 }
1201
1202 static struct stage_access
stage_access_for_layout(VkImageLayout layout,VkImageAspectFlags aspects)1203 stage_access_for_layout(VkImageLayout layout, VkImageAspectFlags aspects)
1204 {
1205 VkPipelineStageFlagBits2 stages = 0;
1206 VkAccessFlagBits2 access = 0;
1207
1208 if (vk_image_layout_supports_input_attachment(layout)) {
1209 stages |= VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT;
1210 access |= VK_ACCESS_2_INPUT_ATTACHMENT_READ_BIT;
1211 }
1212
1213 if (aspects & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) {
1214 stages |= VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT |
1215 VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT;
1216 access |= VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_READ_BIT;
1217 if (!vk_image_layout_are_all_aspects_read_only(layout, aspects)) {
1218 access |= VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
1219
1220 /* It might be a resolve attachment */
1221 stages |= VK_PIPELINE_STAGE_2_ALL_TRANSFER_BIT;
1222 access |= VK_ACCESS_2_TRANSFER_WRITE_BIT;
1223 }
1224 } else {
1225 /* Color */
1226 if (!vk_image_layout_are_all_aspects_read_only(layout, aspects)) {
1227 /* There are no read-only color attachments */
1228 stages |= VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
1229 access |= VK_ACCESS_2_COLOR_ATTACHMENT_READ_BIT |
1230 VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT;
1231
1232 /* It might be a resolve attachment */
1233 stages |= VK_PIPELINE_STAGE_2_ALL_TRANSFER_BIT;
1234 access |= VK_ACCESS_2_TRANSFER_WRITE_BIT;
1235 }
1236 }
1237
1238 return (struct stage_access) {
1239 .stages = stages,
1240 .access = access,
1241 };
1242 }
1243
1244 static void
transition_image_range(const struct vk_image_view * image_view,VkImageSubresourceRange range,VkImageLayout old_layout,VkImageLayout new_layout,VkImageLayout old_stencil_layout,VkImageLayout new_stencil_layout,const VkSampleLocationsInfoEXT * sample_locations,uint32_t * barrier_count,uint32_t max_barrier_count,VkImageMemoryBarrier2 * barriers)1245 transition_image_range(const struct vk_image_view *image_view,
1246 VkImageSubresourceRange range,
1247 VkImageLayout old_layout,
1248 VkImageLayout new_layout,
1249 VkImageLayout old_stencil_layout,
1250 VkImageLayout new_stencil_layout,
1251 const VkSampleLocationsInfoEXT *sample_locations,
1252 uint32_t *barrier_count,
1253 uint32_t max_barrier_count,
1254 VkImageMemoryBarrier2 *barriers)
1255 {
1256 VkImageAspectFlags aspects_left = range.aspectMask;
1257 while (aspects_left) {
1258 range.aspectMask = aspects_left;
1259
1260 /* If we have a depth/stencil image and one of the layouts doesn't match
1261 * between depth and stencil, we need two barriers. Restrict to depth
1262 * and we'll pick up stencil on the next iteration.
1263 */
1264 if (range.aspectMask == (VK_IMAGE_ASPECT_DEPTH_BIT |
1265 VK_IMAGE_ASPECT_STENCIL_BIT) &&
1266 (old_layout != old_stencil_layout ||
1267 new_layout != new_stencil_layout))
1268 range.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
1269
1270 if (range.aspectMask == VK_IMAGE_ASPECT_STENCIL_BIT) {
1271 /* We're down to a single aspect bit so this is going to be the last
1272 * iteration and it's fine to stomp the input variables here.
1273 */
1274 old_layout = old_stencil_layout;
1275 new_layout = new_stencil_layout;
1276 }
1277
1278 if (new_layout != old_layout) {
1279 /* We could go about carefully calculating every possible way the
1280 * attachment may have been used in the render pass or we can break
1281 * out the big hammer and throw in any stage and access flags
1282 * possible for the given layouts.
1283 */
1284 struct stage_access src_sa, dst_sa;
1285 src_sa = stage_access_for_layout(old_layout, range.aspectMask);
1286 dst_sa = stage_access_for_layout(new_layout, range.aspectMask);
1287
1288 assert(*barrier_count < max_barrier_count);
1289 barriers[(*barrier_count)++] = (VkImageMemoryBarrier2) {
1290 .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2,
1291 .pNext = sample_locations,
1292 .srcStageMask = src_sa.stages,
1293 .srcAccessMask = src_sa.access,
1294 .dstStageMask = dst_sa.stages,
1295 .dstAccessMask = dst_sa.access,
1296 .oldLayout = old_layout,
1297 .newLayout = new_layout,
1298 .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
1299 .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
1300 .image = vk_image_to_handle(image_view->image),
1301 .subresourceRange = range,
1302 };
1303 }
1304
1305 aspects_left &= ~range.aspectMask;
1306 }
1307 }
1308
1309 static bool
can_use_attachment_initial_layout(struct vk_command_buffer * cmd_buffer,uint32_t att_idx,uint32_t view_mask,VkImageLayout * layout_out,VkImageLayout * stencil_layout_out)1310 can_use_attachment_initial_layout(struct vk_command_buffer *cmd_buffer,
1311 uint32_t att_idx,
1312 uint32_t view_mask,
1313 VkImageLayout *layout_out,
1314 VkImageLayout *stencil_layout_out)
1315 {
1316 const struct vk_render_pass *pass = cmd_buffer->render_pass;
1317 const struct vk_framebuffer *framebuffer = cmd_buffer->framebuffer;
1318 const struct vk_render_pass_attachment *rp_att = &pass->attachments[att_idx];
1319 struct vk_attachment_state *att_state = &cmd_buffer->attachments[att_idx];
1320 const struct vk_image_view *image_view = att_state->image_view;
1321
1322 if ((rp_att->aspects & ~VK_IMAGE_ASPECT_STENCIL_BIT) &&
1323 rp_att->load_op != VK_ATTACHMENT_LOAD_OP_CLEAR)
1324 return false;
1325
1326 if ((rp_att->aspects & VK_IMAGE_ASPECT_STENCIL_BIT) &&
1327 rp_att->stencil_load_op != VK_ATTACHMENT_LOAD_OP_CLEAR)
1328 return false;
1329
1330 if (cmd_buffer->render_area.offset.x != 0 ||
1331 cmd_buffer->render_area.offset.y != 0 ||
1332 cmd_buffer->render_area.extent.width != image_view->extent.width ||
1333 cmd_buffer->render_area.extent.height != image_view->extent.height)
1334 return false;
1335
1336 if (image_view->image->image_type == VK_IMAGE_TYPE_3D) {
1337 /* For 3D images, the view has to be the whole thing */
1338 if (image_view->base_array_layer != 0)
1339 return false;
1340
1341 if (pass->is_multiview) {
1342 if (!util_is_power_of_two_or_zero(view_mask + 1) ||
1343 util_last_bit(view_mask) != image_view->layer_count)
1344 return false;
1345 } else {
1346 if (framebuffer->layers != image_view->layer_count)
1347 return false;
1348 }
1349 }
1350
1351 /* Finally, check if the entire thing is undefined. It's ok to smash the
1352 * view_mask now as the only thing using it will be the loop below.
1353 */
1354
1355 /* 3D is stupidly special. See transition_attachment() */
1356 if (image_view->image->image_type == VK_IMAGE_TYPE_3D)
1357 view_mask = 1;
1358
1359 VkImageLayout layout = VK_IMAGE_LAYOUT_MAX_ENUM;
1360 VkImageLayout stencil_layout = VK_IMAGE_LAYOUT_MAX_ENUM;
1361
1362 assert(view_mask != 0);
1363 u_foreach_bit(view, view_mask) {
1364 assert(view >= 0 && view < MESA_VK_MAX_MULTIVIEW_VIEW_COUNT);
1365 struct vk_attachment_view_state *att_view_state = &att_state->views[view];
1366
1367 if (rp_att->aspects & ~VK_IMAGE_ASPECT_STENCIL_BIT) {
1368 if (layout == VK_IMAGE_LAYOUT_MAX_ENUM)
1369 layout = att_view_state->layout;
1370 else if (layout != att_view_state->layout)
1371 return false;
1372 }
1373
1374 if (rp_att->aspects & VK_IMAGE_ASPECT_STENCIL_BIT) {
1375 if (stencil_layout == VK_IMAGE_LAYOUT_MAX_ENUM)
1376 stencil_layout = att_view_state->stencil_layout;
1377 else if (stencil_layout != att_view_state->stencil_layout)
1378 return false;
1379 }
1380 }
1381
1382 if (layout != VK_IMAGE_LAYOUT_MAX_ENUM)
1383 *layout_out = layout;
1384 else if (layout_out != NULL)
1385 *layout_out = VK_IMAGE_LAYOUT_UNDEFINED;
1386
1387 if (stencil_layout != VK_IMAGE_LAYOUT_MAX_ENUM)
1388 *stencil_layout_out = stencil_layout;
1389 else if (stencil_layout_out != NULL)
1390 *stencil_layout_out = VK_IMAGE_LAYOUT_UNDEFINED;
1391
1392 return true;
1393 }
1394
1395 uint32_t
vk_command_buffer_get_attachment_layout(const struct vk_command_buffer * cmd_buffer,const struct vk_image * image,VkImageLayout * out_layout,VkImageLayout * out_stencil_layout)1396 vk_command_buffer_get_attachment_layout(const struct vk_command_buffer *cmd_buffer,
1397 const struct vk_image *image,
1398 VkImageLayout *out_layout,
1399 VkImageLayout *out_stencil_layout)
1400 {
1401 const struct vk_render_pass *render_pass = cmd_buffer->render_pass;
1402 assert(render_pass != NULL);
1403
1404 const struct vk_subpass *subpass =
1405 &render_pass->subpasses[cmd_buffer->subpass_idx];
1406 int first_view = ffs(subpass->view_mask) - 1;
1407
1408 for (uint32_t a = 0; a < render_pass->attachment_count; a++) {
1409 if (cmd_buffer->attachments[a].image_view->image == image) {
1410 *out_layout = cmd_buffer->attachments[a].views[first_view].layout;
1411 *out_stencil_layout =
1412 cmd_buffer->attachments[a].views[first_view].stencil_layout;
1413 return a;
1414 }
1415 }
1416 unreachable("Image not found in attachments");
1417 }
1418
1419 void
vk_command_buffer_set_attachment_layout(struct vk_command_buffer * cmd_buffer,uint32_t att_idx,VkImageLayout layout,VkImageLayout stencil_layout)1420 vk_command_buffer_set_attachment_layout(struct vk_command_buffer *cmd_buffer,
1421 uint32_t att_idx,
1422 VkImageLayout layout,
1423 VkImageLayout stencil_layout)
1424 {
1425 const struct vk_render_pass *render_pass = cmd_buffer->render_pass;
1426 const struct vk_subpass *subpass =
1427 &render_pass->subpasses[cmd_buffer->subpass_idx];
1428 uint32_t view_mask = subpass->view_mask;
1429 struct vk_attachment_state *att_state = &cmd_buffer->attachments[att_idx];
1430
1431 u_foreach_bit(view, view_mask) {
1432 assert(view >= 0 && view < MESA_VK_MAX_MULTIVIEW_VIEW_COUNT);
1433 struct vk_attachment_view_state *att_view_state = &att_state->views[view];
1434
1435 att_view_state->layout = layout;
1436 att_view_state->stencil_layout = stencil_layout;
1437 }
1438 }
1439
1440 static void
transition_attachment(struct vk_command_buffer * cmd_buffer,uint32_t att_idx,uint32_t view_mask,VkImageLayout layout,VkImageLayout stencil_layout,uint32_t * barrier_count,uint32_t max_barrier_count,VkImageMemoryBarrier2 * barriers)1441 transition_attachment(struct vk_command_buffer *cmd_buffer,
1442 uint32_t att_idx,
1443 uint32_t view_mask,
1444 VkImageLayout layout,
1445 VkImageLayout stencil_layout,
1446 uint32_t *barrier_count,
1447 uint32_t max_barrier_count,
1448 VkImageMemoryBarrier2 *barriers)
1449 {
1450 const struct vk_render_pass *pass = cmd_buffer->render_pass;
1451 const struct vk_framebuffer *framebuffer = cmd_buffer->framebuffer;
1452 const struct vk_render_pass_attachment *pass_att =
1453 &pass->attachments[att_idx];
1454 struct vk_attachment_state *att_state = &cmd_buffer->attachments[att_idx];
1455 const struct vk_image_view *image_view = att_state->image_view;
1456
1457 /* 3D is stupidly special. From the Vulkan 1.3.204 spec:
1458 *
1459 * "When the VkImageSubresourceRange structure is used to select a
1460 * subset of the slices of a 3D image’s mip level in order to create
1461 * a 2D or 2D array image view of a 3D image created with
1462 * VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT, baseArrayLayer and
1463 * layerCount specify the first slice index and the number of slices
1464 * to include in the created image view. Such an image view can be
1465 * used as a framebuffer attachment that refers only to the specified
1466 * range of slices of the selected mip level. However, any layout
1467 * transitions performed on such an attachment view during a render
1468 * pass instance still apply to the entire subresource referenced
1469 * which includes all the slices of the selected mip level."
1470 *
1471 * To deal with this, we expand out the layer range to include the
1472 * entire 3D image and treat them as having only a single view even when
1473 * multiview is enabled. This later part means that we effectively only
1474 * track one image layout for the entire attachment rather than one per
1475 * view like we do for all the others.
1476 */
1477 if (image_view->image->image_type == VK_IMAGE_TYPE_3D)
1478 view_mask = 1;
1479
1480 u_foreach_bit(view, view_mask) {
1481 assert(view >= 0 && view < MESA_VK_MAX_MULTIVIEW_VIEW_COUNT);
1482 struct vk_attachment_view_state *att_view_state = &att_state->views[view];
1483
1484 /* First, check to see if we even need a transition */
1485 if (att_view_state->layout == layout &&
1486 att_view_state->stencil_layout == stencil_layout)
1487 continue;
1488
1489 VkImageSubresourceRange range = {
1490 .aspectMask = pass_att->aspects,
1491 .baseMipLevel = image_view->base_mip_level,
1492 .levelCount = 1,
1493 };
1494
1495 /* From the Vulkan 1.3.207 spec:
1496 *
1497 * "Automatic layout transitions apply to the entire image
1498 * subresource attached to the framebuffer. If multiview is not
1499 * enabled and the attachment is a view of a 1D or 2D image, the
1500 * automatic layout transitions apply to the number of layers
1501 * specified by VkFramebufferCreateInfo::layers. If multiview is
1502 * enabled and the attachment is a view of a 1D or 2D image, the
1503 * automatic layout transitions apply to the layers corresponding to
1504 * views which are used by some subpass in the render pass, even if
1505 * that subpass does not reference the given attachment. If the
1506 * attachment view is a 2D or 2D array view of a 3D image, even if
1507 * the attachment view only refers to a subset of the slices of the
1508 * selected mip level of the 3D image, automatic layout transitions
1509 * apply to the entire subresource referenced which is the entire mip
1510 * level in this case."
1511 */
1512 if (image_view->image->image_type == VK_IMAGE_TYPE_3D) {
1513 assert(view == 0);
1514 range.baseArrayLayer = 0;
1515 range.layerCount = image_view->extent.depth;
1516 } else if (pass->is_multiview) {
1517 range.baseArrayLayer = image_view->base_array_layer + view;
1518 range.layerCount = 1;
1519 } else {
1520 assert(view == 0);
1521 range.baseArrayLayer = image_view->base_array_layer;
1522 range.layerCount = framebuffer->layers;
1523 }
1524
1525 transition_image_range(image_view, range,
1526 att_view_state->layout, layout,
1527 att_view_state->stencil_layout, stencil_layout,
1528 att_view_state->sample_locations,
1529 barrier_count, max_barrier_count, barriers);
1530
1531 att_view_state->layout = layout;
1532 att_view_state->stencil_layout = stencil_layout;
1533 }
1534 }
1535
1536 static void
load_attachment(struct vk_command_buffer * cmd_buffer,uint32_t att_idx,uint32_t view_mask,VkImageLayout layout,VkImageLayout stencil_layout)1537 load_attachment(struct vk_command_buffer *cmd_buffer,
1538 uint32_t att_idx, uint32_t view_mask,
1539 VkImageLayout layout, VkImageLayout stencil_layout)
1540 {
1541 const struct vk_render_pass *pass = cmd_buffer->render_pass;
1542 const struct vk_framebuffer *framebuffer = cmd_buffer->framebuffer;
1543 const struct vk_render_pass_attachment *rp_att = &pass->attachments[att_idx];
1544 struct vk_attachment_state *att_state = &cmd_buffer->attachments[att_idx];
1545 struct vk_device_dispatch_table *disp =
1546 &cmd_buffer->base.device->dispatch_table;
1547
1548 /* Don't load any views we've already loaded */
1549 view_mask &= ~att_state->views_loaded;
1550 if (view_mask == 0)
1551 return;
1552
1553 /* From here on, if we return, we loaded the views */
1554 att_state->views_loaded |= view_mask;
1555
1556 /* We only need to load/store if there's a clear */
1557 bool need_load_store = false;
1558 if ((rp_att->aspects & ~VK_IMAGE_ASPECT_STENCIL_BIT) &&
1559 rp_att->load_op == VK_ATTACHMENT_LOAD_OP_CLEAR)
1560 need_load_store = true;
1561
1562 if ((rp_att->aspects & VK_IMAGE_ASPECT_STENCIL_BIT) &&
1563 rp_att->stencil_load_op == VK_ATTACHMENT_LOAD_OP_CLEAR)
1564 need_load_store = true;
1565
1566 if (!need_load_store)
1567 return;
1568
1569 const VkRenderingAttachmentInfo att = {
1570 .sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO,
1571 .imageView = vk_image_view_to_handle(att_state->image_view),
1572 .imageLayout = layout,
1573 .loadOp = rp_att->load_op,
1574 .storeOp = VK_ATTACHMENT_STORE_OP_STORE,
1575 .clearValue = att_state->clear_value,
1576 };
1577
1578 const VkRenderingAttachmentInfo stencil_att = {
1579 .sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO,
1580 .imageView = vk_image_view_to_handle(att_state->image_view),
1581 .imageLayout = stencil_layout,
1582 .loadOp = rp_att->stencil_load_op,
1583 .storeOp = VK_ATTACHMENT_STORE_OP_STORE,
1584 .clearValue = att_state->clear_value,
1585 };
1586
1587 VkRenderingInfo render = {
1588 .sType = VK_STRUCTURE_TYPE_RENDERING_INFO,
1589 .renderArea = cmd_buffer->render_area,
1590 .layerCount = pass->is_multiview ? 1 : framebuffer->layers,
1591 .viewMask = pass->is_multiview ? view_mask : 0,
1592 };
1593
1594 if (rp_att->aspects & (VK_IMAGE_ASPECT_DEPTH_BIT |
1595 VK_IMAGE_ASPECT_STENCIL_BIT)) {
1596 if (rp_att->aspects & VK_IMAGE_ASPECT_DEPTH_BIT)
1597 render.pDepthAttachment = &att;
1598 if (rp_att->aspects & VK_IMAGE_ASPECT_STENCIL_BIT)
1599 render.pStencilAttachment = &stencil_att;
1600 } else {
1601 render.colorAttachmentCount = 1;
1602 render.pColorAttachments = &att;
1603 }
1604
1605 disp->CmdBeginRendering(vk_command_buffer_to_handle(cmd_buffer), &render);
1606 disp->CmdEndRendering(vk_command_buffer_to_handle(cmd_buffer));
1607 }
1608
1609 static void
begin_subpass(struct vk_command_buffer * cmd_buffer,const VkSubpassBeginInfo * begin_info)1610 begin_subpass(struct vk_command_buffer *cmd_buffer,
1611 const VkSubpassBeginInfo *begin_info)
1612 {
1613 const struct vk_render_pass *pass = cmd_buffer->render_pass;
1614 const struct vk_framebuffer *framebuffer = cmd_buffer->framebuffer;
1615 const uint32_t subpass_idx = cmd_buffer->subpass_idx;
1616 assert(subpass_idx < pass->subpass_count);
1617 const struct vk_subpass *subpass = &pass->subpasses[subpass_idx];
1618 struct vk_device_dispatch_table *disp =
1619 &cmd_buffer->base.device->dispatch_table;
1620
1621 /* First, we figure out all our attachments and attempt to handle image
1622 * layout transitions and load ops as part of vkCmdBeginRendering if we
1623 * can. For any we can't handle this way, we'll need explicit barriers
1624 * or quick vkCmdBegin/EndRendering to do the load op.
1625 */
1626
1627 STACK_ARRAY(VkRenderingAttachmentInfo, color_attachments,
1628 subpass->color_count);
1629 STACK_ARRAY(VkRenderingAttachmentInitialLayoutInfoMESA,
1630 color_attachment_initial_layouts,
1631 subpass->color_count);
1632
1633 for (uint32_t i = 0; i < subpass->color_count; i++) {
1634 const struct vk_subpass_attachment *sp_att =
1635 &subpass->color_attachments[i];
1636 VkRenderingAttachmentInfo *color_attachment = &color_attachments[i];
1637
1638 if (sp_att->attachment == VK_ATTACHMENT_UNUSED) {
1639 *color_attachment = (VkRenderingAttachmentInfo) {
1640 .sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO,
1641 .imageView = VK_NULL_HANDLE,
1642 };
1643 continue;
1644 }
1645
1646 assert(sp_att->attachment < pass->attachment_count);
1647 const struct vk_render_pass_attachment *rp_att =
1648 &pass->attachments[sp_att->attachment];
1649 struct vk_attachment_state *att_state =
1650 &cmd_buffer->attachments[sp_att->attachment];
1651
1652 *color_attachment = (VkRenderingAttachmentInfo) {
1653 .sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO,
1654 .imageView = vk_image_view_to_handle(att_state->image_view),
1655 .imageLayout = sp_att->layout,
1656 };
1657
1658 if (!(subpass->view_mask & att_state->views_loaded)) {
1659 /* None of these views have been used before */
1660 color_attachment->loadOp = rp_att->load_op;
1661 color_attachment->clearValue = att_state->clear_value;
1662 att_state->views_loaded |= subpass->view_mask;
1663
1664 VkImageLayout initial_layout;
1665 if (can_use_attachment_initial_layout(cmd_buffer,
1666 sp_att->attachment,
1667 subpass->view_mask,
1668 &initial_layout, NULL) &&
1669 sp_att->layout != initial_layout) {
1670 assert(color_attachment->loadOp == VK_ATTACHMENT_LOAD_OP_CLEAR);
1671
1672 VkRenderingAttachmentInitialLayoutInfoMESA *color_initial_layout =
1673 &color_attachment_initial_layouts[i];
1674 *color_initial_layout = (VkRenderingAttachmentInitialLayoutInfoMESA) {
1675 .sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INITIAL_LAYOUT_INFO_MESA,
1676 .initialLayout = initial_layout,
1677 };
1678 __vk_append_struct(color_attachment, color_initial_layout);
1679
1680 vk_command_buffer_set_attachment_layout(cmd_buffer,
1681 sp_att->attachment,
1682 sp_att->layout,
1683 VK_IMAGE_LAYOUT_UNDEFINED);
1684 }
1685 } else {
1686 /* We've seen at least one of the views of this attachment before so
1687 * we need to LOAD_OP_LOAD.
1688 */
1689 color_attachment->loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
1690 }
1691
1692 if (!(subpass->view_mask & ~sp_att->last_subpass)) {
1693 /* This is the last subpass for every view */
1694 color_attachment->storeOp = rp_att->store_op;
1695 } else {
1696 /* For at least one of our views, this isn't the last subpass
1697 *
1698 * In the edge case where we have lots of weird overlap between view
1699 * masks of different subThis may mean that we get STORE_OP_STORE in
1700 * some places where it may have wanted STORE_OP_NONE but that should
1701 * be harmless.
1702 */
1703 color_attachment->storeOp = VK_ATTACHMENT_STORE_OP_STORE;
1704 }
1705
1706 if (sp_att->resolve != NULL) {
1707 assert(sp_att->resolve->attachment < pass->attachment_count);
1708 struct vk_attachment_state *res_att_state =
1709 &cmd_buffer->attachments[sp_att->resolve->attachment];
1710
1711 /* Resolve attachments are entirely overwritten by the resolve
1712 * operation so the load op really doesn't matter. We can consider
1713 * the resolve as being the load.
1714 */
1715 res_att_state->views_loaded |= subpass->view_mask;
1716
1717 if (vk_format_is_int(res_att_state->image_view->format))
1718 color_attachment->resolveMode = VK_RESOLVE_MODE_SAMPLE_ZERO_BIT;
1719 else
1720 color_attachment->resolveMode = VK_RESOLVE_MODE_AVERAGE_BIT;
1721
1722 color_attachment->resolveImageView =
1723 vk_image_view_to_handle(res_att_state->image_view);
1724 color_attachment->resolveImageLayout = sp_att->resolve->layout;
1725 } else if (subpass->mrtss.multisampledRenderToSingleSampledEnable &&
1726 rp_att->samples == VK_SAMPLE_COUNT_1_BIT) {
1727 if (vk_format_is_int(att_state->image_view->format))
1728 color_attachment->resolveMode = VK_RESOLVE_MODE_SAMPLE_ZERO_BIT;
1729 else
1730 color_attachment->resolveMode = VK_RESOLVE_MODE_AVERAGE_BIT;
1731 }
1732 }
1733
1734 VkRenderingAttachmentInfo depth_attachment = {
1735 .sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO,
1736 };
1737 VkRenderingAttachmentInfo stencil_attachment = {
1738 .sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO,
1739 };
1740 VkRenderingAttachmentInitialLayoutInfoMESA depth_initial_layout = {
1741 .sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INITIAL_LAYOUT_INFO_MESA,
1742 };
1743 VkRenderingAttachmentInitialLayoutInfoMESA stencil_initial_layout = {
1744 .sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INITIAL_LAYOUT_INFO_MESA,
1745 };
1746
1747 const VkSampleLocationsInfoEXT *sample_locations = NULL;
1748 if (subpass->depth_stencil_attachment != NULL) {
1749 const struct vk_subpass_attachment *sp_att =
1750 subpass->depth_stencil_attachment;
1751
1752 assert(sp_att->attachment < pass->attachment_count);
1753 const struct vk_render_pass_attachment *rp_att =
1754 &pass->attachments[sp_att->attachment];
1755 struct vk_attachment_state *att_state =
1756 &cmd_buffer->attachments[sp_att->attachment];
1757
1758 assert(sp_att->aspects == rp_att->aspects);
1759 if (rp_att->aspects & VK_IMAGE_ASPECT_DEPTH_BIT) {
1760 depth_attachment.imageView =
1761 vk_image_view_to_handle(att_state->image_view);
1762 depth_attachment.imageLayout = sp_att->layout;
1763 }
1764
1765 if (rp_att->aspects & VK_IMAGE_ASPECT_STENCIL_BIT) {
1766 stencil_attachment.imageView =
1767 vk_image_view_to_handle(att_state->image_view);
1768 stencil_attachment.imageLayout = sp_att->stencil_layout;
1769 }
1770
1771 if (!(subpass->view_mask & att_state->views_loaded)) {
1772 /* None of these views have been used before */
1773 depth_attachment.loadOp = rp_att->load_op;
1774 depth_attachment.clearValue = att_state->clear_value;
1775 stencil_attachment.loadOp = rp_att->stencil_load_op;
1776 stencil_attachment.clearValue = att_state->clear_value;
1777 att_state->views_loaded |= subpass->view_mask;
1778
1779 VkImageLayout initial_layout, initial_stencil_layout;
1780 if (can_use_attachment_initial_layout(cmd_buffer,
1781 sp_att->attachment,
1782 subpass->view_mask,
1783 &initial_layout,
1784 &initial_stencil_layout)) {
1785 if ((rp_att->aspects & VK_IMAGE_ASPECT_DEPTH_BIT) &&
1786 sp_att->layout != initial_layout) {
1787 assert(depth_attachment.loadOp == VK_ATTACHMENT_LOAD_OP_CLEAR);
1788 depth_initial_layout.initialLayout = initial_layout;
1789 __vk_append_struct(&depth_attachment,
1790 &depth_initial_layout);
1791 }
1792
1793 if ((rp_att->aspects & VK_IMAGE_ASPECT_STENCIL_BIT) &&
1794 sp_att->stencil_layout != initial_stencil_layout) {
1795 assert(stencil_attachment.loadOp == VK_ATTACHMENT_LOAD_OP_CLEAR);
1796 stencil_initial_layout.initialLayout = initial_stencil_layout;
1797 __vk_append_struct(&stencil_attachment,
1798 &stencil_initial_layout);
1799 }
1800
1801 vk_command_buffer_set_attachment_layout(cmd_buffer,
1802 sp_att->attachment,
1803 sp_att->layout,
1804 sp_att->stencil_layout);
1805 }
1806 } else {
1807 /* We've seen at least one of the views of this attachment before so
1808 * we need to LOAD_OP_LOAD.
1809 */
1810 depth_attachment.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
1811 stencil_attachment.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
1812 }
1813
1814 if (!(subpass->view_mask & ~sp_att->last_subpass)) {
1815 /* This is the last subpass for every view */
1816 depth_attachment.storeOp = rp_att->store_op;
1817 stencil_attachment.storeOp = rp_att->stencil_store_op;
1818 } else {
1819 /* For at least one of our views, this isn't the last subpass
1820 *
1821 * In the edge case where we have lots of weird overlap between view
1822 * masks of different subThis may mean that we get STORE_OP_STORE in
1823 * some places where it may have wanted STORE_OP_NONE but that should
1824 * be harmless.
1825 */
1826 depth_attachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
1827 stencil_attachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
1828 }
1829
1830 /* From the Vulkan 1.3.212 spec:
1831 *
1832 * "If the current render pass does not use the attachment as a
1833 * depth/stencil attachment in any subpass that happens-before, the
1834 * automatic layout transition uses the sample locations state
1835 * specified in the sampleLocationsInfo member of the element of the
1836 * VkRenderPassSampleLocationsBeginInfoEXT::pAttachmentInitialSampleLocations
1837 * array for which the attachmentIndex member equals the attachment
1838 * index of the attachment, if one is specified. Otherwise, the
1839 * automatic layout transition uses the sample locations state
1840 * specified in the sampleLocationsInfo member of the element of the
1841 * VkRenderPassSampleLocationsBeginInfoEXT::pPostSubpassSampleLocations
1842 * array for which the subpassIndex member equals the index of the
1843 * subpass that last used the attachment as a depth/stencil
1844 * attachment, if one is specified."
1845 *
1846 * Unfortunately, this says nothing whatsoever about multiview.
1847 * However, since multiview render passes are described as a single-view
1848 * render pass repeated per-view, we assume this is per-view.
1849 */
1850 if (cmd_buffer->pass_sample_locations != NULL &&
1851 (att_state->image_view->image->create_flags &
1852 VK_IMAGE_CREATE_SAMPLE_LOCATIONS_COMPATIBLE_DEPTH_BIT_EXT)) {
1853 sample_locations =
1854 get_subpass_sample_locations(cmd_buffer->pass_sample_locations,
1855 subpass_idx);
1856
1857 u_foreach_bit(view, subpass->view_mask)
1858 att_state->views[view].sample_locations = sample_locations;
1859 }
1860
1861 if (sp_att->resolve != NULL ||
1862 (subpass->mrtss.multisampledRenderToSingleSampledEnable &&
1863 rp_att->samples == VK_SAMPLE_COUNT_1_BIT)) {
1864 const struct vk_subpass_attachment *res_sp_att = sp_att->resolve ? sp_att->resolve : sp_att;
1865 assert(res_sp_att->attachment < pass->attachment_count);
1866 const struct vk_render_pass_attachment *res_rp_att =
1867 &pass->attachments[res_sp_att->attachment];
1868 struct vk_attachment_state *res_att_state =
1869 &cmd_buffer->attachments[res_sp_att->attachment];
1870
1871 /* From the Vulkan 1.3.204 spec:
1872 *
1873 * "VkSubpassDescriptionDepthStencilResolve::depthResolveMode is
1874 * ignored if the VkFormat of the pDepthStencilResolveAttachment
1875 * does not have a depth component. Similarly,
1876 * VkSubpassDescriptionDepthStencilResolve::stencilResolveMode is
1877 * ignored if the VkFormat of the pDepthStencilResolveAttachment
1878 * does not have a stencil component."
1879 *
1880 * TODO: Should we handle this here or when we create the render
1881 * pass? Handling it here makes load ops "correct" in the sense
1882 * that, if we resolve to the wrong aspect, we will still consider
1883 * it bound and clear it if requested.
1884 */
1885 VkResolveModeFlagBits depth_resolve_mode = VK_RESOLVE_MODE_NONE;
1886 if (res_rp_att->aspects & VK_IMAGE_ASPECT_DEPTH_BIT)
1887 depth_resolve_mode = subpass->depth_resolve_mode;
1888
1889 VkResolveModeFlagBits stencil_resolve_mode = VK_RESOLVE_MODE_NONE;
1890 if (res_rp_att->aspects & VK_IMAGE_ASPECT_STENCIL_BIT)
1891 stencil_resolve_mode = subpass->stencil_resolve_mode;
1892
1893 VkImageAspectFlags resolved_aspects = 0;
1894
1895 if (depth_resolve_mode != VK_RESOLVE_MODE_NONE) {
1896 depth_attachment.resolveMode = depth_resolve_mode;
1897 if (sp_att->resolve) {
1898 depth_attachment.resolveImageView =
1899 vk_image_view_to_handle(res_att_state->image_view);
1900 depth_attachment.resolveImageLayout =
1901 sp_att->resolve->layout;
1902 }
1903
1904 resolved_aspects |= VK_IMAGE_ASPECT_DEPTH_BIT;
1905 }
1906
1907 if (stencil_resolve_mode != VK_RESOLVE_MODE_NONE) {
1908 stencil_attachment.resolveMode = stencil_resolve_mode;
1909 if (sp_att->resolve) {
1910 stencil_attachment.resolveImageView =
1911 vk_image_view_to_handle(res_att_state->image_view);
1912 stencil_attachment.resolveImageLayout =
1913 sp_att->resolve->stencil_layout;
1914 }
1915
1916 resolved_aspects |= VK_IMAGE_ASPECT_STENCIL_BIT;
1917 }
1918
1919 if (sp_att->resolve && resolved_aspects == rp_att->aspects) {
1920 /* The resolve attachment is entirely overwritten by the
1921 * resolve operation so the load op really doesn't matter.
1922 * We can consider the resolve as being the load.
1923 */
1924 res_att_state->views_loaded |= subpass->view_mask;
1925 }
1926 }
1927 }
1928
1929 /* Next, handle any barriers we need. This may include a general
1930 * VkMemoryBarrier for subpass dependencies and it may include some
1931 * number of VkImageMemoryBarriers for layout transitions.
1932 */
1933
1934 bool needs_mem_barrier = false;
1935 VkMemoryBarrier2 mem_barrier = {
1936 .sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER_2,
1937 };
1938 for (uint32_t d = 0; d < pass->dependency_count; d++) {
1939 const struct vk_subpass_dependency *dep = &pass->dependencies[d];
1940 if (dep->dst_subpass != subpass_idx)
1941 continue;
1942
1943 if (dep->flags & VK_DEPENDENCY_VIEW_LOCAL_BIT) {
1944 /* From the Vulkan 1.3.204 spec:
1945 *
1946 * VUID-VkSubpassDependency2-dependencyFlags-03091
1947 *
1948 * "If dependencyFlags includes VK_DEPENDENCY_VIEW_LOCAL_BIT,
1949 * dstSubpass must not be equal to VK_SUBPASS_EXTERNAL"
1950 */
1951 assert(dep->src_subpass != VK_SUBPASS_EXTERNAL);
1952
1953 assert(dep->src_subpass < pass->subpass_count);
1954 const struct vk_subpass *src_subpass =
1955 &pass->subpasses[dep->src_subpass];
1956
1957 /* Figure out the set of views in the source subpass affected by this
1958 * dependency.
1959 */
1960 uint32_t src_dep_view_mask = subpass->view_mask;
1961 if (dep->view_offset >= 0)
1962 src_dep_view_mask <<= dep->view_offset;
1963 else
1964 src_dep_view_mask >>= -dep->view_offset;
1965
1966 /* From the Vulkan 1.3.204 spec:
1967 *
1968 * "If the dependency is view-local, then each view (dstView) in
1969 * the destination subpass depends on the view dstView +
1970 * pViewOffsets[dependency] in the source subpass. If there is not
1971 * such a view in the source subpass, then this dependency does
1972 * not affect that view in the destination subpass."
1973 */
1974 if (!(src_subpass->view_mask & src_dep_view_mask))
1975 continue;
1976 }
1977
1978 needs_mem_barrier = true;
1979 mem_barrier.srcStageMask |= dep->src_stage_mask;
1980 mem_barrier.srcAccessMask |= dep->src_access_mask;
1981 mem_barrier.dstStageMask |= dep->dst_stage_mask;
1982 mem_barrier.dstAccessMask |= dep->dst_access_mask;
1983 }
1984
1985 if (subpass_idx == 0) {
1986 /* From the Vulkan 1.3.232 spec:
1987 *
1988 * "If there is no subpass dependency from VK_SUBPASS_EXTERNAL to the
1989 * first subpass that uses an attachment, then an implicit subpass
1990 * dependency exists from VK_SUBPASS_EXTERNAL to the first subpass it
1991 * is used in. The implicit subpass dependency only exists if there
1992 * exists an automatic layout transition away from initialLayout. The
1993 * subpass dependency operates as if defined with the following
1994 * parameters:
1995 *
1996 * VkSubpassDependency implicitDependency = {
1997 * .srcSubpass = VK_SUBPASS_EXTERNAL;
1998 * .dstSubpass = firstSubpass; // First subpass attachment is used in
1999 * .srcStageMask = VK_PIPELINE_STAGE_NONE;
2000 * .dstStageMask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
2001 * .srcAccessMask = 0;
2002 * .dstAccessMask = VK_ACCESS_INPUT_ATTACHMENT_READ_BIT |
2003 * VK_ACCESS_COLOR_ATTACHMENT_READ_BIT |
2004 * VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT |
2005 * VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT |
2006 * VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
2007 * .dependencyFlags = 0;
2008 * };"
2009 *
2010 * We could track individual subpasses and attachments and views to make
2011 * sure we only insert this barrier when it's absolutely necessary.
2012 * However, this is only going to happen for the first subpass and
2013 * you're probably going to take a stall in BeginRenderPass() anyway.
2014 * If this is ever a perf problem, we can re-evaluate and do something
2015 * more intellegent at that time.
2016 */
2017 needs_mem_barrier = true;
2018 mem_barrier.dstStageMask |= VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
2019 mem_barrier.dstAccessMask |= VK_ACCESS_INPUT_ATTACHMENT_READ_BIT |
2020 VK_ACCESS_COLOR_ATTACHMENT_READ_BIT |
2021 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT |
2022 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT |
2023 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
2024 }
2025
2026 uint32_t max_image_barrier_count = 0;
2027 for (uint32_t a = 0; a < subpass->attachment_count; a++) {
2028 const struct vk_subpass_attachment *sp_att = &subpass->attachments[a];
2029 if (sp_att->attachment == VK_ATTACHMENT_UNUSED)
2030 continue;
2031
2032 assert(sp_att->attachment < pass->attachment_count);
2033 const struct vk_render_pass_attachment *rp_att =
2034 &pass->attachments[sp_att->attachment];
2035
2036 max_image_barrier_count += util_bitcount(subpass->view_mask) *
2037 util_bitcount(rp_att->aspects);
2038 }
2039 if (pass->fragment_density_map.attachment != VK_ATTACHMENT_UNUSED)
2040 max_image_barrier_count += util_bitcount(subpass->view_mask);
2041 STACK_ARRAY(VkImageMemoryBarrier2, image_barriers, max_image_barrier_count);
2042 uint32_t image_barrier_count = 0;
2043
2044 for (uint32_t a = 0; a < subpass->attachment_count; a++) {
2045 const struct vk_subpass_attachment *sp_att = &subpass->attachments[a];
2046 if (sp_att->attachment == VK_ATTACHMENT_UNUSED)
2047 continue;
2048
2049 /* If we're using an initial layout, the attachment will already be
2050 * marked as transitioned and this will be a no-op.
2051 */
2052 transition_attachment(cmd_buffer, sp_att->attachment,
2053 subpass->view_mask,
2054 sp_att->layout, sp_att->stencil_layout,
2055 &image_barrier_count,
2056 max_image_barrier_count,
2057 image_barriers);
2058 }
2059 if (pass->fragment_density_map.attachment != VK_ATTACHMENT_UNUSED) {
2060 transition_attachment(cmd_buffer, pass->fragment_density_map.attachment,
2061 subpass->view_mask,
2062 pass->fragment_density_map.layout,
2063 VK_IMAGE_LAYOUT_UNDEFINED,
2064 &image_barrier_count,
2065 max_image_barrier_count,
2066 image_barriers);
2067 }
2068 assert(image_barrier_count <= max_image_barrier_count);
2069
2070 if (needs_mem_barrier || image_barrier_count > 0) {
2071 const VkDependencyInfo dependency_info = {
2072 .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
2073 .dependencyFlags = 0,
2074 .memoryBarrierCount = needs_mem_barrier ? 1 : 0,
2075 .pMemoryBarriers = needs_mem_barrier ? &mem_barrier : NULL,
2076 .imageMemoryBarrierCount = image_barrier_count,
2077 .pImageMemoryBarriers = image_barrier_count > 0 ?
2078 image_barriers : NULL,
2079 };
2080 cmd_buffer->runtime_rp_barrier = true;
2081 disp->CmdPipelineBarrier2(vk_command_buffer_to_handle(cmd_buffer),
2082 &dependency_info);
2083 cmd_buffer->runtime_rp_barrier = false;
2084 }
2085
2086 STACK_ARRAY_FINISH(image_barriers);
2087
2088 /* Next, handle any VK_ATTACHMENT_LOAD_OP_CLEAR that we couldn't handle
2089 * directly by emitting a quick vkCmdBegin/EndRendering to do the load.
2090 */
2091 for (uint32_t a = 0; a < subpass->attachment_count; a++) {
2092 const struct vk_subpass_attachment *sp_att = &subpass->attachments[a];
2093 if (sp_att->attachment == VK_ATTACHMENT_UNUSED)
2094 continue;
2095
2096 load_attachment(cmd_buffer, sp_att->attachment, subpass->view_mask,
2097 sp_att->layout, sp_att->stencil_layout);
2098 }
2099
2100 /* TODO: Handle preserve attachments
2101 *
2102 * For immediate renderers, this isn't a big deal as LOAD_OP_LOAD and
2103 * STORE_OP_STORE are effectively free. However, before this gets used on
2104 * a tiling GPU, we should really hook up preserve attachments and use them
2105 * to determine when we can use LOAD/STORE_OP_DONT_CARE between subpasses.
2106 */
2107
2108 VkRenderingInfo rendering = {
2109 .sType = VK_STRUCTURE_TYPE_RENDERING_INFO,
2110 .renderArea = cmd_buffer->render_area,
2111 .layerCount = pass->is_multiview ? 1 : framebuffer->layers,
2112 .viewMask = pass->is_multiview ? subpass->view_mask : 0,
2113 .colorAttachmentCount = subpass->color_count,
2114 .pColorAttachments = color_attachments,
2115 .pDepthAttachment = &depth_attachment,
2116 .pStencilAttachment = &stencil_attachment,
2117 };
2118
2119 VkRenderingFragmentShadingRateAttachmentInfoKHR fsr_attachment;
2120 if (subpass->fragment_shading_rate_attachment) {
2121 const struct vk_subpass_attachment *sp_att =
2122 subpass->fragment_shading_rate_attachment;
2123
2124 assert(sp_att->attachment < pass->attachment_count);
2125 struct vk_attachment_state *att_state =
2126 &cmd_buffer->attachments[sp_att->attachment];
2127
2128 /* Fragment shading rate attachments have no loadOp (it's implicitly
2129 * LOAD_OP_LOAD) so we need to ensure the load op happens.
2130 */
2131 load_attachment(cmd_buffer, sp_att->attachment, subpass->view_mask,
2132 sp_att->layout, sp_att->stencil_layout);
2133
2134 fsr_attachment = (VkRenderingFragmentShadingRateAttachmentInfoKHR) {
2135 .sType = VK_STRUCTURE_TYPE_RENDERING_FRAGMENT_SHADING_RATE_ATTACHMENT_INFO_KHR,
2136 .imageView = vk_image_view_to_handle(att_state->image_view),
2137 .imageLayout = sp_att->layout,
2138 .shadingRateAttachmentTexelSize =
2139 subpass->fragment_shading_rate_attachment_texel_size,
2140 };
2141 __vk_append_struct(&rendering, &fsr_attachment);
2142 }
2143
2144 VkRenderingFragmentDensityMapAttachmentInfoEXT fdm_attachment;
2145 if (pass->fragment_density_map.attachment != VK_ATTACHMENT_UNUSED) {
2146 assert(pass->fragment_density_map.attachment < pass->attachment_count);
2147 struct vk_attachment_state *att_state =
2148 &cmd_buffer->attachments[pass->fragment_density_map.attachment];
2149
2150 /* From the Vulkan 1.3.125 spec:
2151 *
2152 * VUID-VkRenderPassFragmentDensityMapCreateInfoEXT-fragmentDensityMapAttachment-02550
2153 *
2154 * If fragmentDensityMapAttachment is not VK_ATTACHMENT_UNUSED,
2155 * fragmentDensityMapAttachment must reference an attachment with a
2156 * loadOp equal to VK_ATTACHMENT_LOAD_OP_LOAD or
2157 * VK_ATTACHMENT_LOAD_OP_DONT_CARE
2158 *
2159 * This means we don't have to implement the load op.
2160 */
2161
2162 fdm_attachment = (VkRenderingFragmentDensityMapAttachmentInfoEXT) {
2163 .sType = VK_STRUCTURE_TYPE_RENDERING_FRAGMENT_DENSITY_MAP_ATTACHMENT_INFO_EXT,
2164 .imageView = vk_image_view_to_handle(att_state->image_view),
2165 .imageLayout = pass->fragment_density_map.layout,
2166 };
2167 __vk_append_struct(&rendering, &fdm_attachment);
2168 }
2169
2170 VkSampleLocationsInfoEXT sample_locations_tmp;
2171 if (sample_locations) {
2172 sample_locations_tmp = *sample_locations;
2173 __vk_append_struct(&rendering, &sample_locations_tmp);
2174 }
2175
2176 /* Append this one last because it lives in the subpass and we don't want
2177 * to be changed by appending other structures later.
2178 */
2179 if (subpass->mrtss.multisampledRenderToSingleSampledEnable)
2180 __vk_append_struct(&rendering, (void *)&subpass->mrtss);
2181
2182 disp->CmdBeginRendering(vk_command_buffer_to_handle(cmd_buffer),
2183 &rendering);
2184
2185 STACK_ARRAY_FINISH(color_attachments);
2186 STACK_ARRAY_FINISH(color_attachment_initial_layouts);
2187 }
2188
2189 static void
end_subpass(struct vk_command_buffer * cmd_buffer,const VkSubpassEndInfo * end_info)2190 end_subpass(struct vk_command_buffer *cmd_buffer,
2191 const VkSubpassEndInfo *end_info)
2192 {
2193 const struct vk_render_pass *pass = cmd_buffer->render_pass;
2194 const uint32_t subpass_idx = cmd_buffer->subpass_idx;
2195 struct vk_device_dispatch_table *disp =
2196 &cmd_buffer->base.device->dispatch_table;
2197
2198 disp->CmdEndRendering(vk_command_buffer_to_handle(cmd_buffer));
2199
2200 bool needs_mem_barrier = false;
2201 VkMemoryBarrier2 mem_barrier = {
2202 .sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER_2,
2203 };
2204 for (uint32_t d = 0; d < pass->dependency_count; d++) {
2205 const struct vk_subpass_dependency *dep = &pass->dependencies[d];
2206 if (dep->src_subpass != subpass_idx)
2207 continue;
2208
2209 if (dep->dst_subpass != VK_SUBPASS_EXTERNAL)
2210 continue;
2211
2212 needs_mem_barrier = true;
2213 mem_barrier.srcStageMask |= dep->src_stage_mask;
2214 mem_barrier.srcAccessMask |= dep->src_access_mask;
2215 mem_barrier.dstStageMask |= dep->dst_stage_mask;
2216 mem_barrier.dstAccessMask |= dep->dst_access_mask;
2217 }
2218
2219 if (subpass_idx == pass->subpass_count - 1) {
2220 /* From the Vulkan 1.3.232 spec:
2221 *
2222 * "Similarly, if there is no subpass dependency from the last
2223 * subpass that uses an attachment to VK_SUBPASS_EXTERNAL, then an
2224 * implicit subpass dependency exists from the last subpass it is
2225 * used in to VK_SUBPASS_EXTERNAL. The implicit subpass dependency
2226 * only exists if there exists an automatic layout transition into
2227 * finalLayout. The subpass dependency operates as if defined with
2228 * the following parameters:
2229 *
2230 * VkSubpassDependency implicitDependency = {
2231 * .srcSubpass = lastSubpass; // Last subpass attachment is used in
2232 * .dstSubpass = VK_SUBPASS_EXTERNAL;
2233 * .srcStageMask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
2234 * .dstStageMask = VK_PIPELINE_STAGE_NONE;
2235 * .srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT |
2236 * VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
2237 * .dstAccessMask = 0;
2238 * .dependencyFlags = 0;
2239 * };"
2240 *
2241 * We could track individual subpasses and attachments and views to make
2242 * sure we only insert this barrier when it's absolutely necessary.
2243 * However, this is only going to happen for the last subpass and
2244 * you're probably going to take a stall in EndRenderPass() anyway.
2245 * If this is ever a perf problem, we can re-evaluate and do something
2246 * more intellegent at that time.
2247 */
2248 needs_mem_barrier = true;
2249 mem_barrier.srcStageMask |= VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
2250 mem_barrier.srcAccessMask |= VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT |
2251 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
2252 }
2253
2254 if (needs_mem_barrier) {
2255 const VkDependencyInfo dependency_info = {
2256 .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
2257 .dependencyFlags = 0,
2258 .memoryBarrierCount = 1,
2259 .pMemoryBarriers = &mem_barrier,
2260 };
2261 cmd_buffer->runtime_rp_barrier = true;
2262 disp->CmdPipelineBarrier2(vk_command_buffer_to_handle(cmd_buffer),
2263 &dependency_info);
2264 cmd_buffer->runtime_rp_barrier = false;
2265 }
2266 }
2267
2268 VKAPI_ATTR void VKAPI_CALL
vk_common_CmdBeginRenderPass2(VkCommandBuffer commandBuffer,const VkRenderPassBeginInfo * pRenderPassBeginInfo,const VkSubpassBeginInfo * pSubpassBeginInfo)2269 vk_common_CmdBeginRenderPass2(VkCommandBuffer commandBuffer,
2270 const VkRenderPassBeginInfo *pRenderPassBeginInfo,
2271 const VkSubpassBeginInfo *pSubpassBeginInfo)
2272 {
2273 VK_FROM_HANDLE(vk_command_buffer, cmd_buffer, commandBuffer);
2274 VK_FROM_HANDLE(vk_render_pass, pass, pRenderPassBeginInfo->renderPass);
2275 VK_FROM_HANDLE(vk_framebuffer, framebuffer,
2276 pRenderPassBeginInfo->framebuffer);
2277
2278 assert(cmd_buffer->render_pass == NULL);
2279 cmd_buffer->render_pass = pass;
2280 cmd_buffer->subpass_idx = 0;
2281
2282 assert(cmd_buffer->framebuffer == NULL);
2283 cmd_buffer->framebuffer = framebuffer;
2284
2285 cmd_buffer->render_area = pRenderPassBeginInfo->renderArea;
2286
2287 assert(cmd_buffer->attachments == NULL);
2288 if (pass->attachment_count > ARRAY_SIZE(cmd_buffer->_attachments)) {
2289 cmd_buffer->attachments = malloc(pass->attachment_count *
2290 sizeof(*cmd_buffer->attachments));
2291 } else {
2292 cmd_buffer->attachments = cmd_buffer->_attachments;
2293 }
2294
2295 const VkRenderPassAttachmentBeginInfo *attach_begin =
2296 vk_find_struct_const(pRenderPassBeginInfo,
2297 RENDER_PASS_ATTACHMENT_BEGIN_INFO);
2298 if (!attach_begin)
2299 assert(pass->attachment_count == framebuffer->attachment_count);
2300
2301 const VkImageView *image_views;
2302 if (attach_begin && attach_begin->attachmentCount != 0) {
2303 assert(attach_begin->attachmentCount == pass->attachment_count);
2304 image_views = attach_begin->pAttachments;
2305 } else {
2306 assert(framebuffer->attachment_count >= pass->attachment_count);
2307 image_views = framebuffer->attachments;
2308 }
2309
2310 for (uint32_t a = 0; a < pass->attachment_count; ++a) {
2311 VK_FROM_HANDLE(vk_image_view, image_view, image_views[a]);
2312 const struct vk_render_pass_attachment *pass_att = &pass->attachments[a];
2313 struct vk_attachment_state *att_state = &cmd_buffer->attachments[a];
2314
2315 /* From the Vulkan 1.3.204 spec:
2316 *
2317 * VUID-VkFramebufferCreateInfo-pAttachments-00880
2318 *
2319 * "If renderpass is not VK_NULL_HANDLE and flags does not include
2320 * VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT, each element of pAttachments
2321 * must have been created with a VkFormat value that matches the
2322 * VkFormat specified by the corresponding VkAttachmentDescription in
2323 * renderPass"
2324 *
2325 * and
2326 *
2327 * VUID-VkRenderPassBeginInfo-framebuffer-03216
2328 *
2329 * "If framebuffer was created with a VkFramebufferCreateInfo::flags
2330 * value that included VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT, each
2331 * element of the pAttachments member of a
2332 * VkRenderPassAttachmentBeginInfo structure included in the pNext
2333 * chain must be a VkImageView of an image created with a value of
2334 * VkImageViewCreateInfo::format equal to the corresponding value of
2335 * VkAttachmentDescription::format in renderPass"
2336 */
2337 assert(image_view->format == pass_att->format);
2338
2339 /* From the Vulkan 1.3.204 spec:
2340 *
2341 * VUID-VkFramebufferCreateInfo-pAttachments-00881
2342 *
2343 * "If renderpass is not VK_NULL_HANDLE and flags does not include
2344 * VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT, each element of pAttachments
2345 * must have been created with a samples value that matches the
2346 * samples value specified by the corresponding
2347 * VkAttachmentDescription in renderPass"
2348 *
2349 * and
2350 *
2351 * UID-VkRenderPassBeginInfo-framebuffer-03217
2352 *
2353 * "If framebuffer was created with a VkFramebufferCreateInfo::flags
2354 * value that included VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT, each
2355 * element of the pAttachments member of a
2356 * VkRenderPassAttachmentBeginInfo structure included in the pNext
2357 * chain must be a VkImageView of an image created with a value of
2358 * VkImageCreateInfo::samples equal to the corresponding value of
2359 * VkAttachmentDescription::samples in renderPass"
2360 */
2361 assert(image_view->image->samples == pass_att->samples);
2362
2363 /* From the Vulkan 1.3.204 spec:
2364 *
2365 * If multiview is enabled and the shading rate attachment has
2366 * multiple layers, the shading rate attachment texel is selected
2367 * from the layer determined by the ViewIndex built-in. If multiview
2368 * is disabled, and both the shading rate attachment and the
2369 * framebuffer have multiple layers, the shading rate attachment
2370 * texel is selected from the layer determined by the Layer built-in.
2371 * Otherwise, the texel is unconditionally selected from the first
2372 * layer of the attachment.
2373 */
2374 if (!(image_view->usage & VK_IMAGE_USAGE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR))
2375 assert(util_last_bit(pass_att->view_mask) <= image_view->layer_count);
2376
2377 *att_state = (struct vk_attachment_state) {
2378 .image_view = image_view,
2379 .views_loaded = 0,
2380 };
2381
2382 for (uint32_t v = 0; v < MESA_VK_MAX_MULTIVIEW_VIEW_COUNT; v++) {
2383 att_state->views[v] = (struct vk_attachment_view_state) {
2384 .layout = pass_att->initial_layout,
2385 .stencil_layout = pass_att->initial_stencil_layout,
2386 };
2387 }
2388
2389 if (a < pRenderPassBeginInfo->clearValueCount)
2390 att_state->clear_value = pRenderPassBeginInfo->pClearValues[a];
2391 }
2392
2393 const VkRenderPassSampleLocationsBeginInfoEXT *rp_sl_info =
2394 vk_find_struct_const(pRenderPassBeginInfo->pNext,
2395 RENDER_PASS_SAMPLE_LOCATIONS_BEGIN_INFO_EXT);
2396 if (rp_sl_info) {
2397 cmd_buffer->pass_sample_locations = clone_rp_sample_locations(rp_sl_info);
2398 assert(cmd_buffer->pass_sample_locations);
2399
2400 for (uint32_t i = 0; i < rp_sl_info->attachmentInitialSampleLocationsCount; i++) {
2401 const VkAttachmentSampleLocationsEXT *att_sl =
2402 &rp_sl_info->pAttachmentInitialSampleLocations[i];
2403
2404 assert(att_sl->attachmentIndex < pass->attachment_count);
2405 struct vk_attachment_state *att_state =
2406 &cmd_buffer->attachments[att_sl->attachmentIndex];
2407
2408 /* Sample locations only matter for depth/stencil images created with
2409 * VK_IMAGE_CREATE_SAMPLE_LOCATIONS_COMPATIBLE_DEPTH_BIT_EXT
2410 */
2411 if (vk_format_is_depth_or_stencil(att_state->image_view->format) &&
2412 (att_state->image_view->image->create_flags &
2413 VK_IMAGE_CREATE_SAMPLE_LOCATIONS_COMPATIBLE_DEPTH_BIT_EXT)) {
2414 for (uint32_t v = 0; v < MESA_VK_MAX_MULTIVIEW_VIEW_COUNT; v++)
2415 att_state->views[v].sample_locations = &att_sl->sampleLocationsInfo;
2416 }
2417 }
2418 }
2419
2420 begin_subpass(cmd_buffer, pSubpassBeginInfo);
2421 }
2422
2423 void
vk_command_buffer_reset_render_pass(struct vk_command_buffer * cmd_buffer)2424 vk_command_buffer_reset_render_pass(struct vk_command_buffer *cmd_buffer)
2425 {
2426 cmd_buffer->render_pass = NULL;
2427 cmd_buffer->subpass_idx = 0;
2428 cmd_buffer->framebuffer = NULL;
2429 if (cmd_buffer->attachments != cmd_buffer->_attachments)
2430 free(cmd_buffer->attachments);
2431 cmd_buffer->attachments = NULL;
2432 if (cmd_buffer->pass_sample_locations != NULL)
2433 vk_free(vk_default_allocator(), cmd_buffer->pass_sample_locations);
2434 cmd_buffer->pass_sample_locations = NULL;
2435 }
2436
2437 VKAPI_ATTR void VKAPI_CALL
vk_common_CmdNextSubpass2(VkCommandBuffer commandBuffer,const VkSubpassBeginInfo * pSubpassBeginInfo,const VkSubpassEndInfo * pSubpassEndInfo)2438 vk_common_CmdNextSubpass2(VkCommandBuffer commandBuffer,
2439 const VkSubpassBeginInfo *pSubpassBeginInfo,
2440 const VkSubpassEndInfo *pSubpassEndInfo)
2441 {
2442 VK_FROM_HANDLE(vk_command_buffer, cmd_buffer, commandBuffer);
2443
2444 end_subpass(cmd_buffer, pSubpassEndInfo);
2445 cmd_buffer->subpass_idx++;
2446 begin_subpass(cmd_buffer, pSubpassBeginInfo);
2447 }
2448
2449 VKAPI_ATTR void VKAPI_CALL
vk_common_CmdEndRenderPass2(VkCommandBuffer commandBuffer,const VkSubpassEndInfo * pSubpassEndInfo)2450 vk_common_CmdEndRenderPass2(VkCommandBuffer commandBuffer,
2451 const VkSubpassEndInfo *pSubpassEndInfo)
2452 {
2453 VK_FROM_HANDLE(vk_command_buffer, cmd_buffer, commandBuffer);
2454 const struct vk_render_pass *pass = cmd_buffer->render_pass;
2455 struct vk_device_dispatch_table *disp =
2456 &cmd_buffer->base.device->dispatch_table;
2457
2458 end_subpass(cmd_buffer, pSubpassEndInfo);
2459
2460 /* Make sure all our attachments end up in their finalLayout */
2461
2462 uint32_t max_image_barrier_count = 0;
2463 for (uint32_t a = 0; a < pass->attachment_count; a++) {
2464 const struct vk_render_pass_attachment *rp_att = &pass->attachments[a];
2465
2466 max_image_barrier_count += util_bitcount(pass->view_mask) *
2467 util_bitcount(rp_att->aspects);
2468 }
2469 STACK_ARRAY(VkImageMemoryBarrier2, image_barriers, max_image_barrier_count);
2470 uint32_t image_barrier_count = 0;
2471
2472 for (uint32_t a = 0; a < pass->attachment_count; a++) {
2473 const struct vk_render_pass_attachment *rp_att = &pass->attachments[a];
2474
2475 transition_attachment(cmd_buffer, a, pass->view_mask,
2476 rp_att->final_layout,
2477 rp_att->final_stencil_layout,
2478 &image_barrier_count,
2479 max_image_barrier_count,
2480 image_barriers);
2481 }
2482 assert(image_barrier_count <= max_image_barrier_count);
2483
2484 if (image_barrier_count > 0) {
2485 const VkDependencyInfo dependency_info = {
2486 .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
2487 .dependencyFlags = 0,
2488 .imageMemoryBarrierCount = image_barrier_count,
2489 .pImageMemoryBarriers = image_barriers,
2490 };
2491 cmd_buffer->runtime_rp_barrier = true;
2492 disp->CmdPipelineBarrier2(vk_command_buffer_to_handle(cmd_buffer),
2493 &dependency_info);
2494 cmd_buffer->runtime_rp_barrier = false;
2495 }
2496
2497 STACK_ARRAY_FINISH(image_barriers);
2498
2499 vk_command_buffer_reset_render_pass(cmd_buffer);
2500 }
2501