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_meta.h" 25 #include "radv_private.h" 26 #include "nir/nir_builder.h" 27 28 #include "util/format_rgb9e5.h" 29 #include "vk_format.h" 30 /** Vertex attributes for color clears. */ 31 struct color_clear_vattrs { 32 float position[2]; 33 VkClearColorValue color; 34 }; 35 36 /** Vertex attributes for depthstencil clears. */ 37 struct depthstencil_clear_vattrs { 38 float position[2]; 39 float depth_clear; 40 }; 41 42 enum { 43 DEPTH_CLEAR_SLOW, 44 DEPTH_CLEAR_FAST_EXPCLEAR, 45 DEPTH_CLEAR_FAST_NO_EXPCLEAR 46 }; 47 48 static void 49 build_color_shaders(struct nir_shader **out_vs, 50 struct nir_shader **out_fs, 51 uint32_t frag_output) 52 { 53 nir_builder vs_b; 54 nir_builder fs_b; 55 56 nir_builder_init_simple_shader(&vs_b, NULL, MESA_SHADER_VERTEX, NULL); 57 nir_builder_init_simple_shader(&fs_b, NULL, MESA_SHADER_FRAGMENT, NULL); 58 59 vs_b.shader->info->name = ralloc_strdup(vs_b.shader, "meta_clear_color_vs"); 60 fs_b.shader->info->name = ralloc_strdup(fs_b.shader, "meta_clear_color_fs"); 61 62 const struct glsl_type *position_type = glsl_vec4_type(); 63 const struct glsl_type *color_type = glsl_vec4_type(); 64 65 nir_variable *vs_in_pos = 66 nir_variable_create(vs_b.shader, nir_var_shader_in, position_type, 67 "a_position"); 68 vs_in_pos->data.location = VERT_ATTRIB_GENERIC0; 69 70 nir_variable *vs_out_pos = 71 nir_variable_create(vs_b.shader, nir_var_shader_out, position_type, 72 "gl_Position"); 73 vs_out_pos->data.location = VARYING_SLOT_POS; 74 75 nir_variable *vs_in_color = 76 nir_variable_create(vs_b.shader, nir_var_shader_in, color_type, 77 "a_color"); 78 vs_in_color->data.location = VERT_ATTRIB_GENERIC1; 79 80 nir_variable *vs_out_color = 81 nir_variable_create(vs_b.shader, nir_var_shader_out, color_type, 82 "v_color"); 83 vs_out_color->data.location = VARYING_SLOT_VAR0; 84 vs_out_color->data.interpolation = INTERP_MODE_FLAT; 85 86 nir_variable *fs_in_color = 87 nir_variable_create(fs_b.shader, nir_var_shader_in, color_type, 88 "v_color"); 89 fs_in_color->data.location = vs_out_color->data.location; 90 fs_in_color->data.interpolation = vs_out_color->data.interpolation; 91 92 nir_variable *fs_out_color = 93 nir_variable_create(fs_b.shader, nir_var_shader_out, color_type, 94 "f_color"); 95 fs_out_color->data.location = FRAG_RESULT_DATA0 + frag_output; 96 97 nir_copy_var(&vs_b, vs_out_pos, vs_in_pos); 98 nir_copy_var(&vs_b, vs_out_color, vs_in_color); 99 nir_copy_var(&fs_b, fs_out_color, fs_in_color); 100 101 const struct glsl_type *layer_type = glsl_int_type(); 102 nir_variable *vs_out_layer = 103 nir_variable_create(vs_b.shader, nir_var_shader_out, layer_type, 104 "v_layer"); 105 vs_out_layer->data.location = VARYING_SLOT_LAYER; 106 vs_out_layer->data.interpolation = INTERP_MODE_FLAT; 107 nir_ssa_def *inst_id = nir_load_system_value(&vs_b, nir_intrinsic_load_instance_id, 0); 108 109 nir_store_var(&vs_b, vs_out_layer, inst_id, 0x1); 110 111 *out_vs = vs_b.shader; 112 *out_fs = fs_b.shader; 113 } 114 115 static VkResult 116 create_pipeline(struct radv_device *device, 117 struct radv_render_pass *render_pass, 118 uint32_t samples, 119 struct nir_shader *vs_nir, 120 struct nir_shader *fs_nir, 121 const VkPipelineVertexInputStateCreateInfo *vi_state, 122 const VkPipelineDepthStencilStateCreateInfo *ds_state, 123 const VkPipelineColorBlendStateCreateInfo *cb_state, 124 const struct radv_graphics_pipeline_create_info *extra, 125 const VkAllocationCallbacks *alloc, 126 struct radv_pipeline **pipeline) 127 { 128 VkDevice device_h = radv_device_to_handle(device); 129 VkResult result; 130 131 struct radv_shader_module vs_m = { .nir = vs_nir }; 132 struct radv_shader_module fs_m = { .nir = fs_nir }; 133 134 VkPipeline pipeline_h = VK_NULL_HANDLE; 135 result = radv_graphics_pipeline_create(device_h, 136 radv_pipeline_cache_to_handle(&device->meta_state.cache), 137 &(VkGraphicsPipelineCreateInfo) { 138 .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, 139 .stageCount = fs_nir ? 2 : 1, 140 .pStages = (VkPipelineShaderStageCreateInfo[]) { 141 { 142 .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, 143 .stage = VK_SHADER_STAGE_VERTEX_BIT, 144 .module = radv_shader_module_to_handle(&vs_m), 145 .pName = "main", 146 }, 147 { 148 .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, 149 .stage = VK_SHADER_STAGE_FRAGMENT_BIT, 150 .module = radv_shader_module_to_handle(&fs_m), 151 .pName = "main", 152 }, 153 }, 154 .pVertexInputState = vi_state, 155 .pInputAssemblyState = &(VkPipelineInputAssemblyStateCreateInfo) { 156 .sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, 157 .topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, 158 .primitiveRestartEnable = false, 159 }, 160 .pViewportState = &(VkPipelineViewportStateCreateInfo) { 161 .sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, 162 .viewportCount = 0, 163 .scissorCount = 0, 164 }, 165 .pRasterizationState = &(VkPipelineRasterizationStateCreateInfo) { 166 .sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, 167 .rasterizerDiscardEnable = false, 168 .polygonMode = VK_POLYGON_MODE_FILL, 169 .cullMode = VK_CULL_MODE_NONE, 170 .frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE, 171 .depthBiasEnable = false, 172 }, 173 .pMultisampleState = &(VkPipelineMultisampleStateCreateInfo) { 174 .sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, 175 .rasterizationSamples = samples, 176 .sampleShadingEnable = false, 177 .pSampleMask = NULL, 178 .alphaToCoverageEnable = false, 179 .alphaToOneEnable = false, 180 }, 181 .pDepthStencilState = ds_state, 182 .pColorBlendState = cb_state, 183 .pDynamicState = &(VkPipelineDynamicStateCreateInfo) { 184 /* The meta clear pipeline declares all state as dynamic. 185 * As a consequence, vkCmdBindPipeline writes no dynamic state 186 * to the cmd buffer. Therefore, at the end of the meta clear, 187 * we need only restore dynamic state was vkCmdSet. 188 */ 189 .sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, 190 .dynamicStateCount = 6, 191 .pDynamicStates = (VkDynamicState[]) { 192 /* Everything except stencil write mask */ 193 VK_DYNAMIC_STATE_LINE_WIDTH, 194 VK_DYNAMIC_STATE_DEPTH_BIAS, 195 VK_DYNAMIC_STATE_BLEND_CONSTANTS, 196 VK_DYNAMIC_STATE_DEPTH_BOUNDS, 197 VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK, 198 VK_DYNAMIC_STATE_STENCIL_REFERENCE, 199 }, 200 }, 201 .flags = 0, 202 .renderPass = radv_render_pass_to_handle(render_pass), 203 .subpass = 0, 204 }, 205 extra, 206 alloc, 207 &pipeline_h); 208 209 ralloc_free(vs_nir); 210 ralloc_free(fs_nir); 211 212 *pipeline = radv_pipeline_from_handle(pipeline_h); 213 214 return result; 215 } 216 217 static VkResult 218 create_color_renderpass(struct radv_device *device, 219 VkFormat vk_format, 220 uint32_t samples, 221 VkRenderPass *pass) 222 { 223 return radv_CreateRenderPass(radv_device_to_handle(device), 224 &(VkRenderPassCreateInfo) { 225 .sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, 226 .attachmentCount = 1, 227 .pAttachments = &(VkAttachmentDescription) { 228 .format = vk_format, 229 .samples = samples, 230 .loadOp = VK_ATTACHMENT_LOAD_OP_LOAD, 231 .storeOp = VK_ATTACHMENT_STORE_OP_STORE, 232 .initialLayout = VK_IMAGE_LAYOUT_GENERAL, 233 .finalLayout = VK_IMAGE_LAYOUT_GENERAL, 234 }, 235 .subpassCount = 1, 236 .pSubpasses = &(VkSubpassDescription) { 237 .pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS, 238 .inputAttachmentCount = 0, 239 .colorAttachmentCount = 1, 240 .pColorAttachments = &(VkAttachmentReference) { 241 .attachment = 0, 242 .layout = VK_IMAGE_LAYOUT_GENERAL, 243 }, 244 .pResolveAttachments = NULL, 245 .pDepthStencilAttachment = &(VkAttachmentReference) { 246 .attachment = VK_ATTACHMENT_UNUSED, 247 .layout = VK_IMAGE_LAYOUT_GENERAL, 248 }, 249 .preserveAttachmentCount = 1, 250 .pPreserveAttachments = (uint32_t[]) { 0 }, 251 }, 252 .dependencyCount = 0, 253 }, &device->meta_state.alloc, pass); 254 } 255 256 static VkResult 257 create_color_pipeline(struct radv_device *device, 258 uint32_t samples, 259 uint32_t frag_output, 260 struct radv_pipeline **pipeline, 261 VkRenderPass pass) 262 { 263 struct nir_shader *vs_nir; 264 struct nir_shader *fs_nir; 265 VkResult result; 266 build_color_shaders(&vs_nir, &fs_nir, frag_output); 267 268 const VkPipelineVertexInputStateCreateInfo vi_state = { 269 .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, 270 .vertexBindingDescriptionCount = 1, 271 .pVertexBindingDescriptions = (VkVertexInputBindingDescription[]) { 272 { 273 .binding = 0, 274 .stride = sizeof(struct color_clear_vattrs), 275 .inputRate = VK_VERTEX_INPUT_RATE_VERTEX 276 }, 277 }, 278 .vertexAttributeDescriptionCount = 2, 279 .pVertexAttributeDescriptions = (VkVertexInputAttributeDescription[]) { 280 { 281 /* Position */ 282 .location = 0, 283 .binding = 0, 284 .format = VK_FORMAT_R32G32_SFLOAT, 285 .offset = offsetof(struct color_clear_vattrs, position), 286 }, 287 { 288 /* Color */ 289 .location = 1, 290 .binding = 0, 291 .format = VK_FORMAT_R32G32B32A32_SFLOAT, 292 .offset = offsetof(struct color_clear_vattrs, color), 293 }, 294 }, 295 }; 296 297 const VkPipelineDepthStencilStateCreateInfo ds_state = { 298 .sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, 299 .depthTestEnable = false, 300 .depthWriteEnable = false, 301 .depthBoundsTestEnable = false, 302 .stencilTestEnable = false, 303 }; 304 305 VkPipelineColorBlendAttachmentState blend_attachment_state[MAX_RTS] = { 0 }; 306 blend_attachment_state[frag_output] = (VkPipelineColorBlendAttachmentState) { 307 .blendEnable = false, 308 .colorWriteMask = VK_COLOR_COMPONENT_A_BIT | 309 VK_COLOR_COMPONENT_R_BIT | 310 VK_COLOR_COMPONENT_G_BIT | 311 VK_COLOR_COMPONENT_B_BIT, 312 }; 313 314 const VkPipelineColorBlendStateCreateInfo cb_state = { 315 .sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, 316 .logicOpEnable = false, 317 .attachmentCount = MAX_RTS, 318 .pAttachments = blend_attachment_state 319 }; 320 321 322 struct radv_graphics_pipeline_create_info extra = { 323 .use_rectlist = true, 324 }; 325 result = create_pipeline(device, radv_render_pass_from_handle(pass), 326 samples, vs_nir, fs_nir, &vi_state, &ds_state, &cb_state, 327 &extra, &device->meta_state.alloc, pipeline); 328 329 return result; 330 } 331 332 static void 333 destroy_pipeline(struct radv_device *device, struct radv_pipeline *pipeline) 334 { 335 if (!pipeline) 336 return; 337 338 radv_DestroyPipeline(radv_device_to_handle(device), 339 radv_pipeline_to_handle(pipeline), 340 &device->meta_state.alloc); 341 342 } 343 344 static void 345 destroy_render_pass(struct radv_device *device, VkRenderPass renderpass) 346 { 347 radv_DestroyRenderPass(radv_device_to_handle(device), renderpass, 348 &device->meta_state.alloc); 349 } 350 351 void 352 radv_device_finish_meta_clear_state(struct radv_device *device) 353 { 354 struct radv_meta_state *state = &device->meta_state; 355 356 for (uint32_t i = 0; i < ARRAY_SIZE(state->clear); ++i) { 357 for (uint32_t j = 0; j < ARRAY_SIZE(state->clear[i].color_pipelines); ++j) { 358 destroy_pipeline(device, state->clear[i].color_pipelines[j]); 359 destroy_render_pass(device, state->clear[i].render_pass[j]); 360 } 361 362 for (uint32_t j = 0; j < NUM_DEPTH_CLEAR_PIPELINES; j++) { 363 destroy_pipeline(device, state->clear[i].depth_only_pipeline[j]); 364 destroy_pipeline(device, state->clear[i].stencil_only_pipeline[j]); 365 destroy_pipeline(device, state->clear[i].depthstencil_pipeline[j]); 366 } 367 destroy_render_pass(device, state->clear[i].depthstencil_rp); 368 } 369 370 } 371 372 static void 373 emit_color_clear(struct radv_cmd_buffer *cmd_buffer, 374 const VkClearAttachment *clear_att, 375 const VkClearRect *clear_rect) 376 { 377 struct radv_device *device = cmd_buffer->device; 378 const struct radv_subpass *subpass = cmd_buffer->state.subpass; 379 const struct radv_framebuffer *fb = cmd_buffer->state.framebuffer; 380 const uint32_t subpass_att = clear_att->colorAttachment; 381 const uint32_t pass_att = subpass->color_attachments[subpass_att].attachment; 382 const struct radv_image_view *iview = fb->attachments[pass_att].attachment; 383 const uint32_t samples = iview->image->samples; 384 const uint32_t samples_log2 = ffs(samples) - 1; 385 unsigned fs_key = radv_format_meta_fs_key(iview->vk_format); 386 struct radv_pipeline *pipeline; 387 VkClearColorValue clear_value = clear_att->clearValue.color; 388 VkCommandBuffer cmd_buffer_h = radv_cmd_buffer_to_handle(cmd_buffer); 389 VkPipeline pipeline_h; 390 uint32_t offset; 391 392 if (fs_key == -1) { 393 radv_finishme("color clears incomplete"); 394 return; 395 } 396 pipeline = device->meta_state.clear[samples_log2].color_pipelines[fs_key]; 397 pipeline_h = radv_pipeline_to_handle(pipeline); 398 399 if (!pipeline) { 400 radv_finishme("color clears incomplete"); 401 return; 402 } 403 assert(samples_log2 < ARRAY_SIZE(device->meta_state.clear)); 404 assert(pipeline); 405 assert(clear_att->aspectMask == VK_IMAGE_ASPECT_COLOR_BIT); 406 assert(clear_att->colorAttachment < subpass->color_count); 407 408 const struct color_clear_vattrs vertex_data[3] = { 409 { 410 .position = { 411 clear_rect->rect.offset.x, 412 clear_rect->rect.offset.y, 413 }, 414 .color = clear_value, 415 }, 416 { 417 .position = { 418 clear_rect->rect.offset.x, 419 clear_rect->rect.offset.y + clear_rect->rect.extent.height, 420 }, 421 .color = clear_value, 422 }, 423 { 424 .position = { 425 clear_rect->rect.offset.x + clear_rect->rect.extent.width, 426 clear_rect->rect.offset.y, 427 }, 428 .color = clear_value, 429 }, 430 }; 431 432 struct radv_subpass clear_subpass = { 433 .color_count = 1, 434 .color_attachments = (VkAttachmentReference[]) { 435 subpass->color_attachments[clear_att->colorAttachment] 436 }, 437 .depth_stencil_attachment = (VkAttachmentReference) { VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_UNDEFINED } 438 }; 439 440 radv_cmd_buffer_set_subpass(cmd_buffer, &clear_subpass, false); 441 442 radv_cmd_buffer_upload_data(cmd_buffer, sizeof(vertex_data), 16, vertex_data, &offset); 443 struct radv_buffer vertex_buffer = { 444 .device = device, 445 .size = sizeof(vertex_data), 446 .bo = cmd_buffer->upload.upload_bo, 447 .offset = offset, 448 }; 449 450 451 radv_CmdBindVertexBuffers(cmd_buffer_h, 0, 1, 452 (VkBuffer[]) { radv_buffer_to_handle(&vertex_buffer) }, 453 (VkDeviceSize[]) { 0 }); 454 455 if (cmd_buffer->state.pipeline != pipeline) { 456 radv_CmdBindPipeline(cmd_buffer_h, VK_PIPELINE_BIND_POINT_GRAPHICS, 457 pipeline_h); 458 } 459 460 radv_CmdDraw(cmd_buffer_h, 3, clear_rect->layerCount, 0, 0); 461 462 radv_cmd_buffer_set_subpass(cmd_buffer, subpass, false); 463 } 464 465 466 static void 467 build_depthstencil_shader(struct nir_shader **out_vs, struct nir_shader **out_fs) 468 { 469 nir_builder vs_b, fs_b; 470 471 nir_builder_init_simple_shader(&vs_b, NULL, MESA_SHADER_VERTEX, NULL); 472 nir_builder_init_simple_shader(&fs_b, NULL, MESA_SHADER_FRAGMENT, NULL); 473 474 vs_b.shader->info->name = ralloc_strdup(vs_b.shader, "meta_clear_depthstencil_vs"); 475 fs_b.shader->info->name = ralloc_strdup(fs_b.shader, "meta_clear_depthstencil_fs"); 476 const struct glsl_type *position_type = glsl_vec4_type(); 477 478 nir_variable *vs_in_pos = 479 nir_variable_create(vs_b.shader, nir_var_shader_in, position_type, 480 "a_position"); 481 vs_in_pos->data.location = VERT_ATTRIB_GENERIC0; 482 483 nir_variable *vs_out_pos = 484 nir_variable_create(vs_b.shader, nir_var_shader_out, position_type, 485 "gl_Position"); 486 vs_out_pos->data.location = VARYING_SLOT_POS; 487 488 nir_copy_var(&vs_b, vs_out_pos, vs_in_pos); 489 490 const struct glsl_type *layer_type = glsl_int_type(); 491 nir_variable *vs_out_layer = 492 nir_variable_create(vs_b.shader, nir_var_shader_out, layer_type, 493 "v_layer"); 494 vs_out_layer->data.location = VARYING_SLOT_LAYER; 495 vs_out_layer->data.interpolation = INTERP_MODE_FLAT; 496 nir_ssa_def *inst_id = nir_load_system_value(&vs_b, nir_intrinsic_load_instance_id, 0); 497 nir_store_var(&vs_b, vs_out_layer, inst_id, 0x1); 498 499 *out_vs = vs_b.shader; 500 *out_fs = fs_b.shader; 501 } 502 503 static VkResult 504 create_depthstencil_renderpass(struct radv_device *device, 505 uint32_t samples, 506 VkRenderPass *render_pass) 507 { 508 return radv_CreateRenderPass(radv_device_to_handle(device), 509 &(VkRenderPassCreateInfo) { 510 .sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, 511 .attachmentCount = 1, 512 .pAttachments = &(VkAttachmentDescription) { 513 .format = VK_FORMAT_UNDEFINED, 514 .samples = samples, 515 .loadOp = VK_ATTACHMENT_LOAD_OP_LOAD, 516 .storeOp = VK_ATTACHMENT_STORE_OP_STORE, 517 .initialLayout = VK_IMAGE_LAYOUT_GENERAL, 518 .finalLayout = VK_IMAGE_LAYOUT_GENERAL, 519 }, 520 .subpassCount = 1, 521 .pSubpasses = &(VkSubpassDescription) { 522 .pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS, 523 .inputAttachmentCount = 0, 524 .colorAttachmentCount = 0, 525 .pColorAttachments = NULL, 526 .pResolveAttachments = NULL, 527 .pDepthStencilAttachment = &(VkAttachmentReference) { 528 .attachment = 0, 529 .layout = VK_IMAGE_LAYOUT_GENERAL, 530 }, 531 .preserveAttachmentCount = 1, 532 .pPreserveAttachments = (uint32_t[]) { 0 }, 533 }, 534 .dependencyCount = 0, 535 }, &device->meta_state.alloc, render_pass); 536 } 537 538 static VkResult 539 create_depthstencil_pipeline(struct radv_device *device, 540 VkImageAspectFlags aspects, 541 uint32_t samples, 542 int index, 543 struct radv_pipeline **pipeline, 544 VkRenderPass render_pass) 545 { 546 struct nir_shader *vs_nir, *fs_nir; 547 VkResult result; 548 build_depthstencil_shader(&vs_nir, &fs_nir); 549 550 const VkPipelineVertexInputStateCreateInfo vi_state = { 551 .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, 552 .vertexBindingDescriptionCount = 1, 553 .pVertexBindingDescriptions = (VkVertexInputBindingDescription[]) { 554 { 555 .binding = 0, 556 .stride = sizeof(struct depthstencil_clear_vattrs), 557 .inputRate = VK_VERTEX_INPUT_RATE_VERTEX 558 }, 559 }, 560 .vertexAttributeDescriptionCount = 1, 561 .pVertexAttributeDescriptions = (VkVertexInputAttributeDescription[]) { 562 { 563 /* Position */ 564 .location = 0, 565 .binding = 0, 566 .format = VK_FORMAT_R32G32B32_SFLOAT, 567 .offset = offsetof(struct depthstencil_clear_vattrs, position), 568 }, 569 }, 570 }; 571 572 const VkPipelineDepthStencilStateCreateInfo ds_state = { 573 .sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, 574 .depthTestEnable = (aspects & VK_IMAGE_ASPECT_DEPTH_BIT), 575 .depthCompareOp = VK_COMPARE_OP_ALWAYS, 576 .depthWriteEnable = (aspects & VK_IMAGE_ASPECT_DEPTH_BIT), 577 .depthBoundsTestEnable = false, 578 .stencilTestEnable = (aspects & VK_IMAGE_ASPECT_STENCIL_BIT), 579 .front = { 580 .passOp = VK_STENCIL_OP_REPLACE, 581 .compareOp = VK_COMPARE_OP_ALWAYS, 582 .writeMask = UINT32_MAX, 583 .reference = 0, /* dynamic */ 584 }, 585 .back = { 0 /* dont care */ }, 586 }; 587 588 const VkPipelineColorBlendStateCreateInfo cb_state = { 589 .sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, 590 .logicOpEnable = false, 591 .attachmentCount = 0, 592 .pAttachments = NULL, 593 }; 594 595 struct radv_graphics_pipeline_create_info extra = { 596 .use_rectlist = true, 597 }; 598 599 if (aspects & VK_IMAGE_ASPECT_DEPTH_BIT) { 600 extra.db_depth_clear = index == DEPTH_CLEAR_SLOW ? false : true; 601 extra.db_depth_disable_expclear = index == DEPTH_CLEAR_FAST_NO_EXPCLEAR ? true : false; 602 } 603 if (aspects & VK_IMAGE_ASPECT_STENCIL_BIT) { 604 extra.db_stencil_clear = index == DEPTH_CLEAR_SLOW ? false : true; 605 extra.db_stencil_disable_expclear = index == DEPTH_CLEAR_FAST_NO_EXPCLEAR ? true : false; 606 } 607 result = create_pipeline(device, radv_render_pass_from_handle(render_pass), 608 samples, vs_nir, fs_nir, &vi_state, &ds_state, &cb_state, 609 &extra, &device->meta_state.alloc, pipeline); 610 return result; 611 } 612 613 static bool depth_view_can_fast_clear(const struct radv_image_view *iview, 614 VkImageLayout layout, 615 const VkClearRect *clear_rect) 616 { 617 if (clear_rect->rect.offset.x || clear_rect->rect.offset.y || 618 clear_rect->rect.extent.width != iview->extent.width || 619 clear_rect->rect.extent.height != iview->extent.height) 620 return false; 621 if (iview->image->htile.size && 622 iview->base_mip == 0 && 623 iview->base_layer == 0 && 624 radv_layout_can_expclear(iview->image, layout) && 625 memcmp(&iview->extent, &iview->image->extent, sizeof(iview->extent)) == 0) 626 return true; 627 return false; 628 } 629 630 static struct radv_pipeline * 631 pick_depthstencil_pipeline(struct radv_meta_state *meta_state, 632 const struct radv_image_view *iview, 633 int samples_log2, 634 VkImageAspectFlags aspects, 635 VkImageLayout layout, 636 const VkClearRect *clear_rect, 637 VkClearDepthStencilValue clear_value) 638 { 639 bool fast = depth_view_can_fast_clear(iview, layout, clear_rect); 640 int index = DEPTH_CLEAR_SLOW; 641 642 if (fast) { 643 /* we don't know the previous clear values, so we always have 644 * the NO_EXPCLEAR path */ 645 index = DEPTH_CLEAR_FAST_NO_EXPCLEAR; 646 } 647 648 switch (aspects) { 649 case VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT: 650 return meta_state->clear[samples_log2].depthstencil_pipeline[index]; 651 case VK_IMAGE_ASPECT_DEPTH_BIT: 652 return meta_state->clear[samples_log2].depth_only_pipeline[index]; 653 case VK_IMAGE_ASPECT_STENCIL_BIT: 654 return meta_state->clear[samples_log2].stencil_only_pipeline[index]; 655 } 656 unreachable("expected depth or stencil aspect"); 657 } 658 659 static void 660 emit_depthstencil_clear(struct radv_cmd_buffer *cmd_buffer, 661 const VkClearAttachment *clear_att, 662 const VkClearRect *clear_rect) 663 { 664 struct radv_device *device = cmd_buffer->device; 665 struct radv_meta_state *meta_state = &device->meta_state; 666 const struct radv_subpass *subpass = cmd_buffer->state.subpass; 667 const struct radv_framebuffer *fb = cmd_buffer->state.framebuffer; 668 const uint32_t pass_att = subpass->depth_stencil_attachment.attachment; 669 VkClearDepthStencilValue clear_value = clear_att->clearValue.depthStencil; 670 VkImageAspectFlags aspects = clear_att->aspectMask; 671 const struct radv_image_view *iview = fb->attachments[pass_att].attachment; 672 const uint32_t samples = iview->image->samples; 673 const uint32_t samples_log2 = ffs(samples) - 1; 674 VkCommandBuffer cmd_buffer_h = radv_cmd_buffer_to_handle(cmd_buffer); 675 uint32_t offset; 676 677 assert(aspects == VK_IMAGE_ASPECT_DEPTH_BIT || 678 aspects == VK_IMAGE_ASPECT_STENCIL_BIT || 679 aspects == (VK_IMAGE_ASPECT_DEPTH_BIT | 680 VK_IMAGE_ASPECT_STENCIL_BIT)); 681 assert(pass_att != VK_ATTACHMENT_UNUSED); 682 683 const struct depthstencil_clear_vattrs vertex_data[3] = { 684 { 685 .position = { 686 clear_rect->rect.offset.x, 687 clear_rect->rect.offset.y, 688 }, 689 .depth_clear = clear_value.depth, 690 }, 691 { 692 .position = { 693 clear_rect->rect.offset.x, 694 clear_rect->rect.offset.y + clear_rect->rect.extent.height, 695 }, 696 .depth_clear = clear_value.depth, 697 }, 698 { 699 .position = { 700 clear_rect->rect.offset.x + clear_rect->rect.extent.width, 701 clear_rect->rect.offset.y, 702 }, 703 .depth_clear = clear_value.depth, 704 }, 705 }; 706 707 radv_cmd_buffer_upload_data(cmd_buffer, sizeof(vertex_data), 16, vertex_data, &offset); 708 struct radv_buffer vertex_buffer = { 709 .device = device, 710 .size = sizeof(vertex_data), 711 .bo = cmd_buffer->upload.upload_bo, 712 .offset = offset, 713 }; 714 715 if (aspects & VK_IMAGE_ASPECT_STENCIL_BIT) { 716 radv_CmdSetStencilReference(cmd_buffer_h, VK_STENCIL_FACE_FRONT_BIT, 717 clear_value.stencil); 718 } 719 720 radv_CmdBindVertexBuffers(cmd_buffer_h, 0, 1, 721 (VkBuffer[]) { radv_buffer_to_handle(&vertex_buffer) }, 722 (VkDeviceSize[]) { 0 }); 723 724 struct radv_pipeline *pipeline = pick_depthstencil_pipeline(meta_state, 725 iview, 726 samples_log2, 727 aspects, 728 subpass->depth_stencil_attachment.layout, 729 clear_rect, 730 clear_value); 731 if (cmd_buffer->state.pipeline != pipeline) { 732 radv_CmdBindPipeline(cmd_buffer_h, VK_PIPELINE_BIND_POINT_GRAPHICS, 733 radv_pipeline_to_handle(pipeline)); 734 } 735 736 if (depth_view_can_fast_clear(iview, subpass->depth_stencil_attachment.layout, clear_rect)) 737 radv_set_depth_clear_regs(cmd_buffer, iview->image, clear_value, aspects); 738 739 radv_CmdDraw(cmd_buffer_h, 3, clear_rect->layerCount, 0, 0); 740 } 741 742 743 static VkFormat pipeline_formats[] = { 744 VK_FORMAT_R8G8B8A8_UNORM, 745 VK_FORMAT_R8G8B8A8_UINT, 746 VK_FORMAT_R8G8B8A8_SINT, 747 VK_FORMAT_R16G16B16A16_UNORM, 748 VK_FORMAT_R16G16B16A16_SNORM, 749 VK_FORMAT_R16G16B16A16_UINT, 750 VK_FORMAT_R16G16B16A16_SINT, 751 VK_FORMAT_R32_SFLOAT, 752 VK_FORMAT_R32G32_SFLOAT, 753 VK_FORMAT_R32G32B32A32_SFLOAT 754 }; 755 756 VkResult 757 radv_device_init_meta_clear_state(struct radv_device *device) 758 { 759 VkResult res; 760 struct radv_meta_state *state = &device->meta_state; 761 762 memset(&device->meta_state.clear, 0, sizeof(device->meta_state.clear)); 763 764 for (uint32_t i = 0; i < ARRAY_SIZE(state->clear); ++i) { 765 uint32_t samples = 1 << i; 766 for (uint32_t j = 0; j < ARRAY_SIZE(pipeline_formats); ++j) { 767 VkFormat format = pipeline_formats[j]; 768 unsigned fs_key = radv_format_meta_fs_key(format); 769 assert(!state->clear[i].color_pipelines[fs_key]); 770 771 res = create_color_renderpass(device, format, samples, 772 &state->clear[i].render_pass[fs_key]); 773 if (res != VK_SUCCESS) 774 goto fail; 775 776 res = create_color_pipeline(device, samples, 0, &state->clear[i].color_pipelines[fs_key], 777 state->clear[i].render_pass[fs_key]); 778 if (res != VK_SUCCESS) 779 goto fail; 780 781 } 782 783 res = create_depthstencil_renderpass(device, 784 samples, 785 &state->clear[i].depthstencil_rp); 786 if (res != VK_SUCCESS) 787 goto fail; 788 789 for (uint32_t j = 0; j < NUM_DEPTH_CLEAR_PIPELINES; j++) { 790 res = create_depthstencil_pipeline(device, 791 VK_IMAGE_ASPECT_DEPTH_BIT, 792 samples, 793 j, 794 &state->clear[i].depth_only_pipeline[j], 795 state->clear[i].depthstencil_rp); 796 if (res != VK_SUCCESS) 797 goto fail; 798 799 res = create_depthstencil_pipeline(device, 800 VK_IMAGE_ASPECT_STENCIL_BIT, 801 samples, 802 j, 803 &state->clear[i].stencil_only_pipeline[j], 804 state->clear[i].depthstencil_rp); 805 if (res != VK_SUCCESS) 806 goto fail; 807 808 res = create_depthstencil_pipeline(device, 809 VK_IMAGE_ASPECT_DEPTH_BIT | 810 VK_IMAGE_ASPECT_STENCIL_BIT, 811 samples, 812 j, 813 &state->clear[i].depthstencil_pipeline[j], 814 state->clear[i].depthstencil_rp); 815 if (res != VK_SUCCESS) 816 goto fail; 817 } 818 } 819 return VK_SUCCESS; 820 821 fail: 822 radv_device_finish_meta_clear_state(device); 823 return res; 824 } 825 826 static bool 827 emit_fast_color_clear(struct radv_cmd_buffer *cmd_buffer, 828 const VkClearAttachment *clear_att, 829 const VkClearRect *clear_rect) 830 { 831 const struct radv_subpass *subpass = cmd_buffer->state.subpass; 832 const uint32_t subpass_att = clear_att->colorAttachment; 833 const uint32_t pass_att = subpass->color_attachments[subpass_att].attachment; 834 VkImageLayout image_layout = subpass->color_attachments[subpass_att].layout; 835 const struct radv_framebuffer *fb = cmd_buffer->state.framebuffer; 836 const struct radv_image_view *iview = fb->attachments[pass_att].attachment; 837 VkClearColorValue clear_value = clear_att->clearValue.color; 838 uint32_t clear_color[2]; 839 bool ret; 840 841 if (!iview->image->cmask.size && !iview->image->surface.dcc_size) 842 return false; 843 844 if (!(cmd_buffer->device->debug_flags & RADV_DEBUG_FAST_CLEARS)) 845 return false; 846 847 if (!radv_layout_can_fast_clear(iview->image, image_layout, radv_image_queue_family_mask(iview->image, cmd_buffer->queue_family_index))) 848 goto fail; 849 if (vk_format_get_blocksizebits(iview->image->vk_format) > 64) 850 goto fail; 851 852 /* don't fast clear 3D */ 853 if (iview->image->type == VK_IMAGE_TYPE_3D) 854 goto fail; 855 856 /* all layers are bound */ 857 if (iview->base_layer > 0) 858 goto fail; 859 if (iview->image->array_size != iview->layer_count) 860 goto fail; 861 862 if (iview->image->levels > 1) 863 goto fail; 864 865 if (iview->image->surface.level[0].mode < RADEON_SURF_MODE_1D) 866 goto fail; 867 868 if (memcmp(&iview->extent, &iview->image->extent, sizeof(iview->extent))) 869 goto fail; 870 871 if (clear_rect->rect.offset.x || clear_rect->rect.offset.y || 872 clear_rect->rect.extent.width != iview->image->extent.width || 873 clear_rect->rect.extent.height != iview->image->extent.height) 874 goto fail; 875 876 if (clear_rect->baseArrayLayer != 0) 877 goto fail; 878 if (clear_rect->layerCount != iview->image->array_size) 879 goto fail; 880 881 /* DCC */ 882 ret = radv_format_pack_clear_color(iview->image->vk_format, 883 clear_color, &clear_value); 884 if (ret == false) 885 goto fail; 886 887 cmd_buffer->state.flush_bits |= RADV_CMD_FLAG_FLUSH_AND_INV_CB | 888 RADV_CMD_FLAG_FLUSH_AND_INV_CB_META; 889 si_emit_cache_flush(cmd_buffer); 890 /* clear cmask buffer */ 891 if (iview->image->surface.dcc_size) { 892 radv_fill_buffer(cmd_buffer, iview->image->bo, 893 iview->image->offset + iview->image->dcc_offset, 894 iview->image->surface.dcc_size, 0x20202020); 895 } else { 896 radv_fill_buffer(cmd_buffer, iview->image->bo, 897 iview->image->offset + iview->image->cmask.offset, 898 iview->image->cmask.size, 0); 899 } 900 cmd_buffer->state.flush_bits |= RADV_CMD_FLAG_CS_PARTIAL_FLUSH | 901 RADV_CMD_FLAG_INV_VMEM_L1 | 902 RADV_CMD_FLAG_INV_GLOBAL_L2; 903 904 radv_set_color_clear_regs(cmd_buffer, iview->image, subpass_att, clear_color); 905 906 return true; 907 fail: 908 return false; 909 } 910 911 /** 912 * The parameters mean that same as those in vkCmdClearAttachments. 913 */ 914 static void 915 emit_clear(struct radv_cmd_buffer *cmd_buffer, 916 const VkClearAttachment *clear_att, 917 const VkClearRect *clear_rect) 918 { 919 if (clear_att->aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) { 920 921 if (!emit_fast_color_clear(cmd_buffer, clear_att, clear_rect)) 922 emit_color_clear(cmd_buffer, clear_att, clear_rect); 923 } else { 924 assert(clear_att->aspectMask & (VK_IMAGE_ASPECT_DEPTH_BIT | 925 VK_IMAGE_ASPECT_STENCIL_BIT)); 926 emit_depthstencil_clear(cmd_buffer, clear_att, clear_rect); 927 } 928 } 929 930 static bool 931 subpass_needs_clear(const struct radv_cmd_buffer *cmd_buffer) 932 { 933 const struct radv_cmd_state *cmd_state = &cmd_buffer->state; 934 uint32_t ds; 935 936 if (!cmd_state->subpass) 937 return false; 938 ds = cmd_state->subpass->depth_stencil_attachment.attachment; 939 for (uint32_t i = 0; i < cmd_state->subpass->color_count; ++i) { 940 uint32_t a = cmd_state->subpass->color_attachments[i].attachment; 941 if (cmd_state->attachments[a].pending_clear_aspects) { 942 return true; 943 } 944 } 945 946 if (ds != VK_ATTACHMENT_UNUSED && 947 cmd_state->attachments[ds].pending_clear_aspects) { 948 return true; 949 } 950 951 return false; 952 } 953 954 /** 955 * Emit any pending attachment clears for the current subpass. 956 * 957 * @see radv_attachment_state::pending_clear_aspects 958 */ 959 void 960 radv_cmd_buffer_clear_subpass(struct radv_cmd_buffer *cmd_buffer) 961 { 962 struct radv_cmd_state *cmd_state = &cmd_buffer->state; 963 struct radv_meta_saved_state saved_state; 964 965 if (!subpass_needs_clear(cmd_buffer)) 966 return; 967 968 radv_meta_save_graphics_reset_vport_scissor(&saved_state, cmd_buffer); 969 970 VkClearRect clear_rect = { 971 .rect = cmd_state->render_area, 972 .baseArrayLayer = 0, 973 .layerCount = cmd_state->framebuffer->layers, 974 }; 975 976 for (uint32_t i = 0; i < cmd_state->subpass->color_count; ++i) { 977 uint32_t a = cmd_state->subpass->color_attachments[i].attachment; 978 979 if (!cmd_state->attachments[a].pending_clear_aspects) 980 continue; 981 982 assert(cmd_state->attachments[a].pending_clear_aspects == 983 VK_IMAGE_ASPECT_COLOR_BIT); 984 985 VkClearAttachment clear_att = { 986 .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, 987 .colorAttachment = i, /* Use attachment index relative to subpass */ 988 .clearValue = cmd_state->attachments[a].clear_value, 989 }; 990 991 emit_clear(cmd_buffer, &clear_att, &clear_rect); 992 cmd_state->attachments[a].pending_clear_aspects = 0; 993 } 994 995 uint32_t ds = cmd_state->subpass->depth_stencil_attachment.attachment; 996 997 if (ds != VK_ATTACHMENT_UNUSED) { 998 999 if (cmd_state->attachments[ds].pending_clear_aspects) { 1000 1001 VkClearAttachment clear_att = { 1002 .aspectMask = cmd_state->attachments[ds].pending_clear_aspects, 1003 .clearValue = cmd_state->attachments[ds].clear_value, 1004 }; 1005 1006 emit_clear(cmd_buffer, &clear_att, &clear_rect); 1007 cmd_state->attachments[ds].pending_clear_aspects = 0; 1008 } 1009 } 1010 1011 radv_meta_restore(&saved_state, cmd_buffer); 1012 } 1013 1014 static void 1015 radv_clear_image_layer(struct radv_cmd_buffer *cmd_buffer, 1016 struct radv_image *image, 1017 VkImageLayout image_layout, 1018 const VkImageSubresourceRange *range, 1019 VkFormat format, int level, int layer, 1020 const VkClearValue *clear_val) 1021 { 1022 VkDevice device_h = radv_device_to_handle(cmd_buffer->device); 1023 struct radv_image_view iview; 1024 radv_image_view_init(&iview, cmd_buffer->device, 1025 &(VkImageViewCreateInfo) { 1026 .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, 1027 .image = radv_image_to_handle(image), 1028 .viewType = radv_meta_get_view_type(image), 1029 .format = format, 1030 .subresourceRange = { 1031 .aspectMask = range->aspectMask, 1032 .baseMipLevel = range->baseMipLevel + level, 1033 .levelCount = 1, 1034 .baseArrayLayer = range->baseArrayLayer + layer, 1035 .layerCount = 1 1036 }, 1037 }, 1038 cmd_buffer, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT); 1039 1040 VkFramebuffer fb; 1041 radv_CreateFramebuffer(device_h, 1042 &(VkFramebufferCreateInfo) { 1043 .sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, 1044 .attachmentCount = 1, 1045 .pAttachments = (VkImageView[]) { 1046 radv_image_view_to_handle(&iview), 1047 }, 1048 .width = iview.extent.width, 1049 .height = iview.extent.height, 1050 .layers = 1 1051 }, 1052 &cmd_buffer->pool->alloc, 1053 &fb); 1054 1055 VkAttachmentDescription att_desc = { 1056 .format = iview.vk_format, 1057 .loadOp = VK_ATTACHMENT_LOAD_OP_LOAD, 1058 .storeOp = VK_ATTACHMENT_STORE_OP_STORE, 1059 .stencilLoadOp = VK_ATTACHMENT_LOAD_OP_LOAD, 1060 .stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE, 1061 .initialLayout = image_layout, 1062 .finalLayout = image_layout, 1063 }; 1064 1065 VkSubpassDescription subpass_desc = { 1066 .pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS, 1067 .inputAttachmentCount = 0, 1068 .colorAttachmentCount = 0, 1069 .pColorAttachments = NULL, 1070 .pResolveAttachments = NULL, 1071 .pDepthStencilAttachment = NULL, 1072 .preserveAttachmentCount = 0, 1073 .pPreserveAttachments = NULL, 1074 }; 1075 1076 const VkAttachmentReference att_ref = { 1077 .attachment = 0, 1078 .layout = image_layout, 1079 }; 1080 1081 if (range->aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) { 1082 subpass_desc.colorAttachmentCount = 1; 1083 subpass_desc.pColorAttachments = &att_ref; 1084 } else { 1085 subpass_desc.pDepthStencilAttachment = &att_ref; 1086 } 1087 1088 VkRenderPass pass; 1089 radv_CreateRenderPass(device_h, 1090 &(VkRenderPassCreateInfo) { 1091 .sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, 1092 .attachmentCount = 1, 1093 .pAttachments = &att_desc, 1094 .subpassCount = 1, 1095 .pSubpasses = &subpass_desc, 1096 }, 1097 &cmd_buffer->pool->alloc, 1098 &pass); 1099 1100 radv_CmdBeginRenderPass(radv_cmd_buffer_to_handle(cmd_buffer), 1101 &(VkRenderPassBeginInfo) { 1102 .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, 1103 .renderArea = { 1104 .offset = { 0, 0, }, 1105 .extent = { 1106 .width = iview.extent.width, 1107 .height = iview.extent.height, 1108 }, 1109 }, 1110 .renderPass = pass, 1111 .framebuffer = fb, 1112 .clearValueCount = 0, 1113 .pClearValues = NULL, 1114 }, 1115 VK_SUBPASS_CONTENTS_INLINE); 1116 1117 VkClearAttachment clear_att = { 1118 .aspectMask = range->aspectMask, 1119 .colorAttachment = 0, 1120 .clearValue = *clear_val, 1121 }; 1122 1123 VkClearRect clear_rect = { 1124 .rect = { 1125 .offset = { 0, 0 }, 1126 .extent = { iview.extent.width, iview.extent.height }, 1127 }, 1128 .baseArrayLayer = range->baseArrayLayer, 1129 .layerCount = 1, /* FINISHME: clear multi-layer framebuffer */ 1130 }; 1131 1132 emit_clear(cmd_buffer, &clear_att, &clear_rect); 1133 1134 radv_CmdEndRenderPass(radv_cmd_buffer_to_handle(cmd_buffer)); 1135 radv_DestroyRenderPass(device_h, pass, 1136 &cmd_buffer->pool->alloc); 1137 radv_DestroyFramebuffer(device_h, fb, 1138 &cmd_buffer->pool->alloc); 1139 } 1140 static void 1141 radv_cmd_clear_image(struct radv_cmd_buffer *cmd_buffer, 1142 struct radv_image *image, 1143 VkImageLayout image_layout, 1144 const VkClearValue *clear_value, 1145 uint32_t range_count, 1146 const VkImageSubresourceRange *ranges, 1147 bool cs) 1148 { 1149 VkFormat format = image->vk_format; 1150 VkClearValue internal_clear_value = *clear_value; 1151 1152 if (format == VK_FORMAT_E5B9G9R9_UFLOAT_PACK32) { 1153 uint32_t value; 1154 format = VK_FORMAT_R32_UINT; 1155 value = float3_to_rgb9e5(clear_value->color.float32); 1156 internal_clear_value.color.uint32[0] = value; 1157 } 1158 1159 for (uint32_t r = 0; r < range_count; r++) { 1160 const VkImageSubresourceRange *range = &ranges[r]; 1161 for (uint32_t l = 0; l < radv_get_levelCount(image, range); ++l) { 1162 const uint32_t layer_count = image->type == VK_IMAGE_TYPE_3D ? 1163 radv_minify(image->extent.depth, range->baseMipLevel + l) : 1164 radv_get_layerCount(image, range); 1165 for (uint32_t s = 0; s < layer_count; ++s) { 1166 1167 if (cs) { 1168 struct radv_meta_blit2d_surf surf; 1169 surf.format = format; 1170 surf.image = image; 1171 surf.level = range->baseMipLevel + l; 1172 surf.layer = range->baseArrayLayer + s; 1173 surf.aspect_mask = range->aspectMask; 1174 radv_meta_clear_image_cs(cmd_buffer, &surf, 1175 &internal_clear_value.color); 1176 } else { 1177 radv_clear_image_layer(cmd_buffer, image, image_layout, 1178 range, format, l, s, &internal_clear_value); 1179 } 1180 } 1181 } 1182 } 1183 } 1184 1185 union meta_saved_state { 1186 struct radv_meta_saved_state gfx; 1187 struct radv_meta_saved_compute_state compute; 1188 }; 1189 1190 void radv_CmdClearColorImage( 1191 VkCommandBuffer commandBuffer, 1192 VkImage image_h, 1193 VkImageLayout imageLayout, 1194 const VkClearColorValue* pColor, 1195 uint32_t rangeCount, 1196 const VkImageSubresourceRange* pRanges) 1197 { 1198 RADV_FROM_HANDLE(radv_cmd_buffer, cmd_buffer, commandBuffer); 1199 RADV_FROM_HANDLE(radv_image, image, image_h); 1200 union meta_saved_state saved_state; 1201 bool cs = cmd_buffer->queue_family_index == RADV_QUEUE_COMPUTE; 1202 1203 if (cs) 1204 radv_meta_begin_cleari(cmd_buffer, &saved_state.compute); 1205 else 1206 radv_meta_save_graphics_reset_vport_scissor(&saved_state.gfx, cmd_buffer); 1207 1208 radv_cmd_clear_image(cmd_buffer, image, imageLayout, 1209 (const VkClearValue *) pColor, 1210 rangeCount, pRanges, cs); 1211 1212 if (cs) 1213 radv_meta_end_cleari(cmd_buffer, &saved_state.compute); 1214 else 1215 radv_meta_restore(&saved_state.gfx, cmd_buffer); 1216 } 1217 1218 void radv_CmdClearDepthStencilImage( 1219 VkCommandBuffer commandBuffer, 1220 VkImage image_h, 1221 VkImageLayout imageLayout, 1222 const VkClearDepthStencilValue* pDepthStencil, 1223 uint32_t rangeCount, 1224 const VkImageSubresourceRange* pRanges) 1225 { 1226 RADV_FROM_HANDLE(radv_cmd_buffer, cmd_buffer, commandBuffer); 1227 RADV_FROM_HANDLE(radv_image, image, image_h); 1228 struct radv_meta_saved_state saved_state; 1229 1230 radv_meta_save_graphics_reset_vport_scissor(&saved_state, cmd_buffer); 1231 1232 radv_cmd_clear_image(cmd_buffer, image, imageLayout, 1233 (const VkClearValue *) pDepthStencil, 1234 rangeCount, pRanges, false); 1235 1236 radv_meta_restore(&saved_state, cmd_buffer); 1237 } 1238 1239 void radv_CmdClearAttachments( 1240 VkCommandBuffer commandBuffer, 1241 uint32_t attachmentCount, 1242 const VkClearAttachment* pAttachments, 1243 uint32_t rectCount, 1244 const VkClearRect* pRects) 1245 { 1246 RADV_FROM_HANDLE(radv_cmd_buffer, cmd_buffer, commandBuffer); 1247 struct radv_meta_saved_state saved_state; 1248 1249 if (!cmd_buffer->state.subpass) 1250 return; 1251 1252 radv_meta_save_graphics_reset_vport_scissor(&saved_state, cmd_buffer); 1253 1254 /* FINISHME: We can do better than this dumb loop. It thrashes too much 1255 * state. 1256 */ 1257 for (uint32_t a = 0; a < attachmentCount; ++a) { 1258 for (uint32_t r = 0; r < rectCount; ++r) { 1259 emit_clear(cmd_buffer, &pAttachments[a], &pRects[r]); 1260 } 1261 } 1262 1263 radv_meta_restore(&saved_state, cmd_buffer); 1264 } 1265