xref: /aosp_15_r20/external/mesa3d/src/broadcom/vulkan/v3dv_pass.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1*61046927SAndroid Build Coastguard Worker /*
2*61046927SAndroid Build Coastguard Worker  * Copyright © 2019 Raspberry Pi Ltd
3*61046927SAndroid Build Coastguard Worker  *
4*61046927SAndroid Build Coastguard Worker  * Permission is hereby granted, free of charge, to any person obtaining a
5*61046927SAndroid Build Coastguard Worker  * copy of this software and associated documentation files (the "Software"),
6*61046927SAndroid Build Coastguard Worker  * to deal in the Software without restriction, including without limitation
7*61046927SAndroid Build Coastguard Worker  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8*61046927SAndroid Build Coastguard Worker  * and/or sell copies of the Software, and to permit persons to whom the
9*61046927SAndroid Build Coastguard Worker  * Software is furnished to do so, subject to the following conditions:
10*61046927SAndroid Build Coastguard Worker  *
11*61046927SAndroid Build Coastguard Worker  * The above copyright notice and this permission notice (including the next
12*61046927SAndroid Build Coastguard Worker  * paragraph) shall be included in all copies or substantial portions of the
13*61046927SAndroid Build Coastguard Worker  * Software.
14*61046927SAndroid Build Coastguard Worker  *
15*61046927SAndroid Build Coastguard Worker  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16*61046927SAndroid Build Coastguard Worker  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17*61046927SAndroid Build Coastguard Worker  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18*61046927SAndroid Build Coastguard Worker  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19*61046927SAndroid Build Coastguard Worker  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20*61046927SAndroid Build Coastguard Worker  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21*61046927SAndroid Build Coastguard Worker  * IN THE SOFTWARE.
22*61046927SAndroid Build Coastguard Worker  */
23*61046927SAndroid Build Coastguard Worker 
24*61046927SAndroid Build Coastguard Worker #include "v3dv_private.h"
25*61046927SAndroid Build Coastguard Worker 
26*61046927SAndroid Build Coastguard Worker static uint32_t
num_subpass_attachments(const VkSubpassDescription2 * desc)27*61046927SAndroid Build Coastguard Worker num_subpass_attachments(const VkSubpassDescription2 *desc)
28*61046927SAndroid Build Coastguard Worker {
29*61046927SAndroid Build Coastguard Worker    return desc->inputAttachmentCount +
30*61046927SAndroid Build Coastguard Worker           desc->colorAttachmentCount +
31*61046927SAndroid Build Coastguard Worker           (desc->pResolveAttachments ? desc->colorAttachmentCount : 0) +
32*61046927SAndroid Build Coastguard Worker           (desc->pDepthStencilAttachment != NULL);
33*61046927SAndroid Build Coastguard Worker }
34*61046927SAndroid Build Coastguard Worker 
35*61046927SAndroid Build Coastguard Worker static void
set_try_tlb_resolve(struct v3dv_device * device,struct v3dv_render_pass_attachment * att)36*61046927SAndroid Build Coastguard Worker set_try_tlb_resolve(struct v3dv_device *device,
37*61046927SAndroid Build Coastguard Worker                     struct v3dv_render_pass_attachment *att)
38*61046927SAndroid Build Coastguard Worker {
39*61046927SAndroid Build Coastguard Worker    const struct v3dv_format *format = v3dv_X(device, get_format)(att->desc.format);
40*61046927SAndroid Build Coastguard Worker    att->try_tlb_resolve = v3dv_X(device, format_supports_tlb_resolve)(format);
41*61046927SAndroid Build Coastguard Worker }
42*61046927SAndroid Build Coastguard Worker 
43*61046927SAndroid Build Coastguard Worker static void
pass_find_subpass_range_for_attachments(struct v3dv_device * device,struct v3dv_render_pass * pass)44*61046927SAndroid Build Coastguard Worker pass_find_subpass_range_for_attachments(struct v3dv_device *device,
45*61046927SAndroid Build Coastguard Worker                                         struct v3dv_render_pass *pass)
46*61046927SAndroid Build Coastguard Worker {
47*61046927SAndroid Build Coastguard Worker    for (uint32_t i = 0; i < pass->attachment_count; i++) {
48*61046927SAndroid Build Coastguard Worker       pass->attachments[i].first_subpass = pass->subpass_count - 1;
49*61046927SAndroid Build Coastguard Worker       pass->attachments[i].last_subpass = 0;
50*61046927SAndroid Build Coastguard Worker       if (pass->multiview_enabled) {
51*61046927SAndroid Build Coastguard Worker          for (uint32_t j = 0; j < MAX_MULTIVIEW_VIEW_COUNT; j++) {
52*61046927SAndroid Build Coastguard Worker             pass->attachments[i].views[j].first_subpass = pass->subpass_count - 1;
53*61046927SAndroid Build Coastguard Worker             pass->attachments[i].views[j].last_subpass = 0;
54*61046927SAndroid Build Coastguard Worker          }
55*61046927SAndroid Build Coastguard Worker       }
56*61046927SAndroid Build Coastguard Worker    }
57*61046927SAndroid Build Coastguard Worker 
58*61046927SAndroid Build Coastguard Worker    for (uint32_t i = 0; i < pass->subpass_count; i++) {
59*61046927SAndroid Build Coastguard Worker       const struct v3dv_subpass *subpass = &pass->subpasses[i];
60*61046927SAndroid Build Coastguard Worker 
61*61046927SAndroid Build Coastguard Worker       for (uint32_t j = 0; j < subpass->color_count; j++) {
62*61046927SAndroid Build Coastguard Worker          uint32_t attachment_idx = subpass->color_attachments[j].attachment;
63*61046927SAndroid Build Coastguard Worker          if (attachment_idx == VK_ATTACHMENT_UNUSED)
64*61046927SAndroid Build Coastguard Worker             continue;
65*61046927SAndroid Build Coastguard Worker 
66*61046927SAndroid Build Coastguard Worker          struct v3dv_render_pass_attachment *att =
67*61046927SAndroid Build Coastguard Worker             &pass->attachments[attachment_idx];
68*61046927SAndroid Build Coastguard Worker 
69*61046927SAndroid Build Coastguard Worker          if (i < att->first_subpass)
70*61046927SAndroid Build Coastguard Worker             att->first_subpass = i;
71*61046927SAndroid Build Coastguard Worker          if (i > att->last_subpass)
72*61046927SAndroid Build Coastguard Worker             att->last_subpass = i;
73*61046927SAndroid Build Coastguard Worker 
74*61046927SAndroid Build Coastguard Worker          uint32_t view_mask = subpass->view_mask;
75*61046927SAndroid Build Coastguard Worker          while (view_mask) {
76*61046927SAndroid Build Coastguard Worker             uint32_t view_index = u_bit_scan(&view_mask);
77*61046927SAndroid Build Coastguard Worker             if (i < att->views[view_index].first_subpass)
78*61046927SAndroid Build Coastguard Worker                att->views[view_index].first_subpass = i;
79*61046927SAndroid Build Coastguard Worker             if (i > att->views[view_index].last_subpass)
80*61046927SAndroid Build Coastguard Worker                att->views[view_index].last_subpass = i;
81*61046927SAndroid Build Coastguard Worker          }
82*61046927SAndroid Build Coastguard Worker 
83*61046927SAndroid Build Coastguard Worker          if (subpass->resolve_attachments &&
84*61046927SAndroid Build Coastguard Worker              subpass->resolve_attachments[j].attachment != VK_ATTACHMENT_UNUSED) {
85*61046927SAndroid Build Coastguard Worker             set_try_tlb_resolve(device, att);
86*61046927SAndroid Build Coastguard Worker          }
87*61046927SAndroid Build Coastguard Worker       }
88*61046927SAndroid Build Coastguard Worker 
89*61046927SAndroid Build Coastguard Worker       uint32_t ds_attachment_idx = subpass->ds_attachment.attachment;
90*61046927SAndroid Build Coastguard Worker       if (ds_attachment_idx != VK_ATTACHMENT_UNUSED) {
91*61046927SAndroid Build Coastguard Worker          if (i < pass->attachments[ds_attachment_idx].first_subpass)
92*61046927SAndroid Build Coastguard Worker             pass->attachments[ds_attachment_idx].first_subpass = i;
93*61046927SAndroid Build Coastguard Worker          if (i > pass->attachments[ds_attachment_idx].last_subpass)
94*61046927SAndroid Build Coastguard Worker             pass->attachments[ds_attachment_idx].last_subpass = i;
95*61046927SAndroid Build Coastguard Worker 
96*61046927SAndroid Build Coastguard Worker          if (subpass->ds_resolve_attachment.attachment != VK_ATTACHMENT_UNUSED)
97*61046927SAndroid Build Coastguard Worker             set_try_tlb_resolve(device, &pass->attachments[ds_attachment_idx]);
98*61046927SAndroid Build Coastguard Worker       }
99*61046927SAndroid Build Coastguard Worker 
100*61046927SAndroid Build Coastguard Worker       for (uint32_t j = 0; j < subpass->input_count; j++) {
101*61046927SAndroid Build Coastguard Worker          uint32_t input_attachment_idx = subpass->input_attachments[j].attachment;
102*61046927SAndroid Build Coastguard Worker          if (input_attachment_idx == VK_ATTACHMENT_UNUSED)
103*61046927SAndroid Build Coastguard Worker             continue;
104*61046927SAndroid Build Coastguard Worker          if (i < pass->attachments[input_attachment_idx].first_subpass)
105*61046927SAndroid Build Coastguard Worker             pass->attachments[input_attachment_idx].first_subpass = i;
106*61046927SAndroid Build Coastguard Worker          if (i > pass->attachments[input_attachment_idx].last_subpass)
107*61046927SAndroid Build Coastguard Worker             pass->attachments[input_attachment_idx].last_subpass = i;
108*61046927SAndroid Build Coastguard Worker       }
109*61046927SAndroid Build Coastguard Worker 
110*61046927SAndroid Build Coastguard Worker       if (subpass->resolve_attachments) {
111*61046927SAndroid Build Coastguard Worker          for (uint32_t j = 0; j < subpass->color_count; j++) {
112*61046927SAndroid Build Coastguard Worker             uint32_t attachment_idx = subpass->resolve_attachments[j].attachment;
113*61046927SAndroid Build Coastguard Worker             if (attachment_idx == VK_ATTACHMENT_UNUSED)
114*61046927SAndroid Build Coastguard Worker                continue;
115*61046927SAndroid Build Coastguard Worker             if (i < pass->attachments[attachment_idx].first_subpass)
116*61046927SAndroid Build Coastguard Worker                pass->attachments[attachment_idx].first_subpass = i;
117*61046927SAndroid Build Coastguard Worker             if (i > pass->attachments[attachment_idx].last_subpass)
118*61046927SAndroid Build Coastguard Worker                pass->attachments[attachment_idx].last_subpass = i;
119*61046927SAndroid Build Coastguard Worker          }
120*61046927SAndroid Build Coastguard Worker       }
121*61046927SAndroid Build Coastguard Worker    }
122*61046927SAndroid Build Coastguard Worker }
123*61046927SAndroid Build Coastguard Worker 
124*61046927SAndroid Build Coastguard Worker /* GFXH-1461: if depth is cleared but stencil is loaded (or vice versa),
125*61046927SAndroid Build Coastguard Worker  * the clear might get lost. If a subpass has this then we can't emit
126*61046927SAndroid Build Coastguard Worker  * the clear using the TLB and we have to do it as a draw call. This
127*61046927SAndroid Build Coastguard Worker  * issue is fixed since V3D 4.3.18.
128*61046927SAndroid Build Coastguard Worker  *
129*61046927SAndroid Build Coastguard Worker  * FIXME: separate stencil.
130*61046927SAndroid Build Coastguard Worker  */
131*61046927SAndroid Build Coastguard Worker static void
check_do_depth_stencil_clear_with_draw(struct v3dv_device * device,struct v3dv_render_pass * pass,struct v3dv_subpass * subpass)132*61046927SAndroid Build Coastguard Worker check_do_depth_stencil_clear_with_draw(struct v3dv_device *device,
133*61046927SAndroid Build Coastguard Worker                                        struct v3dv_render_pass *pass,
134*61046927SAndroid Build Coastguard Worker                                        struct v3dv_subpass *subpass)
135*61046927SAndroid Build Coastguard Worker {
136*61046927SAndroid Build Coastguard Worker    if (device->devinfo.ver > 42 ||
137*61046927SAndroid Build Coastguard Worker        subpass->ds_attachment.attachment == VK_ATTACHMENT_UNUSED) {
138*61046927SAndroid Build Coastguard Worker       return;
139*61046927SAndroid Build Coastguard Worker    }
140*61046927SAndroid Build Coastguard Worker 
141*61046927SAndroid Build Coastguard Worker    struct v3dv_render_pass_attachment *att =
142*61046927SAndroid Build Coastguard Worker       &pass->attachments[subpass->ds_attachment.attachment];
143*61046927SAndroid Build Coastguard Worker    if (att->desc.format != VK_FORMAT_D24_UNORM_S8_UINT)
144*61046927SAndroid Build Coastguard Worker       return;
145*61046927SAndroid Build Coastguard Worker 
146*61046927SAndroid Build Coastguard Worker    if (att->desc.loadOp == VK_ATTACHMENT_LOAD_OP_CLEAR &&
147*61046927SAndroid Build Coastguard Worker        att->desc.stencilLoadOp == VK_ATTACHMENT_LOAD_OP_LOAD) {
148*61046927SAndroid Build Coastguard Worker       subpass->do_depth_clear_with_draw = true;
149*61046927SAndroid Build Coastguard Worker    } else if (att->desc.loadOp == VK_ATTACHMENT_LOAD_OP_LOAD &&
150*61046927SAndroid Build Coastguard Worker               att->desc.stencilLoadOp == VK_ATTACHMENT_LOAD_OP_CLEAR) {
151*61046927SAndroid Build Coastguard Worker       subpass->do_stencil_clear_with_draw = true;
152*61046927SAndroid Build Coastguard Worker    }
153*61046927SAndroid Build Coastguard Worker }
154*61046927SAndroid Build Coastguard Worker 
155*61046927SAndroid Build Coastguard Worker VKAPI_ATTR VkResult VKAPI_CALL
v3dv_CreateRenderPass2(VkDevice _device,const VkRenderPassCreateInfo2 * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkRenderPass * pRenderPass)156*61046927SAndroid Build Coastguard Worker v3dv_CreateRenderPass2(VkDevice _device,
157*61046927SAndroid Build Coastguard Worker                        const VkRenderPassCreateInfo2 *pCreateInfo,
158*61046927SAndroid Build Coastguard Worker                        const VkAllocationCallbacks *pAllocator,
159*61046927SAndroid Build Coastguard Worker                        VkRenderPass *pRenderPass)
160*61046927SAndroid Build Coastguard Worker {
161*61046927SAndroid Build Coastguard Worker    V3DV_FROM_HANDLE(v3dv_device, device, _device);
162*61046927SAndroid Build Coastguard Worker    struct v3dv_render_pass *pass;
163*61046927SAndroid Build Coastguard Worker 
164*61046927SAndroid Build Coastguard Worker    assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2);
165*61046927SAndroid Build Coastguard Worker 
166*61046927SAndroid Build Coastguard Worker    /* From the VK_KHR_multiview spec:
167*61046927SAndroid Build Coastguard Worker     *
168*61046927SAndroid Build Coastguard Worker     *   When a subpass uses a non-zero view mask, multiview functionality is
169*61046927SAndroid Build Coastguard Worker     *   considered to be enabled. Multiview is all-or-nothing for a render
170*61046927SAndroid Build Coastguard Worker     *   pass - that is, either all subpasses must have a non-zero view mask
171*61046927SAndroid Build Coastguard Worker     *   (though some subpasses may have only one view) or all must be zero.
172*61046927SAndroid Build Coastguard Worker     */
173*61046927SAndroid Build Coastguard Worker    bool multiview_enabled = pCreateInfo->subpassCount &&
174*61046927SAndroid Build Coastguard Worker       pCreateInfo->pSubpasses[0].viewMask;
175*61046927SAndroid Build Coastguard Worker 
176*61046927SAndroid Build Coastguard Worker    size_t size = sizeof(*pass);
177*61046927SAndroid Build Coastguard Worker    size_t subpasses_offset = size;
178*61046927SAndroid Build Coastguard Worker    size += pCreateInfo->subpassCount * sizeof(pass->subpasses[0]);
179*61046927SAndroid Build Coastguard Worker    size_t attachments_offset = size;
180*61046927SAndroid Build Coastguard Worker    size += pCreateInfo->attachmentCount * sizeof(pass->attachments[0]);
181*61046927SAndroid Build Coastguard Worker 
182*61046927SAndroid Build Coastguard Worker    pass = vk_object_zalloc(&device->vk, pAllocator, size,
183*61046927SAndroid Build Coastguard Worker                            VK_OBJECT_TYPE_RENDER_PASS);
184*61046927SAndroid Build Coastguard Worker    if (pass == NULL)
185*61046927SAndroid Build Coastguard Worker       return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
186*61046927SAndroid Build Coastguard Worker 
187*61046927SAndroid Build Coastguard Worker    pass->multiview_enabled = multiview_enabled;
188*61046927SAndroid Build Coastguard Worker    pass->attachment_count = pCreateInfo->attachmentCount;
189*61046927SAndroid Build Coastguard Worker    pass->attachments = (void *) pass + attachments_offset;
190*61046927SAndroid Build Coastguard Worker    pass->subpass_count = pCreateInfo->subpassCount;
191*61046927SAndroid Build Coastguard Worker    pass->subpasses = (void *) pass + subpasses_offset;
192*61046927SAndroid Build Coastguard Worker 
193*61046927SAndroid Build Coastguard Worker    for (uint32_t i = 0; i < pCreateInfo->attachmentCount; i++)
194*61046927SAndroid Build Coastguard Worker       pass->attachments[i].desc = pCreateInfo->pAttachments[i];
195*61046927SAndroid Build Coastguard Worker 
196*61046927SAndroid Build Coastguard Worker    uint32_t subpass_attachment_count = 0;
197*61046927SAndroid Build Coastguard Worker    for (uint32_t i = 0; i < pCreateInfo->subpassCount; i++) {
198*61046927SAndroid Build Coastguard Worker       const VkSubpassDescription2 *desc = &pCreateInfo->pSubpasses[i];
199*61046927SAndroid Build Coastguard Worker       subpass_attachment_count += num_subpass_attachments(desc);
200*61046927SAndroid Build Coastguard Worker    }
201*61046927SAndroid Build Coastguard Worker 
202*61046927SAndroid Build Coastguard Worker    if (subpass_attachment_count) {
203*61046927SAndroid Build Coastguard Worker       const size_t subpass_attachment_bytes =
204*61046927SAndroid Build Coastguard Worker          subpass_attachment_count * sizeof(struct v3dv_subpass_attachment);
205*61046927SAndroid Build Coastguard Worker       pass->subpass_attachments =
206*61046927SAndroid Build Coastguard Worker          vk_alloc2(&device->vk.alloc, pAllocator, subpass_attachment_bytes, 8,
207*61046927SAndroid Build Coastguard Worker                    VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
208*61046927SAndroid Build Coastguard Worker       if (pass->subpass_attachments == NULL) {
209*61046927SAndroid Build Coastguard Worker          vk_object_free(&device->vk, pAllocator, pass);
210*61046927SAndroid Build Coastguard Worker          return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
211*61046927SAndroid Build Coastguard Worker       }
212*61046927SAndroid Build Coastguard Worker    } else {
213*61046927SAndroid Build Coastguard Worker       pass->subpass_attachments = NULL;
214*61046927SAndroid Build Coastguard Worker    }
215*61046927SAndroid Build Coastguard Worker 
216*61046927SAndroid Build Coastguard Worker    struct v3dv_subpass_attachment *p = pass->subpass_attachments;
217*61046927SAndroid Build Coastguard Worker    for (uint32_t i = 0; i < pCreateInfo->subpassCount; i++) {
218*61046927SAndroid Build Coastguard Worker       const VkSubpassDescription2 *desc = &pCreateInfo->pSubpasses[i];
219*61046927SAndroid Build Coastguard Worker       struct v3dv_subpass *subpass = &pass->subpasses[i];
220*61046927SAndroid Build Coastguard Worker 
221*61046927SAndroid Build Coastguard Worker       subpass->input_count = desc->inputAttachmentCount;
222*61046927SAndroid Build Coastguard Worker       subpass->color_count = desc->colorAttachmentCount;
223*61046927SAndroid Build Coastguard Worker       subpass->view_mask = desc->viewMask;
224*61046927SAndroid Build Coastguard Worker 
225*61046927SAndroid Build Coastguard Worker       if (desc->inputAttachmentCount > 0) {
226*61046927SAndroid Build Coastguard Worker          subpass->input_attachments = p;
227*61046927SAndroid Build Coastguard Worker          p += desc->inputAttachmentCount;
228*61046927SAndroid Build Coastguard Worker 
229*61046927SAndroid Build Coastguard Worker          for (uint32_t j = 0; j < desc->inputAttachmentCount; j++) {
230*61046927SAndroid Build Coastguard Worker             subpass->input_attachments[j] = (struct v3dv_subpass_attachment) {
231*61046927SAndroid Build Coastguard Worker                .attachment = desc->pInputAttachments[j].attachment,
232*61046927SAndroid Build Coastguard Worker                .layout = desc->pInputAttachments[j].layout,
233*61046927SAndroid Build Coastguard Worker             };
234*61046927SAndroid Build Coastguard Worker          }
235*61046927SAndroid Build Coastguard Worker       }
236*61046927SAndroid Build Coastguard Worker 
237*61046927SAndroid Build Coastguard Worker       if (desc->colorAttachmentCount > 0) {
238*61046927SAndroid Build Coastguard Worker          subpass->color_attachments = p;
239*61046927SAndroid Build Coastguard Worker          p += desc->colorAttachmentCount;
240*61046927SAndroid Build Coastguard Worker 
241*61046927SAndroid Build Coastguard Worker          for (uint32_t j = 0; j < desc->colorAttachmentCount; j++) {
242*61046927SAndroid Build Coastguard Worker             subpass->color_attachments[j] = (struct v3dv_subpass_attachment) {
243*61046927SAndroid Build Coastguard Worker                .attachment = desc->pColorAttachments[j].attachment,
244*61046927SAndroid Build Coastguard Worker                .layout = desc->pColorAttachments[j].layout,
245*61046927SAndroid Build Coastguard Worker             };
246*61046927SAndroid Build Coastguard Worker          }
247*61046927SAndroid Build Coastguard Worker       }
248*61046927SAndroid Build Coastguard Worker 
249*61046927SAndroid Build Coastguard Worker       if (desc->pResolveAttachments) {
250*61046927SAndroid Build Coastguard Worker          subpass->resolve_attachments = p;
251*61046927SAndroid Build Coastguard Worker          p += desc->colorAttachmentCount;
252*61046927SAndroid Build Coastguard Worker 
253*61046927SAndroid Build Coastguard Worker          for (uint32_t j = 0; j < desc->colorAttachmentCount; j++) {
254*61046927SAndroid Build Coastguard Worker             subpass->resolve_attachments[j] = (struct v3dv_subpass_attachment) {
255*61046927SAndroid Build Coastguard Worker                .attachment = desc->pResolveAttachments[j].attachment,
256*61046927SAndroid Build Coastguard Worker                .layout = desc->pResolveAttachments[j].layout,
257*61046927SAndroid Build Coastguard Worker             };
258*61046927SAndroid Build Coastguard Worker          }
259*61046927SAndroid Build Coastguard Worker       }
260*61046927SAndroid Build Coastguard Worker 
261*61046927SAndroid Build Coastguard Worker       if (desc->pDepthStencilAttachment) {
262*61046927SAndroid Build Coastguard Worker          subpass->ds_attachment = (struct v3dv_subpass_attachment) {
263*61046927SAndroid Build Coastguard Worker             .attachment = desc->pDepthStencilAttachment->attachment,
264*61046927SAndroid Build Coastguard Worker             .layout = desc->pDepthStencilAttachment->layout,
265*61046927SAndroid Build Coastguard Worker          };
266*61046927SAndroid Build Coastguard Worker 
267*61046927SAndroid Build Coastguard Worker          check_do_depth_stencil_clear_with_draw(device, pass, subpass);
268*61046927SAndroid Build Coastguard Worker 
269*61046927SAndroid Build Coastguard Worker          /* VK_KHR_depth_stencil_resolve */
270*61046927SAndroid Build Coastguard Worker          const VkSubpassDescriptionDepthStencilResolve *resolve_desc =
271*61046927SAndroid Build Coastguard Worker             vk_find_struct_const(desc->pNext, SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE);
272*61046927SAndroid Build Coastguard Worker          const VkAttachmentReference2 *resolve_att =
273*61046927SAndroid Build Coastguard Worker             resolve_desc && resolve_desc->pDepthStencilResolveAttachment &&
274*61046927SAndroid Build Coastguard Worker             resolve_desc->pDepthStencilResolveAttachment->attachment != VK_ATTACHMENT_UNUSED ?
275*61046927SAndroid Build Coastguard Worker                resolve_desc->pDepthStencilResolveAttachment : NULL;
276*61046927SAndroid Build Coastguard Worker          if (resolve_att) {
277*61046927SAndroid Build Coastguard Worker             subpass->ds_resolve_attachment = (struct v3dv_subpass_attachment) {
278*61046927SAndroid Build Coastguard Worker                .attachment = resolve_att->attachment,
279*61046927SAndroid Build Coastguard Worker                .layout = resolve_att->layout,
280*61046927SAndroid Build Coastguard Worker             };
281*61046927SAndroid Build Coastguard Worker             assert(resolve_desc->depthResolveMode == VK_RESOLVE_MODE_SAMPLE_ZERO_BIT ||
282*61046927SAndroid Build Coastguard Worker                    resolve_desc->stencilResolveMode == VK_RESOLVE_MODE_SAMPLE_ZERO_BIT);
283*61046927SAndroid Build Coastguard Worker             subpass->resolve_depth =
284*61046927SAndroid Build Coastguard Worker                resolve_desc->depthResolveMode != VK_RESOLVE_MODE_NONE &&
285*61046927SAndroid Build Coastguard Worker                resolve_att->aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT;
286*61046927SAndroid Build Coastguard Worker             subpass->resolve_stencil =
287*61046927SAndroid Build Coastguard Worker                resolve_desc->stencilResolveMode != VK_RESOLVE_MODE_NONE &&
288*61046927SAndroid Build Coastguard Worker                resolve_att->aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT;
289*61046927SAndroid Build Coastguard Worker          } else {
290*61046927SAndroid Build Coastguard Worker             subpass->ds_resolve_attachment.attachment = VK_ATTACHMENT_UNUSED;
291*61046927SAndroid Build Coastguard Worker             subpass->resolve_depth = false;
292*61046927SAndroid Build Coastguard Worker             subpass->resolve_stencil = false;
293*61046927SAndroid Build Coastguard Worker          }
294*61046927SAndroid Build Coastguard Worker       } else {
295*61046927SAndroid Build Coastguard Worker          subpass->ds_attachment.attachment = VK_ATTACHMENT_UNUSED;
296*61046927SAndroid Build Coastguard Worker          subpass->ds_resolve_attachment.attachment = VK_ATTACHMENT_UNUSED;
297*61046927SAndroid Build Coastguard Worker          subpass->resolve_depth = false;
298*61046927SAndroid Build Coastguard Worker          subpass->resolve_stencil = false;
299*61046927SAndroid Build Coastguard Worker       }
300*61046927SAndroid Build Coastguard Worker    }
301*61046927SAndroid Build Coastguard Worker 
302*61046927SAndroid Build Coastguard Worker    pass_find_subpass_range_for_attachments(device, pass);
303*61046927SAndroid Build Coastguard Worker 
304*61046927SAndroid Build Coastguard Worker    /* FIXME: handle subpass dependencies */
305*61046927SAndroid Build Coastguard Worker 
306*61046927SAndroid Build Coastguard Worker    *pRenderPass = v3dv_render_pass_to_handle(pass);
307*61046927SAndroid Build Coastguard Worker 
308*61046927SAndroid Build Coastguard Worker    return VK_SUCCESS;
309*61046927SAndroid Build Coastguard Worker }
310*61046927SAndroid Build Coastguard Worker 
311*61046927SAndroid Build Coastguard Worker VKAPI_ATTR void VKAPI_CALL
v3dv_DestroyRenderPass(VkDevice _device,VkRenderPass _pass,const VkAllocationCallbacks * pAllocator)312*61046927SAndroid Build Coastguard Worker v3dv_DestroyRenderPass(VkDevice _device,
313*61046927SAndroid Build Coastguard Worker                        VkRenderPass _pass,
314*61046927SAndroid Build Coastguard Worker                        const VkAllocationCallbacks *pAllocator)
315*61046927SAndroid Build Coastguard Worker {
316*61046927SAndroid Build Coastguard Worker    V3DV_FROM_HANDLE(v3dv_device, device, _device);
317*61046927SAndroid Build Coastguard Worker    V3DV_FROM_HANDLE(v3dv_render_pass, pass, _pass);
318*61046927SAndroid Build Coastguard Worker 
319*61046927SAndroid Build Coastguard Worker    if (!_pass)
320*61046927SAndroid Build Coastguard Worker       return;
321*61046927SAndroid Build Coastguard Worker 
322*61046927SAndroid Build Coastguard Worker    vk_free2(&device->vk.alloc, pAllocator, pass->subpass_attachments);
323*61046927SAndroid Build Coastguard Worker    vk_object_free(&device->vk, pAllocator, pass);
324*61046927SAndroid Build Coastguard Worker }
325*61046927SAndroid Build Coastguard Worker 
326*61046927SAndroid Build Coastguard Worker static void
get_granularity(struct v3dv_device * device,uint32_t count,const VkFormat * formats,bool msaa,VkExtent2D * granularity)327*61046927SAndroid Build Coastguard Worker get_granularity(struct v3dv_device *device,
328*61046927SAndroid Build Coastguard Worker                 uint32_t count,
329*61046927SAndroid Build Coastguard Worker                 const VkFormat *formats,
330*61046927SAndroid Build Coastguard Worker                 bool msaa,
331*61046927SAndroid Build Coastguard Worker                 VkExtent2D *granularity)
332*61046927SAndroid Build Coastguard Worker {
333*61046927SAndroid Build Coastguard Worker    uint32_t max_internal_bpp = 0;
334*61046927SAndroid Build Coastguard Worker    uint32_t total_color_bpp = 0;
335*61046927SAndroid Build Coastguard Worker    for (int i = 0; i < count; i++) {
336*61046927SAndroid Build Coastguard Worker       const struct v3dv_format *format = v3dv_X(device, get_format)(formats[i]);
337*61046927SAndroid Build Coastguard Worker       assert(format);
338*61046927SAndroid Build Coastguard Worker       /* We don't support rendering to YCbCr images */
339*61046927SAndroid Build Coastguard Worker       assert(format->plane_count == 1);
340*61046927SAndroid Build Coastguard Worker 
341*61046927SAndroid Build Coastguard Worker       uint32_t internal_type, internal_bpp;
342*61046927SAndroid Build Coastguard Worker       v3dv_X(device, get_internal_type_bpp_for_output_format)
343*61046927SAndroid Build Coastguard Worker          (format->planes[0].rt_type, &internal_type, &internal_bpp);
344*61046927SAndroid Build Coastguard Worker 
345*61046927SAndroid Build Coastguard Worker       max_internal_bpp = MAX2(max_internal_bpp, internal_bpp);
346*61046927SAndroid Build Coastguard Worker       total_color_bpp += 4 * v3d_internal_bpp_words(internal_bpp);
347*61046927SAndroid Build Coastguard Worker    }
348*61046927SAndroid Build Coastguard Worker 
349*61046927SAndroid Build Coastguard Worker    /* If requested, double-buffer may or may not be enabled depending on
350*61046927SAndroid Build Coastguard Worker     * heuristics so we choose a conservative granularity here, with it disabled.
351*61046927SAndroid Build Coastguard Worker     */
352*61046927SAndroid Build Coastguard Worker    uint32_t width, height;
353*61046927SAndroid Build Coastguard Worker    v3d_choose_tile_size(&device->devinfo, count,
354*61046927SAndroid Build Coastguard Worker                         max_internal_bpp, total_color_bpp, msaa,
355*61046927SAndroid Build Coastguard Worker                         false /* double-buffer */, &width, &height);
356*61046927SAndroid Build Coastguard Worker    *granularity = (VkExtent2D) {
357*61046927SAndroid Build Coastguard Worker       .width = width,
358*61046927SAndroid Build Coastguard Worker       .height = height
359*61046927SAndroid Build Coastguard Worker    };
360*61046927SAndroid Build Coastguard Worker }
361*61046927SAndroid Build Coastguard Worker 
362*61046927SAndroid Build Coastguard Worker static void
subpass_get_granularity(struct v3dv_device * device,struct v3dv_render_pass * pass,uint32_t subpass_idx,VkExtent2D * granularity)363*61046927SAndroid Build Coastguard Worker subpass_get_granularity(struct v3dv_device *device,
364*61046927SAndroid Build Coastguard Worker                         struct v3dv_render_pass *pass,
365*61046927SAndroid Build Coastguard Worker                         uint32_t subpass_idx,
366*61046927SAndroid Build Coastguard Worker                         VkExtent2D *granularity)
367*61046927SAndroid Build Coastguard Worker {
368*61046927SAndroid Build Coastguard Worker    /* Granularity is defined by the tile size */
369*61046927SAndroid Build Coastguard Worker    assert(subpass_idx < pass->subpass_count);
370*61046927SAndroid Build Coastguard Worker    struct v3dv_subpass *subpass = &pass->subpasses[subpass_idx];
371*61046927SAndroid Build Coastguard Worker    const uint32_t subpass_color_count = subpass->color_count;
372*61046927SAndroid Build Coastguard Worker    assert(subpass_color_count <= V3D_MAX_DRAW_BUFFERS);
373*61046927SAndroid Build Coastguard Worker 
374*61046927SAndroid Build Coastguard Worker    VkFormat formats[V3D_MAX_DRAW_BUFFERS];
375*61046927SAndroid Build Coastguard Worker    bool msaa = false;
376*61046927SAndroid Build Coastguard Worker    uint32_t color_count = 0;
377*61046927SAndroid Build Coastguard Worker    for (uint32_t i = 0; i < subpass_color_count; i++) {
378*61046927SAndroid Build Coastguard Worker       uint32_t attachment_idx = subpass->color_attachments[i].attachment;
379*61046927SAndroid Build Coastguard Worker       if (attachment_idx == VK_ATTACHMENT_UNUSED)
380*61046927SAndroid Build Coastguard Worker          continue;
381*61046927SAndroid Build Coastguard Worker       const VkAttachmentDescription2 *desc =
382*61046927SAndroid Build Coastguard Worker          &pass->attachments[attachment_idx].desc;
383*61046927SAndroid Build Coastguard Worker       formats[color_count++] = desc->format;
384*61046927SAndroid Build Coastguard Worker       if (desc->samples > VK_SAMPLE_COUNT_1_BIT)
385*61046927SAndroid Build Coastguard Worker          msaa = true;
386*61046927SAndroid Build Coastguard Worker    }
387*61046927SAndroid Build Coastguard Worker 
388*61046927SAndroid Build Coastguard Worker    get_granularity(device, color_count, formats, msaa, granularity);
389*61046927SAndroid Build Coastguard Worker }
390*61046927SAndroid Build Coastguard Worker 
391*61046927SAndroid Build Coastguard Worker VKAPI_ATTR void VKAPI_CALL
v3dv_GetRenderAreaGranularity(VkDevice _device,VkRenderPass renderPass,VkExtent2D * pGranularity)392*61046927SAndroid Build Coastguard Worker v3dv_GetRenderAreaGranularity(VkDevice _device,
393*61046927SAndroid Build Coastguard Worker                               VkRenderPass renderPass,
394*61046927SAndroid Build Coastguard Worker                               VkExtent2D *pGranularity)
395*61046927SAndroid Build Coastguard Worker {
396*61046927SAndroid Build Coastguard Worker    V3DV_FROM_HANDLE(v3dv_render_pass, pass, renderPass);
397*61046927SAndroid Build Coastguard Worker    V3DV_FROM_HANDLE(v3dv_device, device, _device);
398*61046927SAndroid Build Coastguard Worker 
399*61046927SAndroid Build Coastguard Worker    *pGranularity = (VkExtent2D) {
400*61046927SAndroid Build Coastguard Worker       .width = 64,
401*61046927SAndroid Build Coastguard Worker       .height = 64,
402*61046927SAndroid Build Coastguard Worker    };
403*61046927SAndroid Build Coastguard Worker 
404*61046927SAndroid Build Coastguard Worker    for (uint32_t i = 0; i < pass->subpass_count; i++) {
405*61046927SAndroid Build Coastguard Worker       VkExtent2D sg;
406*61046927SAndroid Build Coastguard Worker       subpass_get_granularity(device, pass, i, &sg);
407*61046927SAndroid Build Coastguard Worker       pGranularity->width = MIN2(pGranularity->width, sg.width);
408*61046927SAndroid Build Coastguard Worker       pGranularity->height = MIN2(pGranularity->height, sg.height);
409*61046927SAndroid Build Coastguard Worker    }
410*61046927SAndroid Build Coastguard Worker }
411*61046927SAndroid Build Coastguard Worker 
412*61046927SAndroid Build Coastguard Worker /* This is for dynamic rendering, introduced with VK_KHR_maintenance5 */
413*61046927SAndroid Build Coastguard Worker VKAPI_ATTR void VKAPI_CALL
v3dv_GetRenderingAreaGranularityKHR(VkDevice _device,const VkRenderingAreaInfoKHR * pRenderingAreaInfo,VkExtent2D * pGranularity)414*61046927SAndroid Build Coastguard Worker v3dv_GetRenderingAreaGranularityKHR(VkDevice _device,
415*61046927SAndroid Build Coastguard Worker                                     const VkRenderingAreaInfoKHR *pRenderingAreaInfo,
416*61046927SAndroid Build Coastguard Worker                                     VkExtent2D *pGranularity)
417*61046927SAndroid Build Coastguard Worker {
418*61046927SAndroid Build Coastguard Worker    V3DV_FROM_HANDLE(v3dv_device, device, _device);
419*61046927SAndroid Build Coastguard Worker 
420*61046927SAndroid Build Coastguard Worker    /* Since VkRenderingAreaInfoKHR doesn't include information about MSAA we
421*61046927SAndroid Build Coastguard Worker     * choose to compute granularity as if it was disabled which would give us
422*61046927SAndroid Build Coastguard Worker     * the largest granularity (worst case).
423*61046927SAndroid Build Coastguard Worker     */
424*61046927SAndroid Build Coastguard Worker    get_granularity(device,
425*61046927SAndroid Build Coastguard Worker                    pRenderingAreaInfo->colorAttachmentCount,
426*61046927SAndroid Build Coastguard Worker                    pRenderingAreaInfo->pColorAttachmentFormats,
427*61046927SAndroid Build Coastguard Worker                    false /* msaa */,
428*61046927SAndroid Build Coastguard Worker                    pGranularity);
429*61046927SAndroid Build Coastguard Worker }
430*61046927SAndroid Build Coastguard Worker 
431*61046927SAndroid Build Coastguard Worker /* Checks whether the render area rectangle covers a region that is aligned to
432*61046927SAndroid Build Coastguard Worker  * tile boundaries. This means that we are writing to all pixels covered by
433*61046927SAndroid Build Coastguard Worker  * all tiles in that area (except for pixels on edge tiles that are outside
434*61046927SAndroid Build Coastguard Worker  * the framebuffer dimensions).
435*61046927SAndroid Build Coastguard Worker  *
436*61046927SAndroid Build Coastguard Worker  * When our framebuffer is aligned to tile boundaries we know we are writing
437*61046927SAndroid Build Coastguard Worker  * valid data to all all pixels in each tile and we can apply certain
438*61046927SAndroid Build Coastguard Worker  * optimizations, like avoiding tile loads, since we know that none of the
439*61046927SAndroid Build Coastguard Worker  * original pixel values in each tile for that area need to be preserved.
440*61046927SAndroid Build Coastguard Worker  * We also use this to decide if we can use TLB clears, as these clear whole
441*61046927SAndroid Build Coastguard Worker  * tiles so we can't use them if the render area is not aligned.
442*61046927SAndroid Build Coastguard Worker  *
443*61046927SAndroid Build Coastguard Worker  * Note that when an image is created it will possibly include padding blocks
444*61046927SAndroid Build Coastguard Worker  * depending on its tiling layout. When the framebuffer dimensions are not
445*61046927SAndroid Build Coastguard Worker  * aligned to tile boundaries then edge tiles are only partially covered by the
446*61046927SAndroid Build Coastguard Worker  * framebuffer pixels, but tile stores still seem to store full tiles
447*61046927SAndroid Build Coastguard Worker  * writing to the padded sections. This is important when the framebuffer
448*61046927SAndroid Build Coastguard Worker  * is aliasing a smaller section of a larger image, as in that case the edge
449*61046927SAndroid Build Coastguard Worker  * tiles of the framebuffer would overwrite valid pixels in the larger image.
450*61046927SAndroid Build Coastguard Worker  * In that case, we can't flag the area as being aligned.
451*61046927SAndroid Build Coastguard Worker  */
452*61046927SAndroid Build Coastguard Worker bool
v3dv_subpass_area_is_tile_aligned(struct v3dv_device * device,const VkRect2D * area,struct v3dv_framebuffer * fb,struct v3dv_render_pass * pass,uint32_t subpass_idx)453*61046927SAndroid Build Coastguard Worker v3dv_subpass_area_is_tile_aligned(struct v3dv_device *device,
454*61046927SAndroid Build Coastguard Worker                                   const VkRect2D *area,
455*61046927SAndroid Build Coastguard Worker                                   struct v3dv_framebuffer *fb,
456*61046927SAndroid Build Coastguard Worker                                   struct v3dv_render_pass *pass,
457*61046927SAndroid Build Coastguard Worker                                   uint32_t subpass_idx)
458*61046927SAndroid Build Coastguard Worker {
459*61046927SAndroid Build Coastguard Worker    assert(subpass_idx < pass->subpass_count);
460*61046927SAndroid Build Coastguard Worker 
461*61046927SAndroid Build Coastguard Worker    VkExtent2D granularity;
462*61046927SAndroid Build Coastguard Worker    subpass_get_granularity(device, pass, subpass_idx, &granularity);
463*61046927SAndroid Build Coastguard Worker 
464*61046927SAndroid Build Coastguard Worker    return area->offset.x % granularity.width == 0 &&
465*61046927SAndroid Build Coastguard Worker           area->offset.y % granularity.height == 0 &&
466*61046927SAndroid Build Coastguard Worker          (area->extent.width % granularity.width == 0 ||
467*61046927SAndroid Build Coastguard Worker           (fb->has_edge_padding &&
468*61046927SAndroid Build Coastguard Worker            area->offset.x + area->extent.width >= fb->width)) &&
469*61046927SAndroid Build Coastguard Worker          (area->extent.height % granularity.height == 0 ||
470*61046927SAndroid Build Coastguard Worker           (fb->has_edge_padding &&
471*61046927SAndroid Build Coastguard Worker            area->offset.y + area->extent.height >= fb->height));
472*61046927SAndroid Build Coastguard Worker }
473*61046927SAndroid Build Coastguard Worker 
474*61046927SAndroid Build Coastguard Worker static void
setup_dynamic_attachment(struct v3dv_device * device,struct v3dv_render_pass_attachment * att,const VkRenderingAttachmentInfo * info,bool is_stencil,bool is_resolve)475*61046927SAndroid Build Coastguard Worker setup_dynamic_attachment(struct v3dv_device *device,
476*61046927SAndroid Build Coastguard Worker                          struct v3dv_render_pass_attachment *att,
477*61046927SAndroid Build Coastguard Worker                          const VkRenderingAttachmentInfo *info,
478*61046927SAndroid Build Coastguard Worker                          bool is_stencil,
479*61046927SAndroid Build Coastguard Worker                          bool is_resolve)
480*61046927SAndroid Build Coastguard Worker {
481*61046927SAndroid Build Coastguard Worker    struct v3dv_image_view *view = v3dv_image_view_from_handle(info->imageView);
482*61046927SAndroid Build Coastguard Worker 
483*61046927SAndroid Build Coastguard Worker    VkAttachmentLoadOp load_op, stencil_load_op;
484*61046927SAndroid Build Coastguard Worker    VkAttachmentStoreOp store_op, stencil_store_op;
485*61046927SAndroid Build Coastguard Worker 
486*61046927SAndroid Build Coastguard Worker    if (!is_stencil) {
487*61046927SAndroid Build Coastguard Worker       stencil_load_op = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
488*61046927SAndroid Build Coastguard Worker       stencil_store_op = VK_ATTACHMENT_STORE_OP_DONT_CARE;
489*61046927SAndroid Build Coastguard Worker       if (!is_resolve) {
490*61046927SAndroid Build Coastguard Worker          load_op = info->loadOp;
491*61046927SAndroid Build Coastguard Worker          store_op = info->storeOp;
492*61046927SAndroid Build Coastguard Worker       } else {
493*61046927SAndroid Build Coastguard Worker          load_op = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
494*61046927SAndroid Build Coastguard Worker          store_op = VK_ATTACHMENT_STORE_OP_STORE;
495*61046927SAndroid Build Coastguard Worker       }
496*61046927SAndroid Build Coastguard Worker    } else {
497*61046927SAndroid Build Coastguard Worker       load_op = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
498*61046927SAndroid Build Coastguard Worker       store_op = VK_ATTACHMENT_STORE_OP_DONT_CARE;
499*61046927SAndroid Build Coastguard Worker       if (!is_resolve) {
500*61046927SAndroid Build Coastguard Worker          stencil_load_op = info->loadOp;
501*61046927SAndroid Build Coastguard Worker          stencil_store_op = info->storeOp;
502*61046927SAndroid Build Coastguard Worker       } else {
503*61046927SAndroid Build Coastguard Worker          stencil_load_op = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
504*61046927SAndroid Build Coastguard Worker          stencil_store_op = VK_ATTACHMENT_STORE_OP_STORE;
505*61046927SAndroid Build Coastguard Worker       }
506*61046927SAndroid Build Coastguard Worker    }
507*61046927SAndroid Build Coastguard Worker 
508*61046927SAndroid Build Coastguard Worker    att->desc = (VkAttachmentDescription2) {
509*61046927SAndroid Build Coastguard Worker       .sType = VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2,
510*61046927SAndroid Build Coastguard Worker       .flags = 0,
511*61046927SAndroid Build Coastguard Worker       .format = view->vk.format,
512*61046927SAndroid Build Coastguard Worker       .samples = view->vk.image->samples,
513*61046927SAndroid Build Coastguard Worker       .loadOp = load_op,
514*61046927SAndroid Build Coastguard Worker       .storeOp = store_op,
515*61046927SAndroid Build Coastguard Worker       .stencilLoadOp = stencil_load_op,
516*61046927SAndroid Build Coastguard Worker       .stencilStoreOp = stencil_store_op,
517*61046927SAndroid Build Coastguard Worker       .initialLayout = info->imageLayout,
518*61046927SAndroid Build Coastguard Worker       .finalLayout = info->imageLayout,
519*61046927SAndroid Build Coastguard Worker    };
520*61046927SAndroid Build Coastguard Worker 
521*61046927SAndroid Build Coastguard Worker    if (is_resolve)
522*61046927SAndroid Build Coastguard Worker       set_try_tlb_resolve(device, att);
523*61046927SAndroid Build Coastguard Worker }
524*61046927SAndroid Build Coastguard Worker 
525*61046927SAndroid Build Coastguard Worker void
v3dv_setup_dynamic_render_pass(struct v3dv_cmd_buffer * cmd_buffer,const VkRenderingInfoKHR * info)526*61046927SAndroid Build Coastguard Worker v3dv_setup_dynamic_render_pass(struct v3dv_cmd_buffer *cmd_buffer,
527*61046927SAndroid Build Coastguard Worker                                const VkRenderingInfoKHR *info)
528*61046927SAndroid Build Coastguard Worker {
529*61046927SAndroid Build Coastguard Worker    struct v3dv_device *device = cmd_buffer->device;
530*61046927SAndroid Build Coastguard Worker    struct v3dv_cmd_buffer_state *state = &cmd_buffer->state;
531*61046927SAndroid Build Coastguard Worker 
532*61046927SAndroid Build Coastguard Worker    struct v3dv_render_pass *pass = &state->dynamic_pass;
533*61046927SAndroid Build Coastguard Worker    struct v3dv_subpass *subpass = &state->dynamic_subpass;
534*61046927SAndroid Build Coastguard Worker    struct v3dv_render_pass_attachment *pass_attachments =
535*61046927SAndroid Build Coastguard Worker       &state->dynamic_attachments[0];
536*61046927SAndroid Build Coastguard Worker    struct v3dv_subpass_attachment *subpass_attachments =
537*61046927SAndroid Build Coastguard Worker       &state->dynamic_subpass_attachments[0];
538*61046927SAndroid Build Coastguard Worker 
539*61046927SAndroid Build Coastguard Worker    memset(pass, 0, sizeof(*pass));
540*61046927SAndroid Build Coastguard Worker    memset(subpass, 0, sizeof(*subpass));
541*61046927SAndroid Build Coastguard Worker    memset(pass_attachments, 0, sizeof(state->dynamic_subpass_attachments));
542*61046927SAndroid Build Coastguard Worker    memset(subpass_attachments, 0, sizeof(state->dynamic_subpass_attachments));
543*61046927SAndroid Build Coastguard Worker 
544*61046927SAndroid Build Coastguard Worker    vk_object_base_init(&device->vk, (struct vk_object_base *) pass,
545*61046927SAndroid Build Coastguard Worker                        VK_OBJECT_TYPE_RENDER_PASS);
546*61046927SAndroid Build Coastguard Worker 
547*61046927SAndroid Build Coastguard Worker    pass->attachments = pass_attachments;
548*61046927SAndroid Build Coastguard Worker    pass->subpass_attachments = subpass_attachments;
549*61046927SAndroid Build Coastguard Worker 
550*61046927SAndroid Build Coastguard Worker    subpass->view_mask = info->viewMask;
551*61046927SAndroid Build Coastguard Worker    subpass->color_count = info->colorAttachmentCount;
552*61046927SAndroid Build Coastguard Worker    subpass->color_attachments = &subpass_attachments[0];
553*61046927SAndroid Build Coastguard Worker    subpass->resolve_attachments = &subpass_attachments[subpass->color_count];
554*61046927SAndroid Build Coastguard Worker 
555*61046927SAndroid Build Coastguard Worker    pass->multiview_enabled = info->viewMask != 0;
556*61046927SAndroid Build Coastguard Worker    pass->subpass_count = 1;
557*61046927SAndroid Build Coastguard Worker    pass->subpasses = subpass;
558*61046927SAndroid Build Coastguard Worker 
559*61046927SAndroid Build Coastguard Worker    int a = 0;
560*61046927SAndroid Build Coastguard Worker    for (int i = 0; i < info->colorAttachmentCount; i++) {
561*61046927SAndroid Build Coastguard Worker       struct v3dv_render_pass_attachment *att = &pass->attachments[a];
562*61046927SAndroid Build Coastguard Worker       const VkRenderingAttachmentInfo *att_info = &info->pColorAttachments[i];
563*61046927SAndroid Build Coastguard Worker 
564*61046927SAndroid Build Coastguard Worker       if (att_info->imageView == VK_NULL_HANDLE) {
565*61046927SAndroid Build Coastguard Worker          subpass->color_attachments[i].attachment = VK_ATTACHMENT_UNUSED;
566*61046927SAndroid Build Coastguard Worker          subpass->resolve_attachments[i].attachment = VK_ATTACHMENT_UNUSED;
567*61046927SAndroid Build Coastguard Worker          continue;
568*61046927SAndroid Build Coastguard Worker       }
569*61046927SAndroid Build Coastguard Worker 
570*61046927SAndroid Build Coastguard Worker       setup_dynamic_attachment(device, att, att_info, false, false);
571*61046927SAndroid Build Coastguard Worker       subpass->color_attachments[i].attachment = a++;
572*61046927SAndroid Build Coastguard Worker       subpass->color_attachments[i].layout = att_info->imageLayout;
573*61046927SAndroid Build Coastguard Worker 
574*61046927SAndroid Build Coastguard Worker       if (att_info->resolveMode != VK_RESOLVE_MODE_NONE) {
575*61046927SAndroid Build Coastguard Worker          struct v3dv_render_pass_attachment *resolve_att = &pass->attachments[a];
576*61046927SAndroid Build Coastguard Worker          setup_dynamic_attachment(device, resolve_att, att_info, false, true);
577*61046927SAndroid Build Coastguard Worker          subpass->resolve_attachments[i].attachment = a++;
578*61046927SAndroid Build Coastguard Worker          subpass->resolve_attachments[i].layout = att_info->resolveImageLayout;
579*61046927SAndroid Build Coastguard Worker       } else {
580*61046927SAndroid Build Coastguard Worker          subpass->resolve_attachments[i].attachment = VK_ATTACHMENT_UNUSED;
581*61046927SAndroid Build Coastguard Worker       }
582*61046927SAndroid Build Coastguard Worker    }
583*61046927SAndroid Build Coastguard Worker 
584*61046927SAndroid Build Coastguard Worker    bool has_depth = info->pDepthAttachment &&
585*61046927SAndroid Build Coastguard Worker                     info->pDepthAttachment->imageView != VK_NULL_HANDLE;
586*61046927SAndroid Build Coastguard Worker    bool has_stencil = info->pStencilAttachment &&
587*61046927SAndroid Build Coastguard Worker                       info->pStencilAttachment->imageView != VK_NULL_HANDLE;
588*61046927SAndroid Build Coastguard Worker    if (has_depth || has_stencil) {
589*61046927SAndroid Build Coastguard Worker       struct v3dv_render_pass_attachment *att = &pass->attachments[a];
590*61046927SAndroid Build Coastguard Worker       subpass->ds_attachment.attachment = a++;
591*61046927SAndroid Build Coastguard Worker 
592*61046927SAndroid Build Coastguard Worker       bool has_depth_resolve = false;
593*61046927SAndroid Build Coastguard Worker       bool has_stencil_resolve = false;
594*61046927SAndroid Build Coastguard Worker 
595*61046927SAndroid Build Coastguard Worker       if (has_depth) {
596*61046927SAndroid Build Coastguard Worker          setup_dynamic_attachment(device, att, info->pDepthAttachment,
597*61046927SAndroid Build Coastguard Worker                                   false, false);
598*61046927SAndroid Build Coastguard Worker          subpass->ds_attachment.layout = info->pDepthAttachment->imageLayout;
599*61046927SAndroid Build Coastguard Worker          has_depth_resolve =
600*61046927SAndroid Build Coastguard Worker             info->pDepthAttachment->resolveMode != VK_RESOLVE_MODE_NONE;
601*61046927SAndroid Build Coastguard Worker       }
602*61046927SAndroid Build Coastguard Worker 
603*61046927SAndroid Build Coastguard Worker       if (has_stencil) {
604*61046927SAndroid Build Coastguard Worker          if (has_depth) {
605*61046927SAndroid Build Coastguard Worker             att->desc.stencilLoadOp = info->pStencilAttachment->loadOp;
606*61046927SAndroid Build Coastguard Worker             att->desc.stencilStoreOp = info->pStencilAttachment->storeOp;
607*61046927SAndroid Build Coastguard Worker          } else {
608*61046927SAndroid Build Coastguard Worker             setup_dynamic_attachment(device, att, info->pStencilAttachment,
609*61046927SAndroid Build Coastguard Worker                                      true, false);
610*61046927SAndroid Build Coastguard Worker             subpass->ds_attachment.layout =
611*61046927SAndroid Build Coastguard Worker                info->pStencilAttachment->imageLayout;
612*61046927SAndroid Build Coastguard Worker          }
613*61046927SAndroid Build Coastguard Worker          has_stencil_resolve =
614*61046927SAndroid Build Coastguard Worker             info->pStencilAttachment->resolveMode != VK_RESOLVE_MODE_NONE;
615*61046927SAndroid Build Coastguard Worker       }
616*61046927SAndroid Build Coastguard Worker 
617*61046927SAndroid Build Coastguard Worker       if (has_depth_resolve || has_stencil_resolve) {
618*61046927SAndroid Build Coastguard Worker          struct v3dv_render_pass_attachment *att = &pass->attachments[a];
619*61046927SAndroid Build Coastguard Worker          subpass->ds_resolve_attachment.attachment = a++;
620*61046927SAndroid Build Coastguard Worker          if (has_depth_resolve) {
621*61046927SAndroid Build Coastguard Worker             setup_dynamic_attachment(device, att, info->pDepthAttachment,
622*61046927SAndroid Build Coastguard Worker                                      false, true);
623*61046927SAndroid Build Coastguard Worker             subpass->ds_resolve_attachment.layout =
624*61046927SAndroid Build Coastguard Worker                info->pDepthAttachment->resolveImageLayout;
625*61046927SAndroid Build Coastguard Worker             subpass->resolve_depth = true;
626*61046927SAndroid Build Coastguard Worker          }
627*61046927SAndroid Build Coastguard Worker          if (has_stencil_resolve) {
628*61046927SAndroid Build Coastguard Worker             if (has_depth_resolve) {
629*61046927SAndroid Build Coastguard Worker                att->desc.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
630*61046927SAndroid Build Coastguard Worker                att->desc.stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE;
631*61046927SAndroid Build Coastguard Worker             } else {
632*61046927SAndroid Build Coastguard Worker                setup_dynamic_attachment(device, att, info->pStencilAttachment,
633*61046927SAndroid Build Coastguard Worker                                         true, true);
634*61046927SAndroid Build Coastguard Worker                subpass->ds_resolve_attachment.layout =
635*61046927SAndroid Build Coastguard Worker                   info->pStencilAttachment->resolveImageLayout;
636*61046927SAndroid Build Coastguard Worker             }
637*61046927SAndroid Build Coastguard Worker             subpass->resolve_stencil = true;
638*61046927SAndroid Build Coastguard Worker          }
639*61046927SAndroid Build Coastguard Worker       } else {
640*61046927SAndroid Build Coastguard Worker          subpass->ds_resolve_attachment.attachment = VK_ATTACHMENT_UNUSED;
641*61046927SAndroid Build Coastguard Worker       }
642*61046927SAndroid Build Coastguard Worker    } else {
643*61046927SAndroid Build Coastguard Worker       subpass->ds_attachment.attachment = VK_ATTACHMENT_UNUSED;
644*61046927SAndroid Build Coastguard Worker    }
645*61046927SAndroid Build Coastguard Worker 
646*61046927SAndroid Build Coastguard Worker    check_do_depth_stencil_clear_with_draw(device, pass, subpass);
647*61046927SAndroid Build Coastguard Worker 
648*61046927SAndroid Build Coastguard Worker    pass->attachment_count = a;
649*61046927SAndroid Build Coastguard Worker }
650*61046927SAndroid Build Coastguard Worker 
651*61046927SAndroid Build Coastguard Worker void
v3dv_setup_dynamic_render_pass_inheritance(struct v3dv_cmd_buffer * cmd_buffer,const VkCommandBufferInheritanceRenderingInfo * info)652*61046927SAndroid Build Coastguard Worker v3dv_setup_dynamic_render_pass_inheritance(struct v3dv_cmd_buffer *cmd_buffer,
653*61046927SAndroid Build Coastguard Worker                                            const VkCommandBufferInheritanceRenderingInfo *info)
654*61046927SAndroid Build Coastguard Worker {
655*61046927SAndroid Build Coastguard Worker    struct v3dv_device *device = cmd_buffer->device;
656*61046927SAndroid Build Coastguard Worker    struct v3dv_cmd_buffer_state *state = &cmd_buffer->state;
657*61046927SAndroid Build Coastguard Worker 
658*61046927SAndroid Build Coastguard Worker    struct v3dv_render_pass *pass = &state->dynamic_pass;
659*61046927SAndroid Build Coastguard Worker    struct v3dv_subpass *subpass = &state->dynamic_subpass;
660*61046927SAndroid Build Coastguard Worker    struct v3dv_render_pass_attachment *pass_attachments =
661*61046927SAndroid Build Coastguard Worker       &state->dynamic_attachments[0];
662*61046927SAndroid Build Coastguard Worker    struct v3dv_subpass_attachment *subpass_attachments =
663*61046927SAndroid Build Coastguard Worker       &state->dynamic_subpass_attachments[0];
664*61046927SAndroid Build Coastguard Worker 
665*61046927SAndroid Build Coastguard Worker    memset(pass, 0, sizeof(*pass));
666*61046927SAndroid Build Coastguard Worker    memset(subpass, 0, sizeof(*subpass));
667*61046927SAndroid Build Coastguard Worker    memset(pass_attachments, 0, sizeof(state->dynamic_subpass_attachments));
668*61046927SAndroid Build Coastguard Worker    memset(subpass_attachments, 0, sizeof(state->dynamic_subpass_attachments));
669*61046927SAndroid Build Coastguard Worker 
670*61046927SAndroid Build Coastguard Worker    vk_object_base_init(&device->vk, (struct vk_object_base *) pass,
671*61046927SAndroid Build Coastguard Worker                        VK_OBJECT_TYPE_RENDER_PASS);
672*61046927SAndroid Build Coastguard Worker 
673*61046927SAndroid Build Coastguard Worker    pass->attachments = pass_attachments;
674*61046927SAndroid Build Coastguard Worker    pass->subpass_attachments = subpass_attachments;
675*61046927SAndroid Build Coastguard Worker 
676*61046927SAndroid Build Coastguard Worker    subpass->view_mask = info->viewMask;
677*61046927SAndroid Build Coastguard Worker    subpass->color_count = info->colorAttachmentCount;
678*61046927SAndroid Build Coastguard Worker    subpass->color_attachments = &subpass_attachments[0];
679*61046927SAndroid Build Coastguard Worker    subpass->resolve_attachments = NULL;
680*61046927SAndroid Build Coastguard Worker 
681*61046927SAndroid Build Coastguard Worker    pass->multiview_enabled = info->viewMask != 0;
682*61046927SAndroid Build Coastguard Worker    pass->subpass_count = 1;
683*61046927SAndroid Build Coastguard Worker    pass->subpasses = subpass;
684*61046927SAndroid Build Coastguard Worker 
685*61046927SAndroid Build Coastguard Worker    int a = 0;
686*61046927SAndroid Build Coastguard Worker    for (int i = 0; i < info->colorAttachmentCount; i++) {
687*61046927SAndroid Build Coastguard Worker       struct v3dv_render_pass_attachment *att = &pass->attachments[a];
688*61046927SAndroid Build Coastguard Worker       const VkFormat format = info->pColorAttachmentFormats[i];
689*61046927SAndroid Build Coastguard Worker 
690*61046927SAndroid Build Coastguard Worker       if (format == VK_FORMAT_UNDEFINED) {
691*61046927SAndroid Build Coastguard Worker          subpass->color_attachments[i].attachment = VK_ATTACHMENT_UNUSED;
692*61046927SAndroid Build Coastguard Worker          continue;
693*61046927SAndroid Build Coastguard Worker       }
694*61046927SAndroid Build Coastguard Worker 
695*61046927SAndroid Build Coastguard Worker       /* We don't have info about load/store, so we assume we load and we
696*61046927SAndroid Build Coastguard Worker        * store.
697*61046927SAndroid Build Coastguard Worker        */
698*61046927SAndroid Build Coastguard Worker       att->desc.format = format;
699*61046927SAndroid Build Coastguard Worker       att->desc.samples = info->rasterizationSamples;
700*61046927SAndroid Build Coastguard Worker       att->desc.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
701*61046927SAndroid Build Coastguard Worker       att->desc.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
702*61046927SAndroid Build Coastguard Worker       att->desc.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
703*61046927SAndroid Build Coastguard Worker       att->desc.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
704*61046927SAndroid Build Coastguard Worker       subpass->color_attachments[i].attachment = a++;
705*61046927SAndroid Build Coastguard Worker    }
706*61046927SAndroid Build Coastguard Worker 
707*61046927SAndroid Build Coastguard Worker    if (info->depthAttachmentFormat != VK_FORMAT_UNDEFINED ||
708*61046927SAndroid Build Coastguard Worker        info->stencilAttachmentFormat != VK_FORMAT_UNDEFINED) {
709*61046927SAndroid Build Coastguard Worker       struct v3dv_render_pass_attachment *att = &pass->attachments[a];
710*61046927SAndroid Build Coastguard Worker       att->desc.format = info->depthAttachmentFormat != VK_FORMAT_UNDEFINED ?
711*61046927SAndroid Build Coastguard Worker          info->depthAttachmentFormat : info->stencilAttachmentFormat;
712*61046927SAndroid Build Coastguard Worker       att->desc.samples = info->rasterizationSamples;
713*61046927SAndroid Build Coastguard Worker       if (vk_format_has_depth(att->desc.format)) {
714*61046927SAndroid Build Coastguard Worker          att->desc.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
715*61046927SAndroid Build Coastguard Worker          att->desc.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
716*61046927SAndroid Build Coastguard Worker       } else {
717*61046927SAndroid Build Coastguard Worker          att->desc.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
718*61046927SAndroid Build Coastguard Worker          att->desc.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
719*61046927SAndroid Build Coastguard Worker       }
720*61046927SAndroid Build Coastguard Worker       if (vk_format_has_stencil(att->desc.format)) {
721*61046927SAndroid Build Coastguard Worker          att->desc.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
722*61046927SAndroid Build Coastguard Worker          att->desc.stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE;
723*61046927SAndroid Build Coastguard Worker       } else {
724*61046927SAndroid Build Coastguard Worker          att->desc.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
725*61046927SAndroid Build Coastguard Worker          att->desc.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
726*61046927SAndroid Build Coastguard Worker       }
727*61046927SAndroid Build Coastguard Worker       subpass->ds_attachment.attachment = a++;
728*61046927SAndroid Build Coastguard Worker    } else {
729*61046927SAndroid Build Coastguard Worker       subpass->ds_attachment.attachment = VK_ATTACHMENT_UNUSED;
730*61046927SAndroid Build Coastguard Worker    }
731*61046927SAndroid Build Coastguard Worker 
732*61046927SAndroid Build Coastguard Worker    pass->attachment_count = a;
733*61046927SAndroid Build Coastguard Worker }
734