3ccc877b9c7e2867e32b40b79be571e4a212761e
[mesa.git] / src / amd / vulkan / radv_pass.c
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
32 radv_render_pass_compile(struct radv_render_pass *pass)
33 {
34 for (uint32_t i = 0; i < pass->subpass_count; i++) {
35 struct radv_subpass *subpass = &pass->subpasses[i];
36 uint32_t color_sample_count = 1, depth_sample_count = 1;
37
38 /* We don't allow depth_stencil_attachment to be non-NULL and
39 * be VK_ATTACHMENT_UNUSED. This way something can just check
40 * for NULL and be guaranteed that they have a valid
41 * attachment.
42 */
43 if (subpass->depth_stencil_attachment &&
44 subpass->depth_stencil_attachment->attachment == VK_ATTACHMENT_UNUSED)
45 subpass->depth_stencil_attachment = NULL;
46
47 for (uint32_t j = 0; j < subpass->attachment_count; j++) {
48 struct radv_subpass_attachment *subpass_att =
49 &subpass->attachments[j];
50 if (subpass_att->attachment == VK_ATTACHMENT_UNUSED)
51 continue;
52
53 struct radv_render_pass_attachment *pass_att =
54 &pass->attachments[subpass_att->attachment];
55
56 pass_att->last_subpass_idx = i;
57 }
58
59 for (uint32_t j = 0; j < subpass->color_count; j++) {
60 struct radv_subpass_attachment *subpass_att =
61 &subpass->color_attachments[j];
62 if (subpass_att->attachment == VK_ATTACHMENT_UNUSED)
63 continue;
64
65 struct radv_render_pass_attachment *pass_att =
66 &pass->attachments[subpass_att->attachment];
67
68 color_sample_count = pass_att->samples;
69 }
70
71 if (subpass->depth_stencil_attachment) {
72 const uint32_t a =
73 subpass->depth_stencil_attachment->attachment;
74 struct radv_render_pass_attachment *pass_att =
75 &pass->attachments[a];
76 depth_sample_count = pass_att->samples;
77 }
78
79 subpass->max_sample_count = MAX2(color_sample_count,
80 depth_sample_count);
81
82 /* We have to handle resolve attachments specially */
83 subpass->has_resolve = false;
84 if (subpass->resolve_attachments) {
85 for (uint32_t j = 0; j < subpass->color_count; j++) {
86 struct radv_subpass_attachment *resolve_att =
87 &subpass->resolve_attachments[j];
88
89 if (resolve_att->attachment == VK_ATTACHMENT_UNUSED)
90 continue;
91
92 subpass->has_resolve = true;
93 }
94 }
95 }
96 }
97
98 static unsigned
99 radv_num_subpass_attachments(const VkSubpassDescription *desc)
100 {
101 return desc->inputAttachmentCount +
102 desc->colorAttachmentCount +
103 (desc->pResolveAttachments ? desc->colorAttachmentCount : 0) +
104 (desc->pDepthStencilAttachment != NULL);
105 }
106
107 VkResult radv_CreateRenderPass(
108 VkDevice _device,
109 const VkRenderPassCreateInfo* pCreateInfo,
110 const VkAllocationCallbacks* pAllocator,
111 VkRenderPass* pRenderPass)
112 {
113 RADV_FROM_HANDLE(radv_device, device, _device);
114 struct radv_render_pass *pass;
115 size_t size;
116 size_t attachments_offset;
117 VkRenderPassMultiviewCreateInfo *multiview_info = NULL;
118
119 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO);
120
121 size = sizeof(*pass);
122 size += pCreateInfo->subpassCount * sizeof(pass->subpasses[0]);
123 attachments_offset = size;
124 size += pCreateInfo->attachmentCount * sizeof(pass->attachments[0]);
125
126 pass = vk_alloc2(&device->alloc, pAllocator, size, 8,
127 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
128 if (pass == NULL)
129 return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
130
131 memset(pass, 0, size);
132 pass->attachment_count = pCreateInfo->attachmentCount;
133 pass->subpass_count = pCreateInfo->subpassCount;
134 pass->attachments = (void *) pass + attachments_offset;
135
136 vk_foreach_struct(ext, pCreateInfo->pNext) {
137 switch(ext->sType) {
138 case VK_STRUCTURE_TYPE_RENDER_PASS_MULTIVIEW_CREATE_INFO:
139 multiview_info = (VkRenderPassMultiviewCreateInfo*)ext;
140 break;
141 default:
142 break;
143 }
144 }
145
146 for (uint32_t i = 0; i < pCreateInfo->attachmentCount; i++) {
147 struct radv_render_pass_attachment *att = &pass->attachments[i];
148
149 att->format = pCreateInfo->pAttachments[i].format;
150 att->samples = pCreateInfo->pAttachments[i].samples;
151 att->load_op = pCreateInfo->pAttachments[i].loadOp;
152 att->stencil_load_op = pCreateInfo->pAttachments[i].stencilLoadOp;
153 att->initial_layout = pCreateInfo->pAttachments[i].initialLayout;
154 att->final_layout = pCreateInfo->pAttachments[i].finalLayout;
155 // att->store_op = pCreateInfo->pAttachments[i].storeOp;
156 // att->stencil_store_op = pCreateInfo->pAttachments[i].stencilStoreOp;
157 }
158 uint32_t subpass_attachment_count = 0;
159 struct radv_subpass_attachment *p;
160 for (uint32_t i = 0; i < pCreateInfo->subpassCount; i++) {
161 subpass_attachment_count +=
162 radv_num_subpass_attachments(&pCreateInfo->pSubpasses[i]);
163 }
164
165 if (subpass_attachment_count) {
166 pass->subpass_attachments =
167 vk_alloc2(&device->alloc, pAllocator,
168 subpass_attachment_count * sizeof(struct radv_subpass_attachment), 8,
169 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
170 if (pass->subpass_attachments == NULL) {
171 vk_free2(&device->alloc, pAllocator, pass);
172 return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
173 }
174 } else
175 pass->subpass_attachments = NULL;
176
177 p = pass->subpass_attachments;
178 for (uint32_t i = 0; i < pCreateInfo->subpassCount; i++) {
179 const VkSubpassDescription *desc = &pCreateInfo->pSubpasses[i];
180 struct radv_subpass *subpass = &pass->subpasses[i];
181
182 subpass->input_count = desc->inputAttachmentCount;
183 subpass->color_count = desc->colorAttachmentCount;
184 subpass->attachment_count = radv_num_subpass_attachments(desc);
185 subpass->attachments = p;
186
187 if (multiview_info)
188 subpass->view_mask = multiview_info->pViewMasks[i];
189
190 if (desc->inputAttachmentCount > 0) {
191 subpass->input_attachments = p;
192 p += desc->inputAttachmentCount;
193
194 for (uint32_t j = 0; j < desc->inputAttachmentCount; j++) {
195 subpass->input_attachments[j] = (struct radv_subpass_attachment) {
196 .attachment = desc->pInputAttachments[j].attachment,
197 .layout = desc->pInputAttachments[j].layout,
198 };
199 }
200 }
201
202 if (desc->colorAttachmentCount > 0) {
203 subpass->color_attachments = p;
204 p += desc->colorAttachmentCount;
205
206 for (uint32_t j = 0; j < desc->colorAttachmentCount; j++) {
207 subpass->color_attachments[j] = (struct radv_subpass_attachment) {
208 .attachment = desc->pColorAttachments[j].attachment,
209 .layout = desc->pColorAttachments[j].layout,
210 };
211 }
212 }
213
214 if (desc->pResolveAttachments) {
215 subpass->resolve_attachments = p;
216 p += desc->colorAttachmentCount;
217
218 for (uint32_t j = 0; j < desc->colorAttachmentCount; j++) {
219 uint32_t a = desc->pResolveAttachments[j].attachment;
220 subpass->resolve_attachments[j] = (struct radv_subpass_attachment) {
221 .attachment = desc->pResolveAttachments[j].attachment,
222 .layout = desc->pResolveAttachments[j].layout,
223 };
224 }
225 }
226
227 if (desc->pDepthStencilAttachment) {
228 subpass->depth_stencil_attachment = p++;
229
230 *subpass->depth_stencil_attachment = (struct radv_subpass_attachment) {
231 .attachment = desc->pDepthStencilAttachment->attachment,
232 .layout = desc->pDepthStencilAttachment->layout,
233 };
234 }
235 }
236
237 for (unsigned i = 0; i < pCreateInfo->dependencyCount; ++i) {
238 uint32_t src = pCreateInfo->pDependencies[i].srcSubpass;
239 uint32_t dst = pCreateInfo->pDependencies[i].dstSubpass;
240
241 /* Ignore subpass self-dependencies as they allow the app to
242 * call vkCmdPipelineBarrier() inside the render pass and the
243 * driver should only do the barrier when called, not when
244 * starting the render pass.
245 */
246 if (src == dst)
247 continue;
248
249 if (dst == VK_SUBPASS_EXTERNAL) {
250 pass->end_barrier.src_stage_mask = pCreateInfo->pDependencies[i].srcStageMask;
251 pass->end_barrier.src_access_mask = pCreateInfo->pDependencies[i].srcAccessMask;
252 pass->end_barrier.dst_access_mask = pCreateInfo->pDependencies[i].dstAccessMask;
253 } else {
254 pass->subpasses[dst].start_barrier.src_stage_mask = pCreateInfo->pDependencies[i].srcStageMask;
255 pass->subpasses[dst].start_barrier.src_access_mask = pCreateInfo->pDependencies[i].srcAccessMask;
256 pass->subpasses[dst].start_barrier.dst_access_mask = pCreateInfo->pDependencies[i].dstAccessMask;
257 }
258 }
259
260 radv_render_pass_compile(pass);
261
262 *pRenderPass = radv_render_pass_to_handle(pass);
263
264 return VK_SUCCESS;
265 }
266
267 static unsigned
268 radv_num_subpass_attachments2(const VkSubpassDescription2KHR *desc)
269 {
270 return desc->inputAttachmentCount +
271 desc->colorAttachmentCount +
272 (desc->pResolveAttachments ? desc->colorAttachmentCount : 0) +
273 (desc->pDepthStencilAttachment != NULL);
274 }
275
276 VkResult radv_CreateRenderPass2KHR(
277 VkDevice _device,
278 const VkRenderPassCreateInfo2KHR* pCreateInfo,
279 const VkAllocationCallbacks* pAllocator,
280 VkRenderPass* pRenderPass)
281 {
282 RADV_FROM_HANDLE(radv_device, device, _device);
283 struct radv_render_pass *pass;
284 size_t size;
285 size_t attachments_offset;
286
287 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2_KHR);
288
289 size = sizeof(*pass);
290 size += pCreateInfo->subpassCount * sizeof(pass->subpasses[0]);
291 attachments_offset = size;
292 size += pCreateInfo->attachmentCount * sizeof(pass->attachments[0]);
293
294 pass = vk_alloc2(&device->alloc, pAllocator, size, 8,
295 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
296 if (pass == NULL)
297 return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
298
299 memset(pass, 0, size);
300 pass->attachment_count = pCreateInfo->attachmentCount;
301 pass->subpass_count = pCreateInfo->subpassCount;
302 pass->attachments = (void *) pass + attachments_offset;
303
304 for (uint32_t i = 0; i < pCreateInfo->attachmentCount; i++) {
305 struct radv_render_pass_attachment *att = &pass->attachments[i];
306
307 att->format = pCreateInfo->pAttachments[i].format;
308 att->samples = pCreateInfo->pAttachments[i].samples;
309 att->load_op = pCreateInfo->pAttachments[i].loadOp;
310 att->stencil_load_op = pCreateInfo->pAttachments[i].stencilLoadOp;
311 att->initial_layout = pCreateInfo->pAttachments[i].initialLayout;
312 att->final_layout = pCreateInfo->pAttachments[i].finalLayout;
313 // att->store_op = pCreateInfo->pAttachments[i].storeOp;
314 // att->stencil_store_op = pCreateInfo->pAttachments[i].stencilStoreOp;
315 }
316 uint32_t subpass_attachment_count = 0;
317 struct radv_subpass_attachment *p;
318 for (uint32_t i = 0; i < pCreateInfo->subpassCount; i++) {
319 subpass_attachment_count +=
320 radv_num_subpass_attachments2(&pCreateInfo->pSubpasses[i]);
321 }
322
323 if (subpass_attachment_count) {
324 pass->subpass_attachments =
325 vk_alloc2(&device->alloc, pAllocator,
326 subpass_attachment_count * sizeof(struct radv_subpass_attachment), 8,
327 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
328 if (pass->subpass_attachments == NULL) {
329 vk_free2(&device->alloc, pAllocator, pass);
330 return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
331 }
332 } else
333 pass->subpass_attachments = NULL;
334
335 p = pass->subpass_attachments;
336 for (uint32_t i = 0; i < pCreateInfo->subpassCount; i++) {
337 const VkSubpassDescription2KHR *desc = &pCreateInfo->pSubpasses[i];
338 struct radv_subpass *subpass = &pass->subpasses[i];
339
340 subpass->input_count = desc->inputAttachmentCount;
341 subpass->color_count = desc->colorAttachmentCount;
342 subpass->attachment_count = radv_num_subpass_attachments2(desc);
343 subpass->attachments = p;
344 subpass->view_mask = desc->viewMask;
345
346 if (desc->inputAttachmentCount > 0) {
347 subpass->input_attachments = p;
348 p += desc->inputAttachmentCount;
349
350 for (uint32_t j = 0; j < desc->inputAttachmentCount; j++) {
351 subpass->input_attachments[j] = (struct radv_subpass_attachment) {
352 .attachment = desc->pInputAttachments[j].attachment,
353 .layout = desc->pInputAttachments[j].layout,
354 };
355 }
356 }
357
358 if (desc->colorAttachmentCount > 0) {
359 subpass->color_attachments = p;
360 p += desc->colorAttachmentCount;
361
362 for (uint32_t j = 0; j < desc->colorAttachmentCount; j++) {
363 subpass->color_attachments[j] = (struct radv_subpass_attachment) {
364 .attachment = desc->pColorAttachments[j].attachment,
365 .layout = desc->pColorAttachments[j].layout,
366 };
367 }
368 }
369
370 if (desc->pResolveAttachments) {
371 subpass->resolve_attachments = p;
372 p += desc->colorAttachmentCount;
373
374 for (uint32_t j = 0; j < desc->colorAttachmentCount; j++) {
375 uint32_t a = desc->pResolveAttachments[j].attachment;
376 subpass->resolve_attachments[j] = (struct radv_subpass_attachment) {
377 .attachment = desc->pResolveAttachments[j].attachment,
378 .layout = desc->pResolveAttachments[j].layout,
379 };
380 }
381 }
382
383 if (desc->pDepthStencilAttachment) {
384 subpass->depth_stencil_attachment = p++;
385
386 *subpass->depth_stencil_attachment = (struct radv_subpass_attachment) {
387 .attachment = desc->pDepthStencilAttachment->attachment,
388 .layout = desc->pDepthStencilAttachment->layout,
389 };
390 }
391 }
392
393 for (unsigned i = 0; i < pCreateInfo->dependencyCount; ++i) {
394 uint32_t src = pCreateInfo->pDependencies[i].srcSubpass;
395 uint32_t dst = pCreateInfo->pDependencies[i].dstSubpass;
396
397 /* Ignore subpass self-dependencies as they allow the app to
398 * call vkCmdPipelineBarrier() inside the render pass and the
399 * driver should only do the barrier when called, not when
400 * starting the render pass.
401 */
402 if (src == dst)
403 continue;
404
405 if (dst == VK_SUBPASS_EXTERNAL) {
406 pass->end_barrier.src_stage_mask = pCreateInfo->pDependencies[i].srcStageMask;
407 pass->end_barrier.src_access_mask = pCreateInfo->pDependencies[i].srcAccessMask;
408 pass->end_barrier.dst_access_mask = pCreateInfo->pDependencies[i].dstAccessMask;
409 } else {
410 pass->subpasses[dst].start_barrier.src_stage_mask = pCreateInfo->pDependencies[i].srcStageMask;
411 pass->subpasses[dst].start_barrier.src_access_mask = pCreateInfo->pDependencies[i].srcAccessMask;
412 pass->subpasses[dst].start_barrier.dst_access_mask = pCreateInfo->pDependencies[i].dstAccessMask;
413 }
414 }
415
416 radv_render_pass_compile(pass);
417
418 *pRenderPass = radv_render_pass_to_handle(pass);
419
420 return VK_SUCCESS;
421 }
422
423 void radv_DestroyRenderPass(
424 VkDevice _device,
425 VkRenderPass _pass,
426 const VkAllocationCallbacks* pAllocator)
427 {
428 RADV_FROM_HANDLE(radv_device, device, _device);
429 RADV_FROM_HANDLE(radv_render_pass, pass, _pass);
430
431 if (!_pass)
432 return;
433 vk_free2(&device->alloc, pAllocator, pass->subpass_attachments);
434 vk_free2(&device->alloc, pAllocator, pass);
435 }
436
437 void radv_GetRenderAreaGranularity(
438 VkDevice device,
439 VkRenderPass renderPass,
440 VkExtent2D* pGranularity)
441 {
442 pGranularity->width = 1;
443 pGranularity->height = 1;
444 }
445