1 /*
2  * Copyright © 2015 Intel Corporation
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21  * IN THE SOFTWARE.
22  */
23 
24 #include "anv_private.h"
25 
26 #include "vk_util.h"
27 
28 static void
anv_render_pass_add_subpass_dep(struct anv_render_pass * pass,const VkSubpassDependency2KHR * dep)29 anv_render_pass_add_subpass_dep(struct anv_render_pass *pass,
30                                 const VkSubpassDependency2KHR *dep)
31 {
32    if (dep->dstSubpass == VK_SUBPASS_EXTERNAL) {
33       pass->subpass_flushes[pass->subpass_count] |=
34          anv_pipe_invalidate_bits_for_access_flags(dep->dstAccessMask);
35    } else {
36       assert(dep->dstSubpass < pass->subpass_count);
37       pass->subpass_flushes[dep->dstSubpass] |=
38          anv_pipe_invalidate_bits_for_access_flags(dep->dstAccessMask);
39    }
40 
41    if (dep->srcSubpass == VK_SUBPASS_EXTERNAL) {
42       pass->subpass_flushes[0] |=
43          anv_pipe_flush_bits_for_access_flags(dep->srcAccessMask);
44    } else {
45       assert(dep->srcSubpass < pass->subpass_count);
46       pass->subpass_flushes[dep->srcSubpass + 1] |=
47          anv_pipe_flush_bits_for_access_flags(dep->srcAccessMask);
48    }
49 }
50 
51 /* Do a second "compile" step on a render pass */
52 static void
anv_render_pass_compile(struct anv_render_pass * pass)53 anv_render_pass_compile(struct anv_render_pass *pass)
54 {
55    /* The CreateRenderPass code zeros the entire render pass and also uses a
56     * designated initializer for filling these out.  There's no need for us to
57     * do it again.
58     *
59     * for (uint32_t i = 0; i < pass->attachment_count; i++) {
60     *    pass->attachments[i].usage = 0;
61     *    pass->attachments[i].first_subpass_layout = VK_IMAGE_LAYOUT_UNDEFINED;
62     * }
63     */
64 
65    VkImageUsageFlags all_usage = 0;
66    for (uint32_t i = 0; i < pass->subpass_count; i++) {
67       struct anv_subpass *subpass = &pass->subpasses[i];
68 
69       /* We don't allow depth_stencil_attachment to be non-NULL and be
70        * VK_ATTACHMENT_UNUSED.  This way something can just check for NULL
71        * and be guaranteed that they have a valid attachment.
72        */
73       if (subpass->depth_stencil_attachment &&
74           subpass->depth_stencil_attachment->attachment == VK_ATTACHMENT_UNUSED)
75          subpass->depth_stencil_attachment = NULL;
76 
77       if (subpass->ds_resolve_attachment &&
78           subpass->ds_resolve_attachment->attachment == VK_ATTACHMENT_UNUSED)
79          subpass->ds_resolve_attachment = NULL;
80 
81       for (uint32_t j = 0; j < subpass->attachment_count; j++) {
82          struct anv_subpass_attachment *subpass_att = &subpass->attachments[j];
83          if (subpass_att->attachment == VK_ATTACHMENT_UNUSED)
84             continue;
85 
86          struct anv_render_pass_attachment *pass_att =
87             &pass->attachments[subpass_att->attachment];
88 
89          pass_att->usage |= subpass_att->usage;
90          pass_att->last_subpass_idx = i;
91 
92          all_usage |= subpass_att->usage;
93 
94          if (pass_att->first_subpass_layout == VK_IMAGE_LAYOUT_UNDEFINED) {
95             pass_att->first_subpass_layout = subpass_att->layout;
96             assert(pass_att->first_subpass_layout != VK_IMAGE_LAYOUT_UNDEFINED);
97          }
98 
99          if (subpass_att->usage == VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT &&
100              subpass->depth_stencil_attachment &&
101              subpass_att->attachment == subpass->depth_stencil_attachment->attachment)
102             subpass->has_ds_self_dep = true;
103       }
104 
105       /* We have to handle resolve attachments specially */
106       subpass->has_color_resolve = false;
107       if (subpass->resolve_attachments) {
108          for (uint32_t j = 0; j < subpass->color_count; j++) {
109             struct anv_subpass_attachment *color_att =
110                &subpass->color_attachments[j];
111             struct anv_subpass_attachment *resolve_att =
112                &subpass->resolve_attachments[j];
113             if (resolve_att->attachment == VK_ATTACHMENT_UNUSED)
114                continue;
115 
116             subpass->has_color_resolve = true;
117 
118             assert(color_att->attachment < pass->attachment_count);
119             struct anv_render_pass_attachment *color_pass_att =
120                &pass->attachments[color_att->attachment];
121 
122             assert(resolve_att->usage == VK_IMAGE_USAGE_TRANSFER_DST_BIT);
123             assert(color_att->usage == VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
124             color_pass_att->usage |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
125          }
126       }
127 
128       if (subpass->ds_resolve_attachment) {
129          struct anv_subpass_attachment *ds_att =
130             subpass->depth_stencil_attachment;
131          UNUSED struct anv_subpass_attachment *resolve_att =
132             subpass->ds_resolve_attachment;
133 
134          assert(ds_att->attachment < pass->attachment_count);
135          struct anv_render_pass_attachment *ds_pass_att =
136             &pass->attachments[ds_att->attachment];
137 
138          assert(resolve_att->usage == VK_IMAGE_USAGE_TRANSFER_DST_BIT);
139          assert(ds_att->usage == VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT);
140          ds_pass_att->usage |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
141       }
142 
143       for (uint32_t j = 0; j < subpass->attachment_count; j++)
144          assert(__builtin_popcount(subpass->attachments[j].usage) == 1);
145    }
146 
147    /* From the Vulkan 1.0.39 spec:
148     *
149     *    If there is no subpass dependency from VK_SUBPASS_EXTERNAL to the
150     *    first subpass that uses an attachment, then an implicit subpass
151     *    dependency exists from VK_SUBPASS_EXTERNAL to the first subpass it is
152     *    used in. The subpass dependency operates as if defined with the
153     *    following parameters:
154     *
155     *    VkSubpassDependency implicitDependency = {
156     *        .srcSubpass = VK_SUBPASS_EXTERNAL;
157     *        .dstSubpass = firstSubpass; // First subpass attachment is used in
158     *        .srcStageMask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
159     *        .dstStageMask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
160     *        .srcAccessMask = 0;
161     *        .dstAccessMask = VK_ACCESS_INPUT_ATTACHMENT_READ_BIT |
162     *                         VK_ACCESS_COLOR_ATTACHMENT_READ_BIT |
163     *                         VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT |
164     *                         VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT |
165     *                         VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
166     *        .dependencyFlags = 0;
167     *    };
168     *
169     *    Similarly, if there is no subpass dependency from the last subpass
170     *    that uses an attachment to VK_SUBPASS_EXTERNAL, then an implicit
171     *    subpass dependency exists from the last subpass it is used in to
172     *    VK_SUBPASS_EXTERNAL. The subpass dependency operates as if defined
173     *    with the following parameters:
174     *
175     *    VkSubpassDependency implicitDependency = {
176     *        .srcSubpass = lastSubpass; // Last subpass attachment is used in
177     *        .dstSubpass = VK_SUBPASS_EXTERNAL;
178     *        .srcStageMask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
179     *        .dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
180     *        .srcAccessMask = VK_ACCESS_INPUT_ATTACHMENT_READ_BIT |
181     *                         VK_ACCESS_COLOR_ATTACHMENT_READ_BIT |
182     *                         VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT |
183     *                         VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT |
184     *                         VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
185     *        .dstAccessMask = 0;
186     *        .dependencyFlags = 0;
187     *    };
188     *
189     * We could implement this by walking over all of the attachments and
190     * subpasses and checking to see if any of them don't have an external
191     * dependency.  Or, we could just be lazy and add a couple extra flushes.
192     * We choose to be lazy.
193     *
194     * From the documentation for vkCmdNextSubpass:
195     *
196     *    "Moving to the next subpass automatically performs any multisample
197     *    resolve operations in the subpass being ended. End-of-subpass
198     *    multisample resolves are treated as color attachment writes for the
199     *    purposes of synchronization. This applies to resolve operations for
200     *    both color and depth/stencil attachments. That is, they are
201     *    considered to execute in the
202     *    VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT pipeline stage and
203     *    their writes are synchronized with
204     *    VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT."
205     *
206     * Therefore, the above flags concerning color attachments also apply to
207     * color and depth/stencil resolve attachments.
208     */
209    if (all_usage & VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT) {
210       pass->subpass_flushes[0] |=
211          ANV_PIPE_TEXTURE_CACHE_INVALIDATE_BIT;
212    }
213    if (all_usage & (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
214                     VK_IMAGE_USAGE_TRANSFER_DST_BIT)) {
215       pass->subpass_flushes[pass->subpass_count] |=
216          ANV_PIPE_RENDER_TARGET_CACHE_FLUSH_BIT;
217    }
218    if (all_usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) {
219       pass->subpass_flushes[pass->subpass_count] |=
220          ANV_PIPE_DEPTH_CACHE_FLUSH_BIT;
221    }
222 }
223 
224 static unsigned
num_subpass_attachments(const VkSubpassDescription * desc)225 num_subpass_attachments(const VkSubpassDescription *desc)
226 {
227    return desc->inputAttachmentCount +
228           desc->colorAttachmentCount +
229           (desc->pResolveAttachments ? desc->colorAttachmentCount : 0) +
230           (desc->pDepthStencilAttachment != NULL);
231 }
232 
anv_CreateRenderPass(VkDevice _device,const VkRenderPassCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkRenderPass * pRenderPass)233 VkResult anv_CreateRenderPass(
234     VkDevice                                    _device,
235     const VkRenderPassCreateInfo*               pCreateInfo,
236     const VkAllocationCallbacks*                pAllocator,
237     VkRenderPass*                               pRenderPass)
238 {
239    ANV_FROM_HANDLE(anv_device, device, _device);
240 
241    assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO);
242 
243    struct anv_render_pass *pass;
244    struct anv_subpass *subpasses;
245    struct anv_render_pass_attachment *attachments;
246    enum anv_pipe_bits *subpass_flushes;
247 
248    ANV_MULTIALLOC(ma);
249    anv_multialloc_add(&ma, &pass, 1);
250    anv_multialloc_add(&ma, &subpasses, pCreateInfo->subpassCount);
251    anv_multialloc_add(&ma, &attachments, pCreateInfo->attachmentCount);
252    anv_multialloc_add(&ma, &subpass_flushes, pCreateInfo->subpassCount + 1);
253 
254    struct anv_subpass_attachment *subpass_attachments;
255    uint32_t subpass_attachment_count = 0;
256    for (uint32_t i = 0; i < pCreateInfo->subpassCount; i++) {
257       subpass_attachment_count +=
258          num_subpass_attachments(&pCreateInfo->pSubpasses[i]);
259    }
260    anv_multialloc_add(&ma, &subpass_attachments, subpass_attachment_count);
261 
262    if (!anv_multialloc_alloc2(&ma, &device->vk.alloc, pAllocator,
263                               VK_SYSTEM_ALLOCATION_SCOPE_OBJECT))
264       return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
265 
266    /* Clear the subpasses along with the parent pass. This required because
267     * each array member of anv_subpass must be a valid pointer if not NULL.
268     */
269    memset(pass, 0, ma.size);
270    vk_object_base_init(&device->vk, &pass->base, VK_OBJECT_TYPE_RENDER_PASS);
271    pass->attachment_count = pCreateInfo->attachmentCount;
272    pass->subpass_count = pCreateInfo->subpassCount;
273    pass->attachments = attachments;
274    pass->subpass_flushes = subpass_flushes;
275 
276    for (uint32_t i = 0; i < pCreateInfo->attachmentCount; i++) {
277       pass->attachments[i] = (struct anv_render_pass_attachment) {
278          .format                 = pCreateInfo->pAttachments[i].format,
279          .samples                = pCreateInfo->pAttachments[i].samples,
280          .load_op                = pCreateInfo->pAttachments[i].loadOp,
281          .store_op               = pCreateInfo->pAttachments[i].storeOp,
282          .stencil_load_op        = pCreateInfo->pAttachments[i].stencilLoadOp,
283          .initial_layout         = pCreateInfo->pAttachments[i].initialLayout,
284          .final_layout           = pCreateInfo->pAttachments[i].finalLayout,
285 
286          .stencil_initial_layout = pCreateInfo->pAttachments[i].initialLayout,
287          .stencil_final_layout   = pCreateInfo->pAttachments[i].finalLayout,
288       };
289    }
290 
291    for (uint32_t i = 0; i < pCreateInfo->subpassCount; i++) {
292       const VkSubpassDescription *desc = &pCreateInfo->pSubpasses[i];
293       struct anv_subpass *subpass = &pass->subpasses[i];
294 
295       subpass->input_count = desc->inputAttachmentCount;
296       subpass->color_count = desc->colorAttachmentCount;
297       subpass->attachment_count = num_subpass_attachments(desc);
298       subpass->attachments = subpass_attachments;
299       subpass->view_mask = 0;
300 
301       if (desc->inputAttachmentCount > 0) {
302          subpass->input_attachments = subpass_attachments;
303          subpass_attachments += desc->inputAttachmentCount;
304 
305          for (uint32_t j = 0; j < desc->inputAttachmentCount; j++) {
306             subpass->input_attachments[j] = (struct anv_subpass_attachment) {
307                .usage =          VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT,
308                .attachment =     desc->pInputAttachments[j].attachment,
309                .layout =         desc->pInputAttachments[j].layout,
310                .stencil_layout = desc->pInputAttachments[j].layout,
311             };
312          }
313       }
314 
315       if (desc->colorAttachmentCount > 0) {
316          subpass->color_attachments = subpass_attachments;
317          subpass_attachments += desc->colorAttachmentCount;
318 
319          for (uint32_t j = 0; j < desc->colorAttachmentCount; j++) {
320             subpass->color_attachments[j] = (struct anv_subpass_attachment) {
321                .usage =       VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
322                .attachment =  desc->pColorAttachments[j].attachment,
323                .layout =      desc->pColorAttachments[j].layout,
324             };
325          }
326       }
327 
328       if (desc->pResolveAttachments) {
329          subpass->resolve_attachments = subpass_attachments;
330          subpass_attachments += desc->colorAttachmentCount;
331 
332          for (uint32_t j = 0; j < desc->colorAttachmentCount; j++) {
333             subpass->resolve_attachments[j] = (struct anv_subpass_attachment) {
334                .usage =       VK_IMAGE_USAGE_TRANSFER_DST_BIT,
335                .attachment =  desc->pResolveAttachments[j].attachment,
336                .layout =      desc->pResolveAttachments[j].layout,
337             };
338          }
339       }
340 
341       if (desc->pDepthStencilAttachment) {
342          subpass->depth_stencil_attachment = subpass_attachments++;
343 
344          *subpass->depth_stencil_attachment = (struct anv_subpass_attachment) {
345             .usage =          VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
346             .attachment =     desc->pDepthStencilAttachment->attachment,
347             .layout =         desc->pDepthStencilAttachment->layout,
348             .stencil_layout = desc->pDepthStencilAttachment->layout,
349          };
350       }
351    }
352 
353    for (uint32_t i = 0; i < pCreateInfo->dependencyCount; i++) {
354       /* Convert to a Dependency2KHR */
355       VkSubpassDependency2 dep2 = {
356          .srcSubpass       = pCreateInfo->pDependencies[i].srcSubpass,
357          .dstSubpass       = pCreateInfo->pDependencies[i].dstSubpass,
358          .srcStageMask     = pCreateInfo->pDependencies[i].srcStageMask,
359          .dstStageMask     = pCreateInfo->pDependencies[i].dstStageMask,
360          .srcAccessMask    = pCreateInfo->pDependencies[i].srcAccessMask,
361          .dstAccessMask    = pCreateInfo->pDependencies[i].dstAccessMask,
362          .dependencyFlags  = pCreateInfo->pDependencies[i].dependencyFlags,
363       };
364       anv_render_pass_add_subpass_dep(pass, &dep2);
365    }
366 
367    vk_foreach_struct(ext, pCreateInfo->pNext) {
368       switch (ext->sType) {
369       case VK_STRUCTURE_TYPE_RENDER_PASS_INPUT_ATTACHMENT_ASPECT_CREATE_INFO:
370          /* We don't care about this information */
371          break;
372 
373       case VK_STRUCTURE_TYPE_RENDER_PASS_MULTIVIEW_CREATE_INFO: {
374          VkRenderPassMultiviewCreateInfo *mv = (void *)ext;
375 
376          for (uint32_t i = 0; i < mv->subpassCount; i++) {
377             pass->subpasses[i].view_mask = mv->pViewMasks[i];
378          }
379          break;
380       }
381 
382       default:
383          anv_debug_ignored_stype(ext->sType);
384       }
385    }
386 
387    anv_render_pass_compile(pass);
388 
389    *pRenderPass = anv_render_pass_to_handle(pass);
390 
391    return VK_SUCCESS;
392 }
393 
394 static unsigned
num_subpass_attachments2(const VkSubpassDescription2KHR * desc)395 num_subpass_attachments2(const VkSubpassDescription2KHR *desc)
396 {
397    const VkSubpassDescriptionDepthStencilResolveKHR *ds_resolve =
398       vk_find_struct_const(desc->pNext,
399                            SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE_KHR);
400 
401    return desc->inputAttachmentCount +
402           desc->colorAttachmentCount +
403           (desc->pResolveAttachments ? desc->colorAttachmentCount : 0) +
404           (desc->pDepthStencilAttachment != NULL) +
405           (ds_resolve && ds_resolve->pDepthStencilResolveAttachment);
406 }
407 
anv_CreateRenderPass2(VkDevice _device,const VkRenderPassCreateInfo2KHR * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkRenderPass * pRenderPass)408 VkResult anv_CreateRenderPass2(
409     VkDevice                                    _device,
410     const VkRenderPassCreateInfo2KHR*           pCreateInfo,
411     const VkAllocationCallbacks*                pAllocator,
412     VkRenderPass*                               pRenderPass)
413 {
414    ANV_FROM_HANDLE(anv_device, device, _device);
415 
416    assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2_KHR);
417 
418    struct anv_render_pass *pass;
419    struct anv_subpass *subpasses;
420    struct anv_render_pass_attachment *attachments;
421    enum anv_pipe_bits *subpass_flushes;
422 
423    ANV_MULTIALLOC(ma);
424    anv_multialloc_add(&ma, &pass, 1);
425    anv_multialloc_add(&ma, &subpasses, pCreateInfo->subpassCount);
426    anv_multialloc_add(&ma, &attachments, pCreateInfo->attachmentCount);
427    anv_multialloc_add(&ma, &subpass_flushes, pCreateInfo->subpassCount + 1);
428 
429    struct anv_subpass_attachment *subpass_attachments;
430    uint32_t subpass_attachment_count = 0;
431    for (uint32_t i = 0; i < pCreateInfo->subpassCount; i++) {
432       subpass_attachment_count +=
433          num_subpass_attachments2(&pCreateInfo->pSubpasses[i]);
434    }
435    anv_multialloc_add(&ma, &subpass_attachments, subpass_attachment_count);
436 
437    if (!anv_multialloc_alloc2(&ma, &device->vk.alloc, pAllocator,
438                               VK_SYSTEM_ALLOCATION_SCOPE_OBJECT))
439       return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
440 
441    /* Clear the subpasses along with the parent pass. This required because
442     * each array member of anv_subpass must be a valid pointer if not NULL.
443     */
444    memset(pass, 0, ma.size);
445    vk_object_base_init(&device->vk, &pass->base, VK_OBJECT_TYPE_RENDER_PASS);
446    pass->attachment_count = pCreateInfo->attachmentCount;
447    pass->subpass_count = pCreateInfo->subpassCount;
448    pass->attachments = attachments;
449    pass->subpass_flushes = subpass_flushes;
450 
451    for (uint32_t i = 0; i < pCreateInfo->attachmentCount; i++) {
452       const VkAttachmentDescriptionStencilLayoutKHR *stencil_layout =
453          vk_find_struct_const(pCreateInfo->pAttachments[i].pNext,
454                               ATTACHMENT_DESCRIPTION_STENCIL_LAYOUT_KHR);
455 
456       pass->attachments[i] = (struct anv_render_pass_attachment) {
457          .format                 = pCreateInfo->pAttachments[i].format,
458          .samples                = pCreateInfo->pAttachments[i].samples,
459          .load_op                = pCreateInfo->pAttachments[i].loadOp,
460          .store_op               = pCreateInfo->pAttachments[i].storeOp,
461          .stencil_load_op        = pCreateInfo->pAttachments[i].stencilLoadOp,
462          .initial_layout         = pCreateInfo->pAttachments[i].initialLayout,
463          .final_layout           = pCreateInfo->pAttachments[i].finalLayout,
464 
465          .stencil_initial_layout = (stencil_layout ?
466                                     stencil_layout->stencilInitialLayout :
467                                     pCreateInfo->pAttachments[i].initialLayout),
468          .stencil_final_layout   = (stencil_layout ?
469                                     stencil_layout->stencilFinalLayout :
470                                     pCreateInfo->pAttachments[i].finalLayout),
471       };
472    }
473 
474    for (uint32_t i = 0; i < pCreateInfo->subpassCount; i++) {
475       const VkSubpassDescription2KHR *desc = &pCreateInfo->pSubpasses[i];
476       struct anv_subpass *subpass = &pass->subpasses[i];
477 
478       subpass->input_count = desc->inputAttachmentCount;
479       subpass->color_count = desc->colorAttachmentCount;
480       subpass->attachment_count = num_subpass_attachments2(desc);
481       subpass->attachments = subpass_attachments;
482       subpass->view_mask = desc->viewMask;
483 
484       if (desc->inputAttachmentCount > 0) {
485          subpass->input_attachments = subpass_attachments;
486          subpass_attachments += desc->inputAttachmentCount;
487 
488          for (uint32_t j = 0; j < desc->inputAttachmentCount; j++) {
489             const VkAttachmentReferenceStencilLayoutKHR *stencil_layout =
490                vk_find_struct_const(desc->pInputAttachments[j].pNext,
491                                     ATTACHMENT_REFERENCE_STENCIL_LAYOUT_KHR);
492 
493             subpass->input_attachments[j] = (struct anv_subpass_attachment) {
494                .usage =          VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT,
495                .attachment =     desc->pInputAttachments[j].attachment,
496                .layout =         desc->pInputAttachments[j].layout,
497                .stencil_layout = (stencil_layout ?
498                                   stencil_layout->stencilLayout :
499                                   desc->pInputAttachments[j].layout),
500             };
501          }
502       }
503 
504       if (desc->colorAttachmentCount > 0) {
505          subpass->color_attachments = subpass_attachments;
506          subpass_attachments += desc->colorAttachmentCount;
507 
508          for (uint32_t j = 0; j < desc->colorAttachmentCount; j++) {
509             subpass->color_attachments[j] = (struct anv_subpass_attachment) {
510                .usage =       VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
511                .attachment =  desc->pColorAttachments[j].attachment,
512                .layout =      desc->pColorAttachments[j].layout,
513             };
514          }
515       }
516 
517       if (desc->pResolveAttachments) {
518          subpass->resolve_attachments = subpass_attachments;
519          subpass_attachments += desc->colorAttachmentCount;
520 
521          for (uint32_t j = 0; j < desc->colorAttachmentCount; j++) {
522             subpass->resolve_attachments[j] = (struct anv_subpass_attachment) {
523                .usage =       VK_IMAGE_USAGE_TRANSFER_DST_BIT,
524                .attachment =  desc->pResolveAttachments[j].attachment,
525                .layout =      desc->pResolveAttachments[j].layout,
526             };
527          }
528       }
529 
530       if (desc->pDepthStencilAttachment) {
531          subpass->depth_stencil_attachment = subpass_attachments++;
532 
533          const VkAttachmentReferenceStencilLayoutKHR *stencil_attachment =
534             vk_find_struct_const(desc->pDepthStencilAttachment->pNext,
535                                  ATTACHMENT_REFERENCE_STENCIL_LAYOUT_KHR);
536 
537          *subpass->depth_stencil_attachment = (struct anv_subpass_attachment) {
538             .usage =          VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
539             .attachment =     desc->pDepthStencilAttachment->attachment,
540             .layout =         desc->pDepthStencilAttachment->layout,
541             .stencil_layout = stencil_attachment ?
542                               stencil_attachment->stencilLayout :
543                               desc->pDepthStencilAttachment->layout,
544          };
545       }
546 
547       const VkSubpassDescriptionDepthStencilResolveKHR *ds_resolve =
548          vk_find_struct_const(desc->pNext,
549                               SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE_KHR);
550 
551       if (ds_resolve && ds_resolve->pDepthStencilResolveAttachment) {
552          subpass->ds_resolve_attachment = subpass_attachments++;
553 
554          const VkAttachmentReferenceStencilLayoutKHR *stencil_resolve_attachment =
555             vk_find_struct_const(ds_resolve->pDepthStencilResolveAttachment->pNext,
556                                  ATTACHMENT_REFERENCE_STENCIL_LAYOUT_KHR);
557 
558          *subpass->ds_resolve_attachment = (struct anv_subpass_attachment) {
559             .usage =          VK_IMAGE_USAGE_TRANSFER_DST_BIT,
560             .attachment =     ds_resolve->pDepthStencilResolveAttachment->attachment,
561             .layout =         ds_resolve->pDepthStencilResolveAttachment->layout,
562             .stencil_layout = stencil_resolve_attachment ?
563                               stencil_resolve_attachment->stencilLayout :
564                               ds_resolve->pDepthStencilResolveAttachment->layout,
565          };
566          subpass->depth_resolve_mode = ds_resolve->depthResolveMode;
567          subpass->stencil_resolve_mode = ds_resolve->stencilResolveMode;
568       }
569    }
570 
571    for (uint32_t i = 0; i < pCreateInfo->dependencyCount; i++)
572       anv_render_pass_add_subpass_dep(pass, &pCreateInfo->pDependencies[i]);
573 
574    vk_foreach_struct(ext, pCreateInfo->pNext) {
575       switch (ext->sType) {
576       default:
577          anv_debug_ignored_stype(ext->sType);
578       }
579    }
580 
581    anv_render_pass_compile(pass);
582 
583    *pRenderPass = anv_render_pass_to_handle(pass);
584 
585    return VK_SUCCESS;
586 }
587 
anv_DestroyRenderPass(VkDevice _device,VkRenderPass _pass,const VkAllocationCallbacks * pAllocator)588 void anv_DestroyRenderPass(
589     VkDevice                                    _device,
590     VkRenderPass                                _pass,
591     const VkAllocationCallbacks*                pAllocator)
592 {
593    ANV_FROM_HANDLE(anv_device, device, _device);
594    ANV_FROM_HANDLE(anv_render_pass, pass, _pass);
595 
596    if (!pass)
597       return;
598 
599    vk_object_base_finish(&pass->base);
600    vk_free2(&device->vk.alloc, pAllocator, pass);
601 }
602 
anv_GetRenderAreaGranularity(VkDevice device,VkRenderPass renderPass,VkExtent2D * pGranularity)603 void anv_GetRenderAreaGranularity(
604     VkDevice                                    device,
605     VkRenderPass                                renderPass,
606     VkExtent2D*                                 pGranularity)
607 {
608    ANV_FROM_HANDLE(anv_render_pass, pass, renderPass);
609 
610    /* This granularity satisfies HiZ fast clear alignment requirements
611     * for all sample counts.
612     */
613    for (unsigned i = 0; i < pass->subpass_count; ++i) {
614       if (pass->subpasses[i].depth_stencil_attachment) {
615          *pGranularity = (VkExtent2D) { .width = 8, .height = 4 };
616          return;
617       }
618    }
619 
620    *pGranularity = (VkExtent2D) { 1, 1 };
621 }
622