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