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