1b8e80941Smrg/*
2b8e80941Smrg * Copyright © 2016 Red Hat.
3b8e80941Smrg * Copyright © 2016 Bas Nieuwenhuizen
4b8e80941Smrg *
5b8e80941Smrg * based in part on anv driver which is:
6b8e80941Smrg * Copyright © 2015 Intel Corporation
7b8e80941Smrg *
8b8e80941Smrg * Permission is hereby granted, free of charge, to any person obtaining a
9b8e80941Smrg * copy of this software and associated documentation files (the "Software"),
10b8e80941Smrg * to deal in the Software without restriction, including without limitation
11b8e80941Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12b8e80941Smrg * and/or sell copies of the Software, and to permit persons to whom the
13b8e80941Smrg * Software is furnished to do so, subject to the following conditions:
14b8e80941Smrg *
15b8e80941Smrg * The above copyright notice and this permission notice (including the next
16b8e80941Smrg * paragraph) shall be included in all copies or substantial portions of the
17b8e80941Smrg * Software.
18b8e80941Smrg *
19b8e80941Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20b8e80941Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21b8e80941Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
22b8e80941Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23b8e80941Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24b8e80941Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
25b8e80941Smrg * IN THE SOFTWARE.
26b8e80941Smrg */
27b8e80941Smrg#include "radv_private.h"
28b8e80941Smrg
29b8e80941Smrg#include "vk_util.h"
30b8e80941Smrg
31b8e80941Smrgstatic void
32b8e80941Smrgradv_render_pass_add_subpass_dep(struct radv_render_pass *pass,
33b8e80941Smrg				 const VkSubpassDependency2KHR *dep)
34b8e80941Smrg{
35b8e80941Smrg	uint32_t src = dep->srcSubpass;
36b8e80941Smrg	uint32_t dst = dep->dstSubpass;
37b8e80941Smrg
38b8e80941Smrg	/* Ignore subpass self-dependencies as they allow the app to call
39b8e80941Smrg	 * vkCmdPipelineBarrier() inside the render pass and the driver should
40b8e80941Smrg	 * only do the barrier when called, not when starting the render pass.
41b8e80941Smrg	 */
42b8e80941Smrg	if (src == dst)
43b8e80941Smrg		return;
44b8e80941Smrg
45b8e80941Smrg	/* Accumulate all ingoing external dependencies to the first subpass. */
46b8e80941Smrg	if (src == VK_SUBPASS_EXTERNAL)
47b8e80941Smrg		dst = 0;
48b8e80941Smrg
49b8e80941Smrg	if (dst == VK_SUBPASS_EXTERNAL) {
50b8e80941Smrg		if (dep->dstStageMask != VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT)
51b8e80941Smrg			pass->end_barrier.src_stage_mask |= dep->srcStageMask;
52b8e80941Smrg		pass->end_barrier.src_access_mask |= dep->srcAccessMask;
53b8e80941Smrg		pass->end_barrier.dst_access_mask |= dep->dstAccessMask;
54b8e80941Smrg	} else {
55b8e80941Smrg		if (dep->dstStageMask != VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT)
56b8e80941Smrg			pass->subpasses[dst].start_barrier.src_stage_mask |= dep->srcStageMask;
57b8e80941Smrg		pass->subpasses[dst].start_barrier.src_access_mask |= dep->srcAccessMask;
58b8e80941Smrg		pass->subpasses[dst].start_barrier.dst_access_mask |= dep->dstAccessMask;
59b8e80941Smrg	}
60b8e80941Smrg}
61b8e80941Smrg
62b8e80941Smrgstatic void
63b8e80941Smrgradv_render_pass_compile(struct radv_render_pass *pass)
64b8e80941Smrg{
65b8e80941Smrg	for (uint32_t i = 0; i < pass->subpass_count; i++) {
66b8e80941Smrg		struct radv_subpass *subpass = &pass->subpasses[i];
67b8e80941Smrg		uint32_t color_sample_count = 1, depth_sample_count = 1;
68b8e80941Smrg
69b8e80941Smrg		/* We don't allow depth_stencil_attachment to be non-NULL and
70b8e80941Smrg		 * be VK_ATTACHMENT_UNUSED.  This way something can just check
71b8e80941Smrg		 * for NULL and be guaranteed that they have a valid
72b8e80941Smrg		 * attachment.
73b8e80941Smrg		 */
74b8e80941Smrg		if (subpass->depth_stencil_attachment &&
75b8e80941Smrg		    subpass->depth_stencil_attachment->attachment == VK_ATTACHMENT_UNUSED)
76b8e80941Smrg			subpass->depth_stencil_attachment = NULL;
77b8e80941Smrg
78b8e80941Smrg		for (uint32_t j = 0; j < subpass->attachment_count; j++) {
79b8e80941Smrg			struct radv_subpass_attachment *subpass_att =
80b8e80941Smrg				&subpass->attachments[j];
81b8e80941Smrg			if (subpass_att->attachment == VK_ATTACHMENT_UNUSED)
82b8e80941Smrg				continue;
83b8e80941Smrg
84b8e80941Smrg			struct radv_render_pass_attachment *pass_att =
85b8e80941Smrg				&pass->attachments[subpass_att->attachment];
86b8e80941Smrg
87b8e80941Smrg			pass_att->last_subpass_idx = i;
88b8e80941Smrg		}
89b8e80941Smrg
90b8e80941Smrg		subpass->has_color_att = false;
91b8e80941Smrg		for (uint32_t j = 0; j < subpass->color_count; j++) {
92b8e80941Smrg			struct radv_subpass_attachment *subpass_att =
93b8e80941Smrg				&subpass->color_attachments[j];
94b8e80941Smrg			if (subpass_att->attachment == VK_ATTACHMENT_UNUSED)
95b8e80941Smrg				continue;
96b8e80941Smrg
97b8e80941Smrg			subpass->has_color_att = true;
98b8e80941Smrg
99b8e80941Smrg			struct radv_render_pass_attachment *pass_att =
100b8e80941Smrg				&pass->attachments[subpass_att->attachment];
101b8e80941Smrg
102b8e80941Smrg			color_sample_count = pass_att->samples;
103b8e80941Smrg		}
104b8e80941Smrg
105b8e80941Smrg		if (subpass->depth_stencil_attachment) {
106b8e80941Smrg			const uint32_t a =
107b8e80941Smrg				subpass->depth_stencil_attachment->attachment;
108b8e80941Smrg			struct radv_render_pass_attachment *pass_att =
109b8e80941Smrg				&pass->attachments[a];
110b8e80941Smrg			depth_sample_count = pass_att->samples;
111b8e80941Smrg		}
112b8e80941Smrg
113b8e80941Smrg		subpass->max_sample_count = MAX2(color_sample_count,
114b8e80941Smrg						 depth_sample_count);
115b8e80941Smrg
116b8e80941Smrg		/* We have to handle resolve attachments specially */
117b8e80941Smrg		subpass->has_resolve = false;
118b8e80941Smrg		if (subpass->resolve_attachments) {
119b8e80941Smrg			for (uint32_t j = 0; j < subpass->color_count; j++) {
120b8e80941Smrg				struct radv_subpass_attachment *resolve_att =
121b8e80941Smrg					&subpass->resolve_attachments[j];
122b8e80941Smrg
123b8e80941Smrg				if (resolve_att->attachment == VK_ATTACHMENT_UNUSED)
124b8e80941Smrg					continue;
125b8e80941Smrg
126b8e80941Smrg				subpass->has_resolve = true;
127b8e80941Smrg			}
128b8e80941Smrg		}
129b8e80941Smrg	}
130b8e80941Smrg}
131b8e80941Smrg
132b8e80941Smrgstatic unsigned
133b8e80941Smrgradv_num_subpass_attachments(const VkSubpassDescription *desc)
134b8e80941Smrg{
135b8e80941Smrg	return desc->inputAttachmentCount +
136b8e80941Smrg	       desc->colorAttachmentCount +
137b8e80941Smrg	       (desc->pResolveAttachments ? desc->colorAttachmentCount : 0) +
138b8e80941Smrg	       (desc->pDepthStencilAttachment != NULL);
139b8e80941Smrg}
140b8e80941Smrg
141b8e80941SmrgVkResult radv_CreateRenderPass(
142b8e80941Smrg	VkDevice                                    _device,
143b8e80941Smrg	const VkRenderPassCreateInfo*               pCreateInfo,
144b8e80941Smrg	const VkAllocationCallbacks*                pAllocator,
145b8e80941Smrg	VkRenderPass*                               pRenderPass)
146b8e80941Smrg{
147b8e80941Smrg	RADV_FROM_HANDLE(radv_device, device, _device);
148b8e80941Smrg	struct radv_render_pass *pass;
149b8e80941Smrg	size_t size;
150b8e80941Smrg	size_t attachments_offset;
151b8e80941Smrg	VkRenderPassMultiviewCreateInfo *multiview_info = NULL;
152b8e80941Smrg
153b8e80941Smrg	assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO);
154b8e80941Smrg
155b8e80941Smrg	size = sizeof(*pass);
156b8e80941Smrg	size += pCreateInfo->subpassCount * sizeof(pass->subpasses[0]);
157b8e80941Smrg	attachments_offset = size;
158b8e80941Smrg	size += pCreateInfo->attachmentCount * sizeof(pass->attachments[0]);
159b8e80941Smrg
160b8e80941Smrg	pass = vk_alloc2(&device->alloc, pAllocator, size, 8,
161b8e80941Smrg			   VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
162b8e80941Smrg	if (pass == NULL)
163b8e80941Smrg		return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
164b8e80941Smrg
165b8e80941Smrg	memset(pass, 0, size);
166b8e80941Smrg	pass->attachment_count = pCreateInfo->attachmentCount;
167b8e80941Smrg	pass->subpass_count = pCreateInfo->subpassCount;
168b8e80941Smrg	pass->attachments = (void *) pass + attachments_offset;
169b8e80941Smrg
170b8e80941Smrg	vk_foreach_struct(ext, pCreateInfo->pNext) {
171b8e80941Smrg		switch(ext->sType) {
172b8e80941Smrg		case  VK_STRUCTURE_TYPE_RENDER_PASS_MULTIVIEW_CREATE_INFO:
173b8e80941Smrg			multiview_info = (VkRenderPassMultiviewCreateInfo*)ext;
174b8e80941Smrg			break;
175b8e80941Smrg		default:
176b8e80941Smrg			break;
177b8e80941Smrg		}
178b8e80941Smrg	}
179b8e80941Smrg
180b8e80941Smrg	for (uint32_t i = 0; i < pCreateInfo->attachmentCount; i++) {
181b8e80941Smrg		struct radv_render_pass_attachment *att = &pass->attachments[i];
182b8e80941Smrg
183b8e80941Smrg		att->format = pCreateInfo->pAttachments[i].format;
184b8e80941Smrg		att->samples = pCreateInfo->pAttachments[i].samples;
185b8e80941Smrg		att->load_op = pCreateInfo->pAttachments[i].loadOp;
186b8e80941Smrg		att->stencil_load_op = pCreateInfo->pAttachments[i].stencilLoadOp;
187b8e80941Smrg		att->initial_layout =  pCreateInfo->pAttachments[i].initialLayout;
188b8e80941Smrg		att->final_layout =  pCreateInfo->pAttachments[i].finalLayout;
189b8e80941Smrg		// att->store_op = pCreateInfo->pAttachments[i].storeOp;
190b8e80941Smrg		// att->stencil_store_op = pCreateInfo->pAttachments[i].stencilStoreOp;
191b8e80941Smrg	}
192b8e80941Smrg	uint32_t subpass_attachment_count = 0;
193b8e80941Smrg	struct radv_subpass_attachment *p;
194b8e80941Smrg	for (uint32_t i = 0; i < pCreateInfo->subpassCount; i++) {
195b8e80941Smrg		subpass_attachment_count +=
196b8e80941Smrg			radv_num_subpass_attachments(&pCreateInfo->pSubpasses[i]);
197b8e80941Smrg	}
198b8e80941Smrg
199b8e80941Smrg	if (subpass_attachment_count) {
200b8e80941Smrg		pass->subpass_attachments =
201b8e80941Smrg			vk_alloc2(&device->alloc, pAllocator,
202b8e80941Smrg				    subpass_attachment_count * sizeof(struct radv_subpass_attachment), 8,
203b8e80941Smrg				    VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
204b8e80941Smrg		if (pass->subpass_attachments == NULL) {
205b8e80941Smrg			vk_free2(&device->alloc, pAllocator, pass);
206b8e80941Smrg			return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
207b8e80941Smrg		}
208b8e80941Smrg	} else
209b8e80941Smrg		pass->subpass_attachments = NULL;
210b8e80941Smrg
211b8e80941Smrg	p = pass->subpass_attachments;
212b8e80941Smrg	for (uint32_t i = 0; i < pCreateInfo->subpassCount; i++) {
213b8e80941Smrg		const VkSubpassDescription *desc = &pCreateInfo->pSubpasses[i];
214b8e80941Smrg		struct radv_subpass *subpass = &pass->subpasses[i];
215b8e80941Smrg
216b8e80941Smrg		subpass->input_count = desc->inputAttachmentCount;
217b8e80941Smrg		subpass->color_count = desc->colorAttachmentCount;
218b8e80941Smrg		subpass->attachment_count = radv_num_subpass_attachments(desc);
219b8e80941Smrg		subpass->attachments = p;
220b8e80941Smrg
221b8e80941Smrg		if (multiview_info)
222b8e80941Smrg			subpass->view_mask = multiview_info->pViewMasks[i];
223b8e80941Smrg
224b8e80941Smrg		if (desc->inputAttachmentCount > 0) {
225b8e80941Smrg			subpass->input_attachments = p;
226b8e80941Smrg			p += desc->inputAttachmentCount;
227b8e80941Smrg
228b8e80941Smrg			for (uint32_t j = 0; j < desc->inputAttachmentCount; j++) {
229b8e80941Smrg				subpass->input_attachments[j] = (struct radv_subpass_attachment) {
230b8e80941Smrg					.attachment = desc->pInputAttachments[j].attachment,
231b8e80941Smrg					.layout = desc->pInputAttachments[j].layout,
232b8e80941Smrg				};
233b8e80941Smrg			}
234b8e80941Smrg		}
235b8e80941Smrg
236b8e80941Smrg		if (desc->colorAttachmentCount > 0) {
237b8e80941Smrg			subpass->color_attachments = p;
238b8e80941Smrg			p += desc->colorAttachmentCount;
239b8e80941Smrg
240b8e80941Smrg			for (uint32_t j = 0; j < desc->colorAttachmentCount; j++) {
241b8e80941Smrg				subpass->color_attachments[j] = (struct radv_subpass_attachment) {
242b8e80941Smrg					.attachment = desc->pColorAttachments[j].attachment,
243b8e80941Smrg					.layout = desc->pColorAttachments[j].layout,
244b8e80941Smrg				};
245b8e80941Smrg			}
246b8e80941Smrg		}
247b8e80941Smrg
248b8e80941Smrg		if (desc->pResolveAttachments) {
249b8e80941Smrg			subpass->resolve_attachments = p;
250b8e80941Smrg			p += desc->colorAttachmentCount;
251b8e80941Smrg
252b8e80941Smrg			for (uint32_t j = 0; j < desc->colorAttachmentCount; j++) {
253b8e80941Smrg				subpass->resolve_attachments[j] = (struct radv_subpass_attachment) {
254b8e80941Smrg					.attachment = desc->pResolveAttachments[j].attachment,
255b8e80941Smrg					.layout = desc->pResolveAttachments[j].layout,
256b8e80941Smrg				};
257b8e80941Smrg			}
258b8e80941Smrg		}
259b8e80941Smrg
260b8e80941Smrg		if (desc->pDepthStencilAttachment) {
261b8e80941Smrg			subpass->depth_stencil_attachment = p++;
262b8e80941Smrg
263b8e80941Smrg			*subpass->depth_stencil_attachment = (struct radv_subpass_attachment) {
264b8e80941Smrg				.attachment = desc->pDepthStencilAttachment->attachment,
265b8e80941Smrg				.layout = desc->pDepthStencilAttachment->layout,
266b8e80941Smrg			};
267b8e80941Smrg		}
268b8e80941Smrg	}
269b8e80941Smrg
270b8e80941Smrg	for (unsigned i = 0; i < pCreateInfo->dependencyCount; ++i) {
271b8e80941Smrg		/* Convert to a Dependency2KHR */
272b8e80941Smrg		struct VkSubpassDependency2KHR dep2 = {
273b8e80941Smrg			.srcSubpass       = pCreateInfo->pDependencies[i].srcSubpass,
274b8e80941Smrg			.dstSubpass       = pCreateInfo->pDependencies[i].dstSubpass,
275b8e80941Smrg			.srcStageMask     = pCreateInfo->pDependencies[i].srcStageMask,
276b8e80941Smrg			.dstStageMask     = pCreateInfo->pDependencies[i].dstStageMask,
277b8e80941Smrg			.srcAccessMask    = pCreateInfo->pDependencies[i].srcAccessMask,
278b8e80941Smrg			.dstAccessMask    = pCreateInfo->pDependencies[i].dstAccessMask,
279b8e80941Smrg			.dependencyFlags  = pCreateInfo->pDependencies[i].dependencyFlags,
280b8e80941Smrg		};
281b8e80941Smrg		radv_render_pass_add_subpass_dep(pass, &dep2);
282b8e80941Smrg	}
283b8e80941Smrg
284b8e80941Smrg	radv_render_pass_compile(pass);
285b8e80941Smrg
286b8e80941Smrg	*pRenderPass = radv_render_pass_to_handle(pass);
287b8e80941Smrg
288b8e80941Smrg	return VK_SUCCESS;
289b8e80941Smrg}
290b8e80941Smrg
291b8e80941Smrgstatic unsigned
292b8e80941Smrgradv_num_subpass_attachments2(const VkSubpassDescription2KHR *desc)
293b8e80941Smrg{
294b8e80941Smrg	return desc->inputAttachmentCount +
295b8e80941Smrg	       desc->colorAttachmentCount +
296b8e80941Smrg	       (desc->pResolveAttachments ? desc->colorAttachmentCount : 0) +
297b8e80941Smrg	       (desc->pDepthStencilAttachment != NULL);
298b8e80941Smrg}
299b8e80941Smrg
300b8e80941SmrgVkResult radv_CreateRenderPass2KHR(
301b8e80941Smrg    VkDevice                                    _device,
302b8e80941Smrg    const VkRenderPassCreateInfo2KHR*           pCreateInfo,
303b8e80941Smrg    const VkAllocationCallbacks*                pAllocator,
304b8e80941Smrg    VkRenderPass*                               pRenderPass)
305b8e80941Smrg{
306b8e80941Smrg	RADV_FROM_HANDLE(radv_device, device, _device);
307b8e80941Smrg	struct radv_render_pass *pass;
308b8e80941Smrg	size_t size;
309b8e80941Smrg	size_t attachments_offset;
310b8e80941Smrg
311b8e80941Smrg	assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2_KHR);
312b8e80941Smrg
313b8e80941Smrg	size = sizeof(*pass);
314b8e80941Smrg	size += pCreateInfo->subpassCount * sizeof(pass->subpasses[0]);
315b8e80941Smrg	attachments_offset = size;
316b8e80941Smrg	size += pCreateInfo->attachmentCount * sizeof(pass->attachments[0]);
317b8e80941Smrg
318b8e80941Smrg	pass = vk_alloc2(&device->alloc, pAllocator, size, 8,
319b8e80941Smrg			   VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
320b8e80941Smrg	if (pass == NULL)
321b8e80941Smrg		return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
322b8e80941Smrg
323b8e80941Smrg	memset(pass, 0, size);
324b8e80941Smrg	pass->attachment_count = pCreateInfo->attachmentCount;
325b8e80941Smrg	pass->subpass_count = pCreateInfo->subpassCount;
326b8e80941Smrg	pass->attachments = (void *) pass + attachments_offset;
327b8e80941Smrg
328b8e80941Smrg	for (uint32_t i = 0; i < pCreateInfo->attachmentCount; i++) {
329b8e80941Smrg		struct radv_render_pass_attachment *att = &pass->attachments[i];
330b8e80941Smrg
331b8e80941Smrg		att->format = pCreateInfo->pAttachments[i].format;
332b8e80941Smrg		att->samples = pCreateInfo->pAttachments[i].samples;
333b8e80941Smrg		att->load_op = pCreateInfo->pAttachments[i].loadOp;
334b8e80941Smrg		att->stencil_load_op = pCreateInfo->pAttachments[i].stencilLoadOp;
335b8e80941Smrg		att->initial_layout =  pCreateInfo->pAttachments[i].initialLayout;
336b8e80941Smrg		att->final_layout =  pCreateInfo->pAttachments[i].finalLayout;
337b8e80941Smrg		// att->store_op = pCreateInfo->pAttachments[i].storeOp;
338b8e80941Smrg		// att->stencil_store_op = pCreateInfo->pAttachments[i].stencilStoreOp;
339b8e80941Smrg	}
340b8e80941Smrg	uint32_t subpass_attachment_count = 0;
341b8e80941Smrg	struct radv_subpass_attachment *p;
342b8e80941Smrg	for (uint32_t i = 0; i < pCreateInfo->subpassCount; i++) {
343b8e80941Smrg		subpass_attachment_count +=
344b8e80941Smrg			radv_num_subpass_attachments2(&pCreateInfo->pSubpasses[i]);
345b8e80941Smrg	}
346b8e80941Smrg
347b8e80941Smrg	if (subpass_attachment_count) {
348b8e80941Smrg		pass->subpass_attachments =
349b8e80941Smrg			vk_alloc2(&device->alloc, pAllocator,
350b8e80941Smrg				    subpass_attachment_count * sizeof(struct radv_subpass_attachment), 8,
351b8e80941Smrg				    VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
352b8e80941Smrg		if (pass->subpass_attachments == NULL) {
353b8e80941Smrg			vk_free2(&device->alloc, pAllocator, pass);
354b8e80941Smrg			return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
355b8e80941Smrg		}
356b8e80941Smrg	} else
357b8e80941Smrg		pass->subpass_attachments = NULL;
358b8e80941Smrg
359b8e80941Smrg	p = pass->subpass_attachments;
360b8e80941Smrg	for (uint32_t i = 0; i < pCreateInfo->subpassCount; i++) {
361b8e80941Smrg		const VkSubpassDescription2KHR *desc = &pCreateInfo->pSubpasses[i];
362b8e80941Smrg		struct radv_subpass *subpass = &pass->subpasses[i];
363b8e80941Smrg
364b8e80941Smrg		subpass->input_count = desc->inputAttachmentCount;
365b8e80941Smrg		subpass->color_count = desc->colorAttachmentCount;
366b8e80941Smrg		subpass->attachment_count = radv_num_subpass_attachments2(desc);
367b8e80941Smrg		subpass->attachments = p;
368b8e80941Smrg		subpass->view_mask = desc->viewMask;
369b8e80941Smrg
370b8e80941Smrg		if (desc->inputAttachmentCount > 0) {
371b8e80941Smrg			subpass->input_attachments = p;
372b8e80941Smrg			p += desc->inputAttachmentCount;
373b8e80941Smrg
374b8e80941Smrg			for (uint32_t j = 0; j < desc->inputAttachmentCount; j++) {
375b8e80941Smrg				subpass->input_attachments[j] = (struct radv_subpass_attachment) {
376b8e80941Smrg					.attachment = desc->pInputAttachments[j].attachment,
377b8e80941Smrg					.layout = desc->pInputAttachments[j].layout,
378b8e80941Smrg				};
379b8e80941Smrg			}
380b8e80941Smrg		}
381b8e80941Smrg
382b8e80941Smrg		if (desc->colorAttachmentCount > 0) {
383b8e80941Smrg			subpass->color_attachments = p;
384b8e80941Smrg			p += desc->colorAttachmentCount;
385b8e80941Smrg
386b8e80941Smrg			for (uint32_t j = 0; j < desc->colorAttachmentCount; j++) {
387b8e80941Smrg				subpass->color_attachments[j] = (struct radv_subpass_attachment) {
388b8e80941Smrg					.attachment = desc->pColorAttachments[j].attachment,
389b8e80941Smrg					.layout = desc->pColorAttachments[j].layout,
390b8e80941Smrg				};
391b8e80941Smrg			}
392b8e80941Smrg		}
393b8e80941Smrg
394b8e80941Smrg		if (desc->pResolveAttachments) {
395b8e80941Smrg			subpass->resolve_attachments = p;
396b8e80941Smrg			p += desc->colorAttachmentCount;
397b8e80941Smrg
398b8e80941Smrg			for (uint32_t j = 0; j < desc->colorAttachmentCount; j++) {
399b8e80941Smrg				subpass->resolve_attachments[j] = (struct radv_subpass_attachment) {
400b8e80941Smrg					.attachment = desc->pResolveAttachments[j].attachment,
401b8e80941Smrg					.layout = desc->pResolveAttachments[j].layout,
402b8e80941Smrg				};
403b8e80941Smrg			}
404b8e80941Smrg		}
405b8e80941Smrg
406b8e80941Smrg		if (desc->pDepthStencilAttachment) {
407b8e80941Smrg			subpass->depth_stencil_attachment = p++;
408b8e80941Smrg
409b8e80941Smrg			*subpass->depth_stencil_attachment = (struct radv_subpass_attachment) {
410b8e80941Smrg				.attachment = desc->pDepthStencilAttachment->attachment,
411b8e80941Smrg				.layout = desc->pDepthStencilAttachment->layout,
412b8e80941Smrg			};
413b8e80941Smrg		}
414b8e80941Smrg	}
415b8e80941Smrg
416b8e80941Smrg	for (unsigned i = 0; i < pCreateInfo->dependencyCount; ++i) {
417b8e80941Smrg		radv_render_pass_add_subpass_dep(pass,
418b8e80941Smrg						 &pCreateInfo->pDependencies[i]);
419b8e80941Smrg	}
420b8e80941Smrg
421b8e80941Smrg	radv_render_pass_compile(pass);
422b8e80941Smrg
423b8e80941Smrg	*pRenderPass = radv_render_pass_to_handle(pass);
424b8e80941Smrg
425b8e80941Smrg	return VK_SUCCESS;
426b8e80941Smrg}
427b8e80941Smrg
428b8e80941Smrgvoid radv_DestroyRenderPass(
429b8e80941Smrg	VkDevice                                    _device,
430b8e80941Smrg	VkRenderPass                                _pass,
431b8e80941Smrg	const VkAllocationCallbacks*                pAllocator)
432b8e80941Smrg{
433b8e80941Smrg	RADV_FROM_HANDLE(radv_device, device, _device);
434b8e80941Smrg	RADV_FROM_HANDLE(radv_render_pass, pass, _pass);
435b8e80941Smrg
436b8e80941Smrg	if (!_pass)
437b8e80941Smrg		return;
438b8e80941Smrg	vk_free2(&device->alloc, pAllocator, pass->subpass_attachments);
439b8e80941Smrg	vk_free2(&device->alloc, pAllocator, pass);
440b8e80941Smrg}
441b8e80941Smrg
442b8e80941Smrgvoid radv_GetRenderAreaGranularity(
443b8e80941Smrg    VkDevice                                    device,
444b8e80941Smrg    VkRenderPass                                renderPass,
445b8e80941Smrg    VkExtent2D*                                 pGranularity)
446b8e80941Smrg{
447b8e80941Smrg	pGranularity->width = 1;
448b8e80941Smrg	pGranularity->height = 1;
449b8e80941Smrg}
450b8e80941Smrg
451