turnip: remove compute emit_border_color
[mesa.git] / src / freedreno / vulkan / tu_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
25 * DEALINGS IN THE SOFTWARE.
26 */
27 #include "tu_private.h"
28
29 #include "vk_util.h"
30 #include "vk_format.h"
31
32 static void update_samples(struct tu_subpass *subpass,
33 VkSampleCountFlagBits samples)
34 {
35 assert(subpass->samples == 0 || subpass->samples == samples);
36 subpass->samples = samples;
37 }
38
39 VkResult
40 tu_CreateRenderPass(VkDevice _device,
41 const VkRenderPassCreateInfo *pCreateInfo,
42 const VkAllocationCallbacks *pAllocator,
43 VkRenderPass *pRenderPass)
44 {
45 TU_FROM_HANDLE(tu_device, device, _device);
46 struct tu_render_pass *pass;
47 size_t size;
48 size_t attachments_offset;
49
50 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO);
51 assert(pCreateInfo->attachmentCount < MAX_ATTACHMENTS);
52
53 size = sizeof(*pass);
54 size += pCreateInfo->subpassCount * sizeof(pass->subpasses[0]);
55 attachments_offset = size;
56 size += pCreateInfo->attachmentCount * sizeof(pass->attachments[0]);
57
58 pass = vk_alloc2(&device->alloc, pAllocator, size, 8,
59 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
60 if (pass == NULL)
61 return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
62
63 memset(pass, 0, size);
64 pass->attachment_count = pCreateInfo->attachmentCount;
65 pass->subpass_count = pCreateInfo->subpassCount;
66 pass->attachments = (void *) pass + attachments_offset;
67
68 for (uint32_t i = 0; i < pCreateInfo->attachmentCount; i++) {
69 struct tu_render_pass_attachment *att = &pass->attachments[i];
70
71 att->format = pCreateInfo->pAttachments[i].format;
72 att->cpp = vk_format_get_blocksize(att->format) *
73 pCreateInfo->pAttachments[i].samples;
74 att->load_op = pCreateInfo->pAttachments[i].loadOp;
75 att->stencil_load_op = pCreateInfo->pAttachments[i].stencilLoadOp;
76 att->store_op = pCreateInfo->pAttachments[i].storeOp;
77 if (pCreateInfo->pAttachments[i].stencilStoreOp == VK_ATTACHMENT_STORE_OP_STORE &&
78 vk_format_has_stencil(att->format))
79 att->store_op = VK_ATTACHMENT_STORE_OP_STORE;
80 }
81
82 uint32_t subpass_attachment_count = 0;
83 struct tu_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 + desc->colorAttachmentCount +
89 (desc->pResolveAttachments ? desc->colorAttachmentCount : 0);
90 }
91
92 if (subpass_attachment_count) {
93 pass->subpass_attachments = vk_alloc2(
94 &device->alloc, pAllocator,
95 subpass_attachment_count * sizeof(struct tu_subpass_attachment), 8,
96 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
97 if (pass->subpass_attachments == NULL) {
98 vk_free2(&device->alloc, pAllocator, pass);
99 return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
100 }
101 } else
102 pass->subpass_attachments = NULL;
103
104 p = pass->subpass_attachments;
105 for (uint32_t i = 0; i < pCreateInfo->subpassCount; i++) {
106 const VkSubpassDescription *desc = &pCreateInfo->pSubpasses[i];
107 struct tu_subpass *subpass = &pass->subpasses[i];
108
109 subpass->input_count = desc->inputAttachmentCount;
110 subpass->color_count = desc->colorAttachmentCount;
111 subpass->samples = 0;
112
113 if (desc->inputAttachmentCount > 0) {
114 subpass->input_attachments = p;
115 p += desc->inputAttachmentCount;
116
117 for (uint32_t j = 0; j < desc->inputAttachmentCount; j++) {
118 uint32_t a = desc->pInputAttachments[j].attachment;
119 subpass->input_attachments[j].attachment = a;
120 if (a != VK_ATTACHMENT_UNUSED)
121 pass->attachments[a].needs_gmem = true;
122 }
123 }
124
125 if (desc->colorAttachmentCount > 0) {
126 subpass->color_attachments = p;
127 p += desc->colorAttachmentCount;
128
129 for (uint32_t j = 0; j < desc->colorAttachmentCount; j++) {
130 uint32_t a = desc->pColorAttachments[j].attachment;
131 subpass->color_attachments[j].attachment = a;
132
133 if (a != VK_ATTACHMENT_UNUSED) {
134 pass->attachments[a].needs_gmem = true;
135 update_samples(subpass, pCreateInfo->pAttachments[a].samples);
136 }
137 }
138 }
139
140 subpass->resolve_attachments = desc->pResolveAttachments ? p : NULL;
141 if (desc->pResolveAttachments) {
142 p += desc->colorAttachmentCount;
143 for (uint32_t j = 0; j < desc->colorAttachmentCount; j++) {
144 subpass->resolve_attachments[j].attachment =
145 desc->pResolveAttachments[j].attachment;
146 }
147 }
148
149 uint32_t a = desc->pDepthStencilAttachment ?
150 desc->pDepthStencilAttachment->attachment : VK_ATTACHMENT_UNUSED;
151 subpass->depth_stencil_attachment.attachment = a;
152 if (a != VK_ATTACHMENT_UNUSED) {
153 pass->attachments[a].needs_gmem = true;
154 update_samples(subpass, pCreateInfo->pAttachments[a].samples);
155 }
156
157 subpass->samples = subpass->samples ?: 1;
158 }
159
160 *pRenderPass = tu_render_pass_to_handle(pass);
161
162 return VK_SUCCESS;
163 }
164
165 VkResult
166 tu_CreateRenderPass2KHR(VkDevice _device,
167 const VkRenderPassCreateInfo2KHR *pCreateInfo,
168 const VkAllocationCallbacks *pAllocator,
169 VkRenderPass *pRenderPass)
170 {
171 TU_FROM_HANDLE(tu_device, device, _device);
172 struct tu_render_pass *pass;
173 size_t size;
174 size_t attachments_offset;
175
176 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2_KHR);
177 assert(pCreateInfo->attachmentCount < MAX_ATTACHMENTS);
178
179 size = sizeof(*pass);
180 size += pCreateInfo->subpassCount * sizeof(pass->subpasses[0]);
181 attachments_offset = size;
182 size += pCreateInfo->attachmentCount * sizeof(pass->attachments[0]);
183
184 pass = vk_alloc2(&device->alloc, pAllocator, size, 8,
185 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
186 if (pass == NULL)
187 return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
188
189 memset(pass, 0, size);
190 pass->attachment_count = pCreateInfo->attachmentCount;
191 pass->subpass_count = pCreateInfo->subpassCount;
192 pass->attachments = (void *) pass + attachments_offset;
193
194 for (uint32_t i = 0; i < pCreateInfo->attachmentCount; i++) {
195 struct tu_render_pass_attachment *att = &pass->attachments[i];
196
197 att->format = pCreateInfo->pAttachments[i].format;
198 att->cpp = vk_format_get_blocksize(att->format) *
199 pCreateInfo->pAttachments[i].samples;
200 att->load_op = pCreateInfo->pAttachments[i].loadOp;
201 att->stencil_load_op = pCreateInfo->pAttachments[i].stencilLoadOp;
202 att->store_op = pCreateInfo->pAttachments[i].storeOp;
203 att->stencil_store_op = pCreateInfo->pAttachments[i].stencilStoreOp;
204 if (pCreateInfo->pAttachments[i].stencilStoreOp == VK_ATTACHMENT_STORE_OP_STORE &&
205 vk_format_has_stencil(att->format))
206 att->store_op = VK_ATTACHMENT_STORE_OP_STORE;
207 }
208 uint32_t subpass_attachment_count = 0;
209 struct tu_subpass_attachment *p;
210 for (uint32_t i = 0; i < pCreateInfo->subpassCount; i++) {
211 const VkSubpassDescription2KHR *desc = &pCreateInfo->pSubpasses[i];
212
213 subpass_attachment_count +=
214 desc->inputAttachmentCount + desc->colorAttachmentCount +
215 (desc->pResolveAttachments ? desc->colorAttachmentCount : 0);
216 }
217
218 if (subpass_attachment_count) {
219 pass->subpass_attachments = vk_alloc2(
220 &device->alloc, pAllocator,
221 subpass_attachment_count * sizeof(struct tu_subpass_attachment), 8,
222 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
223 if (pass->subpass_attachments == NULL) {
224 vk_free2(&device->alloc, pAllocator, pass);
225 return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
226 }
227 } else
228 pass->subpass_attachments = NULL;
229
230 p = pass->subpass_attachments;
231 for (uint32_t i = 0; i < pCreateInfo->subpassCount; i++) {
232 const VkSubpassDescription2KHR *desc = &pCreateInfo->pSubpasses[i];
233 struct tu_subpass *subpass = &pass->subpasses[i];
234
235 subpass->input_count = desc->inputAttachmentCount;
236 subpass->color_count = desc->colorAttachmentCount;
237 subpass->samples = 0;
238
239 if (desc->inputAttachmentCount > 0) {
240 subpass->input_attachments = p;
241 p += desc->inputAttachmentCount;
242
243 for (uint32_t j = 0; j < desc->inputAttachmentCount; j++) {
244 uint32_t a = desc->pInputAttachments[j].attachment;
245 subpass->input_attachments[j].attachment = a;
246 if (a != VK_ATTACHMENT_UNUSED)
247 pass->attachments[a].needs_gmem = true;
248 }
249 }
250
251 if (desc->colorAttachmentCount > 0) {
252 subpass->color_attachments = p;
253 p += desc->colorAttachmentCount;
254
255 for (uint32_t j = 0; j < desc->colorAttachmentCount; j++) {
256 uint32_t a = desc->pColorAttachments[j].attachment;
257 subpass->color_attachments[j].attachment = a;
258
259 if (a != VK_ATTACHMENT_UNUSED) {
260 pass->attachments[a].needs_gmem = true;
261 update_samples(subpass, pCreateInfo->pAttachments[a].samples);
262 }
263 }
264 }
265
266 subpass->resolve_attachments = desc->pResolveAttachments ? p : NULL;
267 if (desc->pResolveAttachments) {
268 p += desc->colorAttachmentCount;
269 for (uint32_t j = 0; j < desc->colorAttachmentCount; j++) {
270 subpass->resolve_attachments[j].attachment =
271 desc->pResolveAttachments[j].attachment;
272 }
273 }
274
275
276 uint32_t a = desc->pDepthStencilAttachment ?
277 desc->pDepthStencilAttachment->attachment : VK_ATTACHMENT_UNUSED;
278 subpass->depth_stencil_attachment.attachment = a;
279 if (a != VK_ATTACHMENT_UNUSED) {
280 pass->attachments[a].needs_gmem = true;
281 update_samples(subpass, pCreateInfo->pAttachments[a].samples);
282 }
283
284 subpass->samples = subpass->samples ?: 1;
285 }
286
287 *pRenderPass = tu_render_pass_to_handle(pass);
288
289 return VK_SUCCESS;
290 }
291
292 void
293 tu_DestroyRenderPass(VkDevice _device,
294 VkRenderPass _pass,
295 const VkAllocationCallbacks *pAllocator)
296 {
297 TU_FROM_HANDLE(tu_device, device, _device);
298 TU_FROM_HANDLE(tu_render_pass, pass, _pass);
299
300 if (!_pass)
301 return;
302 vk_free2(&device->alloc, pAllocator, pass->subpass_attachments);
303 vk_free2(&device->alloc, pAllocator, pass);
304 }
305
306 void
307 tu_GetRenderAreaGranularity(VkDevice _device,
308 VkRenderPass renderPass,
309 VkExtent2D *pGranularity)
310 {
311 TU_FROM_HANDLE(tu_device, device, _device);
312
313 pGranularity->width = device->physical_device->tile_align_w;
314 pGranularity->height = device->physical_device->tile_align_h;
315 }