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 32 enum { 33 DEPTH_CLEAR_SLOW, 34 DEPTH_CLEAR_FAST_EXPCLEAR, 35 DEPTH_CLEAR_FAST_NO_EXPCLEAR 36 }; 37 38 static void 39 build_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 94 static VkResult 95 create_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 197 static VkResult 198 create_color_renderpass(struct radv_device *device, 199 VkFormat vk_format, 200 uint32_t samples, 201 VkRenderPass *pass) 202 { 203 return radv_CreateRenderPass(radv_device_to_handle(device), 204 &(VkRenderPassCreateInfo) { 205 .sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, 206 .attachmentCount = 1, 207 .pAttachments = &(VkAttachmentDescription) { 208 .format = vk_format, 209 .samples = samples, 210 .loadOp = VK_ATTACHMENT_LOAD_OP_LOAD, 211 .storeOp = VK_ATTACHMENT_STORE_OP_STORE, 212 .initialLayout = VK_IMAGE_LAYOUT_GENERAL, 213 .finalLayout = VK_IMAGE_LAYOUT_GENERAL, 214 }, 215 .subpassCount = 1, 216 .pSubpasses = &(VkSubpassDescription) { 217 .pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS, 218 .inputAttachmentCount = 0, 219 .colorAttachmentCount = 1, 220 .pColorAttachments = &(VkAttachmentReference) { 221 .attachment = 0, 222 .layout = VK_IMAGE_LAYOUT_GENERAL, 223 }, 224 .pResolveAttachments = NULL, 225 .pDepthStencilAttachment = &(VkAttachmentReference) { 226 .attachment = VK_ATTACHMENT_UNUSED, 227 .layout = VK_IMAGE_LAYOUT_GENERAL, 228 }, 229 .preserveAttachmentCount = 1, 230 .pPreserveAttachments = (uint32_t[]) { 0 }, 231 }, 232 .dependencyCount = 0, 233 }, &device->meta_state.alloc, pass); 234 } 235 236 static VkResult 237 create_color_pipeline(struct radv_device *device, 238 uint32_t samples, 239 uint32_t frag_output, 240 VkPipeline *pipeline, 241 VkRenderPass pass) 242 { 243 struct nir_shader *vs_nir; 244 struct nir_shader *fs_nir; 245 VkResult result; 246 build_color_shaders(&vs_nir, &fs_nir, frag_output); 247 248 const VkPipelineVertexInputStateCreateInfo vi_state = { 249 .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, 250 .vertexBindingDescriptionCount = 0, 251 .vertexAttributeDescriptionCount = 0, 252 }; 253 254 const VkPipelineDepthStencilStateCreateInfo ds_state = { 255 .sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, 256 .depthTestEnable = false, 257 .depthWriteEnable = false, 258 .depthBoundsTestEnable = false, 259 .stencilTestEnable = false, 260 }; 261 262 VkPipelineColorBlendAttachmentState blend_attachment_state[MAX_RTS] = { 0 }; 263 blend_attachment_state[frag_output] = (VkPipelineColorBlendAttachmentState) { 264 .blendEnable = false, 265 .colorWriteMask = VK_COLOR_COMPONENT_A_BIT | 266 VK_COLOR_COMPONENT_R_BIT | 267 VK_COLOR_COMPONENT_G_BIT | 268 VK_COLOR_COMPONENT_B_BIT, 269 }; 270 271 const VkPipelineColorBlendStateCreateInfo cb_state = { 272 .sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, 273 .logicOpEnable = false, 274 .attachmentCount = MAX_RTS, 275 .pAttachments = blend_attachment_state 276 }; 277 278 279 struct radv_graphics_pipeline_create_info extra = { 280 .use_rectlist = true, 281 }; 282 result = create_pipeline(device, radv_render_pass_from_handle(pass), 283 samples, vs_nir, fs_nir, &vi_state, &ds_state, &cb_state, 284 device->meta_state.clear_color_p_layout, 285 &extra, &device->meta_state.alloc, pipeline); 286 287 return result; 288 } 289 290 void 291 radv_device_finish_meta_clear_state(struct radv_device *device) 292 { 293 struct radv_meta_state *state = &device->meta_state; 294 295 for (uint32_t i = 0; i < ARRAY_SIZE(state->clear); ++i) { 296 for (uint32_t j = 0; j < ARRAY_SIZE(state->clear[i].color_pipelines); ++j) { 297 radv_DestroyPipeline(radv_device_to_handle(device), 298 state->clear[i].color_pipelines[j], 299 &state->alloc); 300 radv_DestroyRenderPass(radv_device_to_handle(device), 301 state->clear[i].render_pass[j], 302 &state->alloc); 303 } 304 305 for (uint32_t j = 0; j < NUM_DEPTH_CLEAR_PIPELINES; j++) { 306 radv_DestroyPipeline(radv_device_to_handle(device), 307 state->clear[i].depth_only_pipeline[j], 308 &state->alloc); 309 radv_DestroyPipeline(radv_device_to_handle(device), 310 state->clear[i].stencil_only_pipeline[j], 311 &state->alloc); 312 radv_DestroyPipeline(radv_device_to_handle(device), 313 state->clear[i].depthstencil_pipeline[j], 314 &state->alloc); 315 } 316 radv_DestroyRenderPass(radv_device_to_handle(device), 317 state->clear[i].depthstencil_rp, 318 &state->alloc); 319 } 320 radv_DestroyPipelineLayout(radv_device_to_handle(device), 321 state->clear_color_p_layout, 322 &state->alloc); 323 radv_DestroyPipelineLayout(radv_device_to_handle(device), 324 state->clear_depth_p_layout, 325 &state->alloc); 326 } 327 328 static void 329 emit_color_clear(struct radv_cmd_buffer *cmd_buffer, 330 const VkClearAttachment *clear_att, 331 const VkClearRect *clear_rect, 332 uint32_t view_mask) 333 { 334 struct radv_device *device = cmd_buffer->device; 335 const struct radv_subpass *subpass = cmd_buffer->state.subpass; 336 const struct radv_framebuffer *fb = cmd_buffer->state.framebuffer; 337 const uint32_t subpass_att = clear_att->colorAttachment; 338 const uint32_t pass_att = subpass->color_attachments[subpass_att].attachment; 339 const struct radv_image_view *iview = fb->attachments[pass_att].attachment; 340 const uint32_t samples = iview->image->info.samples; 341 const uint32_t samples_log2 = ffs(samples) - 1; 342 unsigned fs_key = radv_format_meta_fs_key(iview->vk_format); 343 VkClearColorValue clear_value = clear_att->clearValue.color; 344 VkCommandBuffer cmd_buffer_h = radv_cmd_buffer_to_handle(cmd_buffer); 345 VkPipeline pipeline; 346 347 if (fs_key == -1) { 348 radv_finishme("color clears incomplete"); 349 return; 350 } 351 352 pipeline = device->meta_state.clear[samples_log2].color_pipelines[fs_key]; 353 if (!pipeline) { 354 radv_finishme("color clears incomplete"); 355 return; 356 } 357 assert(samples_log2 < ARRAY_SIZE(device->meta_state.clear)); 358 assert(pipeline); 359 assert(clear_att->aspectMask == VK_IMAGE_ASPECT_COLOR_BIT); 360 assert(clear_att->colorAttachment < subpass->color_count); 361 362 radv_CmdPushConstants(radv_cmd_buffer_to_handle(cmd_buffer), 363 device->meta_state.clear_color_p_layout, 364 VK_SHADER_STAGE_FRAGMENT_BIT, 0, 16, 365 &clear_value); 366 367 struct radv_subpass clear_subpass = { 368 .color_count = 1, 369 .color_attachments = (VkAttachmentReference[]) { 370 subpass->color_attachments[clear_att->colorAttachment] 371 }, 372 .depth_stencil_attachment = (VkAttachmentReference) { VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_UNDEFINED } 373 }; 374 375 radv_cmd_buffer_set_subpass(cmd_buffer, &clear_subpass, false); 376 377 radv_CmdBindPipeline(cmd_buffer_h, VK_PIPELINE_BIND_POINT_GRAPHICS, 378 pipeline); 379 380 radv_CmdSetViewport(radv_cmd_buffer_to_handle(cmd_buffer), 0, 1, &(VkViewport) { 381 .x = clear_rect->rect.offset.x, 382 .y = clear_rect->rect.offset.y, 383 .width = clear_rect->rect.extent.width, 384 .height = clear_rect->rect.extent.height, 385 .minDepth = 0.0f, 386 .maxDepth = 1.0f 387 }); 388 389 radv_CmdSetScissor(radv_cmd_buffer_to_handle(cmd_buffer), 0, 1, &clear_rect->rect); 390 391 if (view_mask) { 392 unsigned i; 393 for_each_bit(i, view_mask) 394 radv_CmdDraw(cmd_buffer_h, 3, 1, 0, i); 395 } else { 396 radv_CmdDraw(cmd_buffer_h, 3, clear_rect->layerCount, 0, clear_rect->baseArrayLayer); 397 } 398 399 radv_cmd_buffer_set_subpass(cmd_buffer, subpass, false); 400 } 401 402 403 static void 404 build_depthstencil_shader(struct nir_shader **out_vs, struct nir_shader **out_fs) 405 { 406 nir_builder vs_b, fs_b; 407 408 nir_builder_init_simple_shader(&vs_b, NULL, MESA_SHADER_VERTEX, NULL); 409 nir_builder_init_simple_shader(&fs_b, NULL, MESA_SHADER_FRAGMENT, NULL); 410 411 vs_b.shader->info.name = ralloc_strdup(vs_b.shader, "meta_clear_depthstencil_vs"); 412 fs_b.shader->info.name = ralloc_strdup(fs_b.shader, "meta_clear_depthstencil_fs"); 413 const struct glsl_type *position_out_type = glsl_vec4_type(); 414 415 nir_variable *vs_out_pos = 416 nir_variable_create(vs_b.shader, nir_var_shader_out, position_out_type, 417 "gl_Position"); 418 vs_out_pos->data.location = VARYING_SLOT_POS; 419 420 nir_intrinsic_instr *in_color_load = nir_intrinsic_instr_create(vs_b.shader, nir_intrinsic_load_push_constant); 421 nir_intrinsic_set_base(in_color_load, 0); 422 nir_intrinsic_set_range(in_color_load, 4); 423 in_color_load->src[0] = nir_src_for_ssa(nir_imm_int(&vs_b, 0)); 424 in_color_load->num_components = 1; 425 nir_ssa_dest_init(&in_color_load->instr, &in_color_load->dest, 1, 32, "depth value"); 426 nir_builder_instr_insert(&vs_b, &in_color_load->instr); 427 428 nir_ssa_def *outvec = radv_meta_gen_rect_vertices_comp2(&vs_b, &in_color_load->dest.ssa); 429 nir_store_var(&vs_b, vs_out_pos, outvec, 0xf); 430 431 const struct glsl_type *layer_type = glsl_int_type(); 432 nir_variable *vs_out_layer = 433 nir_variable_create(vs_b.shader, nir_var_shader_out, layer_type, 434 "v_layer"); 435 vs_out_layer->data.location = VARYING_SLOT_LAYER; 436 vs_out_layer->data.interpolation = INTERP_MODE_FLAT; 437 nir_ssa_def *inst_id = nir_load_system_value(&vs_b, nir_intrinsic_load_instance_id, 0); 438 nir_ssa_def *base_instance = nir_load_system_value(&vs_b, nir_intrinsic_load_base_instance, 0); 439 440 nir_ssa_def *layer_id = nir_iadd(&vs_b, inst_id, base_instance); 441 nir_store_var(&vs_b, vs_out_layer, layer_id, 0x1); 442 443 *out_vs = vs_b.shader; 444 *out_fs = fs_b.shader; 445 } 446 447 static VkResult 448 create_depthstencil_renderpass(struct radv_device *device, 449 uint32_t samples, 450 VkRenderPass *render_pass) 451 { 452 return radv_CreateRenderPass(radv_device_to_handle(device), 453 &(VkRenderPassCreateInfo) { 454 .sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, 455 .attachmentCount = 1, 456 .pAttachments = &(VkAttachmentDescription) { 457 .format = VK_FORMAT_D32_SFLOAT_S8_UINT, 458 .samples = samples, 459 .loadOp = VK_ATTACHMENT_LOAD_OP_LOAD, 460 .storeOp = VK_ATTACHMENT_STORE_OP_STORE, 461 .initialLayout = VK_IMAGE_LAYOUT_GENERAL, 462 .finalLayout = VK_IMAGE_LAYOUT_GENERAL, 463 }, 464 .subpassCount = 1, 465 .pSubpasses = &(VkSubpassDescription) { 466 .pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS, 467 .inputAttachmentCount = 0, 468 .colorAttachmentCount = 0, 469 .pColorAttachments = NULL, 470 .pResolveAttachments = NULL, 471 .pDepthStencilAttachment = &(VkAttachmentReference) { 472 .attachment = 0, 473 .layout = VK_IMAGE_LAYOUT_GENERAL, 474 }, 475 .preserveAttachmentCount = 1, 476 .pPreserveAttachments = (uint32_t[]) { 0 }, 477 }, 478 .dependencyCount = 0, 479 }, &device->meta_state.alloc, render_pass); 480 } 481 482 static VkResult 483 create_depthstencil_pipeline(struct radv_device *device, 484 VkImageAspectFlags aspects, 485 uint32_t samples, 486 int index, 487 VkPipeline *pipeline, 488 VkRenderPass render_pass) 489 { 490 struct nir_shader *vs_nir, *fs_nir; 491 VkResult result; 492 build_depthstencil_shader(&vs_nir, &fs_nir); 493 494 const VkPipelineVertexInputStateCreateInfo vi_state = { 495 .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, 496 .vertexBindingDescriptionCount = 0, 497 .vertexAttributeDescriptionCount = 0, 498 }; 499 500 const VkPipelineDepthStencilStateCreateInfo ds_state = { 501 .sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, 502 .depthTestEnable = (aspects & VK_IMAGE_ASPECT_DEPTH_BIT), 503 .depthCompareOp = VK_COMPARE_OP_ALWAYS, 504 .depthWriteEnable = (aspects & VK_IMAGE_ASPECT_DEPTH_BIT), 505 .depthBoundsTestEnable = false, 506 .stencilTestEnable = (aspects & VK_IMAGE_ASPECT_STENCIL_BIT), 507 .front = { 508 .passOp = VK_STENCIL_OP_REPLACE, 509 .compareOp = VK_COMPARE_OP_ALWAYS, 510 .writeMask = UINT32_MAX, 511 .reference = 0, /* dynamic */ 512 }, 513 .back = { 0 /* dont care */ }, 514 }; 515 516 const VkPipelineColorBlendStateCreateInfo cb_state = { 517 .sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, 518 .logicOpEnable = false, 519 .attachmentCount = 0, 520 .pAttachments = NULL, 521 }; 522 523 struct radv_graphics_pipeline_create_info extra = { 524 .use_rectlist = true, 525 }; 526 527 if (aspects & VK_IMAGE_ASPECT_DEPTH_BIT) { 528 extra.db_depth_clear = index == DEPTH_CLEAR_SLOW ? false : true; 529 extra.db_depth_disable_expclear = index == DEPTH_CLEAR_FAST_NO_EXPCLEAR ? true : false; 530 } 531 if (aspects & VK_IMAGE_ASPECT_STENCIL_BIT) { 532 extra.db_stencil_clear = index == DEPTH_CLEAR_SLOW ? false : true; 533 extra.db_stencil_disable_expclear = index == DEPTH_CLEAR_FAST_NO_EXPCLEAR ? true : false; 534 } 535 result = create_pipeline(device, radv_render_pass_from_handle(render_pass), 536 samples, vs_nir, fs_nir, &vi_state, &ds_state, &cb_state, 537 device->meta_state.clear_depth_p_layout, 538 &extra, &device->meta_state.alloc, pipeline); 539 return result; 540 } 541 542 static bool depth_view_can_fast_clear(struct radv_cmd_buffer *cmd_buffer, 543 const struct radv_image_view *iview, 544 VkImageAspectFlags aspects, 545 VkImageLayout layout, 546 const VkClearRect *clear_rect, 547 VkClearDepthStencilValue clear_value) 548 { 549 uint32_t queue_mask = radv_image_queue_family_mask(iview->image, 550 cmd_buffer->queue_family_index, 551 cmd_buffer->queue_family_index); 552 if (clear_rect->rect.offset.x || clear_rect->rect.offset.y || 553 clear_rect->rect.extent.width != iview->extent.width || 554 clear_rect->rect.extent.height != iview->extent.height) 555 return false; 556 if (iview->image->tc_compatible_htile && 557 (((aspects & VK_IMAGE_ASPECT_DEPTH_BIT) && clear_value.depth != 0.0 && 558 clear_value.depth != 1.0) || 559 ((aspects & VK_IMAGE_ASPECT_STENCIL_BIT) && clear_value.stencil != 0))) 560 return false; 561 if (iview->image->surface.htile_size && 562 iview->base_mip == 0 && 563 iview->base_layer == 0 && 564 radv_layout_is_htile_compressed(iview->image, layout, queue_mask) && 565 !radv_image_extent_compare(iview->image, &iview->extent)) 566 return true; 567 return false; 568 } 569 570 static VkPipeline 571 pick_depthstencil_pipeline(struct radv_cmd_buffer *cmd_buffer, 572 struct radv_meta_state *meta_state, 573 const struct radv_image_view *iview, 574 int samples_log2, 575 VkImageAspectFlags aspects, 576 VkImageLayout layout, 577 const VkClearRect *clear_rect, 578 VkClearDepthStencilValue clear_value) 579 { 580 bool fast = depth_view_can_fast_clear(cmd_buffer, iview, aspects, layout, clear_rect, clear_value); 581 int index = DEPTH_CLEAR_SLOW; 582 583 if (fast) { 584 /* we don't know the previous clear values, so we always have 585 * the NO_EXPCLEAR path */ 586 index = DEPTH_CLEAR_FAST_NO_EXPCLEAR; 587 } 588 589 switch (aspects) { 590 case VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT: 591 return meta_state->clear[samples_log2].depthstencil_pipeline[index]; 592 case VK_IMAGE_ASPECT_DEPTH_BIT: 593 return meta_state->clear[samples_log2].depth_only_pipeline[index]; 594 case VK_IMAGE_ASPECT_STENCIL_BIT: 595 return meta_state->clear[samples_log2].stencil_only_pipeline[index]; 596 } 597 unreachable("expected depth or stencil aspect"); 598 } 599 600 static void 601 emit_depthstencil_clear(struct radv_cmd_buffer *cmd_buffer, 602 const VkClearAttachment *clear_att, 603 const VkClearRect *clear_rect) 604 { 605 struct radv_device *device = cmd_buffer->device; 606 struct radv_meta_state *meta_state = &device->meta_state; 607 const struct radv_subpass *subpass = cmd_buffer->state.subpass; 608 const struct radv_framebuffer *fb = cmd_buffer->state.framebuffer; 609 const uint32_t pass_att = subpass->depth_stencil_attachment.attachment; 610 VkClearDepthStencilValue clear_value = clear_att->clearValue.depthStencil; 611 VkImageAspectFlags aspects = clear_att->aspectMask; 612 const struct radv_image_view *iview = fb->attachments[pass_att].attachment; 613 const uint32_t samples = iview->image->info.samples; 614 const uint32_t samples_log2 = ffs(samples) - 1; 615 VkCommandBuffer cmd_buffer_h = radv_cmd_buffer_to_handle(cmd_buffer); 616 617 assert(pass_att != VK_ATTACHMENT_UNUSED); 618 619 if (!(aspects & VK_IMAGE_ASPECT_DEPTH_BIT)) 620 clear_value.depth = 1.0f; 621 622 radv_CmdPushConstants(radv_cmd_buffer_to_handle(cmd_buffer), 623 device->meta_state.clear_depth_p_layout, 624 VK_SHADER_STAGE_VERTEX_BIT, 0, 4, 625 &clear_value.depth); 626 627 uint32_t prev_reference = cmd_buffer->state.dynamic.stencil_reference.front; 628 if (aspects & VK_IMAGE_ASPECT_STENCIL_BIT) { 629 radv_CmdSetStencilReference(cmd_buffer_h, VK_STENCIL_FACE_FRONT_BIT, 630 clear_value.stencil); 631 } 632 633 VkPipeline pipeline = pick_depthstencil_pipeline(cmd_buffer, 634 meta_state, 635 iview, 636 samples_log2, 637 aspects, 638 subpass->depth_stencil_attachment.layout, 639 clear_rect, 640 clear_value); 641 642 radv_CmdBindPipeline(cmd_buffer_h, VK_PIPELINE_BIND_POINT_GRAPHICS, 643 pipeline); 644 645 if (depth_view_can_fast_clear(cmd_buffer, iview, aspects, 646 subpass->depth_stencil_attachment.layout, 647 clear_rect, clear_value)) 648 radv_set_depth_clear_regs(cmd_buffer, iview->image, clear_value, aspects); 649 650 radv_CmdSetViewport(radv_cmd_buffer_to_handle(cmd_buffer), 0, 1, &(VkViewport) { 651 .x = clear_rect->rect.offset.x, 652 .y = clear_rect->rect.offset.y, 653 .width = clear_rect->rect.extent.width, 654 .height = clear_rect->rect.extent.height, 655 .minDepth = 0.0f, 656 .maxDepth = 1.0f 657 }); 658 659 radv_CmdSetScissor(radv_cmd_buffer_to_handle(cmd_buffer), 0, 1, &clear_rect->rect); 660 661 radv_CmdDraw(cmd_buffer_h, 3, clear_rect->layerCount, 0, clear_rect->baseArrayLayer); 662 663 if (aspects & VK_IMAGE_ASPECT_STENCIL_BIT) { 664 radv_CmdSetStencilReference(cmd_buffer_h, VK_STENCIL_FACE_FRONT_BIT, 665 prev_reference); 666 } 667 } 668 669 static bool 670 emit_fast_htile_clear(struct radv_cmd_buffer *cmd_buffer, 671 const VkClearAttachment *clear_att, 672 const VkClearRect *clear_rect, 673 enum radv_cmd_flush_bits *pre_flush, 674 enum radv_cmd_flush_bits *post_flush) 675 { 676 const struct radv_subpass *subpass = cmd_buffer->state.subpass; 677 const uint32_t pass_att = subpass->depth_stencil_attachment.attachment; 678 VkImageLayout image_layout = subpass->depth_stencil_attachment.layout; 679 const struct radv_framebuffer *fb = cmd_buffer->state.framebuffer; 680 const struct radv_image_view *iview = fb->attachments[pass_att].attachment; 681 VkClearDepthStencilValue clear_value = clear_att->clearValue.depthStencil; 682 VkImageAspectFlags aspects = clear_att->aspectMask; 683 uint32_t clear_word, flush_bits; 684 685 if (!iview->image->surface.htile_size) 686 return false; 687 688 if (cmd_buffer->device->instance->debug_flags & RADV_DEBUG_NO_FAST_CLEARS) 689 return false; 690 691 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))) 692 goto fail; 693 694 /* don't fast clear 3D */ 695 if (iview->image->type == VK_IMAGE_TYPE_3D) 696 goto fail; 697 698 /* all layers are bound */ 699 if (iview->base_layer > 0) 700 goto fail; 701 if (iview->image->info.array_size != iview->layer_count) 702 goto fail; 703 704 if (!radv_image_extent_compare(iview->image, &iview->extent)) 705 goto fail; 706 707 if (clear_rect->rect.offset.x || clear_rect->rect.offset.y || 708 clear_rect->rect.extent.width != iview->image->info.width || 709 clear_rect->rect.extent.height != iview->image->info.height) 710 goto fail; 711 712 if (clear_rect->baseArrayLayer != 0) 713 goto fail; 714 if (clear_rect->layerCount != iview->image->info.array_size) 715 goto fail; 716 717 if ((clear_value.depth != 0.0 && clear_value.depth != 1.0) || !(aspects & VK_IMAGE_ASPECT_DEPTH_BIT)) 718 goto fail; 719 720 if (vk_format_aspects(iview->image->vk_format) & VK_IMAGE_ASPECT_STENCIL_BIT) { 721 if (clear_value.stencil != 0 || !(aspects & VK_IMAGE_ASPECT_STENCIL_BIT)) 722 goto fail; 723 clear_word = clear_value.depth ? 0xfffc0000 : 0; 724 } else 725 clear_word = clear_value.depth ? 0xfffffff0 : 0; 726 727 if (pre_flush) { 728 cmd_buffer->state.flush_bits |= (RADV_CMD_FLAG_FLUSH_AND_INV_DB | 729 RADV_CMD_FLAG_FLUSH_AND_INV_DB_META) & ~ *pre_flush; 730 *pre_flush |= cmd_buffer->state.flush_bits; 731 } else 732 cmd_buffer->state.flush_bits |= RADV_CMD_FLAG_FLUSH_AND_INV_DB | 733 RADV_CMD_FLAG_FLUSH_AND_INV_DB_META; 734 735 flush_bits = radv_fill_buffer(cmd_buffer, iview->image->bo, 736 iview->image->offset + iview->image->htile_offset, 737 iview->image->surface.htile_size, clear_word); 738 739 radv_set_depth_clear_regs(cmd_buffer, iview->image, clear_value, aspects); 740 if (post_flush) { 741 *post_flush |= flush_bits; 742 } else { 743 cmd_buffer->state.flush_bits |= flush_bits; 744 } 745 746 return true; 747 fail: 748 return false; 749 } 750 751 static VkFormat pipeline_formats[] = { 752 VK_FORMAT_R8G8B8A8_UNORM, 753 VK_FORMAT_R8G8B8A8_UINT, 754 VK_FORMAT_R8G8B8A8_SINT, 755 VK_FORMAT_A2R10G10B10_UINT_PACK32, 756 VK_FORMAT_A2R10G10B10_SINT_PACK32, 757 VK_FORMAT_R16G16B16A16_UNORM, 758 VK_FORMAT_R16G16B16A16_SNORM, 759 VK_FORMAT_R16G16B16A16_UINT, 760 VK_FORMAT_R16G16B16A16_SINT, 761 VK_FORMAT_R32_SFLOAT, 762 VK_FORMAT_R32G32_SFLOAT, 763 VK_FORMAT_R32G32B32A32_SFLOAT 764 }; 765 766 VkResult 767 radv_device_init_meta_clear_state(struct radv_device *device) 768 { 769 VkResult res; 770 struct radv_meta_state *state = &device->meta_state; 771 772 VkPipelineLayoutCreateInfo pl_color_create_info = { 773 .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, 774 .setLayoutCount = 0, 775 .pushConstantRangeCount = 1, 776 .pPushConstantRanges = &(VkPushConstantRange){VK_SHADER_STAGE_FRAGMENT_BIT, 0, 16}, 777 }; 778 779 res = radv_CreatePipelineLayout(radv_device_to_handle(device), 780 &pl_color_create_info, 781 &device->meta_state.alloc, 782 &device->meta_state.clear_color_p_layout); 783 if (res != VK_SUCCESS) 784 goto fail; 785 786 VkPipelineLayoutCreateInfo pl_depth_create_info = { 787 .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, 788 .setLayoutCount = 0, 789 .pushConstantRangeCount = 1, 790 .pPushConstantRanges = &(VkPushConstantRange){VK_SHADER_STAGE_VERTEX_BIT, 0, 4}, 791 }; 792 793 res = radv_CreatePipelineLayout(radv_device_to_handle(device), 794 &pl_depth_create_info, 795 &device->meta_state.alloc, 796 &device->meta_state.clear_depth_p_layout); 797 if (res != VK_SUCCESS) 798 goto fail; 799 800 for (uint32_t i = 0; i < ARRAY_SIZE(state->clear); ++i) { 801 uint32_t samples = 1 << i; 802 for (uint32_t j = 0; j < ARRAY_SIZE(pipeline_formats); ++j) { 803 VkFormat format = pipeline_formats[j]; 804 unsigned fs_key = radv_format_meta_fs_key(format); 805 assert(!state->clear[i].color_pipelines[fs_key]); 806 807 res = create_color_renderpass(device, format, samples, 808 &state->clear[i].render_pass[fs_key]); 809 if (res != VK_SUCCESS) 810 goto fail; 811 812 res = create_color_pipeline(device, samples, 0, &state->clear[i].color_pipelines[fs_key], 813 state->clear[i].render_pass[fs_key]); 814 if (res != VK_SUCCESS) 815 goto fail; 816 817 } 818 819 res = create_depthstencil_renderpass(device, 820 samples, 821 &state->clear[i].depthstencil_rp); 822 if (res != VK_SUCCESS) 823 goto fail; 824 825 for (uint32_t j = 0; j < NUM_DEPTH_CLEAR_PIPELINES; j++) { 826 res = create_depthstencil_pipeline(device, 827 VK_IMAGE_ASPECT_DEPTH_BIT, 828 samples, 829 j, 830 &state->clear[i].depth_only_pipeline[j], 831 state->clear[i].depthstencil_rp); 832 if (res != VK_SUCCESS) 833 goto fail; 834 835 res = create_depthstencil_pipeline(device, 836 VK_IMAGE_ASPECT_STENCIL_BIT, 837 samples, 838 j, 839 &state->clear[i].stencil_only_pipeline[j], 840 state->clear[i].depthstencil_rp); 841 if (res != VK_SUCCESS) 842 goto fail; 843 844 res = create_depthstencil_pipeline(device, 845 VK_IMAGE_ASPECT_DEPTH_BIT | 846 VK_IMAGE_ASPECT_STENCIL_BIT, 847 samples, 848 j, 849 &state->clear[i].depthstencil_pipeline[j], 850 state->clear[i].depthstencil_rp); 851 if (res != VK_SUCCESS) 852 goto fail; 853 } 854 } 855 return VK_SUCCESS; 856 857 fail: 858 radv_device_finish_meta_clear_state(device); 859 return res; 860 } 861 862 static void vi_get_fast_clear_parameters(VkFormat format, 863 const VkClearColorValue *clear_value, 864 uint32_t* reset_value, 865 bool *can_avoid_fast_clear_elim) 866 { 867 bool values[4] = {}; 868 int extra_channel; 869 bool main_value = false; 870 bool extra_value = false; 871 int i; 872 *can_avoid_fast_clear_elim = false; 873 874 *reset_value = 0x20202020U; 875 876 const struct vk_format_description *desc = vk_format_description(format); 877 if (format == VK_FORMAT_B10G11R11_UFLOAT_PACK32 || 878 format == VK_FORMAT_R5G6B5_UNORM_PACK16 || 879 format == VK_FORMAT_B5G6R5_UNORM_PACK16) 880 extra_channel = -1; 881 else if (desc->layout == VK_FORMAT_LAYOUT_PLAIN) { 882 if (radv_translate_colorswap(format, false) <= 1) 883 extra_channel = desc->nr_channels - 1; 884 else 885 extra_channel = 0; 886 } else 887 return; 888 889 for (i = 0; i < 4; i++) { 890 int index = desc->swizzle[i] - VK_SWIZZLE_X; 891 if (desc->swizzle[i] < VK_SWIZZLE_X || 892 desc->swizzle[i] > VK_SWIZZLE_W) 893 continue; 894 895 if (desc->channel[i].pure_integer && 896 desc->channel[i].type == VK_FORMAT_TYPE_SIGNED) { 897 /* Use the maximum value for clamping the clear color. */ 898 int max = u_bit_consecutive(0, desc->channel[i].size - 1); 899 900 values[i] = clear_value->int32[i] != 0; 901 if (clear_value->int32[i] != 0 && MIN2(clear_value->int32[i], max) != max) 902 return; 903 } else if (desc->channel[i].pure_integer && 904 desc->channel[i].type == VK_FORMAT_TYPE_UNSIGNED) { 905 /* Use the maximum value for clamping the clear color. */ 906 unsigned max = u_bit_consecutive(0, desc->channel[i].size); 907 908 values[i] = clear_value->uint32[i] != 0U; 909 if (clear_value->uint32[i] != 0U && MIN2(clear_value->uint32[i], max) != max) 910 return; 911 } else { 912 values[i] = clear_value->float32[i] != 0.0F; 913 if (clear_value->float32[i] != 0.0F && clear_value->float32[i] != 1.0F) 914 return; 915 } 916 917 if (index == extra_channel) 918 extra_value = values[i]; 919 else 920 main_value = values[i]; 921 } 922 923 for (int i = 0; i < 4; ++i) 924 if (values[i] != main_value && 925 desc->swizzle[i] - VK_SWIZZLE_X != extra_channel && 926 desc->swizzle[i] >= VK_SWIZZLE_X && 927 desc->swizzle[i] <= VK_SWIZZLE_W) 928 return; 929 930 *can_avoid_fast_clear_elim = true; 931 if (main_value) 932 *reset_value |= 0x80808080U; 933 934 if (extra_value) 935 *reset_value |= 0x40404040U; 936 return; 937 } 938 939 static bool 940 emit_fast_color_clear(struct radv_cmd_buffer *cmd_buffer, 941 const VkClearAttachment *clear_att, 942 const VkClearRect *clear_rect, 943 enum radv_cmd_flush_bits *pre_flush, 944 enum radv_cmd_flush_bits *post_flush, 945 uint32_t view_mask) 946 { 947 const struct radv_subpass *subpass = cmd_buffer->state.subpass; 948 const uint32_t subpass_att = clear_att->colorAttachment; 949 const uint32_t pass_att = subpass->color_attachments[subpass_att].attachment; 950 VkImageLayout image_layout = subpass->color_attachments[subpass_att].layout; 951 const struct radv_framebuffer *fb = cmd_buffer->state.framebuffer; 952 const struct radv_image_view *iview = fb->attachments[pass_att].attachment; 953 VkClearColorValue clear_value = clear_att->clearValue.color; 954 uint32_t clear_color[2], flush_bits; 955 bool ret; 956 957 if (!iview->image->cmask.size && !iview->image->surface.dcc_size) 958 return false; 959 960 if (cmd_buffer->device->instance->debug_flags & RADV_DEBUG_NO_FAST_CLEARS) 961 return false; 962 963 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))) 964 goto fail; 965 966 /* don't fast clear 3D */ 967 if (iview->image->type == VK_IMAGE_TYPE_3D) 968 goto fail; 969 970 /* all layers are bound */ 971 if (iview->base_layer > 0) 972 goto fail; 973 if (iview->image->info.array_size != iview->layer_count) 974 goto fail; 975 976 if (iview->image->info.levels > 1) 977 goto fail; 978 979 if (iview->image->surface.is_linear) 980 goto fail; 981 if (!radv_image_extent_compare(iview->image, &iview->extent)) 982 goto fail; 983 984 if (clear_rect->rect.offset.x || clear_rect->rect.offset.y || 985 clear_rect->rect.extent.width != iview->image->info.width || 986 clear_rect->rect.extent.height != iview->image->info.height) 987 goto fail; 988 989 if (view_mask && (iview->image->info.array_size >= 32 || 990 (1u << iview->image->info.array_size) - 1u != view_mask)) 991 goto fail; 992 if (!view_mask && clear_rect->baseArrayLayer != 0) 993 goto fail; 994 if (!view_mask && clear_rect->layerCount != iview->image->info.array_size) 995 goto fail; 996 997 /* RB+ doesn't work with CMASK fast clear on Stoney. */ 998 if (!iview->image->surface.dcc_size && 999 cmd_buffer->device->physical_device->rad_info.family == CHIP_STONEY) 1000 goto fail; 1001 1002 /* DCC */ 1003 ret = radv_format_pack_clear_color(iview->image->vk_format, 1004 clear_color, &clear_value); 1005 if (ret == false) 1006 goto fail; 1007 1008 if (pre_flush) { 1009 cmd_buffer->state.flush_bits |= (RADV_CMD_FLAG_FLUSH_AND_INV_CB | 1010 RADV_CMD_FLAG_FLUSH_AND_INV_CB_META) & ~ *pre_flush; 1011 *pre_flush |= cmd_buffer->state.flush_bits; 1012 } else 1013 cmd_buffer->state.flush_bits |= RADV_CMD_FLAG_FLUSH_AND_INV_CB | 1014 RADV_CMD_FLAG_FLUSH_AND_INV_CB_META; 1015 /* clear cmask buffer */ 1016 if (iview->image->surface.dcc_size) { 1017 uint32_t reset_value; 1018 bool can_avoid_fast_clear_elim; 1019 vi_get_fast_clear_parameters(iview->image->vk_format, 1020 &clear_value, &reset_value, 1021 &can_avoid_fast_clear_elim); 1022 1023 flush_bits = radv_fill_buffer(cmd_buffer, iview->image->bo, 1024 iview->image->offset + iview->image->dcc_offset, 1025 iview->image->surface.dcc_size, reset_value); 1026 radv_set_dcc_need_cmask_elim_pred(cmd_buffer, iview->image, 1027 !can_avoid_fast_clear_elim); 1028 } else { 1029 flush_bits = radv_fill_buffer(cmd_buffer, iview->image->bo, 1030 iview->image->offset + iview->image->cmask.offset, 1031 iview->image->cmask.size, 0); 1032 } 1033 1034 if (post_flush) { 1035 *post_flush |= flush_bits; 1036 } else { 1037 cmd_buffer->state.flush_bits |= flush_bits; 1038 } 1039 1040 radv_set_color_clear_regs(cmd_buffer, iview->image, subpass_att, clear_color); 1041 1042 return true; 1043 fail: 1044 return false; 1045 } 1046 1047 /** 1048 * The parameters mean that same as those in vkCmdClearAttachments. 1049 */ 1050 static void 1051 emit_clear(struct radv_cmd_buffer *cmd_buffer, 1052 const VkClearAttachment *clear_att, 1053 const VkClearRect *clear_rect, 1054 enum radv_cmd_flush_bits *pre_flush, 1055 enum radv_cmd_flush_bits *post_flush, 1056 uint32_t view_mask) 1057 { 1058 if (clear_att->aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) { 1059 if (!emit_fast_color_clear(cmd_buffer, clear_att, clear_rect, 1060 pre_flush, post_flush, view_mask)) 1061 emit_color_clear(cmd_buffer, clear_att, clear_rect, view_mask); 1062 } else { 1063 assert(clear_att->aspectMask & (VK_IMAGE_ASPECT_DEPTH_BIT | 1064 VK_IMAGE_ASPECT_STENCIL_BIT)); 1065 if (!emit_fast_htile_clear(cmd_buffer, clear_att, clear_rect, 1066 pre_flush, post_flush)) 1067 emit_depthstencil_clear(cmd_buffer, clear_att, clear_rect); 1068 } 1069 } 1070 1071 static inline bool 1072 radv_attachment_needs_clear(struct radv_cmd_state *cmd_state, uint32_t a) 1073 { 1074 uint32_t view_mask = cmd_state->subpass->view_mask; 1075 return (a != VK_ATTACHMENT_UNUSED && 1076 cmd_state->attachments[a].pending_clear_aspects && 1077 (!view_mask || (view_mask & ~cmd_state->attachments[a].cleared_views))); 1078 } 1079 1080 static bool 1081 radv_subpass_needs_clear(struct radv_cmd_buffer *cmd_buffer) 1082 { 1083 struct radv_cmd_state *cmd_state = &cmd_buffer->state; 1084 uint32_t a; 1085 1086 if (!cmd_state->subpass) 1087 return false; 1088 1089 for (uint32_t i = 0; i < cmd_state->subpass->color_count; ++i) { 1090 a = cmd_state->subpass->color_attachments[i].attachment; 1091 if (radv_attachment_needs_clear(cmd_state, a)) 1092 return true; 1093 } 1094 1095 a = cmd_state->subpass->depth_stencil_attachment.attachment; 1096 return radv_attachment_needs_clear(cmd_state, a); 1097 } 1098 1099 static void 1100 radv_subpass_clear_attachment(struct radv_cmd_buffer *cmd_buffer, 1101 struct radv_attachment_state *attachment, 1102 const VkClearAttachment *clear_att, 1103 enum radv_cmd_flush_bits *pre_flush, 1104 enum radv_cmd_flush_bits *post_flush) 1105 { 1106 struct radv_cmd_state *cmd_state = &cmd_buffer->state; 1107 uint32_t view_mask = cmd_state->subpass->view_mask; 1108 1109 VkClearRect clear_rect = { 1110 .rect = cmd_state->render_area, 1111 .baseArrayLayer = 0, 1112 .layerCount = cmd_state->framebuffer->layers, 1113 }; 1114 1115 emit_clear(cmd_buffer, clear_att, &clear_rect, pre_flush, post_flush, 1116 view_mask & ~attachment->cleared_views); 1117 if (view_mask) 1118 attachment->cleared_views |= view_mask; 1119 else 1120 attachment->pending_clear_aspects = 0; 1121 } 1122 1123 /** 1124 * Emit any pending attachment clears for the current subpass. 1125 * 1126 * @see radv_attachment_state::pending_clear_aspects 1127 */ 1128 void 1129 radv_cmd_buffer_clear_subpass(struct radv_cmd_buffer *cmd_buffer) 1130 { 1131 struct radv_cmd_state *cmd_state = &cmd_buffer->state; 1132 struct radv_meta_saved_state saved_state; 1133 enum radv_cmd_flush_bits pre_flush = 0; 1134 enum radv_cmd_flush_bits post_flush = 0; 1135 1136 if (!radv_subpass_needs_clear(cmd_buffer)) 1137 return; 1138 1139 radv_meta_save(&saved_state, cmd_buffer, 1140 RADV_META_SAVE_GRAPHICS_PIPELINE | 1141 RADV_META_SAVE_CONSTANTS); 1142 1143 for (uint32_t i = 0; i < cmd_state->subpass->color_count; ++i) { 1144 uint32_t a = cmd_state->subpass->color_attachments[i].attachment; 1145 1146 if (!radv_attachment_needs_clear(cmd_state, a)) 1147 continue; 1148 1149 assert(cmd_state->attachments[a].pending_clear_aspects == 1150 VK_IMAGE_ASPECT_COLOR_BIT); 1151 1152 VkClearAttachment clear_att = { 1153 .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, 1154 .colorAttachment = i, /* Use attachment index relative to subpass */ 1155 .clearValue = cmd_state->attachments[a].clear_value, 1156 }; 1157 1158 radv_subpass_clear_attachment(cmd_buffer, 1159 &cmd_state->attachments[a], 1160 &clear_att, &pre_flush, 1161 &post_flush); 1162 } 1163 1164 uint32_t ds = cmd_state->subpass->depth_stencil_attachment.attachment; 1165 if (radv_attachment_needs_clear(cmd_state, ds)) { 1166 VkClearAttachment clear_att = { 1167 .aspectMask = cmd_state->attachments[ds].pending_clear_aspects, 1168 .clearValue = cmd_state->attachments[ds].clear_value, 1169 }; 1170 1171 radv_subpass_clear_attachment(cmd_buffer, 1172 &cmd_state->attachments[ds], 1173 &clear_att, &pre_flush, 1174 &post_flush); 1175 } 1176 1177 radv_meta_restore(&saved_state, cmd_buffer); 1178 cmd_buffer->state.flush_bits |= post_flush; 1179 } 1180 1181 static void 1182 radv_clear_image_layer(struct radv_cmd_buffer *cmd_buffer, 1183 struct radv_image *image, 1184 VkImageLayout image_layout, 1185 const VkImageSubresourceRange *range, 1186 VkFormat format, int level, int layer, 1187 const VkClearValue *clear_val) 1188 { 1189 VkDevice device_h = radv_device_to_handle(cmd_buffer->device); 1190 struct radv_image_view iview; 1191 uint32_t width = radv_minify(image->info.width, range->baseMipLevel + level); 1192 uint32_t height = radv_minify(image->info.height, range->baseMipLevel + level); 1193 1194 radv_image_view_init(&iview, cmd_buffer->device, 1195 &(VkImageViewCreateInfo) { 1196 .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, 1197 .image = radv_image_to_handle(image), 1198 .viewType = radv_meta_get_view_type(image), 1199 .format = format, 1200 .subresourceRange = { 1201 .aspectMask = range->aspectMask, 1202 .baseMipLevel = range->baseMipLevel + level, 1203 .levelCount = 1, 1204 .baseArrayLayer = range->baseArrayLayer + layer, 1205 .layerCount = 1 1206 }, 1207 }); 1208 1209 VkFramebuffer fb; 1210 radv_CreateFramebuffer(device_h, 1211 &(VkFramebufferCreateInfo) { 1212 .sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, 1213 .attachmentCount = 1, 1214 .pAttachments = (VkImageView[]) { 1215 radv_image_view_to_handle(&iview), 1216 }, 1217 .width = width, 1218 .height = height, 1219 .layers = 1 1220 }, 1221 &cmd_buffer->pool->alloc, 1222 &fb); 1223 1224 VkAttachmentDescription att_desc = { 1225 .format = iview.vk_format, 1226 .loadOp = VK_ATTACHMENT_LOAD_OP_LOAD, 1227 .storeOp = VK_ATTACHMENT_STORE_OP_STORE, 1228 .stencilLoadOp = VK_ATTACHMENT_LOAD_OP_LOAD, 1229 .stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE, 1230 .initialLayout = image_layout, 1231 .finalLayout = image_layout, 1232 }; 1233 1234 VkSubpassDescription subpass_desc = { 1235 .pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS, 1236 .inputAttachmentCount = 0, 1237 .colorAttachmentCount = 0, 1238 .pColorAttachments = NULL, 1239 .pResolveAttachments = NULL, 1240 .pDepthStencilAttachment = NULL, 1241 .preserveAttachmentCount = 0, 1242 .pPreserveAttachments = NULL, 1243 }; 1244 1245 const VkAttachmentReference att_ref = { 1246 .attachment = 0, 1247 .layout = image_layout, 1248 }; 1249 1250 if (range->aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) { 1251 subpass_desc.colorAttachmentCount = 1; 1252 subpass_desc.pColorAttachments = &att_ref; 1253 } else { 1254 subpass_desc.pDepthStencilAttachment = &att_ref; 1255 } 1256 1257 VkRenderPass pass; 1258 radv_CreateRenderPass(device_h, 1259 &(VkRenderPassCreateInfo) { 1260 .sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, 1261 .attachmentCount = 1, 1262 .pAttachments = &att_desc, 1263 .subpassCount = 1, 1264 .pSubpasses = &subpass_desc, 1265 }, 1266 &cmd_buffer->pool->alloc, 1267 &pass); 1268 1269 radv_CmdBeginRenderPass(radv_cmd_buffer_to_handle(cmd_buffer), 1270 &(VkRenderPassBeginInfo) { 1271 .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, 1272 .renderArea = { 1273 .offset = { 0, 0, }, 1274 .extent = { 1275 .width = width, 1276 .height = height, 1277 }, 1278 }, 1279 .renderPass = pass, 1280 .framebuffer = fb, 1281 .clearValueCount = 0, 1282 .pClearValues = NULL, 1283 }, 1284 VK_SUBPASS_CONTENTS_INLINE); 1285 1286 VkClearAttachment clear_att = { 1287 .aspectMask = range->aspectMask, 1288 .colorAttachment = 0, 1289 .clearValue = *clear_val, 1290 }; 1291 1292 VkClearRect clear_rect = { 1293 .rect = { 1294 .offset = { 0, 0 }, 1295 .extent = { width, height }, 1296 }, 1297 .baseArrayLayer = range->baseArrayLayer, 1298 .layerCount = 1, /* FINISHME: clear multi-layer framebuffer */ 1299 }; 1300 1301 emit_clear(cmd_buffer, &clear_att, &clear_rect, NULL, NULL, 0); 1302 1303 radv_CmdEndRenderPass(radv_cmd_buffer_to_handle(cmd_buffer)); 1304 radv_DestroyRenderPass(device_h, pass, 1305 &cmd_buffer->pool->alloc); 1306 radv_DestroyFramebuffer(device_h, fb, 1307 &cmd_buffer->pool->alloc); 1308 } 1309 static void 1310 radv_cmd_clear_image(struct radv_cmd_buffer *cmd_buffer, 1311 struct radv_image *image, 1312 VkImageLayout image_layout, 1313 const VkClearValue *clear_value, 1314 uint32_t range_count, 1315 const VkImageSubresourceRange *ranges, 1316 bool cs) 1317 { 1318 VkFormat format = image->vk_format; 1319 VkClearValue internal_clear_value = *clear_value; 1320 1321 if (format == VK_FORMAT_E5B9G9R9_UFLOAT_PACK32) { 1322 uint32_t value; 1323 format = VK_FORMAT_R32_UINT; 1324 value = float3_to_rgb9e5(clear_value->color.float32); 1325 internal_clear_value.color.uint32[0] = value; 1326 } 1327 1328 if (format == VK_FORMAT_R4G4_UNORM_PACK8) { 1329 uint8_t r, g; 1330 format = VK_FORMAT_R8_UINT; 1331 r = float_to_ubyte(clear_value->color.float32[0]) >> 4; 1332 g = float_to_ubyte(clear_value->color.float32[1]) >> 4; 1333 internal_clear_value.color.uint32[0] = (r << 4) | (g & 0xf); 1334 } 1335 1336 for (uint32_t r = 0; r < range_count; r++) { 1337 const VkImageSubresourceRange *range = &ranges[r]; 1338 for (uint32_t l = 0; l < radv_get_levelCount(image, range); ++l) { 1339 const uint32_t layer_count = image->type == VK_IMAGE_TYPE_3D ? 1340 radv_minify(image->info.depth, range->baseMipLevel + l) : 1341 radv_get_layerCount(image, range); 1342 for (uint32_t s = 0; s < layer_count; ++s) { 1343 1344 if (cs) { 1345 struct radv_meta_blit2d_surf surf; 1346 surf.format = format; 1347 surf.image = image; 1348 surf.level = range->baseMipLevel + l; 1349 surf.layer = range->baseArrayLayer + s; 1350 surf.aspect_mask = range->aspectMask; 1351 radv_meta_clear_image_cs(cmd_buffer, &surf, 1352 &internal_clear_value.color); 1353 } else { 1354 radv_clear_image_layer(cmd_buffer, image, image_layout, 1355 range, format, l, s, &internal_clear_value); 1356 } 1357 } 1358 } 1359 } 1360 } 1361 1362 void radv_CmdClearColorImage( 1363 VkCommandBuffer commandBuffer, 1364 VkImage image_h, 1365 VkImageLayout imageLayout, 1366 const VkClearColorValue* pColor, 1367 uint32_t rangeCount, 1368 const VkImageSubresourceRange* pRanges) 1369 { 1370 RADV_FROM_HANDLE(radv_cmd_buffer, cmd_buffer, commandBuffer); 1371 RADV_FROM_HANDLE(radv_image, image, image_h); 1372 struct radv_meta_saved_state saved_state; 1373 bool cs = cmd_buffer->queue_family_index == RADV_QUEUE_COMPUTE; 1374 1375 if (cs) { 1376 radv_meta_save(&saved_state, cmd_buffer, 1377 RADV_META_SAVE_COMPUTE_PIPELINE | 1378 RADV_META_SAVE_CONSTANTS | 1379 RADV_META_SAVE_DESCRIPTORS); 1380 } else { 1381 radv_meta_save(&saved_state, cmd_buffer, 1382 RADV_META_SAVE_GRAPHICS_PIPELINE | 1383 RADV_META_SAVE_CONSTANTS); 1384 } 1385 1386 radv_cmd_clear_image(cmd_buffer, image, imageLayout, 1387 (const VkClearValue *) pColor, 1388 rangeCount, pRanges, cs); 1389 1390 radv_meta_restore(&saved_state, cmd_buffer); 1391 } 1392 1393 void radv_CmdClearDepthStencilImage( 1394 VkCommandBuffer commandBuffer, 1395 VkImage image_h, 1396 VkImageLayout imageLayout, 1397 const VkClearDepthStencilValue* pDepthStencil, 1398 uint32_t rangeCount, 1399 const VkImageSubresourceRange* pRanges) 1400 { 1401 RADV_FROM_HANDLE(radv_cmd_buffer, cmd_buffer, commandBuffer); 1402 RADV_FROM_HANDLE(radv_image, image, image_h); 1403 struct radv_meta_saved_state saved_state; 1404 1405 radv_meta_save(&saved_state, cmd_buffer, 1406 RADV_META_SAVE_GRAPHICS_PIPELINE | 1407 RADV_META_SAVE_CONSTANTS); 1408 1409 radv_cmd_clear_image(cmd_buffer, image, imageLayout, 1410 (const VkClearValue *) pDepthStencil, 1411 rangeCount, pRanges, false); 1412 1413 radv_meta_restore(&saved_state, cmd_buffer); 1414 } 1415 1416 void radv_CmdClearAttachments( 1417 VkCommandBuffer commandBuffer, 1418 uint32_t attachmentCount, 1419 const VkClearAttachment* pAttachments, 1420 uint32_t rectCount, 1421 const VkClearRect* pRects) 1422 { 1423 RADV_FROM_HANDLE(radv_cmd_buffer, cmd_buffer, commandBuffer); 1424 struct radv_meta_saved_state saved_state; 1425 enum radv_cmd_flush_bits pre_flush = 0; 1426 enum radv_cmd_flush_bits post_flush = 0; 1427 1428 if (!cmd_buffer->state.subpass) 1429 return; 1430 1431 radv_meta_save(&saved_state, cmd_buffer, 1432 RADV_META_SAVE_GRAPHICS_PIPELINE | 1433 RADV_META_SAVE_CONSTANTS); 1434 1435 /* FINISHME: We can do better than this dumb loop. It thrashes too much 1436 * state. 1437 */ 1438 for (uint32_t a = 0; a < attachmentCount; ++a) { 1439 for (uint32_t r = 0; r < rectCount; ++r) { 1440 emit_clear(cmd_buffer, &pAttachments[a], &pRects[r], &pre_flush, &post_flush, 1441 cmd_buffer->state.subpass->view_mask); 1442 } 1443 } 1444 1445 radv_meta_restore(&saved_state, cmd_buffer); 1446 cmd_buffer->state.flush_bits |= post_flush; 1447 } 1448