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