• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright © 2016 Red Hat.
3  * Copyright © 2016 Bas Nieuwenhuizen
4  *
5  * based in part on anv driver which is:
6  * Copyright © 2015 Intel Corporation
7  *
8  * Permission is hereby granted, free of charge, to any person obtaining a
9  * copy of this software and associated documentation files (the "Software"),
10  * to deal in the Software without restriction, including without limitation
11  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12  * and/or sell copies of the Software, and to permit persons to whom the
13  * Software is furnished to do so, subject to the following conditions:
14  *
15  * The above copyright notice and this permission notice (including the next
16  * paragraph) shall be included in all copies or substantial portions of the
17  * Software.
18  *
19  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
22  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
25  * IN THE SOFTWARE.
26  */
27 #include "radv_private.h"
28 
29 #include "vk_util.h"
30 
31 static void
radv_render_pass_add_subpass_dep(struct radv_render_pass * pass,const VkSubpassDependency2 * dep)32 radv_render_pass_add_subpass_dep(struct radv_render_pass *pass,
33 				 const VkSubpassDependency2 *dep)
34 {
35 	uint32_t src = dep->srcSubpass;
36 	uint32_t dst = dep->dstSubpass;
37 
38 	/* Ignore subpass self-dependencies as they allow the app to call
39 	 * vkCmdPipelineBarrier() inside the render pass and the driver should
40 	 * only do the barrier when called, not when starting the render pass.
41 	 */
42 	if (src == dst)
43 		return;
44 
45 	/* Accumulate all ingoing external dependencies to the first subpass. */
46 	if (src == VK_SUBPASS_EXTERNAL)
47 		dst = 0;
48 
49 	if (dst == VK_SUBPASS_EXTERNAL) {
50 		if (dep->dstStageMask != VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT)
51 			pass->end_barrier.src_stage_mask |= dep->srcStageMask;
52 		pass->end_barrier.src_access_mask |= dep->srcAccessMask;
53 		pass->end_barrier.dst_access_mask |= dep->dstAccessMask;
54 	} else {
55 		if (dep->dstStageMask != VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT)
56 			pass->subpasses[dst].start_barrier.src_stage_mask |= dep->srcStageMask;
57 		pass->subpasses[dst].start_barrier.src_access_mask |= dep->srcAccessMask;
58 		pass->subpasses[dst].start_barrier.dst_access_mask |= dep->dstAccessMask;
59 	}
60 }
61 
62 static bool
radv_pass_has_layout_transitions(const struct radv_render_pass * pass)63 radv_pass_has_layout_transitions(const struct radv_render_pass *pass)
64 {
65 	for (unsigned i = 0; i < pass->subpass_count; i++) {
66 		const struct radv_subpass *subpass = &pass->subpasses[i];
67 		for (unsigned j = 0; j < subpass->attachment_count; j++) {
68 			const uint32_t a = subpass->attachments[j].attachment;
69 			if (a == VK_ATTACHMENT_UNUSED)
70 				continue;
71 
72 			uint32_t initial_layout = pass->attachments[a].initial_layout;
73 			uint32_t stencil_initial_layout = pass->attachments[a].stencil_initial_layout;
74 			uint32_t final_layout = pass->attachments[a].final_layout;
75 			uint32_t stencil_final_layout = pass->attachments[a].stencil_final_layout;
76 
77 			if (subpass->attachments[j].layout != initial_layout ||
78 			    subpass->attachments[j].layout != stencil_initial_layout ||
79 			    subpass->attachments[j].layout != final_layout ||
80 			    subpass->attachments[j].layout != stencil_final_layout)
81 				return true;
82 		}
83 	}
84 
85 	return false;
86 }
87 
88 static void
radv_render_pass_add_implicit_deps(struct radv_render_pass * pass,bool has_ingoing_dep,bool has_outgoing_dep)89 radv_render_pass_add_implicit_deps(struct radv_render_pass *pass,
90 				   bool has_ingoing_dep, bool has_outgoing_dep)
91 {
92 	/* From the Vulkan 1.0.39 spec:
93 	*
94 	*    If there is no subpass dependency from VK_SUBPASS_EXTERNAL to the
95 	*    first subpass that uses an attachment, then an implicit subpass
96 	*    dependency exists from VK_SUBPASS_EXTERNAL to the first subpass it is
97 	*    used in. The implicit subpass dependency only exists if there
98 	*    exists an automatic layout transition away from initialLayout.
99 	*    The subpass dependency operates as if defined with the
100 	*    following parameters:
101 	*
102 	*    VkSubpassDependency implicitDependency = {
103 	*        .srcSubpass = VK_SUBPASS_EXTERNAL;
104 	*        .dstSubpass = firstSubpass; // First subpass attachment is used in
105 	*        .srcStageMask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
106 	*        .dstStageMask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
107 	*        .srcAccessMask = 0;
108 	*        .dstAccessMask = VK_ACCESS_INPUT_ATTACHMENT_READ_BIT |
109 	*                         VK_ACCESS_COLOR_ATTACHMENT_READ_BIT |
110 	*                         VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT |
111 	*                         VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT |
112 	*                         VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
113 	*        .dependencyFlags = 0;
114 	*    };
115 	*
116 	*    Similarly, if there is no subpass dependency from the last subpass
117 	*    that uses an attachment to VK_SUBPASS_EXTERNAL, then an implicit
118 	*    subpass dependency exists from the last subpass it is used in to
119 	*    VK_SUBPASS_EXTERNAL. The implicit subpass dependency only exists
120 	*    if there exists an automatic layout transition into finalLayout.
121 	*    The subpass dependency operates as if defined with the following
122 	*    parameters:
123 	*
124 	*    VkSubpassDependency implicitDependency = {
125 	*        .srcSubpass = lastSubpass; // Last subpass attachment is used in
126 	*        .dstSubpass = VK_SUBPASS_EXTERNAL;
127 	*        .srcStageMask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
128 	*        .dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
129 	*        .srcAccessMask = VK_ACCESS_INPUT_ATTACHMENT_READ_BIT |
130 	*                         VK_ACCESS_COLOR_ATTACHMENT_READ_BIT |
131 	*                         VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT |
132 	*                         VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT |
133 	*                         VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
134 	*        .dstAccessMask = 0;
135 	*        .dependencyFlags = 0;
136 	*    };
137 	*/
138 
139 	/* Implicit subpass dependencies only make sense if automatic layout
140 	 * transitions are performed.
141 	 */
142 	if (!radv_pass_has_layout_transitions(pass))
143 		return;
144 
145 	if (!has_ingoing_dep) {
146 		const VkSubpassDependency2KHR implicit_ingoing_dep = {
147 			.srcSubpass = VK_SUBPASS_EXTERNAL,
148 			.dstSubpass = 0,
149 			.srcStageMask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
150 			.dstStageMask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
151 			.srcAccessMask = 0,
152 			.dstAccessMask = VK_ACCESS_INPUT_ATTACHMENT_READ_BIT |
153 					 VK_ACCESS_COLOR_ATTACHMENT_READ_BIT |
154 					 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT |
155 					 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT |
156 					 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
157 			.dependencyFlags = 0,
158 		};
159 
160 		radv_render_pass_add_subpass_dep(pass, &implicit_ingoing_dep);
161 	}
162 
163 	if (!has_outgoing_dep) {
164 		const VkSubpassDependency2KHR implicit_outgoing_dep = {
165 			.srcSubpass = 0,
166 			.dstSubpass = VK_SUBPASS_EXTERNAL,
167 			.srcStageMask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
168 			.dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
169 			.srcAccessMask = VK_ACCESS_INPUT_ATTACHMENT_READ_BIT |
170 					 VK_ACCESS_COLOR_ATTACHMENT_READ_BIT |
171 					 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT |
172 					 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT |
173 					 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
174 			.dstAccessMask = 0,
175 			.dependencyFlags = 0,
176 		};
177 
178 		radv_render_pass_add_subpass_dep(pass, &implicit_outgoing_dep);
179 	}
180 }
181 
182 static void
radv_render_pass_compile(struct radv_render_pass * pass)183 radv_render_pass_compile(struct radv_render_pass *pass)
184 {
185 	for (uint32_t i = 0; i < pass->subpass_count; i++) {
186 		struct radv_subpass *subpass = &pass->subpasses[i];
187 
188 		for (uint32_t j = 0; j < subpass->attachment_count; j++) {
189 			struct radv_subpass_attachment *subpass_att =
190 				&subpass->attachments[j];
191 			if (subpass_att->attachment == VK_ATTACHMENT_UNUSED)
192 				continue;
193 
194 			struct radv_render_pass_attachment *pass_att =
195 				&pass->attachments[subpass_att->attachment];
196 
197 			pass_att->first_subpass_idx = UINT32_MAX;
198 		}
199 	}
200 
201 	for (uint32_t i = 0; i < pass->subpass_count; i++) {
202 		struct radv_subpass *subpass = &pass->subpasses[i];
203 		uint32_t color_sample_count = 1, depth_sample_count = 1;
204 
205 		/* We don't allow depth_stencil_attachment to be non-NULL and
206 		 * be VK_ATTACHMENT_UNUSED.  This way something can just check
207 		 * for NULL and be guaranteed that they have a valid
208 		 * attachment.
209 		 */
210 		if (subpass->depth_stencil_attachment &&
211 		    subpass->depth_stencil_attachment->attachment == VK_ATTACHMENT_UNUSED)
212 			subpass->depth_stencil_attachment = NULL;
213 
214 		if (subpass->ds_resolve_attachment &&
215 		    subpass->ds_resolve_attachment->attachment == VK_ATTACHMENT_UNUSED)
216 			subpass->ds_resolve_attachment = NULL;
217 
218 		for (uint32_t j = 0; j < subpass->attachment_count; j++) {
219 			struct radv_subpass_attachment *subpass_att =
220 				&subpass->attachments[j];
221 			if (subpass_att->attachment == VK_ATTACHMENT_UNUSED)
222 				continue;
223 
224 			struct radv_render_pass_attachment *pass_att =
225 				&pass->attachments[subpass_att->attachment];
226 
227 			if (i < pass_att->first_subpass_idx)
228 				pass_att->first_subpass_idx = i;
229 			pass_att->last_subpass_idx = i;
230 		}
231 
232 		subpass->has_color_att = false;
233 		for (uint32_t j = 0; j < subpass->color_count; j++) {
234 			struct radv_subpass_attachment *subpass_att =
235 				&subpass->color_attachments[j];
236 			if (subpass_att->attachment == VK_ATTACHMENT_UNUSED)
237 				continue;
238 
239 			subpass->has_color_att = true;
240 
241 			struct radv_render_pass_attachment *pass_att =
242 				&pass->attachments[subpass_att->attachment];
243 
244 			color_sample_count = pass_att->samples;
245 		}
246 
247 		if (subpass->depth_stencil_attachment) {
248 			const uint32_t a =
249 				subpass->depth_stencil_attachment->attachment;
250 			struct radv_render_pass_attachment *pass_att =
251 				&pass->attachments[a];
252 			depth_sample_count = pass_att->samples;
253 		}
254 
255 		subpass->max_sample_count = MAX2(color_sample_count,
256 						 depth_sample_count);
257 		subpass->color_sample_count = color_sample_count;
258 		subpass->depth_sample_count = depth_sample_count;
259 
260 		/* We have to handle resolve attachments specially */
261 		subpass->has_color_resolve = false;
262 		if (subpass->resolve_attachments) {
263 			for (uint32_t j = 0; j < subpass->color_count; j++) {
264 				struct radv_subpass_attachment *resolve_att =
265 					&subpass->resolve_attachments[j];
266 
267 				if (resolve_att->attachment == VK_ATTACHMENT_UNUSED)
268 					continue;
269 
270 				subpass->has_color_resolve = true;
271 			}
272 		}
273 
274 		for (uint32_t j = 0; j < subpass->input_count; ++j) {
275 			if (subpass->input_attachments[j].attachment == VK_ATTACHMENT_UNUSED)
276 				continue;
277 
278 			for (uint32_t k = 0; k < subpass->color_count; ++k) {
279 				if (subpass->color_attachments[k].attachment == subpass->input_attachments[j].attachment) {
280 					subpass->input_attachments[j].in_render_loop = true;
281 					subpass->color_attachments[k].in_render_loop = true;
282 				}
283 			}
284 
285 			if (subpass->depth_stencil_attachment &&
286 			    subpass->depth_stencil_attachment->attachment == subpass->input_attachments[j].attachment) {
287 				subpass->input_attachments[j].in_render_loop = true;
288 				subpass->depth_stencil_attachment->in_render_loop = true;
289 			}
290 		}
291 	}
292 }
293 
294 static unsigned
radv_num_subpass_attachments(const VkSubpassDescription * desc)295 radv_num_subpass_attachments(const VkSubpassDescription *desc)
296 {
297 	return desc->inputAttachmentCount +
298 	       desc->colorAttachmentCount +
299 	       (desc->pResolveAttachments ? desc->colorAttachmentCount : 0) +
300 	       (desc->pDepthStencilAttachment != NULL);
301 }
302 
303 static void
radv_destroy_render_pass(struct radv_device * device,const VkAllocationCallbacks * pAllocator,struct radv_render_pass * pass)304 radv_destroy_render_pass(struct radv_device *device,
305 			 const VkAllocationCallbacks *pAllocator,
306 			 struct radv_render_pass *pass)
307 {
308 	vk_object_base_finish(&pass->base);
309 	vk_free2(&device->vk.alloc, pAllocator, pass->subpass_attachments);
310 	vk_free2(&device->vk.alloc, pAllocator, pass);
311 }
312 
radv_CreateRenderPass(VkDevice _device,const VkRenderPassCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkRenderPass * pRenderPass)313 VkResult radv_CreateRenderPass(
314 	VkDevice                                    _device,
315 	const VkRenderPassCreateInfo*               pCreateInfo,
316 	const VkAllocationCallbacks*                pAllocator,
317 	VkRenderPass*                               pRenderPass)
318 {
319 	RADV_FROM_HANDLE(radv_device, device, _device);
320 	struct radv_render_pass *pass;
321 	size_t size;
322 	size_t attachments_offset;
323 	VkRenderPassMultiviewCreateInfo *multiview_info = NULL;
324 
325 	assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO);
326 
327 	size = sizeof(*pass);
328 	size += pCreateInfo->subpassCount * sizeof(pass->subpasses[0]);
329 	attachments_offset = size;
330 	size += pCreateInfo->attachmentCount * sizeof(pass->attachments[0]);
331 
332 	pass = vk_alloc2(&device->vk.alloc, pAllocator, size, 8,
333 			   VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
334 	if (pass == NULL)
335 		return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
336 
337 	memset(pass, 0, size);
338 
339 	vk_object_base_init(&device->vk, &pass->base,
340 			    VK_OBJECT_TYPE_RENDER_PASS);
341 
342 	pass->attachment_count = pCreateInfo->attachmentCount;
343 	pass->subpass_count = pCreateInfo->subpassCount;
344 	pass->attachments = (void *) pass + attachments_offset;
345 
346 	vk_foreach_struct(ext, pCreateInfo->pNext) {
347 		switch(ext->sType) {
348 		case  VK_STRUCTURE_TYPE_RENDER_PASS_MULTIVIEW_CREATE_INFO:
349 			multiview_info = (VkRenderPassMultiviewCreateInfo*)ext;
350 			break;
351 		default:
352 			break;
353 		}
354 	}
355 
356 	for (uint32_t i = 0; i < pCreateInfo->attachmentCount; i++) {
357 		struct radv_render_pass_attachment *att = &pass->attachments[i];
358 
359 		att->format = pCreateInfo->pAttachments[i].format;
360 		att->samples = pCreateInfo->pAttachments[i].samples;
361 		att->load_op = pCreateInfo->pAttachments[i].loadOp;
362 		att->stencil_load_op = pCreateInfo->pAttachments[i].stencilLoadOp;
363 		att->initial_layout =  pCreateInfo->pAttachments[i].initialLayout;
364 		att->final_layout =  pCreateInfo->pAttachments[i].finalLayout;
365 		att->stencil_initial_layout = pCreateInfo->pAttachments[i].initialLayout;
366 		att->stencil_final_layout = pCreateInfo->pAttachments[i].finalLayout;
367 		// att->store_op = pCreateInfo->pAttachments[i].storeOp;
368 		// att->stencil_store_op = pCreateInfo->pAttachments[i].stencilStoreOp;
369 	}
370 	uint32_t subpass_attachment_count = 0;
371 	struct radv_subpass_attachment *p;
372 	for (uint32_t i = 0; i < pCreateInfo->subpassCount; i++) {
373 		subpass_attachment_count +=
374 			radv_num_subpass_attachments(&pCreateInfo->pSubpasses[i]);
375 	}
376 
377 	if (subpass_attachment_count) {
378 		pass->subpass_attachments =
379 			vk_alloc2(&device->vk.alloc, pAllocator,
380 				    subpass_attachment_count * sizeof(struct radv_subpass_attachment), 8,
381 				    VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
382 		if (pass->subpass_attachments == NULL) {
383 			radv_destroy_render_pass(device, pAllocator, pass);
384 			return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
385 		}
386 	} else
387 		pass->subpass_attachments = NULL;
388 
389 	p = pass->subpass_attachments;
390 	for (uint32_t i = 0; i < pCreateInfo->subpassCount; i++) {
391 		const VkSubpassDescription *desc = &pCreateInfo->pSubpasses[i];
392 		struct radv_subpass *subpass = &pass->subpasses[i];
393 
394 		subpass->input_count = desc->inputAttachmentCount;
395 		subpass->color_count = desc->colorAttachmentCount;
396 		subpass->attachment_count = radv_num_subpass_attachments(desc);
397 		subpass->attachments = p;
398 
399 		if (multiview_info)
400 			subpass->view_mask = multiview_info->pViewMasks[i];
401 
402 		if (desc->inputAttachmentCount > 0) {
403 			subpass->input_attachments = p;
404 			p += desc->inputAttachmentCount;
405 
406 			for (uint32_t j = 0; j < desc->inputAttachmentCount; j++) {
407 				subpass->input_attachments[j] = (struct radv_subpass_attachment) {
408 					.attachment = desc->pInputAttachments[j].attachment,
409 					.layout = desc->pInputAttachments[j].layout,
410 					.stencil_layout = desc->pInputAttachments[j].layout,
411 				};
412 			}
413 		}
414 
415 		if (desc->colorAttachmentCount > 0) {
416 			subpass->color_attachments = p;
417 			p += desc->colorAttachmentCount;
418 
419 			for (uint32_t j = 0; j < desc->colorAttachmentCount; j++) {
420 				subpass->color_attachments[j] = (struct radv_subpass_attachment) {
421 					.attachment = desc->pColorAttachments[j].attachment,
422 					.layout = desc->pColorAttachments[j].layout,
423 				};
424 			}
425 		}
426 
427 		if (desc->pResolveAttachments) {
428 			subpass->resolve_attachments = p;
429 			p += desc->colorAttachmentCount;
430 
431 			for (uint32_t j = 0; j < desc->colorAttachmentCount; j++) {
432 				subpass->resolve_attachments[j] = (struct radv_subpass_attachment) {
433 					.attachment = desc->pResolveAttachments[j].attachment,
434 					.layout = desc->pResolveAttachments[j].layout,
435 					.stencil_layout = desc->pResolveAttachments[j].layout,
436 				};
437 			}
438 		}
439 
440 		if (desc->pDepthStencilAttachment) {
441 			subpass->depth_stencil_attachment = p++;
442 
443 			*subpass->depth_stencil_attachment = (struct radv_subpass_attachment) {
444 				.attachment = desc->pDepthStencilAttachment->attachment,
445 				.layout = desc->pDepthStencilAttachment->layout,
446 				.stencil_layout = desc->pDepthStencilAttachment->layout,
447 			};
448 		}
449 	}
450 
451 	bool has_ingoing_dep = false;
452 	bool has_outgoing_dep = false;
453 
454 	for (unsigned i = 0; i < pCreateInfo->dependencyCount; ++i) {
455 		/* Convert to a Dependency2 */
456 		struct VkSubpassDependency2 dep2 = {
457 			.srcSubpass       = pCreateInfo->pDependencies[i].srcSubpass,
458 			.dstSubpass       = pCreateInfo->pDependencies[i].dstSubpass,
459 			.srcStageMask     = pCreateInfo->pDependencies[i].srcStageMask,
460 			.dstStageMask     = pCreateInfo->pDependencies[i].dstStageMask,
461 			.srcAccessMask    = pCreateInfo->pDependencies[i].srcAccessMask,
462 			.dstAccessMask    = pCreateInfo->pDependencies[i].dstAccessMask,
463 			.dependencyFlags  = pCreateInfo->pDependencies[i].dependencyFlags,
464 		};
465 		radv_render_pass_add_subpass_dep(pass, &dep2);
466 
467 		/* Determine if the subpass has explicit dependencies from/to
468 		 * VK_SUBPASS_EXTERNAL.
469 		 */
470 		if (pCreateInfo->pDependencies[i].srcSubpass == VK_SUBPASS_EXTERNAL)
471 			has_ingoing_dep = true;
472 		if (pCreateInfo->pDependencies[i].dstSubpass == VK_SUBPASS_EXTERNAL)
473 			has_outgoing_dep = true;
474 	}
475 
476 	radv_render_pass_add_implicit_deps(pass,
477 					   has_ingoing_dep, has_outgoing_dep);
478 
479 	radv_render_pass_compile(pass);
480 
481 	*pRenderPass = radv_render_pass_to_handle(pass);
482 
483 	return VK_SUCCESS;
484 }
485 
486 static unsigned
radv_num_subpass_attachments2(const VkSubpassDescription2 * desc)487 radv_num_subpass_attachments2(const VkSubpassDescription2 *desc)
488 {
489 	const VkSubpassDescriptionDepthStencilResolve *ds_resolve =
490 		vk_find_struct_const(desc->pNext,
491 				     SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE);
492 
493 	return desc->inputAttachmentCount +
494 	       desc->colorAttachmentCount +
495 	       (desc->pResolveAttachments ? desc->colorAttachmentCount : 0) +
496 	       (desc->pDepthStencilAttachment != NULL) +
497 	       (ds_resolve && ds_resolve->pDepthStencilResolveAttachment);
498 }
499 
radv_CreateRenderPass2(VkDevice _device,const VkRenderPassCreateInfo2 * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkRenderPass * pRenderPass)500 VkResult radv_CreateRenderPass2(
501     VkDevice                                    _device,
502     const VkRenderPassCreateInfo2*              pCreateInfo,
503     const VkAllocationCallbacks*                pAllocator,
504     VkRenderPass*                               pRenderPass)
505 {
506 	RADV_FROM_HANDLE(radv_device, device, _device);
507 	struct radv_render_pass *pass;
508 	size_t size;
509 	size_t attachments_offset;
510 
511 	assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2);
512 
513 	size = sizeof(*pass);
514 	size += pCreateInfo->subpassCount * sizeof(pass->subpasses[0]);
515 	attachments_offset = size;
516 	size += pCreateInfo->attachmentCount * sizeof(pass->attachments[0]);
517 
518 	pass = vk_alloc2(&device->vk.alloc, pAllocator, size, 8,
519 			   VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
520 	if (pass == NULL)
521 		return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
522 
523 	memset(pass, 0, size);
524 
525 	vk_object_base_init(&device->vk, &pass->base,
526 			    VK_OBJECT_TYPE_RENDER_PASS);
527 
528 	pass->attachment_count = pCreateInfo->attachmentCount;
529 	pass->subpass_count = pCreateInfo->subpassCount;
530 	pass->attachments = (void *) pass + attachments_offset;
531 
532 	for (uint32_t i = 0; i < pCreateInfo->attachmentCount; i++) {
533 		struct radv_render_pass_attachment *att = &pass->attachments[i];
534 		const VkAttachmentDescriptionStencilLayoutKHR *stencil_layout =
535 			vk_find_struct_const(pCreateInfo->pAttachments[i].pNext,
536 					     ATTACHMENT_DESCRIPTION_STENCIL_LAYOUT_KHR);
537 
538 		att->format = pCreateInfo->pAttachments[i].format;
539 		att->samples = pCreateInfo->pAttachments[i].samples;
540 		att->load_op = pCreateInfo->pAttachments[i].loadOp;
541 		att->stencil_load_op = pCreateInfo->pAttachments[i].stencilLoadOp;
542 		att->initial_layout =  pCreateInfo->pAttachments[i].initialLayout;
543 		att->final_layout =  pCreateInfo->pAttachments[i].finalLayout;
544 		att->stencil_initial_layout = (stencil_layout ?
545 					       stencil_layout->stencilInitialLayout :
546 					       pCreateInfo->pAttachments[i].initialLayout);
547 		att->stencil_final_layout = (stencil_layout ?
548 					     stencil_layout->stencilFinalLayout :
549 					     pCreateInfo->pAttachments[i].finalLayout);
550 		// att->store_op = pCreateInfo->pAttachments[i].storeOp;
551 		// att->stencil_store_op = pCreateInfo->pAttachments[i].stencilStoreOp;
552 	}
553 	uint32_t subpass_attachment_count = 0;
554 	struct radv_subpass_attachment *p;
555 	for (uint32_t i = 0; i < pCreateInfo->subpassCount; i++) {
556 		subpass_attachment_count +=
557 			radv_num_subpass_attachments2(&pCreateInfo->pSubpasses[i]);
558 	}
559 
560 	if (subpass_attachment_count) {
561 		pass->subpass_attachments =
562 			vk_alloc2(&device->vk.alloc, pAllocator,
563 				    subpass_attachment_count * sizeof(struct radv_subpass_attachment), 8,
564 				    VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
565 		if (pass->subpass_attachments == NULL) {
566 			radv_destroy_render_pass(device, pAllocator, pass);
567 			return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
568 		}
569 	} else
570 		pass->subpass_attachments = NULL;
571 
572 	p = pass->subpass_attachments;
573 	for (uint32_t i = 0; i < pCreateInfo->subpassCount; i++) {
574 		const VkSubpassDescription2 *desc = &pCreateInfo->pSubpasses[i];
575 		struct radv_subpass *subpass = &pass->subpasses[i];
576 
577 		subpass->input_count = desc->inputAttachmentCount;
578 		subpass->color_count = desc->colorAttachmentCount;
579 		subpass->attachment_count = radv_num_subpass_attachments2(desc);
580 		subpass->attachments = p;
581 		subpass->view_mask = desc->viewMask;
582 
583 		if (desc->inputAttachmentCount > 0) {
584 			subpass->input_attachments = p;
585 			p += desc->inputAttachmentCount;
586 
587 			for (uint32_t j = 0; j < desc->inputAttachmentCount; j++) {
588 				const VkAttachmentReferenceStencilLayoutKHR *stencil_attachment =
589 			            vk_find_struct_const(desc->pInputAttachments[j].pNext,
590 							 ATTACHMENT_REFERENCE_STENCIL_LAYOUT_KHR);
591 
592 				subpass->input_attachments[j] = (struct radv_subpass_attachment) {
593 					.attachment = desc->pInputAttachments[j].attachment,
594 					.layout = desc->pInputAttachments[j].layout,
595 					.stencil_layout = (stencil_attachment ?
596 							   stencil_attachment->stencilLayout :
597 							   desc->pInputAttachments[j].layout),
598 				};
599 			}
600 		}
601 
602 		if (desc->colorAttachmentCount > 0) {
603 			subpass->color_attachments = p;
604 			p += desc->colorAttachmentCount;
605 
606 			for (uint32_t j = 0; j < desc->colorAttachmentCount; j++) {
607 				subpass->color_attachments[j] = (struct radv_subpass_attachment) {
608 					.attachment = desc->pColorAttachments[j].attachment,
609 					.layout = desc->pColorAttachments[j].layout,
610 				};
611 			}
612 		}
613 
614 		if (desc->pResolveAttachments) {
615 			subpass->resolve_attachments = p;
616 			p += desc->colorAttachmentCount;
617 
618 			for (uint32_t j = 0; j < desc->colorAttachmentCount; j++) {
619 				subpass->resolve_attachments[j] = (struct radv_subpass_attachment) {
620 					.attachment = desc->pResolveAttachments[j].attachment,
621 					.layout = desc->pResolveAttachments[j].layout,
622 				};
623 			}
624 		}
625 
626 		if (desc->pDepthStencilAttachment) {
627 			subpass->depth_stencil_attachment = p++;
628 
629 			const VkAttachmentReferenceStencilLayoutKHR *stencil_attachment =
630 		            vk_find_struct_const(desc->pDepthStencilAttachment->pNext,
631 						 ATTACHMENT_REFERENCE_STENCIL_LAYOUT_KHR);
632 
633 			*subpass->depth_stencil_attachment = (struct radv_subpass_attachment) {
634 				.attachment = desc->pDepthStencilAttachment->attachment,
635 				.layout = desc->pDepthStencilAttachment->layout,
636 				.stencil_layout = (stencil_attachment ?
637 						   stencil_attachment->stencilLayout :
638 						   desc->pDepthStencilAttachment->layout),
639 			};
640 		}
641 
642 		const VkSubpassDescriptionDepthStencilResolve *ds_resolve =
643 			vk_find_struct_const(desc->pNext,
644 					     SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE);
645 
646 		if (ds_resolve && ds_resolve->pDepthStencilResolveAttachment) {
647 			subpass->ds_resolve_attachment = p++;
648 
649 			const VkAttachmentReferenceStencilLayoutKHR *stencil_resolve_attachment =
650 		            vk_find_struct_const(ds_resolve->pDepthStencilResolveAttachment->pNext,
651 						 ATTACHMENT_REFERENCE_STENCIL_LAYOUT_KHR);
652 
653 			*subpass->ds_resolve_attachment = (struct radv_subpass_attachment) {
654 				.attachment =  ds_resolve->pDepthStencilResolveAttachment->attachment,
655 				.layout =      ds_resolve->pDepthStencilResolveAttachment->layout,
656 				.stencil_layout = (stencil_resolve_attachment ?
657 						   stencil_resolve_attachment->stencilLayout :
658 						   ds_resolve->pDepthStencilResolveAttachment->layout),
659 			};
660 
661 			subpass->depth_resolve_mode = ds_resolve->depthResolveMode;
662 			subpass->stencil_resolve_mode = ds_resolve->stencilResolveMode;
663 		}
664 	}
665 
666 	bool has_ingoing_dep = false;
667 	bool has_outgoing_dep = false;
668 
669 	for (unsigned i = 0; i < pCreateInfo->dependencyCount; ++i) {
670 		radv_render_pass_add_subpass_dep(pass,
671 						 &pCreateInfo->pDependencies[i]);
672 
673 		/* Determine if the subpass has explicit dependencies from/to
674 		 * VK_SUBPASS_EXTERNAL.
675 		 */
676 		if (pCreateInfo->pDependencies[i].srcSubpass == VK_SUBPASS_EXTERNAL)
677 			has_ingoing_dep = true;
678 		if (pCreateInfo->pDependencies[i].dstSubpass == VK_SUBPASS_EXTERNAL)
679 			has_outgoing_dep = true;
680 	}
681 
682 	radv_render_pass_add_implicit_deps(pass,
683 					   has_ingoing_dep, has_outgoing_dep);
684 
685 	radv_render_pass_compile(pass);
686 
687 	*pRenderPass = radv_render_pass_to_handle(pass);
688 
689 	return VK_SUCCESS;
690 }
691 
radv_DestroyRenderPass(VkDevice _device,VkRenderPass _pass,const VkAllocationCallbacks * pAllocator)692 void radv_DestroyRenderPass(
693 	VkDevice                                    _device,
694 	VkRenderPass                                _pass,
695 	const VkAllocationCallbacks*                pAllocator)
696 {
697 	RADV_FROM_HANDLE(radv_device, device, _device);
698 	RADV_FROM_HANDLE(radv_render_pass, pass, _pass);
699 
700 	if (!_pass)
701 		return;
702 
703 	radv_destroy_render_pass(device, pAllocator, pass);
704 }
705 
radv_GetRenderAreaGranularity(VkDevice device,VkRenderPass renderPass,VkExtent2D * pGranularity)706 void radv_GetRenderAreaGranularity(
707     VkDevice                                    device,
708     VkRenderPass                                renderPass,
709     VkExtent2D*                                 pGranularity)
710 {
711 	pGranularity->width = 1;
712 	pGranularity->height = 1;
713 }
714 
715