1bf215546Sopenharmony_ci/* 2bf215546Sopenharmony_ci * Copyright © 2015 Intel Corporation 3bf215546Sopenharmony_ci * 4bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 5bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"), 6bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation 7bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the 9bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions: 10bf215546Sopenharmony_ci * 11bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the next 12bf215546Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the 13bf215546Sopenharmony_ci * Software. 14bf215546Sopenharmony_ci * 15bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19bf215546Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20bf215546Sopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21bf215546Sopenharmony_ci * IN THE SOFTWARE. 22bf215546Sopenharmony_ci */ 23bf215546Sopenharmony_ci 24bf215546Sopenharmony_ci#include "nir/nir_builder.h" 25bf215546Sopenharmony_ci#include "radv_debug.h" 26bf215546Sopenharmony_ci#include "radv_meta.h" 27bf215546Sopenharmony_ci#include "radv_private.h" 28bf215546Sopenharmony_ci 29bf215546Sopenharmony_ci#include "util/format_rgb9e5.h" 30bf215546Sopenharmony_ci#include "vk_format.h" 31bf215546Sopenharmony_ci 32bf215546Sopenharmony_cienum { DEPTH_CLEAR_SLOW, DEPTH_CLEAR_FAST }; 33bf215546Sopenharmony_ci 34bf215546Sopenharmony_cistatic void 35bf215546Sopenharmony_cibuild_color_shaders(struct radv_device *dev, struct nir_shader **out_vs, struct nir_shader **out_fs, 36bf215546Sopenharmony_ci uint32_t frag_output) 37bf215546Sopenharmony_ci{ 38bf215546Sopenharmony_ci nir_builder vs_b = radv_meta_init_shader(dev, MESA_SHADER_VERTEX, "meta_clear_color_vs"); 39bf215546Sopenharmony_ci nir_builder fs_b = 40bf215546Sopenharmony_ci radv_meta_init_shader(dev, MESA_SHADER_FRAGMENT, "meta_clear_color_fs-%d", frag_output); 41bf215546Sopenharmony_ci 42bf215546Sopenharmony_ci const struct glsl_type *position_type = glsl_vec4_type(); 43bf215546Sopenharmony_ci const struct glsl_type *color_type = glsl_vec4_type(); 44bf215546Sopenharmony_ci 45bf215546Sopenharmony_ci nir_variable *vs_out_pos = 46bf215546Sopenharmony_ci nir_variable_create(vs_b.shader, nir_var_shader_out, position_type, "gl_Position"); 47bf215546Sopenharmony_ci vs_out_pos->data.location = VARYING_SLOT_POS; 48bf215546Sopenharmony_ci 49bf215546Sopenharmony_ci nir_ssa_def *in_color_load = 50bf215546Sopenharmony_ci nir_load_push_constant(&fs_b, 4, 32, nir_imm_int(&fs_b, 0), .range = 16); 51bf215546Sopenharmony_ci 52bf215546Sopenharmony_ci nir_variable *fs_out_color = 53bf215546Sopenharmony_ci nir_variable_create(fs_b.shader, nir_var_shader_out, color_type, "f_color"); 54bf215546Sopenharmony_ci fs_out_color->data.location = FRAG_RESULT_DATA0 + frag_output; 55bf215546Sopenharmony_ci 56bf215546Sopenharmony_ci nir_store_var(&fs_b, fs_out_color, in_color_load, 0xf); 57bf215546Sopenharmony_ci 58bf215546Sopenharmony_ci nir_ssa_def *outvec = nir_gen_rect_vertices(&vs_b, NULL, NULL); 59bf215546Sopenharmony_ci nir_store_var(&vs_b, vs_out_pos, outvec, 0xf); 60bf215546Sopenharmony_ci 61bf215546Sopenharmony_ci const struct glsl_type *layer_type = glsl_int_type(); 62bf215546Sopenharmony_ci nir_variable *vs_out_layer = 63bf215546Sopenharmony_ci nir_variable_create(vs_b.shader, nir_var_shader_out, layer_type, "v_layer"); 64bf215546Sopenharmony_ci vs_out_layer->data.location = VARYING_SLOT_LAYER; 65bf215546Sopenharmony_ci vs_out_layer->data.interpolation = INTERP_MODE_FLAT; 66bf215546Sopenharmony_ci nir_ssa_def *inst_id = nir_load_instance_id(&vs_b); 67bf215546Sopenharmony_ci nir_ssa_def *base_instance = nir_load_base_instance(&vs_b); 68bf215546Sopenharmony_ci 69bf215546Sopenharmony_ci nir_ssa_def *layer_id = nir_iadd(&vs_b, inst_id, base_instance); 70bf215546Sopenharmony_ci nir_store_var(&vs_b, vs_out_layer, layer_id, 0x1); 71bf215546Sopenharmony_ci 72bf215546Sopenharmony_ci *out_vs = vs_b.shader; 73bf215546Sopenharmony_ci *out_fs = fs_b.shader; 74bf215546Sopenharmony_ci} 75bf215546Sopenharmony_ci 76bf215546Sopenharmony_cistatic VkResult 77bf215546Sopenharmony_cicreate_pipeline(struct radv_device *device, uint32_t samples, 78bf215546Sopenharmony_ci struct nir_shader *vs_nir, struct nir_shader *fs_nir, 79bf215546Sopenharmony_ci const VkPipelineVertexInputStateCreateInfo *vi_state, 80bf215546Sopenharmony_ci const VkPipelineDepthStencilStateCreateInfo *ds_state, 81bf215546Sopenharmony_ci const VkPipelineColorBlendStateCreateInfo *cb_state, 82bf215546Sopenharmony_ci const VkPipelineRenderingCreateInfo *dyn_state, 83bf215546Sopenharmony_ci const VkPipelineLayout layout, 84bf215546Sopenharmony_ci const struct radv_graphics_pipeline_create_info *extra, 85bf215546Sopenharmony_ci const VkAllocationCallbacks *alloc, VkPipeline *pipeline) 86bf215546Sopenharmony_ci{ 87bf215546Sopenharmony_ci VkDevice device_h = radv_device_to_handle(device); 88bf215546Sopenharmony_ci VkResult result; 89bf215546Sopenharmony_ci 90bf215546Sopenharmony_ci result = radv_graphics_pipeline_create( 91bf215546Sopenharmony_ci device_h, radv_pipeline_cache_to_handle(&device->meta_state.cache), 92bf215546Sopenharmony_ci &(VkGraphicsPipelineCreateInfo){ 93bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, 94bf215546Sopenharmony_ci .pNext = dyn_state, 95bf215546Sopenharmony_ci .stageCount = fs_nir ? 2 : 1, 96bf215546Sopenharmony_ci .pStages = 97bf215546Sopenharmony_ci (VkPipelineShaderStageCreateInfo[]){ 98bf215546Sopenharmony_ci { 99bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, 100bf215546Sopenharmony_ci .stage = VK_SHADER_STAGE_VERTEX_BIT, 101bf215546Sopenharmony_ci .module = vk_shader_module_handle_from_nir(vs_nir), 102bf215546Sopenharmony_ci .pName = "main", 103bf215546Sopenharmony_ci }, 104bf215546Sopenharmony_ci { 105bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, 106bf215546Sopenharmony_ci .stage = VK_SHADER_STAGE_FRAGMENT_BIT, 107bf215546Sopenharmony_ci .module = vk_shader_module_handle_from_nir(fs_nir), 108bf215546Sopenharmony_ci .pName = "main", 109bf215546Sopenharmony_ci }, 110bf215546Sopenharmony_ci }, 111bf215546Sopenharmony_ci .pVertexInputState = vi_state, 112bf215546Sopenharmony_ci .pInputAssemblyState = 113bf215546Sopenharmony_ci &(VkPipelineInputAssemblyStateCreateInfo){ 114bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, 115bf215546Sopenharmony_ci .topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, 116bf215546Sopenharmony_ci .primitiveRestartEnable = false, 117bf215546Sopenharmony_ci }, 118bf215546Sopenharmony_ci .pViewportState = 119bf215546Sopenharmony_ci &(VkPipelineViewportStateCreateInfo){ 120bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, 121bf215546Sopenharmony_ci .viewportCount = 1, 122bf215546Sopenharmony_ci .scissorCount = 1, 123bf215546Sopenharmony_ci }, 124bf215546Sopenharmony_ci .pRasterizationState = 125bf215546Sopenharmony_ci &(VkPipelineRasterizationStateCreateInfo){ 126bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, 127bf215546Sopenharmony_ci .rasterizerDiscardEnable = false, 128bf215546Sopenharmony_ci .polygonMode = VK_POLYGON_MODE_FILL, 129bf215546Sopenharmony_ci .cullMode = VK_CULL_MODE_NONE, 130bf215546Sopenharmony_ci .frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE, 131bf215546Sopenharmony_ci .depthBiasEnable = false, 132bf215546Sopenharmony_ci .depthBiasConstantFactor = 0.0f, 133bf215546Sopenharmony_ci .depthBiasClamp = 0.0f, 134bf215546Sopenharmony_ci .depthBiasSlopeFactor = 0.0f, 135bf215546Sopenharmony_ci .lineWidth = 1.0f, 136bf215546Sopenharmony_ci }, 137bf215546Sopenharmony_ci .pMultisampleState = 138bf215546Sopenharmony_ci &(VkPipelineMultisampleStateCreateInfo){ 139bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, 140bf215546Sopenharmony_ci .rasterizationSamples = samples, 141bf215546Sopenharmony_ci .sampleShadingEnable = false, 142bf215546Sopenharmony_ci .pSampleMask = NULL, 143bf215546Sopenharmony_ci .alphaToCoverageEnable = false, 144bf215546Sopenharmony_ci .alphaToOneEnable = false, 145bf215546Sopenharmony_ci }, 146bf215546Sopenharmony_ci .pDepthStencilState = ds_state, 147bf215546Sopenharmony_ci .pColorBlendState = cb_state, 148bf215546Sopenharmony_ci .pDynamicState = 149bf215546Sopenharmony_ci &(VkPipelineDynamicStateCreateInfo){ 150bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, 151bf215546Sopenharmony_ci .dynamicStateCount = 3, 152bf215546Sopenharmony_ci .pDynamicStates = 153bf215546Sopenharmony_ci (VkDynamicState[]){ 154bf215546Sopenharmony_ci VK_DYNAMIC_STATE_VIEWPORT, 155bf215546Sopenharmony_ci VK_DYNAMIC_STATE_SCISSOR, 156bf215546Sopenharmony_ci VK_DYNAMIC_STATE_STENCIL_REFERENCE, 157bf215546Sopenharmony_ci }, 158bf215546Sopenharmony_ci }, 159bf215546Sopenharmony_ci .layout = layout, 160bf215546Sopenharmony_ci .flags = 0, 161bf215546Sopenharmony_ci .renderPass = VK_NULL_HANDLE, 162bf215546Sopenharmony_ci .subpass = 0, 163bf215546Sopenharmony_ci }, 164bf215546Sopenharmony_ci extra, alloc, pipeline); 165bf215546Sopenharmony_ci 166bf215546Sopenharmony_ci ralloc_free(vs_nir); 167bf215546Sopenharmony_ci ralloc_free(fs_nir); 168bf215546Sopenharmony_ci 169bf215546Sopenharmony_ci return result; 170bf215546Sopenharmony_ci} 171bf215546Sopenharmony_ci 172bf215546Sopenharmony_cistatic VkResult 173bf215546Sopenharmony_cicreate_color_pipeline(struct radv_device *device, uint32_t samples, uint32_t frag_output, 174bf215546Sopenharmony_ci VkFormat format, VkPipeline *pipeline) 175bf215546Sopenharmony_ci{ 176bf215546Sopenharmony_ci struct nir_shader *vs_nir; 177bf215546Sopenharmony_ci struct nir_shader *fs_nir; 178bf215546Sopenharmony_ci VkResult result; 179bf215546Sopenharmony_ci 180bf215546Sopenharmony_ci mtx_lock(&device->meta_state.mtx); 181bf215546Sopenharmony_ci if (*pipeline) { 182bf215546Sopenharmony_ci mtx_unlock(&device->meta_state.mtx); 183bf215546Sopenharmony_ci return VK_SUCCESS; 184bf215546Sopenharmony_ci } 185bf215546Sopenharmony_ci 186bf215546Sopenharmony_ci build_color_shaders(device, &vs_nir, &fs_nir, frag_output); 187bf215546Sopenharmony_ci 188bf215546Sopenharmony_ci const VkPipelineVertexInputStateCreateInfo vi_state = { 189bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, 190bf215546Sopenharmony_ci .vertexBindingDescriptionCount = 0, 191bf215546Sopenharmony_ci .vertexAttributeDescriptionCount = 0, 192bf215546Sopenharmony_ci }; 193bf215546Sopenharmony_ci 194bf215546Sopenharmony_ci const VkPipelineDepthStencilStateCreateInfo ds_state = { 195bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, 196bf215546Sopenharmony_ci .depthTestEnable = false, 197bf215546Sopenharmony_ci .depthWriteEnable = false, 198bf215546Sopenharmony_ci .depthBoundsTestEnable = false, 199bf215546Sopenharmony_ci .stencilTestEnable = false, 200bf215546Sopenharmony_ci .minDepthBounds = 0.0f, 201bf215546Sopenharmony_ci .maxDepthBounds = 1.0f, 202bf215546Sopenharmony_ci }; 203bf215546Sopenharmony_ci 204bf215546Sopenharmony_ci VkPipelineColorBlendAttachmentState blend_attachment_state[MAX_RTS] = {0}; 205bf215546Sopenharmony_ci blend_attachment_state[frag_output] = (VkPipelineColorBlendAttachmentState){ 206bf215546Sopenharmony_ci .blendEnable = false, 207bf215546Sopenharmony_ci .colorWriteMask = VK_COLOR_COMPONENT_A_BIT | VK_COLOR_COMPONENT_R_BIT | 208bf215546Sopenharmony_ci VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT, 209bf215546Sopenharmony_ci }; 210bf215546Sopenharmony_ci 211bf215546Sopenharmony_ci const VkPipelineColorBlendStateCreateInfo cb_state = { 212bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, 213bf215546Sopenharmony_ci .logicOpEnable = false, 214bf215546Sopenharmony_ci .attachmentCount = MAX_RTS, 215bf215546Sopenharmony_ci .pAttachments = blend_attachment_state, 216bf215546Sopenharmony_ci .blendConstants = { 0.0f, 0.0f, 0.0f, 0.0f }}; 217bf215546Sopenharmony_ci 218bf215546Sopenharmony_ci VkFormat att_formats[MAX_RTS] = { 0 }; 219bf215546Sopenharmony_ci att_formats[frag_output] = format; 220bf215546Sopenharmony_ci 221bf215546Sopenharmony_ci const VkPipelineRenderingCreateInfo rendering_create_info = { 222bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO, 223bf215546Sopenharmony_ci .colorAttachmentCount = MAX_RTS, 224bf215546Sopenharmony_ci .pColorAttachmentFormats = att_formats, 225bf215546Sopenharmony_ci }; 226bf215546Sopenharmony_ci 227bf215546Sopenharmony_ci struct radv_graphics_pipeline_create_info extra = { 228bf215546Sopenharmony_ci .use_rectlist = true, 229bf215546Sopenharmony_ci }; 230bf215546Sopenharmony_ci result = 231bf215546Sopenharmony_ci create_pipeline(device, samples, vs_nir, fs_nir, &vi_state, &ds_state, &cb_state, 232bf215546Sopenharmony_ci &rendering_create_info, device->meta_state.clear_color_p_layout, 233bf215546Sopenharmony_ci &extra, &device->meta_state.alloc, pipeline); 234bf215546Sopenharmony_ci 235bf215546Sopenharmony_ci mtx_unlock(&device->meta_state.mtx); 236bf215546Sopenharmony_ci return result; 237bf215546Sopenharmony_ci} 238bf215546Sopenharmony_ci 239bf215546Sopenharmony_cistatic void 240bf215546Sopenharmony_cifinish_meta_clear_htile_mask_state(struct radv_device *device) 241bf215546Sopenharmony_ci{ 242bf215546Sopenharmony_ci struct radv_meta_state *state = &device->meta_state; 243bf215546Sopenharmony_ci 244bf215546Sopenharmony_ci radv_DestroyPipeline(radv_device_to_handle(device), state->clear_htile_mask_pipeline, 245bf215546Sopenharmony_ci &state->alloc); 246bf215546Sopenharmony_ci radv_DestroyPipelineLayout(radv_device_to_handle(device), state->clear_htile_mask_p_layout, 247bf215546Sopenharmony_ci &state->alloc); 248bf215546Sopenharmony_ci device->vk.dispatch_table.DestroyDescriptorSetLayout( 249bf215546Sopenharmony_ci radv_device_to_handle(device), state->clear_htile_mask_ds_layout, &state->alloc); 250bf215546Sopenharmony_ci} 251bf215546Sopenharmony_ci 252bf215546Sopenharmony_cistatic void 253bf215546Sopenharmony_cifinish_meta_clear_dcc_comp_to_single_state(struct radv_device *device) 254bf215546Sopenharmony_ci{ 255bf215546Sopenharmony_ci struct radv_meta_state *state = &device->meta_state; 256bf215546Sopenharmony_ci 257bf215546Sopenharmony_ci for (uint32_t i = 0; i < 2; i++) { 258bf215546Sopenharmony_ci radv_DestroyPipeline(radv_device_to_handle(device), 259bf215546Sopenharmony_ci state->clear_dcc_comp_to_single_pipeline[i], &state->alloc); 260bf215546Sopenharmony_ci } 261bf215546Sopenharmony_ci radv_DestroyPipelineLayout(radv_device_to_handle(device), state->clear_dcc_comp_to_single_p_layout, 262bf215546Sopenharmony_ci &state->alloc); 263bf215546Sopenharmony_ci device->vk.dispatch_table.DestroyDescriptorSetLayout( 264bf215546Sopenharmony_ci radv_device_to_handle(device), state->clear_dcc_comp_to_single_ds_layout, &state->alloc); 265bf215546Sopenharmony_ci} 266bf215546Sopenharmony_ci 267bf215546Sopenharmony_civoid 268bf215546Sopenharmony_ciradv_device_finish_meta_clear_state(struct radv_device *device) 269bf215546Sopenharmony_ci{ 270bf215546Sopenharmony_ci struct radv_meta_state *state = &device->meta_state; 271bf215546Sopenharmony_ci 272bf215546Sopenharmony_ci for (uint32_t i = 0; i < ARRAY_SIZE(state->color_clear); ++i) { 273bf215546Sopenharmony_ci for (uint32_t j = 0; j < ARRAY_SIZE(state->color_clear[0]); ++j) { 274bf215546Sopenharmony_ci for (uint32_t k = 0; k < ARRAY_SIZE(state->color_clear[i][j].color_pipelines); ++k) { 275bf215546Sopenharmony_ci radv_DestroyPipeline(radv_device_to_handle(device), 276bf215546Sopenharmony_ci state->color_clear[i][j].color_pipelines[k], &state->alloc); 277bf215546Sopenharmony_ci } 278bf215546Sopenharmony_ci } 279bf215546Sopenharmony_ci } 280bf215546Sopenharmony_ci for (uint32_t i = 0; i < ARRAY_SIZE(state->ds_clear); ++i) { 281bf215546Sopenharmony_ci for (uint32_t j = 0; j < NUM_DEPTH_CLEAR_PIPELINES; j++) { 282bf215546Sopenharmony_ci radv_DestroyPipeline(radv_device_to_handle(device), 283bf215546Sopenharmony_ci state->ds_clear[i].depth_only_pipeline[j], &state->alloc); 284bf215546Sopenharmony_ci radv_DestroyPipeline(radv_device_to_handle(device), 285bf215546Sopenharmony_ci state->ds_clear[i].stencil_only_pipeline[j], &state->alloc); 286bf215546Sopenharmony_ci radv_DestroyPipeline(radv_device_to_handle(device), 287bf215546Sopenharmony_ci state->ds_clear[i].depthstencil_pipeline[j], &state->alloc); 288bf215546Sopenharmony_ci 289bf215546Sopenharmony_ci radv_DestroyPipeline(radv_device_to_handle(device), 290bf215546Sopenharmony_ci state->ds_clear[i].depth_only_unrestricted_pipeline[j], 291bf215546Sopenharmony_ci &state->alloc); 292bf215546Sopenharmony_ci radv_DestroyPipeline(radv_device_to_handle(device), 293bf215546Sopenharmony_ci state->ds_clear[i].stencil_only_unrestricted_pipeline[j], 294bf215546Sopenharmony_ci &state->alloc); 295bf215546Sopenharmony_ci radv_DestroyPipeline(radv_device_to_handle(device), 296bf215546Sopenharmony_ci state->ds_clear[i].depthstencil_unrestricted_pipeline[j], 297bf215546Sopenharmony_ci &state->alloc); 298bf215546Sopenharmony_ci } 299bf215546Sopenharmony_ci } 300bf215546Sopenharmony_ci radv_DestroyPipelineLayout(radv_device_to_handle(device), state->clear_color_p_layout, 301bf215546Sopenharmony_ci &state->alloc); 302bf215546Sopenharmony_ci radv_DestroyPipelineLayout(radv_device_to_handle(device), state->clear_depth_p_layout, 303bf215546Sopenharmony_ci &state->alloc); 304bf215546Sopenharmony_ci radv_DestroyPipelineLayout(radv_device_to_handle(device), 305bf215546Sopenharmony_ci state->clear_depth_unrestricted_p_layout, &state->alloc); 306bf215546Sopenharmony_ci 307bf215546Sopenharmony_ci finish_meta_clear_htile_mask_state(device); 308bf215546Sopenharmony_ci finish_meta_clear_dcc_comp_to_single_state(device); 309bf215546Sopenharmony_ci} 310bf215546Sopenharmony_ci 311bf215546Sopenharmony_cistatic void 312bf215546Sopenharmony_ciemit_color_clear(struct radv_cmd_buffer *cmd_buffer, const VkClearAttachment *clear_att, 313bf215546Sopenharmony_ci const VkClearRect *clear_rect, uint32_t view_mask) 314bf215546Sopenharmony_ci{ 315bf215546Sopenharmony_ci struct radv_device *device = cmd_buffer->device; 316bf215546Sopenharmony_ci const struct radv_subpass *subpass = cmd_buffer->state.subpass; 317bf215546Sopenharmony_ci const uint32_t subpass_att = clear_att->colorAttachment; 318bf215546Sopenharmony_ci const uint32_t pass_att = subpass->color_attachments[subpass_att].attachment; 319bf215546Sopenharmony_ci const struct radv_image_view *iview = 320bf215546Sopenharmony_ci cmd_buffer->state.attachments ? cmd_buffer->state.attachments[pass_att].iview : NULL; 321bf215546Sopenharmony_ci uint32_t samples, samples_log2; 322bf215546Sopenharmony_ci VkFormat format; 323bf215546Sopenharmony_ci unsigned fs_key; 324bf215546Sopenharmony_ci VkClearColorValue clear_value = clear_att->clearValue.color; 325bf215546Sopenharmony_ci VkCommandBuffer cmd_buffer_h = radv_cmd_buffer_to_handle(cmd_buffer); 326bf215546Sopenharmony_ci VkPipeline pipeline; 327bf215546Sopenharmony_ci 328bf215546Sopenharmony_ci /* When a framebuffer is bound to the current command buffer, get the 329bf215546Sopenharmony_ci * number of samples from it. Otherwise, get the number of samples from 330bf215546Sopenharmony_ci * the render pass because it's likely a secondary command buffer. 331bf215546Sopenharmony_ci */ 332bf215546Sopenharmony_ci if (iview) { 333bf215546Sopenharmony_ci samples = iview->image->info.samples; 334bf215546Sopenharmony_ci format = iview->vk.format; 335bf215546Sopenharmony_ci } else { 336bf215546Sopenharmony_ci samples = cmd_buffer->state.pass->attachments[pass_att].samples; 337bf215546Sopenharmony_ci format = cmd_buffer->state.pass->attachments[pass_att].format; 338bf215546Sopenharmony_ci } 339bf215546Sopenharmony_ci 340bf215546Sopenharmony_ci samples_log2 = ffs(samples) - 1; 341bf215546Sopenharmony_ci fs_key = radv_format_meta_fs_key(device, format); 342bf215546Sopenharmony_ci assert(fs_key != -1); 343bf215546Sopenharmony_ci 344bf215546Sopenharmony_ci if (device->meta_state.color_clear[samples_log2][clear_att->colorAttachment] 345bf215546Sopenharmony_ci .color_pipelines[fs_key] == VK_NULL_HANDLE) { 346bf215546Sopenharmony_ci VkResult ret = create_color_pipeline( 347bf215546Sopenharmony_ci device, samples, clear_att->colorAttachment, radv_fs_key_format_exemplars[fs_key], 348bf215546Sopenharmony_ci &device->meta_state.color_clear[samples_log2][clear_att->colorAttachment] 349bf215546Sopenharmony_ci .color_pipelines[fs_key]); 350bf215546Sopenharmony_ci if (ret != VK_SUCCESS) { 351bf215546Sopenharmony_ci cmd_buffer->record_result = ret; 352bf215546Sopenharmony_ci return; 353bf215546Sopenharmony_ci } 354bf215546Sopenharmony_ci } 355bf215546Sopenharmony_ci 356bf215546Sopenharmony_ci pipeline = device->meta_state.color_clear[samples_log2][clear_att->colorAttachment] 357bf215546Sopenharmony_ci .color_pipelines[fs_key]; 358bf215546Sopenharmony_ci 359bf215546Sopenharmony_ci assert(samples_log2 < ARRAY_SIZE(device->meta_state.color_clear)); 360bf215546Sopenharmony_ci assert(pipeline); 361bf215546Sopenharmony_ci assert(clear_att->aspectMask == VK_IMAGE_ASPECT_COLOR_BIT); 362bf215546Sopenharmony_ci assert(clear_att->colorAttachment < subpass->color_count); 363bf215546Sopenharmony_ci 364bf215546Sopenharmony_ci radv_CmdPushConstants(radv_cmd_buffer_to_handle(cmd_buffer), 365bf215546Sopenharmony_ci device->meta_state.clear_color_p_layout, VK_SHADER_STAGE_FRAGMENT_BIT, 0, 366bf215546Sopenharmony_ci 16, &clear_value); 367bf215546Sopenharmony_ci 368bf215546Sopenharmony_ci radv_CmdBindPipeline(cmd_buffer_h, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline); 369bf215546Sopenharmony_ci 370bf215546Sopenharmony_ci radv_CmdSetViewport(radv_cmd_buffer_to_handle(cmd_buffer), 0, 1, 371bf215546Sopenharmony_ci &(VkViewport){.x = clear_rect->rect.offset.x, 372bf215546Sopenharmony_ci .y = clear_rect->rect.offset.y, 373bf215546Sopenharmony_ci .width = clear_rect->rect.extent.width, 374bf215546Sopenharmony_ci .height = clear_rect->rect.extent.height, 375bf215546Sopenharmony_ci .minDepth = 0.0f, 376bf215546Sopenharmony_ci .maxDepth = 1.0f}); 377bf215546Sopenharmony_ci 378bf215546Sopenharmony_ci radv_CmdSetScissor(radv_cmd_buffer_to_handle(cmd_buffer), 0, 1, &clear_rect->rect); 379bf215546Sopenharmony_ci 380bf215546Sopenharmony_ci if (view_mask) { 381bf215546Sopenharmony_ci u_foreach_bit(i, view_mask) radv_CmdDraw(cmd_buffer_h, 3, 1, 0, i); 382bf215546Sopenharmony_ci } else { 383bf215546Sopenharmony_ci radv_CmdDraw(cmd_buffer_h, 3, clear_rect->layerCount, 0, clear_rect->baseArrayLayer); 384bf215546Sopenharmony_ci } 385bf215546Sopenharmony_ci} 386bf215546Sopenharmony_ci 387bf215546Sopenharmony_cistatic void 388bf215546Sopenharmony_cibuild_depthstencil_shader(struct radv_device *dev, struct nir_shader **out_vs, 389bf215546Sopenharmony_ci struct nir_shader **out_fs, bool unrestricted) 390bf215546Sopenharmony_ci{ 391bf215546Sopenharmony_ci nir_builder vs_b = radv_meta_init_shader( 392bf215546Sopenharmony_ci dev, MESA_SHADER_VERTEX, 393bf215546Sopenharmony_ci unrestricted ? "meta_clear_depthstencil_unrestricted_vs" : "meta_clear_depthstencil_vs"); 394bf215546Sopenharmony_ci nir_builder fs_b = radv_meta_init_shader( 395bf215546Sopenharmony_ci dev, MESA_SHADER_FRAGMENT, 396bf215546Sopenharmony_ci unrestricted ? "meta_clear_depthstencil_unrestricted_fs" : "meta_clear_depthstencil_fs"); 397bf215546Sopenharmony_ci 398bf215546Sopenharmony_ci const struct glsl_type *position_out_type = glsl_vec4_type(); 399bf215546Sopenharmony_ci 400bf215546Sopenharmony_ci nir_variable *vs_out_pos = 401bf215546Sopenharmony_ci nir_variable_create(vs_b.shader, nir_var_shader_out, position_out_type, "gl_Position"); 402bf215546Sopenharmony_ci vs_out_pos->data.location = VARYING_SLOT_POS; 403bf215546Sopenharmony_ci 404bf215546Sopenharmony_ci nir_ssa_def *z; 405bf215546Sopenharmony_ci if (unrestricted) { 406bf215546Sopenharmony_ci nir_ssa_def *in_color_load = 407bf215546Sopenharmony_ci nir_load_push_constant(&fs_b, 1, 32, nir_imm_int(&fs_b, 0), .range = 4); 408bf215546Sopenharmony_ci 409bf215546Sopenharmony_ci nir_variable *fs_out_depth = 410bf215546Sopenharmony_ci nir_variable_create(fs_b.shader, nir_var_shader_out, glsl_int_type(), "f_depth"); 411bf215546Sopenharmony_ci fs_out_depth->data.location = FRAG_RESULT_DEPTH; 412bf215546Sopenharmony_ci nir_store_var(&fs_b, fs_out_depth, in_color_load, 0x1); 413bf215546Sopenharmony_ci 414bf215546Sopenharmony_ci z = nir_imm_float(&vs_b, 0.0); 415bf215546Sopenharmony_ci } else { 416bf215546Sopenharmony_ci z = nir_load_push_constant(&vs_b, 1, 32, nir_imm_int(&vs_b, 0), .range = 4); 417bf215546Sopenharmony_ci } 418bf215546Sopenharmony_ci 419bf215546Sopenharmony_ci nir_ssa_def *outvec = nir_gen_rect_vertices(&vs_b, z, NULL); 420bf215546Sopenharmony_ci nir_store_var(&vs_b, vs_out_pos, outvec, 0xf); 421bf215546Sopenharmony_ci 422bf215546Sopenharmony_ci const struct glsl_type *layer_type = glsl_int_type(); 423bf215546Sopenharmony_ci nir_variable *vs_out_layer = 424bf215546Sopenharmony_ci nir_variable_create(vs_b.shader, nir_var_shader_out, layer_type, "v_layer"); 425bf215546Sopenharmony_ci vs_out_layer->data.location = VARYING_SLOT_LAYER; 426bf215546Sopenharmony_ci vs_out_layer->data.interpolation = INTERP_MODE_FLAT; 427bf215546Sopenharmony_ci nir_ssa_def *inst_id = nir_load_instance_id(&vs_b); 428bf215546Sopenharmony_ci nir_ssa_def *base_instance = nir_load_base_instance(&vs_b); 429bf215546Sopenharmony_ci 430bf215546Sopenharmony_ci nir_ssa_def *layer_id = nir_iadd(&vs_b, inst_id, base_instance); 431bf215546Sopenharmony_ci nir_store_var(&vs_b, vs_out_layer, layer_id, 0x1); 432bf215546Sopenharmony_ci 433bf215546Sopenharmony_ci *out_vs = vs_b.shader; 434bf215546Sopenharmony_ci *out_fs = fs_b.shader; 435bf215546Sopenharmony_ci} 436bf215546Sopenharmony_ci 437bf215546Sopenharmony_cistatic VkResult 438bf215546Sopenharmony_cicreate_depthstencil_pipeline(struct radv_device *device, VkImageAspectFlags aspects, 439bf215546Sopenharmony_ci uint32_t samples, int index, bool unrestricted, VkPipeline *pipeline) 440bf215546Sopenharmony_ci{ 441bf215546Sopenharmony_ci struct nir_shader *vs_nir, *fs_nir; 442bf215546Sopenharmony_ci VkResult result; 443bf215546Sopenharmony_ci 444bf215546Sopenharmony_ci mtx_lock(&device->meta_state.mtx); 445bf215546Sopenharmony_ci if (*pipeline) { 446bf215546Sopenharmony_ci mtx_unlock(&device->meta_state.mtx); 447bf215546Sopenharmony_ci return VK_SUCCESS; 448bf215546Sopenharmony_ci } 449bf215546Sopenharmony_ci 450bf215546Sopenharmony_ci build_depthstencil_shader(device, &vs_nir, &fs_nir, unrestricted); 451bf215546Sopenharmony_ci 452bf215546Sopenharmony_ci const VkPipelineVertexInputStateCreateInfo vi_state = { 453bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, 454bf215546Sopenharmony_ci .vertexBindingDescriptionCount = 0, 455bf215546Sopenharmony_ci .vertexAttributeDescriptionCount = 0, 456bf215546Sopenharmony_ci }; 457bf215546Sopenharmony_ci 458bf215546Sopenharmony_ci const VkPipelineDepthStencilStateCreateInfo ds_state = { 459bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, 460bf215546Sopenharmony_ci .depthTestEnable = !!(aspects & VK_IMAGE_ASPECT_DEPTH_BIT), 461bf215546Sopenharmony_ci .depthCompareOp = VK_COMPARE_OP_ALWAYS, 462bf215546Sopenharmony_ci .depthWriteEnable = !!(aspects & VK_IMAGE_ASPECT_DEPTH_BIT), 463bf215546Sopenharmony_ci .depthBoundsTestEnable = false, 464bf215546Sopenharmony_ci .stencilTestEnable = !!(aspects & VK_IMAGE_ASPECT_STENCIL_BIT), 465bf215546Sopenharmony_ci .front = 466bf215546Sopenharmony_ci { 467bf215546Sopenharmony_ci .passOp = VK_STENCIL_OP_REPLACE, 468bf215546Sopenharmony_ci .compareOp = VK_COMPARE_OP_ALWAYS, 469bf215546Sopenharmony_ci .writeMask = UINT32_MAX, 470bf215546Sopenharmony_ci .reference = 0, /* dynamic */ 471bf215546Sopenharmony_ci }, 472bf215546Sopenharmony_ci .back = {0 /* dont care */}, 473bf215546Sopenharmony_ci .minDepthBounds = 0.0f, 474bf215546Sopenharmony_ci .maxDepthBounds = 1.0f, 475bf215546Sopenharmony_ci }; 476bf215546Sopenharmony_ci 477bf215546Sopenharmony_ci const VkPipelineColorBlendStateCreateInfo cb_state = { 478bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, 479bf215546Sopenharmony_ci .logicOpEnable = false, 480bf215546Sopenharmony_ci .attachmentCount = 0, 481bf215546Sopenharmony_ci .pAttachments = NULL, 482bf215546Sopenharmony_ci .blendConstants = { 0.0f, 0.0f, 0.0f, 0.0f }, 483bf215546Sopenharmony_ci }; 484bf215546Sopenharmony_ci 485bf215546Sopenharmony_ci const VkPipelineRenderingCreateInfo rendering_create_info = { 486bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO, 487bf215546Sopenharmony_ci .depthAttachmentFormat = 488bf215546Sopenharmony_ci (aspects & VK_IMAGE_ASPECT_DEPTH_BIT) ? VK_FORMAT_D32_SFLOAT : VK_FORMAT_UNDEFINED, 489bf215546Sopenharmony_ci .stencilAttachmentFormat = 490bf215546Sopenharmony_ci (aspects & VK_IMAGE_ASPECT_STENCIL_BIT) ? VK_FORMAT_S8_UINT : VK_FORMAT_UNDEFINED, 491bf215546Sopenharmony_ci }; 492bf215546Sopenharmony_ci 493bf215546Sopenharmony_ci struct radv_graphics_pipeline_create_info extra = { 494bf215546Sopenharmony_ci .use_rectlist = true, 495bf215546Sopenharmony_ci }; 496bf215546Sopenharmony_ci 497bf215546Sopenharmony_ci if (aspects & VK_IMAGE_ASPECT_DEPTH_BIT) { 498bf215546Sopenharmony_ci extra.db_depth_clear = index == DEPTH_CLEAR_SLOW ? false : true; 499bf215546Sopenharmony_ci } 500bf215546Sopenharmony_ci if (aspects & VK_IMAGE_ASPECT_STENCIL_BIT) { 501bf215546Sopenharmony_ci extra.db_stencil_clear = index == DEPTH_CLEAR_SLOW ? false : true; 502bf215546Sopenharmony_ci } 503bf215546Sopenharmony_ci result = 504bf215546Sopenharmony_ci create_pipeline(device, samples, vs_nir, fs_nir, &vi_state, &ds_state, &cb_state, 505bf215546Sopenharmony_ci &rendering_create_info, device->meta_state.clear_depth_p_layout, &extra, 506bf215546Sopenharmony_ci &device->meta_state.alloc, pipeline); 507bf215546Sopenharmony_ci 508bf215546Sopenharmony_ci mtx_unlock(&device->meta_state.mtx); 509bf215546Sopenharmony_ci return result; 510bf215546Sopenharmony_ci} 511bf215546Sopenharmony_ci 512bf215546Sopenharmony_cistatic bool 513bf215546Sopenharmony_cidepth_view_can_fast_clear(struct radv_cmd_buffer *cmd_buffer, const struct radv_image_view *iview, 514bf215546Sopenharmony_ci VkImageAspectFlags aspects, VkImageLayout layout, bool in_render_loop, 515bf215546Sopenharmony_ci const VkClearRect *clear_rect, VkClearDepthStencilValue clear_value) 516bf215546Sopenharmony_ci{ 517bf215546Sopenharmony_ci if (!iview) 518bf215546Sopenharmony_ci return false; 519bf215546Sopenharmony_ci 520bf215546Sopenharmony_ci uint32_t queue_mask = radv_image_queue_family_mask(iview->image, cmd_buffer->qf, 521bf215546Sopenharmony_ci cmd_buffer->qf); 522bf215546Sopenharmony_ci if (clear_rect->rect.offset.x || clear_rect->rect.offset.y || 523bf215546Sopenharmony_ci clear_rect->rect.extent.width != iview->extent.width || 524bf215546Sopenharmony_ci clear_rect->rect.extent.height != iview->extent.height) 525bf215546Sopenharmony_ci return false; 526bf215546Sopenharmony_ci if (radv_image_is_tc_compat_htile(iview->image) && 527bf215546Sopenharmony_ci (((aspects & VK_IMAGE_ASPECT_DEPTH_BIT) && clear_value.depth != 0.0 && 528bf215546Sopenharmony_ci clear_value.depth != 1.0) || 529bf215546Sopenharmony_ci ((aspects & VK_IMAGE_ASPECT_STENCIL_BIT) && clear_value.stencil != 0))) 530bf215546Sopenharmony_ci return false; 531bf215546Sopenharmony_ci if (radv_htile_enabled(iview->image, iview->vk.base_mip_level) && iview->vk.base_mip_level == 0 && 532bf215546Sopenharmony_ci iview->vk.base_array_layer == 0 && iview->vk.layer_count == iview->image->info.array_size && 533bf215546Sopenharmony_ci radv_layout_is_htile_compressed(cmd_buffer->device, iview->image, layout, in_render_loop, 534bf215546Sopenharmony_ci queue_mask) && 535bf215546Sopenharmony_ci radv_image_extent_compare(iview->image, &iview->extent)) 536bf215546Sopenharmony_ci return true; 537bf215546Sopenharmony_ci return false; 538bf215546Sopenharmony_ci} 539bf215546Sopenharmony_ci 540bf215546Sopenharmony_cistatic VkPipeline 541bf215546Sopenharmony_cipick_depthstencil_pipeline(struct radv_cmd_buffer *cmd_buffer, struct radv_meta_state *meta_state, 542bf215546Sopenharmony_ci const struct radv_image_view *iview, int samples_log2, 543bf215546Sopenharmony_ci VkImageAspectFlags aspects, VkImageLayout layout, bool in_render_loop, 544bf215546Sopenharmony_ci const VkClearRect *clear_rect, VkClearDepthStencilValue clear_value) 545bf215546Sopenharmony_ci{ 546bf215546Sopenharmony_ci bool fast = depth_view_can_fast_clear(cmd_buffer, iview, aspects, layout, in_render_loop, 547bf215546Sopenharmony_ci clear_rect, clear_value); 548bf215546Sopenharmony_ci bool unrestricted = cmd_buffer->device->vk.enabled_extensions.EXT_depth_range_unrestricted; 549bf215546Sopenharmony_ci int index = fast ? DEPTH_CLEAR_FAST : DEPTH_CLEAR_SLOW; 550bf215546Sopenharmony_ci VkPipeline *pipeline; 551bf215546Sopenharmony_ci 552bf215546Sopenharmony_ci switch (aspects) { 553bf215546Sopenharmony_ci case VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT: 554bf215546Sopenharmony_ci pipeline = unrestricted 555bf215546Sopenharmony_ci ? &meta_state->ds_clear[samples_log2].depthstencil_unrestricted_pipeline[index] 556bf215546Sopenharmony_ci : &meta_state->ds_clear[samples_log2].depthstencil_pipeline[index]; 557bf215546Sopenharmony_ci break; 558bf215546Sopenharmony_ci case VK_IMAGE_ASPECT_DEPTH_BIT: 559bf215546Sopenharmony_ci pipeline = unrestricted 560bf215546Sopenharmony_ci ? &meta_state->ds_clear[samples_log2].depth_only_unrestricted_pipeline[index] 561bf215546Sopenharmony_ci : &meta_state->ds_clear[samples_log2].depth_only_pipeline[index]; 562bf215546Sopenharmony_ci break; 563bf215546Sopenharmony_ci case VK_IMAGE_ASPECT_STENCIL_BIT: 564bf215546Sopenharmony_ci pipeline = unrestricted 565bf215546Sopenharmony_ci ? &meta_state->ds_clear[samples_log2].stencil_only_unrestricted_pipeline[index] 566bf215546Sopenharmony_ci : &meta_state->ds_clear[samples_log2].stencil_only_pipeline[index]; 567bf215546Sopenharmony_ci break; 568bf215546Sopenharmony_ci default: 569bf215546Sopenharmony_ci unreachable("expected depth or stencil aspect"); 570bf215546Sopenharmony_ci } 571bf215546Sopenharmony_ci 572bf215546Sopenharmony_ci if (*pipeline == VK_NULL_HANDLE) { 573bf215546Sopenharmony_ci VkResult ret = create_depthstencil_pipeline( 574bf215546Sopenharmony_ci cmd_buffer->device, aspects, 1u << samples_log2, index, unrestricted, pipeline); 575bf215546Sopenharmony_ci if (ret != VK_SUCCESS) { 576bf215546Sopenharmony_ci cmd_buffer->record_result = ret; 577bf215546Sopenharmony_ci return VK_NULL_HANDLE; 578bf215546Sopenharmony_ci } 579bf215546Sopenharmony_ci } 580bf215546Sopenharmony_ci return *pipeline; 581bf215546Sopenharmony_ci} 582bf215546Sopenharmony_ci 583bf215546Sopenharmony_cistatic void 584bf215546Sopenharmony_ciemit_depthstencil_clear(struct radv_cmd_buffer *cmd_buffer, const VkClearAttachment *clear_att, 585bf215546Sopenharmony_ci const VkClearRect *clear_rect, struct radv_subpass_attachment *ds_att, 586bf215546Sopenharmony_ci uint32_t view_mask, bool ds_resolve_clear) 587bf215546Sopenharmony_ci{ 588bf215546Sopenharmony_ci struct radv_device *device = cmd_buffer->device; 589bf215546Sopenharmony_ci struct radv_meta_state *meta_state = &device->meta_state; 590bf215546Sopenharmony_ci const struct radv_subpass *subpass = cmd_buffer->state.subpass; 591bf215546Sopenharmony_ci const uint32_t pass_att = ds_att->attachment; 592bf215546Sopenharmony_ci VkClearDepthStencilValue clear_value = clear_att->clearValue.depthStencil; 593bf215546Sopenharmony_ci VkImageAspectFlags aspects = clear_att->aspectMask; 594bf215546Sopenharmony_ci const struct radv_image_view *iview = 595bf215546Sopenharmony_ci cmd_buffer->state.attachments ? cmd_buffer->state.attachments[pass_att].iview : NULL; 596bf215546Sopenharmony_ci uint32_t samples, samples_log2; 597bf215546Sopenharmony_ci VkCommandBuffer cmd_buffer_h = radv_cmd_buffer_to_handle(cmd_buffer); 598bf215546Sopenharmony_ci 599bf215546Sopenharmony_ci /* When a framebuffer is bound to the current command buffer, get the 600bf215546Sopenharmony_ci * number of samples from it. Otherwise, get the number of samples from 601bf215546Sopenharmony_ci * the render pass because it's likely a secondary command buffer. 602bf215546Sopenharmony_ci */ 603bf215546Sopenharmony_ci if (iview) { 604bf215546Sopenharmony_ci samples = iview->image->info.samples; 605bf215546Sopenharmony_ci } else { 606bf215546Sopenharmony_ci samples = cmd_buffer->state.pass->attachments[pass_att].samples; 607bf215546Sopenharmony_ci } 608bf215546Sopenharmony_ci 609bf215546Sopenharmony_ci samples_log2 = ffs(samples) - 1; 610bf215546Sopenharmony_ci 611bf215546Sopenharmony_ci assert(pass_att != VK_ATTACHMENT_UNUSED); 612bf215546Sopenharmony_ci 613bf215546Sopenharmony_ci if (!(aspects & VK_IMAGE_ASPECT_DEPTH_BIT)) 614bf215546Sopenharmony_ci clear_value.depth = 1.0f; 615bf215546Sopenharmony_ci 616bf215546Sopenharmony_ci if (cmd_buffer->device->vk.enabled_extensions.EXT_depth_range_unrestricted) { 617bf215546Sopenharmony_ci radv_CmdPushConstants(radv_cmd_buffer_to_handle(cmd_buffer), 618bf215546Sopenharmony_ci device->meta_state.clear_depth_unrestricted_p_layout, 619bf215546Sopenharmony_ci VK_SHADER_STAGE_FRAGMENT_BIT, 0, 4, &clear_value.depth); 620bf215546Sopenharmony_ci } else { 621bf215546Sopenharmony_ci radv_CmdPushConstants(radv_cmd_buffer_to_handle(cmd_buffer), 622bf215546Sopenharmony_ci device->meta_state.clear_depth_p_layout, VK_SHADER_STAGE_VERTEX_BIT, 0, 623bf215546Sopenharmony_ci 4, &clear_value.depth); 624bf215546Sopenharmony_ci } 625bf215546Sopenharmony_ci 626bf215546Sopenharmony_ci uint32_t prev_reference = cmd_buffer->state.dynamic.stencil_reference.front; 627bf215546Sopenharmony_ci if (aspects & VK_IMAGE_ASPECT_STENCIL_BIT) { 628bf215546Sopenharmony_ci radv_CmdSetStencilReference(cmd_buffer_h, VK_STENCIL_FACE_FRONT_BIT, clear_value.stencil); 629bf215546Sopenharmony_ci } 630bf215546Sopenharmony_ci 631bf215546Sopenharmony_ci VkPipeline pipeline = 632bf215546Sopenharmony_ci pick_depthstencil_pipeline(cmd_buffer, meta_state, iview, samples_log2, aspects, 633bf215546Sopenharmony_ci ds_att->layout, ds_att->in_render_loop, clear_rect, clear_value); 634bf215546Sopenharmony_ci if (!pipeline) 635bf215546Sopenharmony_ci return; 636bf215546Sopenharmony_ci 637bf215546Sopenharmony_ci struct radv_subpass clear_subpass = { 638bf215546Sopenharmony_ci .color_count = 0, 639bf215546Sopenharmony_ci .color_attachments = NULL, 640bf215546Sopenharmony_ci .depth_stencil_attachment = ds_att, 641bf215546Sopenharmony_ci }; 642bf215546Sopenharmony_ci 643bf215546Sopenharmony_ci if (ds_resolve_clear) 644bf215546Sopenharmony_ci radv_cmd_buffer_set_subpass(cmd_buffer, &clear_subpass); 645bf215546Sopenharmony_ci 646bf215546Sopenharmony_ci radv_CmdBindPipeline(cmd_buffer_h, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline); 647bf215546Sopenharmony_ci 648bf215546Sopenharmony_ci if (depth_view_can_fast_clear(cmd_buffer, iview, aspects, ds_att->layout, ds_att->in_render_loop, 649bf215546Sopenharmony_ci clear_rect, clear_value)) 650bf215546Sopenharmony_ci radv_update_ds_clear_metadata(cmd_buffer, iview, clear_value, aspects); 651bf215546Sopenharmony_ci 652bf215546Sopenharmony_ci radv_CmdSetViewport(radv_cmd_buffer_to_handle(cmd_buffer), 0, 1, 653bf215546Sopenharmony_ci &(VkViewport){.x = clear_rect->rect.offset.x, 654bf215546Sopenharmony_ci .y = clear_rect->rect.offset.y, 655bf215546Sopenharmony_ci .width = clear_rect->rect.extent.width, 656bf215546Sopenharmony_ci .height = clear_rect->rect.extent.height, 657bf215546Sopenharmony_ci .minDepth = 0.0f, 658bf215546Sopenharmony_ci .maxDepth = 1.0f}); 659bf215546Sopenharmony_ci 660bf215546Sopenharmony_ci radv_CmdSetScissor(radv_cmd_buffer_to_handle(cmd_buffer), 0, 1, &clear_rect->rect); 661bf215546Sopenharmony_ci 662bf215546Sopenharmony_ci if (view_mask) { 663bf215546Sopenharmony_ci u_foreach_bit(i, view_mask) radv_CmdDraw(cmd_buffer_h, 3, 1, 0, i); 664bf215546Sopenharmony_ci } else { 665bf215546Sopenharmony_ci radv_CmdDraw(cmd_buffer_h, 3, clear_rect->layerCount, 0, clear_rect->baseArrayLayer); 666bf215546Sopenharmony_ci } 667bf215546Sopenharmony_ci 668bf215546Sopenharmony_ci if (aspects & VK_IMAGE_ASPECT_STENCIL_BIT) { 669bf215546Sopenharmony_ci radv_CmdSetStencilReference(cmd_buffer_h, VK_STENCIL_FACE_FRONT_BIT, prev_reference); 670bf215546Sopenharmony_ci } 671bf215546Sopenharmony_ci 672bf215546Sopenharmony_ci if (ds_resolve_clear) 673bf215546Sopenharmony_ci radv_cmd_buffer_restore_subpass(cmd_buffer, subpass); 674bf215546Sopenharmony_ci} 675bf215546Sopenharmony_ci 676bf215546Sopenharmony_cistatic uint32_t 677bf215546Sopenharmony_ciclear_htile_mask(struct radv_cmd_buffer *cmd_buffer, const struct radv_image *image, 678bf215546Sopenharmony_ci struct radeon_winsys_bo *bo, uint64_t offset, uint64_t size, uint32_t htile_value, 679bf215546Sopenharmony_ci uint32_t htile_mask) 680bf215546Sopenharmony_ci{ 681bf215546Sopenharmony_ci struct radv_device *device = cmd_buffer->device; 682bf215546Sopenharmony_ci struct radv_meta_state *state = &device->meta_state; 683bf215546Sopenharmony_ci uint64_t block_count = round_up_u64(size, 1024); 684bf215546Sopenharmony_ci struct radv_meta_saved_state saved_state; 685bf215546Sopenharmony_ci struct radv_buffer dst_buffer; 686bf215546Sopenharmony_ci 687bf215546Sopenharmony_ci radv_meta_save( 688bf215546Sopenharmony_ci &saved_state, cmd_buffer, 689bf215546Sopenharmony_ci RADV_META_SAVE_COMPUTE_PIPELINE | RADV_META_SAVE_CONSTANTS | RADV_META_SAVE_DESCRIPTORS); 690bf215546Sopenharmony_ci 691bf215546Sopenharmony_ci radv_buffer_init(&dst_buffer, device, bo, size, offset); 692bf215546Sopenharmony_ci 693bf215546Sopenharmony_ci radv_CmdBindPipeline(radv_cmd_buffer_to_handle(cmd_buffer), VK_PIPELINE_BIND_POINT_COMPUTE, 694bf215546Sopenharmony_ci state->clear_htile_mask_pipeline); 695bf215546Sopenharmony_ci 696bf215546Sopenharmony_ci radv_meta_push_descriptor_set( 697bf215546Sopenharmony_ci cmd_buffer, VK_PIPELINE_BIND_POINT_COMPUTE, state->clear_htile_mask_p_layout, 0, /* set */ 698bf215546Sopenharmony_ci 1, /* descriptorWriteCount */ 699bf215546Sopenharmony_ci (VkWriteDescriptorSet[]){ 700bf215546Sopenharmony_ci {.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, 701bf215546Sopenharmony_ci .dstBinding = 0, 702bf215546Sopenharmony_ci .dstArrayElement = 0, 703bf215546Sopenharmony_ci .descriptorCount = 1, 704bf215546Sopenharmony_ci .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 705bf215546Sopenharmony_ci .pBufferInfo = &(VkDescriptorBufferInfo){.buffer = radv_buffer_to_handle(&dst_buffer), 706bf215546Sopenharmony_ci .offset = 0, 707bf215546Sopenharmony_ci .range = size}}}); 708bf215546Sopenharmony_ci 709bf215546Sopenharmony_ci const unsigned constants[2] = { 710bf215546Sopenharmony_ci htile_value & htile_mask, 711bf215546Sopenharmony_ci ~htile_mask, 712bf215546Sopenharmony_ci }; 713bf215546Sopenharmony_ci 714bf215546Sopenharmony_ci radv_CmdPushConstants(radv_cmd_buffer_to_handle(cmd_buffer), state->clear_htile_mask_p_layout, 715bf215546Sopenharmony_ci VK_SHADER_STAGE_COMPUTE_BIT, 0, 8, constants); 716bf215546Sopenharmony_ci 717bf215546Sopenharmony_ci radv_CmdDispatch(radv_cmd_buffer_to_handle(cmd_buffer), block_count, 1, 1); 718bf215546Sopenharmony_ci 719bf215546Sopenharmony_ci radv_buffer_finish(&dst_buffer); 720bf215546Sopenharmony_ci 721bf215546Sopenharmony_ci radv_meta_restore(&saved_state, cmd_buffer); 722bf215546Sopenharmony_ci 723bf215546Sopenharmony_ci return RADV_CMD_FLAG_CS_PARTIAL_FLUSH | 724bf215546Sopenharmony_ci radv_src_access_flush(cmd_buffer, VK_ACCESS_2_SHADER_WRITE_BIT, image); 725bf215546Sopenharmony_ci} 726bf215546Sopenharmony_ci 727bf215546Sopenharmony_cistatic uint32_t 728bf215546Sopenharmony_ciradv_get_htile_fast_clear_value(const struct radv_device *device, const struct radv_image *image, 729bf215546Sopenharmony_ci VkClearDepthStencilValue value) 730bf215546Sopenharmony_ci{ 731bf215546Sopenharmony_ci uint32_t max_zval = 0x3fff; /* maximum 14-bit value. */ 732bf215546Sopenharmony_ci uint32_t zmask = 0, smem = 0; 733bf215546Sopenharmony_ci uint32_t htile_value; 734bf215546Sopenharmony_ci uint32_t zmin, zmax; 735bf215546Sopenharmony_ci 736bf215546Sopenharmony_ci /* Convert the depth value to 14-bit zmin/zmax values. */ 737bf215546Sopenharmony_ci zmin = lroundf(value.depth * max_zval); 738bf215546Sopenharmony_ci zmax = zmin; 739bf215546Sopenharmony_ci 740bf215546Sopenharmony_ci if (radv_image_tile_stencil_disabled(device, image)) { 741bf215546Sopenharmony_ci /* Z only (no stencil): 742bf215546Sopenharmony_ci * 743bf215546Sopenharmony_ci * |31 18|17 4|3 0| 744bf215546Sopenharmony_ci * +---------+---------+-------+ 745bf215546Sopenharmony_ci * | Max Z | Min Z | ZMask | 746bf215546Sopenharmony_ci */ 747bf215546Sopenharmony_ci htile_value = (((zmax & 0x3fff) << 18) | 748bf215546Sopenharmony_ci ((zmin & 0x3fff) << 4) | 749bf215546Sopenharmony_ci ((zmask & 0xf) << 0)); 750bf215546Sopenharmony_ci } else { 751bf215546Sopenharmony_ci 752bf215546Sopenharmony_ci /* Z and stencil: 753bf215546Sopenharmony_ci * 754bf215546Sopenharmony_ci * |31 12|11 10|9 8|7 6|5 4|3 0| 755bf215546Sopenharmony_ci * +-----------+-----+------+-----+-----+-------+ 756bf215546Sopenharmony_ci * | Z Range | | SMem | SR1 | SR0 | ZMask | 757bf215546Sopenharmony_ci * 758bf215546Sopenharmony_ci * Z, stencil, 4 bit VRS encoding: 759bf215546Sopenharmony_ci * |31 12| 11 10 |9 8|7 6 |5 4|3 0| 760bf215546Sopenharmony_ci * +-----------+------------+------+------------+-----+-------+ 761bf215546Sopenharmony_ci * | Z Range | VRS Y-rate | SMem | VRS X-rate | SR0 | ZMask | 762bf215546Sopenharmony_ci */ 763bf215546Sopenharmony_ci uint32_t delta = 0; 764bf215546Sopenharmony_ci uint32_t zrange = ((zmax << 6) | delta); 765bf215546Sopenharmony_ci uint32_t sresults = 0xf; /* SR0/SR1 both as 0x3. */ 766bf215546Sopenharmony_ci 767bf215546Sopenharmony_ci if (radv_image_has_vrs_htile(device, image)) 768bf215546Sopenharmony_ci sresults = 0x3; 769bf215546Sopenharmony_ci 770bf215546Sopenharmony_ci htile_value = (((zrange & 0xfffff) << 12) | 771bf215546Sopenharmony_ci ((smem & 0x3) << 8) | 772bf215546Sopenharmony_ci ((sresults & 0xf) << 4) | 773bf215546Sopenharmony_ci ((zmask & 0xf) << 0)); 774bf215546Sopenharmony_ci } 775bf215546Sopenharmony_ci 776bf215546Sopenharmony_ci return htile_value; 777bf215546Sopenharmony_ci} 778bf215546Sopenharmony_ci 779bf215546Sopenharmony_cistatic uint32_t 780bf215546Sopenharmony_ciradv_get_htile_mask(const struct radv_device *device, const struct radv_image *image, 781bf215546Sopenharmony_ci VkImageAspectFlags aspects) 782bf215546Sopenharmony_ci{ 783bf215546Sopenharmony_ci uint32_t mask = 0; 784bf215546Sopenharmony_ci 785bf215546Sopenharmony_ci if (radv_image_tile_stencil_disabled(device, image)) { 786bf215546Sopenharmony_ci /* All the HTILE buffer is used when there is no stencil. */ 787bf215546Sopenharmony_ci mask = UINT32_MAX; 788bf215546Sopenharmony_ci } else { 789bf215546Sopenharmony_ci if (aspects & VK_IMAGE_ASPECT_DEPTH_BIT) 790bf215546Sopenharmony_ci mask |= 0xfffffc0f; 791bf215546Sopenharmony_ci if (aspects & VK_IMAGE_ASPECT_STENCIL_BIT) 792bf215546Sopenharmony_ci mask |= 0x000003f0; 793bf215546Sopenharmony_ci } 794bf215546Sopenharmony_ci 795bf215546Sopenharmony_ci return mask; 796bf215546Sopenharmony_ci} 797bf215546Sopenharmony_ci 798bf215546Sopenharmony_cistatic bool 799bf215546Sopenharmony_ciradv_is_fast_clear_depth_allowed(VkClearDepthStencilValue value) 800bf215546Sopenharmony_ci{ 801bf215546Sopenharmony_ci return value.depth == 1.0f || value.depth == 0.0f; 802bf215546Sopenharmony_ci} 803bf215546Sopenharmony_ci 804bf215546Sopenharmony_cistatic bool 805bf215546Sopenharmony_ciradv_is_fast_clear_stencil_allowed(VkClearDepthStencilValue value) 806bf215546Sopenharmony_ci{ 807bf215546Sopenharmony_ci return value.stencil == 0; 808bf215546Sopenharmony_ci} 809bf215546Sopenharmony_ci 810bf215546Sopenharmony_cistatic bool 811bf215546Sopenharmony_ciradv_can_fast_clear_depth(struct radv_cmd_buffer *cmd_buffer, const struct radv_image_view *iview, 812bf215546Sopenharmony_ci VkImageLayout image_layout, bool in_render_loop, 813bf215546Sopenharmony_ci VkImageAspectFlags aspects, const VkClearRect *clear_rect, 814bf215546Sopenharmony_ci const VkClearDepthStencilValue clear_value, uint32_t view_mask) 815bf215546Sopenharmony_ci{ 816bf215546Sopenharmony_ci if (!iview || !iview->support_fast_clear) 817bf215546Sopenharmony_ci return false; 818bf215546Sopenharmony_ci 819bf215546Sopenharmony_ci if (!radv_layout_is_htile_compressed( 820bf215546Sopenharmony_ci cmd_buffer->device, iview->image, image_layout, in_render_loop, 821bf215546Sopenharmony_ci radv_image_queue_family_mask(iview->image, cmd_buffer->qf, 822bf215546Sopenharmony_ci cmd_buffer->qf))) 823bf215546Sopenharmony_ci return false; 824bf215546Sopenharmony_ci 825bf215546Sopenharmony_ci if (clear_rect->rect.offset.x || clear_rect->rect.offset.y || 826bf215546Sopenharmony_ci clear_rect->rect.extent.width != iview->image->info.width || 827bf215546Sopenharmony_ci clear_rect->rect.extent.height != iview->image->info.height) 828bf215546Sopenharmony_ci return false; 829bf215546Sopenharmony_ci 830bf215546Sopenharmony_ci if (view_mask && (iview->image->info.array_size >= 32 || 831bf215546Sopenharmony_ci (1u << iview->image->info.array_size) - 1u != view_mask)) 832bf215546Sopenharmony_ci return false; 833bf215546Sopenharmony_ci if (!view_mask && clear_rect->baseArrayLayer != 0) 834bf215546Sopenharmony_ci return false; 835bf215546Sopenharmony_ci if (!view_mask && clear_rect->layerCount != iview->image->info.array_size) 836bf215546Sopenharmony_ci return false; 837bf215546Sopenharmony_ci 838bf215546Sopenharmony_ci if (cmd_buffer->device->vk.enabled_extensions.EXT_depth_range_unrestricted && 839bf215546Sopenharmony_ci (aspects & VK_IMAGE_ASPECT_DEPTH_BIT) && 840bf215546Sopenharmony_ci (clear_value.depth < 0.0 || clear_value.depth > 1.0)) 841bf215546Sopenharmony_ci return false; 842bf215546Sopenharmony_ci 843bf215546Sopenharmony_ci if (radv_image_is_tc_compat_htile(iview->image) && 844bf215546Sopenharmony_ci (((aspects & VK_IMAGE_ASPECT_DEPTH_BIT) && !radv_is_fast_clear_depth_allowed(clear_value)) || 845bf215546Sopenharmony_ci ((aspects & VK_IMAGE_ASPECT_STENCIL_BIT) && 846bf215546Sopenharmony_ci !radv_is_fast_clear_stencil_allowed(clear_value)))) 847bf215546Sopenharmony_ci return false; 848bf215546Sopenharmony_ci 849bf215546Sopenharmony_ci if (iview->image->info.levels > 1) { 850bf215546Sopenharmony_ci uint32_t last_level = iview->vk.base_mip_level + iview->vk.level_count - 1; 851bf215546Sopenharmony_ci if (last_level >= iview->image->planes[0].surface.num_meta_levels) { 852bf215546Sopenharmony_ci /* Do not fast clears if one level can't be fast cleared. */ 853bf215546Sopenharmony_ci return false; 854bf215546Sopenharmony_ci } 855bf215546Sopenharmony_ci } 856bf215546Sopenharmony_ci 857bf215546Sopenharmony_ci return true; 858bf215546Sopenharmony_ci} 859bf215546Sopenharmony_ci 860bf215546Sopenharmony_cistatic void 861bf215546Sopenharmony_ciradv_fast_clear_depth(struct radv_cmd_buffer *cmd_buffer, const struct radv_image_view *iview, 862bf215546Sopenharmony_ci const VkClearAttachment *clear_att, enum radv_cmd_flush_bits *pre_flush, 863bf215546Sopenharmony_ci enum radv_cmd_flush_bits *post_flush) 864bf215546Sopenharmony_ci{ 865bf215546Sopenharmony_ci VkClearDepthStencilValue clear_value = clear_att->clearValue.depthStencil; 866bf215546Sopenharmony_ci VkImageAspectFlags aspects = clear_att->aspectMask; 867bf215546Sopenharmony_ci uint32_t clear_word, flush_bits; 868bf215546Sopenharmony_ci 869bf215546Sopenharmony_ci clear_word = radv_get_htile_fast_clear_value(cmd_buffer->device, iview->image, clear_value); 870bf215546Sopenharmony_ci 871bf215546Sopenharmony_ci if (pre_flush) { 872bf215546Sopenharmony_ci enum radv_cmd_flush_bits bits = 873bf215546Sopenharmony_ci radv_src_access_flush(cmd_buffer, VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, 874bf215546Sopenharmony_ci iview->image) | 875bf215546Sopenharmony_ci radv_dst_access_flush(cmd_buffer, VK_ACCESS_2_SHADER_WRITE_BIT | 876bf215546Sopenharmony_ci VK_ACCESS_2_SHADER_READ_BIT, iview->image); 877bf215546Sopenharmony_ci cmd_buffer->state.flush_bits |= bits & ~*pre_flush; 878bf215546Sopenharmony_ci *pre_flush |= cmd_buffer->state.flush_bits; 879bf215546Sopenharmony_ci } 880bf215546Sopenharmony_ci 881bf215546Sopenharmony_ci VkImageSubresourceRange range = { 882bf215546Sopenharmony_ci .aspectMask = aspects, 883bf215546Sopenharmony_ci .baseMipLevel = iview->vk.base_mip_level, 884bf215546Sopenharmony_ci .levelCount = iview->vk.level_count, 885bf215546Sopenharmony_ci .baseArrayLayer = iview->vk.base_array_layer, 886bf215546Sopenharmony_ci .layerCount = iview->vk.layer_count, 887bf215546Sopenharmony_ci }; 888bf215546Sopenharmony_ci 889bf215546Sopenharmony_ci flush_bits = radv_clear_htile(cmd_buffer, iview->image, &range, clear_word); 890bf215546Sopenharmony_ci 891bf215546Sopenharmony_ci if (iview->image->planes[0].surface.has_stencil && 892bf215546Sopenharmony_ci !(aspects == (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT))) { 893bf215546Sopenharmony_ci /* Synchronize after performing a depth-only or a stencil-only 894bf215546Sopenharmony_ci * fast clear because the driver uses an optimized path which 895bf215546Sopenharmony_ci * performs a read-modify-write operation, and the two separate 896bf215546Sopenharmony_ci * aspects might use the same HTILE memory. 897bf215546Sopenharmony_ci */ 898bf215546Sopenharmony_ci cmd_buffer->state.flush_bits |= flush_bits; 899bf215546Sopenharmony_ci } 900bf215546Sopenharmony_ci 901bf215546Sopenharmony_ci radv_update_ds_clear_metadata(cmd_buffer, iview, clear_value, aspects); 902bf215546Sopenharmony_ci if (post_flush) { 903bf215546Sopenharmony_ci *post_flush |= flush_bits; 904bf215546Sopenharmony_ci } 905bf215546Sopenharmony_ci} 906bf215546Sopenharmony_ci 907bf215546Sopenharmony_cistatic nir_shader * 908bf215546Sopenharmony_cibuild_clear_htile_mask_shader(struct radv_device *dev) 909bf215546Sopenharmony_ci{ 910bf215546Sopenharmony_ci nir_builder b = radv_meta_init_shader(dev, MESA_SHADER_COMPUTE, "meta_clear_htile_mask"); 911bf215546Sopenharmony_ci b.shader->info.workgroup_size[0] = 64; 912bf215546Sopenharmony_ci 913bf215546Sopenharmony_ci nir_ssa_def *global_id = get_global_ids(&b, 1); 914bf215546Sopenharmony_ci 915bf215546Sopenharmony_ci nir_ssa_def *offset = nir_imul_imm(&b, global_id, 16); 916bf215546Sopenharmony_ci offset = nir_channel(&b, offset, 0); 917bf215546Sopenharmony_ci 918bf215546Sopenharmony_ci nir_ssa_def *buf = radv_meta_load_descriptor(&b, 0, 0); 919bf215546Sopenharmony_ci 920bf215546Sopenharmony_ci nir_ssa_def *constants = nir_load_push_constant(&b, 2, 32, nir_imm_int(&b, 0), .range = 8); 921bf215546Sopenharmony_ci 922bf215546Sopenharmony_ci nir_ssa_def *load = nir_load_ssbo(&b, 4, 32, buf, offset, .align_mul = 16); 923bf215546Sopenharmony_ci 924bf215546Sopenharmony_ci /* data = (data & ~htile_mask) | (htile_value & htile_mask) */ 925bf215546Sopenharmony_ci nir_ssa_def *data = nir_iand(&b, load, nir_channel(&b, constants, 1)); 926bf215546Sopenharmony_ci data = nir_ior(&b, data, nir_channel(&b, constants, 0)); 927bf215546Sopenharmony_ci 928bf215546Sopenharmony_ci nir_store_ssbo(&b, data, buf, offset, .access = ACCESS_NON_READABLE, .align_mul = 16); 929bf215546Sopenharmony_ci 930bf215546Sopenharmony_ci return b.shader; 931bf215546Sopenharmony_ci} 932bf215546Sopenharmony_ci 933bf215546Sopenharmony_cistatic VkResult 934bf215546Sopenharmony_ciinit_meta_clear_htile_mask_state(struct radv_device *device) 935bf215546Sopenharmony_ci{ 936bf215546Sopenharmony_ci struct radv_meta_state *state = &device->meta_state; 937bf215546Sopenharmony_ci VkResult result; 938bf215546Sopenharmony_ci nir_shader *cs = build_clear_htile_mask_shader(device); 939bf215546Sopenharmony_ci 940bf215546Sopenharmony_ci VkDescriptorSetLayoutCreateInfo ds_layout_info = { 941bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, 942bf215546Sopenharmony_ci .flags = VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR, 943bf215546Sopenharmony_ci .bindingCount = 1, 944bf215546Sopenharmony_ci .pBindings = (VkDescriptorSetLayoutBinding[]){ 945bf215546Sopenharmony_ci {.binding = 0, 946bf215546Sopenharmony_ci .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 947bf215546Sopenharmony_ci .descriptorCount = 1, 948bf215546Sopenharmony_ci .stageFlags = VK_SHADER_STAGE_COMPUTE_BIT, 949bf215546Sopenharmony_ci .pImmutableSamplers = NULL}, 950bf215546Sopenharmony_ci }}; 951bf215546Sopenharmony_ci 952bf215546Sopenharmony_ci result = radv_CreateDescriptorSetLayout(radv_device_to_handle(device), &ds_layout_info, 953bf215546Sopenharmony_ci &state->alloc, &state->clear_htile_mask_ds_layout); 954bf215546Sopenharmony_ci if (result != VK_SUCCESS) 955bf215546Sopenharmony_ci goto fail; 956bf215546Sopenharmony_ci 957bf215546Sopenharmony_ci VkPipelineLayoutCreateInfo p_layout_info = { 958bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, 959bf215546Sopenharmony_ci .setLayoutCount = 1, 960bf215546Sopenharmony_ci .pSetLayouts = &state->clear_htile_mask_ds_layout, 961bf215546Sopenharmony_ci .pushConstantRangeCount = 1, 962bf215546Sopenharmony_ci .pPushConstantRanges = 963bf215546Sopenharmony_ci &(VkPushConstantRange){ 964bf215546Sopenharmony_ci VK_SHADER_STAGE_COMPUTE_BIT, 965bf215546Sopenharmony_ci 0, 966bf215546Sopenharmony_ci 8, 967bf215546Sopenharmony_ci }, 968bf215546Sopenharmony_ci }; 969bf215546Sopenharmony_ci 970bf215546Sopenharmony_ci result = radv_CreatePipelineLayout(radv_device_to_handle(device), &p_layout_info, &state->alloc, 971bf215546Sopenharmony_ci &state->clear_htile_mask_p_layout); 972bf215546Sopenharmony_ci if (result != VK_SUCCESS) 973bf215546Sopenharmony_ci goto fail; 974bf215546Sopenharmony_ci 975bf215546Sopenharmony_ci VkPipelineShaderStageCreateInfo shader_stage = { 976bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, 977bf215546Sopenharmony_ci .stage = VK_SHADER_STAGE_COMPUTE_BIT, 978bf215546Sopenharmony_ci .module = vk_shader_module_handle_from_nir(cs), 979bf215546Sopenharmony_ci .pName = "main", 980bf215546Sopenharmony_ci .pSpecializationInfo = NULL, 981bf215546Sopenharmony_ci }; 982bf215546Sopenharmony_ci 983bf215546Sopenharmony_ci VkComputePipelineCreateInfo pipeline_info = { 984bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, 985bf215546Sopenharmony_ci .stage = shader_stage, 986bf215546Sopenharmony_ci .flags = 0, 987bf215546Sopenharmony_ci .layout = state->clear_htile_mask_p_layout, 988bf215546Sopenharmony_ci }; 989bf215546Sopenharmony_ci 990bf215546Sopenharmony_ci result = radv_CreateComputePipelines(radv_device_to_handle(device), 991bf215546Sopenharmony_ci radv_pipeline_cache_to_handle(&state->cache), 1, 992bf215546Sopenharmony_ci &pipeline_info, NULL, &state->clear_htile_mask_pipeline); 993bf215546Sopenharmony_ci 994bf215546Sopenharmony_cifail: 995bf215546Sopenharmony_ci ralloc_free(cs); 996bf215546Sopenharmony_ci return result; 997bf215546Sopenharmony_ci} 998bf215546Sopenharmony_ci 999bf215546Sopenharmony_ci/* Clear DCC using comp-to-single by storing the clear value at the beginning of every 256B block. 1000bf215546Sopenharmony_ci * For MSAA images, clearing the first sample should be enough as long as CMASK is also cleared. 1001bf215546Sopenharmony_ci */ 1002bf215546Sopenharmony_cistatic nir_shader * 1003bf215546Sopenharmony_cibuild_clear_dcc_comp_to_single_shader(struct radv_device *dev, bool is_msaa) 1004bf215546Sopenharmony_ci{ 1005bf215546Sopenharmony_ci enum glsl_sampler_dim dim = is_msaa ? GLSL_SAMPLER_DIM_MS : GLSL_SAMPLER_DIM_2D; 1006bf215546Sopenharmony_ci const struct glsl_type *img_type = glsl_image_type(dim, true, GLSL_TYPE_FLOAT); 1007bf215546Sopenharmony_ci 1008bf215546Sopenharmony_ci nir_builder b = 1009bf215546Sopenharmony_ci radv_meta_init_shader(dev, MESA_SHADER_COMPUTE, "meta_clear_dcc_comp_to_single-%s", 1010bf215546Sopenharmony_ci is_msaa ? "multisampled" : "singlesampled"); 1011bf215546Sopenharmony_ci b.shader->info.workgroup_size[0] = 8; 1012bf215546Sopenharmony_ci b.shader->info.workgroup_size[1] = 8; 1013bf215546Sopenharmony_ci 1014bf215546Sopenharmony_ci nir_ssa_def *global_id = get_global_ids(&b, 3); 1015bf215546Sopenharmony_ci 1016bf215546Sopenharmony_ci /* Load the dimensions in pixels of a block that gets compressed to one DCC byte. */ 1017bf215546Sopenharmony_ci nir_ssa_def *dcc_block_size = nir_load_push_constant(&b, 2, 32, nir_imm_int(&b, 0), .range = 8); 1018bf215546Sopenharmony_ci 1019bf215546Sopenharmony_ci /* Compute the coordinates. */ 1020bf215546Sopenharmony_ci nir_ssa_def *coord = nir_channels(&b, global_id, 0x3); 1021bf215546Sopenharmony_ci coord = nir_imul(&b, coord, dcc_block_size); 1022bf215546Sopenharmony_ci coord = nir_vec4(&b, nir_channel(&b, coord, 0), 1023bf215546Sopenharmony_ci nir_channel(&b, coord, 1), 1024bf215546Sopenharmony_ci nir_channel(&b, global_id, 2), 1025bf215546Sopenharmony_ci nir_ssa_undef(&b, 1, 32)); 1026bf215546Sopenharmony_ci 1027bf215546Sopenharmony_ci nir_variable *output_img = nir_variable_create(b.shader, nir_var_image, img_type, "out_img"); 1028bf215546Sopenharmony_ci output_img->data.descriptor_set = 0; 1029bf215546Sopenharmony_ci output_img->data.binding = 0; 1030bf215546Sopenharmony_ci 1031bf215546Sopenharmony_ci /* Load the clear color values. */ 1032bf215546Sopenharmony_ci nir_ssa_def *clear_values = nir_load_push_constant(&b, 2, 32, nir_imm_int(&b, 8), .range = 8); 1033bf215546Sopenharmony_ci 1034bf215546Sopenharmony_ci nir_ssa_def *data = nir_vec4(&b, nir_channel(&b, clear_values, 0), 1035bf215546Sopenharmony_ci nir_channel(&b, clear_values, 1), 1036bf215546Sopenharmony_ci nir_channel(&b, clear_values, 1), 1037bf215546Sopenharmony_ci nir_channel(&b, clear_values, 1)); 1038bf215546Sopenharmony_ci 1039bf215546Sopenharmony_ci /* Store the clear color values. */ 1040bf215546Sopenharmony_ci nir_ssa_def *sample_id = is_msaa ? nir_imm_int(&b, 0) : nir_ssa_undef(&b, 1, 32); 1041bf215546Sopenharmony_ci nir_image_deref_store(&b, &nir_build_deref_var(&b, output_img)->dest.ssa, coord, 1042bf215546Sopenharmony_ci sample_id, data, nir_imm_int(&b, 0), 1043bf215546Sopenharmony_ci .image_dim = dim, .image_array = true); 1044bf215546Sopenharmony_ci 1045bf215546Sopenharmony_ci return b.shader; 1046bf215546Sopenharmony_ci} 1047bf215546Sopenharmony_ci 1048bf215546Sopenharmony_cistatic VkResult 1049bf215546Sopenharmony_cicreate_dcc_comp_to_single_pipeline(struct radv_device *device, bool is_msaa, VkPipeline *pipeline) 1050bf215546Sopenharmony_ci{ 1051bf215546Sopenharmony_ci struct radv_meta_state *state = &device->meta_state; 1052bf215546Sopenharmony_ci VkResult result; 1053bf215546Sopenharmony_ci nir_shader *cs = build_clear_dcc_comp_to_single_shader(device, is_msaa); 1054bf215546Sopenharmony_ci 1055bf215546Sopenharmony_ci VkPipelineShaderStageCreateInfo shader_stage = { 1056bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, 1057bf215546Sopenharmony_ci .stage = VK_SHADER_STAGE_COMPUTE_BIT, 1058bf215546Sopenharmony_ci .module = vk_shader_module_handle_from_nir(cs), 1059bf215546Sopenharmony_ci .pName = "main", 1060bf215546Sopenharmony_ci .pSpecializationInfo = NULL, 1061bf215546Sopenharmony_ci }; 1062bf215546Sopenharmony_ci 1063bf215546Sopenharmony_ci VkComputePipelineCreateInfo pipeline_info = { 1064bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, 1065bf215546Sopenharmony_ci .stage = shader_stage, 1066bf215546Sopenharmony_ci .flags = 0, 1067bf215546Sopenharmony_ci .layout = state->clear_dcc_comp_to_single_p_layout, 1068bf215546Sopenharmony_ci }; 1069bf215546Sopenharmony_ci 1070bf215546Sopenharmony_ci result = radv_CreateComputePipelines(radv_device_to_handle(device), 1071bf215546Sopenharmony_ci radv_pipeline_cache_to_handle(&state->cache), 1, 1072bf215546Sopenharmony_ci &pipeline_info, NULL, pipeline); 1073bf215546Sopenharmony_ci 1074bf215546Sopenharmony_ci ralloc_free(cs); 1075bf215546Sopenharmony_ci return result; 1076bf215546Sopenharmony_ci} 1077bf215546Sopenharmony_ci 1078bf215546Sopenharmony_cistatic VkResult 1079bf215546Sopenharmony_ciinit_meta_clear_dcc_comp_to_single_state(struct radv_device *device) 1080bf215546Sopenharmony_ci{ 1081bf215546Sopenharmony_ci struct radv_meta_state *state = &device->meta_state; 1082bf215546Sopenharmony_ci VkResult result; 1083bf215546Sopenharmony_ci 1084bf215546Sopenharmony_ci VkDescriptorSetLayoutCreateInfo ds_layout_info = { 1085bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, 1086bf215546Sopenharmony_ci .flags = VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR, 1087bf215546Sopenharmony_ci .bindingCount = 1, 1088bf215546Sopenharmony_ci .pBindings = (VkDescriptorSetLayoutBinding[]){ 1089bf215546Sopenharmony_ci {.binding = 0, 1090bf215546Sopenharmony_ci .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1091bf215546Sopenharmony_ci .descriptorCount = 1, 1092bf215546Sopenharmony_ci .stageFlags = VK_SHADER_STAGE_COMPUTE_BIT, 1093bf215546Sopenharmony_ci .pImmutableSamplers = NULL}, 1094bf215546Sopenharmony_ci }}; 1095bf215546Sopenharmony_ci 1096bf215546Sopenharmony_ci result = radv_CreateDescriptorSetLayout(radv_device_to_handle(device), &ds_layout_info, 1097bf215546Sopenharmony_ci &state->alloc, &state->clear_dcc_comp_to_single_ds_layout); 1098bf215546Sopenharmony_ci if (result != VK_SUCCESS) 1099bf215546Sopenharmony_ci goto fail; 1100bf215546Sopenharmony_ci 1101bf215546Sopenharmony_ci VkPipelineLayoutCreateInfo p_layout_info = { 1102bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, 1103bf215546Sopenharmony_ci .setLayoutCount = 1, 1104bf215546Sopenharmony_ci .pSetLayouts = &state->clear_dcc_comp_to_single_ds_layout, 1105bf215546Sopenharmony_ci .pushConstantRangeCount = 1, 1106bf215546Sopenharmony_ci .pPushConstantRanges = 1107bf215546Sopenharmony_ci &(VkPushConstantRange){ 1108bf215546Sopenharmony_ci VK_SHADER_STAGE_COMPUTE_BIT, 1109bf215546Sopenharmony_ci 0, 1110bf215546Sopenharmony_ci 16, 1111bf215546Sopenharmony_ci }, 1112bf215546Sopenharmony_ci }; 1113bf215546Sopenharmony_ci 1114bf215546Sopenharmony_ci result = radv_CreatePipelineLayout(radv_device_to_handle(device), &p_layout_info, &state->alloc, 1115bf215546Sopenharmony_ci &state->clear_dcc_comp_to_single_p_layout); 1116bf215546Sopenharmony_ci if (result != VK_SUCCESS) 1117bf215546Sopenharmony_ci goto fail; 1118bf215546Sopenharmony_ci 1119bf215546Sopenharmony_ci for (uint32_t i = 0; i < 2; i++) { 1120bf215546Sopenharmony_ci result = create_dcc_comp_to_single_pipeline(device, !!i, 1121bf215546Sopenharmony_ci &state->clear_dcc_comp_to_single_pipeline[i]); 1122bf215546Sopenharmony_ci if (result != VK_SUCCESS) 1123bf215546Sopenharmony_ci goto fail; 1124bf215546Sopenharmony_ci } 1125bf215546Sopenharmony_ci 1126bf215546Sopenharmony_cifail: 1127bf215546Sopenharmony_ci return result; 1128bf215546Sopenharmony_ci} 1129bf215546Sopenharmony_ci 1130bf215546Sopenharmony_ciVkResult 1131bf215546Sopenharmony_ciradv_device_init_meta_clear_state(struct radv_device *device, bool on_demand) 1132bf215546Sopenharmony_ci{ 1133bf215546Sopenharmony_ci VkResult res; 1134bf215546Sopenharmony_ci struct radv_meta_state *state = &device->meta_state; 1135bf215546Sopenharmony_ci 1136bf215546Sopenharmony_ci VkPipelineLayoutCreateInfo pl_color_create_info = { 1137bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, 1138bf215546Sopenharmony_ci .setLayoutCount = 0, 1139bf215546Sopenharmony_ci .pushConstantRangeCount = 1, 1140bf215546Sopenharmony_ci .pPushConstantRanges = &(VkPushConstantRange){VK_SHADER_STAGE_FRAGMENT_BIT, 0, 16}, 1141bf215546Sopenharmony_ci }; 1142bf215546Sopenharmony_ci 1143bf215546Sopenharmony_ci res = radv_CreatePipelineLayout(radv_device_to_handle(device), &pl_color_create_info, 1144bf215546Sopenharmony_ci &device->meta_state.alloc, 1145bf215546Sopenharmony_ci &device->meta_state.clear_color_p_layout); 1146bf215546Sopenharmony_ci if (res != VK_SUCCESS) 1147bf215546Sopenharmony_ci return res; 1148bf215546Sopenharmony_ci 1149bf215546Sopenharmony_ci VkPipelineLayoutCreateInfo pl_depth_create_info = { 1150bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, 1151bf215546Sopenharmony_ci .setLayoutCount = 0, 1152bf215546Sopenharmony_ci .pushConstantRangeCount = 1, 1153bf215546Sopenharmony_ci .pPushConstantRanges = &(VkPushConstantRange){VK_SHADER_STAGE_VERTEX_BIT, 0, 4}, 1154bf215546Sopenharmony_ci }; 1155bf215546Sopenharmony_ci 1156bf215546Sopenharmony_ci res = radv_CreatePipelineLayout(radv_device_to_handle(device), &pl_depth_create_info, 1157bf215546Sopenharmony_ci &device->meta_state.alloc, 1158bf215546Sopenharmony_ci &device->meta_state.clear_depth_p_layout); 1159bf215546Sopenharmony_ci if (res != VK_SUCCESS) 1160bf215546Sopenharmony_ci return res; 1161bf215546Sopenharmony_ci 1162bf215546Sopenharmony_ci VkPipelineLayoutCreateInfo pl_depth_unrestricted_create_info = { 1163bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, 1164bf215546Sopenharmony_ci .setLayoutCount = 0, 1165bf215546Sopenharmony_ci .pushConstantRangeCount = 1, 1166bf215546Sopenharmony_ci .pPushConstantRanges = &(VkPushConstantRange){VK_SHADER_STAGE_FRAGMENT_BIT, 0, 4}, 1167bf215546Sopenharmony_ci }; 1168bf215546Sopenharmony_ci 1169bf215546Sopenharmony_ci res = radv_CreatePipelineLayout(radv_device_to_handle(device), 1170bf215546Sopenharmony_ci &pl_depth_unrestricted_create_info, &device->meta_state.alloc, 1171bf215546Sopenharmony_ci &device->meta_state.clear_depth_unrestricted_p_layout); 1172bf215546Sopenharmony_ci if (res != VK_SUCCESS) 1173bf215546Sopenharmony_ci return res; 1174bf215546Sopenharmony_ci 1175bf215546Sopenharmony_ci res = init_meta_clear_htile_mask_state(device); 1176bf215546Sopenharmony_ci if (res != VK_SUCCESS) 1177bf215546Sopenharmony_ci return res; 1178bf215546Sopenharmony_ci 1179bf215546Sopenharmony_ci res = init_meta_clear_dcc_comp_to_single_state(device); 1180bf215546Sopenharmony_ci if (res != VK_SUCCESS) 1181bf215546Sopenharmony_ci return res; 1182bf215546Sopenharmony_ci 1183bf215546Sopenharmony_ci if (on_demand) 1184bf215546Sopenharmony_ci return VK_SUCCESS; 1185bf215546Sopenharmony_ci 1186bf215546Sopenharmony_ci for (uint32_t i = 0; i < ARRAY_SIZE(state->color_clear); ++i) { 1187bf215546Sopenharmony_ci uint32_t samples = 1 << i; 1188bf215546Sopenharmony_ci 1189bf215546Sopenharmony_ci /* Only precompile meta pipelines for attachment 0 as other are uncommon. */ 1190bf215546Sopenharmony_ci for (uint32_t j = 0; j < NUM_META_FS_KEYS; ++j) { 1191bf215546Sopenharmony_ci VkFormat format = radv_fs_key_format_exemplars[j]; 1192bf215546Sopenharmony_ci unsigned fs_key = radv_format_meta_fs_key(device, format); 1193bf215546Sopenharmony_ci assert(!state->color_clear[i][0].color_pipelines[fs_key]); 1194bf215546Sopenharmony_ci 1195bf215546Sopenharmony_ci res = create_color_pipeline(device, samples, 0, format, 1196bf215546Sopenharmony_ci &state->color_clear[i][0].color_pipelines[fs_key]); 1197bf215546Sopenharmony_ci if (res != VK_SUCCESS) 1198bf215546Sopenharmony_ci return res; 1199bf215546Sopenharmony_ci } 1200bf215546Sopenharmony_ci } 1201bf215546Sopenharmony_ci for (uint32_t i = 0; i < ARRAY_SIZE(state->ds_clear); ++i) { 1202bf215546Sopenharmony_ci uint32_t samples = 1 << i; 1203bf215546Sopenharmony_ci 1204bf215546Sopenharmony_ci for (uint32_t j = 0; j < NUM_DEPTH_CLEAR_PIPELINES; j++) { 1205bf215546Sopenharmony_ci res = create_depthstencil_pipeline(device, VK_IMAGE_ASPECT_DEPTH_BIT, samples, j, false, 1206bf215546Sopenharmony_ci &state->ds_clear[i].depth_only_pipeline[j]); 1207bf215546Sopenharmony_ci if (res != VK_SUCCESS) 1208bf215546Sopenharmony_ci return res; 1209bf215546Sopenharmony_ci 1210bf215546Sopenharmony_ci res = create_depthstencil_pipeline(device, VK_IMAGE_ASPECT_STENCIL_BIT, samples, j, false, 1211bf215546Sopenharmony_ci &state->ds_clear[i].stencil_only_pipeline[j]); 1212bf215546Sopenharmony_ci if (res != VK_SUCCESS) 1213bf215546Sopenharmony_ci return res; 1214bf215546Sopenharmony_ci 1215bf215546Sopenharmony_ci res = create_depthstencil_pipeline( 1216bf215546Sopenharmony_ci device, VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT, samples, j, false, 1217bf215546Sopenharmony_ci &state->ds_clear[i].depthstencil_pipeline[j]); 1218bf215546Sopenharmony_ci if (res != VK_SUCCESS) 1219bf215546Sopenharmony_ci return res; 1220bf215546Sopenharmony_ci 1221bf215546Sopenharmony_ci res = create_depthstencil_pipeline(device, VK_IMAGE_ASPECT_DEPTH_BIT, samples, j, true, 1222bf215546Sopenharmony_ci &state->ds_clear[i].depth_only_unrestricted_pipeline[j]); 1223bf215546Sopenharmony_ci if (res != VK_SUCCESS) 1224bf215546Sopenharmony_ci return res; 1225bf215546Sopenharmony_ci 1226bf215546Sopenharmony_ci res = 1227bf215546Sopenharmony_ci create_depthstencil_pipeline(device, VK_IMAGE_ASPECT_STENCIL_BIT, samples, j, true, 1228bf215546Sopenharmony_ci &state->ds_clear[i].stencil_only_unrestricted_pipeline[j]); 1229bf215546Sopenharmony_ci if (res != VK_SUCCESS) 1230bf215546Sopenharmony_ci return res; 1231bf215546Sopenharmony_ci 1232bf215546Sopenharmony_ci res = create_depthstencil_pipeline( 1233bf215546Sopenharmony_ci device, VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT, samples, j, true, 1234bf215546Sopenharmony_ci &state->ds_clear[i].depthstencil_unrestricted_pipeline[j]); 1235bf215546Sopenharmony_ci if (res != VK_SUCCESS) 1236bf215546Sopenharmony_ci return res; 1237bf215546Sopenharmony_ci } 1238bf215546Sopenharmony_ci } 1239bf215546Sopenharmony_ci return VK_SUCCESS; 1240bf215546Sopenharmony_ci} 1241bf215546Sopenharmony_ci 1242bf215546Sopenharmony_cistatic uint32_t 1243bf215546Sopenharmony_ciradv_get_cmask_fast_clear_value(const struct radv_image *image) 1244bf215546Sopenharmony_ci{ 1245bf215546Sopenharmony_ci uint32_t value = 0; /* Default value when no DCC. */ 1246bf215546Sopenharmony_ci 1247bf215546Sopenharmony_ci /* The fast-clear value is different for images that have both DCC and 1248bf215546Sopenharmony_ci * CMASK metadata. 1249bf215546Sopenharmony_ci */ 1250bf215546Sopenharmony_ci if (radv_image_has_dcc(image)) { 1251bf215546Sopenharmony_ci /* DCC fast clear with MSAA should clear CMASK to 0xC. */ 1252bf215546Sopenharmony_ci return image->info.samples > 1 ? 0xcccccccc : 0xffffffff; 1253bf215546Sopenharmony_ci } 1254bf215546Sopenharmony_ci 1255bf215546Sopenharmony_ci return value; 1256bf215546Sopenharmony_ci} 1257bf215546Sopenharmony_ci 1258bf215546Sopenharmony_ciuint32_t 1259bf215546Sopenharmony_ciradv_clear_cmask(struct radv_cmd_buffer *cmd_buffer, struct radv_image *image, 1260bf215546Sopenharmony_ci const VkImageSubresourceRange *range, uint32_t value) 1261bf215546Sopenharmony_ci{ 1262bf215546Sopenharmony_ci uint64_t offset = image->bindings[0].offset + image->planes[0].surface.cmask_offset; 1263bf215546Sopenharmony_ci uint64_t size; 1264bf215546Sopenharmony_ci 1265bf215546Sopenharmony_ci if (cmd_buffer->device->physical_device->rad_info.gfx_level == GFX9) { 1266bf215546Sopenharmony_ci /* TODO: clear layers. */ 1267bf215546Sopenharmony_ci size = image->planes[0].surface.cmask_size; 1268bf215546Sopenharmony_ci } else { 1269bf215546Sopenharmony_ci unsigned slice_size = image->planes[0].surface.cmask_slice_size; 1270bf215546Sopenharmony_ci 1271bf215546Sopenharmony_ci offset += slice_size * range->baseArrayLayer; 1272bf215546Sopenharmony_ci size = slice_size * radv_get_layerCount(image, range); 1273bf215546Sopenharmony_ci } 1274bf215546Sopenharmony_ci 1275bf215546Sopenharmony_ci return radv_fill_buffer(cmd_buffer, image, image->bindings[0].bo, 1276bf215546Sopenharmony_ci radv_buffer_get_va(image->bindings[0].bo) + offset, size, value); 1277bf215546Sopenharmony_ci} 1278bf215546Sopenharmony_ci 1279bf215546Sopenharmony_ciuint32_t 1280bf215546Sopenharmony_ciradv_clear_fmask(struct radv_cmd_buffer *cmd_buffer, struct radv_image *image, 1281bf215546Sopenharmony_ci const VkImageSubresourceRange *range, uint32_t value) 1282bf215546Sopenharmony_ci{ 1283bf215546Sopenharmony_ci uint64_t offset = image->bindings[0].offset + image->planes[0].surface.fmask_offset; 1284bf215546Sopenharmony_ci unsigned slice_size = image->planes[0].surface.fmask_slice_size; 1285bf215546Sopenharmony_ci uint64_t size; 1286bf215546Sopenharmony_ci 1287bf215546Sopenharmony_ci /* MSAA images do not support mipmap levels. */ 1288bf215546Sopenharmony_ci assert(range->baseMipLevel == 0 && radv_get_levelCount(image, range) == 1); 1289bf215546Sopenharmony_ci 1290bf215546Sopenharmony_ci offset += slice_size * range->baseArrayLayer; 1291bf215546Sopenharmony_ci size = slice_size * radv_get_layerCount(image, range); 1292bf215546Sopenharmony_ci 1293bf215546Sopenharmony_ci return radv_fill_buffer(cmd_buffer, image, image->bindings[0].bo, 1294bf215546Sopenharmony_ci radv_buffer_get_va(image->bindings[0].bo) + offset, size, value); 1295bf215546Sopenharmony_ci} 1296bf215546Sopenharmony_ci 1297bf215546Sopenharmony_ciuint32_t 1298bf215546Sopenharmony_ciradv_clear_dcc(struct radv_cmd_buffer *cmd_buffer, struct radv_image *image, 1299bf215546Sopenharmony_ci const VkImageSubresourceRange *range, uint32_t value) 1300bf215546Sopenharmony_ci{ 1301bf215546Sopenharmony_ci uint32_t level_count = radv_get_levelCount(image, range); 1302bf215546Sopenharmony_ci uint32_t layer_count = radv_get_layerCount(image, range); 1303bf215546Sopenharmony_ci uint32_t flush_bits = 0; 1304bf215546Sopenharmony_ci 1305bf215546Sopenharmony_ci /* Mark the image as being compressed. */ 1306bf215546Sopenharmony_ci radv_update_dcc_metadata(cmd_buffer, image, range, true); 1307bf215546Sopenharmony_ci 1308bf215546Sopenharmony_ci for (uint32_t l = 0; l < level_count; l++) { 1309bf215546Sopenharmony_ci uint64_t offset = image->bindings[0].offset + image->planes[0].surface.meta_offset; 1310bf215546Sopenharmony_ci uint32_t level = range->baseMipLevel + l; 1311bf215546Sopenharmony_ci uint64_t size; 1312bf215546Sopenharmony_ci 1313bf215546Sopenharmony_ci if (cmd_buffer->device->physical_device->rad_info.gfx_level >= GFX10) { 1314bf215546Sopenharmony_ci /* DCC for mipmaps+layers is currently disabled. */ 1315bf215546Sopenharmony_ci offset += image->planes[0].surface.meta_slice_size * range->baseArrayLayer + 1316bf215546Sopenharmony_ci image->planes[0].surface.u.gfx9.meta_levels[level].offset; 1317bf215546Sopenharmony_ci size = image->planes[0].surface.u.gfx9.meta_levels[level].size * layer_count; 1318bf215546Sopenharmony_ci } else if (cmd_buffer->device->physical_device->rad_info.gfx_level == GFX9) { 1319bf215546Sopenharmony_ci /* Mipmap levels and layers aren't implemented. */ 1320bf215546Sopenharmony_ci assert(level == 0); 1321bf215546Sopenharmony_ci size = image->planes[0].surface.meta_size; 1322bf215546Sopenharmony_ci } else { 1323bf215546Sopenharmony_ci const struct legacy_surf_dcc_level *dcc_level = 1324bf215546Sopenharmony_ci &image->planes[0].surface.u.legacy.color.dcc_level[level]; 1325bf215546Sopenharmony_ci 1326bf215546Sopenharmony_ci /* If dcc_fast_clear_size is 0 (which might happens for 1327bf215546Sopenharmony_ci * mipmaps) the fill buffer operation below is a no-op. 1328bf215546Sopenharmony_ci * This can only happen during initialization as the 1329bf215546Sopenharmony_ci * fast clear path fallbacks to slow clears if one 1330bf215546Sopenharmony_ci * level can't be fast cleared. 1331bf215546Sopenharmony_ci */ 1332bf215546Sopenharmony_ci offset += 1333bf215546Sopenharmony_ci dcc_level->dcc_offset + dcc_level->dcc_slice_fast_clear_size * range->baseArrayLayer; 1334bf215546Sopenharmony_ci size = dcc_level->dcc_slice_fast_clear_size * radv_get_layerCount(image, range); 1335bf215546Sopenharmony_ci } 1336bf215546Sopenharmony_ci 1337bf215546Sopenharmony_ci /* Do not clear this level if it can't be compressed. */ 1338bf215546Sopenharmony_ci if (!size) 1339bf215546Sopenharmony_ci continue; 1340bf215546Sopenharmony_ci 1341bf215546Sopenharmony_ci flush_bits |= radv_fill_buffer(cmd_buffer, image, image->bindings[0].bo, 1342bf215546Sopenharmony_ci radv_buffer_get_va(image->bindings[0].bo) + offset, 1343bf215546Sopenharmony_ci size, value); 1344bf215546Sopenharmony_ci } 1345bf215546Sopenharmony_ci 1346bf215546Sopenharmony_ci return flush_bits; 1347bf215546Sopenharmony_ci} 1348bf215546Sopenharmony_ci 1349bf215546Sopenharmony_cistatic uint32_t 1350bf215546Sopenharmony_ciradv_clear_dcc_comp_to_single(struct radv_cmd_buffer *cmd_buffer, 1351bf215546Sopenharmony_ci struct radv_image *image, 1352bf215546Sopenharmony_ci const VkImageSubresourceRange *range, 1353bf215546Sopenharmony_ci uint32_t color_values[2]) 1354bf215546Sopenharmony_ci{ 1355bf215546Sopenharmony_ci struct radv_device *device = cmd_buffer->device; 1356bf215546Sopenharmony_ci unsigned bytes_per_pixel = vk_format_get_blocksize(image->vk.format); 1357bf215546Sopenharmony_ci unsigned layer_count = radv_get_layerCount(image, range); 1358bf215546Sopenharmony_ci struct radv_meta_saved_state saved_state; 1359bf215546Sopenharmony_ci bool is_msaa = image->info.samples > 1; 1360bf215546Sopenharmony_ci struct radv_image_view iview; 1361bf215546Sopenharmony_ci VkFormat format; 1362bf215546Sopenharmony_ci 1363bf215546Sopenharmony_ci switch (bytes_per_pixel) { 1364bf215546Sopenharmony_ci case 1: 1365bf215546Sopenharmony_ci format = VK_FORMAT_R8_UINT; 1366bf215546Sopenharmony_ci break; 1367bf215546Sopenharmony_ci case 2: 1368bf215546Sopenharmony_ci format = VK_FORMAT_R16_UINT; 1369bf215546Sopenharmony_ci break; 1370bf215546Sopenharmony_ci case 4: 1371bf215546Sopenharmony_ci format = VK_FORMAT_R32_UINT; 1372bf215546Sopenharmony_ci break; 1373bf215546Sopenharmony_ci case 8: 1374bf215546Sopenharmony_ci format = VK_FORMAT_R32G32_UINT; 1375bf215546Sopenharmony_ci break; 1376bf215546Sopenharmony_ci case 16: 1377bf215546Sopenharmony_ci format = VK_FORMAT_R32G32B32A32_UINT; 1378bf215546Sopenharmony_ci break; 1379bf215546Sopenharmony_ci default: 1380bf215546Sopenharmony_ci unreachable("Unsupported number of bytes per pixel"); 1381bf215546Sopenharmony_ci } 1382bf215546Sopenharmony_ci 1383bf215546Sopenharmony_ci radv_meta_save( 1384bf215546Sopenharmony_ci &saved_state, cmd_buffer, 1385bf215546Sopenharmony_ci RADV_META_SAVE_DESCRIPTORS | RADV_META_SAVE_COMPUTE_PIPELINE | RADV_META_SAVE_CONSTANTS); 1386bf215546Sopenharmony_ci 1387bf215546Sopenharmony_ci VkPipeline pipeline = device->meta_state.clear_dcc_comp_to_single_pipeline[is_msaa]; 1388bf215546Sopenharmony_ci 1389bf215546Sopenharmony_ci radv_CmdBindPipeline(radv_cmd_buffer_to_handle(cmd_buffer), VK_PIPELINE_BIND_POINT_COMPUTE, 1390bf215546Sopenharmony_ci pipeline); 1391bf215546Sopenharmony_ci 1392bf215546Sopenharmony_ci for (uint32_t l = 0; l < radv_get_levelCount(image, range); l++) { 1393bf215546Sopenharmony_ci uint32_t width, height; 1394bf215546Sopenharmony_ci 1395bf215546Sopenharmony_ci /* Do not write the clear color value for levels without DCC. */ 1396bf215546Sopenharmony_ci if (!radv_dcc_enabled(image, range->baseMipLevel + l)) 1397bf215546Sopenharmony_ci continue; 1398bf215546Sopenharmony_ci 1399bf215546Sopenharmony_ci width = radv_minify(image->info.width, range->baseMipLevel + l); 1400bf215546Sopenharmony_ci height = radv_minify(image->info.height, range->baseMipLevel + l); 1401bf215546Sopenharmony_ci 1402bf215546Sopenharmony_ci radv_image_view_init( 1403bf215546Sopenharmony_ci &iview, cmd_buffer->device, 1404bf215546Sopenharmony_ci &(VkImageViewCreateInfo){ 1405bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, 1406bf215546Sopenharmony_ci .image = radv_image_to_handle(image), 1407bf215546Sopenharmony_ci .viewType = VK_IMAGE_VIEW_TYPE_2D, 1408bf215546Sopenharmony_ci .format = format, 1409bf215546Sopenharmony_ci .subresourceRange = {.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, 1410bf215546Sopenharmony_ci .baseMipLevel = range->baseMipLevel + l, 1411bf215546Sopenharmony_ci .levelCount = 1, 1412bf215546Sopenharmony_ci .baseArrayLayer = range->baseArrayLayer, 1413bf215546Sopenharmony_ci .layerCount = layer_count}, 1414bf215546Sopenharmony_ci }, 1415bf215546Sopenharmony_ci 0, &(struct radv_image_view_extra_create_info){.disable_compression = true}); 1416bf215546Sopenharmony_ci 1417bf215546Sopenharmony_ci radv_meta_push_descriptor_set( 1418bf215546Sopenharmony_ci cmd_buffer, VK_PIPELINE_BIND_POINT_COMPUTE, 1419bf215546Sopenharmony_ci device->meta_state.clear_dcc_comp_to_single_p_layout, 0, 1420bf215546Sopenharmony_ci 1, 1421bf215546Sopenharmony_ci (VkWriteDescriptorSet[]){{.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, 1422bf215546Sopenharmony_ci .dstBinding = 0, 1423bf215546Sopenharmony_ci .dstArrayElement = 0, 1424bf215546Sopenharmony_ci .descriptorCount = 1, 1425bf215546Sopenharmony_ci .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1426bf215546Sopenharmony_ci .pImageInfo = 1427bf215546Sopenharmony_ci (VkDescriptorImageInfo[]){ 1428bf215546Sopenharmony_ci { 1429bf215546Sopenharmony_ci .sampler = VK_NULL_HANDLE, 1430bf215546Sopenharmony_ci .imageView = radv_image_view_to_handle(&iview), 1431bf215546Sopenharmony_ci .imageLayout = VK_IMAGE_LAYOUT_GENERAL, 1432bf215546Sopenharmony_ci }, 1433bf215546Sopenharmony_ci }}}); 1434bf215546Sopenharmony_ci 1435bf215546Sopenharmony_ci unsigned dcc_width = 1436bf215546Sopenharmony_ci DIV_ROUND_UP(width, image->planes[0].surface.u.gfx9.color.dcc_block_width); 1437bf215546Sopenharmony_ci unsigned dcc_height = 1438bf215546Sopenharmony_ci DIV_ROUND_UP(height, image->planes[0].surface.u.gfx9.color.dcc_block_height); 1439bf215546Sopenharmony_ci 1440bf215546Sopenharmony_ci const unsigned constants[4] = { 1441bf215546Sopenharmony_ci image->planes[0].surface.u.gfx9.color.dcc_block_width, 1442bf215546Sopenharmony_ci image->planes[0].surface.u.gfx9.color.dcc_block_height, 1443bf215546Sopenharmony_ci color_values[0], 1444bf215546Sopenharmony_ci color_values[1], 1445bf215546Sopenharmony_ci }; 1446bf215546Sopenharmony_ci 1447bf215546Sopenharmony_ci radv_CmdPushConstants(radv_cmd_buffer_to_handle(cmd_buffer), 1448bf215546Sopenharmony_ci device->meta_state.clear_dcc_comp_to_single_p_layout, 1449bf215546Sopenharmony_ci VK_SHADER_STAGE_COMPUTE_BIT, 0, 16, constants); 1450bf215546Sopenharmony_ci 1451bf215546Sopenharmony_ci radv_unaligned_dispatch(cmd_buffer, dcc_width, dcc_height, layer_count); 1452bf215546Sopenharmony_ci 1453bf215546Sopenharmony_ci radv_image_view_finish(&iview); 1454bf215546Sopenharmony_ci } 1455bf215546Sopenharmony_ci 1456bf215546Sopenharmony_ci radv_meta_restore(&saved_state, cmd_buffer); 1457bf215546Sopenharmony_ci 1458bf215546Sopenharmony_ci return RADV_CMD_FLAG_CS_PARTIAL_FLUSH | 1459bf215546Sopenharmony_ci radv_src_access_flush(cmd_buffer, VK_ACCESS_2_SHADER_WRITE_BIT, image); 1460bf215546Sopenharmony_ci} 1461bf215546Sopenharmony_ci 1462bf215546Sopenharmony_ciuint32_t 1463bf215546Sopenharmony_ciradv_clear_htile(struct radv_cmd_buffer *cmd_buffer, const struct radv_image *image, 1464bf215546Sopenharmony_ci const VkImageSubresourceRange *range, uint32_t value) 1465bf215546Sopenharmony_ci{ 1466bf215546Sopenharmony_ci uint32_t level_count = radv_get_levelCount(image, range); 1467bf215546Sopenharmony_ci uint32_t flush_bits = 0; 1468bf215546Sopenharmony_ci uint32_t htile_mask; 1469bf215546Sopenharmony_ci 1470bf215546Sopenharmony_ci htile_mask = radv_get_htile_mask(cmd_buffer->device, image, range->aspectMask); 1471bf215546Sopenharmony_ci 1472bf215546Sopenharmony_ci if (level_count != image->info.levels) { 1473bf215546Sopenharmony_ci assert(cmd_buffer->device->physical_device->rad_info.gfx_level >= GFX10); 1474bf215546Sopenharmony_ci 1475bf215546Sopenharmony_ci /* Clear individuals levels separately. */ 1476bf215546Sopenharmony_ci for (uint32_t l = 0; l < level_count; l++) { 1477bf215546Sopenharmony_ci uint32_t level = range->baseMipLevel + l; 1478bf215546Sopenharmony_ci uint64_t offset = image->bindings[0].offset + image->planes[0].surface.meta_offset + 1479bf215546Sopenharmony_ci image->planes[0].surface.u.gfx9.meta_levels[level].offset; 1480bf215546Sopenharmony_ci uint32_t size = image->planes[0].surface.u.gfx9.meta_levels[level].size; 1481bf215546Sopenharmony_ci 1482bf215546Sopenharmony_ci /* Do not clear this level if it can be compressed. */ 1483bf215546Sopenharmony_ci if (!size) 1484bf215546Sopenharmony_ci continue; 1485bf215546Sopenharmony_ci 1486bf215546Sopenharmony_ci if (htile_mask == UINT_MAX) { 1487bf215546Sopenharmony_ci /* Clear the whole HTILE buffer. */ 1488bf215546Sopenharmony_ci flush_bits |= radv_fill_buffer(cmd_buffer, image, image->bindings[0].bo, 1489bf215546Sopenharmony_ci radv_buffer_get_va(image->bindings[0].bo) + offset, 1490bf215546Sopenharmony_ci size, value); 1491bf215546Sopenharmony_ci } else { 1492bf215546Sopenharmony_ci /* Only clear depth or stencil bytes in the HTILE buffer. */ 1493bf215546Sopenharmony_ci flush_bits |= 1494bf215546Sopenharmony_ci clear_htile_mask(cmd_buffer, image, image->bindings[0].bo, offset, size, value, htile_mask); 1495bf215546Sopenharmony_ci } 1496bf215546Sopenharmony_ci } 1497bf215546Sopenharmony_ci } else { 1498bf215546Sopenharmony_ci unsigned layer_count = radv_get_layerCount(image, range); 1499bf215546Sopenharmony_ci uint64_t size = image->planes[0].surface.meta_slice_size * layer_count; 1500bf215546Sopenharmony_ci uint64_t offset = image->bindings[0].offset + image->planes[0].surface.meta_offset + 1501bf215546Sopenharmony_ci image->planes[0].surface.meta_slice_size * range->baseArrayLayer; 1502bf215546Sopenharmony_ci 1503bf215546Sopenharmony_ci if (htile_mask == UINT_MAX) { 1504bf215546Sopenharmony_ci /* Clear the whole HTILE buffer. */ 1505bf215546Sopenharmony_ci flush_bits = radv_fill_buffer(cmd_buffer, image, image->bindings[0].bo, 1506bf215546Sopenharmony_ci radv_buffer_get_va(image->bindings[0].bo) + offset, 1507bf215546Sopenharmony_ci size, value); 1508bf215546Sopenharmony_ci } else { 1509bf215546Sopenharmony_ci /* Only clear depth or stencil bytes in the HTILE buffer. */ 1510bf215546Sopenharmony_ci flush_bits = 1511bf215546Sopenharmony_ci clear_htile_mask(cmd_buffer, image, image->bindings[0].bo, offset, size, value, htile_mask); 1512bf215546Sopenharmony_ci } 1513bf215546Sopenharmony_ci } 1514bf215546Sopenharmony_ci 1515bf215546Sopenharmony_ci return flush_bits; 1516bf215546Sopenharmony_ci} 1517bf215546Sopenharmony_ci 1518bf215546Sopenharmony_cienum { 1519bf215546Sopenharmony_ci RADV_DCC_CLEAR_0000 = 0x00000000U, 1520bf215546Sopenharmony_ci RADV_DCC_GFX8_CLEAR_0001 = 0x40404040U, 1521bf215546Sopenharmony_ci RADV_DCC_GFX8_CLEAR_1110 = 0x80808080U, 1522bf215546Sopenharmony_ci RADV_DCC_GFX8_CLEAR_1111 = 0xC0C0C0C0U, 1523bf215546Sopenharmony_ci RADV_DCC_GFX8_CLEAR_REG = 0x20202020U, 1524bf215546Sopenharmony_ci RADV_DCC_GFX9_CLEAR_SINGLE = 0x10101010U, 1525bf215546Sopenharmony_ci RADV_DCC_GFX11_CLEAR_SINGLE = 0x01010101U, 1526bf215546Sopenharmony_ci RADV_DCC_GFX11_CLEAR_0000 = 0x00000000U, 1527bf215546Sopenharmony_ci RADV_DCC_GFX11_CLEAR_1111_UNORM = 0x02020202U, 1528bf215546Sopenharmony_ci RADV_DCC_GFX11_CLEAR_1111_FP16 = 0x04040404U, 1529bf215546Sopenharmony_ci RADV_DCC_GFX11_CLEAR_1111_FP32 = 0x06060606U, 1530bf215546Sopenharmony_ci RADV_DCC_GFX11_CLEAR_0001_UNORM = 0x08080808U, 1531bf215546Sopenharmony_ci RADV_DCC_GFX11_CLEAR_1110_UNORM = 0x0A0A0A0AU, 1532bf215546Sopenharmony_ci}; 1533bf215546Sopenharmony_ci 1534bf215546Sopenharmony_cistatic uint32_t 1535bf215546Sopenharmony_ciradv_dcc_single_clear_value(const struct radv_device *device) 1536bf215546Sopenharmony_ci{ 1537bf215546Sopenharmony_ci return device->physical_device->rad_info.gfx_level >= GFX11 ? RADV_DCC_GFX11_CLEAR_SINGLE 1538bf215546Sopenharmony_ci : RADV_DCC_GFX9_CLEAR_SINGLE; 1539bf215546Sopenharmony_ci} 1540bf215546Sopenharmony_ci 1541bf215546Sopenharmony_cistatic void 1542bf215546Sopenharmony_cigfx8_get_fast_clear_parameters(struct radv_device *device, const struct radv_image_view *iview, 1543bf215546Sopenharmony_ci const VkClearColorValue *clear_value, uint32_t *reset_value, 1544bf215546Sopenharmony_ci bool *can_avoid_fast_clear_elim) 1545bf215546Sopenharmony_ci{ 1546bf215546Sopenharmony_ci bool values[4] = {0}; 1547bf215546Sopenharmony_ci int extra_channel; 1548bf215546Sopenharmony_ci bool main_value = false; 1549bf215546Sopenharmony_ci bool extra_value = false; 1550bf215546Sopenharmony_ci bool has_color = false; 1551bf215546Sopenharmony_ci bool has_alpha = false; 1552bf215546Sopenharmony_ci 1553bf215546Sopenharmony_ci /* comp-to-single allows to perform DCC fast clears without requiring a FCE. */ 1554bf215546Sopenharmony_ci if (iview->image->support_comp_to_single) { 1555bf215546Sopenharmony_ci *reset_value = RADV_DCC_GFX9_CLEAR_SINGLE; 1556bf215546Sopenharmony_ci *can_avoid_fast_clear_elim = true; 1557bf215546Sopenharmony_ci } else { 1558bf215546Sopenharmony_ci *reset_value = RADV_DCC_GFX8_CLEAR_REG; 1559bf215546Sopenharmony_ci *can_avoid_fast_clear_elim = false; 1560bf215546Sopenharmony_ci } 1561bf215546Sopenharmony_ci 1562bf215546Sopenharmony_ci const struct util_format_description *desc = vk_format_description(iview->vk.format); 1563bf215546Sopenharmony_ci if (iview->vk.format == VK_FORMAT_B10G11R11_UFLOAT_PACK32 || 1564bf215546Sopenharmony_ci iview->vk.format == VK_FORMAT_R5G6B5_UNORM_PACK16 || iview->vk.format == VK_FORMAT_B5G6R5_UNORM_PACK16) 1565bf215546Sopenharmony_ci extra_channel = -1; 1566bf215546Sopenharmony_ci else if (desc->layout == UTIL_FORMAT_LAYOUT_PLAIN) { 1567bf215546Sopenharmony_ci if (vi_alpha_is_on_msb(device, iview->vk.format)) 1568bf215546Sopenharmony_ci extra_channel = desc->nr_channels - 1; 1569bf215546Sopenharmony_ci else 1570bf215546Sopenharmony_ci extra_channel = 0; 1571bf215546Sopenharmony_ci } else 1572bf215546Sopenharmony_ci return; 1573bf215546Sopenharmony_ci 1574bf215546Sopenharmony_ci for (int i = 0; i < 4; i++) { 1575bf215546Sopenharmony_ci int index = desc->swizzle[i] - PIPE_SWIZZLE_X; 1576bf215546Sopenharmony_ci if (desc->swizzle[i] < PIPE_SWIZZLE_X || desc->swizzle[i] > PIPE_SWIZZLE_W) 1577bf215546Sopenharmony_ci continue; 1578bf215546Sopenharmony_ci 1579bf215546Sopenharmony_ci if (desc->channel[i].pure_integer && desc->channel[i].type == UTIL_FORMAT_TYPE_SIGNED) { 1580bf215546Sopenharmony_ci /* Use the maximum value for clamping the clear color. */ 1581bf215546Sopenharmony_ci int max = u_bit_consecutive(0, desc->channel[i].size - 1); 1582bf215546Sopenharmony_ci 1583bf215546Sopenharmony_ci values[i] = clear_value->int32[i] != 0; 1584bf215546Sopenharmony_ci if (clear_value->int32[i] != 0 && MIN2(clear_value->int32[i], max) != max) 1585bf215546Sopenharmony_ci return; 1586bf215546Sopenharmony_ci } else if (desc->channel[i].pure_integer && 1587bf215546Sopenharmony_ci desc->channel[i].type == UTIL_FORMAT_TYPE_UNSIGNED) { 1588bf215546Sopenharmony_ci /* Use the maximum value for clamping the clear color. */ 1589bf215546Sopenharmony_ci unsigned max = u_bit_consecutive(0, desc->channel[i].size); 1590bf215546Sopenharmony_ci 1591bf215546Sopenharmony_ci values[i] = clear_value->uint32[i] != 0U; 1592bf215546Sopenharmony_ci if (clear_value->uint32[i] != 0U && MIN2(clear_value->uint32[i], max) != max) 1593bf215546Sopenharmony_ci return; 1594bf215546Sopenharmony_ci } else { 1595bf215546Sopenharmony_ci values[i] = clear_value->float32[i] != 0.0F; 1596bf215546Sopenharmony_ci if (clear_value->float32[i] != 0.0F && clear_value->float32[i] != 1.0F) 1597bf215546Sopenharmony_ci return; 1598bf215546Sopenharmony_ci } 1599bf215546Sopenharmony_ci 1600bf215546Sopenharmony_ci if (index == extra_channel) { 1601bf215546Sopenharmony_ci extra_value = values[i]; 1602bf215546Sopenharmony_ci has_alpha = true; 1603bf215546Sopenharmony_ci } else { 1604bf215546Sopenharmony_ci main_value = values[i]; 1605bf215546Sopenharmony_ci has_color = true; 1606bf215546Sopenharmony_ci } 1607bf215546Sopenharmony_ci } 1608bf215546Sopenharmony_ci 1609bf215546Sopenharmony_ci /* If alpha isn't present, make it the same as color, and vice versa. */ 1610bf215546Sopenharmony_ci if (!has_alpha) 1611bf215546Sopenharmony_ci extra_value = main_value; 1612bf215546Sopenharmony_ci else if (!has_color) 1613bf215546Sopenharmony_ci main_value = extra_value; 1614bf215546Sopenharmony_ci 1615bf215546Sopenharmony_ci for (int i = 0; i < 4; ++i) 1616bf215546Sopenharmony_ci if (values[i] != main_value && desc->swizzle[i] - PIPE_SWIZZLE_X != extra_channel && 1617bf215546Sopenharmony_ci desc->swizzle[i] >= PIPE_SWIZZLE_X && desc->swizzle[i] <= PIPE_SWIZZLE_W) 1618bf215546Sopenharmony_ci return; 1619bf215546Sopenharmony_ci 1620bf215546Sopenharmony_ci /* Only DCC clear code 0000 is allowed for signed<->unsigned formats. */ 1621bf215546Sopenharmony_ci if ((main_value || extra_value) && iview->image->dcc_sign_reinterpret) 1622bf215546Sopenharmony_ci return; 1623bf215546Sopenharmony_ci 1624bf215546Sopenharmony_ci *can_avoid_fast_clear_elim = true; 1625bf215546Sopenharmony_ci 1626bf215546Sopenharmony_ci if (main_value) { 1627bf215546Sopenharmony_ci if (extra_value) 1628bf215546Sopenharmony_ci *reset_value = RADV_DCC_GFX8_CLEAR_1111; 1629bf215546Sopenharmony_ci else 1630bf215546Sopenharmony_ci *reset_value = RADV_DCC_GFX8_CLEAR_1110; 1631bf215546Sopenharmony_ci } else { 1632bf215546Sopenharmony_ci if (extra_value) 1633bf215546Sopenharmony_ci *reset_value = RADV_DCC_GFX8_CLEAR_0001; 1634bf215546Sopenharmony_ci else 1635bf215546Sopenharmony_ci *reset_value = RADV_DCC_CLEAR_0000; 1636bf215546Sopenharmony_ci } 1637bf215546Sopenharmony_ci} 1638bf215546Sopenharmony_ci 1639bf215546Sopenharmony_cistatic bool 1640bf215546Sopenharmony_cigfx11_get_fast_clear_parameters(struct radv_device *device, const struct radv_image_view *iview, 1641bf215546Sopenharmony_ci const VkClearColorValue *clear_value, uint32_t *reset_value) 1642bf215546Sopenharmony_ci{ 1643bf215546Sopenharmony_ci int extra_channel; 1644bf215546Sopenharmony_ci 1645bf215546Sopenharmony_ci bool all_bits_are_0 = true; 1646bf215546Sopenharmony_ci bool all_bits_are_1 = true; 1647bf215546Sopenharmony_ci bool all_words_are_fp16_1 = true; 1648bf215546Sopenharmony_ci bool all_words_are_fp32_1 = true; 1649bf215546Sopenharmony_ci bool unorm_0001 = true; 1650bf215546Sopenharmony_ci bool unorm_1110 = true; 1651bf215546Sopenharmony_ci 1652bf215546Sopenharmony_ci const struct util_format_description *desc = vk_format_description(iview->vk.format); 1653bf215546Sopenharmony_ci if (iview->vk.format == VK_FORMAT_B10G11R11_UFLOAT_PACK32 || 1654bf215546Sopenharmony_ci iview->vk.format == VK_FORMAT_R5G6B5_UNORM_PACK16 || 1655bf215546Sopenharmony_ci iview->vk.format == VK_FORMAT_B5G6R5_UNORM_PACK16) 1656bf215546Sopenharmony_ci extra_channel = -1; 1657bf215546Sopenharmony_ci else if (desc->layout == UTIL_FORMAT_LAYOUT_PLAIN) { 1658bf215546Sopenharmony_ci if (vi_alpha_is_on_msb(device, iview->vk.format)) 1659bf215546Sopenharmony_ci extra_channel = desc->nr_channels - 1; 1660bf215546Sopenharmony_ci else 1661bf215546Sopenharmony_ci extra_channel = 0; 1662bf215546Sopenharmony_ci } else 1663bf215546Sopenharmony_ci return false; 1664bf215546Sopenharmony_ci 1665bf215546Sopenharmony_ci for (int i = 0; i < 4; i++) { 1666bf215546Sopenharmony_ci int index = desc->swizzle[i] - PIPE_SWIZZLE_X; 1667bf215546Sopenharmony_ci if (desc->swizzle[i] < PIPE_SWIZZLE_X || desc->swizzle[i] > PIPE_SWIZZLE_W) 1668bf215546Sopenharmony_ci continue; 1669bf215546Sopenharmony_ci 1670bf215546Sopenharmony_ci uint32_t extra_xor = index == extra_channel ? ~0u : 0; 1671bf215546Sopenharmony_ci if (clear_value->uint32[i] & ((1u << desc->channel[i].size) - 1)) 1672bf215546Sopenharmony_ci all_bits_are_0 = false; 1673bf215546Sopenharmony_ci if (~clear_value->uint32[i] & ((1u << desc->channel[i].size) - 1)) 1674bf215546Sopenharmony_ci all_bits_are_1 = false; 1675bf215546Sopenharmony_ci if (desc->channel[i].type != UTIL_FORMAT_TYPE_FLOAT || desc->channel[i].size != 16 || 1676bf215546Sopenharmony_ci clear_value->float32[i] != 1.0) 1677bf215546Sopenharmony_ci all_words_are_fp16_1 = false; 1678bf215546Sopenharmony_ci if (desc->channel[i].type != UTIL_FORMAT_TYPE_FLOAT || desc->channel[i].size != 32 || 1679bf215546Sopenharmony_ci clear_value->float32[i] != 1.0) 1680bf215546Sopenharmony_ci all_words_are_fp32_1 = false; 1681bf215546Sopenharmony_ci if ((clear_value->uint32[i] ^ extra_xor) & ((1u << desc->channel[i].size) - 1)) 1682bf215546Sopenharmony_ci unorm_0001 = false; 1683bf215546Sopenharmony_ci if ((~clear_value->uint32[i] ^ extra_xor) & ((1u << desc->channel[i].size) - 1)) 1684bf215546Sopenharmony_ci unorm_1110 = false; 1685bf215546Sopenharmony_ci } 1686bf215546Sopenharmony_ci 1687bf215546Sopenharmony_ci if (all_bits_are_0) 1688bf215546Sopenharmony_ci *reset_value = RADV_DCC_CLEAR_0000; 1689bf215546Sopenharmony_ci else if (all_bits_are_1) 1690bf215546Sopenharmony_ci *reset_value = RADV_DCC_GFX11_CLEAR_1111_UNORM; 1691bf215546Sopenharmony_ci else if (all_words_are_fp16_1) 1692bf215546Sopenharmony_ci *reset_value = RADV_DCC_GFX11_CLEAR_1111_FP16; 1693bf215546Sopenharmony_ci else if (all_words_are_fp32_1) 1694bf215546Sopenharmony_ci *reset_value = RADV_DCC_GFX11_CLEAR_1111_FP32; 1695bf215546Sopenharmony_ci else if (unorm_0001) 1696bf215546Sopenharmony_ci *reset_value = RADV_DCC_GFX11_CLEAR_0001_UNORM; 1697bf215546Sopenharmony_ci else if (unorm_1110) 1698bf215546Sopenharmony_ci *reset_value = RADV_DCC_GFX11_CLEAR_1110_UNORM; 1699bf215546Sopenharmony_ci else if (iview->image->support_comp_to_single) 1700bf215546Sopenharmony_ci *reset_value = RADV_DCC_GFX11_CLEAR_SINGLE; 1701bf215546Sopenharmony_ci else 1702bf215546Sopenharmony_ci return false; 1703bf215546Sopenharmony_ci 1704bf215546Sopenharmony_ci return true; 1705bf215546Sopenharmony_ci} 1706bf215546Sopenharmony_ci 1707bf215546Sopenharmony_cistatic bool 1708bf215546Sopenharmony_ciradv_can_fast_clear_color(struct radv_cmd_buffer *cmd_buffer, const struct radv_image_view *iview, 1709bf215546Sopenharmony_ci VkImageLayout image_layout, bool in_render_loop, 1710bf215546Sopenharmony_ci const VkClearRect *clear_rect, VkClearColorValue clear_value, 1711bf215546Sopenharmony_ci uint32_t view_mask) 1712bf215546Sopenharmony_ci{ 1713bf215546Sopenharmony_ci uint32_t clear_color[2]; 1714bf215546Sopenharmony_ci 1715bf215546Sopenharmony_ci if (!iview || !iview->support_fast_clear) 1716bf215546Sopenharmony_ci return false; 1717bf215546Sopenharmony_ci 1718bf215546Sopenharmony_ci if (!radv_layout_can_fast_clear( 1719bf215546Sopenharmony_ci cmd_buffer->device, iview->image, iview->vk.base_mip_level, image_layout, in_render_loop, 1720bf215546Sopenharmony_ci radv_image_queue_family_mask(iview->image, cmd_buffer->qf, 1721bf215546Sopenharmony_ci cmd_buffer->qf))) 1722bf215546Sopenharmony_ci return false; 1723bf215546Sopenharmony_ci 1724bf215546Sopenharmony_ci if (clear_rect->rect.offset.x || clear_rect->rect.offset.y || 1725bf215546Sopenharmony_ci clear_rect->rect.extent.width != iview->image->info.width || 1726bf215546Sopenharmony_ci clear_rect->rect.extent.height != iview->image->info.height) 1727bf215546Sopenharmony_ci return false; 1728bf215546Sopenharmony_ci 1729bf215546Sopenharmony_ci if (view_mask && (iview->image->info.array_size >= 32 || 1730bf215546Sopenharmony_ci (1u << iview->image->info.array_size) - 1u != view_mask)) 1731bf215546Sopenharmony_ci return false; 1732bf215546Sopenharmony_ci if (!view_mask && clear_rect->baseArrayLayer != 0) 1733bf215546Sopenharmony_ci return false; 1734bf215546Sopenharmony_ci if (!view_mask && clear_rect->layerCount != iview->image->info.array_size) 1735bf215546Sopenharmony_ci return false; 1736bf215546Sopenharmony_ci 1737bf215546Sopenharmony_ci /* DCC */ 1738bf215546Sopenharmony_ci if (!radv_format_pack_clear_color(iview->vk.format, clear_color, &clear_value)) 1739bf215546Sopenharmony_ci return false; 1740bf215546Sopenharmony_ci 1741bf215546Sopenharmony_ci /* Images that support comp-to-single clears don't have clear values. */ 1742bf215546Sopenharmony_ci if (!iview->image->support_comp_to_single && 1743bf215546Sopenharmony_ci !radv_image_has_clear_value(iview->image) && (clear_color[0] != 0 || clear_color[1] != 0)) 1744bf215546Sopenharmony_ci return false; 1745bf215546Sopenharmony_ci 1746bf215546Sopenharmony_ci if (radv_dcc_enabled(iview->image, iview->vk.base_mip_level)) { 1747bf215546Sopenharmony_ci bool can_avoid_fast_clear_elim; 1748bf215546Sopenharmony_ci uint32_t reset_value; 1749bf215546Sopenharmony_ci 1750bf215546Sopenharmony_ci if (cmd_buffer->device->physical_device->rad_info.gfx_level >= GFX11) { 1751bf215546Sopenharmony_ci if (!gfx11_get_fast_clear_parameters(cmd_buffer->device, iview, &clear_value, 1752bf215546Sopenharmony_ci &reset_value)) 1753bf215546Sopenharmony_ci return false; 1754bf215546Sopenharmony_ci } else { 1755bf215546Sopenharmony_ci gfx8_get_fast_clear_parameters(cmd_buffer->device, iview, &clear_value, &reset_value, 1756bf215546Sopenharmony_ci &can_avoid_fast_clear_elim); 1757bf215546Sopenharmony_ci } 1758bf215546Sopenharmony_ci 1759bf215546Sopenharmony_ci if (iview->image->info.levels > 1) { 1760bf215546Sopenharmony_ci if (cmd_buffer->device->physical_device->rad_info.gfx_level >= GFX9) { 1761bf215546Sopenharmony_ci uint32_t last_level = iview->vk.base_mip_level + iview->vk.level_count - 1; 1762bf215546Sopenharmony_ci if (last_level >= iview->image->planes[0].surface.num_meta_levels) { 1763bf215546Sopenharmony_ci /* Do not fast clears if one level can't be fast cleard. */ 1764bf215546Sopenharmony_ci return false; 1765bf215546Sopenharmony_ci } 1766bf215546Sopenharmony_ci } else { 1767bf215546Sopenharmony_ci for (uint32_t l = 0; l < iview->vk.level_count; l++) { 1768bf215546Sopenharmony_ci uint32_t level = iview->vk.base_mip_level + l; 1769bf215546Sopenharmony_ci struct legacy_surf_dcc_level *dcc_level = 1770bf215546Sopenharmony_ci &iview->image->planes[0].surface.u.legacy.color.dcc_level[level]; 1771bf215546Sopenharmony_ci 1772bf215546Sopenharmony_ci /* Do not fast clears if one level can't be 1773bf215546Sopenharmony_ci * fast cleared. 1774bf215546Sopenharmony_ci */ 1775bf215546Sopenharmony_ci if (!dcc_level->dcc_fast_clear_size) 1776bf215546Sopenharmony_ci return false; 1777bf215546Sopenharmony_ci } 1778bf215546Sopenharmony_ci } 1779bf215546Sopenharmony_ci } 1780bf215546Sopenharmony_ci } 1781bf215546Sopenharmony_ci 1782bf215546Sopenharmony_ci return true; 1783bf215546Sopenharmony_ci} 1784bf215546Sopenharmony_ci 1785bf215546Sopenharmony_cistatic void 1786bf215546Sopenharmony_ciradv_fast_clear_color(struct radv_cmd_buffer *cmd_buffer, const struct radv_image_view *iview, 1787bf215546Sopenharmony_ci const VkClearAttachment *clear_att, uint32_t subpass_att, 1788bf215546Sopenharmony_ci enum radv_cmd_flush_bits *pre_flush, enum radv_cmd_flush_bits *post_flush) 1789bf215546Sopenharmony_ci{ 1790bf215546Sopenharmony_ci VkClearColorValue clear_value = clear_att->clearValue.color; 1791bf215546Sopenharmony_ci uint32_t clear_color[2], flush_bits = 0; 1792bf215546Sopenharmony_ci uint32_t cmask_clear_value; 1793bf215546Sopenharmony_ci VkImageSubresourceRange range = { 1794bf215546Sopenharmony_ci .aspectMask = iview->vk.aspects, 1795bf215546Sopenharmony_ci .baseMipLevel = iview->vk.base_mip_level, 1796bf215546Sopenharmony_ci .levelCount = iview->vk.level_count, 1797bf215546Sopenharmony_ci .baseArrayLayer = iview->vk.base_array_layer, 1798bf215546Sopenharmony_ci .layerCount = iview->vk.layer_count, 1799bf215546Sopenharmony_ci }; 1800bf215546Sopenharmony_ci 1801bf215546Sopenharmony_ci if (pre_flush) { 1802bf215546Sopenharmony_ci enum radv_cmd_flush_bits bits = 1803bf215546Sopenharmony_ci radv_src_access_flush(cmd_buffer, VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT, iview->image) | 1804bf215546Sopenharmony_ci radv_dst_access_flush(cmd_buffer, VK_ACCESS_2_SHADER_WRITE_BIT, iview->image); 1805bf215546Sopenharmony_ci cmd_buffer->state.flush_bits |= bits & ~*pre_flush; 1806bf215546Sopenharmony_ci *pre_flush |= cmd_buffer->state.flush_bits; 1807bf215546Sopenharmony_ci } 1808bf215546Sopenharmony_ci 1809bf215546Sopenharmony_ci /* DCC */ 1810bf215546Sopenharmony_ci radv_format_pack_clear_color(iview->vk.format, clear_color, &clear_value); 1811bf215546Sopenharmony_ci 1812bf215546Sopenharmony_ci cmask_clear_value = radv_get_cmask_fast_clear_value(iview->image); 1813bf215546Sopenharmony_ci 1814bf215546Sopenharmony_ci /* clear cmask buffer */ 1815bf215546Sopenharmony_ci bool need_decompress_pass = false; 1816bf215546Sopenharmony_ci if (radv_dcc_enabled(iview->image, iview->vk.base_mip_level)) { 1817bf215546Sopenharmony_ci uint32_t reset_value; 1818bf215546Sopenharmony_ci bool can_avoid_fast_clear_elim = true; 1819bf215546Sopenharmony_ci 1820bf215546Sopenharmony_ci if (cmd_buffer->device->physical_device->rad_info.gfx_level >= GFX11) { 1821bf215546Sopenharmony_ci ASSERTED bool result = 1822bf215546Sopenharmony_ci gfx11_get_fast_clear_parameters(cmd_buffer->device, iview, &clear_value, &reset_value); 1823bf215546Sopenharmony_ci assert(result); 1824bf215546Sopenharmony_ci } else { 1825bf215546Sopenharmony_ci gfx8_get_fast_clear_parameters(cmd_buffer->device, iview, &clear_value, &reset_value, 1826bf215546Sopenharmony_ci &can_avoid_fast_clear_elim); 1827bf215546Sopenharmony_ci } 1828bf215546Sopenharmony_ci 1829bf215546Sopenharmony_ci if (radv_image_has_cmask(iview->image)) { 1830bf215546Sopenharmony_ci flush_bits = radv_clear_cmask(cmd_buffer, iview->image, &range, cmask_clear_value); 1831bf215546Sopenharmony_ci } 1832bf215546Sopenharmony_ci 1833bf215546Sopenharmony_ci if (!can_avoid_fast_clear_elim) 1834bf215546Sopenharmony_ci need_decompress_pass = true; 1835bf215546Sopenharmony_ci 1836bf215546Sopenharmony_ci flush_bits |= radv_clear_dcc(cmd_buffer, iview->image, &range, reset_value); 1837bf215546Sopenharmony_ci 1838bf215546Sopenharmony_ci if (reset_value == radv_dcc_single_clear_value(cmd_buffer->device)) { 1839bf215546Sopenharmony_ci /* Write the clear color to the first byte of each 256B block when the image supports DCC 1840bf215546Sopenharmony_ci * fast clears with comp-to-single. 1841bf215546Sopenharmony_ci */ 1842bf215546Sopenharmony_ci flush_bits |= radv_clear_dcc_comp_to_single(cmd_buffer, iview->image, &range, clear_color); 1843bf215546Sopenharmony_ci } 1844bf215546Sopenharmony_ci } else { 1845bf215546Sopenharmony_ci flush_bits = radv_clear_cmask(cmd_buffer, iview->image, &range, cmask_clear_value); 1846bf215546Sopenharmony_ci 1847bf215546Sopenharmony_ci /* Fast clearing with CMASK should always be eliminated. */ 1848bf215546Sopenharmony_ci need_decompress_pass = true; 1849bf215546Sopenharmony_ci } 1850bf215546Sopenharmony_ci 1851bf215546Sopenharmony_ci if (post_flush) { 1852bf215546Sopenharmony_ci *post_flush |= flush_bits; 1853bf215546Sopenharmony_ci } 1854bf215546Sopenharmony_ci 1855bf215546Sopenharmony_ci /* Update the FCE predicate to perform a fast-clear eliminate. */ 1856bf215546Sopenharmony_ci radv_update_fce_metadata(cmd_buffer, iview->image, &range, need_decompress_pass); 1857bf215546Sopenharmony_ci 1858bf215546Sopenharmony_ci radv_update_color_clear_metadata(cmd_buffer, iview, subpass_att, clear_color); 1859bf215546Sopenharmony_ci} 1860bf215546Sopenharmony_ci 1861bf215546Sopenharmony_ci/** 1862bf215546Sopenharmony_ci * The parameters mean that same as those in vkCmdClearAttachments. 1863bf215546Sopenharmony_ci */ 1864bf215546Sopenharmony_cistatic void 1865bf215546Sopenharmony_ciemit_clear(struct radv_cmd_buffer *cmd_buffer, const VkClearAttachment *clear_att, 1866bf215546Sopenharmony_ci const VkClearRect *clear_rect, enum radv_cmd_flush_bits *pre_flush, 1867bf215546Sopenharmony_ci enum radv_cmd_flush_bits *post_flush, uint32_t view_mask, bool ds_resolve_clear) 1868bf215546Sopenharmony_ci{ 1869bf215546Sopenharmony_ci const struct vk_framebuffer *fb = cmd_buffer->state.framebuffer; 1870bf215546Sopenharmony_ci const struct radv_subpass *subpass = cmd_buffer->state.subpass; 1871bf215546Sopenharmony_ci VkImageAspectFlags aspects = clear_att->aspectMask; 1872bf215546Sopenharmony_ci 1873bf215546Sopenharmony_ci if (aspects & VK_IMAGE_ASPECT_COLOR_BIT) { 1874bf215546Sopenharmony_ci const uint32_t subpass_att = clear_att->colorAttachment; 1875bf215546Sopenharmony_ci assert(subpass_att < subpass->color_count); 1876bf215546Sopenharmony_ci const uint32_t pass_att = subpass->color_attachments[subpass_att].attachment; 1877bf215546Sopenharmony_ci if (pass_att == VK_ATTACHMENT_UNUSED) 1878bf215546Sopenharmony_ci return; 1879bf215546Sopenharmony_ci 1880bf215546Sopenharmony_ci VkImageLayout image_layout = subpass->color_attachments[subpass_att].layout; 1881bf215546Sopenharmony_ci bool in_render_loop = subpass->color_attachments[subpass_att].in_render_loop; 1882bf215546Sopenharmony_ci const struct radv_image_view *iview = 1883bf215546Sopenharmony_ci fb ? cmd_buffer->state.attachments[pass_att].iview : NULL; 1884bf215546Sopenharmony_ci VkClearColorValue clear_value = clear_att->clearValue.color; 1885bf215546Sopenharmony_ci 1886bf215546Sopenharmony_ci if (radv_can_fast_clear_color(cmd_buffer, iview, image_layout, in_render_loop, clear_rect, 1887bf215546Sopenharmony_ci clear_value, view_mask)) { 1888bf215546Sopenharmony_ci radv_fast_clear_color(cmd_buffer, iview, clear_att, subpass_att, pre_flush, post_flush); 1889bf215546Sopenharmony_ci } else { 1890bf215546Sopenharmony_ci emit_color_clear(cmd_buffer, clear_att, clear_rect, view_mask); 1891bf215546Sopenharmony_ci } 1892bf215546Sopenharmony_ci } else { 1893bf215546Sopenharmony_ci struct radv_subpass_attachment *ds_att = subpass->depth_stencil_attachment; 1894bf215546Sopenharmony_ci 1895bf215546Sopenharmony_ci if (ds_resolve_clear) 1896bf215546Sopenharmony_ci ds_att = subpass->ds_resolve_attachment; 1897bf215546Sopenharmony_ci 1898bf215546Sopenharmony_ci if (!ds_att || ds_att->attachment == VK_ATTACHMENT_UNUSED) 1899bf215546Sopenharmony_ci return; 1900bf215546Sopenharmony_ci 1901bf215546Sopenharmony_ci VkImageLayout image_layout = ds_att->layout; 1902bf215546Sopenharmony_ci bool in_render_loop = ds_att->in_render_loop; 1903bf215546Sopenharmony_ci const struct radv_image_view *iview = 1904bf215546Sopenharmony_ci fb ? cmd_buffer->state.attachments[ds_att->attachment].iview : NULL; 1905bf215546Sopenharmony_ci VkClearDepthStencilValue clear_value = clear_att->clearValue.depthStencil; 1906bf215546Sopenharmony_ci 1907bf215546Sopenharmony_ci assert(aspects & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)); 1908bf215546Sopenharmony_ci 1909bf215546Sopenharmony_ci if (radv_can_fast_clear_depth(cmd_buffer, iview, image_layout, in_render_loop, aspects, 1910bf215546Sopenharmony_ci clear_rect, clear_value, view_mask)) { 1911bf215546Sopenharmony_ci radv_fast_clear_depth(cmd_buffer, iview, clear_att, pre_flush, post_flush); 1912bf215546Sopenharmony_ci } else { 1913bf215546Sopenharmony_ci emit_depthstencil_clear(cmd_buffer, clear_att, clear_rect, ds_att, view_mask, 1914bf215546Sopenharmony_ci ds_resolve_clear); 1915bf215546Sopenharmony_ci } 1916bf215546Sopenharmony_ci } 1917bf215546Sopenharmony_ci} 1918bf215546Sopenharmony_ci 1919bf215546Sopenharmony_cistatic inline bool 1920bf215546Sopenharmony_ciradv_attachment_needs_clear(struct radv_cmd_state *cmd_state, uint32_t a) 1921bf215546Sopenharmony_ci{ 1922bf215546Sopenharmony_ci uint32_t view_mask = cmd_state->subpass->view_mask; 1923bf215546Sopenharmony_ci return (a != VK_ATTACHMENT_UNUSED && cmd_state->attachments[a].pending_clear_aspects && 1924bf215546Sopenharmony_ci (!view_mask || (view_mask & ~cmd_state->attachments[a].cleared_views))); 1925bf215546Sopenharmony_ci} 1926bf215546Sopenharmony_ci 1927bf215546Sopenharmony_cistatic bool 1928bf215546Sopenharmony_ciradv_subpass_needs_clear(struct radv_cmd_buffer *cmd_buffer) 1929bf215546Sopenharmony_ci{ 1930bf215546Sopenharmony_ci struct radv_cmd_state *cmd_state = &cmd_buffer->state; 1931bf215546Sopenharmony_ci uint32_t a; 1932bf215546Sopenharmony_ci 1933bf215546Sopenharmony_ci if (!cmd_state->subpass) 1934bf215546Sopenharmony_ci return false; 1935bf215546Sopenharmony_ci 1936bf215546Sopenharmony_ci for (uint32_t i = 0; i < cmd_state->subpass->color_count; ++i) { 1937bf215546Sopenharmony_ci a = cmd_state->subpass->color_attachments[i].attachment; 1938bf215546Sopenharmony_ci if (radv_attachment_needs_clear(cmd_state, a)) 1939bf215546Sopenharmony_ci return true; 1940bf215546Sopenharmony_ci } 1941bf215546Sopenharmony_ci 1942bf215546Sopenharmony_ci if (cmd_state->subpass->depth_stencil_attachment) { 1943bf215546Sopenharmony_ci a = cmd_state->subpass->depth_stencil_attachment->attachment; 1944bf215546Sopenharmony_ci if (radv_attachment_needs_clear(cmd_state, a)) 1945bf215546Sopenharmony_ci return true; 1946bf215546Sopenharmony_ci } 1947bf215546Sopenharmony_ci 1948bf215546Sopenharmony_ci if (!cmd_state->subpass->ds_resolve_attachment) 1949bf215546Sopenharmony_ci return false; 1950bf215546Sopenharmony_ci 1951bf215546Sopenharmony_ci a = cmd_state->subpass->ds_resolve_attachment->attachment; 1952bf215546Sopenharmony_ci return radv_attachment_needs_clear(cmd_state, a); 1953bf215546Sopenharmony_ci} 1954bf215546Sopenharmony_ci 1955bf215546Sopenharmony_cistatic void 1956bf215546Sopenharmony_ciradv_subpass_clear_attachment(struct radv_cmd_buffer *cmd_buffer, 1957bf215546Sopenharmony_ci struct radv_attachment_state *attachment, 1958bf215546Sopenharmony_ci const VkClearAttachment *clear_att, 1959bf215546Sopenharmony_ci enum radv_cmd_flush_bits *pre_flush, 1960bf215546Sopenharmony_ci enum radv_cmd_flush_bits *post_flush, bool ds_resolve_clear) 1961bf215546Sopenharmony_ci{ 1962bf215546Sopenharmony_ci struct radv_cmd_state *cmd_state = &cmd_buffer->state; 1963bf215546Sopenharmony_ci uint32_t view_mask = cmd_state->subpass->view_mask; 1964bf215546Sopenharmony_ci 1965bf215546Sopenharmony_ci VkClearRect clear_rect = { 1966bf215546Sopenharmony_ci .rect = cmd_state->render_area, 1967bf215546Sopenharmony_ci .baseArrayLayer = 0, 1968bf215546Sopenharmony_ci .layerCount = cmd_state->framebuffer->layers, 1969bf215546Sopenharmony_ci }; 1970bf215546Sopenharmony_ci 1971bf215546Sopenharmony_ci radv_describe_begin_render_pass_clear(cmd_buffer, clear_att->aspectMask); 1972bf215546Sopenharmony_ci 1973bf215546Sopenharmony_ci emit_clear(cmd_buffer, clear_att, &clear_rect, pre_flush, post_flush, 1974bf215546Sopenharmony_ci view_mask & ~attachment->cleared_views, ds_resolve_clear); 1975bf215546Sopenharmony_ci if (view_mask) 1976bf215546Sopenharmony_ci attachment->cleared_views |= view_mask; 1977bf215546Sopenharmony_ci else 1978bf215546Sopenharmony_ci attachment->pending_clear_aspects = 0; 1979bf215546Sopenharmony_ci 1980bf215546Sopenharmony_ci radv_describe_end_render_pass_clear(cmd_buffer); 1981bf215546Sopenharmony_ci} 1982bf215546Sopenharmony_ci 1983bf215546Sopenharmony_ci/** 1984bf215546Sopenharmony_ci * Emit any pending attachment clears for the current subpass. 1985bf215546Sopenharmony_ci * 1986bf215546Sopenharmony_ci * @see radv_attachment_state::pending_clear_aspects 1987bf215546Sopenharmony_ci */ 1988bf215546Sopenharmony_civoid 1989bf215546Sopenharmony_ciradv_cmd_buffer_clear_subpass(struct radv_cmd_buffer *cmd_buffer) 1990bf215546Sopenharmony_ci{ 1991bf215546Sopenharmony_ci struct radv_cmd_state *cmd_state = &cmd_buffer->state; 1992bf215546Sopenharmony_ci struct radv_meta_saved_state saved_state; 1993bf215546Sopenharmony_ci enum radv_cmd_flush_bits pre_flush = 0; 1994bf215546Sopenharmony_ci enum radv_cmd_flush_bits post_flush = 0; 1995bf215546Sopenharmony_ci 1996bf215546Sopenharmony_ci if (!radv_subpass_needs_clear(cmd_buffer)) 1997bf215546Sopenharmony_ci return; 1998bf215546Sopenharmony_ci 1999bf215546Sopenharmony_ci /* Subpass clear should not be affected by conditional rendering. */ 2000bf215546Sopenharmony_ci radv_meta_save( 2001bf215546Sopenharmony_ci &saved_state, cmd_buffer, 2002bf215546Sopenharmony_ci RADV_META_SAVE_GRAPHICS_PIPELINE | RADV_META_SAVE_CONSTANTS | RADV_META_SUSPEND_PREDICATING); 2003bf215546Sopenharmony_ci 2004bf215546Sopenharmony_ci for (uint32_t i = 0; i < cmd_state->subpass->color_count; ++i) { 2005bf215546Sopenharmony_ci uint32_t a = cmd_state->subpass->color_attachments[i].attachment; 2006bf215546Sopenharmony_ci 2007bf215546Sopenharmony_ci if (!radv_attachment_needs_clear(cmd_state, a)) 2008bf215546Sopenharmony_ci continue; 2009bf215546Sopenharmony_ci 2010bf215546Sopenharmony_ci assert(cmd_state->attachments[a].pending_clear_aspects == VK_IMAGE_ASPECT_COLOR_BIT); 2011bf215546Sopenharmony_ci 2012bf215546Sopenharmony_ci VkClearAttachment clear_att = { 2013bf215546Sopenharmony_ci .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, 2014bf215546Sopenharmony_ci .colorAttachment = i, /* Use attachment index relative to subpass */ 2015bf215546Sopenharmony_ci .clearValue = cmd_state->attachments[a].clear_value, 2016bf215546Sopenharmony_ci }; 2017bf215546Sopenharmony_ci 2018bf215546Sopenharmony_ci radv_subpass_clear_attachment(cmd_buffer, &cmd_state->attachments[a], &clear_att, &pre_flush, 2019bf215546Sopenharmony_ci &post_flush, false); 2020bf215546Sopenharmony_ci } 2021bf215546Sopenharmony_ci 2022bf215546Sopenharmony_ci if (cmd_state->subpass->depth_stencil_attachment) { 2023bf215546Sopenharmony_ci uint32_t ds = cmd_state->subpass->depth_stencil_attachment->attachment; 2024bf215546Sopenharmony_ci if (radv_attachment_needs_clear(cmd_state, ds)) { 2025bf215546Sopenharmony_ci VkClearAttachment clear_att = { 2026bf215546Sopenharmony_ci .aspectMask = cmd_state->attachments[ds].pending_clear_aspects, 2027bf215546Sopenharmony_ci .clearValue = cmd_state->attachments[ds].clear_value, 2028bf215546Sopenharmony_ci }; 2029bf215546Sopenharmony_ci 2030bf215546Sopenharmony_ci radv_subpass_clear_attachment(cmd_buffer, &cmd_state->attachments[ds], &clear_att, 2031bf215546Sopenharmony_ci &pre_flush, &post_flush, false); 2032bf215546Sopenharmony_ci } 2033bf215546Sopenharmony_ci } 2034bf215546Sopenharmony_ci 2035bf215546Sopenharmony_ci if (cmd_state->subpass->ds_resolve_attachment) { 2036bf215546Sopenharmony_ci uint32_t ds_resolve = cmd_state->subpass->ds_resolve_attachment->attachment; 2037bf215546Sopenharmony_ci if (radv_attachment_needs_clear(cmd_state, ds_resolve)) { 2038bf215546Sopenharmony_ci VkClearAttachment clear_att = { 2039bf215546Sopenharmony_ci .aspectMask = cmd_state->attachments[ds_resolve].pending_clear_aspects, 2040bf215546Sopenharmony_ci .clearValue = cmd_state->attachments[ds_resolve].clear_value, 2041bf215546Sopenharmony_ci }; 2042bf215546Sopenharmony_ci 2043bf215546Sopenharmony_ci radv_subpass_clear_attachment(cmd_buffer, &cmd_state->attachments[ds_resolve], &clear_att, 2044bf215546Sopenharmony_ci &pre_flush, &post_flush, true); 2045bf215546Sopenharmony_ci } 2046bf215546Sopenharmony_ci } 2047bf215546Sopenharmony_ci 2048bf215546Sopenharmony_ci radv_meta_restore(&saved_state, cmd_buffer); 2049bf215546Sopenharmony_ci cmd_buffer->state.flush_bits |= post_flush; 2050bf215546Sopenharmony_ci} 2051bf215546Sopenharmony_ci 2052bf215546Sopenharmony_cistatic void 2053bf215546Sopenharmony_ciradv_clear_image_layer(struct radv_cmd_buffer *cmd_buffer, struct radv_image *image, 2054bf215546Sopenharmony_ci VkImageLayout image_layout, const VkImageSubresourceRange *range, 2055bf215546Sopenharmony_ci VkFormat format, int level, unsigned layer_count, 2056bf215546Sopenharmony_ci const VkClearValue *clear_val) 2057bf215546Sopenharmony_ci{ 2058bf215546Sopenharmony_ci struct radv_image_view iview; 2059bf215546Sopenharmony_ci uint32_t width = radv_minify(image->info.width, range->baseMipLevel + level); 2060bf215546Sopenharmony_ci uint32_t height = radv_minify(image->info.height, range->baseMipLevel + level); 2061bf215546Sopenharmony_ci 2062bf215546Sopenharmony_ci radv_image_view_init(&iview, cmd_buffer->device, 2063bf215546Sopenharmony_ci &(VkImageViewCreateInfo){ 2064bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, 2065bf215546Sopenharmony_ci .image = radv_image_to_handle(image), 2066bf215546Sopenharmony_ci .viewType = radv_meta_get_view_type(image), 2067bf215546Sopenharmony_ci .format = format, 2068bf215546Sopenharmony_ci .subresourceRange = {.aspectMask = range->aspectMask, 2069bf215546Sopenharmony_ci .baseMipLevel = range->baseMipLevel + level, 2070bf215546Sopenharmony_ci .levelCount = 1, 2071bf215546Sopenharmony_ci .baseArrayLayer = range->baseArrayLayer, 2072bf215546Sopenharmony_ci .layerCount = layer_count}, 2073bf215546Sopenharmony_ci }, 2074bf215546Sopenharmony_ci 0, NULL); 2075bf215546Sopenharmony_ci 2076bf215546Sopenharmony_ci VkClearAttachment clear_att = { 2077bf215546Sopenharmony_ci .aspectMask = range->aspectMask, 2078bf215546Sopenharmony_ci .colorAttachment = 0, 2079bf215546Sopenharmony_ci .clearValue = *clear_val, 2080bf215546Sopenharmony_ci }; 2081bf215546Sopenharmony_ci 2082bf215546Sopenharmony_ci VkClearRect clear_rect = { 2083bf215546Sopenharmony_ci .rect = 2084bf215546Sopenharmony_ci { 2085bf215546Sopenharmony_ci .offset = {0, 0}, 2086bf215546Sopenharmony_ci .extent = {width, height}, 2087bf215546Sopenharmony_ci }, 2088bf215546Sopenharmony_ci .baseArrayLayer = 0, 2089bf215546Sopenharmony_ci .layerCount = layer_count, 2090bf215546Sopenharmony_ci }; 2091bf215546Sopenharmony_ci 2092bf215546Sopenharmony_ci VkRenderingAttachmentInfo color_att = {0}, depth_att = {0}, stencil_att = {0}; 2093bf215546Sopenharmony_ci 2094bf215546Sopenharmony_ci if (range->aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) { 2095bf215546Sopenharmony_ci color_att.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO; 2096bf215546Sopenharmony_ci color_att.imageView = radv_image_view_to_handle(&iview); 2097bf215546Sopenharmony_ci color_att.imageLayout = image_layout; 2098bf215546Sopenharmony_ci color_att.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD; 2099bf215546Sopenharmony_ci color_att.storeOp = VK_ATTACHMENT_STORE_OP_STORE; 2100bf215546Sopenharmony_ci } else { 2101bf215546Sopenharmony_ci if (range->aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) { 2102bf215546Sopenharmony_ci depth_att.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO; 2103bf215546Sopenharmony_ci depth_att.imageView = radv_image_view_to_handle(&iview); 2104bf215546Sopenharmony_ci depth_att.imageLayout = image_layout; 2105bf215546Sopenharmony_ci depth_att.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD; 2106bf215546Sopenharmony_ci depth_att.storeOp = VK_ATTACHMENT_STORE_OP_STORE; 2107bf215546Sopenharmony_ci } 2108bf215546Sopenharmony_ci 2109bf215546Sopenharmony_ci if (range->aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) { 2110bf215546Sopenharmony_ci stencil_att.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO; 2111bf215546Sopenharmony_ci stencil_att.imageView = radv_image_view_to_handle(&iview); 2112bf215546Sopenharmony_ci stencil_att.imageLayout = image_layout; 2113bf215546Sopenharmony_ci stencil_att.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD; 2114bf215546Sopenharmony_ci stencil_att.storeOp = VK_ATTACHMENT_STORE_OP_STORE; 2115bf215546Sopenharmony_ci } 2116bf215546Sopenharmony_ci } 2117bf215546Sopenharmony_ci 2118bf215546Sopenharmony_ci VkRenderingInfo rendering_info = { 2119bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_RENDERING_INFO, 2120bf215546Sopenharmony_ci .renderArea = { 2121bf215546Sopenharmony_ci .offset = { 0, 0 }, 2122bf215546Sopenharmony_ci .extent = { width, height }, 2123bf215546Sopenharmony_ci }, 2124bf215546Sopenharmony_ci .layerCount = layer_count, 2125bf215546Sopenharmony_ci }; 2126bf215546Sopenharmony_ci 2127bf215546Sopenharmony_ci if (range->aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) { 2128bf215546Sopenharmony_ci rendering_info.colorAttachmentCount = 1; 2129bf215546Sopenharmony_ci rendering_info.pColorAttachments = &color_att; 2130bf215546Sopenharmony_ci } else { 2131bf215546Sopenharmony_ci if (range->aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) 2132bf215546Sopenharmony_ci rendering_info.pDepthAttachment = &depth_att; 2133bf215546Sopenharmony_ci if (range->aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) 2134bf215546Sopenharmony_ci rendering_info.pStencilAttachment = &stencil_att; 2135bf215546Sopenharmony_ci } 2136bf215546Sopenharmony_ci 2137bf215546Sopenharmony_ci radv_CmdBeginRendering(radv_cmd_buffer_to_handle(cmd_buffer), &rendering_info); 2138bf215546Sopenharmony_ci 2139bf215546Sopenharmony_ci emit_clear(cmd_buffer, &clear_att, &clear_rect, NULL, NULL, 0, false); 2140bf215546Sopenharmony_ci 2141bf215546Sopenharmony_ci radv_CmdEndRendering(radv_cmd_buffer_to_handle(cmd_buffer)); 2142bf215546Sopenharmony_ci 2143bf215546Sopenharmony_ci radv_image_view_finish(&iview); 2144bf215546Sopenharmony_ci} 2145bf215546Sopenharmony_ci 2146bf215546Sopenharmony_ci/** 2147bf215546Sopenharmony_ci * Return TRUE if a fast color or depth clear has been performed. 2148bf215546Sopenharmony_ci */ 2149bf215546Sopenharmony_cistatic bool 2150bf215546Sopenharmony_ciradv_fast_clear_range(struct radv_cmd_buffer *cmd_buffer, struct radv_image *image, VkFormat format, 2151bf215546Sopenharmony_ci VkImageLayout image_layout, bool in_render_loop, 2152bf215546Sopenharmony_ci const VkImageSubresourceRange *range, const VkClearValue *clear_val) 2153bf215546Sopenharmony_ci{ 2154bf215546Sopenharmony_ci struct radv_image_view iview; 2155bf215546Sopenharmony_ci bool fast_cleared = false; 2156bf215546Sopenharmony_ci 2157bf215546Sopenharmony_ci radv_image_view_init(&iview, cmd_buffer->device, 2158bf215546Sopenharmony_ci &(VkImageViewCreateInfo){ 2159bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, 2160bf215546Sopenharmony_ci .image = radv_image_to_handle(image), 2161bf215546Sopenharmony_ci .viewType = radv_meta_get_view_type(image), 2162bf215546Sopenharmony_ci .format = image->vk.format, 2163bf215546Sopenharmony_ci .subresourceRange = 2164bf215546Sopenharmony_ci { 2165bf215546Sopenharmony_ci .aspectMask = range->aspectMask, 2166bf215546Sopenharmony_ci .baseMipLevel = range->baseMipLevel, 2167bf215546Sopenharmony_ci .levelCount = range->levelCount, 2168bf215546Sopenharmony_ci .baseArrayLayer = range->baseArrayLayer, 2169bf215546Sopenharmony_ci .layerCount = range->layerCount, 2170bf215546Sopenharmony_ci }, 2171bf215546Sopenharmony_ci }, 2172bf215546Sopenharmony_ci 0, NULL); 2173bf215546Sopenharmony_ci 2174bf215546Sopenharmony_ci VkClearRect clear_rect = { 2175bf215546Sopenharmony_ci .rect = 2176bf215546Sopenharmony_ci { 2177bf215546Sopenharmony_ci .offset = {0, 0}, 2178bf215546Sopenharmony_ci .extent = 2179bf215546Sopenharmony_ci { 2180bf215546Sopenharmony_ci radv_minify(image->info.width, range->baseMipLevel), 2181bf215546Sopenharmony_ci radv_minify(image->info.height, range->baseMipLevel), 2182bf215546Sopenharmony_ci }, 2183bf215546Sopenharmony_ci }, 2184bf215546Sopenharmony_ci .baseArrayLayer = range->baseArrayLayer, 2185bf215546Sopenharmony_ci .layerCount = range->layerCount, 2186bf215546Sopenharmony_ci }; 2187bf215546Sopenharmony_ci 2188bf215546Sopenharmony_ci VkClearAttachment clear_att = { 2189bf215546Sopenharmony_ci .aspectMask = range->aspectMask, 2190bf215546Sopenharmony_ci .colorAttachment = 0, 2191bf215546Sopenharmony_ci .clearValue = *clear_val, 2192bf215546Sopenharmony_ci }; 2193bf215546Sopenharmony_ci 2194bf215546Sopenharmony_ci if (vk_format_is_color(format)) { 2195bf215546Sopenharmony_ci if (radv_can_fast_clear_color(cmd_buffer, &iview, image_layout, in_render_loop, &clear_rect, 2196bf215546Sopenharmony_ci clear_att.clearValue.color, 0)) { 2197bf215546Sopenharmony_ci radv_fast_clear_color(cmd_buffer, &iview, &clear_att, clear_att.colorAttachment, NULL, 2198bf215546Sopenharmony_ci NULL); 2199bf215546Sopenharmony_ci fast_cleared = true; 2200bf215546Sopenharmony_ci } 2201bf215546Sopenharmony_ci } else { 2202bf215546Sopenharmony_ci if (radv_can_fast_clear_depth(cmd_buffer, &iview, image_layout, in_render_loop, 2203bf215546Sopenharmony_ci range->aspectMask, &clear_rect, 2204bf215546Sopenharmony_ci clear_att.clearValue.depthStencil, 0)) { 2205bf215546Sopenharmony_ci radv_fast_clear_depth(cmd_buffer, &iview, &clear_att, NULL, NULL); 2206bf215546Sopenharmony_ci fast_cleared = true; 2207bf215546Sopenharmony_ci } 2208bf215546Sopenharmony_ci } 2209bf215546Sopenharmony_ci 2210bf215546Sopenharmony_ci radv_image_view_finish(&iview); 2211bf215546Sopenharmony_ci return fast_cleared; 2212bf215546Sopenharmony_ci} 2213bf215546Sopenharmony_ci 2214bf215546Sopenharmony_cistatic void 2215bf215546Sopenharmony_ciradv_cmd_clear_image(struct radv_cmd_buffer *cmd_buffer, struct radv_image *image, 2216bf215546Sopenharmony_ci VkImageLayout image_layout, const VkClearValue *clear_value, 2217bf215546Sopenharmony_ci uint32_t range_count, const VkImageSubresourceRange *ranges, bool cs) 2218bf215546Sopenharmony_ci{ 2219bf215546Sopenharmony_ci VkFormat format = image->vk.format; 2220bf215546Sopenharmony_ci VkClearValue internal_clear_value; 2221bf215546Sopenharmony_ci 2222bf215546Sopenharmony_ci if (ranges->aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) 2223bf215546Sopenharmony_ci internal_clear_value.color = clear_value->color; 2224bf215546Sopenharmony_ci else 2225bf215546Sopenharmony_ci internal_clear_value.depthStencil = clear_value->depthStencil; 2226bf215546Sopenharmony_ci 2227bf215546Sopenharmony_ci bool disable_compression = false; 2228bf215546Sopenharmony_ci 2229bf215546Sopenharmony_ci if (format == VK_FORMAT_E5B9G9R9_UFLOAT_PACK32) { 2230bf215546Sopenharmony_ci bool blendable; 2231bf215546Sopenharmony_ci if (cs ? !radv_is_storage_image_format_supported(cmd_buffer->device->physical_device, format) 2232bf215546Sopenharmony_ci : !radv_is_colorbuffer_format_supported(cmd_buffer->device->physical_device, format, 2233bf215546Sopenharmony_ci &blendable)) { 2234bf215546Sopenharmony_ci format = VK_FORMAT_R32_UINT; 2235bf215546Sopenharmony_ci internal_clear_value.color.uint32[0] = float3_to_rgb9e5(clear_value->color.float32); 2236bf215546Sopenharmony_ci 2237bf215546Sopenharmony_ci uint32_t queue_mask = radv_image_queue_family_mask(image, cmd_buffer->qf, 2238bf215546Sopenharmony_ci cmd_buffer->qf); 2239bf215546Sopenharmony_ci 2240bf215546Sopenharmony_ci for (uint32_t r = 0; r < range_count; r++) { 2241bf215546Sopenharmony_ci const VkImageSubresourceRange *range = &ranges[r]; 2242bf215546Sopenharmony_ci 2243bf215546Sopenharmony_ci /* Don't use compressed image stores because they will use an incompatible format. */ 2244bf215546Sopenharmony_ci if (radv_layout_dcc_compressed(cmd_buffer->device, image, range->baseMipLevel, 2245bf215546Sopenharmony_ci image_layout, false, queue_mask)) { 2246bf215546Sopenharmony_ci disable_compression = cs; 2247bf215546Sopenharmony_ci break; 2248bf215546Sopenharmony_ci } 2249bf215546Sopenharmony_ci } 2250bf215546Sopenharmony_ci } 2251bf215546Sopenharmony_ci } 2252bf215546Sopenharmony_ci 2253bf215546Sopenharmony_ci if (format == VK_FORMAT_R4G4_UNORM_PACK8) { 2254bf215546Sopenharmony_ci uint8_t r, g; 2255bf215546Sopenharmony_ci format = VK_FORMAT_R8_UINT; 2256bf215546Sopenharmony_ci r = float_to_ubyte(clear_value->color.float32[0]) >> 4; 2257bf215546Sopenharmony_ci g = float_to_ubyte(clear_value->color.float32[1]) >> 4; 2258bf215546Sopenharmony_ci internal_clear_value.color.uint32[0] = (r << 4) | (g & 0xf); 2259bf215546Sopenharmony_ci } 2260bf215546Sopenharmony_ci 2261bf215546Sopenharmony_ci for (uint32_t r = 0; r < range_count; r++) { 2262bf215546Sopenharmony_ci const VkImageSubresourceRange *range = &ranges[r]; 2263bf215546Sopenharmony_ci 2264bf215546Sopenharmony_ci /* Try to perform a fast clear first, otherwise fallback to 2265bf215546Sopenharmony_ci * the legacy path. 2266bf215546Sopenharmony_ci */ 2267bf215546Sopenharmony_ci if (!cs && radv_fast_clear_range(cmd_buffer, image, format, image_layout, false, range, 2268bf215546Sopenharmony_ci &internal_clear_value)) { 2269bf215546Sopenharmony_ci continue; 2270bf215546Sopenharmony_ci } 2271bf215546Sopenharmony_ci 2272bf215546Sopenharmony_ci for (uint32_t l = 0; l < radv_get_levelCount(image, range); ++l) { 2273bf215546Sopenharmony_ci const uint32_t layer_count = image->vk.image_type == VK_IMAGE_TYPE_3D 2274bf215546Sopenharmony_ci ? radv_minify(image->info.depth, range->baseMipLevel + l) 2275bf215546Sopenharmony_ci : radv_get_layerCount(image, range); 2276bf215546Sopenharmony_ci 2277bf215546Sopenharmony_ci if (cs) { 2278bf215546Sopenharmony_ci for (uint32_t s = 0; s < layer_count; ++s) { 2279bf215546Sopenharmony_ci struct radv_meta_blit2d_surf surf; 2280bf215546Sopenharmony_ci surf.format = format; 2281bf215546Sopenharmony_ci surf.image = image; 2282bf215546Sopenharmony_ci surf.level = range->baseMipLevel + l; 2283bf215546Sopenharmony_ci surf.layer = range->baseArrayLayer + s; 2284bf215546Sopenharmony_ci surf.aspect_mask = range->aspectMask; 2285bf215546Sopenharmony_ci surf.disable_compression = disable_compression; 2286bf215546Sopenharmony_ci radv_meta_clear_image_cs(cmd_buffer, &surf, &internal_clear_value.color); 2287bf215546Sopenharmony_ci } 2288bf215546Sopenharmony_ci } else { 2289bf215546Sopenharmony_ci assert(!disable_compression); 2290bf215546Sopenharmony_ci radv_clear_image_layer(cmd_buffer, image, image_layout, range, format, l, layer_count, 2291bf215546Sopenharmony_ci &internal_clear_value); 2292bf215546Sopenharmony_ci } 2293bf215546Sopenharmony_ci } 2294bf215546Sopenharmony_ci } 2295bf215546Sopenharmony_ci 2296bf215546Sopenharmony_ci if (disable_compression) { 2297bf215546Sopenharmony_ci enum radv_cmd_flush_bits flush_bits = 0; 2298bf215546Sopenharmony_ci for (unsigned i = 0; i < range_count; i++) { 2299bf215546Sopenharmony_ci if (radv_dcc_enabled(image, ranges[i].baseMipLevel)) 2300bf215546Sopenharmony_ci flush_bits |= radv_clear_dcc(cmd_buffer, image, &ranges[i], 0xffffffffu); 2301bf215546Sopenharmony_ci } 2302bf215546Sopenharmony_ci cmd_buffer->state.flush_bits |= flush_bits; 2303bf215546Sopenharmony_ci } 2304bf215546Sopenharmony_ci} 2305bf215546Sopenharmony_ci 2306bf215546Sopenharmony_ciVKAPI_ATTR void VKAPI_CALL 2307bf215546Sopenharmony_ciradv_CmdClearColorImage(VkCommandBuffer commandBuffer, VkImage image_h, VkImageLayout imageLayout, 2308bf215546Sopenharmony_ci const VkClearColorValue *pColor, uint32_t rangeCount, 2309bf215546Sopenharmony_ci const VkImageSubresourceRange *pRanges) 2310bf215546Sopenharmony_ci{ 2311bf215546Sopenharmony_ci RADV_FROM_HANDLE(radv_cmd_buffer, cmd_buffer, commandBuffer); 2312bf215546Sopenharmony_ci RADV_FROM_HANDLE(radv_image, image, image_h); 2313bf215546Sopenharmony_ci struct radv_meta_saved_state saved_state; 2314bf215546Sopenharmony_ci bool cs; 2315bf215546Sopenharmony_ci 2316bf215546Sopenharmony_ci cs = cmd_buffer->qf == RADV_QUEUE_COMPUTE || 2317bf215546Sopenharmony_ci !radv_image_is_renderable(cmd_buffer->device, image); 2318bf215546Sopenharmony_ci 2319bf215546Sopenharmony_ci /* Clear commands (except vkCmdClearAttachments) should not be affected by conditional rendering. 2320bf215546Sopenharmony_ci */ 2321bf215546Sopenharmony_ci enum radv_meta_save_flags save_flags = RADV_META_SAVE_CONSTANTS | RADV_META_SUSPEND_PREDICATING; 2322bf215546Sopenharmony_ci if (cs) 2323bf215546Sopenharmony_ci save_flags |= RADV_META_SAVE_COMPUTE_PIPELINE | RADV_META_SAVE_DESCRIPTORS; 2324bf215546Sopenharmony_ci else 2325bf215546Sopenharmony_ci save_flags |= RADV_META_SAVE_GRAPHICS_PIPELINE; 2326bf215546Sopenharmony_ci 2327bf215546Sopenharmony_ci radv_meta_save(&saved_state, cmd_buffer, save_flags); 2328bf215546Sopenharmony_ci 2329bf215546Sopenharmony_ci radv_cmd_clear_image(cmd_buffer, image, imageLayout, (const VkClearValue *)pColor, rangeCount, 2330bf215546Sopenharmony_ci pRanges, cs); 2331bf215546Sopenharmony_ci 2332bf215546Sopenharmony_ci radv_meta_restore(&saved_state, cmd_buffer); 2333bf215546Sopenharmony_ci} 2334bf215546Sopenharmony_ci 2335bf215546Sopenharmony_ciVKAPI_ATTR void VKAPI_CALL 2336bf215546Sopenharmony_ciradv_CmdClearDepthStencilImage(VkCommandBuffer commandBuffer, VkImage image_h, 2337bf215546Sopenharmony_ci VkImageLayout imageLayout, 2338bf215546Sopenharmony_ci const VkClearDepthStencilValue *pDepthStencil, uint32_t rangeCount, 2339bf215546Sopenharmony_ci const VkImageSubresourceRange *pRanges) 2340bf215546Sopenharmony_ci{ 2341bf215546Sopenharmony_ci RADV_FROM_HANDLE(radv_cmd_buffer, cmd_buffer, commandBuffer); 2342bf215546Sopenharmony_ci RADV_FROM_HANDLE(radv_image, image, image_h); 2343bf215546Sopenharmony_ci struct radv_meta_saved_state saved_state; 2344bf215546Sopenharmony_ci 2345bf215546Sopenharmony_ci /* Clear commands (except vkCmdClearAttachments) should not be affected by conditional rendering. */ 2346bf215546Sopenharmony_ci radv_meta_save( 2347bf215546Sopenharmony_ci &saved_state, cmd_buffer, 2348bf215546Sopenharmony_ci RADV_META_SAVE_GRAPHICS_PIPELINE | RADV_META_SAVE_CONSTANTS | RADV_META_SUSPEND_PREDICATING); 2349bf215546Sopenharmony_ci 2350bf215546Sopenharmony_ci radv_cmd_clear_image(cmd_buffer, image, imageLayout, (const VkClearValue *)pDepthStencil, 2351bf215546Sopenharmony_ci rangeCount, pRanges, false); 2352bf215546Sopenharmony_ci 2353bf215546Sopenharmony_ci radv_meta_restore(&saved_state, cmd_buffer); 2354bf215546Sopenharmony_ci} 2355bf215546Sopenharmony_ci 2356bf215546Sopenharmony_ciVKAPI_ATTR void VKAPI_CALL 2357bf215546Sopenharmony_ciradv_CmdClearAttachments(VkCommandBuffer commandBuffer, uint32_t attachmentCount, 2358bf215546Sopenharmony_ci const VkClearAttachment *pAttachments, uint32_t rectCount, 2359bf215546Sopenharmony_ci const VkClearRect *pRects) 2360bf215546Sopenharmony_ci{ 2361bf215546Sopenharmony_ci RADV_FROM_HANDLE(radv_cmd_buffer, cmd_buffer, commandBuffer); 2362bf215546Sopenharmony_ci struct radv_meta_saved_state saved_state; 2363bf215546Sopenharmony_ci enum radv_cmd_flush_bits pre_flush = 0; 2364bf215546Sopenharmony_ci enum radv_cmd_flush_bits post_flush = 0; 2365bf215546Sopenharmony_ci 2366bf215546Sopenharmony_ci if (!cmd_buffer->state.subpass) 2367bf215546Sopenharmony_ci return; 2368bf215546Sopenharmony_ci 2369bf215546Sopenharmony_ci radv_meta_save(&saved_state, cmd_buffer, 2370bf215546Sopenharmony_ci RADV_META_SAVE_GRAPHICS_PIPELINE | RADV_META_SAVE_CONSTANTS); 2371bf215546Sopenharmony_ci 2372bf215546Sopenharmony_ci /* FINISHME: We can do better than this dumb loop. It thrashes too much 2373bf215546Sopenharmony_ci * state. 2374bf215546Sopenharmony_ci */ 2375bf215546Sopenharmony_ci for (uint32_t a = 0; a < attachmentCount; ++a) { 2376bf215546Sopenharmony_ci for (uint32_t r = 0; r < rectCount; ++r) { 2377bf215546Sopenharmony_ci emit_clear(cmd_buffer, &pAttachments[a], &pRects[r], &pre_flush, &post_flush, 2378bf215546Sopenharmony_ci cmd_buffer->state.subpass->view_mask, false); 2379bf215546Sopenharmony_ci } 2380bf215546Sopenharmony_ci } 2381bf215546Sopenharmony_ci 2382bf215546Sopenharmony_ci radv_meta_restore(&saved_state, cmd_buffer); 2383bf215546Sopenharmony_ci cmd_buffer->state.flush_bits |= post_flush; 2384bf215546Sopenharmony_ci} 2385