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