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 31VkResult 32tu_CreateRenderPass(VkDevice _device, 33 const VkRenderPassCreateInfo *pCreateInfo, 34 const VkAllocationCallbacks *pAllocator, 35 VkRenderPass *pRenderPass) 36{ 37 TU_FROM_HANDLE(tu_device, device, _device); 38 struct tu_render_pass *pass; 39 size_t size; 40 size_t attachments_offset; 41 VkRenderPassMultiviewCreateInfo *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 { 62 switch (ext->sType) { 63 case VK_STRUCTURE_TYPE_RENDER_PASS_MULTIVIEW_CREATE_INFO: 64 multiview_info = (VkRenderPassMultiviewCreateInfo *) ext; 65 break; 66 default: 67 break; 68 } 69 } 70 71 for (uint32_t i = 0; i < pCreateInfo->attachmentCount; i++) { 72 struct tu_render_pass_attachment *att = &pass->attachments[i]; 73 74 att->format = pCreateInfo->pAttachments[i].format; 75 att->samples = pCreateInfo->pAttachments[i].samples; 76 att->load_op = pCreateInfo->pAttachments[i].loadOp; 77 att->stencil_load_op = pCreateInfo->pAttachments[i].stencilLoadOp; 78 att->initial_layout = pCreateInfo->pAttachments[i].initialLayout; 79 att->final_layout = pCreateInfo->pAttachments[i].finalLayout; 80 // att->store_op = pCreateInfo->pAttachments[i].storeOp; 81 // att->stencil_store_op = pCreateInfo->pAttachments[i].stencilStoreOp; 82 } 83 uint32_t subpass_attachment_count = 0; 84 struct tu_subpass_attachment *p; 85 for (uint32_t i = 0; i < pCreateInfo->subpassCount; i++) { 86 const VkSubpassDescription *desc = &pCreateInfo->pSubpasses[i]; 87 88 subpass_attachment_count += 89 desc->inputAttachmentCount + desc->colorAttachmentCount + 90 (desc->pResolveAttachments ? desc->colorAttachmentCount : 0) + 91 (desc->pDepthStencilAttachment != NULL); 92 } 93 94 if (subpass_attachment_count) { 95 pass->subpass_attachments = vk_alloc2( 96 &device->alloc, pAllocator, 97 subpass_attachment_count * sizeof(struct tu_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 tu_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 tu_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] 128 .view_mask |= subpass->view_mask; 129 } 130 } 131 132 if (desc->colorAttachmentCount > 0) { 133 subpass->color_attachments = p; 134 p += desc->colorAttachmentCount; 135 136 for (uint32_t j = 0; j < desc->colorAttachmentCount; j++) { 137 subpass->color_attachments[j] = (struct tu_subpass_attachment) { 138 .attachment = desc->pColorAttachments[j].attachment, 139 .layout = desc->pColorAttachments[j].layout, 140 }; 141 if (desc->pColorAttachments[j].attachment != 142 VK_ATTACHMENT_UNUSED) { 143 pass->attachments[desc->pColorAttachments[j].attachment] 144 .view_mask |= subpass->view_mask; 145 color_sample_count = 146 pCreateInfo 147 ->pAttachments[desc->pColorAttachments[j].attachment] 148 .samples; 149 } 150 } 151 } 152 153 subpass->has_resolve = false; 154 if (desc->pResolveAttachments) { 155 subpass->resolve_attachments = p; 156 p += desc->colorAttachmentCount; 157 158 for (uint32_t j = 0; j < desc->colorAttachmentCount; j++) { 159 uint32_t a = desc->pResolveAttachments[j].attachment; 160 subpass->resolve_attachments[j] = (struct tu_subpass_attachment) { 161 .attachment = desc->pResolveAttachments[j].attachment, 162 .layout = desc->pResolveAttachments[j].layout, 163 }; 164 if (a != VK_ATTACHMENT_UNUSED) { 165 subpass->has_resolve = true; 166 pass->attachments[desc->pResolveAttachments[j].attachment] 167 .view_mask |= subpass->view_mask; 168 } 169 } 170 } 171 172 if (desc->pDepthStencilAttachment) { 173 subpass->depth_stencil_attachment = (struct tu_subpass_attachment) { 174 .attachment = desc->pDepthStencilAttachment->attachment, 175 .layout = desc->pDepthStencilAttachment->layout, 176 }; 177 if (desc->pDepthStencilAttachment->attachment != 178 VK_ATTACHMENT_UNUSED) { 179 pass->attachments[desc->pDepthStencilAttachment->attachment] 180 .view_mask |= subpass->view_mask; 181 depth_sample_count = 182 pCreateInfo 183 ->pAttachments[desc->pDepthStencilAttachment->attachment] 184 .samples; 185 } 186 } else { 187 subpass->depth_stencil_attachment.attachment = VK_ATTACHMENT_UNUSED; 188 } 189 190 subpass->max_sample_count = 191 MAX2(color_sample_count, depth_sample_count); 192 } 193 194 for (unsigned i = 0; i < pCreateInfo->dependencyCount; ++i) { 195 uint32_t dst = pCreateInfo->pDependencies[i].dstSubpass; 196 if (dst == VK_SUBPASS_EXTERNAL) { 197 pass->end_barrier.src_stage_mask = 198 pCreateInfo->pDependencies[i].srcStageMask; 199 pass->end_barrier.src_access_mask = 200 pCreateInfo->pDependencies[i].srcAccessMask; 201 pass->end_barrier.dst_access_mask = 202 pCreateInfo->pDependencies[i].dstAccessMask; 203 } else { 204 pass->subpasses[dst].start_barrier.src_stage_mask = 205 pCreateInfo->pDependencies[i].srcStageMask; 206 pass->subpasses[dst].start_barrier.src_access_mask = 207 pCreateInfo->pDependencies[i].srcAccessMask; 208 pass->subpasses[dst].start_barrier.dst_access_mask = 209 pCreateInfo->pDependencies[i].dstAccessMask; 210 } 211 } 212 213 *pRenderPass = tu_render_pass_to_handle(pass); 214 215 return VK_SUCCESS; 216} 217 218VkResult 219tu_CreateRenderPass2KHR(VkDevice _device, 220 const VkRenderPassCreateInfo2KHR *pCreateInfo, 221 const VkAllocationCallbacks *pAllocator, 222 VkRenderPass *pRenderPass) 223{ 224 TU_FROM_HANDLE(tu_device, device, _device); 225 struct tu_render_pass *pass; 226 size_t size; 227 size_t attachments_offset; 228 229 assert(pCreateInfo->sType == 230 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2_KHR); 231 232 size = sizeof(*pass); 233 size += pCreateInfo->subpassCount * sizeof(pass->subpasses[0]); 234 attachments_offset = size; 235 size += pCreateInfo->attachmentCount * sizeof(pass->attachments[0]); 236 237 pass = vk_alloc2(&device->alloc, pAllocator, size, 8, 238 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); 239 if (pass == NULL) 240 return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY); 241 242 memset(pass, 0, size); 243 pass->attachment_count = pCreateInfo->attachmentCount; 244 pass->subpass_count = pCreateInfo->subpassCount; 245 pass->attachments = (void *) pass + attachments_offset; 246 247 for (uint32_t i = 0; i < pCreateInfo->attachmentCount; i++) { 248 struct tu_render_pass_attachment *att = &pass->attachments[i]; 249 250 att->format = pCreateInfo->pAttachments[i].format; 251 att->samples = pCreateInfo->pAttachments[i].samples; 252 att->load_op = pCreateInfo->pAttachments[i].loadOp; 253 att->stencil_load_op = pCreateInfo->pAttachments[i].stencilLoadOp; 254 att->initial_layout = pCreateInfo->pAttachments[i].initialLayout; 255 att->final_layout = pCreateInfo->pAttachments[i].finalLayout; 256 // att->store_op = pCreateInfo->pAttachments[i].storeOp; 257 // att->stencil_store_op = pCreateInfo->pAttachments[i].stencilStoreOp; 258 } 259 uint32_t subpass_attachment_count = 0; 260 struct tu_subpass_attachment *p; 261 for (uint32_t i = 0; i < pCreateInfo->subpassCount; i++) { 262 const VkSubpassDescription2KHR *desc = &pCreateInfo->pSubpasses[i]; 263 264 subpass_attachment_count += 265 desc->inputAttachmentCount + desc->colorAttachmentCount + 266 (desc->pResolveAttachments ? desc->colorAttachmentCount : 0) + 267 (desc->pDepthStencilAttachment != NULL); 268 } 269 270 if (subpass_attachment_count) { 271 pass->subpass_attachments = vk_alloc2( 272 &device->alloc, pAllocator, 273 subpass_attachment_count * sizeof(struct tu_subpass_attachment), 8, 274 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); 275 if (pass->subpass_attachments == NULL) { 276 vk_free2(&device->alloc, pAllocator, pass); 277 return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY); 278 } 279 } else 280 pass->subpass_attachments = NULL; 281 282 p = pass->subpass_attachments; 283 for (uint32_t i = 0; i < pCreateInfo->subpassCount; i++) { 284 const VkSubpassDescription2KHR *desc = &pCreateInfo->pSubpasses[i]; 285 uint32_t color_sample_count = 1, depth_sample_count = 1; 286 struct tu_subpass *subpass = &pass->subpasses[i]; 287 288 subpass->input_count = desc->inputAttachmentCount; 289 subpass->color_count = desc->colorAttachmentCount; 290 subpass->view_mask = desc->viewMask; 291 292 if (desc->inputAttachmentCount > 0) { 293 subpass->input_attachments = p; 294 p += desc->inputAttachmentCount; 295 296 for (uint32_t j = 0; j < desc->inputAttachmentCount; j++) { 297 subpass->input_attachments[j] = (struct tu_subpass_attachment) { 298 .attachment = desc->pInputAttachments[j].attachment, 299 .layout = desc->pInputAttachments[j].layout, 300 }; 301 if (desc->pInputAttachments[j].attachment != VK_ATTACHMENT_UNUSED) 302 pass->attachments[desc->pInputAttachments[j].attachment] 303 .view_mask |= subpass->view_mask; 304 } 305 } 306 307 if (desc->colorAttachmentCount > 0) { 308 subpass->color_attachments = p; 309 p += desc->colorAttachmentCount; 310 311 for (uint32_t j = 0; j < desc->colorAttachmentCount; j++) { 312 subpass->color_attachments[j] = (struct tu_subpass_attachment) { 313 .attachment = desc->pColorAttachments[j].attachment, 314 .layout = desc->pColorAttachments[j].layout, 315 }; 316 if (desc->pColorAttachments[j].attachment != 317 VK_ATTACHMENT_UNUSED) { 318 pass->attachments[desc->pColorAttachments[j].attachment] 319 .view_mask |= subpass->view_mask; 320 color_sample_count = 321 pCreateInfo 322 ->pAttachments[desc->pColorAttachments[j].attachment] 323 .samples; 324 } 325 } 326 } 327 328 subpass->has_resolve = false; 329 if (desc->pResolveAttachments) { 330 subpass->resolve_attachments = p; 331 p += desc->colorAttachmentCount; 332 333 for (uint32_t j = 0; j < desc->colorAttachmentCount; j++) { 334 uint32_t a = desc->pResolveAttachments[j].attachment; 335 subpass->resolve_attachments[j] = (struct tu_subpass_attachment) { 336 .attachment = desc->pResolveAttachments[j].attachment, 337 .layout = desc->pResolveAttachments[j].layout, 338 }; 339 if (a != VK_ATTACHMENT_UNUSED) { 340 subpass->has_resolve = true; 341 pass->attachments[desc->pResolveAttachments[j].attachment] 342 .view_mask |= subpass->view_mask; 343 } 344 } 345 } 346 347 if (desc->pDepthStencilAttachment) { 348 subpass->depth_stencil_attachment = (struct tu_subpass_attachment) { 349 .attachment = desc->pDepthStencilAttachment->attachment, 350 .layout = desc->pDepthStencilAttachment->layout, 351 }; 352 if (desc->pDepthStencilAttachment->attachment != 353 VK_ATTACHMENT_UNUSED) { 354 pass->attachments[desc->pDepthStencilAttachment->attachment] 355 .view_mask |= subpass->view_mask; 356 depth_sample_count = 357 pCreateInfo 358 ->pAttachments[desc->pDepthStencilAttachment->attachment] 359 .samples; 360 } 361 } else { 362 subpass->depth_stencil_attachment.attachment = VK_ATTACHMENT_UNUSED; 363 } 364 365 subpass->max_sample_count = 366 MAX2(color_sample_count, depth_sample_count); 367 } 368 369 for (unsigned i = 0; i < pCreateInfo->dependencyCount; ++i) { 370 uint32_t dst = pCreateInfo->pDependencies[i].dstSubpass; 371 if (dst == VK_SUBPASS_EXTERNAL) { 372 pass->end_barrier.src_stage_mask = 373 pCreateInfo->pDependencies[i].srcStageMask; 374 pass->end_barrier.src_access_mask = 375 pCreateInfo->pDependencies[i].srcAccessMask; 376 pass->end_barrier.dst_access_mask = 377 pCreateInfo->pDependencies[i].dstAccessMask; 378 } else { 379 pass->subpasses[dst].start_barrier.src_stage_mask = 380 pCreateInfo->pDependencies[i].srcStageMask; 381 pass->subpasses[dst].start_barrier.src_access_mask = 382 pCreateInfo->pDependencies[i].srcAccessMask; 383 pass->subpasses[dst].start_barrier.dst_access_mask = 384 pCreateInfo->pDependencies[i].dstAccessMask; 385 } 386 } 387 388 *pRenderPass = tu_render_pass_to_handle(pass); 389 390 return VK_SUCCESS; 391} 392 393void 394tu_DestroyRenderPass(VkDevice _device, 395 VkRenderPass _pass, 396 const VkAllocationCallbacks *pAllocator) 397{ 398 TU_FROM_HANDLE(tu_device, device, _device); 399 TU_FROM_HANDLE(tu_render_pass, pass, _pass); 400 401 if (!_pass) 402 return; 403 vk_free2(&device->alloc, pAllocator, pass->subpass_attachments); 404 vk_free2(&device->alloc, pAllocator, pass); 405} 406 407void 408tu_GetRenderAreaGranularity(VkDevice _device, 409 VkRenderPass renderPass, 410 VkExtent2D *pGranularity) 411{ 412 TU_FROM_HANDLE(tu_device, device, _device); 413 414 pGranularity->width = device->physical_device->tile_align_w; 415 pGranularity->height = device->physical_device->tile_align_h; 416} 417