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