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