OSDN Git Service

radv: introduce radv_subpass_attachment data structure
[android-x86/external-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 VkResult radv_CreateRenderPass(
32         VkDevice                                    _device,
33         const VkRenderPassCreateInfo*               pCreateInfo,
34         const VkAllocationCallbacks*                pAllocator,
35         VkRenderPass*                               pRenderPass)
36 {
37         RADV_FROM_HANDLE(radv_device, device, _device);
38         struct radv_render_pass *pass;
39         size_t size;
40         size_t attachments_offset;
41         VkRenderPassMultiviewCreateInfoKHR *multiview_info = NULL;
42
43         assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO);
44
45         size = sizeof(*pass);
46         size += pCreateInfo->subpassCount * sizeof(pass->subpasses[0]);
47         attachments_offset = size;
48         size += pCreateInfo->attachmentCount * sizeof(pass->attachments[0]);
49
50         pass = vk_alloc2(&device->alloc, pAllocator, size, 8,
51                            VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
52         if (pass == NULL)
53                 return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
54
55         memset(pass, 0, size);
56         pass->attachment_count = pCreateInfo->attachmentCount;
57         pass->subpass_count = pCreateInfo->subpassCount;
58         pass->attachments = (void *) pass + attachments_offset;
59
60         vk_foreach_struct(ext, pCreateInfo->pNext) {
61                 switch(ext->sType) {
62                 case  VK_STRUCTURE_TYPE_RENDER_PASS_MULTIVIEW_CREATE_INFO_KHR:
63                         multiview_info = ( VkRenderPassMultiviewCreateInfoKHR*)ext;
64                         break;
65                 default:
66                         break;
67                 }
68         }
69
70         for (uint32_t i = 0; i < pCreateInfo->attachmentCount; i++) {
71                 struct radv_render_pass_attachment *att = &pass->attachments[i];
72
73                 att->format = pCreateInfo->pAttachments[i].format;
74                 att->samples = pCreateInfo->pAttachments[i].samples;
75                 att->load_op = pCreateInfo->pAttachments[i].loadOp;
76                 att->stencil_load_op = pCreateInfo->pAttachments[i].stencilLoadOp;
77                 att->initial_layout =  pCreateInfo->pAttachments[i].initialLayout;
78                 att->final_layout =  pCreateInfo->pAttachments[i].finalLayout;
79                 // att->store_op = pCreateInfo->pAttachments[i].storeOp;
80                 // att->stencil_store_op = pCreateInfo->pAttachments[i].stencilStoreOp;
81         }
82         uint32_t subpass_attachment_count = 0;
83         struct radv_subpass_attachment *p;
84         for (uint32_t i = 0; i < pCreateInfo->subpassCount; i++) {
85                 const VkSubpassDescription *desc = &pCreateInfo->pSubpasses[i];
86
87                 subpass_attachment_count +=
88                         desc->inputAttachmentCount +
89                         desc->colorAttachmentCount +
90                         (desc->pResolveAttachments ? desc->colorAttachmentCount : 0) +
91                         (desc->pDepthStencilAttachment != NULL);
92         }
93
94         if (subpass_attachment_count) {
95                 pass->subpass_attachments =
96                         vk_alloc2(&device->alloc, pAllocator,
97                                     subpass_attachment_count * sizeof(struct radv_subpass_attachment), 8,
98                                     VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
99                 if (pass->subpass_attachments == NULL) {
100                         vk_free2(&device->alloc, pAllocator, pass);
101                         return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
102                 }
103         } else
104                 pass->subpass_attachments = NULL;
105
106         p = pass->subpass_attachments;
107         for (uint32_t i = 0; i < pCreateInfo->subpassCount; i++) {
108                 const VkSubpassDescription *desc = &pCreateInfo->pSubpasses[i];
109                 uint32_t color_sample_count = 1, depth_sample_count = 1;
110                 struct radv_subpass *subpass = &pass->subpasses[i];
111
112                 subpass->input_count = desc->inputAttachmentCount;
113                 subpass->color_count = desc->colorAttachmentCount;
114                 if (multiview_info)
115                         subpass->view_mask = multiview_info->pViewMasks[i];
116
117                 if (desc->inputAttachmentCount > 0) {
118                         subpass->input_attachments = p;
119                         p += desc->inputAttachmentCount;
120
121                         for (uint32_t j = 0; j < desc->inputAttachmentCount; j++) {
122                                 subpass->input_attachments[j] = (struct radv_subpass_attachment) {
123                                         .attachment = desc->pInputAttachments[j].attachment,
124                                         .layout = desc->pInputAttachments[j].layout,
125                                 };
126                                 if (desc->pInputAttachments[j].attachment != VK_ATTACHMENT_UNUSED)
127                                         pass->attachments[desc->pInputAttachments[j].attachment].view_mask |= subpass->view_mask;
128                         }
129                 }
130
131                 if (desc->colorAttachmentCount > 0) {
132                         subpass->color_attachments = p;
133                         p += desc->colorAttachmentCount;
134
135                         for (uint32_t j = 0; j < desc->colorAttachmentCount; j++) {
136                                 subpass->color_attachments[j] = (struct radv_subpass_attachment) {
137                                         .attachment = desc->pColorAttachments[j].attachment,
138                                         .layout = desc->pColorAttachments[j].layout,
139                                 };
140                                 if (desc->pColorAttachments[j].attachment != VK_ATTACHMENT_UNUSED) {
141                                         pass->attachments[desc->pColorAttachments[j].attachment].view_mask |= subpass->view_mask;
142                                         color_sample_count = pCreateInfo->pAttachments[desc->pColorAttachments[j].attachment].samples;
143                                 }
144                         }
145                 }
146
147                 subpass->has_resolve = false;
148                 if (desc->pResolveAttachments) {
149                         subpass->resolve_attachments = p;
150                         p += desc->colorAttachmentCount;
151
152                         for (uint32_t j = 0; j < desc->colorAttachmentCount; j++) {
153                                 uint32_t a = desc->pResolveAttachments[j].attachment;
154                                 subpass->resolve_attachments[j] = (struct radv_subpass_attachment) {
155                                         .attachment = desc->pResolveAttachments[j].attachment,
156                                         .layout = desc->pResolveAttachments[j].layout,
157                                 };
158                                 if (a != VK_ATTACHMENT_UNUSED) {
159                                         subpass->has_resolve = true;
160                                         pass->attachments[desc->pResolveAttachments[j].attachment].view_mask |= subpass->view_mask;
161                                 }
162                         }
163                 }
164
165                 if (desc->pDepthStencilAttachment) {
166                         subpass->depth_stencil_attachment = (struct radv_subpass_attachment) {
167                                 .attachment = desc->pDepthStencilAttachment->attachment,
168                                 .layout = desc->pDepthStencilAttachment->layout,
169                         };
170                         if (desc->pDepthStencilAttachment->attachment != VK_ATTACHMENT_UNUSED) {
171                                 pass->attachments[desc->pDepthStencilAttachment->attachment].view_mask |= subpass->view_mask;
172                                 depth_sample_count = pCreateInfo->pAttachments[desc->pDepthStencilAttachment->attachment].samples;
173                         }
174                 } else {
175                         subpass->depth_stencil_attachment.attachment = VK_ATTACHMENT_UNUSED;
176                 }
177
178                 subpass->max_sample_count = MAX2(color_sample_count,
179                                                  depth_sample_count);
180         }
181
182         for (unsigned i = 0; i < pCreateInfo->dependencyCount; ++i) {
183                 uint32_t dst = pCreateInfo->pDependencies[i].dstSubpass;
184                 if (dst == VK_SUBPASS_EXTERNAL) {
185                         pass->end_barrier.src_stage_mask = pCreateInfo->pDependencies[i].srcStageMask;
186                         pass->end_barrier.src_access_mask = pCreateInfo->pDependencies[i].srcAccessMask;
187                         pass->end_barrier.dst_access_mask = pCreateInfo->pDependencies[i].dstAccessMask;
188                 } else {
189                         pass->subpasses[dst].start_barrier.src_stage_mask = pCreateInfo->pDependencies[i].srcStageMask;
190                         pass->subpasses[dst].start_barrier.src_access_mask = pCreateInfo->pDependencies[i].srcAccessMask;
191                         pass->subpasses[dst].start_barrier.dst_access_mask = pCreateInfo->pDependencies[i].dstAccessMask;
192                 }
193         }
194
195         *pRenderPass = radv_render_pass_to_handle(pass);
196
197         return VK_SUCCESS;
198 }
199
200 void radv_DestroyRenderPass(
201         VkDevice                                    _device,
202         VkRenderPass                                _pass,
203         const VkAllocationCallbacks*                pAllocator)
204 {
205         RADV_FROM_HANDLE(radv_device, device, _device);
206         RADV_FROM_HANDLE(radv_render_pass, pass, _pass);
207
208         if (!_pass)
209                 return;
210         vk_free2(&device->alloc, pAllocator, pass->subpass_attachments);
211         vk_free2(&device->alloc, pAllocator, pass);
212 }
213
214 void radv_GetRenderAreaGranularity(
215     VkDevice                                    device,
216     VkRenderPass                                renderPass,
217     VkExtent2D*                                 pGranularity)
218 {
219         pGranularity->width = 1;
220         pGranularity->height = 1;
221 }
222