• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright © 2020 Valve Corporation
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21  * IN THE SOFTWARE.
22  */
23 
24 #include "vk_render_pass.h"
25 
26 #include "vk_alloc.h"
27 #include "vk_command_buffer.h"
28 #include "vk_common_entrypoints.h"
29 #include "vk_device.h"
30 #include "vk_format.h"
31 #include "vk_framebuffer.h"
32 #include "vk_image.h"
33 #include "vk_util.h"
34 
35 #include "util/log.h"
36 
37 static void
translate_references(VkAttachmentReference2 ** reference_ptr,uint32_t reference_count,const VkAttachmentReference * reference,const VkRenderPassCreateInfo * pass_info,bool is_input_attachment)38 translate_references(VkAttachmentReference2 **reference_ptr,
39                      uint32_t reference_count,
40                      const VkAttachmentReference *reference,
41                      const VkRenderPassCreateInfo *pass_info,
42                      bool is_input_attachment)
43 {
44    VkAttachmentReference2 *reference2 = *reference_ptr;
45    *reference_ptr += reference_count;
46    for (uint32_t i = 0; i < reference_count; i++) {
47       reference2[i] = (VkAttachmentReference2) {
48          .sType = VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2,
49          .pNext = NULL,
50          .attachment = reference[i].attachment,
51          .layout = reference[i].layout,
52       };
53 
54       if (is_input_attachment &&
55           reference2[i].attachment != VK_ATTACHMENT_UNUSED) {
56          assert(reference2[i].attachment < pass_info->attachmentCount);
57          const VkAttachmentDescription *att =
58             &pass_info->pAttachments[reference2[i].attachment];
59          reference2[i].aspectMask = vk_format_aspects(att->format);
60       }
61    }
62 }
63 
64 VKAPI_ATTR VkResult VKAPI_CALL
vk_common_CreateRenderPass(VkDevice _device,const VkRenderPassCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkRenderPass * pRenderPass)65 vk_common_CreateRenderPass(VkDevice _device,
66                            const VkRenderPassCreateInfo *pCreateInfo,
67                            const VkAllocationCallbacks *pAllocator,
68                            VkRenderPass *pRenderPass)
69 {
70    VK_FROM_HANDLE(vk_device, device, _device);
71 
72    uint32_t reference_count = 0;
73    for (uint32_t i = 0; i < pCreateInfo->subpassCount; i++) {
74       reference_count += pCreateInfo->pSubpasses[i].inputAttachmentCount;
75       reference_count += pCreateInfo->pSubpasses[i].colorAttachmentCount;
76       if (pCreateInfo->pSubpasses[i].pResolveAttachments)
77          reference_count += pCreateInfo->pSubpasses[i].colorAttachmentCount;
78       if (pCreateInfo->pSubpasses[i].pDepthStencilAttachment)
79          reference_count += 1;
80    }
81 
82    VK_MULTIALLOC(ma);
83    VK_MULTIALLOC_DECL(&ma, VkRenderPassCreateInfo2, create_info, 1);
84    VK_MULTIALLOC_DECL(&ma, VkSubpassDescription2, subpasses,
85                            pCreateInfo->subpassCount);
86    VK_MULTIALLOC_DECL(&ma, VkAttachmentDescription2, attachments,
87                            pCreateInfo->attachmentCount);
88    VK_MULTIALLOC_DECL(&ma, VkSubpassDependency2, dependencies,
89                            pCreateInfo->dependencyCount);
90    VK_MULTIALLOC_DECL(&ma, VkAttachmentReference2, references,
91                            reference_count);
92    if (!vk_multialloc_alloc2(&ma, &device->alloc, pAllocator,
93                              VK_SYSTEM_ALLOCATION_SCOPE_COMMAND))
94       return VK_ERROR_OUT_OF_HOST_MEMORY;
95 
96    VkAttachmentReference2 *reference_ptr = references;
97 
98    const VkRenderPassMultiviewCreateInfo *multiview_info = NULL;
99    const VkRenderPassInputAttachmentAspectCreateInfo *aspect_info = NULL;
100    vk_foreach_struct_const(ext, pCreateInfo->pNext) {
101       switch (ext->sType) {
102       case VK_STRUCTURE_TYPE_RENDER_PASS_INPUT_ATTACHMENT_ASPECT_CREATE_INFO:
103          aspect_info = (const VkRenderPassInputAttachmentAspectCreateInfo *)ext;
104          /* We don't care about this information */
105          break;
106 
107       case VK_STRUCTURE_TYPE_RENDER_PASS_MULTIVIEW_CREATE_INFO:
108          multiview_info = (const VkRenderPassMultiviewCreateInfo*) ext;
109          break;
110 
111       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 
242 VKAPI_ATTR void VKAPI_CALL
vk_common_CmdBeginRenderPass(VkCommandBuffer commandBuffer,const VkRenderPassBeginInfo * pRenderPassBegin,VkSubpassContents contents)243 vk_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 
261 VKAPI_ATTR void VKAPI_CALL
vk_common_CmdEndRenderPass(VkCommandBuffer commandBuffer)262 vk_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 
276 VKAPI_ATTR void VKAPI_CALL
vk_common_CmdNextSubpass(VkCommandBuffer commandBuffer,VkSubpassContents contents)277 vk_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 
298 static unsigned
num_subpass_attachments2(const VkSubpassDescription2 * desc)299 num_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 
329 static void
vk_render_pass_attachment_init(struct vk_render_pass_attachment * att,const VkAttachmentDescription2 * desc)330 vk_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 
349 static void
vk_subpass_attachment_init(struct vk_subpass_attachment * att,struct vk_render_pass * pass,uint32_t subpass_idx,const VkAttachmentReference2 * ref,const VkAttachmentDescription2 * attachments,VkImageUsageFlagBits usage)350 vk_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 
405 static void
vk_subpass_attachment_link_resolve(struct vk_subpass_attachment * att,struct vk_subpass_attachment * resolve,const VkRenderPassCreateInfo2 * info)406 vk_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 
417 VKAPI_ATTR VkResult VKAPI_CALL
vk_common_CreateRenderPass2(VkDevice _device,const VkRenderPassCreateInfo2 * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkRenderPass * pRenderPass)418 vk_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 
821 const VkPipelineRenderingCreateInfo *
vk_get_pipeline_rendering_create_info(const VkGraphicsPipelineCreateInfo * info)822 vk_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 
833 const VkAttachmentSampleCountInfoAMD *
vk_get_pipeline_sample_count_info_amd(const VkGraphicsPipelineCreateInfo * info)834 vk_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 
845 const VkCommandBufferInheritanceRenderingInfo *
vk_get_command_buffer_inheritance_rendering_info(VkCommandBufferLevel level,const VkCommandBufferBeginInfo * pBeginInfo)846 vk_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 
889 const VkRenderingInfo *
vk_get_command_buffer_inheritance_as_rendering_resume(VkCommandBufferLevel level,const VkCommandBufferBeginInfo * pBeginInfo,void * stack_data)890 vk_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 
1014 VKAPI_ATTR void VKAPI_CALL
vk_common_DestroyRenderPass(VkDevice _device,VkRenderPass renderPass,const VkAllocationCallbacks * pAllocator)1015 vk_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 
1028 VKAPI_ATTR void VKAPI_CALL
vk_common_GetRenderAreaGranularity(VkDevice device,VkRenderPass renderPass,VkExtent2D * pGranularity)1029 vk_common_GetRenderAreaGranularity(VkDevice device,
1030                                    VkRenderPass renderPass,
1031                                    VkExtent2D *pGranularity)
1032 {
1033    *pGranularity = (VkExtent2D) { 1, 1 };
1034 }
1035 
1036 static VkRenderPassSampleLocationsBeginInfoEXT *
clone_rp_sample_locations(const VkRenderPassSampleLocationsBeginInfoEXT * loc)1037 clone_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 
1121 static const VkSampleLocationsInfoEXT *
get_subpass_sample_locations(const VkRenderPassSampleLocationsBeginInfoEXT * loc,uint32_t subpass_idx)1122 get_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 
1133 static bool
vk_image_layout_supports_input_attachment(VkImageLayout layout)1134 vk_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 
1159 struct stage_access {
1160    VkPipelineStageFlagBits2 stages;
1161    VkAccessFlagBits2 access;
1162 };
1163 
1164 static bool
vk_image_layout_are_all_aspects_read_only(VkImageLayout layout,VkImageAspectFlags aspects)1165 vk_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 
1176 static struct stage_access
stage_access_for_layout(VkImageLayout layout,VkImageAspectFlags aspects)1177 stage_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 
1218 static void
transition_image_range(const struct vk_image_view * image_view,VkImageSubresourceRange range,VkImageLayout old_layout,VkImageLayout new_layout,VkImageLayout old_stencil_layout,VkImageLayout new_stencil_layout,const VkSampleLocationsInfoEXT * sample_locations,uint32_t * barrier_count,uint32_t max_barrier_count,VkImageMemoryBarrier2 * barriers)1219 transition_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 
1283 static bool
can_use_attachment_initial_layout(struct vk_command_buffer * cmd_buffer,uint32_t att_idx,uint32_t view_mask,VkImageLayout * layout_out,VkImageLayout * stencil_layout_out)1284 can_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 
1369 static void
set_attachment_layout(struct vk_command_buffer * cmd_buffer,uint32_t att_idx,uint32_t view_mask,VkImageLayout layout,VkImageLayout stencil_layout)1370 set_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 
1387 static void
transition_attachment(struct vk_command_buffer * cmd_buffer,uint32_t att_idx,uint32_t view_mask,VkImageLayout layout,VkImageLayout stencil_layout,uint32_t * barrier_count,uint32_t max_barrier_count,VkImageMemoryBarrier2 * barriers)1388 transition_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 
1483 static void
load_attachment(struct vk_command_buffer * cmd_buffer,uint32_t att_idx,uint32_t view_mask,VkImageLayout layout,VkImageLayout stencil_layout)1484 load_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 
1556 static void
begin_subpass(struct vk_command_buffer * cmd_buffer,const VkSubpassBeginInfo * begin_info)1557 begin_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 
2094 static void
end_subpass(struct vk_command_buffer * cmd_buffer,const VkSubpassEndInfo * end_info)2095 end_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 
2171 VKAPI_ATTR void VKAPI_CALL
vk_common_CmdBeginRenderPass2(VkCommandBuffer commandBuffer,const VkRenderPassBeginInfo * pRenderPassBeginInfo,const VkSubpassBeginInfo * pSubpassBeginInfo)2172 vk_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 
2326 void
vk_command_buffer_reset_render_pass(struct vk_command_buffer * cmd_buffer)2327 vk_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 
2340 VKAPI_ATTR void VKAPI_CALL
vk_common_CmdNextSubpass2(VkCommandBuffer commandBuffer,const VkSubpassBeginInfo * pSubpassBeginInfo,const VkSubpassEndInfo * pSubpassEndInfo)2341 vk_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 
2352 VKAPI_ATTR void VKAPI_CALL
vk_common_CmdEndRenderPass2(VkCommandBuffer commandBuffer,const VkSubpassEndInfo * pSubpassEndInfo)2353 vk_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