1/* 2 * Copyright © 2021 Collabora Ltd. 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 21 * DEALINGS IN THE SOFTWARE. 22 */ 23 24#include "nir/nir_builder.h" 25#include "pan_blitter.h" 26#include "pan_encoder.h" 27#include "pan_shader.h" 28 29#include "panvk_private.h" 30#include "panvk_vX_meta.h" 31 32#include "vk_format.h" 33 34static mali_ptr 35panvk_meta_clear_color_attachment_shader(struct panfrost_device *pdev, 36 struct pan_pool *bin_pool, 37 unsigned rt, 38 enum glsl_base_type base_type, 39 struct pan_shader_info *shader_info) 40{ 41 nir_builder b = nir_builder_init_simple_shader(MESA_SHADER_FRAGMENT, 42 GENX(pan_shader_get_compiler_options)(), 43 "panvk_meta_clear_rt%d_attachment(base_type=%d)", 44 rt, base_type); 45 46 b.shader->info.internal = true; 47 b.shader->info.num_ubos = 1; 48 49 const struct glsl_type *out_type = glsl_vector_type(base_type, 4); 50 nir_variable *out = 51 nir_variable_create(b.shader, nir_var_shader_out, out_type, "out"); 52 out->data.location = FRAG_RESULT_DATA0 + rt; 53 54 nir_ssa_def *clear_values = nir_load_ubo(&b, 4, 32, nir_imm_int(&b, 0), 55 nir_imm_int(&b, 0), 56 .align_mul = 4, 57 .align_offset = 0, 58 .range_base = 0, 59 .range = ~0); 60 nir_store_var(&b, out, clear_values, 0xff); 61 62 struct panfrost_compile_inputs inputs = { 63 .gpu_id = pdev->gpu_id, 64 .is_blit = true, 65 }; 66 67 struct util_dynarray binary; 68 69 util_dynarray_init(&binary, NULL); 70 GENX(pan_shader_compile)(b.shader, &inputs, &binary, shader_info); 71 72 /* Make sure UBO words have been upgraded to push constants */ 73 assert(shader_info->ubo_mask == 0); 74 75 mali_ptr shader = 76 pan_pool_upload_aligned(bin_pool, binary.data, binary.size, 77 PAN_ARCH >= 6 ? 128 : 64); 78 79 util_dynarray_fini(&binary); 80 ralloc_free(b.shader); 81 82 return shader; 83} 84 85static mali_ptr 86panvk_meta_clear_zs_attachment_shader(struct panfrost_device *pdev, 87 struct pan_pool *bin_pool, 88 bool clear_z, bool clear_s, 89 enum glsl_base_type base_type, 90 struct pan_shader_info *shader_info) 91{ 92 nir_builder b = nir_builder_init_simple_shader(MESA_SHADER_FRAGMENT, 93 GENX(pan_shader_get_compiler_options)(), 94 "panvk_meta_clear_%s%s_attachment()", 95 clear_z ? "z" : "", clear_s ? "s" : ""); 96 97 b.shader->info.internal = true; 98 b.shader->info.num_ubos = 1; 99 100 unsigned drv_loc = 0; 101 nir_variable *z_out = 102 clear_z ? 103 nir_variable_create(b.shader, nir_var_shader_out, glsl_float_type(), "depth") : 104 NULL; 105 nir_variable *s_out = 106 clear_s ? 107 nir_variable_create(b.shader, nir_var_shader_out, glsl_float_type(), "stencil") : 108 NULL; 109 110 nir_ssa_def *clear_values = nir_load_ubo(&b, 2, 32, nir_imm_int(&b, 0), 111 nir_imm_int(&b, 0), 112 .align_mul = 4, 113 .align_offset = 0, 114 .range_base = 0, 115 .range = ~0); 116 117 if (z_out) { 118 z_out->data.location = FRAG_RESULT_DEPTH; 119 z_out->data.driver_location = drv_loc++; 120 nir_store_var(&b, z_out, nir_channel(&b, clear_values, 0), 1); 121 } 122 123 if (s_out) { 124 s_out->data.location = FRAG_RESULT_STENCIL; 125 s_out->data.driver_location = drv_loc++; 126 nir_store_var(&b, s_out, nir_channel(&b, clear_values, 1), 1); 127 } 128 129 struct panfrost_compile_inputs inputs = { 130 .gpu_id = pdev->gpu_id, 131 .is_blit = true, 132 }; 133 134 struct util_dynarray binary; 135 136 util_dynarray_init(&binary, NULL); 137 GENX(pan_shader_compile)(b.shader, &inputs, &binary, shader_info); 138 139 /* Make sure UBO words have been upgraded to push constants */ 140 assert(shader_info->ubo_mask == 0); 141 142 mali_ptr shader = 143 pan_pool_upload_aligned(bin_pool, binary.data, binary.size, 144 PAN_ARCH >= 6 ? 128 : 64); 145 146 util_dynarray_fini(&binary); 147 ralloc_free(b.shader); 148 149 return shader; 150} 151 152static mali_ptr 153panvk_meta_clear_attachments_emit_rsd(struct panfrost_device *pdev, 154 struct pan_pool *desc_pool, 155 enum pipe_format format, 156 unsigned rt, bool z, bool s, 157 struct pan_shader_info *shader_info, 158 mali_ptr shader) 159{ 160 struct panfrost_ptr rsd_ptr = 161 pan_pool_alloc_desc_aggregate(desc_pool, 162 PAN_DESC(RENDERER_STATE), 163 PAN_DESC_ARRAY(rt + 1, BLEND)); 164 bool zs = z | s; 165 166 pan_pack(rsd_ptr.cpu, RENDERER_STATE, cfg) { 167 pan_shader_prepare_rsd(shader_info, shader, &cfg); 168 cfg.properties.depth_source = 169 z ? 170 MALI_DEPTH_SOURCE_SHADER : 171 MALI_DEPTH_SOURCE_FIXED_FUNCTION; 172 cfg.multisample_misc.depth_write_mask = z; 173 cfg.multisample_misc.sample_mask = UINT16_MAX; 174 cfg.multisample_misc.depth_function = MALI_FUNC_ALWAYS; 175 cfg.stencil_mask_misc.stencil_enable = s; 176 cfg.properties.stencil_from_shader = s; 177 cfg.stencil_mask_misc.stencil_mask_front = 0xFF; 178 cfg.stencil_mask_misc.stencil_mask_back = 0xFF; 179 cfg.stencil_front.compare_function = MALI_FUNC_ALWAYS; 180 cfg.stencil_front.stencil_fail = MALI_STENCIL_OP_REPLACE; 181 cfg.stencil_front.depth_fail = MALI_STENCIL_OP_REPLACE; 182 cfg.stencil_front.depth_pass = MALI_STENCIL_OP_REPLACE; 183 cfg.stencil_front.mask = 0xFF; 184 cfg.stencil_back = cfg.stencil_front; 185 186#if PAN_ARCH >= 6 187 cfg.properties.allow_forward_pixel_to_be_killed = PAN_ARCH >= 7 || !zs; 188 cfg.properties.allow_forward_pixel_to_kill = !zs; 189 if (zs) { 190 cfg.properties.zs_update_operation = 191 MALI_PIXEL_KILL_FORCE_LATE; 192 cfg.properties.pixel_kill_operation = 193 MALI_PIXEL_KILL_FORCE_LATE; 194 } else { 195 cfg.properties.zs_update_operation = 196 MALI_PIXEL_KILL_STRONG_EARLY; 197 cfg.properties.pixel_kill_operation = 198 MALI_PIXEL_KILL_FORCE_EARLY; 199 } 200#else 201 cfg.properties.shader_reads_tilebuffer = false; 202 cfg.properties.work_register_count = shader_info->work_reg_count; 203 cfg.properties.force_early_z = !zs; 204 cfg.stencil_mask_misc.alpha_test_compare_function = MALI_FUNC_ALWAYS; 205#endif 206 } 207 208 void *bd = rsd_ptr.cpu + pan_size(RENDERER_STATE); 209 210 /* Disable all RTs except the one we're interested in. */ 211 for (unsigned i = 0; i < rt; i++) { 212 pan_pack(bd, BLEND, cfg) { 213 cfg.enable = false; 214#if PAN_ARCH >= 6 215 cfg.internal.mode = MALI_BLEND_MODE_OFF; 216#endif 217 } 218 219 bd += pan_size(BLEND); 220 } 221 222 if (zs) { 223 /* We write the depth/stencil, disable blending on RT0. */ 224 pan_pack(bd, BLEND, cfg) { 225 cfg.enable = false; 226#if PAN_ARCH >= 6 227 cfg.internal.mode = MALI_BLEND_MODE_OFF; 228#endif 229 } 230 } else { 231 pan_pack(bd, BLEND, cfg) { 232 cfg.round_to_fb_precision = true; 233 cfg.load_destination = false; 234 cfg.equation.rgb.a = MALI_BLEND_OPERAND_A_SRC; 235 cfg.equation.rgb.b = MALI_BLEND_OPERAND_B_SRC; 236 cfg.equation.rgb.c = MALI_BLEND_OPERAND_C_ZERO; 237 cfg.equation.alpha.a = MALI_BLEND_OPERAND_A_SRC; 238 cfg.equation.alpha.b = MALI_BLEND_OPERAND_B_SRC; 239 cfg.equation.alpha.c = MALI_BLEND_OPERAND_C_ZERO; 240#if PAN_ARCH >= 6 241 cfg.internal.mode = MALI_BLEND_MODE_OPAQUE; 242 cfg.equation.color_mask = 0xf; 243 cfg.internal.fixed_function.num_comps = 4; 244 cfg.internal.fixed_function.conversion.memory_format = 245 panfrost_format_to_bifrost_blend(pdev, format, false); 246 cfg.internal.fixed_function.conversion.register_format = 247 shader_info->bifrost.blend[rt].format; 248#else 249 cfg.equation.color_mask = 250 (1 << util_format_get_nr_components(format)) - 1; 251#endif 252 } 253 } 254 255 return rsd_ptr.gpu; 256} 257 258static mali_ptr 259panvk_meta_clear_attachment_emit_push_constants(struct panfrost_device *pdev, 260 const struct panfrost_ubo_push *pushmap, 261 struct pan_pool *pool, 262 const VkClearValue *clear_value) 263{ 264 assert(pushmap->count <= (sizeof(*clear_value) / 4)); 265 266 uint32_t *in = (uint32_t *)clear_value; 267 uint32_t pushvals[sizeof(*clear_value) / 4]; 268 269 for (unsigned i = 0; i < pushmap->count; i++) { 270 assert(i < ARRAY_SIZE(pushvals)); 271 assert(pushmap->words[i].ubo == 0); 272 assert(pushmap->words[i].offset < sizeof(*clear_value)); 273 pushvals[i] = in[pushmap->words[i].offset / 4]; 274 } 275 276 return pan_pool_upload_aligned(pool, pushvals, sizeof(pushvals), 16); 277} 278 279static mali_ptr 280panvk_meta_clear_attachment_emit_ubo(struct panfrost_device *pdev, 281 const struct panfrost_ubo_push *pushmap, 282 struct pan_pool *pool, 283 const VkClearValue *clear_value) 284{ 285 struct panfrost_ptr ubo = pan_pool_alloc_desc(pool, UNIFORM_BUFFER); 286 287 pan_pack(ubo.cpu, UNIFORM_BUFFER, cfg) { 288 cfg.entries = DIV_ROUND_UP(sizeof(*clear_value), 16); 289 cfg.pointer = pan_pool_upload_aligned(pool, clear_value, sizeof(*clear_value), 16); 290 } 291 292 return ubo.gpu; 293} 294 295static void 296panvk_meta_clear_attachment_emit_dcd(struct pan_pool *pool, 297 mali_ptr coords, 298 mali_ptr ubo, mali_ptr push_constants, 299 mali_ptr vpd, mali_ptr tsd, mali_ptr rsd, 300 void *out) 301{ 302 pan_pack(out, DRAW, cfg) { 303 cfg.four_components_per_vertex = true; 304 cfg.draw_descriptor_is_64b = true; 305 cfg.thread_storage = tsd; 306 cfg.state = rsd; 307 cfg.uniform_buffers = ubo; 308 cfg.push_uniforms = push_constants; 309 cfg.position = coords; 310 cfg.viewport = vpd; 311 } 312} 313 314static struct panfrost_ptr 315panvk_meta_clear_attachment_emit_tiler_job(struct pan_pool *desc_pool, 316 struct pan_scoreboard *scoreboard, 317 mali_ptr coords, 318 mali_ptr ubo, mali_ptr push_constants, 319 mali_ptr vpd, mali_ptr rsd, 320 mali_ptr tsd, mali_ptr tiler) 321{ 322 struct panfrost_ptr job = 323 pan_pool_alloc_desc(desc_pool, TILER_JOB); 324 325 panvk_meta_clear_attachment_emit_dcd(desc_pool, 326 coords, 327 ubo, push_constants, 328 vpd, tsd, rsd, 329 pan_section_ptr(job.cpu, TILER_JOB, DRAW)); 330 331 pan_section_pack(job.cpu, TILER_JOB, PRIMITIVE, cfg) { 332 cfg.draw_mode = MALI_DRAW_MODE_TRIANGLE_STRIP; 333 cfg.index_count = 4; 334 cfg.job_task_split = 6; 335 } 336 337 pan_section_pack(job.cpu, TILER_JOB, PRIMITIVE_SIZE, cfg) { 338 cfg.constant = 1.0f; 339 } 340 341 void *invoc = pan_section_ptr(job.cpu, 342 TILER_JOB, 343 INVOCATION); 344 panfrost_pack_work_groups_compute(invoc, 1, 4, 345 1, 1, 1, 1, true, false); 346 347#if PAN_ARCH >= 6 348 pan_section_pack(job.cpu, TILER_JOB, PADDING, cfg); 349 pan_section_pack(job.cpu, TILER_JOB, TILER, cfg) { 350 cfg.address = tiler; 351 } 352#endif 353 354 panfrost_add_job(desc_pool, scoreboard, MALI_JOB_TYPE_TILER, 355 false, false, 0, 0, &job, false); 356 return job; 357} 358 359static enum glsl_base_type 360panvk_meta_get_format_type(enum pipe_format format) 361{ 362 const struct util_format_description *desc = util_format_description(format); 363 int i; 364 365 i = util_format_get_first_non_void_channel(format); 366 assert(i >= 0); 367 368 if (desc->channel[i].normalized) 369 return GLSL_TYPE_FLOAT; 370 371 switch(desc->channel[i].type) { 372 373 case UTIL_FORMAT_TYPE_UNSIGNED: 374 return GLSL_TYPE_UINT; 375 376 case UTIL_FORMAT_TYPE_SIGNED: 377 return GLSL_TYPE_INT; 378 379 case UTIL_FORMAT_TYPE_FLOAT: 380 return GLSL_TYPE_FLOAT; 381 382 default: 383 unreachable("Unhandled format"); 384 return GLSL_TYPE_FLOAT; 385 } 386} 387 388static void 389panvk_meta_clear_attachment(struct panvk_cmd_buffer *cmdbuf, 390 unsigned attachment, unsigned rt, 391 VkImageAspectFlags mask, 392 const VkClearValue *clear_value, 393 const VkClearRect *clear_rect) 394{ 395 struct panvk_physical_device *dev = cmdbuf->device->physical_device; 396 struct panfrost_device *pdev = &dev->pdev; 397 struct panvk_meta *meta = &cmdbuf->device->physical_device->meta; 398 struct panvk_batch *batch = cmdbuf->state.batch; 399 const struct panvk_render_pass *pass = cmdbuf->state.pass; 400 const struct panvk_render_pass_attachment *att = &pass->attachments[attachment]; 401 unsigned minx = MAX2(clear_rect->rect.offset.x, 0); 402 unsigned miny = MAX2(clear_rect->rect.offset.y, 0); 403 unsigned maxx = MAX2(clear_rect->rect.offset.x + clear_rect->rect.extent.width - 1, 0); 404 unsigned maxy = MAX2(clear_rect->rect.offset.y + clear_rect->rect.extent.height - 1, 0); 405 406 panvk_per_arch(cmd_alloc_fb_desc)(cmdbuf); 407 panvk_per_arch(cmd_alloc_tls_desc)(cmdbuf, true); 408 panvk_per_arch(cmd_prepare_tiler_context)(cmdbuf); 409 410 mali_ptr vpd = 411 panvk_per_arch(meta_emit_viewport)(&cmdbuf->desc_pool.base, 412 minx, miny, maxx, maxy); 413 414 float rect[] = { 415 minx, miny, 0.0, 1.0, 416 maxx + 1, miny, 0.0, 1.0, 417 minx, maxy + 1, 0.0, 1.0, 418 maxx + 1, maxy + 1, 0.0, 1.0, 419 }; 420 mali_ptr coordinates = pan_pool_upload_aligned(&cmdbuf->desc_pool.base, 421 rect, sizeof(rect), 64); 422 423 enum glsl_base_type base_type = panvk_meta_get_format_type(att->format); 424 struct pan_shader_info *shader_info; 425 bool clear_z = false, clear_s = false; 426 mali_ptr shader; 427 428 switch (mask) { 429 case VK_IMAGE_ASPECT_COLOR_BIT: 430 shader = meta->clear_attachment.color[rt][base_type].shader; 431 shader_info = &meta->clear_attachment.color[rt][base_type].shader_info; 432 break; 433 case VK_IMAGE_ASPECT_DEPTH_BIT: 434 shader = meta->clear_attachment.z.shader; 435 shader_info = &meta->clear_attachment.z.shader_info; 436 clear_z = true; 437 break; 438 case VK_IMAGE_ASPECT_STENCIL_BIT: 439 shader = meta->clear_attachment.s.shader; 440 shader_info = &meta->clear_attachment.s.shader_info; 441 clear_s = true; 442 break; 443 case VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT: 444 shader = meta->clear_attachment.zs.shader; 445 shader_info = &meta->clear_attachment.zs.shader_info; 446 clear_s = clear_z = true; 447 break; 448 default: 449 unreachable("Invalid aspect mask\n"); 450 } 451 452 mali_ptr rsd = 453 panvk_meta_clear_attachments_emit_rsd(pdev, 454 &cmdbuf->desc_pool.base, 455 att->format, rt, clear_z, clear_s, 456 shader_info, 457 shader); 458 459 mali_ptr pushconsts = 460 panvk_meta_clear_attachment_emit_push_constants(pdev, &shader_info->push, 461 &cmdbuf->desc_pool.base, 462 clear_value); 463 mali_ptr ubo = 464 panvk_meta_clear_attachment_emit_ubo(pdev, &shader_info->push, 465 &cmdbuf->desc_pool.base, 466 clear_value); 467 468 mali_ptr tsd = PAN_ARCH >= 6 ? batch->tls.gpu : batch->fb.desc.gpu; 469 mali_ptr tiler = PAN_ARCH >= 6 ? batch->tiler.descs.gpu : 0; 470 471 struct panfrost_ptr job; 472 473 job = panvk_meta_clear_attachment_emit_tiler_job(&cmdbuf->desc_pool.base, 474 &batch->scoreboard, 475 coordinates, 476 ubo, pushconsts, 477 vpd, rsd, tsd, tiler); 478 479 util_dynarray_append(&batch->jobs, void *, job.cpu); 480} 481 482static void 483panvk_meta_clear_color_img(struct panvk_cmd_buffer *cmdbuf, 484 struct panvk_image *img, 485 const VkClearColorValue *color, 486 const VkImageSubresourceRange *range) 487{ 488 struct pan_fb_info *fbinfo = &cmdbuf->state.fb.info; 489 struct pan_image_view view = { 490 .format = img->pimage.layout.format, 491 .dim = MALI_TEXTURE_DIMENSION_2D, 492 .image = &img->pimage, 493 .nr_samples = img->pimage.layout.nr_samples, 494 .swizzle = { PIPE_SWIZZLE_X, PIPE_SWIZZLE_Y, PIPE_SWIZZLE_Z, PIPE_SWIZZLE_W }, 495 }; 496 497 cmdbuf->state.fb.crc_valid[0] = false; 498 *fbinfo = (struct pan_fb_info){ 499 .nr_samples = img->pimage.layout.nr_samples, 500 .rt_count = 1, 501 .rts[0].view = &view, 502 .rts[0].clear = true, 503 .rts[0].crc_valid = &cmdbuf->state.fb.crc_valid[0], 504 }; 505 506 uint32_t clearval[4]; 507 pan_pack_color(clearval, (union pipe_color_union *)color, 508 img->pimage.layout.format, false); 509 memcpy(fbinfo->rts[0].clear_value, clearval, sizeof(fbinfo->rts[0].clear_value)); 510 511 for (unsigned level = range->baseMipLevel; 512 level < range->baseMipLevel + range->levelCount; level++) { 513 view.first_level = view.last_level = level; 514 fbinfo->width = u_minify(img->pimage.layout.width, level); 515 fbinfo->height = u_minify(img->pimage.layout.height, level); 516 fbinfo->extent.maxx = fbinfo->width - 1; 517 fbinfo->extent.maxy = fbinfo->height - 1; 518 519 for (unsigned layer = range->baseArrayLayer; 520 layer < range->baseArrayLayer + range->layerCount; layer++) { 521 view.first_layer = view.last_layer = layer; 522 panvk_cmd_open_batch(cmdbuf); 523 panvk_per_arch(cmd_alloc_fb_desc)(cmdbuf); 524 panvk_per_arch(cmd_close_batch)(cmdbuf); 525 } 526 } 527} 528 529void 530panvk_per_arch(CmdClearColorImage)(VkCommandBuffer commandBuffer, 531 VkImage image, 532 VkImageLayout imageLayout, 533 const VkClearColorValue *pColor, 534 uint32_t rangeCount, 535 const VkImageSubresourceRange *pRanges) 536{ 537 VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer); 538 VK_FROM_HANDLE(panvk_image, img, image); 539 540 panvk_per_arch(cmd_close_batch)(cmdbuf); 541 542 for (unsigned i = 0; i < rangeCount; i++) 543 panvk_meta_clear_color_img(cmdbuf, img, pColor, &pRanges[i]); 544} 545 546static void 547panvk_meta_clear_zs_img(struct panvk_cmd_buffer *cmdbuf, 548 struct panvk_image *img, 549 const VkClearDepthStencilValue *value, 550 const VkImageSubresourceRange *range) 551{ 552 struct pan_fb_info *fbinfo = &cmdbuf->state.fb.info; 553 struct pan_image_view view = { 554 .format = img->pimage.layout.format, 555 .dim = MALI_TEXTURE_DIMENSION_2D, 556 .image = &img->pimage, 557 .nr_samples = img->pimage.layout.nr_samples, 558 .swizzle = { PIPE_SWIZZLE_X, PIPE_SWIZZLE_Y, PIPE_SWIZZLE_Z, PIPE_SWIZZLE_W }, 559 }; 560 561 cmdbuf->state.fb.crc_valid[0] = false; 562 *fbinfo = (struct pan_fb_info){ 563 .nr_samples = img->pimage.layout.nr_samples, 564 .rt_count = 1, 565 }; 566 567 const struct util_format_description *fdesc = 568 util_format_description(view.format); 569 570 if (util_format_has_depth(fdesc)) { 571 fbinfo->zs.view.zs = &view; 572 fbinfo->zs.clear.z = range->aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT; 573 if (util_format_has_stencil(fdesc)) { 574 fbinfo->zs.clear.s = range->aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT; 575 fbinfo->zs.preload.z = !fbinfo->zs.clear.z && fbinfo->zs.clear.s; 576 fbinfo->zs.preload.s = !fbinfo->zs.clear.s && fbinfo->zs.clear.z; 577 } 578 } else { 579 fbinfo->zs.view.s = &view; 580 fbinfo->zs.clear.s = range->aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT; 581 } 582 583 if (fbinfo->zs.clear.z) 584 fbinfo->zs.clear_value.depth = value->depth; 585 586 if (fbinfo->zs.clear.s) 587 fbinfo->zs.clear_value.stencil = value->stencil; 588 589 for (unsigned level = range->baseMipLevel; 590 level < range->baseMipLevel + range->levelCount; level++) { 591 view.first_level = view.last_level = level; 592 fbinfo->width = u_minify(img->pimage.layout.width, level); 593 fbinfo->height = u_minify(img->pimage.layout.height, level); 594 fbinfo->extent.maxx = fbinfo->width - 1; 595 fbinfo->extent.maxy = fbinfo->height - 1; 596 597 for (unsigned layer = range->baseArrayLayer; 598 layer < range->baseArrayLayer + range->layerCount; layer++) { 599 view.first_layer = view.last_layer = layer; 600 panvk_cmd_open_batch(cmdbuf); 601 panvk_per_arch(cmd_alloc_fb_desc)(cmdbuf); 602 panvk_per_arch(cmd_close_batch)(cmdbuf); 603 } 604 } 605} 606 607void 608panvk_per_arch(CmdClearDepthStencilImage)(VkCommandBuffer commandBuffer, 609 VkImage image, 610 VkImageLayout imageLayout, 611 const VkClearDepthStencilValue *pDepthStencil, 612 uint32_t rangeCount, 613 const VkImageSubresourceRange *pRanges) 614{ 615 VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer); 616 VK_FROM_HANDLE(panvk_image, img, image); 617 618 panvk_per_arch(cmd_close_batch)(cmdbuf); 619 620 for (unsigned i = 0; i < rangeCount; i++) 621 panvk_meta_clear_zs_img(cmdbuf, img, pDepthStencil, &pRanges[i]); 622} 623 624void 625panvk_per_arch(CmdClearAttachments)(VkCommandBuffer commandBuffer, 626 uint32_t attachmentCount, 627 const VkClearAttachment *pAttachments, 628 uint32_t rectCount, 629 const VkClearRect *pRects) 630{ 631 VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer); 632 const struct panvk_subpass *subpass = cmdbuf->state.subpass; 633 634 for (unsigned i = 0; i < attachmentCount; i++) { 635 for (unsigned j = 0; j < rectCount; j++) { 636 637 uint32_t attachment, rt = 0; 638 if (pAttachments[i].aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) { 639 rt = pAttachments[i].colorAttachment; 640 attachment = subpass->color_attachments[rt].idx; 641 } else { 642 attachment = subpass->zs_attachment.idx; 643 } 644 645 if (attachment == VK_ATTACHMENT_UNUSED) 646 continue; 647 648 panvk_meta_clear_attachment(cmdbuf, attachment, rt, 649 pAttachments[i].aspectMask, 650 &pAttachments[i].clearValue, 651 &pRects[j]); 652 } 653 } 654} 655 656static void 657panvk_meta_clear_attachment_init(struct panvk_physical_device *dev) 658{ 659 for (unsigned rt = 0; rt < MAX_RTS; rt++) { 660 dev->meta.clear_attachment.color[rt][GLSL_TYPE_UINT].shader = 661 panvk_meta_clear_color_attachment_shader( 662 &dev->pdev, 663 &dev->meta.bin_pool.base, 664 rt, 665 GLSL_TYPE_UINT, 666 &dev->meta.clear_attachment.color[rt][GLSL_TYPE_UINT].shader_info); 667 668 dev->meta.clear_attachment.color[rt][GLSL_TYPE_INT].shader = 669 panvk_meta_clear_color_attachment_shader( 670 &dev->pdev, 671 &dev->meta.bin_pool.base, 672 rt, 673 GLSL_TYPE_INT, 674 &dev->meta.clear_attachment.color[rt][GLSL_TYPE_INT].shader_info); 675 676 dev->meta.clear_attachment.color[rt][GLSL_TYPE_FLOAT].shader = 677 panvk_meta_clear_color_attachment_shader( 678 &dev->pdev, 679 &dev->meta.bin_pool.base, 680 rt, 681 GLSL_TYPE_FLOAT, 682 &dev->meta.clear_attachment.color[rt][GLSL_TYPE_FLOAT].shader_info); 683 } 684 685 dev->meta.clear_attachment.z.shader = 686 panvk_meta_clear_zs_attachment_shader( 687 &dev->pdev, 688 &dev->meta.bin_pool.base, 689 true, false, 690 GLSL_TYPE_FLOAT, 691 &dev->meta.clear_attachment.z.shader_info); 692 dev->meta.clear_attachment.s.shader = 693 panvk_meta_clear_zs_attachment_shader( 694 &dev->pdev, 695 &dev->meta.bin_pool.base, 696 false, true, 697 GLSL_TYPE_FLOAT, 698 &dev->meta.clear_attachment.s.shader_info); 699 dev->meta.clear_attachment.zs.shader = 700 panvk_meta_clear_zs_attachment_shader( 701 &dev->pdev, 702 &dev->meta.bin_pool.base, 703 true, true, 704 GLSL_TYPE_FLOAT, 705 &dev->meta.clear_attachment.zs.shader_info); 706} 707 708void 709panvk_per_arch(meta_clear_init)(struct panvk_physical_device *dev) 710{ 711 panvk_meta_clear_attachment_init(dev); 712} 713