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