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