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