radv_meta_clear.c revision 01e04c3f
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 "radv_debug.h" 25#include "radv_meta.h" 26#include "radv_private.h" 27#include "nir/nir_builder.h" 28 29#include "util/format_rgb9e5.h" 30#include "vk_format.h" 31 32enum { 33 DEPTH_CLEAR_SLOW, 34 DEPTH_CLEAR_FAST_EXPCLEAR, 35 DEPTH_CLEAR_FAST_NO_EXPCLEAR 36}; 37 38static void 39build_color_shaders(struct nir_shader **out_vs, 40 struct nir_shader **out_fs, 41 uint32_t frag_output) 42{ 43 nir_builder vs_b; 44 nir_builder fs_b; 45 46 nir_builder_init_simple_shader(&vs_b, NULL, MESA_SHADER_VERTEX, NULL); 47 nir_builder_init_simple_shader(&fs_b, NULL, MESA_SHADER_FRAGMENT, NULL); 48 49 vs_b.shader->info.name = ralloc_strdup(vs_b.shader, "meta_clear_color_vs"); 50 fs_b.shader->info.name = ralloc_strdup(fs_b.shader, "meta_clear_color_fs"); 51 52 const struct glsl_type *position_type = glsl_vec4_type(); 53 const struct glsl_type *color_type = glsl_vec4_type(); 54 55 nir_variable *vs_out_pos = 56 nir_variable_create(vs_b.shader, nir_var_shader_out, position_type, 57 "gl_Position"); 58 vs_out_pos->data.location = VARYING_SLOT_POS; 59 60 nir_intrinsic_instr *in_color_load = nir_intrinsic_instr_create(fs_b.shader, nir_intrinsic_load_push_constant); 61 nir_intrinsic_set_base(in_color_load, 0); 62 nir_intrinsic_set_range(in_color_load, 16); 63 in_color_load->src[0] = nir_src_for_ssa(nir_imm_int(&fs_b, 0)); 64 in_color_load->num_components = 4; 65 nir_ssa_dest_init(&in_color_load->instr, &in_color_load->dest, 4, 32, "clear color"); 66 nir_builder_instr_insert(&fs_b, &in_color_load->instr); 67 68 nir_variable *fs_out_color = 69 nir_variable_create(fs_b.shader, nir_var_shader_out, color_type, 70 "f_color"); 71 fs_out_color->data.location = FRAG_RESULT_DATA0 + frag_output; 72 73 nir_store_var(&fs_b, fs_out_color, &in_color_load->dest.ssa, 0xf); 74 75 nir_ssa_def *outvec = radv_meta_gen_rect_vertices(&vs_b); 76 nir_store_var(&vs_b, vs_out_pos, outvec, 0xf); 77 78 const struct glsl_type *layer_type = glsl_int_type(); 79 nir_variable *vs_out_layer = 80 nir_variable_create(vs_b.shader, nir_var_shader_out, layer_type, 81 "v_layer"); 82 vs_out_layer->data.location = VARYING_SLOT_LAYER; 83 vs_out_layer->data.interpolation = INTERP_MODE_FLAT; 84 nir_ssa_def *inst_id = nir_load_system_value(&vs_b, nir_intrinsic_load_instance_id, 0); 85 nir_ssa_def *base_instance = nir_load_system_value(&vs_b, nir_intrinsic_load_base_instance, 0); 86 87 nir_ssa_def *layer_id = nir_iadd(&vs_b, inst_id, base_instance); 88 nir_store_var(&vs_b, vs_out_layer, layer_id, 0x1); 89 90 *out_vs = vs_b.shader; 91 *out_fs = fs_b.shader; 92} 93 94static VkResult 95create_pipeline(struct radv_device *device, 96 struct radv_render_pass *render_pass, 97 uint32_t samples, 98 struct nir_shader *vs_nir, 99 struct nir_shader *fs_nir, 100 const VkPipelineVertexInputStateCreateInfo *vi_state, 101 const VkPipelineDepthStencilStateCreateInfo *ds_state, 102 const VkPipelineColorBlendStateCreateInfo *cb_state, 103 const VkPipelineLayout layout, 104 const struct radv_graphics_pipeline_create_info *extra, 105 const VkAllocationCallbacks *alloc, 106 VkPipeline *pipeline) 107{ 108 VkDevice device_h = radv_device_to_handle(device); 109 VkResult result; 110 111 struct radv_shader_module vs_m = { .nir = vs_nir }; 112 struct radv_shader_module fs_m = { .nir = fs_nir }; 113 114 result = radv_graphics_pipeline_create(device_h, 115 radv_pipeline_cache_to_handle(&device->meta_state.cache), 116 &(VkGraphicsPipelineCreateInfo) { 117 .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, 118 .stageCount = fs_nir ? 2 : 1, 119 .pStages = (VkPipelineShaderStageCreateInfo[]) { 120 { 121 .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, 122 .stage = VK_SHADER_STAGE_VERTEX_BIT, 123 .module = radv_shader_module_to_handle(&vs_m), 124 .pName = "main", 125 }, 126 { 127 .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, 128 .stage = VK_SHADER_STAGE_FRAGMENT_BIT, 129 .module = radv_shader_module_to_handle(&fs_m), 130 .pName = "main", 131 }, 132 }, 133 .pVertexInputState = vi_state, 134 .pInputAssemblyState = &(VkPipelineInputAssemblyStateCreateInfo) { 135 .sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, 136 .topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, 137 .primitiveRestartEnable = false, 138 }, 139 .pViewportState = &(VkPipelineViewportStateCreateInfo) { 140 .sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, 141 .viewportCount = 1, 142 .scissorCount = 1, 143 }, 144 .pRasterizationState = &(VkPipelineRasterizationStateCreateInfo) { 145 .sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, 146 .rasterizerDiscardEnable = false, 147 .polygonMode = VK_POLYGON_MODE_FILL, 148 .cullMode = VK_CULL_MODE_NONE, 149 .frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE, 150 .depthBiasEnable = false, 151 }, 152 .pMultisampleState = &(VkPipelineMultisampleStateCreateInfo) { 153 .sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, 154 .rasterizationSamples = samples, 155 .sampleShadingEnable = false, 156 .pSampleMask = NULL, 157 .alphaToCoverageEnable = false, 158 .alphaToOneEnable = false, 159 }, 160 .pDepthStencilState = ds_state, 161 .pColorBlendState = cb_state, 162 .pDynamicState = &(VkPipelineDynamicStateCreateInfo) { 163 /* The meta clear pipeline declares all state as dynamic. 164 * As a consequence, vkCmdBindPipeline writes no dynamic state 165 * to the cmd buffer. Therefore, at the end of the meta clear, 166 * we need only restore dynamic state was vkCmdSet. 167 */ 168 .sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, 169 .dynamicStateCount = 8, 170 .pDynamicStates = (VkDynamicState[]) { 171 /* Everything except stencil write mask */ 172 VK_DYNAMIC_STATE_VIEWPORT, 173 VK_DYNAMIC_STATE_SCISSOR, 174 VK_DYNAMIC_STATE_LINE_WIDTH, 175 VK_DYNAMIC_STATE_DEPTH_BIAS, 176 VK_DYNAMIC_STATE_BLEND_CONSTANTS, 177 VK_DYNAMIC_STATE_DEPTH_BOUNDS, 178 VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK, 179 VK_DYNAMIC_STATE_STENCIL_REFERENCE, 180 }, 181 }, 182 .layout = layout, 183 .flags = 0, 184 .renderPass = radv_render_pass_to_handle(render_pass), 185 .subpass = 0, 186 }, 187 extra, 188 alloc, 189 pipeline); 190 191 ralloc_free(vs_nir); 192 ralloc_free(fs_nir); 193 194 return result; 195} 196 197static VkResult 198create_color_renderpass(struct radv_device *device, 199 VkFormat vk_format, 200 uint32_t samples, 201 VkRenderPass *pass) 202{ 203 mtx_lock(&device->meta_state.mtx); 204 if (*pass) { 205 mtx_unlock (&device->meta_state.mtx); 206 return VK_SUCCESS; 207 } 208 209 VkResult result = radv_CreateRenderPass(radv_device_to_handle(device), 210 &(VkRenderPassCreateInfo) { 211 .sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, 212 .attachmentCount = 1, 213 .pAttachments = &(VkAttachmentDescription) { 214 .format = vk_format, 215 .samples = samples, 216 .loadOp = VK_ATTACHMENT_LOAD_OP_LOAD, 217 .storeOp = VK_ATTACHMENT_STORE_OP_STORE, 218 .initialLayout = VK_IMAGE_LAYOUT_GENERAL, 219 .finalLayout = VK_IMAGE_LAYOUT_GENERAL, 220 }, 221 .subpassCount = 1, 222 .pSubpasses = &(VkSubpassDescription) { 223 .pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS, 224 .inputAttachmentCount = 0, 225 .colorAttachmentCount = 1, 226 .pColorAttachments = &(VkAttachmentReference) { 227 .attachment = 0, 228 .layout = VK_IMAGE_LAYOUT_GENERAL, 229 }, 230 .pResolveAttachments = NULL, 231 .pDepthStencilAttachment = &(VkAttachmentReference) { 232 .attachment = VK_ATTACHMENT_UNUSED, 233 .layout = VK_IMAGE_LAYOUT_GENERAL, 234 }, 235 .preserveAttachmentCount = 1, 236 .pPreserveAttachments = (uint32_t[]) { 0 }, 237 }, 238 .dependencyCount = 0, 239 }, &device->meta_state.alloc, pass); 240 mtx_unlock(&device->meta_state.mtx); 241 return result; 242} 243 244static VkResult 245create_color_pipeline(struct radv_device *device, 246 uint32_t samples, 247 uint32_t frag_output, 248 VkPipeline *pipeline, 249 VkRenderPass pass) 250{ 251 struct nir_shader *vs_nir; 252 struct nir_shader *fs_nir; 253 VkResult result; 254 255 mtx_lock(&device->meta_state.mtx); 256 if (*pipeline) { 257 mtx_unlock(&device->meta_state.mtx); 258 return VK_SUCCESS; 259 } 260 261 build_color_shaders(&vs_nir, &fs_nir, frag_output); 262 263 const VkPipelineVertexInputStateCreateInfo vi_state = { 264 .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, 265 .vertexBindingDescriptionCount = 0, 266 .vertexAttributeDescriptionCount = 0, 267 }; 268 269 const VkPipelineDepthStencilStateCreateInfo ds_state = { 270 .sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, 271 .depthTestEnable = false, 272 .depthWriteEnable = false, 273 .depthBoundsTestEnable = false, 274 .stencilTestEnable = false, 275 }; 276 277 VkPipelineColorBlendAttachmentState blend_attachment_state[MAX_RTS] = { 0 }; 278 blend_attachment_state[frag_output] = (VkPipelineColorBlendAttachmentState) { 279 .blendEnable = false, 280 .colorWriteMask = VK_COLOR_COMPONENT_A_BIT | 281 VK_COLOR_COMPONENT_R_BIT | 282 VK_COLOR_COMPONENT_G_BIT | 283 VK_COLOR_COMPONENT_B_BIT, 284 }; 285 286 const VkPipelineColorBlendStateCreateInfo cb_state = { 287 .sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, 288 .logicOpEnable = false, 289 .attachmentCount = MAX_RTS, 290 .pAttachments = blend_attachment_state 291 }; 292 293 294 struct radv_graphics_pipeline_create_info extra = { 295 .use_rectlist = true, 296 }; 297 result = create_pipeline(device, radv_render_pass_from_handle(pass), 298 samples, vs_nir, fs_nir, &vi_state, &ds_state, &cb_state, 299 device->meta_state.clear_color_p_layout, 300 &extra, &device->meta_state.alloc, pipeline); 301 302 mtx_unlock(&device->meta_state.mtx); 303 return result; 304} 305 306void 307radv_device_finish_meta_clear_state(struct radv_device *device) 308{ 309 struct radv_meta_state *state = &device->meta_state; 310 311 for (uint32_t i = 0; i < ARRAY_SIZE(state->clear); ++i) { 312 for (uint32_t j = 0; j < ARRAY_SIZE(state->clear[i].color_pipelines); ++j) { 313 radv_DestroyPipeline(radv_device_to_handle(device), 314 state->clear[i].color_pipelines[j], 315 &state->alloc); 316 radv_DestroyRenderPass(radv_device_to_handle(device), 317 state->clear[i].render_pass[j], 318 &state->alloc); 319 } 320 321 for (uint32_t j = 0; j < NUM_DEPTH_CLEAR_PIPELINES; j++) { 322 radv_DestroyPipeline(radv_device_to_handle(device), 323 state->clear[i].depth_only_pipeline[j], 324 &state->alloc); 325 radv_DestroyPipeline(radv_device_to_handle(device), 326 state->clear[i].stencil_only_pipeline[j], 327 &state->alloc); 328 radv_DestroyPipeline(radv_device_to_handle(device), 329 state->clear[i].depthstencil_pipeline[j], 330 &state->alloc); 331 } 332 radv_DestroyRenderPass(radv_device_to_handle(device), 333 state->clear[i].depthstencil_rp, 334 &state->alloc); 335 } 336 radv_DestroyPipelineLayout(radv_device_to_handle(device), 337 state->clear_color_p_layout, 338 &state->alloc); 339 radv_DestroyPipelineLayout(radv_device_to_handle(device), 340 state->clear_depth_p_layout, 341 &state->alloc); 342} 343 344static void 345emit_color_clear(struct radv_cmd_buffer *cmd_buffer, 346 const VkClearAttachment *clear_att, 347 const VkClearRect *clear_rect, 348 uint32_t view_mask) 349{ 350 struct radv_device *device = cmd_buffer->device; 351 const struct radv_subpass *subpass = cmd_buffer->state.subpass; 352 const struct radv_framebuffer *fb = cmd_buffer->state.framebuffer; 353 const uint32_t subpass_att = clear_att->colorAttachment; 354 const uint32_t pass_att = subpass->color_attachments[subpass_att].attachment; 355 const struct radv_image_view *iview = fb->attachments[pass_att].attachment; 356 const uint32_t samples = iview->image->info.samples; 357 const uint32_t samples_log2 = ffs(samples) - 1; 358 unsigned fs_key = radv_format_meta_fs_key(iview->vk_format); 359 VkClearColorValue clear_value = clear_att->clearValue.color; 360 VkCommandBuffer cmd_buffer_h = radv_cmd_buffer_to_handle(cmd_buffer); 361 VkPipeline pipeline; 362 363 if (fs_key == -1) { 364 radv_finishme("color clears incomplete"); 365 return; 366 } 367 368 if (device->meta_state.clear[samples_log2].render_pass[fs_key] == VK_NULL_HANDLE) { 369 VkResult ret = create_color_renderpass(device, radv_fs_key_format_exemplars[fs_key], 370 samples, 371 &device->meta_state.clear[samples_log2].render_pass[fs_key]); 372 if (ret != VK_SUCCESS) { 373 cmd_buffer->record_result = ret; 374 return; 375 } 376 } 377 378 if (device->meta_state.clear[samples_log2].color_pipelines[fs_key] == VK_NULL_HANDLE) { 379 VkResult ret = create_color_pipeline(device, samples, 0, 380 &device->meta_state.clear[samples_log2].color_pipelines[fs_key], 381 device->meta_state.clear[samples_log2].render_pass[fs_key]); 382 if (ret != VK_SUCCESS) { 383 cmd_buffer->record_result = ret; 384 return; 385 } 386 } 387 388 pipeline = device->meta_state.clear[samples_log2].color_pipelines[fs_key]; 389 if (!pipeline) { 390 radv_finishme("color clears incomplete"); 391 return; 392 } 393 assert(samples_log2 < ARRAY_SIZE(device->meta_state.clear)); 394 assert(pipeline); 395 assert(clear_att->aspectMask == VK_IMAGE_ASPECT_COLOR_BIT); 396 assert(clear_att->colorAttachment < subpass->color_count); 397 398 radv_CmdPushConstants(radv_cmd_buffer_to_handle(cmd_buffer), 399 device->meta_state.clear_color_p_layout, 400 VK_SHADER_STAGE_FRAGMENT_BIT, 0, 16, 401 &clear_value); 402 403 struct radv_subpass clear_subpass = { 404 .color_count = 1, 405 .color_attachments = (struct radv_subpass_attachment[]) { 406 subpass->color_attachments[clear_att->colorAttachment] 407 }, 408 .depth_stencil_attachment = (struct radv_subpass_attachment) { VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_UNDEFINED } 409 }; 410 411 radv_cmd_buffer_set_subpass(cmd_buffer, &clear_subpass, false); 412 413 radv_CmdBindPipeline(cmd_buffer_h, VK_PIPELINE_BIND_POINT_GRAPHICS, 414 pipeline); 415 416 radv_CmdSetViewport(radv_cmd_buffer_to_handle(cmd_buffer), 0, 1, &(VkViewport) { 417 .x = clear_rect->rect.offset.x, 418 .y = clear_rect->rect.offset.y, 419 .width = clear_rect->rect.extent.width, 420 .height = clear_rect->rect.extent.height, 421 .minDepth = 0.0f, 422 .maxDepth = 1.0f 423 }); 424 425 radv_CmdSetScissor(radv_cmd_buffer_to_handle(cmd_buffer), 0, 1, &clear_rect->rect); 426 427 if (view_mask) { 428 unsigned i; 429 for_each_bit(i, view_mask) 430 radv_CmdDraw(cmd_buffer_h, 3, 1, 0, i); 431 } else { 432 radv_CmdDraw(cmd_buffer_h, 3, clear_rect->layerCount, 0, clear_rect->baseArrayLayer); 433 } 434 435 radv_cmd_buffer_set_subpass(cmd_buffer, subpass, false); 436} 437 438 439static void 440build_depthstencil_shader(struct nir_shader **out_vs, struct nir_shader **out_fs) 441{ 442 nir_builder vs_b, fs_b; 443 444 nir_builder_init_simple_shader(&vs_b, NULL, MESA_SHADER_VERTEX, NULL); 445 nir_builder_init_simple_shader(&fs_b, NULL, MESA_SHADER_FRAGMENT, NULL); 446 447 vs_b.shader->info.name = ralloc_strdup(vs_b.shader, "meta_clear_depthstencil_vs"); 448 fs_b.shader->info.name = ralloc_strdup(fs_b.shader, "meta_clear_depthstencil_fs"); 449 const struct glsl_type *position_out_type = glsl_vec4_type(); 450 451 nir_variable *vs_out_pos = 452 nir_variable_create(vs_b.shader, nir_var_shader_out, position_out_type, 453 "gl_Position"); 454 vs_out_pos->data.location = VARYING_SLOT_POS; 455 456 nir_intrinsic_instr *in_color_load = nir_intrinsic_instr_create(vs_b.shader, nir_intrinsic_load_push_constant); 457 nir_intrinsic_set_base(in_color_load, 0); 458 nir_intrinsic_set_range(in_color_load, 4); 459 in_color_load->src[0] = nir_src_for_ssa(nir_imm_int(&vs_b, 0)); 460 in_color_load->num_components = 1; 461 nir_ssa_dest_init(&in_color_load->instr, &in_color_load->dest, 1, 32, "depth value"); 462 nir_builder_instr_insert(&vs_b, &in_color_load->instr); 463 464 nir_ssa_def *outvec = radv_meta_gen_rect_vertices_comp2(&vs_b, &in_color_load->dest.ssa); 465 nir_store_var(&vs_b, vs_out_pos, outvec, 0xf); 466 467 const struct glsl_type *layer_type = glsl_int_type(); 468 nir_variable *vs_out_layer = 469 nir_variable_create(vs_b.shader, nir_var_shader_out, layer_type, 470 "v_layer"); 471 vs_out_layer->data.location = VARYING_SLOT_LAYER; 472 vs_out_layer->data.interpolation = INTERP_MODE_FLAT; 473 nir_ssa_def *inst_id = nir_load_system_value(&vs_b, nir_intrinsic_load_instance_id, 0); 474 nir_ssa_def *base_instance = nir_load_system_value(&vs_b, nir_intrinsic_load_base_instance, 0); 475 476 nir_ssa_def *layer_id = nir_iadd(&vs_b, inst_id, base_instance); 477 nir_store_var(&vs_b, vs_out_layer, layer_id, 0x1); 478 479 *out_vs = vs_b.shader; 480 *out_fs = fs_b.shader; 481} 482 483static VkResult 484create_depthstencil_renderpass(struct radv_device *device, 485 uint32_t samples, 486 VkRenderPass *render_pass) 487{ 488 mtx_lock(&device->meta_state.mtx); 489 if (*render_pass) { 490 mtx_unlock(&device->meta_state.mtx); 491 return VK_SUCCESS; 492 } 493 494 VkResult result = radv_CreateRenderPass(radv_device_to_handle(device), 495 &(VkRenderPassCreateInfo) { 496 .sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, 497 .attachmentCount = 1, 498 .pAttachments = &(VkAttachmentDescription) { 499 .format = VK_FORMAT_D32_SFLOAT_S8_UINT, 500 .samples = samples, 501 .loadOp = VK_ATTACHMENT_LOAD_OP_LOAD, 502 .storeOp = VK_ATTACHMENT_STORE_OP_STORE, 503 .initialLayout = VK_IMAGE_LAYOUT_GENERAL, 504 .finalLayout = VK_IMAGE_LAYOUT_GENERAL, 505 }, 506 .subpassCount = 1, 507 .pSubpasses = &(VkSubpassDescription) { 508 .pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS, 509 .inputAttachmentCount = 0, 510 .colorAttachmentCount = 0, 511 .pColorAttachments = NULL, 512 .pResolveAttachments = NULL, 513 .pDepthStencilAttachment = &(VkAttachmentReference) { 514 .attachment = 0, 515 .layout = VK_IMAGE_LAYOUT_GENERAL, 516 }, 517 .preserveAttachmentCount = 1, 518 .pPreserveAttachments = (uint32_t[]) { 0 }, 519 }, 520 .dependencyCount = 0, 521 }, &device->meta_state.alloc, render_pass); 522 mtx_unlock(&device->meta_state.mtx); 523 return result; 524} 525 526static VkResult 527create_depthstencil_pipeline(struct radv_device *device, 528 VkImageAspectFlags aspects, 529 uint32_t samples, 530 int index, 531 VkPipeline *pipeline, 532 VkRenderPass render_pass) 533{ 534 struct nir_shader *vs_nir, *fs_nir; 535 VkResult result; 536 537 mtx_lock(&device->meta_state.mtx); 538 if (*pipeline) { 539 mtx_unlock(&device->meta_state.mtx); 540 return VK_SUCCESS; 541 } 542 543 build_depthstencil_shader(&vs_nir, &fs_nir); 544 545 const VkPipelineVertexInputStateCreateInfo vi_state = { 546 .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, 547 .vertexBindingDescriptionCount = 0, 548 .vertexAttributeDescriptionCount = 0, 549 }; 550 551 const VkPipelineDepthStencilStateCreateInfo ds_state = { 552 .sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, 553 .depthTestEnable = (aspects & VK_IMAGE_ASPECT_DEPTH_BIT), 554 .depthCompareOp = VK_COMPARE_OP_ALWAYS, 555 .depthWriteEnable = (aspects & VK_IMAGE_ASPECT_DEPTH_BIT), 556 .depthBoundsTestEnable = false, 557 .stencilTestEnable = (aspects & VK_IMAGE_ASPECT_STENCIL_BIT), 558 .front = { 559 .passOp = VK_STENCIL_OP_REPLACE, 560 .compareOp = VK_COMPARE_OP_ALWAYS, 561 .writeMask = UINT32_MAX, 562 .reference = 0, /* dynamic */ 563 }, 564 .back = { 0 /* dont care */ }, 565 }; 566 567 const VkPipelineColorBlendStateCreateInfo cb_state = { 568 .sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, 569 .logicOpEnable = false, 570 .attachmentCount = 0, 571 .pAttachments = NULL, 572 }; 573 574 struct radv_graphics_pipeline_create_info extra = { 575 .use_rectlist = true, 576 }; 577 578 if (aspects & VK_IMAGE_ASPECT_DEPTH_BIT) { 579 extra.db_depth_clear = index == DEPTH_CLEAR_SLOW ? false : true; 580 extra.db_depth_disable_expclear = index == DEPTH_CLEAR_FAST_NO_EXPCLEAR ? true : false; 581 } 582 if (aspects & VK_IMAGE_ASPECT_STENCIL_BIT) { 583 extra.db_stencil_clear = index == DEPTH_CLEAR_SLOW ? false : true; 584 extra.db_stencil_disable_expclear = index == DEPTH_CLEAR_FAST_NO_EXPCLEAR ? true : false; 585 } 586 result = create_pipeline(device, radv_render_pass_from_handle(render_pass), 587 samples, vs_nir, fs_nir, &vi_state, &ds_state, &cb_state, 588 device->meta_state.clear_depth_p_layout, 589 &extra, &device->meta_state.alloc, pipeline); 590 591 mtx_unlock(&device->meta_state.mtx); 592 return result; 593} 594 595static bool depth_view_can_fast_clear(struct radv_cmd_buffer *cmd_buffer, 596 const struct radv_image_view *iview, 597 VkImageAspectFlags aspects, 598 VkImageLayout layout, 599 const VkClearRect *clear_rect, 600 VkClearDepthStencilValue clear_value) 601{ 602 uint32_t queue_mask = radv_image_queue_family_mask(iview->image, 603 cmd_buffer->queue_family_index, 604 cmd_buffer->queue_family_index); 605 if (clear_rect->rect.offset.x || clear_rect->rect.offset.y || 606 clear_rect->rect.extent.width != iview->extent.width || 607 clear_rect->rect.extent.height != iview->extent.height) 608 return false; 609 if (radv_image_is_tc_compat_htile(iview->image) && 610 (((aspects & VK_IMAGE_ASPECT_DEPTH_BIT) && clear_value.depth != 0.0 && 611 clear_value.depth != 1.0) || 612 ((aspects & VK_IMAGE_ASPECT_STENCIL_BIT) && clear_value.stencil != 0))) 613 return false; 614 if (radv_image_has_htile(iview->image) && 615 iview->base_mip == 0 && 616 iview->base_layer == 0 && 617 radv_layout_is_htile_compressed(iview->image, layout, queue_mask) && 618 !radv_image_extent_compare(iview->image, &iview->extent)) 619 return true; 620 return false; 621} 622 623static VkPipeline 624pick_depthstencil_pipeline(struct radv_cmd_buffer *cmd_buffer, 625 struct radv_meta_state *meta_state, 626 const struct radv_image_view *iview, 627 int samples_log2, 628 VkImageAspectFlags aspects, 629 VkImageLayout layout, 630 const VkClearRect *clear_rect, 631 VkClearDepthStencilValue clear_value) 632{ 633 bool fast = depth_view_can_fast_clear(cmd_buffer, iview, aspects, layout, clear_rect, clear_value); 634 int index = DEPTH_CLEAR_SLOW; 635 VkPipeline *pipeline; 636 637 if (fast) { 638 /* we don't know the previous clear values, so we always have 639 * the NO_EXPCLEAR path */ 640 index = DEPTH_CLEAR_FAST_NO_EXPCLEAR; 641 } 642 643 switch (aspects) { 644 case VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT: 645 pipeline = &meta_state->clear[samples_log2].depthstencil_pipeline[index]; 646 break; 647 case VK_IMAGE_ASPECT_DEPTH_BIT: 648 pipeline = &meta_state->clear[samples_log2].depth_only_pipeline[index]; 649 break; 650 case VK_IMAGE_ASPECT_STENCIL_BIT: 651 pipeline = &meta_state->clear[samples_log2].stencil_only_pipeline[index]; 652 break; 653 default: 654 unreachable("expected depth or stencil aspect"); 655 } 656 657 if (cmd_buffer->device->meta_state.clear[samples_log2].depthstencil_rp == VK_NULL_HANDLE) { 658 VkResult ret = create_depthstencil_renderpass(cmd_buffer->device, 1u << samples_log2, 659 &cmd_buffer->device->meta_state.clear[samples_log2].depthstencil_rp); 660 if (ret != VK_SUCCESS) { 661 cmd_buffer->record_result = ret; 662 return VK_NULL_HANDLE; 663 } 664 } 665 666 if (*pipeline == VK_NULL_HANDLE) { 667 VkResult ret = create_depthstencil_pipeline(cmd_buffer->device, aspects, 1u << samples_log2, index, 668 pipeline, cmd_buffer->device->meta_state.clear[samples_log2].depthstencil_rp); 669 if (ret != VK_SUCCESS) { 670 cmd_buffer->record_result = ret; 671 return VK_NULL_HANDLE; 672 } 673 } 674 return *pipeline; 675} 676 677static void 678emit_depthstencil_clear(struct radv_cmd_buffer *cmd_buffer, 679 const VkClearAttachment *clear_att, 680 const VkClearRect *clear_rect) 681{ 682 struct radv_device *device = cmd_buffer->device; 683 struct radv_meta_state *meta_state = &device->meta_state; 684 const struct radv_subpass *subpass = cmd_buffer->state.subpass; 685 const struct radv_framebuffer *fb = cmd_buffer->state.framebuffer; 686 const uint32_t pass_att = subpass->depth_stencil_attachment.attachment; 687 VkClearDepthStencilValue clear_value = clear_att->clearValue.depthStencil; 688 VkImageAspectFlags aspects = clear_att->aspectMask; 689 const struct radv_image_view *iview = fb->attachments[pass_att].attachment; 690 const uint32_t samples = iview->image->info.samples; 691 const uint32_t samples_log2 = ffs(samples) - 1; 692 VkCommandBuffer cmd_buffer_h = radv_cmd_buffer_to_handle(cmd_buffer); 693 694 assert(pass_att != VK_ATTACHMENT_UNUSED); 695 696 if (!(aspects & VK_IMAGE_ASPECT_DEPTH_BIT)) 697 clear_value.depth = 1.0f; 698 699 radv_CmdPushConstants(radv_cmd_buffer_to_handle(cmd_buffer), 700 device->meta_state.clear_depth_p_layout, 701 VK_SHADER_STAGE_VERTEX_BIT, 0, 4, 702 &clear_value.depth); 703 704 uint32_t prev_reference = cmd_buffer->state.dynamic.stencil_reference.front; 705 if (aspects & VK_IMAGE_ASPECT_STENCIL_BIT) { 706 radv_CmdSetStencilReference(cmd_buffer_h, VK_STENCIL_FACE_FRONT_BIT, 707 clear_value.stencil); 708 } 709 710 VkPipeline pipeline = pick_depthstencil_pipeline(cmd_buffer, 711 meta_state, 712 iview, 713 samples_log2, 714 aspects, 715 subpass->depth_stencil_attachment.layout, 716 clear_rect, 717 clear_value); 718 if (!pipeline) 719 return; 720 721 radv_CmdBindPipeline(cmd_buffer_h, VK_PIPELINE_BIND_POINT_GRAPHICS, 722 pipeline); 723 724 if (depth_view_can_fast_clear(cmd_buffer, iview, aspects, 725 subpass->depth_stencil_attachment.layout, 726 clear_rect, clear_value)) 727 radv_update_ds_clear_metadata(cmd_buffer, iview->image, 728 clear_value, aspects); 729 730 radv_CmdSetViewport(radv_cmd_buffer_to_handle(cmd_buffer), 0, 1, &(VkViewport) { 731 .x = clear_rect->rect.offset.x, 732 .y = clear_rect->rect.offset.y, 733 .width = clear_rect->rect.extent.width, 734 .height = clear_rect->rect.extent.height, 735 .minDepth = 0.0f, 736 .maxDepth = 1.0f 737 }); 738 739 radv_CmdSetScissor(radv_cmd_buffer_to_handle(cmd_buffer), 0, 1, &clear_rect->rect); 740 741 radv_CmdDraw(cmd_buffer_h, 3, clear_rect->layerCount, 0, clear_rect->baseArrayLayer); 742 743 if (aspects & VK_IMAGE_ASPECT_STENCIL_BIT) { 744 radv_CmdSetStencilReference(cmd_buffer_h, VK_STENCIL_FACE_FRONT_BIT, 745 prev_reference); 746 } 747} 748 749static bool 750emit_fast_htile_clear(struct radv_cmd_buffer *cmd_buffer, 751 const VkClearAttachment *clear_att, 752 const VkClearRect *clear_rect, 753 enum radv_cmd_flush_bits *pre_flush, 754 enum radv_cmd_flush_bits *post_flush) 755{ 756 const struct radv_subpass *subpass = cmd_buffer->state.subpass; 757 const uint32_t pass_att = subpass->depth_stencil_attachment.attachment; 758 VkImageLayout image_layout = subpass->depth_stencil_attachment.layout; 759 const struct radv_framebuffer *fb = cmd_buffer->state.framebuffer; 760 const struct radv_image_view *iview = fb->attachments[pass_att].attachment; 761 VkClearDepthStencilValue clear_value = clear_att->clearValue.depthStencil; 762 VkImageAspectFlags aspects = clear_att->aspectMask; 763 uint32_t clear_word, flush_bits; 764 765 if (!radv_image_has_htile(iview->image)) 766 return false; 767 768 if (cmd_buffer->device->instance->debug_flags & RADV_DEBUG_NO_FAST_CLEARS) 769 return false; 770 771 if (!radv_layout_is_htile_compressed(iview->image, image_layout, radv_image_queue_family_mask(iview->image, cmd_buffer->queue_family_index, cmd_buffer->queue_family_index))) 772 goto fail; 773 774 /* don't fast clear 3D */ 775 if (iview->image->type == VK_IMAGE_TYPE_3D) 776 goto fail; 777 778 /* all layers are bound */ 779 if (iview->base_layer > 0) 780 goto fail; 781 if (iview->image->info.array_size != iview->layer_count) 782 goto fail; 783 784 if (!radv_image_extent_compare(iview->image, &iview->extent)) 785 goto fail; 786 787 if (clear_rect->rect.offset.x || clear_rect->rect.offset.y || 788 clear_rect->rect.extent.width != iview->image->info.width || 789 clear_rect->rect.extent.height != iview->image->info.height) 790 goto fail; 791 792 if (clear_rect->baseArrayLayer != 0) 793 goto fail; 794 if (clear_rect->layerCount != iview->image->info.array_size) 795 goto fail; 796 797 if ((clear_value.depth != 0.0 && clear_value.depth != 1.0) || !(aspects & VK_IMAGE_ASPECT_DEPTH_BIT)) 798 goto fail; 799 800 /* GFX8 only supports 32-bit depth surfaces but we can enable TC-compat 801 * HTILE for 16-bit surfaces if no Z planes are compressed. Though, 802 * fast HTILE clears don't seem to work. 803 */ 804 if (cmd_buffer->device->physical_device->rad_info.chip_class == VI && 805 iview->image->vk_format == VK_FORMAT_D16_UNORM) 806 goto fail; 807 808 if (vk_format_aspects(iview->image->vk_format) & VK_IMAGE_ASPECT_STENCIL_BIT) { 809 if (clear_value.stencil != 0 || !(aspects & VK_IMAGE_ASPECT_STENCIL_BIT)) 810 goto fail; 811 clear_word = clear_value.depth ? 0xfffc0000 : 0; 812 } else 813 clear_word = clear_value.depth ? 0xfffffff0 : 0; 814 815 if (pre_flush) { 816 cmd_buffer->state.flush_bits |= (RADV_CMD_FLAG_FLUSH_AND_INV_DB | 817 RADV_CMD_FLAG_FLUSH_AND_INV_DB_META) & ~ *pre_flush; 818 *pre_flush |= cmd_buffer->state.flush_bits; 819 } else 820 cmd_buffer->state.flush_bits |= RADV_CMD_FLAG_FLUSH_AND_INV_DB | 821 RADV_CMD_FLAG_FLUSH_AND_INV_DB_META; 822 823 flush_bits = radv_fill_buffer(cmd_buffer, iview->image->bo, 824 iview->image->offset + iview->image->htile_offset, 825 iview->image->surface.htile_size, clear_word); 826 827 radv_update_ds_clear_metadata(cmd_buffer, iview->image, clear_value, aspects); 828 if (post_flush) { 829 *post_flush |= flush_bits; 830 } else { 831 cmd_buffer->state.flush_bits |= flush_bits; 832 } 833 834 return true; 835fail: 836 return false; 837} 838 839VkResult 840radv_device_init_meta_clear_state(struct radv_device *device, bool on_demand) 841{ 842 VkResult res; 843 struct radv_meta_state *state = &device->meta_state; 844 845 VkPipelineLayoutCreateInfo pl_color_create_info = { 846 .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, 847 .setLayoutCount = 0, 848 .pushConstantRangeCount = 1, 849 .pPushConstantRanges = &(VkPushConstantRange){VK_SHADER_STAGE_FRAGMENT_BIT, 0, 16}, 850 }; 851 852 res = radv_CreatePipelineLayout(radv_device_to_handle(device), 853 &pl_color_create_info, 854 &device->meta_state.alloc, 855 &device->meta_state.clear_color_p_layout); 856 if (res != VK_SUCCESS) 857 goto fail; 858 859 VkPipelineLayoutCreateInfo pl_depth_create_info = { 860 .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, 861 .setLayoutCount = 0, 862 .pushConstantRangeCount = 1, 863 .pPushConstantRanges = &(VkPushConstantRange){VK_SHADER_STAGE_VERTEX_BIT, 0, 4}, 864 }; 865 866 res = radv_CreatePipelineLayout(radv_device_to_handle(device), 867 &pl_depth_create_info, 868 &device->meta_state.alloc, 869 &device->meta_state.clear_depth_p_layout); 870 if (res != VK_SUCCESS) 871 goto fail; 872 873 if (on_demand) 874 return VK_SUCCESS; 875 876 for (uint32_t i = 0; i < ARRAY_SIZE(state->clear); ++i) { 877 uint32_t samples = 1 << i; 878 for (uint32_t j = 0; j < NUM_META_FS_KEYS; ++j) { 879 VkFormat format = radv_fs_key_format_exemplars[j]; 880 unsigned fs_key = radv_format_meta_fs_key(format); 881 assert(!state->clear[i].color_pipelines[fs_key]); 882 883 res = create_color_renderpass(device, format, samples, 884 &state->clear[i].render_pass[fs_key]); 885 if (res != VK_SUCCESS) 886 goto fail; 887 888 res = create_color_pipeline(device, samples, 0, &state->clear[i].color_pipelines[fs_key], 889 state->clear[i].render_pass[fs_key]); 890 if (res != VK_SUCCESS) 891 goto fail; 892 893 } 894 895 res = create_depthstencil_renderpass(device, 896 samples, 897 &state->clear[i].depthstencil_rp); 898 if (res != VK_SUCCESS) 899 goto fail; 900 901 for (uint32_t j = 0; j < NUM_DEPTH_CLEAR_PIPELINES; j++) { 902 res = create_depthstencil_pipeline(device, 903 VK_IMAGE_ASPECT_DEPTH_BIT, 904 samples, 905 j, 906 &state->clear[i].depth_only_pipeline[j], 907 state->clear[i].depthstencil_rp); 908 if (res != VK_SUCCESS) 909 goto fail; 910 911 res = create_depthstencil_pipeline(device, 912 VK_IMAGE_ASPECT_STENCIL_BIT, 913 samples, 914 j, 915 &state->clear[i].stencil_only_pipeline[j], 916 state->clear[i].depthstencil_rp); 917 if (res != VK_SUCCESS) 918 goto fail; 919 920 res = create_depthstencil_pipeline(device, 921 VK_IMAGE_ASPECT_DEPTH_BIT | 922 VK_IMAGE_ASPECT_STENCIL_BIT, 923 samples, 924 j, 925 &state->clear[i].depthstencil_pipeline[j], 926 state->clear[i].depthstencil_rp); 927 if (res != VK_SUCCESS) 928 goto fail; 929 } 930 } 931 return VK_SUCCESS; 932 933fail: 934 radv_device_finish_meta_clear_state(device); 935 return res; 936} 937 938static uint32_t 939radv_get_cmask_fast_clear_value(const struct radv_image *image) 940{ 941 uint32_t value = 0; /* Default value when no DCC. */ 942 943 /* The fast-clear value is different for images that have both DCC and 944 * CMASK metadata. 945 */ 946 if (radv_image_has_dcc(image)) { 947 /* DCC fast clear with MSAA should clear CMASK to 0xC. */ 948 return image->info.samples > 1 ? 0xcccccccc : 0xffffffff; 949 } 950 951 return value; 952} 953 954uint32_t 955radv_clear_cmask(struct radv_cmd_buffer *cmd_buffer, 956 struct radv_image *image, uint32_t value) 957{ 958 return radv_fill_buffer(cmd_buffer, image->bo, 959 image->offset + image->cmask.offset, 960 image->cmask.size, value); 961} 962 963uint32_t 964radv_clear_dcc(struct radv_cmd_buffer *cmd_buffer, 965 struct radv_image *image, uint32_t value) 966{ 967 return radv_fill_buffer(cmd_buffer, image->bo, 968 image->offset + image->dcc_offset, 969 image->surface.dcc_size, value); 970} 971 972static void vi_get_fast_clear_parameters(VkFormat format, 973 const VkClearColorValue *clear_value, 974 uint32_t* reset_value, 975 bool *can_avoid_fast_clear_elim) 976{ 977 bool values[4] = {}; 978 int extra_channel; 979 bool main_value = false; 980 bool extra_value = false; 981 int i; 982 *can_avoid_fast_clear_elim = false; 983 984 *reset_value = 0x20202020U; 985 986 const struct vk_format_description *desc = vk_format_description(format); 987 if (format == VK_FORMAT_B10G11R11_UFLOAT_PACK32 || 988 format == VK_FORMAT_R5G6B5_UNORM_PACK16 || 989 format == VK_FORMAT_B5G6R5_UNORM_PACK16) 990 extra_channel = -1; 991 else if (desc->layout == VK_FORMAT_LAYOUT_PLAIN) { 992 if (radv_translate_colorswap(format, false) <= 1) 993 extra_channel = desc->nr_channels - 1; 994 else 995 extra_channel = 0; 996 } else 997 return; 998 999 for (i = 0; i < 4; i++) { 1000 int index = desc->swizzle[i] - VK_SWIZZLE_X; 1001 if (desc->swizzle[i] < VK_SWIZZLE_X || 1002 desc->swizzle[i] > VK_SWIZZLE_W) 1003 continue; 1004 1005 if (desc->channel[i].pure_integer && 1006 desc->channel[i].type == VK_FORMAT_TYPE_SIGNED) { 1007 /* Use the maximum value for clamping the clear color. */ 1008 int max = u_bit_consecutive(0, desc->channel[i].size - 1); 1009 1010 values[i] = clear_value->int32[i] != 0; 1011 if (clear_value->int32[i] != 0 && MIN2(clear_value->int32[i], max) != max) 1012 return; 1013 } else if (desc->channel[i].pure_integer && 1014 desc->channel[i].type == VK_FORMAT_TYPE_UNSIGNED) { 1015 /* Use the maximum value for clamping the clear color. */ 1016 unsigned max = u_bit_consecutive(0, desc->channel[i].size); 1017 1018 values[i] = clear_value->uint32[i] != 0U; 1019 if (clear_value->uint32[i] != 0U && MIN2(clear_value->uint32[i], max) != max) 1020 return; 1021 } else { 1022 values[i] = clear_value->float32[i] != 0.0F; 1023 if (clear_value->float32[i] != 0.0F && clear_value->float32[i] != 1.0F) 1024 return; 1025 } 1026 1027 if (index == extra_channel) 1028 extra_value = values[i]; 1029 else 1030 main_value = values[i]; 1031 } 1032 1033 for (int i = 0; i < 4; ++i) 1034 if (values[i] != main_value && 1035 desc->swizzle[i] - VK_SWIZZLE_X != extra_channel && 1036 desc->swizzle[i] >= VK_SWIZZLE_X && 1037 desc->swizzle[i] <= VK_SWIZZLE_W) 1038 return; 1039 1040 *can_avoid_fast_clear_elim = true; 1041 if (main_value) 1042 *reset_value |= 0x80808080U; 1043 1044 if (extra_value) 1045 *reset_value |= 0x40404040U; 1046 return; 1047} 1048 1049static bool 1050emit_fast_color_clear(struct radv_cmd_buffer *cmd_buffer, 1051 const VkClearAttachment *clear_att, 1052 const VkClearRect *clear_rect, 1053 enum radv_cmd_flush_bits *pre_flush, 1054 enum radv_cmd_flush_bits *post_flush, 1055 uint32_t view_mask) 1056{ 1057 const struct radv_subpass *subpass = cmd_buffer->state.subpass; 1058 const uint32_t subpass_att = clear_att->colorAttachment; 1059 const uint32_t pass_att = subpass->color_attachments[subpass_att].attachment; 1060 VkImageLayout image_layout = subpass->color_attachments[subpass_att].layout; 1061 const struct radv_framebuffer *fb = cmd_buffer->state.framebuffer; 1062 const struct radv_image_view *iview = fb->attachments[pass_att].attachment; 1063 VkClearColorValue clear_value = clear_att->clearValue.color; 1064 uint32_t clear_color[2], flush_bits = 0; 1065 uint32_t cmask_clear_value; 1066 bool ret; 1067 1068 if (!radv_image_has_cmask(iview->image) && !radv_image_has_dcc(iview->image)) 1069 return false; 1070 1071 if (cmd_buffer->device->instance->debug_flags & RADV_DEBUG_NO_FAST_CLEARS) 1072 return false; 1073 1074 if (!radv_layout_can_fast_clear(iview->image, image_layout, radv_image_queue_family_mask(iview->image, cmd_buffer->queue_family_index, cmd_buffer->queue_family_index))) 1075 goto fail; 1076 1077 /* don't fast clear 3D */ 1078 if (iview->image->type == VK_IMAGE_TYPE_3D) 1079 goto fail; 1080 1081 /* all layers are bound */ 1082 if (iview->base_layer > 0) 1083 goto fail; 1084 if (iview->image->info.array_size != iview->layer_count) 1085 goto fail; 1086 1087 if (iview->image->info.levels > 1) 1088 goto fail; 1089 1090 if (!radv_image_extent_compare(iview->image, &iview->extent)) 1091 goto fail; 1092 1093 if (clear_rect->rect.offset.x || clear_rect->rect.offset.y || 1094 clear_rect->rect.extent.width != iview->image->info.width || 1095 clear_rect->rect.extent.height != iview->image->info.height) 1096 goto fail; 1097 1098 if (view_mask && (iview->image->info.array_size >= 32 || 1099 (1u << iview->image->info.array_size) - 1u != view_mask)) 1100 goto fail; 1101 if (!view_mask && clear_rect->baseArrayLayer != 0) 1102 goto fail; 1103 if (!view_mask && clear_rect->layerCount != iview->image->info.array_size) 1104 goto fail; 1105 1106 /* RB+ doesn't work with CMASK fast clear on Stoney. */ 1107 if (!radv_image_has_dcc(iview->image) && 1108 cmd_buffer->device->physical_device->rad_info.family == CHIP_STONEY) 1109 goto fail; 1110 1111 /* DCC */ 1112 ret = radv_format_pack_clear_color(iview->vk_format, 1113 clear_color, &clear_value); 1114 if (ret == false) 1115 goto fail; 1116 1117 if (pre_flush) { 1118 cmd_buffer->state.flush_bits |= (RADV_CMD_FLAG_FLUSH_AND_INV_CB | 1119 RADV_CMD_FLAG_FLUSH_AND_INV_CB_META) & ~ *pre_flush; 1120 *pre_flush |= cmd_buffer->state.flush_bits; 1121 } else 1122 cmd_buffer->state.flush_bits |= RADV_CMD_FLAG_FLUSH_AND_INV_CB | 1123 RADV_CMD_FLAG_FLUSH_AND_INV_CB_META; 1124 1125 cmask_clear_value = radv_get_cmask_fast_clear_value(iview->image); 1126 1127 /* clear cmask buffer */ 1128 if (radv_image_has_dcc(iview->image)) { 1129 uint32_t reset_value; 1130 bool can_avoid_fast_clear_elim; 1131 bool need_decompress_pass = false; 1132 1133 vi_get_fast_clear_parameters(iview->vk_format, 1134 &clear_value, &reset_value, 1135 &can_avoid_fast_clear_elim); 1136 1137 if (iview->image->info.samples > 1) { 1138 /* DCC fast clear with MSAA should clear CMASK. */ 1139 /* FIXME: This doesn't work for now. There is a 1140 * hardware bug with fast clears and DCC for MSAA 1141 * textures. AMDVLK has a workaround but it doesn't 1142 * seem to work here. Note that we might emit useless 1143 * CB flushes but that shouldn't matter. 1144 */ 1145 if (!can_avoid_fast_clear_elim) 1146 goto fail; 1147 1148 assert(radv_image_has_cmask(iview->image)); 1149 1150 flush_bits = radv_clear_cmask(cmd_buffer, iview->image, 1151 cmask_clear_value); 1152 1153 need_decompress_pass = true; 1154 } 1155 1156 if (!can_avoid_fast_clear_elim) 1157 need_decompress_pass = true; 1158 1159 flush_bits |= radv_clear_dcc(cmd_buffer, iview->image, reset_value); 1160 1161 radv_set_dcc_need_cmask_elim_pred(cmd_buffer, iview->image, 1162 need_decompress_pass); 1163 } else { 1164 flush_bits = radv_clear_cmask(cmd_buffer, iview->image, 1165 cmask_clear_value); 1166 } 1167 1168 if (post_flush) { 1169 *post_flush |= flush_bits; 1170 } else { 1171 cmd_buffer->state.flush_bits |= flush_bits; 1172 } 1173 1174 radv_update_color_clear_metadata(cmd_buffer, iview->image, subpass_att, 1175 clear_color); 1176 1177 return true; 1178fail: 1179 return false; 1180} 1181 1182/** 1183 * The parameters mean that same as those in vkCmdClearAttachments. 1184 */ 1185static void 1186emit_clear(struct radv_cmd_buffer *cmd_buffer, 1187 const VkClearAttachment *clear_att, 1188 const VkClearRect *clear_rect, 1189 enum radv_cmd_flush_bits *pre_flush, 1190 enum radv_cmd_flush_bits *post_flush, 1191 uint32_t view_mask) 1192{ 1193 if (clear_att->aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) { 1194 if (!emit_fast_color_clear(cmd_buffer, clear_att, clear_rect, 1195 pre_flush, post_flush, view_mask)) 1196 emit_color_clear(cmd_buffer, clear_att, clear_rect, view_mask); 1197 } else { 1198 assert(clear_att->aspectMask & (VK_IMAGE_ASPECT_DEPTH_BIT | 1199 VK_IMAGE_ASPECT_STENCIL_BIT)); 1200 if (!emit_fast_htile_clear(cmd_buffer, clear_att, clear_rect, 1201 pre_flush, post_flush)) 1202 emit_depthstencil_clear(cmd_buffer, clear_att, clear_rect); 1203 } 1204} 1205 1206static inline bool 1207radv_attachment_needs_clear(struct radv_cmd_state *cmd_state, uint32_t a) 1208{ 1209 uint32_t view_mask = cmd_state->subpass->view_mask; 1210 return (a != VK_ATTACHMENT_UNUSED && 1211 cmd_state->attachments[a].pending_clear_aspects && 1212 (!view_mask || (view_mask & ~cmd_state->attachments[a].cleared_views))); 1213} 1214 1215static bool 1216radv_subpass_needs_clear(struct radv_cmd_buffer *cmd_buffer) 1217{ 1218 struct radv_cmd_state *cmd_state = &cmd_buffer->state; 1219 uint32_t a; 1220 1221 if (!cmd_state->subpass) 1222 return false; 1223 1224 for (uint32_t i = 0; i < cmd_state->subpass->color_count; ++i) { 1225 a = cmd_state->subpass->color_attachments[i].attachment; 1226 if (radv_attachment_needs_clear(cmd_state, a)) 1227 return true; 1228 } 1229 1230 a = cmd_state->subpass->depth_stencil_attachment.attachment; 1231 return radv_attachment_needs_clear(cmd_state, a); 1232} 1233 1234static void 1235radv_subpass_clear_attachment(struct radv_cmd_buffer *cmd_buffer, 1236 struct radv_attachment_state *attachment, 1237 const VkClearAttachment *clear_att, 1238 enum radv_cmd_flush_bits *pre_flush, 1239 enum radv_cmd_flush_bits *post_flush) 1240{ 1241 struct radv_cmd_state *cmd_state = &cmd_buffer->state; 1242 uint32_t view_mask = cmd_state->subpass->view_mask; 1243 1244 VkClearRect clear_rect = { 1245 .rect = cmd_state->render_area, 1246 .baseArrayLayer = 0, 1247 .layerCount = cmd_state->framebuffer->layers, 1248 }; 1249 1250 emit_clear(cmd_buffer, clear_att, &clear_rect, pre_flush, post_flush, 1251 view_mask & ~attachment->cleared_views); 1252 if (view_mask) 1253 attachment->cleared_views |= view_mask; 1254 else 1255 attachment->pending_clear_aspects = 0; 1256} 1257 1258/** 1259 * Emit any pending attachment clears for the current subpass. 1260 * 1261 * @see radv_attachment_state::pending_clear_aspects 1262 */ 1263void 1264radv_cmd_buffer_clear_subpass(struct radv_cmd_buffer *cmd_buffer) 1265{ 1266 struct radv_cmd_state *cmd_state = &cmd_buffer->state; 1267 struct radv_meta_saved_state saved_state; 1268 enum radv_cmd_flush_bits pre_flush = 0; 1269 enum radv_cmd_flush_bits post_flush = 0; 1270 1271 if (!radv_subpass_needs_clear(cmd_buffer)) 1272 return; 1273 1274 radv_meta_save(&saved_state, cmd_buffer, 1275 RADV_META_SAVE_GRAPHICS_PIPELINE | 1276 RADV_META_SAVE_CONSTANTS); 1277 1278 for (uint32_t i = 0; i < cmd_state->subpass->color_count; ++i) { 1279 uint32_t a = cmd_state->subpass->color_attachments[i].attachment; 1280 1281 if (!radv_attachment_needs_clear(cmd_state, a)) 1282 continue; 1283 1284 assert(cmd_state->attachments[a].pending_clear_aspects == 1285 VK_IMAGE_ASPECT_COLOR_BIT); 1286 1287 VkClearAttachment clear_att = { 1288 .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, 1289 .colorAttachment = i, /* Use attachment index relative to subpass */ 1290 .clearValue = cmd_state->attachments[a].clear_value, 1291 }; 1292 1293 radv_subpass_clear_attachment(cmd_buffer, 1294 &cmd_state->attachments[a], 1295 &clear_att, &pre_flush, 1296 &post_flush); 1297 } 1298 1299 uint32_t ds = cmd_state->subpass->depth_stencil_attachment.attachment; 1300 if (radv_attachment_needs_clear(cmd_state, ds)) { 1301 VkClearAttachment clear_att = { 1302 .aspectMask = cmd_state->attachments[ds].pending_clear_aspects, 1303 .clearValue = cmd_state->attachments[ds].clear_value, 1304 }; 1305 1306 radv_subpass_clear_attachment(cmd_buffer, 1307 &cmd_state->attachments[ds], 1308 &clear_att, &pre_flush, 1309 &post_flush); 1310 } 1311 1312 radv_meta_restore(&saved_state, cmd_buffer); 1313 cmd_buffer->state.flush_bits |= post_flush; 1314} 1315 1316static void 1317radv_clear_image_layer(struct radv_cmd_buffer *cmd_buffer, 1318 struct radv_image *image, 1319 VkImageLayout image_layout, 1320 const VkImageSubresourceRange *range, 1321 VkFormat format, int level, int layer, 1322 const VkClearValue *clear_val) 1323{ 1324 VkDevice device_h = radv_device_to_handle(cmd_buffer->device); 1325 struct radv_image_view iview; 1326 uint32_t width = radv_minify(image->info.width, range->baseMipLevel + level); 1327 uint32_t height = radv_minify(image->info.height, range->baseMipLevel + level); 1328 1329 radv_image_view_init(&iview, cmd_buffer->device, 1330 &(VkImageViewCreateInfo) { 1331 .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, 1332 .image = radv_image_to_handle(image), 1333 .viewType = radv_meta_get_view_type(image), 1334 .format = format, 1335 .subresourceRange = { 1336 .aspectMask = range->aspectMask, 1337 .baseMipLevel = range->baseMipLevel + level, 1338 .levelCount = 1, 1339 .baseArrayLayer = range->baseArrayLayer + layer, 1340 .layerCount = 1 1341 }, 1342 }); 1343 1344 VkFramebuffer fb; 1345 radv_CreateFramebuffer(device_h, 1346 &(VkFramebufferCreateInfo) { 1347 .sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, 1348 .attachmentCount = 1, 1349 .pAttachments = (VkImageView[]) { 1350 radv_image_view_to_handle(&iview), 1351 }, 1352 .width = width, 1353 .height = height, 1354 .layers = 1 1355 }, 1356 &cmd_buffer->pool->alloc, 1357 &fb); 1358 1359 VkAttachmentDescription att_desc = { 1360 .format = iview.vk_format, 1361 .loadOp = VK_ATTACHMENT_LOAD_OP_LOAD, 1362 .storeOp = VK_ATTACHMENT_STORE_OP_STORE, 1363 .stencilLoadOp = VK_ATTACHMENT_LOAD_OP_LOAD, 1364 .stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE, 1365 .initialLayout = image_layout, 1366 .finalLayout = image_layout, 1367 }; 1368 1369 VkSubpassDescription subpass_desc = { 1370 .pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS, 1371 .inputAttachmentCount = 0, 1372 .colorAttachmentCount = 0, 1373 .pColorAttachments = NULL, 1374 .pResolveAttachments = NULL, 1375 .pDepthStencilAttachment = NULL, 1376 .preserveAttachmentCount = 0, 1377 .pPreserveAttachments = NULL, 1378 }; 1379 1380 const VkAttachmentReference att_ref = { 1381 .attachment = 0, 1382 .layout = image_layout, 1383 }; 1384 1385 if (range->aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) { 1386 subpass_desc.colorAttachmentCount = 1; 1387 subpass_desc.pColorAttachments = &att_ref; 1388 } else { 1389 subpass_desc.pDepthStencilAttachment = &att_ref; 1390 } 1391 1392 VkRenderPass pass; 1393 radv_CreateRenderPass(device_h, 1394 &(VkRenderPassCreateInfo) { 1395 .sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, 1396 .attachmentCount = 1, 1397 .pAttachments = &att_desc, 1398 .subpassCount = 1, 1399 .pSubpasses = &subpass_desc, 1400 }, 1401 &cmd_buffer->pool->alloc, 1402 &pass); 1403 1404 radv_CmdBeginRenderPass(radv_cmd_buffer_to_handle(cmd_buffer), 1405 &(VkRenderPassBeginInfo) { 1406 .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, 1407 .renderArea = { 1408 .offset = { 0, 0, }, 1409 .extent = { 1410 .width = width, 1411 .height = height, 1412 }, 1413 }, 1414 .renderPass = pass, 1415 .framebuffer = fb, 1416 .clearValueCount = 0, 1417 .pClearValues = NULL, 1418 }, 1419 VK_SUBPASS_CONTENTS_INLINE); 1420 1421 VkClearAttachment clear_att = { 1422 .aspectMask = range->aspectMask, 1423 .colorAttachment = 0, 1424 .clearValue = *clear_val, 1425 }; 1426 1427 VkClearRect clear_rect = { 1428 .rect = { 1429 .offset = { 0, 0 }, 1430 .extent = { width, height }, 1431 }, 1432 .baseArrayLayer = range->baseArrayLayer, 1433 .layerCount = 1, /* FINISHME: clear multi-layer framebuffer */ 1434 }; 1435 1436 emit_clear(cmd_buffer, &clear_att, &clear_rect, NULL, NULL, 0); 1437 1438 radv_CmdEndRenderPass(radv_cmd_buffer_to_handle(cmd_buffer)); 1439 radv_DestroyRenderPass(device_h, pass, 1440 &cmd_buffer->pool->alloc); 1441 radv_DestroyFramebuffer(device_h, fb, 1442 &cmd_buffer->pool->alloc); 1443} 1444static void 1445radv_cmd_clear_image(struct radv_cmd_buffer *cmd_buffer, 1446 struct radv_image *image, 1447 VkImageLayout image_layout, 1448 const VkClearValue *clear_value, 1449 uint32_t range_count, 1450 const VkImageSubresourceRange *ranges, 1451 bool cs) 1452{ 1453 VkFormat format = image->vk_format; 1454 VkClearValue internal_clear_value = *clear_value; 1455 1456 if (format == VK_FORMAT_E5B9G9R9_UFLOAT_PACK32) { 1457 uint32_t value; 1458 format = VK_FORMAT_R32_UINT; 1459 value = float3_to_rgb9e5(clear_value->color.float32); 1460 internal_clear_value.color.uint32[0] = value; 1461 } 1462 1463 if (format == VK_FORMAT_R4G4_UNORM_PACK8) { 1464 uint8_t r, g; 1465 format = VK_FORMAT_R8_UINT; 1466 r = float_to_ubyte(clear_value->color.float32[0]) >> 4; 1467 g = float_to_ubyte(clear_value->color.float32[1]) >> 4; 1468 internal_clear_value.color.uint32[0] = (r << 4) | (g & 0xf); 1469 } 1470 1471 for (uint32_t r = 0; r < range_count; r++) { 1472 const VkImageSubresourceRange *range = &ranges[r]; 1473 for (uint32_t l = 0; l < radv_get_levelCount(image, range); ++l) { 1474 const uint32_t layer_count = image->type == VK_IMAGE_TYPE_3D ? 1475 radv_minify(image->info.depth, range->baseMipLevel + l) : 1476 radv_get_layerCount(image, range); 1477 for (uint32_t s = 0; s < layer_count; ++s) { 1478 1479 if (cs || 1480 (format == VK_FORMAT_R32G32B32_UINT || 1481 format == VK_FORMAT_R32G32B32_SINT || 1482 format == VK_FORMAT_R32G32B32_SFLOAT)) { 1483 struct radv_meta_blit2d_surf surf; 1484 surf.format = format; 1485 surf.image = image; 1486 surf.level = range->baseMipLevel + l; 1487 surf.layer = range->baseArrayLayer + s; 1488 surf.aspect_mask = range->aspectMask; 1489 radv_meta_clear_image_cs(cmd_buffer, &surf, 1490 &internal_clear_value.color); 1491 } else { 1492 radv_clear_image_layer(cmd_buffer, image, image_layout, 1493 range, format, l, s, &internal_clear_value); 1494 } 1495 } 1496 } 1497 } 1498} 1499 1500void radv_CmdClearColorImage( 1501 VkCommandBuffer commandBuffer, 1502 VkImage image_h, 1503 VkImageLayout imageLayout, 1504 const VkClearColorValue* pColor, 1505 uint32_t rangeCount, 1506 const VkImageSubresourceRange* pRanges) 1507{ 1508 RADV_FROM_HANDLE(radv_cmd_buffer, cmd_buffer, commandBuffer); 1509 RADV_FROM_HANDLE(radv_image, image, image_h); 1510 struct radv_meta_saved_state saved_state; 1511 bool cs = cmd_buffer->queue_family_index == RADV_QUEUE_COMPUTE; 1512 1513 if (cs) { 1514 radv_meta_save(&saved_state, cmd_buffer, 1515 RADV_META_SAVE_COMPUTE_PIPELINE | 1516 RADV_META_SAVE_CONSTANTS | 1517 RADV_META_SAVE_DESCRIPTORS); 1518 } else { 1519 radv_meta_save(&saved_state, cmd_buffer, 1520 RADV_META_SAVE_GRAPHICS_PIPELINE | 1521 RADV_META_SAVE_CONSTANTS); 1522 } 1523 1524 radv_cmd_clear_image(cmd_buffer, image, imageLayout, 1525 (const VkClearValue *) pColor, 1526 rangeCount, pRanges, cs); 1527 1528 radv_meta_restore(&saved_state, cmd_buffer); 1529} 1530 1531void radv_CmdClearDepthStencilImage( 1532 VkCommandBuffer commandBuffer, 1533 VkImage image_h, 1534 VkImageLayout imageLayout, 1535 const VkClearDepthStencilValue* pDepthStencil, 1536 uint32_t rangeCount, 1537 const VkImageSubresourceRange* pRanges) 1538{ 1539 RADV_FROM_HANDLE(radv_cmd_buffer, cmd_buffer, commandBuffer); 1540 RADV_FROM_HANDLE(radv_image, image, image_h); 1541 struct radv_meta_saved_state saved_state; 1542 1543 radv_meta_save(&saved_state, cmd_buffer, 1544 RADV_META_SAVE_GRAPHICS_PIPELINE | 1545 RADV_META_SAVE_CONSTANTS); 1546 1547 radv_cmd_clear_image(cmd_buffer, image, imageLayout, 1548 (const VkClearValue *) pDepthStencil, 1549 rangeCount, pRanges, false); 1550 1551 radv_meta_restore(&saved_state, cmd_buffer); 1552} 1553 1554void radv_CmdClearAttachments( 1555 VkCommandBuffer commandBuffer, 1556 uint32_t attachmentCount, 1557 const VkClearAttachment* pAttachments, 1558 uint32_t rectCount, 1559 const VkClearRect* pRects) 1560{ 1561 RADV_FROM_HANDLE(radv_cmd_buffer, cmd_buffer, commandBuffer); 1562 struct radv_meta_saved_state saved_state; 1563 enum radv_cmd_flush_bits pre_flush = 0; 1564 enum radv_cmd_flush_bits post_flush = 0; 1565 1566 if (!cmd_buffer->state.subpass) 1567 return; 1568 1569 radv_meta_save(&saved_state, cmd_buffer, 1570 RADV_META_SAVE_GRAPHICS_PIPELINE | 1571 RADV_META_SAVE_CONSTANTS); 1572 1573 /* FINISHME: We can do better than this dumb loop. It thrashes too much 1574 * state. 1575 */ 1576 for (uint32_t a = 0; a < attachmentCount; ++a) { 1577 for (uint32_t r = 0; r < rectCount; ++r) { 1578 emit_clear(cmd_buffer, &pAttachments[a], &pRects[r], &pre_flush, &post_flush, 1579 cmd_buffer->state.subpass->view_mask); 1580 } 1581 } 1582 1583 radv_meta_restore(&saved_state, cmd_buffer); 1584 cmd_buffer->state.flush_bits |= post_flush; 1585} 1586