1bf215546Sopenharmony_ci/* 2bf215546Sopenharmony_ci * Copyright © 2016 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 <assert.h> 25bf215546Sopenharmony_ci#include <stdbool.h> 26bf215546Sopenharmony_ci 27bf215546Sopenharmony_ci#include "radv_meta.h" 28bf215546Sopenharmony_ci#include "radv_private.h" 29bf215546Sopenharmony_ci#include "sid.h" 30bf215546Sopenharmony_ci 31bf215546Sopenharmony_cienum radv_color_op { 32bf215546Sopenharmony_ci FAST_CLEAR_ELIMINATE, 33bf215546Sopenharmony_ci FMASK_DECOMPRESS, 34bf215546Sopenharmony_ci DCC_DECOMPRESS, 35bf215546Sopenharmony_ci}; 36bf215546Sopenharmony_ci 37bf215546Sopenharmony_cistatic nir_shader * 38bf215546Sopenharmony_cibuild_dcc_decompress_compute_shader(struct radv_device *dev) 39bf215546Sopenharmony_ci{ 40bf215546Sopenharmony_ci const struct glsl_type *img_type = glsl_image_type(GLSL_SAMPLER_DIM_2D, false, GLSL_TYPE_FLOAT); 41bf215546Sopenharmony_ci 42bf215546Sopenharmony_ci nir_builder b = radv_meta_init_shader(dev, MESA_SHADER_COMPUTE, "dcc_decompress_compute"); 43bf215546Sopenharmony_ci 44bf215546Sopenharmony_ci /* We need at least 16/16/1 to cover an entire DCC block in a single workgroup. */ 45bf215546Sopenharmony_ci b.shader->info.workgroup_size[0] = 16; 46bf215546Sopenharmony_ci b.shader->info.workgroup_size[1] = 16; 47bf215546Sopenharmony_ci nir_variable *input_img = nir_variable_create(b.shader, nir_var_image, img_type, "in_img"); 48bf215546Sopenharmony_ci input_img->data.descriptor_set = 0; 49bf215546Sopenharmony_ci input_img->data.binding = 0; 50bf215546Sopenharmony_ci 51bf215546Sopenharmony_ci nir_variable *output_img = nir_variable_create(b.shader, nir_var_image, img_type, "out_img"); 52bf215546Sopenharmony_ci output_img->data.descriptor_set = 0; 53bf215546Sopenharmony_ci output_img->data.binding = 1; 54bf215546Sopenharmony_ci 55bf215546Sopenharmony_ci nir_ssa_def *global_id = get_global_ids(&b, 2); 56bf215546Sopenharmony_ci nir_ssa_def *img_coord = nir_vec4(&b, nir_channel(&b, global_id, 0), 57bf215546Sopenharmony_ci nir_channel(&b, global_id, 1), 58bf215546Sopenharmony_ci nir_ssa_undef(&b, 1, 32), 59bf215546Sopenharmony_ci nir_ssa_undef(&b, 1, 32)); 60bf215546Sopenharmony_ci 61bf215546Sopenharmony_ci nir_ssa_def *data = nir_image_deref_load( 62bf215546Sopenharmony_ci &b, 4, 32, &nir_build_deref_var(&b, input_img)->dest.ssa, img_coord, nir_ssa_undef(&b, 1, 32), 63bf215546Sopenharmony_ci nir_imm_int(&b, 0), .image_dim = GLSL_SAMPLER_DIM_2D); 64bf215546Sopenharmony_ci 65bf215546Sopenharmony_ci /* We need a NIR_SCOPE_DEVICE memory_scope because ACO will avoid 66bf215546Sopenharmony_ci * creating a vmcnt(0) because it expects the L1 cache to keep memory 67bf215546Sopenharmony_ci * operations in-order for the same workgroup. The vmcnt(0) seems 68bf215546Sopenharmony_ci * necessary however. */ 69bf215546Sopenharmony_ci nir_scoped_barrier(&b, .execution_scope = NIR_SCOPE_WORKGROUP, .memory_scope = NIR_SCOPE_DEVICE, 70bf215546Sopenharmony_ci .memory_semantics = NIR_MEMORY_ACQ_REL, .memory_modes = nir_var_mem_ssbo); 71bf215546Sopenharmony_ci 72bf215546Sopenharmony_ci nir_image_deref_store(&b, &nir_build_deref_var(&b, output_img)->dest.ssa, img_coord, 73bf215546Sopenharmony_ci nir_ssa_undef(&b, 1, 32), data, nir_imm_int(&b, 0), 74bf215546Sopenharmony_ci .image_dim = GLSL_SAMPLER_DIM_2D); 75bf215546Sopenharmony_ci return b.shader; 76bf215546Sopenharmony_ci} 77bf215546Sopenharmony_ci 78bf215546Sopenharmony_cistatic VkResult 79bf215546Sopenharmony_cicreate_dcc_compress_compute(struct radv_device *device) 80bf215546Sopenharmony_ci{ 81bf215546Sopenharmony_ci VkResult result = VK_SUCCESS; 82bf215546Sopenharmony_ci nir_shader *cs = build_dcc_decompress_compute_shader(device); 83bf215546Sopenharmony_ci 84bf215546Sopenharmony_ci VkDescriptorSetLayoutCreateInfo ds_create_info = { 85bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, 86bf215546Sopenharmony_ci .flags = VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR, 87bf215546Sopenharmony_ci .bindingCount = 2, 88bf215546Sopenharmony_ci .pBindings = (VkDescriptorSetLayoutBinding[]){ 89bf215546Sopenharmony_ci {.binding = 0, 90bf215546Sopenharmony_ci .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 91bf215546Sopenharmony_ci .descriptorCount = 1, 92bf215546Sopenharmony_ci .stageFlags = VK_SHADER_STAGE_COMPUTE_BIT, 93bf215546Sopenharmony_ci .pImmutableSamplers = NULL}, 94bf215546Sopenharmony_ci {.binding = 1, 95bf215546Sopenharmony_ci .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 96bf215546Sopenharmony_ci .descriptorCount = 1, 97bf215546Sopenharmony_ci .stageFlags = VK_SHADER_STAGE_COMPUTE_BIT, 98bf215546Sopenharmony_ci .pImmutableSamplers = NULL}, 99bf215546Sopenharmony_ci }}; 100bf215546Sopenharmony_ci 101bf215546Sopenharmony_ci result = radv_CreateDescriptorSetLayout( 102bf215546Sopenharmony_ci radv_device_to_handle(device), &ds_create_info, &device->meta_state.alloc, 103bf215546Sopenharmony_ci &device->meta_state.fast_clear_flush.dcc_decompress_compute_ds_layout); 104bf215546Sopenharmony_ci if (result != VK_SUCCESS) 105bf215546Sopenharmony_ci goto cleanup; 106bf215546Sopenharmony_ci 107bf215546Sopenharmony_ci VkPipelineLayoutCreateInfo pl_create_info = { 108bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, 109bf215546Sopenharmony_ci .setLayoutCount = 1, 110bf215546Sopenharmony_ci .pSetLayouts = &device->meta_state.fast_clear_flush.dcc_decompress_compute_ds_layout, 111bf215546Sopenharmony_ci .pushConstantRangeCount = 0, 112bf215546Sopenharmony_ci .pPushConstantRanges = NULL, 113bf215546Sopenharmony_ci }; 114bf215546Sopenharmony_ci 115bf215546Sopenharmony_ci result = radv_CreatePipelineLayout( 116bf215546Sopenharmony_ci radv_device_to_handle(device), &pl_create_info, &device->meta_state.alloc, 117bf215546Sopenharmony_ci &device->meta_state.fast_clear_flush.dcc_decompress_compute_p_layout); 118bf215546Sopenharmony_ci if (result != VK_SUCCESS) 119bf215546Sopenharmony_ci goto cleanup; 120bf215546Sopenharmony_ci 121bf215546Sopenharmony_ci /* compute shader */ 122bf215546Sopenharmony_ci 123bf215546Sopenharmony_ci VkPipelineShaderStageCreateInfo pipeline_shader_stage = { 124bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, 125bf215546Sopenharmony_ci .stage = VK_SHADER_STAGE_COMPUTE_BIT, 126bf215546Sopenharmony_ci .module = vk_shader_module_handle_from_nir(cs), 127bf215546Sopenharmony_ci .pName = "main", 128bf215546Sopenharmony_ci .pSpecializationInfo = NULL, 129bf215546Sopenharmony_ci }; 130bf215546Sopenharmony_ci 131bf215546Sopenharmony_ci VkComputePipelineCreateInfo vk_pipeline_info = { 132bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, 133bf215546Sopenharmony_ci .stage = pipeline_shader_stage, 134bf215546Sopenharmony_ci .flags = 0, 135bf215546Sopenharmony_ci .layout = device->meta_state.fast_clear_flush.dcc_decompress_compute_p_layout, 136bf215546Sopenharmony_ci }; 137bf215546Sopenharmony_ci 138bf215546Sopenharmony_ci result = radv_CreateComputePipelines( 139bf215546Sopenharmony_ci radv_device_to_handle(device), radv_pipeline_cache_to_handle(&device->meta_state.cache), 1, 140bf215546Sopenharmony_ci &vk_pipeline_info, NULL, 141bf215546Sopenharmony_ci &device->meta_state.fast_clear_flush.dcc_decompress_compute_pipeline); 142bf215546Sopenharmony_ci if (result != VK_SUCCESS) 143bf215546Sopenharmony_ci goto cleanup; 144bf215546Sopenharmony_ci 145bf215546Sopenharmony_cicleanup: 146bf215546Sopenharmony_ci ralloc_free(cs); 147bf215546Sopenharmony_ci return result; 148bf215546Sopenharmony_ci} 149bf215546Sopenharmony_ci 150bf215546Sopenharmony_cistatic VkResult 151bf215546Sopenharmony_cicreate_pipeline_layout(struct radv_device *device, VkPipelineLayout *layout) 152bf215546Sopenharmony_ci{ 153bf215546Sopenharmony_ci VkPipelineLayoutCreateInfo pl_create_info = { 154bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, 155bf215546Sopenharmony_ci .setLayoutCount = 0, 156bf215546Sopenharmony_ci .pSetLayouts = NULL, 157bf215546Sopenharmony_ci .pushConstantRangeCount = 0, 158bf215546Sopenharmony_ci .pPushConstantRanges = NULL, 159bf215546Sopenharmony_ci }; 160bf215546Sopenharmony_ci 161bf215546Sopenharmony_ci return radv_CreatePipelineLayout(radv_device_to_handle(device), &pl_create_info, 162bf215546Sopenharmony_ci &device->meta_state.alloc, layout); 163bf215546Sopenharmony_ci} 164bf215546Sopenharmony_ci 165bf215546Sopenharmony_cistatic VkResult 166bf215546Sopenharmony_cicreate_pipeline(struct radv_device *device, VkShaderModule vs_module_h, VkPipelineLayout layout) 167bf215546Sopenharmony_ci{ 168bf215546Sopenharmony_ci VkResult result; 169bf215546Sopenharmony_ci VkDevice device_h = radv_device_to_handle(device); 170bf215546Sopenharmony_ci 171bf215546Sopenharmony_ci nir_shader *fs_module = radv_meta_build_nir_fs_noop(device); 172bf215546Sopenharmony_ci 173bf215546Sopenharmony_ci if (!fs_module) { 174bf215546Sopenharmony_ci /* XXX: Need more accurate error */ 175bf215546Sopenharmony_ci result = VK_ERROR_OUT_OF_HOST_MEMORY; 176bf215546Sopenharmony_ci goto cleanup; 177bf215546Sopenharmony_ci } 178bf215546Sopenharmony_ci 179bf215546Sopenharmony_ci const VkPipelineShaderStageCreateInfo stages[2] = { 180bf215546Sopenharmony_ci { 181bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, 182bf215546Sopenharmony_ci .stage = VK_SHADER_STAGE_VERTEX_BIT, 183bf215546Sopenharmony_ci .module = vs_module_h, 184bf215546Sopenharmony_ci .pName = "main", 185bf215546Sopenharmony_ci }, 186bf215546Sopenharmony_ci { 187bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, 188bf215546Sopenharmony_ci .stage = VK_SHADER_STAGE_FRAGMENT_BIT, 189bf215546Sopenharmony_ci .module = vk_shader_module_handle_from_nir(fs_module), 190bf215546Sopenharmony_ci .pName = "main", 191bf215546Sopenharmony_ci }, 192bf215546Sopenharmony_ci }; 193bf215546Sopenharmony_ci 194bf215546Sopenharmony_ci const VkPipelineVertexInputStateCreateInfo vi_state = { 195bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, 196bf215546Sopenharmony_ci .vertexBindingDescriptionCount = 0, 197bf215546Sopenharmony_ci .vertexAttributeDescriptionCount = 0, 198bf215546Sopenharmony_ci }; 199bf215546Sopenharmony_ci 200bf215546Sopenharmony_ci const VkPipelineInputAssemblyStateCreateInfo ia_state = { 201bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, 202bf215546Sopenharmony_ci .topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, 203bf215546Sopenharmony_ci .primitiveRestartEnable = false, 204bf215546Sopenharmony_ci }; 205bf215546Sopenharmony_ci 206bf215546Sopenharmony_ci const VkPipelineColorBlendStateCreateInfo blend_state = { 207bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, 208bf215546Sopenharmony_ci .logicOpEnable = false, 209bf215546Sopenharmony_ci .attachmentCount = 1, 210bf215546Sopenharmony_ci .pAttachments = (VkPipelineColorBlendAttachmentState[]){ 211bf215546Sopenharmony_ci { 212bf215546Sopenharmony_ci .colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | 213bf215546Sopenharmony_ci VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT, 214bf215546Sopenharmony_ci }, 215bf215546Sopenharmony_ci }}; 216bf215546Sopenharmony_ci const VkPipelineRasterizationStateCreateInfo rs_state = { 217bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, 218bf215546Sopenharmony_ci .depthClampEnable = false, 219bf215546Sopenharmony_ci .rasterizerDiscardEnable = false, 220bf215546Sopenharmony_ci .polygonMode = VK_POLYGON_MODE_FILL, 221bf215546Sopenharmony_ci .cullMode = VK_CULL_MODE_NONE, 222bf215546Sopenharmony_ci .frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE, 223bf215546Sopenharmony_ci }; 224bf215546Sopenharmony_ci 225bf215546Sopenharmony_ci const VkFormat color_format = VK_FORMAT_R8_UNORM; 226bf215546Sopenharmony_ci const VkPipelineRenderingCreateInfo rendering_create_info = { 227bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO, 228bf215546Sopenharmony_ci .colorAttachmentCount = 1, 229bf215546Sopenharmony_ci .pColorAttachmentFormats = &color_format, 230bf215546Sopenharmony_ci }; 231bf215546Sopenharmony_ci 232bf215546Sopenharmony_ci result = radv_graphics_pipeline_create( 233bf215546Sopenharmony_ci device_h, radv_pipeline_cache_to_handle(&device->meta_state.cache), 234bf215546Sopenharmony_ci &(VkGraphicsPipelineCreateInfo){ 235bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, 236bf215546Sopenharmony_ci .pNext = &rendering_create_info, 237bf215546Sopenharmony_ci .stageCount = 2, 238bf215546Sopenharmony_ci .pStages = stages, 239bf215546Sopenharmony_ci 240bf215546Sopenharmony_ci .pVertexInputState = &vi_state, 241bf215546Sopenharmony_ci .pInputAssemblyState = &ia_state, 242bf215546Sopenharmony_ci 243bf215546Sopenharmony_ci .pViewportState = 244bf215546Sopenharmony_ci &(VkPipelineViewportStateCreateInfo){ 245bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, 246bf215546Sopenharmony_ci .viewportCount = 1, 247bf215546Sopenharmony_ci .scissorCount = 1, 248bf215546Sopenharmony_ci }, 249bf215546Sopenharmony_ci .pRasterizationState = &rs_state, 250bf215546Sopenharmony_ci .pMultisampleState = 251bf215546Sopenharmony_ci &(VkPipelineMultisampleStateCreateInfo){ 252bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, 253bf215546Sopenharmony_ci .rasterizationSamples = 1, 254bf215546Sopenharmony_ci .sampleShadingEnable = false, 255bf215546Sopenharmony_ci .pSampleMask = NULL, 256bf215546Sopenharmony_ci .alphaToCoverageEnable = false, 257bf215546Sopenharmony_ci .alphaToOneEnable = false, 258bf215546Sopenharmony_ci }, 259bf215546Sopenharmony_ci .pColorBlendState = &blend_state, 260bf215546Sopenharmony_ci .pDynamicState = 261bf215546Sopenharmony_ci &(VkPipelineDynamicStateCreateInfo){ 262bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, 263bf215546Sopenharmony_ci .dynamicStateCount = 2, 264bf215546Sopenharmony_ci .pDynamicStates = 265bf215546Sopenharmony_ci (VkDynamicState[]){ 266bf215546Sopenharmony_ci VK_DYNAMIC_STATE_VIEWPORT, 267bf215546Sopenharmony_ci VK_DYNAMIC_STATE_SCISSOR, 268bf215546Sopenharmony_ci }, 269bf215546Sopenharmony_ci }, 270bf215546Sopenharmony_ci .layout = layout, 271bf215546Sopenharmony_ci .renderPass = VK_NULL_HANDLE, 272bf215546Sopenharmony_ci .subpass = 0, 273bf215546Sopenharmony_ci }, 274bf215546Sopenharmony_ci &(struct radv_graphics_pipeline_create_info){ 275bf215546Sopenharmony_ci .use_rectlist = true, 276bf215546Sopenharmony_ci .custom_blend_mode = V_028808_CB_ELIMINATE_FAST_CLEAR, 277bf215546Sopenharmony_ci }, 278bf215546Sopenharmony_ci &device->meta_state.alloc, &device->meta_state.fast_clear_flush.cmask_eliminate_pipeline); 279bf215546Sopenharmony_ci if (result != VK_SUCCESS) 280bf215546Sopenharmony_ci goto cleanup; 281bf215546Sopenharmony_ci 282bf215546Sopenharmony_ci result = radv_graphics_pipeline_create( 283bf215546Sopenharmony_ci device_h, radv_pipeline_cache_to_handle(&device->meta_state.cache), 284bf215546Sopenharmony_ci &(VkGraphicsPipelineCreateInfo){ 285bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, 286bf215546Sopenharmony_ci .pNext = &rendering_create_info, 287bf215546Sopenharmony_ci .stageCount = 2, 288bf215546Sopenharmony_ci .pStages = stages, 289bf215546Sopenharmony_ci 290bf215546Sopenharmony_ci .pVertexInputState = &vi_state, 291bf215546Sopenharmony_ci .pInputAssemblyState = &ia_state, 292bf215546Sopenharmony_ci 293bf215546Sopenharmony_ci .pViewportState = 294bf215546Sopenharmony_ci &(VkPipelineViewportStateCreateInfo){ 295bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, 296bf215546Sopenharmony_ci .viewportCount = 1, 297bf215546Sopenharmony_ci .scissorCount = 1, 298bf215546Sopenharmony_ci }, 299bf215546Sopenharmony_ci .pRasterizationState = &rs_state, 300bf215546Sopenharmony_ci .pMultisampleState = 301bf215546Sopenharmony_ci &(VkPipelineMultisampleStateCreateInfo){ 302bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, 303bf215546Sopenharmony_ci .rasterizationSamples = 1, 304bf215546Sopenharmony_ci .sampleShadingEnable = false, 305bf215546Sopenharmony_ci .pSampleMask = NULL, 306bf215546Sopenharmony_ci .alphaToCoverageEnable = false, 307bf215546Sopenharmony_ci .alphaToOneEnable = false, 308bf215546Sopenharmony_ci }, 309bf215546Sopenharmony_ci .pColorBlendState = &blend_state, 310bf215546Sopenharmony_ci .pDynamicState = 311bf215546Sopenharmony_ci &(VkPipelineDynamicStateCreateInfo){ 312bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, 313bf215546Sopenharmony_ci .dynamicStateCount = 2, 314bf215546Sopenharmony_ci .pDynamicStates = 315bf215546Sopenharmony_ci (VkDynamicState[]){ 316bf215546Sopenharmony_ci VK_DYNAMIC_STATE_VIEWPORT, 317bf215546Sopenharmony_ci VK_DYNAMIC_STATE_SCISSOR, 318bf215546Sopenharmony_ci }, 319bf215546Sopenharmony_ci }, 320bf215546Sopenharmony_ci .layout = layout, 321bf215546Sopenharmony_ci .renderPass = VK_NULL_HANDLE, 322bf215546Sopenharmony_ci .subpass = 0, 323bf215546Sopenharmony_ci }, 324bf215546Sopenharmony_ci &(struct radv_graphics_pipeline_create_info){ 325bf215546Sopenharmony_ci .use_rectlist = true, 326bf215546Sopenharmony_ci .custom_blend_mode = V_028808_CB_FMASK_DECOMPRESS, 327bf215546Sopenharmony_ci }, 328bf215546Sopenharmony_ci &device->meta_state.alloc, &device->meta_state.fast_clear_flush.fmask_decompress_pipeline); 329bf215546Sopenharmony_ci if (result != VK_SUCCESS) 330bf215546Sopenharmony_ci goto cleanup; 331bf215546Sopenharmony_ci 332bf215546Sopenharmony_ci result = radv_graphics_pipeline_create( 333bf215546Sopenharmony_ci device_h, radv_pipeline_cache_to_handle(&device->meta_state.cache), 334bf215546Sopenharmony_ci &(VkGraphicsPipelineCreateInfo){ 335bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, 336bf215546Sopenharmony_ci .pNext = &rendering_create_info, 337bf215546Sopenharmony_ci .stageCount = 2, 338bf215546Sopenharmony_ci .pStages = stages, 339bf215546Sopenharmony_ci 340bf215546Sopenharmony_ci .pVertexInputState = &vi_state, 341bf215546Sopenharmony_ci .pInputAssemblyState = &ia_state, 342bf215546Sopenharmony_ci 343bf215546Sopenharmony_ci .pViewportState = 344bf215546Sopenharmony_ci &(VkPipelineViewportStateCreateInfo){ 345bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, 346bf215546Sopenharmony_ci .viewportCount = 1, 347bf215546Sopenharmony_ci .scissorCount = 1, 348bf215546Sopenharmony_ci }, 349bf215546Sopenharmony_ci .pRasterizationState = &rs_state, 350bf215546Sopenharmony_ci .pMultisampleState = 351bf215546Sopenharmony_ci &(VkPipelineMultisampleStateCreateInfo){ 352bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, 353bf215546Sopenharmony_ci .rasterizationSamples = 1, 354bf215546Sopenharmony_ci .sampleShadingEnable = false, 355bf215546Sopenharmony_ci .pSampleMask = NULL, 356bf215546Sopenharmony_ci .alphaToCoverageEnable = false, 357bf215546Sopenharmony_ci .alphaToOneEnable = false, 358bf215546Sopenharmony_ci }, 359bf215546Sopenharmony_ci .pColorBlendState = &blend_state, 360bf215546Sopenharmony_ci .pDynamicState = 361bf215546Sopenharmony_ci &(VkPipelineDynamicStateCreateInfo){ 362bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, 363bf215546Sopenharmony_ci .dynamicStateCount = 2, 364bf215546Sopenharmony_ci .pDynamicStates = 365bf215546Sopenharmony_ci (VkDynamicState[]){ 366bf215546Sopenharmony_ci VK_DYNAMIC_STATE_VIEWPORT, 367bf215546Sopenharmony_ci VK_DYNAMIC_STATE_SCISSOR, 368bf215546Sopenharmony_ci }, 369bf215546Sopenharmony_ci }, 370bf215546Sopenharmony_ci .layout = layout, 371bf215546Sopenharmony_ci .renderPass = VK_NULL_HANDLE, 372bf215546Sopenharmony_ci .subpass = 0, 373bf215546Sopenharmony_ci }, 374bf215546Sopenharmony_ci &(struct radv_graphics_pipeline_create_info){ 375bf215546Sopenharmony_ci .use_rectlist = true, 376bf215546Sopenharmony_ci .custom_blend_mode = device->physical_device->rad_info.gfx_level >= GFX11 377bf215546Sopenharmony_ci ? V_028808_CB_DCC_DECOMPRESS_GFX11 378bf215546Sopenharmony_ci : V_028808_CB_DCC_DECOMPRESS_GFX8, 379bf215546Sopenharmony_ci }, 380bf215546Sopenharmony_ci &device->meta_state.alloc, &device->meta_state.fast_clear_flush.dcc_decompress_pipeline); 381bf215546Sopenharmony_ci if (result != VK_SUCCESS) 382bf215546Sopenharmony_ci goto cleanup; 383bf215546Sopenharmony_ci 384bf215546Sopenharmony_cicleanup: 385bf215546Sopenharmony_ci ralloc_free(fs_module); 386bf215546Sopenharmony_ci return result; 387bf215546Sopenharmony_ci} 388bf215546Sopenharmony_ci 389bf215546Sopenharmony_civoid 390bf215546Sopenharmony_ciradv_device_finish_meta_fast_clear_flush_state(struct radv_device *device) 391bf215546Sopenharmony_ci{ 392bf215546Sopenharmony_ci struct radv_meta_state *state = &device->meta_state; 393bf215546Sopenharmony_ci 394bf215546Sopenharmony_ci radv_DestroyPipeline(radv_device_to_handle(device), 395bf215546Sopenharmony_ci state->fast_clear_flush.dcc_decompress_pipeline, &state->alloc); 396bf215546Sopenharmony_ci radv_DestroyPipeline(radv_device_to_handle(device), 397bf215546Sopenharmony_ci state->fast_clear_flush.fmask_decompress_pipeline, &state->alloc); 398bf215546Sopenharmony_ci radv_DestroyPipeline(radv_device_to_handle(device), 399bf215546Sopenharmony_ci state->fast_clear_flush.cmask_eliminate_pipeline, &state->alloc); 400bf215546Sopenharmony_ci radv_DestroyPipelineLayout(radv_device_to_handle(device), state->fast_clear_flush.p_layout, 401bf215546Sopenharmony_ci &state->alloc); 402bf215546Sopenharmony_ci 403bf215546Sopenharmony_ci radv_DestroyPipeline(radv_device_to_handle(device), 404bf215546Sopenharmony_ci state->fast_clear_flush.dcc_decompress_compute_pipeline, &state->alloc); 405bf215546Sopenharmony_ci radv_DestroyPipelineLayout(radv_device_to_handle(device), 406bf215546Sopenharmony_ci state->fast_clear_flush.dcc_decompress_compute_p_layout, 407bf215546Sopenharmony_ci &state->alloc); 408bf215546Sopenharmony_ci device->vk.dispatch_table.DestroyDescriptorSetLayout( 409bf215546Sopenharmony_ci radv_device_to_handle(device), state->fast_clear_flush.dcc_decompress_compute_ds_layout, 410bf215546Sopenharmony_ci &state->alloc); 411bf215546Sopenharmony_ci} 412bf215546Sopenharmony_ci 413bf215546Sopenharmony_cistatic VkResult 414bf215546Sopenharmony_ciradv_device_init_meta_fast_clear_flush_state_internal(struct radv_device *device) 415bf215546Sopenharmony_ci{ 416bf215546Sopenharmony_ci VkResult res = VK_SUCCESS; 417bf215546Sopenharmony_ci 418bf215546Sopenharmony_ci mtx_lock(&device->meta_state.mtx); 419bf215546Sopenharmony_ci if (device->meta_state.fast_clear_flush.cmask_eliminate_pipeline) { 420bf215546Sopenharmony_ci mtx_unlock(&device->meta_state.mtx); 421bf215546Sopenharmony_ci return VK_SUCCESS; 422bf215546Sopenharmony_ci } 423bf215546Sopenharmony_ci 424bf215546Sopenharmony_ci nir_shader *vs_module = radv_meta_build_nir_vs_generate_vertices(device); 425bf215546Sopenharmony_ci if (!vs_module) { 426bf215546Sopenharmony_ci /* XXX: Need more accurate error */ 427bf215546Sopenharmony_ci res = VK_ERROR_OUT_OF_HOST_MEMORY; 428bf215546Sopenharmony_ci goto cleanup; 429bf215546Sopenharmony_ci } 430bf215546Sopenharmony_ci 431bf215546Sopenharmony_ci res = create_pipeline_layout(device, &device->meta_state.fast_clear_flush.p_layout); 432bf215546Sopenharmony_ci if (res != VK_SUCCESS) 433bf215546Sopenharmony_ci goto cleanup; 434bf215546Sopenharmony_ci 435bf215546Sopenharmony_ci VkShaderModule vs_module_h = vk_shader_module_handle_from_nir(vs_module); 436bf215546Sopenharmony_ci res = create_pipeline(device, vs_module_h, device->meta_state.fast_clear_flush.p_layout); 437bf215546Sopenharmony_ci if (res != VK_SUCCESS) 438bf215546Sopenharmony_ci goto cleanup; 439bf215546Sopenharmony_ci 440bf215546Sopenharmony_ci res = create_dcc_compress_compute(device); 441bf215546Sopenharmony_ci if (res != VK_SUCCESS) 442bf215546Sopenharmony_ci goto cleanup; 443bf215546Sopenharmony_ci 444bf215546Sopenharmony_cicleanup: 445bf215546Sopenharmony_ci ralloc_free(vs_module); 446bf215546Sopenharmony_ci mtx_unlock(&device->meta_state.mtx); 447bf215546Sopenharmony_ci 448bf215546Sopenharmony_ci return res; 449bf215546Sopenharmony_ci} 450bf215546Sopenharmony_ci 451bf215546Sopenharmony_ciVkResult 452bf215546Sopenharmony_ciradv_device_init_meta_fast_clear_flush_state(struct radv_device *device, bool on_demand) 453bf215546Sopenharmony_ci{ 454bf215546Sopenharmony_ci if (on_demand) 455bf215546Sopenharmony_ci return VK_SUCCESS; 456bf215546Sopenharmony_ci 457bf215546Sopenharmony_ci return radv_device_init_meta_fast_clear_flush_state_internal(device); 458bf215546Sopenharmony_ci} 459bf215546Sopenharmony_ci 460bf215546Sopenharmony_cistatic void 461bf215546Sopenharmony_ciradv_emit_set_predication_state_from_image(struct radv_cmd_buffer *cmd_buffer, 462bf215546Sopenharmony_ci struct radv_image *image, uint64_t pred_offset, 463bf215546Sopenharmony_ci bool value) 464bf215546Sopenharmony_ci{ 465bf215546Sopenharmony_ci uint64_t va = 0; 466bf215546Sopenharmony_ci 467bf215546Sopenharmony_ci if (value) { 468bf215546Sopenharmony_ci va = radv_buffer_get_va(image->bindings[0].bo) + image->bindings[0].offset; 469bf215546Sopenharmony_ci va += pred_offset; 470bf215546Sopenharmony_ci } 471bf215546Sopenharmony_ci 472bf215546Sopenharmony_ci si_emit_set_predication_state(cmd_buffer, true, PREDICATION_OP_BOOL64, va); 473bf215546Sopenharmony_ci} 474bf215546Sopenharmony_ci 475bf215546Sopenharmony_cistatic void 476bf215546Sopenharmony_ciradv_process_color_image_layer(struct radv_cmd_buffer *cmd_buffer, struct radv_image *image, 477bf215546Sopenharmony_ci const VkImageSubresourceRange *range, int level, int layer, 478bf215546Sopenharmony_ci bool flush_cb) 479bf215546Sopenharmony_ci{ 480bf215546Sopenharmony_ci struct radv_device *device = cmd_buffer->device; 481bf215546Sopenharmony_ci struct radv_image_view iview; 482bf215546Sopenharmony_ci uint32_t width, height; 483bf215546Sopenharmony_ci 484bf215546Sopenharmony_ci width = radv_minify(image->info.width, range->baseMipLevel + level); 485bf215546Sopenharmony_ci height = radv_minify(image->info.height, range->baseMipLevel + level); 486bf215546Sopenharmony_ci 487bf215546Sopenharmony_ci radv_image_view_init(&iview, device, 488bf215546Sopenharmony_ci &(VkImageViewCreateInfo){ 489bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, 490bf215546Sopenharmony_ci .image = radv_image_to_handle(image), 491bf215546Sopenharmony_ci .viewType = radv_meta_get_view_type(image), 492bf215546Sopenharmony_ci .format = image->vk.format, 493bf215546Sopenharmony_ci .subresourceRange = 494bf215546Sopenharmony_ci { 495bf215546Sopenharmony_ci .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, 496bf215546Sopenharmony_ci .baseMipLevel = range->baseMipLevel + level, 497bf215546Sopenharmony_ci .levelCount = 1, 498bf215546Sopenharmony_ci .baseArrayLayer = range->baseArrayLayer + layer, 499bf215546Sopenharmony_ci .layerCount = 1, 500bf215546Sopenharmony_ci }, 501bf215546Sopenharmony_ci }, 502bf215546Sopenharmony_ci 0, NULL); 503bf215546Sopenharmony_ci 504bf215546Sopenharmony_ci const VkRenderingAttachmentInfo color_att = { 505bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO, 506bf215546Sopenharmony_ci .imageView = radv_image_view_to_handle(&iview), 507bf215546Sopenharmony_ci .imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 508bf215546Sopenharmony_ci .loadOp = VK_ATTACHMENT_LOAD_OP_LOAD, 509bf215546Sopenharmony_ci .storeOp = VK_ATTACHMENT_STORE_OP_STORE, 510bf215546Sopenharmony_ci }; 511bf215546Sopenharmony_ci 512bf215546Sopenharmony_ci const VkRenderingInfo rendering_info = { 513bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_RENDERING_INFO, 514bf215546Sopenharmony_ci .renderArea = { 515bf215546Sopenharmony_ci .offset = { 0, 0 }, 516bf215546Sopenharmony_ci .extent = { width, height } 517bf215546Sopenharmony_ci }, 518bf215546Sopenharmony_ci .layerCount = 1, 519bf215546Sopenharmony_ci .colorAttachmentCount = 1, 520bf215546Sopenharmony_ci .pColorAttachments = &color_att, 521bf215546Sopenharmony_ci }; 522bf215546Sopenharmony_ci 523bf215546Sopenharmony_ci radv_CmdBeginRendering(radv_cmd_buffer_to_handle(cmd_buffer), &rendering_info); 524bf215546Sopenharmony_ci 525bf215546Sopenharmony_ci if (flush_cb) 526bf215546Sopenharmony_ci cmd_buffer->state.flush_bits |= 527bf215546Sopenharmony_ci radv_dst_access_flush(cmd_buffer, VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT, image); 528bf215546Sopenharmony_ci 529bf215546Sopenharmony_ci radv_CmdDraw(radv_cmd_buffer_to_handle(cmd_buffer), 3, 1, 0, 0); 530bf215546Sopenharmony_ci 531bf215546Sopenharmony_ci if (flush_cb) 532bf215546Sopenharmony_ci cmd_buffer->state.flush_bits |= 533bf215546Sopenharmony_ci radv_src_access_flush(cmd_buffer, VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT, image); 534bf215546Sopenharmony_ci 535bf215546Sopenharmony_ci radv_CmdEndRendering(radv_cmd_buffer_to_handle(cmd_buffer)); 536bf215546Sopenharmony_ci 537bf215546Sopenharmony_ci radv_image_view_finish(&iview); 538bf215546Sopenharmony_ci} 539bf215546Sopenharmony_ci 540bf215546Sopenharmony_cistatic void 541bf215546Sopenharmony_ciradv_process_color_image(struct radv_cmd_buffer *cmd_buffer, struct radv_image *image, 542bf215546Sopenharmony_ci const VkImageSubresourceRange *subresourceRange, enum radv_color_op op) 543bf215546Sopenharmony_ci{ 544bf215546Sopenharmony_ci struct radv_device *device = cmd_buffer->device; 545bf215546Sopenharmony_ci struct radv_meta_saved_state saved_state; 546bf215546Sopenharmony_ci bool old_predicating = false; 547bf215546Sopenharmony_ci bool flush_cb = false; 548bf215546Sopenharmony_ci uint64_t pred_offset; 549bf215546Sopenharmony_ci VkPipeline *pipeline; 550bf215546Sopenharmony_ci 551bf215546Sopenharmony_ci switch (op) { 552bf215546Sopenharmony_ci case FAST_CLEAR_ELIMINATE: 553bf215546Sopenharmony_ci pipeline = &device->meta_state.fast_clear_flush.cmask_eliminate_pipeline; 554bf215546Sopenharmony_ci pred_offset = image->fce_pred_offset; 555bf215546Sopenharmony_ci break; 556bf215546Sopenharmony_ci case FMASK_DECOMPRESS: 557bf215546Sopenharmony_ci pipeline = &device->meta_state.fast_clear_flush.fmask_decompress_pipeline; 558bf215546Sopenharmony_ci pred_offset = 0; /* FMASK_DECOMPRESS is never predicated. */ 559bf215546Sopenharmony_ci 560bf215546Sopenharmony_ci /* Flushing CB is required before and after FMASK_DECOMPRESS. */ 561bf215546Sopenharmony_ci flush_cb = true; 562bf215546Sopenharmony_ci break; 563bf215546Sopenharmony_ci case DCC_DECOMPRESS: 564bf215546Sopenharmony_ci pipeline = &device->meta_state.fast_clear_flush.dcc_decompress_pipeline; 565bf215546Sopenharmony_ci pred_offset = image->dcc_pred_offset; 566bf215546Sopenharmony_ci 567bf215546Sopenharmony_ci /* Flushing CB is required before and after DCC_DECOMPRESS. */ 568bf215546Sopenharmony_ci flush_cb = true; 569bf215546Sopenharmony_ci break; 570bf215546Sopenharmony_ci default: 571bf215546Sopenharmony_ci unreachable("Invalid color op"); 572bf215546Sopenharmony_ci } 573bf215546Sopenharmony_ci 574bf215546Sopenharmony_ci if (radv_dcc_enabled(image, subresourceRange->baseMipLevel) && 575bf215546Sopenharmony_ci (image->info.array_size != radv_get_layerCount(image, subresourceRange) || 576bf215546Sopenharmony_ci subresourceRange->baseArrayLayer != 0)) { 577bf215546Sopenharmony_ci /* Only use predication if the image has DCC with mipmaps or 578bf215546Sopenharmony_ci * if the range of layers covers the whole image because the 579bf215546Sopenharmony_ci * predication is based on mip level. 580bf215546Sopenharmony_ci */ 581bf215546Sopenharmony_ci pred_offset = 0; 582bf215546Sopenharmony_ci } 583bf215546Sopenharmony_ci 584bf215546Sopenharmony_ci if (!*pipeline) { 585bf215546Sopenharmony_ci VkResult ret; 586bf215546Sopenharmony_ci 587bf215546Sopenharmony_ci ret = radv_device_init_meta_fast_clear_flush_state_internal(device); 588bf215546Sopenharmony_ci if (ret != VK_SUCCESS) { 589bf215546Sopenharmony_ci cmd_buffer->record_result = ret; 590bf215546Sopenharmony_ci return; 591bf215546Sopenharmony_ci } 592bf215546Sopenharmony_ci } 593bf215546Sopenharmony_ci 594bf215546Sopenharmony_ci radv_meta_save(&saved_state, cmd_buffer, RADV_META_SAVE_GRAPHICS_PIPELINE | RADV_META_SAVE_PASS); 595bf215546Sopenharmony_ci 596bf215546Sopenharmony_ci if (pred_offset) { 597bf215546Sopenharmony_ci pred_offset += 8 * subresourceRange->baseMipLevel; 598bf215546Sopenharmony_ci 599bf215546Sopenharmony_ci old_predicating = cmd_buffer->state.predicating; 600bf215546Sopenharmony_ci 601bf215546Sopenharmony_ci radv_emit_set_predication_state_from_image(cmd_buffer, image, pred_offset, true); 602bf215546Sopenharmony_ci cmd_buffer->state.predicating = true; 603bf215546Sopenharmony_ci } 604bf215546Sopenharmony_ci 605bf215546Sopenharmony_ci radv_CmdBindPipeline(radv_cmd_buffer_to_handle(cmd_buffer), VK_PIPELINE_BIND_POINT_GRAPHICS, 606bf215546Sopenharmony_ci *pipeline); 607bf215546Sopenharmony_ci 608bf215546Sopenharmony_ci for (uint32_t l = 0; l < radv_get_levelCount(image, subresourceRange); ++l) { 609bf215546Sopenharmony_ci uint32_t width, height; 610bf215546Sopenharmony_ci 611bf215546Sopenharmony_ci /* Do not decompress levels without DCC. */ 612bf215546Sopenharmony_ci if (op == DCC_DECOMPRESS && !radv_dcc_enabled(image, subresourceRange->baseMipLevel + l)) 613bf215546Sopenharmony_ci continue; 614bf215546Sopenharmony_ci 615bf215546Sopenharmony_ci width = radv_minify(image->info.width, subresourceRange->baseMipLevel + l); 616bf215546Sopenharmony_ci height = radv_minify(image->info.height, subresourceRange->baseMipLevel + l); 617bf215546Sopenharmony_ci 618bf215546Sopenharmony_ci radv_CmdSetViewport(radv_cmd_buffer_to_handle(cmd_buffer), 0, 1, 619bf215546Sopenharmony_ci &(VkViewport){.x = 0, 620bf215546Sopenharmony_ci .y = 0, 621bf215546Sopenharmony_ci .width = width, 622bf215546Sopenharmony_ci .height = height, 623bf215546Sopenharmony_ci .minDepth = 0.0f, 624bf215546Sopenharmony_ci .maxDepth = 1.0f}); 625bf215546Sopenharmony_ci 626bf215546Sopenharmony_ci radv_CmdSetScissor(radv_cmd_buffer_to_handle(cmd_buffer), 0, 1, 627bf215546Sopenharmony_ci &(VkRect2D){ 628bf215546Sopenharmony_ci .offset = {0, 0}, 629bf215546Sopenharmony_ci .extent = {width, height}, 630bf215546Sopenharmony_ci }); 631bf215546Sopenharmony_ci 632bf215546Sopenharmony_ci for (uint32_t s = 0; s < radv_get_layerCount(image, subresourceRange); s++) { 633bf215546Sopenharmony_ci radv_process_color_image_layer(cmd_buffer, image, subresourceRange, l, s, flush_cb); 634bf215546Sopenharmony_ci } 635bf215546Sopenharmony_ci } 636bf215546Sopenharmony_ci 637bf215546Sopenharmony_ci cmd_buffer->state.flush_bits |= 638bf215546Sopenharmony_ci RADV_CMD_FLAG_FLUSH_AND_INV_CB | RADV_CMD_FLAG_FLUSH_AND_INV_CB_META; 639bf215546Sopenharmony_ci 640bf215546Sopenharmony_ci if (pred_offset) { 641bf215546Sopenharmony_ci pred_offset += 8 * subresourceRange->baseMipLevel; 642bf215546Sopenharmony_ci 643bf215546Sopenharmony_ci cmd_buffer->state.predicating = old_predicating; 644bf215546Sopenharmony_ci 645bf215546Sopenharmony_ci radv_emit_set_predication_state_from_image(cmd_buffer, image, pred_offset, false); 646bf215546Sopenharmony_ci 647bf215546Sopenharmony_ci if (cmd_buffer->state.predication_type != -1) { 648bf215546Sopenharmony_ci /* Restore previous conditional rendering user state. */ 649bf215546Sopenharmony_ci si_emit_set_predication_state(cmd_buffer, cmd_buffer->state.predication_type, 650bf215546Sopenharmony_ci cmd_buffer->state.predication_op, 651bf215546Sopenharmony_ci cmd_buffer->state.predication_va); 652bf215546Sopenharmony_ci } 653bf215546Sopenharmony_ci } 654bf215546Sopenharmony_ci 655bf215546Sopenharmony_ci radv_meta_restore(&saved_state, cmd_buffer); 656bf215546Sopenharmony_ci 657bf215546Sopenharmony_ci /* Clear the image's fast-clear eliminate predicate because FMASK_DECOMPRESS and DCC_DECOMPRESS 658bf215546Sopenharmony_ci * also perform a fast-clear eliminate. 659bf215546Sopenharmony_ci */ 660bf215546Sopenharmony_ci radv_update_fce_metadata(cmd_buffer, image, subresourceRange, false); 661bf215546Sopenharmony_ci 662bf215546Sopenharmony_ci /* Mark the image as being decompressed. */ 663bf215546Sopenharmony_ci if (op == DCC_DECOMPRESS) 664bf215546Sopenharmony_ci radv_update_dcc_metadata(cmd_buffer, image, subresourceRange, false); 665bf215546Sopenharmony_ci} 666bf215546Sopenharmony_ci 667bf215546Sopenharmony_cistatic void 668bf215546Sopenharmony_ciradv_fast_clear_eliminate(struct radv_cmd_buffer *cmd_buffer, struct radv_image *image, 669bf215546Sopenharmony_ci const VkImageSubresourceRange *subresourceRange) 670bf215546Sopenharmony_ci{ 671bf215546Sopenharmony_ci struct radv_barrier_data barrier = {0}; 672bf215546Sopenharmony_ci 673bf215546Sopenharmony_ci barrier.layout_transitions.fast_clear_eliminate = 1; 674bf215546Sopenharmony_ci radv_describe_layout_transition(cmd_buffer, &barrier); 675bf215546Sopenharmony_ci 676bf215546Sopenharmony_ci radv_process_color_image(cmd_buffer, image, subresourceRange, FAST_CLEAR_ELIMINATE); 677bf215546Sopenharmony_ci} 678bf215546Sopenharmony_ci 679bf215546Sopenharmony_cistatic void 680bf215546Sopenharmony_ciradv_fmask_decompress(struct radv_cmd_buffer *cmd_buffer, struct radv_image *image, 681bf215546Sopenharmony_ci const VkImageSubresourceRange *subresourceRange) 682bf215546Sopenharmony_ci{ 683bf215546Sopenharmony_ci struct radv_barrier_data barrier = {0}; 684bf215546Sopenharmony_ci 685bf215546Sopenharmony_ci barrier.layout_transitions.fmask_decompress = 1; 686bf215546Sopenharmony_ci radv_describe_layout_transition(cmd_buffer, &barrier); 687bf215546Sopenharmony_ci 688bf215546Sopenharmony_ci radv_process_color_image(cmd_buffer, image, subresourceRange, FMASK_DECOMPRESS); 689bf215546Sopenharmony_ci} 690bf215546Sopenharmony_ci 691bf215546Sopenharmony_civoid 692bf215546Sopenharmony_ciradv_fast_clear_flush_image_inplace(struct radv_cmd_buffer *cmd_buffer, struct radv_image *image, 693bf215546Sopenharmony_ci const VkImageSubresourceRange *subresourceRange) 694bf215546Sopenharmony_ci{ 695bf215546Sopenharmony_ci if (radv_image_has_fmask(image) && !image->tc_compatible_cmask) { 696bf215546Sopenharmony_ci if (radv_image_has_dcc(image) && radv_image_has_cmask(image)) { 697bf215546Sopenharmony_ci /* MSAA images with DCC and CMASK might have been fast-cleared and might require a FCE but 698bf215546Sopenharmony_ci * FMASK_DECOMPRESS can't eliminate DCC fast clears. 699bf215546Sopenharmony_ci */ 700bf215546Sopenharmony_ci radv_fast_clear_eliminate(cmd_buffer, image, subresourceRange); 701bf215546Sopenharmony_ci } 702bf215546Sopenharmony_ci 703bf215546Sopenharmony_ci radv_fmask_decompress(cmd_buffer, image, subresourceRange); 704bf215546Sopenharmony_ci } else { 705bf215546Sopenharmony_ci /* Skip fast clear eliminate for images that support comp-to-single fast clears. */ 706bf215546Sopenharmony_ci if (image->support_comp_to_single) 707bf215546Sopenharmony_ci return; 708bf215546Sopenharmony_ci 709bf215546Sopenharmony_ci radv_fast_clear_eliminate(cmd_buffer, image, subresourceRange); 710bf215546Sopenharmony_ci } 711bf215546Sopenharmony_ci} 712bf215546Sopenharmony_ci 713bf215546Sopenharmony_cistatic void 714bf215546Sopenharmony_ciradv_decompress_dcc_compute(struct radv_cmd_buffer *cmd_buffer, struct radv_image *image, 715bf215546Sopenharmony_ci const VkImageSubresourceRange *subresourceRange) 716bf215546Sopenharmony_ci{ 717bf215546Sopenharmony_ci struct radv_meta_saved_state saved_state; 718bf215546Sopenharmony_ci struct radv_image_view load_iview = {0}; 719bf215546Sopenharmony_ci struct radv_image_view store_iview = {0}; 720bf215546Sopenharmony_ci struct radv_device *device = cmd_buffer->device; 721bf215546Sopenharmony_ci 722bf215546Sopenharmony_ci cmd_buffer->state.flush_bits |= 723bf215546Sopenharmony_ci radv_dst_access_flush(cmd_buffer, VK_ACCESS_2_SHADER_WRITE_BIT, image); 724bf215546Sopenharmony_ci 725bf215546Sopenharmony_ci if (!cmd_buffer->device->meta_state.fast_clear_flush.cmask_eliminate_pipeline) { 726bf215546Sopenharmony_ci VkResult ret = radv_device_init_meta_fast_clear_flush_state_internal(cmd_buffer->device); 727bf215546Sopenharmony_ci if (ret != VK_SUCCESS) { 728bf215546Sopenharmony_ci cmd_buffer->record_result = ret; 729bf215546Sopenharmony_ci return; 730bf215546Sopenharmony_ci } 731bf215546Sopenharmony_ci } 732bf215546Sopenharmony_ci 733bf215546Sopenharmony_ci radv_meta_save(&saved_state, cmd_buffer, 734bf215546Sopenharmony_ci RADV_META_SAVE_DESCRIPTORS | RADV_META_SAVE_COMPUTE_PIPELINE); 735bf215546Sopenharmony_ci 736bf215546Sopenharmony_ci radv_CmdBindPipeline(radv_cmd_buffer_to_handle(cmd_buffer), VK_PIPELINE_BIND_POINT_COMPUTE, 737bf215546Sopenharmony_ci device->meta_state.fast_clear_flush.dcc_decompress_compute_pipeline); 738bf215546Sopenharmony_ci 739bf215546Sopenharmony_ci for (uint32_t l = 0; l < radv_get_levelCount(image, subresourceRange); l++) { 740bf215546Sopenharmony_ci uint32_t width, height; 741bf215546Sopenharmony_ci 742bf215546Sopenharmony_ci /* Do not decompress levels without DCC. */ 743bf215546Sopenharmony_ci if (!radv_dcc_enabled(image, subresourceRange->baseMipLevel + l)) 744bf215546Sopenharmony_ci continue; 745bf215546Sopenharmony_ci 746bf215546Sopenharmony_ci width = radv_minify(image->info.width, subresourceRange->baseMipLevel + l); 747bf215546Sopenharmony_ci height = radv_minify(image->info.height, subresourceRange->baseMipLevel + l); 748bf215546Sopenharmony_ci 749bf215546Sopenharmony_ci for (uint32_t s = 0; s < radv_get_layerCount(image, subresourceRange); s++) { 750bf215546Sopenharmony_ci radv_image_view_init( 751bf215546Sopenharmony_ci &load_iview, cmd_buffer->device, 752bf215546Sopenharmony_ci &(VkImageViewCreateInfo){ 753bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, 754bf215546Sopenharmony_ci .image = radv_image_to_handle(image), 755bf215546Sopenharmony_ci .viewType = VK_IMAGE_VIEW_TYPE_2D, 756bf215546Sopenharmony_ci .format = image->vk.format, 757bf215546Sopenharmony_ci .subresourceRange = {.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, 758bf215546Sopenharmony_ci .baseMipLevel = subresourceRange->baseMipLevel + l, 759bf215546Sopenharmony_ci .levelCount = 1, 760bf215546Sopenharmony_ci .baseArrayLayer = subresourceRange->baseArrayLayer + s, 761bf215546Sopenharmony_ci .layerCount = 1}, 762bf215546Sopenharmony_ci }, 763bf215546Sopenharmony_ci 0, &(struct radv_image_view_extra_create_info){.enable_compression = true}); 764bf215546Sopenharmony_ci radv_image_view_init( 765bf215546Sopenharmony_ci &store_iview, cmd_buffer->device, 766bf215546Sopenharmony_ci &(VkImageViewCreateInfo){ 767bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, 768bf215546Sopenharmony_ci .image = radv_image_to_handle(image), 769bf215546Sopenharmony_ci .viewType = VK_IMAGE_VIEW_TYPE_2D, 770bf215546Sopenharmony_ci .format = image->vk.format, 771bf215546Sopenharmony_ci .subresourceRange = {.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, 772bf215546Sopenharmony_ci .baseMipLevel = subresourceRange->baseMipLevel + l, 773bf215546Sopenharmony_ci .levelCount = 1, 774bf215546Sopenharmony_ci .baseArrayLayer = subresourceRange->baseArrayLayer + s, 775bf215546Sopenharmony_ci .layerCount = 1}, 776bf215546Sopenharmony_ci }, 777bf215546Sopenharmony_ci 0, &(struct radv_image_view_extra_create_info){.disable_compression = true}); 778bf215546Sopenharmony_ci 779bf215546Sopenharmony_ci radv_meta_push_descriptor_set( 780bf215546Sopenharmony_ci cmd_buffer, VK_PIPELINE_BIND_POINT_COMPUTE, 781bf215546Sopenharmony_ci device->meta_state.fast_clear_flush.dcc_decompress_compute_p_layout, 0, /* set */ 782bf215546Sopenharmony_ci 2, /* descriptorWriteCount */ 783bf215546Sopenharmony_ci (VkWriteDescriptorSet[]){{.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, 784bf215546Sopenharmony_ci .dstBinding = 0, 785bf215546Sopenharmony_ci .dstArrayElement = 0, 786bf215546Sopenharmony_ci .descriptorCount = 1, 787bf215546Sopenharmony_ci .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 788bf215546Sopenharmony_ci .pImageInfo = 789bf215546Sopenharmony_ci (VkDescriptorImageInfo[]){ 790bf215546Sopenharmony_ci { 791bf215546Sopenharmony_ci .sampler = VK_NULL_HANDLE, 792bf215546Sopenharmony_ci .imageView = radv_image_view_to_handle(&load_iview), 793bf215546Sopenharmony_ci .imageLayout = VK_IMAGE_LAYOUT_GENERAL, 794bf215546Sopenharmony_ci }, 795bf215546Sopenharmony_ci }}, 796bf215546Sopenharmony_ci {.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, 797bf215546Sopenharmony_ci .dstBinding = 1, 798bf215546Sopenharmony_ci .dstArrayElement = 0, 799bf215546Sopenharmony_ci .descriptorCount = 1, 800bf215546Sopenharmony_ci .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 801bf215546Sopenharmony_ci .pImageInfo = (VkDescriptorImageInfo[]){ 802bf215546Sopenharmony_ci { 803bf215546Sopenharmony_ci .sampler = VK_NULL_HANDLE, 804bf215546Sopenharmony_ci .imageView = radv_image_view_to_handle(&store_iview), 805bf215546Sopenharmony_ci .imageLayout = VK_IMAGE_LAYOUT_GENERAL, 806bf215546Sopenharmony_ci }, 807bf215546Sopenharmony_ci }}}); 808bf215546Sopenharmony_ci 809bf215546Sopenharmony_ci radv_unaligned_dispatch(cmd_buffer, width, height, 1); 810bf215546Sopenharmony_ci 811bf215546Sopenharmony_ci radv_image_view_finish(&load_iview); 812bf215546Sopenharmony_ci radv_image_view_finish(&store_iview); 813bf215546Sopenharmony_ci } 814bf215546Sopenharmony_ci } 815bf215546Sopenharmony_ci 816bf215546Sopenharmony_ci /* Mark this image as actually being decompressed. */ 817bf215546Sopenharmony_ci radv_update_dcc_metadata(cmd_buffer, image, subresourceRange, false); 818bf215546Sopenharmony_ci 819bf215546Sopenharmony_ci radv_meta_restore(&saved_state, cmd_buffer); 820bf215546Sopenharmony_ci 821bf215546Sopenharmony_ci cmd_buffer->state.flush_bits |= 822bf215546Sopenharmony_ci RADV_CMD_FLAG_CS_PARTIAL_FLUSH | RADV_CMD_FLAG_INV_VCACHE | 823bf215546Sopenharmony_ci radv_src_access_flush(cmd_buffer, VK_ACCESS_2_SHADER_WRITE_BIT, image); 824bf215546Sopenharmony_ci 825bf215546Sopenharmony_ci /* Initialize the DCC metadata as "fully expanded". */ 826bf215546Sopenharmony_ci cmd_buffer->state.flush_bits |= radv_init_dcc(cmd_buffer, image, subresourceRange, 0xffffffff); 827bf215546Sopenharmony_ci} 828bf215546Sopenharmony_ci 829bf215546Sopenharmony_civoid 830bf215546Sopenharmony_ciradv_decompress_dcc(struct radv_cmd_buffer *cmd_buffer, struct radv_image *image, 831bf215546Sopenharmony_ci const VkImageSubresourceRange *subresourceRange) 832bf215546Sopenharmony_ci{ 833bf215546Sopenharmony_ci struct radv_barrier_data barrier = {0}; 834bf215546Sopenharmony_ci 835bf215546Sopenharmony_ci barrier.layout_transitions.dcc_decompress = 1; 836bf215546Sopenharmony_ci radv_describe_layout_transition(cmd_buffer, &barrier); 837bf215546Sopenharmony_ci 838bf215546Sopenharmony_ci if (cmd_buffer->qf == RADV_QUEUE_GENERAL) 839bf215546Sopenharmony_ci radv_process_color_image(cmd_buffer, image, subresourceRange, DCC_DECOMPRESS); 840bf215546Sopenharmony_ci else 841bf215546Sopenharmony_ci radv_decompress_dcc_compute(cmd_buffer, image, subresourceRange); 842bf215546Sopenharmony_ci} 843