15c42758f009d393f0c0705a9937f656fd035eb8
[mesa.git] / src / intel / vulkan / anv_pass.c
1 /*
2 * Copyright © 2015 Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 */
23
24 #include "anv_private.h"
25
26 static unsigned
27 num_subpass_attachments(const VkSubpassDescription *desc)
28 {
29 return desc->inputAttachmentCount +
30 desc->colorAttachmentCount +
31 (desc->pResolveAttachments ? desc->colorAttachmentCount : 0) +
32 (desc->pDepthStencilAttachment != NULL);
33 }
34
35 VkResult anv_CreateRenderPass(
36 VkDevice _device,
37 const VkRenderPassCreateInfo* pCreateInfo,
38 const VkAllocationCallbacks* pAllocator,
39 VkRenderPass* pRenderPass)
40 {
41 ANV_FROM_HANDLE(anv_device, device, _device);
42
43 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO);
44
45 struct anv_render_pass *pass;
46 struct anv_subpass *subpasses;
47 struct anv_render_pass_attachment *attachments;
48
49 ANV_MULTIALLOC(ma);
50 anv_multialloc_add(&ma, &pass, 1);
51 anv_multialloc_add(&ma, &subpasses, pCreateInfo->subpassCount);
52 anv_multialloc_add(&ma, &attachments, pCreateInfo->attachmentCount);
53
54 VkAttachmentReference *subpass_attachments;
55 uint32_t subpass_attachment_count = 0;
56 for (uint32_t i = 0; i < pCreateInfo->subpassCount; i++) {
57 subpass_attachment_count +=
58 num_subpass_attachments(&pCreateInfo->pSubpasses[i]);
59 }
60 anv_multialloc_add(&ma, &subpass_attachments, subpass_attachment_count);
61
62 enum anv_subpass_usage *subpass_usages;
63 anv_multialloc_add(&ma, &subpass_usages,
64 pCreateInfo->subpassCount * pCreateInfo->attachmentCount);
65
66 if (!anv_multialloc_alloc2(&ma, &device->alloc, pAllocator,
67 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT))
68 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
69
70 /* Clear the subpasses along with the parent pass. This required because
71 * each array member of anv_subpass must be a valid pointer if not NULL.
72 */
73 memset(pass, 0, ma.size);
74 pass->attachment_count = pCreateInfo->attachmentCount;
75 pass->subpass_count = pCreateInfo->subpassCount;
76 pass->attachments = attachments;
77
78 for (uint32_t i = 0; i < pCreateInfo->attachmentCount; i++) {
79 struct anv_render_pass_attachment *att = &pass->attachments[i];
80
81 att->format = pCreateInfo->pAttachments[i].format;
82 att->samples = pCreateInfo->pAttachments[i].samples;
83 att->usage = 0;
84 att->load_op = pCreateInfo->pAttachments[i].loadOp;
85 att->store_op = pCreateInfo->pAttachments[i].storeOp;
86 att->stencil_load_op = pCreateInfo->pAttachments[i].stencilLoadOp;
87 att->initial_layout = pCreateInfo->pAttachments[i].initialLayout;
88 att->final_layout = pCreateInfo->pAttachments[i].finalLayout;
89 att->subpass_usage = subpass_usages;
90 subpass_usages += pass->subpass_count;
91 }
92
93 for (uint32_t i = 0; i < pCreateInfo->subpassCount; i++) {
94 const VkSubpassDescription *desc = &pCreateInfo->pSubpasses[i];
95 struct anv_subpass *subpass = &pass->subpasses[i];
96
97 subpass->input_count = desc->inputAttachmentCount;
98 subpass->color_count = desc->colorAttachmentCount;
99 subpass->attachment_count = num_subpass_attachments(desc);
100 subpass->attachments = subpass_attachments;
101
102 if (desc->inputAttachmentCount > 0) {
103 subpass->input_attachments = subpass_attachments;
104 subpass_attachments += desc->inputAttachmentCount;
105
106 for (uint32_t j = 0; j < desc->inputAttachmentCount; j++) {
107 uint32_t a = desc->pInputAttachments[j].attachment;
108 subpass->input_attachments[j] = desc->pInputAttachments[j];
109 if (a != VK_ATTACHMENT_UNUSED) {
110 pass->attachments[a].usage |= VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
111 pass->attachments[a].subpass_usage[i] |= ANV_SUBPASS_USAGE_INPUT;
112 pass->attachments[a].last_subpass_idx = i;
113
114 if (desc->pDepthStencilAttachment &&
115 a == desc->pDepthStencilAttachment->attachment)
116 subpass->has_ds_self_dep = true;
117 }
118 }
119 }
120
121 if (desc->colorAttachmentCount > 0) {
122 subpass->color_attachments = subpass_attachments;
123 subpass_attachments += desc->colorAttachmentCount;
124
125 for (uint32_t j = 0; j < desc->colorAttachmentCount; j++) {
126 uint32_t a = desc->pColorAttachments[j].attachment;
127 subpass->color_attachments[j] = desc->pColorAttachments[j];
128 if (a != VK_ATTACHMENT_UNUSED) {
129 pass->attachments[a].usage |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
130 pass->attachments[a].subpass_usage[i] |= ANV_SUBPASS_USAGE_DRAW;
131 pass->attachments[a].last_subpass_idx = i;
132 }
133 }
134 }
135
136 subpass->has_resolve = false;
137 if (desc->pResolveAttachments) {
138 subpass->resolve_attachments = subpass_attachments;
139 subpass_attachments += desc->colorAttachmentCount;
140
141 for (uint32_t j = 0; j < desc->colorAttachmentCount; j++) {
142 uint32_t a = desc->pResolveAttachments[j].attachment;
143 subpass->resolve_attachments[j] = desc->pResolveAttachments[j];
144 if (a != VK_ATTACHMENT_UNUSED) {
145 subpass->has_resolve = true;
146 uint32_t color_att = desc->pColorAttachments[j].attachment;
147 pass->attachments[color_att].usage |=
148 VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
149 pass->attachments[a].usage |= VK_IMAGE_USAGE_TRANSFER_DST_BIT;
150
151 pass->attachments[color_att].subpass_usage[i] |=
152 ANV_SUBPASS_USAGE_RESOLVE_SRC;
153 pass->attachments[a].subpass_usage[i] |=
154 ANV_SUBPASS_USAGE_RESOLVE_DST;
155 pass->attachments[a].last_subpass_idx = i;
156 }
157 }
158 }
159
160 if (desc->pDepthStencilAttachment) {
161 uint32_t a = desc->pDepthStencilAttachment->attachment;
162 *subpass_attachments++ = subpass->depth_stencil_attachment =
163 *desc->pDepthStencilAttachment;
164 if (a != VK_ATTACHMENT_UNUSED) {
165 pass->attachments[a].usage |=
166 VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
167 pass->attachments[a].subpass_usage[i] |= ANV_SUBPASS_USAGE_DRAW;
168 pass->attachments[a].last_subpass_idx = i;
169 }
170 } else {
171 subpass->depth_stencil_attachment.attachment = VK_ATTACHMENT_UNUSED;
172 subpass->depth_stencil_attachment.layout = VK_IMAGE_LAYOUT_UNDEFINED;
173 }
174 }
175
176 *pRenderPass = anv_render_pass_to_handle(pass);
177
178 return VK_SUCCESS;
179 }
180
181 void anv_DestroyRenderPass(
182 VkDevice _device,
183 VkRenderPass _pass,
184 const VkAllocationCallbacks* pAllocator)
185 {
186 ANV_FROM_HANDLE(anv_device, device, _device);
187 ANV_FROM_HANDLE(anv_render_pass, pass, _pass);
188
189 vk_free2(&device->alloc, pAllocator, pass);
190 }
191
192 void anv_GetRenderAreaGranularity(
193 VkDevice device,
194 VkRenderPass renderPass,
195 VkExtent2D* pGranularity)
196 {
197 ANV_FROM_HANDLE(anv_render_pass, pass, renderPass);
198
199 /* This granularity satisfies HiZ fast clear alignment requirements
200 * for all sample counts.
201 */
202 for (unsigned i = 0; i < pass->subpass_count; ++i) {
203 if (pass->subpasses[i].depth_stencil_attachment.attachment !=
204 VK_ATTACHMENT_UNUSED) {
205 *pGranularity = (VkExtent2D) { .width = 8, .height = 4 };
206 return;
207 }
208 }
209
210 *pGranularity = (VkExtent2D) { 1, 1 };
211 }