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#include "vk_util.h" 27 28static void 29anv_render_pass_add_subpass_dep(struct anv_render_pass *pass, 30 const VkSubpassDependency2KHR *dep) 31{ 32 if (dep->dstSubpass == VK_SUBPASS_EXTERNAL) { 33 pass->subpass_flushes[pass->subpass_count] |= 34 anv_pipe_invalidate_bits_for_access_flags(dep->dstAccessMask); 35 } else { 36 assert(dep->dstSubpass < pass->subpass_count); 37 pass->subpass_flushes[dep->dstSubpass] |= 38 anv_pipe_invalidate_bits_for_access_flags(dep->dstAccessMask); 39 } 40 41 if (dep->srcSubpass == VK_SUBPASS_EXTERNAL) { 42 pass->subpass_flushes[0] |= 43 anv_pipe_flush_bits_for_access_flags(dep->srcAccessMask); 44 } else { 45 assert(dep->srcSubpass < pass->subpass_count); 46 pass->subpass_flushes[dep->srcSubpass + 1] |= 47 anv_pipe_flush_bits_for_access_flags(dep->srcAccessMask); 48 } 49} 50 51/* Do a second "compile" step on a render pass */ 52static void 53anv_render_pass_compile(struct anv_render_pass *pass) 54{ 55 /* The CreateRenderPass code zeros the entire render pass and also uses a 56 * designated initializer for filling these out. There's no need for us to 57 * do it again. 58 * 59 * for (uint32_t i = 0; i < pass->attachment_count; i++) { 60 * pass->attachments[i].usage = 0; 61 * pass->attachments[i].first_subpass_layout = VK_IMAGE_LAYOUT_UNDEFINED; 62 * } 63 */ 64 65 VkImageUsageFlags all_usage = 0; 66 for (uint32_t i = 0; i < pass->subpass_count; i++) { 67 struct anv_subpass *subpass = &pass->subpasses[i]; 68 69 /* We don't allow depth_stencil_attachment to be non-NULL and be 70 * VK_ATTACHMENT_UNUSED. This way something can just check for NULL 71 * and be guaranteed that they have a valid attachment. 72 */ 73 if (subpass->depth_stencil_attachment && 74 subpass->depth_stencil_attachment->attachment == VK_ATTACHMENT_UNUSED) 75 subpass->depth_stencil_attachment = NULL; 76 77 if (subpass->ds_resolve_attachment && 78 subpass->ds_resolve_attachment->attachment == VK_ATTACHMENT_UNUSED) 79 subpass->ds_resolve_attachment = NULL; 80 81 for (uint32_t j = 0; j < subpass->attachment_count; j++) { 82 struct anv_subpass_attachment *subpass_att = &subpass->attachments[j]; 83 if (subpass_att->attachment == VK_ATTACHMENT_UNUSED) 84 continue; 85 86 struct anv_render_pass_attachment *pass_att = 87 &pass->attachments[subpass_att->attachment]; 88 89 assert(__builtin_popcount(subpass_att->usage) == 1); 90 pass_att->usage |= subpass_att->usage; 91 pass_att->last_subpass_idx = i; 92 93 all_usage |= subpass_att->usage; 94 95 if (pass_att->first_subpass_layout == VK_IMAGE_LAYOUT_UNDEFINED) { 96 pass_att->first_subpass_layout = subpass_att->layout; 97 assert(pass_att->first_subpass_layout != VK_IMAGE_LAYOUT_UNDEFINED); 98 } 99 100 if (subpass_att->usage == VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT && 101 subpass->depth_stencil_attachment && 102 subpass_att->attachment == subpass->depth_stencil_attachment->attachment) 103 subpass->has_ds_self_dep = true; 104 } 105 106 /* We have to handle resolve attachments specially */ 107 subpass->has_color_resolve = false; 108 if (subpass->resolve_attachments) { 109 for (uint32_t j = 0; j < subpass->color_count; j++) { 110 struct anv_subpass_attachment *color_att = 111 &subpass->color_attachments[j]; 112 struct anv_subpass_attachment *resolve_att = 113 &subpass->resolve_attachments[j]; 114 if (resolve_att->attachment == VK_ATTACHMENT_UNUSED) 115 continue; 116 117 subpass->has_color_resolve = true; 118 119 assert(resolve_att->usage == VK_IMAGE_USAGE_TRANSFER_DST_BIT); 120 color_att->usage |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT; 121 } 122 } 123 124 if (subpass->ds_resolve_attachment) { 125 struct anv_subpass_attachment *ds_att = 126 subpass->depth_stencil_attachment; 127 UNUSED struct anv_subpass_attachment *resolve_att = 128 subpass->ds_resolve_attachment; 129 130 assert(resolve_att->usage == VK_IMAGE_USAGE_TRANSFER_DST_BIT); 131 ds_att->usage |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT; 132 } 133 } 134 135 /* From the Vulkan 1.0.39 spec: 136 * 137 * If there is no subpass dependency from VK_SUBPASS_EXTERNAL to the 138 * first subpass that uses an attachment, then an implicit subpass 139 * dependency exists from VK_SUBPASS_EXTERNAL to the first subpass it is 140 * used in. The subpass dependency operates as if defined with the 141 * following parameters: 142 * 143 * VkSubpassDependency implicitDependency = { 144 * .srcSubpass = VK_SUBPASS_EXTERNAL; 145 * .dstSubpass = firstSubpass; // First subpass attachment is used in 146 * .srcStageMask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; 147 * .dstStageMask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT; 148 * .srcAccessMask = 0; 149 * .dstAccessMask = VK_ACCESS_INPUT_ATTACHMENT_READ_BIT | 150 * VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | 151 * VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | 152 * VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | 153 * VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; 154 * .dependencyFlags = 0; 155 * }; 156 * 157 * Similarly, if there is no subpass dependency from the last subpass 158 * that uses an attachment to VK_SUBPASS_EXTERNAL, then an implicit 159 * subpass dependency exists from the last subpass it is used in to 160 * VK_SUBPASS_EXTERNAL. The subpass dependency operates as if defined 161 * with the following parameters: 162 * 163 * VkSubpassDependency implicitDependency = { 164 * .srcSubpass = lastSubpass; // Last subpass attachment is used in 165 * .dstSubpass = VK_SUBPASS_EXTERNAL; 166 * .srcStageMask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT; 167 * .dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT; 168 * .srcAccessMask = VK_ACCESS_INPUT_ATTACHMENT_READ_BIT | 169 * VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | 170 * VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | 171 * VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | 172 * VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; 173 * .dstAccessMask = 0; 174 * .dependencyFlags = 0; 175 * }; 176 * 177 * We could implement this by walking over all of the attachments and 178 * subpasses and checking to see if any of them don't have an external 179 * dependency. Or, we could just be lazy and add a couple extra flushes. 180 * We choose to be lazy. 181 * 182 * From the documentation for vkCmdNextSubpass: 183 * 184 * "Moving to the next subpass automatically performs any multisample 185 * resolve operations in the subpass being ended. End-of-subpass 186 * multisample resolves are treated as color attachment writes for the 187 * purposes of synchronization. This applies to resolve operations for 188 * both color and depth/stencil attachments. That is, they are 189 * considered to execute in the 190 * VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT pipeline stage and 191 * their writes are synchronized with 192 * VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT." 193 * 194 * Therefore, the above flags concerning color attachments also apply to 195 * color and depth/stencil resolve attachments. 196 */ 197 if (all_usage & VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT) { 198 pass->subpass_flushes[0] |= 199 ANV_PIPE_TEXTURE_CACHE_INVALIDATE_BIT; 200 } 201 if (all_usage & (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | 202 VK_IMAGE_USAGE_TRANSFER_DST_BIT)) { 203 pass->subpass_flushes[pass->subpass_count] |= 204 ANV_PIPE_RENDER_TARGET_CACHE_FLUSH_BIT; 205 } 206 if (all_usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) { 207 pass->subpass_flushes[pass->subpass_count] |= 208 ANV_PIPE_DEPTH_CACHE_FLUSH_BIT; 209 } 210} 211 212static unsigned 213num_subpass_attachments(const VkSubpassDescription *desc) 214{ 215 return desc->inputAttachmentCount + 216 desc->colorAttachmentCount + 217 (desc->pResolveAttachments ? desc->colorAttachmentCount : 0) + 218 (desc->pDepthStencilAttachment != NULL); 219} 220 221VkResult anv_CreateRenderPass( 222 VkDevice _device, 223 const VkRenderPassCreateInfo* pCreateInfo, 224 const VkAllocationCallbacks* pAllocator, 225 VkRenderPass* pRenderPass) 226{ 227 ANV_FROM_HANDLE(anv_device, device, _device); 228 229 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO); 230 231 struct anv_render_pass *pass; 232 struct anv_subpass *subpasses; 233 struct anv_render_pass_attachment *attachments; 234 enum anv_pipe_bits *subpass_flushes; 235 236 ANV_MULTIALLOC(ma); 237 anv_multialloc_add(&ma, &pass, 1); 238 anv_multialloc_add(&ma, &subpasses, pCreateInfo->subpassCount); 239 anv_multialloc_add(&ma, &attachments, pCreateInfo->attachmentCount); 240 anv_multialloc_add(&ma, &subpass_flushes, pCreateInfo->subpassCount + 1); 241 242 struct anv_subpass_attachment *subpass_attachments; 243 uint32_t subpass_attachment_count = 0; 244 for (uint32_t i = 0; i < pCreateInfo->subpassCount; i++) { 245 subpass_attachment_count += 246 num_subpass_attachments(&pCreateInfo->pSubpasses[i]); 247 } 248 anv_multialloc_add(&ma, &subpass_attachments, subpass_attachment_count); 249 250 if (!anv_multialloc_alloc2(&ma, &device->alloc, pAllocator, 251 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT)) 252 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY); 253 254 /* Clear the subpasses along with the parent pass. This required because 255 * each array member of anv_subpass must be a valid pointer if not NULL. 256 */ 257 memset(pass, 0, ma.size); 258 pass->attachment_count = pCreateInfo->attachmentCount; 259 pass->subpass_count = pCreateInfo->subpassCount; 260 pass->attachments = attachments; 261 pass->subpass_flushes = subpass_flushes; 262 263 for (uint32_t i = 0; i < pCreateInfo->attachmentCount; i++) { 264 pass->attachments[i] = (struct anv_render_pass_attachment) { 265 .format = pCreateInfo->pAttachments[i].format, 266 .samples = pCreateInfo->pAttachments[i].samples, 267 .load_op = pCreateInfo->pAttachments[i].loadOp, 268 .store_op = pCreateInfo->pAttachments[i].storeOp, 269 .stencil_load_op = pCreateInfo->pAttachments[i].stencilLoadOp, 270 .initial_layout = pCreateInfo->pAttachments[i].initialLayout, 271 .final_layout = pCreateInfo->pAttachments[i].finalLayout, 272 }; 273 } 274 275 for (uint32_t i = 0; i < pCreateInfo->subpassCount; i++) { 276 const VkSubpassDescription *desc = &pCreateInfo->pSubpasses[i]; 277 struct anv_subpass *subpass = &pass->subpasses[i]; 278 279 subpass->input_count = desc->inputAttachmentCount; 280 subpass->color_count = desc->colorAttachmentCount; 281 subpass->attachment_count = num_subpass_attachments(desc); 282 subpass->attachments = subpass_attachments; 283 subpass->view_mask = 0; 284 285 if (desc->inputAttachmentCount > 0) { 286 subpass->input_attachments = subpass_attachments; 287 subpass_attachments += desc->inputAttachmentCount; 288 289 for (uint32_t j = 0; j < desc->inputAttachmentCount; j++) { 290 subpass->input_attachments[j] = (struct anv_subpass_attachment) { 291 .usage = VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT, 292 .attachment = desc->pInputAttachments[j].attachment, 293 .layout = desc->pInputAttachments[j].layout, 294 }; 295 } 296 } 297 298 if (desc->colorAttachmentCount > 0) { 299 subpass->color_attachments = subpass_attachments; 300 subpass_attachments += desc->colorAttachmentCount; 301 302 for (uint32_t j = 0; j < desc->colorAttachmentCount; j++) { 303 subpass->color_attachments[j] = (struct anv_subpass_attachment) { 304 .usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, 305 .attachment = desc->pColorAttachments[j].attachment, 306 .layout = desc->pColorAttachments[j].layout, 307 }; 308 } 309 } 310 311 if (desc->pResolveAttachments) { 312 subpass->resolve_attachments = subpass_attachments; 313 subpass_attachments += desc->colorAttachmentCount; 314 315 for (uint32_t j = 0; j < desc->colorAttachmentCount; j++) { 316 subpass->resolve_attachments[j] = (struct anv_subpass_attachment) { 317 .usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT, 318 .attachment = desc->pResolveAttachments[j].attachment, 319 .layout = desc->pResolveAttachments[j].layout, 320 }; 321 } 322 } 323 324 if (desc->pDepthStencilAttachment) { 325 subpass->depth_stencil_attachment = subpass_attachments++; 326 327 *subpass->depth_stencil_attachment = (struct anv_subpass_attachment) { 328 .usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, 329 .attachment = desc->pDepthStencilAttachment->attachment, 330 .layout = desc->pDepthStencilAttachment->layout, 331 }; 332 } 333 } 334 335 for (uint32_t i = 0; i < pCreateInfo->dependencyCount; i++) { 336 /* Convert to a Dependency2KHR */ 337 struct VkSubpassDependency2KHR dep2 = { 338 .srcSubpass = pCreateInfo->pDependencies[i].srcSubpass, 339 .dstSubpass = pCreateInfo->pDependencies[i].dstSubpass, 340 .srcStageMask = pCreateInfo->pDependencies[i].srcStageMask, 341 .dstStageMask = pCreateInfo->pDependencies[i].dstStageMask, 342 .srcAccessMask = pCreateInfo->pDependencies[i].srcAccessMask, 343 .dstAccessMask = pCreateInfo->pDependencies[i].dstAccessMask, 344 .dependencyFlags = pCreateInfo->pDependencies[i].dependencyFlags, 345 }; 346 anv_render_pass_add_subpass_dep(pass, &dep2); 347 } 348 349 vk_foreach_struct(ext, pCreateInfo->pNext) { 350 switch (ext->sType) { 351 case VK_STRUCTURE_TYPE_RENDER_PASS_INPUT_ATTACHMENT_ASPECT_CREATE_INFO: 352 /* We don't care about this information */ 353 break; 354 355 case VK_STRUCTURE_TYPE_RENDER_PASS_MULTIVIEW_CREATE_INFO: { 356 VkRenderPassMultiviewCreateInfo *mv = (void *)ext; 357 358 for (uint32_t i = 0; i < mv->subpassCount; i++) { 359 pass->subpasses[i].view_mask = mv->pViewMasks[i]; 360 } 361 break; 362 } 363 364 default: 365 anv_debug_ignored_stype(ext->sType); 366 } 367 } 368 369 anv_render_pass_compile(pass); 370 371 *pRenderPass = anv_render_pass_to_handle(pass); 372 373 return VK_SUCCESS; 374} 375 376static unsigned 377num_subpass_attachments2(const VkSubpassDescription2KHR *desc) 378{ 379 const VkSubpassDescriptionDepthStencilResolveKHR *ds_resolve = 380 vk_find_struct_const(desc->pNext, 381 SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE_KHR); 382 383 return desc->inputAttachmentCount + 384 desc->colorAttachmentCount + 385 (desc->pResolveAttachments ? desc->colorAttachmentCount : 0) + 386 (desc->pDepthStencilAttachment != NULL) + 387 (ds_resolve && ds_resolve->pDepthStencilResolveAttachment); 388} 389 390VkResult anv_CreateRenderPass2KHR( 391 VkDevice _device, 392 const VkRenderPassCreateInfo2KHR* pCreateInfo, 393 const VkAllocationCallbacks* pAllocator, 394 VkRenderPass* pRenderPass) 395{ 396 ANV_FROM_HANDLE(anv_device, device, _device); 397 398 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2_KHR); 399 400 struct anv_render_pass *pass; 401 struct anv_subpass *subpasses; 402 struct anv_render_pass_attachment *attachments; 403 enum anv_pipe_bits *subpass_flushes; 404 405 ANV_MULTIALLOC(ma); 406 anv_multialloc_add(&ma, &pass, 1); 407 anv_multialloc_add(&ma, &subpasses, pCreateInfo->subpassCount); 408 anv_multialloc_add(&ma, &attachments, pCreateInfo->attachmentCount); 409 anv_multialloc_add(&ma, &subpass_flushes, pCreateInfo->subpassCount + 1); 410 411 struct anv_subpass_attachment *subpass_attachments; 412 uint32_t subpass_attachment_count = 0; 413 for (uint32_t i = 0; i < pCreateInfo->subpassCount; i++) { 414 subpass_attachment_count += 415 num_subpass_attachments2(&pCreateInfo->pSubpasses[i]); 416 } 417 anv_multialloc_add(&ma, &subpass_attachments, subpass_attachment_count); 418 419 if (!anv_multialloc_alloc2(&ma, &device->alloc, pAllocator, 420 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT)) 421 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY); 422 423 /* Clear the subpasses along with the parent pass. This required because 424 * each array member of anv_subpass must be a valid pointer if not NULL. 425 */ 426 memset(pass, 0, ma.size); 427 pass->attachment_count = pCreateInfo->attachmentCount; 428 pass->subpass_count = pCreateInfo->subpassCount; 429 pass->attachments = attachments; 430 pass->subpass_flushes = subpass_flushes; 431 432 for (uint32_t i = 0; i < pCreateInfo->attachmentCount; i++) { 433 pass->attachments[i] = (struct anv_render_pass_attachment) { 434 .format = pCreateInfo->pAttachments[i].format, 435 .samples = pCreateInfo->pAttachments[i].samples, 436 .load_op = pCreateInfo->pAttachments[i].loadOp, 437 .store_op = pCreateInfo->pAttachments[i].storeOp, 438 .stencil_load_op = pCreateInfo->pAttachments[i].stencilLoadOp, 439 .initial_layout = pCreateInfo->pAttachments[i].initialLayout, 440 .final_layout = pCreateInfo->pAttachments[i].finalLayout, 441 }; 442 } 443 444 for (uint32_t i = 0; i < pCreateInfo->subpassCount; i++) { 445 const VkSubpassDescription2KHR *desc = &pCreateInfo->pSubpasses[i]; 446 struct anv_subpass *subpass = &pass->subpasses[i]; 447 448 subpass->input_count = desc->inputAttachmentCount; 449 subpass->color_count = desc->colorAttachmentCount; 450 subpass->attachment_count = num_subpass_attachments2(desc); 451 subpass->attachments = subpass_attachments; 452 subpass->view_mask = desc->viewMask; 453 454 if (desc->inputAttachmentCount > 0) { 455 subpass->input_attachments = subpass_attachments; 456 subpass_attachments += desc->inputAttachmentCount; 457 458 for (uint32_t j = 0; j < desc->inputAttachmentCount; j++) { 459 subpass->input_attachments[j] = (struct anv_subpass_attachment) { 460 .usage = VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT, 461 .attachment = desc->pInputAttachments[j].attachment, 462 .layout = desc->pInputAttachments[j].layout, 463 }; 464 } 465 } 466 467 if (desc->colorAttachmentCount > 0) { 468 subpass->color_attachments = subpass_attachments; 469 subpass_attachments += desc->colorAttachmentCount; 470 471 for (uint32_t j = 0; j < desc->colorAttachmentCount; j++) { 472 subpass->color_attachments[j] = (struct anv_subpass_attachment) { 473 .usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, 474 .attachment = desc->pColorAttachments[j].attachment, 475 .layout = desc->pColorAttachments[j].layout, 476 }; 477 } 478 } 479 480 if (desc->pResolveAttachments) { 481 subpass->resolve_attachments = subpass_attachments; 482 subpass_attachments += desc->colorAttachmentCount; 483 484 for (uint32_t j = 0; j < desc->colorAttachmentCount; j++) { 485 subpass->resolve_attachments[j] = (struct anv_subpass_attachment) { 486 .usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT, 487 .attachment = desc->pResolveAttachments[j].attachment, 488 .layout = desc->pResolveAttachments[j].layout, 489 }; 490 } 491 } 492 493 if (desc->pDepthStencilAttachment) { 494 subpass->depth_stencil_attachment = subpass_attachments++; 495 496 *subpass->depth_stencil_attachment = (struct anv_subpass_attachment) { 497 .usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, 498 .attachment = desc->pDepthStencilAttachment->attachment, 499 .layout = desc->pDepthStencilAttachment->layout, 500 }; 501 } 502 503 const VkSubpassDescriptionDepthStencilResolveKHR *ds_resolve = 504 vk_find_struct_const(desc->pNext, 505 SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE_KHR); 506 507 if (ds_resolve && ds_resolve->pDepthStencilResolveAttachment) { 508 subpass->ds_resolve_attachment = subpass_attachments++; 509 510 *subpass->ds_resolve_attachment = (struct anv_subpass_attachment) { 511 .usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT, 512 .attachment = ds_resolve->pDepthStencilResolveAttachment->attachment, 513 .layout = ds_resolve->pDepthStencilResolveAttachment->layout, 514 }; 515 subpass->depth_resolve_mode = ds_resolve->depthResolveMode; 516 subpass->stencil_resolve_mode = ds_resolve->stencilResolveMode; 517 } 518 } 519 520 for (uint32_t i = 0; i < pCreateInfo->dependencyCount; i++) 521 anv_render_pass_add_subpass_dep(pass, &pCreateInfo->pDependencies[i]); 522 523 vk_foreach_struct(ext, pCreateInfo->pNext) { 524 switch (ext->sType) { 525 default: 526 anv_debug_ignored_stype(ext->sType); 527 } 528 } 529 530 anv_render_pass_compile(pass); 531 532 *pRenderPass = anv_render_pass_to_handle(pass); 533 534 return VK_SUCCESS; 535} 536 537void anv_DestroyRenderPass( 538 VkDevice _device, 539 VkRenderPass _pass, 540 const VkAllocationCallbacks* pAllocator) 541{ 542 ANV_FROM_HANDLE(anv_device, device, _device); 543 ANV_FROM_HANDLE(anv_render_pass, pass, _pass); 544 545 vk_free2(&device->alloc, pAllocator, pass); 546} 547 548void anv_GetRenderAreaGranularity( 549 VkDevice device, 550 VkRenderPass renderPass, 551 VkExtent2D* pGranularity) 552{ 553 ANV_FROM_HANDLE(anv_render_pass, pass, renderPass); 554 555 /* This granularity satisfies HiZ fast clear alignment requirements 556 * for all sample counts. 557 */ 558 for (unsigned i = 0; i < pass->subpass_count; ++i) { 559 if (pass->subpasses[i].depth_stencil_attachment) { 560 *pGranularity = (VkExtent2D) { .width = 8, .height = 4 }; 561 return; 562 } 563 } 564 565 *pGranularity = (VkExtent2D) { 1, 1 }; 566} 567