Home | History | Annotate | Download | only in vulkan
      1 /*
      2  * Copyright  2016 Intel Corporation
      3  *
      4  * Permission is hereby granted, free of charge, to any person obtaining a
      5  * copy of this software and associated documentation files (the "Software"),
      6  * to deal in the Software without restriction, including without limitation
      7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      8  * and/or sell copies of the Software, and to permit persons to whom the
      9  * Software is furnished to do so, subject to the following conditions:
     10  *
     11  * The above copyright notice and this permission notice (including the next
     12  * paragraph) shall be included in all copies or substantial portions of the
     13  * Software.
     14  *
     15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
     20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
     21  * IN THE SOFTWARE.
     22  */
     23 
     24 #include <assert.h>
     25 #include <stdbool.h>
     26 
     27 #include "radv_meta.h"
     28 #include "radv_private.h"
     29 #include "sid.h"
     30 
     31 
     32 static nir_shader *
     33 build_dcc_decompress_compute_shader(struct radv_device *dev)
     34 {
     35 	nir_builder b;
     36 	const struct glsl_type *buf_type = glsl_sampler_type(GLSL_SAMPLER_DIM_2D,
     37 							     false,
     38 							     false,
     39 							     GLSL_TYPE_FLOAT);
     40 	const struct glsl_type *img_type = glsl_sampler_type(GLSL_SAMPLER_DIM_2D,
     41 							     false,
     42 							     false,
     43 							     GLSL_TYPE_FLOAT);
     44 	nir_builder_init_simple_shader(&b, NULL, MESA_SHADER_COMPUTE, NULL);
     45 	b.shader->info.name = ralloc_strdup(b.shader, "dcc_decompress_compute");
     46 
     47 	/* We need at least 16/16/1 to cover an entire DCC block in a single workgroup. */
     48 	b.shader->info.cs.local_size[0] = 16;
     49 	b.shader->info.cs.local_size[1] = 16;
     50 	b.shader->info.cs.local_size[2] = 1;
     51 	nir_variable *input_img = nir_variable_create(b.shader, nir_var_uniform,
     52 						      buf_type, "s_tex");
     53 	input_img->data.descriptor_set = 0;
     54 	input_img->data.binding = 0;
     55 
     56 	nir_variable *output_img = nir_variable_create(b.shader, nir_var_uniform,
     57 						       img_type, "out_img");
     58 	output_img->data.descriptor_set = 0;
     59 	output_img->data.binding = 1;
     60 
     61 	nir_ssa_def *invoc_id = nir_load_system_value(&b, nir_intrinsic_load_local_invocation_id, 0);
     62 	nir_ssa_def *wg_id = nir_load_system_value(&b, nir_intrinsic_load_work_group_id, 0);
     63 	nir_ssa_def *block_size = nir_imm_ivec4(&b,
     64 						b.shader->info.cs.local_size[0],
     65 						b.shader->info.cs.local_size[1],
     66 						b.shader->info.cs.local_size[2], 0);
     67 
     68 	nir_ssa_def *global_id = nir_iadd(&b, nir_imul(&b, wg_id, block_size), invoc_id);
     69 
     70 	nir_tex_instr *tex = nir_tex_instr_create(b.shader, 2);
     71 	tex->sampler_dim = GLSL_SAMPLER_DIM_2D;
     72 	tex->op = nir_texop_txf;
     73 	tex->src[0].src_type = nir_tex_src_coord;
     74 	tex->src[0].src = nir_src_for_ssa(nir_channels(&b, global_id, 3));
     75 	tex->src[1].src_type = nir_tex_src_lod;
     76 	tex->src[1].src = nir_src_for_ssa(nir_imm_int(&b, 0));
     77 	tex->dest_type = nir_type_float;
     78 	tex->is_array = false;
     79 	tex->coord_components = 2;
     80 	tex->texture = nir_deref_var_create(tex, input_img);
     81 	tex->sampler = NULL;
     82 
     83 	nir_ssa_dest_init(&tex->instr, &tex->dest, 4, 32, "tex");
     84 	nir_builder_instr_insert(&b, &tex->instr);
     85 
     86 	nir_intrinsic_instr *membar = nir_intrinsic_instr_create(b.shader, nir_intrinsic_memory_barrier);
     87 	nir_builder_instr_insert(&b, &membar->instr);
     88 
     89 	nir_intrinsic_instr *bar = nir_intrinsic_instr_create(b.shader, nir_intrinsic_barrier);
     90 	nir_builder_instr_insert(&b, &bar->instr);
     91 
     92 	nir_ssa_def *outval = &tex->dest.ssa;
     93 	nir_intrinsic_instr *store = nir_intrinsic_instr_create(b.shader, nir_intrinsic_image_store);
     94 	store->src[0] = nir_src_for_ssa(global_id);
     95 	store->src[1] = nir_src_for_ssa(nir_ssa_undef(&b, 1, 32));
     96 	store->src[2] = nir_src_for_ssa(outval);
     97 	store->variables[0] = nir_deref_var_create(store, output_img);
     98 
     99 	nir_builder_instr_insert(&b, &store->instr);
    100 	return b.shader;
    101 }
    102 
    103 static VkResult
    104 create_dcc_compress_compute(struct radv_device *device)
    105 {
    106 	VkResult result = VK_SUCCESS;
    107 	struct radv_shader_module cs = { .nir = NULL };
    108 
    109 	cs.nir = build_dcc_decompress_compute_shader(device);
    110 
    111 	VkDescriptorSetLayoutCreateInfo ds_create_info = {
    112 		.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
    113 		.flags = VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR,
    114 		.bindingCount = 2,
    115 		.pBindings = (VkDescriptorSetLayoutBinding[]) {
    116 			{
    117 				.binding = 0,
    118 				.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
    119 				.descriptorCount = 1,
    120 				.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT,
    121 				.pImmutableSamplers = NULL
    122 			},
    123 			{
    124 				.binding = 1,
    125 				.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
    126 				.descriptorCount = 1,
    127 				.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT,
    128 				.pImmutableSamplers = NULL
    129 			},
    130 		}
    131 	};
    132 
    133 	result = radv_CreateDescriptorSetLayout(radv_device_to_handle(device),
    134 						&ds_create_info,
    135 						&device->meta_state.alloc,
    136 						&device->meta_state.fast_clear_flush.dcc_decompress_compute_ds_layout);
    137 	if (result != VK_SUCCESS)
    138 		goto cleanup;
    139 
    140 
    141 	VkPipelineLayoutCreateInfo pl_create_info = {
    142 		.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
    143 		.setLayoutCount = 1,
    144 		.pSetLayouts = &device->meta_state.fast_clear_flush.dcc_decompress_compute_ds_layout,
    145 		.pushConstantRangeCount = 1,
    146 		.pPushConstantRanges = &(VkPushConstantRange){VK_SHADER_STAGE_COMPUTE_BIT, 0, 8},
    147 	};
    148 
    149 	result = radv_CreatePipelineLayout(radv_device_to_handle(device),
    150 					  &pl_create_info,
    151 					  &device->meta_state.alloc,
    152 					  &device->meta_state.fast_clear_flush.dcc_decompress_compute_p_layout);
    153 	if (result != VK_SUCCESS)
    154 		goto cleanup;
    155 
    156 	/* compute shader */
    157 
    158 	VkPipelineShaderStageCreateInfo pipeline_shader_stage = {
    159 		.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
    160 		.stage = VK_SHADER_STAGE_COMPUTE_BIT,
    161 		.module = radv_shader_module_to_handle(&cs),
    162 		.pName = "main",
    163 		.pSpecializationInfo = NULL,
    164 	};
    165 
    166 	VkComputePipelineCreateInfo vk_pipeline_info = {
    167 		.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
    168 		.stage = pipeline_shader_stage,
    169 		.flags = 0,
    170 		.layout = device->meta_state.fast_clear_flush.dcc_decompress_compute_p_layout,
    171 	};
    172 
    173 	result = radv_CreateComputePipelines(radv_device_to_handle(device),
    174 					     radv_pipeline_cache_to_handle(&device->meta_state.cache),
    175 					     1, &vk_pipeline_info, NULL,
    176 					     &device->meta_state.fast_clear_flush.dcc_decompress_compute_pipeline);
    177 	if (result != VK_SUCCESS)
    178 		goto cleanup;
    179 
    180 cleanup:
    181 	ralloc_free(cs.nir);
    182 	return result;
    183 }
    184 
    185 static VkResult
    186 create_pass(struct radv_device *device)
    187 {
    188 	VkResult result;
    189 	VkDevice device_h = radv_device_to_handle(device);
    190 	const VkAllocationCallbacks *alloc = &device->meta_state.alloc;
    191 	VkAttachmentDescription attachment;
    192 
    193 	attachment.format = VK_FORMAT_UNDEFINED;
    194 	attachment.samples = 1;
    195 	attachment.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
    196 	attachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
    197 	attachment.initialLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
    198 	attachment.finalLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
    199 
    200 	result = radv_CreateRenderPass(device_h,
    201 				       &(VkRenderPassCreateInfo) {
    202 					       .sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
    203 						       .attachmentCount = 1,
    204 						       .pAttachments = &attachment,
    205 						       .subpassCount = 1,
    206 						       .pSubpasses = &(VkSubpassDescription) {
    207 						       .pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS,
    208 						       .inputAttachmentCount = 0,
    209 						       .colorAttachmentCount = 1,
    210 						       .pColorAttachments = (VkAttachmentReference[]) {
    211 							       {
    212 								       .attachment = 0,
    213 								       .layout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
    214 							       },
    215 						       },
    216 						       .pResolveAttachments = NULL,
    217 						       .pDepthStencilAttachment = &(VkAttachmentReference) {
    218 							       .attachment = VK_ATTACHMENT_UNUSED,
    219 						       },
    220 						       .preserveAttachmentCount = 0,
    221 						       .pPreserveAttachments = NULL,
    222 					       },
    223 								.dependencyCount = 0,
    224 				       },
    225 				       alloc,
    226 				       &device->meta_state.fast_clear_flush.pass);
    227 
    228 	return result;
    229 }
    230 
    231 static VkResult
    232 create_pipeline_layout(struct radv_device *device, VkPipelineLayout *layout)
    233 {
    234 	VkPipelineLayoutCreateInfo pl_create_info = {
    235 		.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
    236 		.setLayoutCount = 0,
    237 		.pSetLayouts = NULL,
    238 		.pushConstantRangeCount = 0,
    239 		.pPushConstantRanges = NULL,
    240 	};
    241 
    242 	return radv_CreatePipelineLayout(radv_device_to_handle(device),
    243 					 &pl_create_info,
    244 					 &device->meta_state.alloc,
    245 					 layout);
    246 }
    247 
    248 static VkResult
    249 create_pipeline(struct radv_device *device,
    250 		VkShaderModule vs_module_h,
    251 		VkPipelineLayout layout)
    252 {
    253 	VkResult result;
    254 	VkDevice device_h = radv_device_to_handle(device);
    255 
    256 	struct radv_shader_module fs_module = {
    257 		.nir = radv_meta_build_nir_fs_noop(),
    258 	};
    259 
    260 	if (!fs_module.nir) {
    261 		/* XXX: Need more accurate error */
    262 		result = VK_ERROR_OUT_OF_HOST_MEMORY;
    263 		goto cleanup;
    264 	}
    265 
    266 	const VkPipelineShaderStageCreateInfo stages[2] = {
    267 		{
    268 			.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
    269 			.stage = VK_SHADER_STAGE_VERTEX_BIT,
    270 			.module = vs_module_h,
    271 			.pName = "main",
    272 		},
    273 		{
    274 			.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
    275 			.stage = VK_SHADER_STAGE_FRAGMENT_BIT,
    276 			.module = radv_shader_module_to_handle(&fs_module),
    277 			.pName = "main",
    278 		},
    279 	};
    280 
    281 	const VkPipelineVertexInputStateCreateInfo vi_state = {
    282 		.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
    283 		.vertexBindingDescriptionCount = 0,
    284 		.vertexAttributeDescriptionCount = 0,
    285 	};
    286 
    287 	const VkPipelineInputAssemblyStateCreateInfo ia_state = {
    288 		.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
    289 		.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,
    290 		.primitiveRestartEnable = false,
    291 	};
    292 
    293 	const VkPipelineColorBlendStateCreateInfo blend_state = {
    294 		.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
    295 		.logicOpEnable = false,
    296 		.attachmentCount = 1,
    297 		.pAttachments = (VkPipelineColorBlendAttachmentState []) {
    298 			{
    299 				.colorWriteMask = VK_COLOR_COMPONENT_R_BIT |
    300 				VK_COLOR_COMPONENT_G_BIT |
    301 				VK_COLOR_COMPONENT_B_BIT |
    302 				VK_COLOR_COMPONENT_A_BIT,
    303 			},
    304 		}
    305 	};
    306 	const VkPipelineRasterizationStateCreateInfo rs_state = {
    307 		.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
    308 		.depthClampEnable = false,
    309 		.rasterizerDiscardEnable = false,
    310 		.polygonMode = VK_POLYGON_MODE_FILL,
    311 		.cullMode = VK_CULL_MODE_NONE,
    312 		.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE,
    313 	};
    314 
    315 	result = radv_graphics_pipeline_create(device_h,
    316 					       radv_pipeline_cache_to_handle(&device->meta_state.cache),
    317 					       &(VkGraphicsPipelineCreateInfo) {
    318 						       .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
    319 						       .stageCount = 2,
    320 						       .pStages = stages,
    321 
    322 						       .pVertexInputState = &vi_state,
    323 						       .pInputAssemblyState = &ia_state,
    324 
    325 					       .pViewportState = &(VkPipelineViewportStateCreateInfo) {
    326 						       .sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
    327 						       .viewportCount = 1,
    328 						       .scissorCount = 1,
    329 					       },
    330 						       .pRasterizationState = &rs_state,
    331 					       .pMultisampleState = &(VkPipelineMultisampleStateCreateInfo) {
    332 						       .sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
    333 						       .rasterizationSamples = 1,
    334 						       .sampleShadingEnable = false,
    335 						       .pSampleMask = NULL,
    336 						       .alphaToCoverageEnable = false,
    337 						       .alphaToOneEnable = false,
    338 					       },
    339 						.pColorBlendState = &blend_state,
    340 						.pDynamicState = &(VkPipelineDynamicStateCreateInfo) {
    341 							.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,
    342 							.dynamicStateCount = 2,
    343 							.pDynamicStates = (VkDynamicState[]) {
    344 								VK_DYNAMIC_STATE_VIEWPORT,
    345 								VK_DYNAMIC_STATE_SCISSOR,
    346 							},
    347 						},
    348 					        .layout = layout,
    349 						.renderPass = device->meta_state.fast_clear_flush.pass,
    350 						.subpass = 0,
    351 					       },
    352 					       &(struct radv_graphics_pipeline_create_info) {
    353 						       .use_rectlist = true,
    354 						       .custom_blend_mode = V_028808_CB_ELIMINATE_FAST_CLEAR,
    355 					       },
    356 					       &device->meta_state.alloc,
    357 					       &device->meta_state.fast_clear_flush.cmask_eliminate_pipeline);
    358 	if (result != VK_SUCCESS)
    359 		goto cleanup;
    360 
    361 	result = radv_graphics_pipeline_create(device_h,
    362 					       radv_pipeline_cache_to_handle(&device->meta_state.cache),
    363 					       &(VkGraphicsPipelineCreateInfo) {
    364 						       .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
    365 						       .stageCount = 2,
    366 						       .pStages = stages,
    367 
    368 						       .pVertexInputState = &vi_state,
    369 						       .pInputAssemblyState = &ia_state,
    370 
    371 					       .pViewportState = &(VkPipelineViewportStateCreateInfo) {
    372 						       .sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
    373 						       .viewportCount = 1,
    374 						       .scissorCount = 1,
    375 					       },
    376 						       .pRasterizationState = &rs_state,
    377 					       .pMultisampleState = &(VkPipelineMultisampleStateCreateInfo) {
    378 						       .sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
    379 						       .rasterizationSamples = 1,
    380 						       .sampleShadingEnable = false,
    381 						       .pSampleMask = NULL,
    382 						       .alphaToCoverageEnable = false,
    383 						       .alphaToOneEnable = false,
    384 					       },
    385 						.pColorBlendState = &blend_state,
    386 						.pDynamicState = &(VkPipelineDynamicStateCreateInfo) {
    387 							.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,
    388 							.dynamicStateCount = 2,
    389 							.pDynamicStates = (VkDynamicState[]) {
    390 								VK_DYNAMIC_STATE_VIEWPORT,
    391 								VK_DYNAMIC_STATE_SCISSOR,
    392 							},
    393 						},
    394 						.layout = layout,
    395 						.renderPass = device->meta_state.fast_clear_flush.pass,
    396 						.subpass = 0,
    397 					       },
    398 					       &(struct radv_graphics_pipeline_create_info) {
    399 						       .use_rectlist = true,
    400 						       .custom_blend_mode = V_028808_CB_FMASK_DECOMPRESS,
    401 					       },
    402 					       &device->meta_state.alloc,
    403 					       &device->meta_state.fast_clear_flush.fmask_decompress_pipeline);
    404 	if (result != VK_SUCCESS)
    405 		goto cleanup;
    406 
    407 	result = radv_graphics_pipeline_create(device_h,
    408 					       radv_pipeline_cache_to_handle(&device->meta_state.cache),
    409 					       &(VkGraphicsPipelineCreateInfo) {
    410 						       .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
    411 						       .stageCount = 2,
    412 						       .pStages = stages,
    413 
    414 						       .pVertexInputState = &vi_state,
    415 						       .pInputAssemblyState = &ia_state,
    416 
    417 					       .pViewportState = &(VkPipelineViewportStateCreateInfo) {
    418 						       .sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
    419 						       .viewportCount = 1,
    420 						       .scissorCount = 1,
    421 					       },
    422 						       .pRasterizationState = &rs_state,
    423 					       .pMultisampleState = &(VkPipelineMultisampleStateCreateInfo) {
    424 						       .sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
    425 						       .rasterizationSamples = 1,
    426 						       .sampleShadingEnable = false,
    427 						       .pSampleMask = NULL,
    428 						       .alphaToCoverageEnable = false,
    429 						       .alphaToOneEnable = false,
    430 					       },
    431 						.pColorBlendState = &blend_state,
    432 						.pDynamicState = &(VkPipelineDynamicStateCreateInfo) {
    433 							.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,
    434 							.dynamicStateCount = 2,
    435 							.pDynamicStates = (VkDynamicState[]) {
    436 								VK_DYNAMIC_STATE_VIEWPORT,
    437 								VK_DYNAMIC_STATE_SCISSOR,
    438 							},
    439 						},
    440 						.layout = layout,
    441 						.renderPass = device->meta_state.fast_clear_flush.pass,
    442 						.subpass = 0,
    443 					       },
    444 					       &(struct radv_graphics_pipeline_create_info) {
    445 						       .use_rectlist = true,
    446 						       .custom_blend_mode = V_028808_CB_DCC_DECOMPRESS,
    447 					       },
    448 					       &device->meta_state.alloc,
    449 					       &device->meta_state.fast_clear_flush.dcc_decompress_pipeline);
    450 	if (result != VK_SUCCESS)
    451 		goto cleanup;
    452 
    453 	goto cleanup;
    454 
    455 cleanup:
    456 	ralloc_free(fs_module.nir);
    457 	return result;
    458 }
    459 
    460 void
    461 radv_device_finish_meta_fast_clear_flush_state(struct radv_device *device)
    462 {
    463 	struct radv_meta_state *state = &device->meta_state;
    464 
    465 	radv_DestroyPipeline(radv_device_to_handle(device),
    466 			     state->fast_clear_flush.dcc_decompress_pipeline,
    467 			     &state->alloc);
    468 	radv_DestroyPipeline(radv_device_to_handle(device),
    469 			     state->fast_clear_flush.fmask_decompress_pipeline,
    470 			     &state->alloc);
    471 	radv_DestroyPipeline(radv_device_to_handle(device),
    472 			     state->fast_clear_flush.cmask_eliminate_pipeline,
    473 			     &state->alloc);
    474 	radv_DestroyRenderPass(radv_device_to_handle(device),
    475 			       state->fast_clear_flush.pass, &state->alloc);
    476 	radv_DestroyPipelineLayout(radv_device_to_handle(device),
    477 				   state->fast_clear_flush.p_layout,
    478 				   &state->alloc);
    479 
    480 	radv_DestroyPipeline(radv_device_to_handle(device),
    481 			     state->fast_clear_flush.dcc_decompress_compute_pipeline,
    482 			     &state->alloc);
    483 	radv_DestroyPipelineLayout(radv_device_to_handle(device),
    484 				   state->fast_clear_flush.dcc_decompress_compute_p_layout,
    485 				   &state->alloc);
    486 	radv_DestroyDescriptorSetLayout(radv_device_to_handle(device),
    487 	                                state->fast_clear_flush.dcc_decompress_compute_ds_layout,
    488 	                                &state->alloc);
    489 }
    490 
    491 VkResult
    492 radv_device_init_meta_fast_clear_flush_state(struct radv_device *device)
    493 {
    494 	VkResult res = VK_SUCCESS;
    495 
    496 	struct radv_shader_module vs_module = { .nir = radv_meta_build_nir_vs_generate_vertices() };
    497 	if (!vs_module.nir) {
    498 		/* XXX: Need more accurate error */
    499 		res = VK_ERROR_OUT_OF_HOST_MEMORY;
    500 		goto fail;
    501 	}
    502 
    503 	res = create_pass(device);
    504 	if (res != VK_SUCCESS)
    505 		goto fail;
    506 
    507 	res = create_pipeline_layout(device,
    508 				     &device->meta_state.fast_clear_flush.p_layout);
    509 	if (res != VK_SUCCESS)
    510 		goto fail;
    511 
    512 	VkShaderModule vs_module_h = radv_shader_module_to_handle(&vs_module);
    513 	res = create_pipeline(device, vs_module_h,
    514 			      device->meta_state.fast_clear_flush.p_layout);
    515 	if (res != VK_SUCCESS)
    516 		goto fail;
    517 
    518 	res = create_dcc_compress_compute(device);
    519 	if (res != VK_SUCCESS)
    520 		goto fail;
    521 
    522 	goto cleanup;
    523 
    524 fail:
    525 	radv_device_finish_meta_fast_clear_flush_state(device);
    526 
    527 cleanup:
    528 	ralloc_free(vs_module.nir);
    529 
    530 	return res;
    531 }
    532 
    533 static void
    534 emit_fast_clear_flush(struct radv_cmd_buffer *cmd_buffer,
    535 		      const VkExtent2D *resolve_extent,
    536 		      VkPipeline pipeline)
    537 {
    538 	VkCommandBuffer cmd_buffer_h = radv_cmd_buffer_to_handle(cmd_buffer);
    539 
    540 	radv_CmdBindPipeline(cmd_buffer_h, VK_PIPELINE_BIND_POINT_GRAPHICS,
    541 			     pipeline);
    542 
    543 	radv_CmdSetViewport(radv_cmd_buffer_to_handle(cmd_buffer), 0, 1, &(VkViewport) {
    544 			.x = 0,
    545 			.y = 0,
    546 			.width = resolve_extent->width,
    547 			.height = resolve_extent->height,
    548 			.minDepth = 0.0f,
    549 			.maxDepth = 1.0f
    550 		});
    551 
    552 		radv_CmdSetScissor(radv_cmd_buffer_to_handle(cmd_buffer), 0, 1, &(VkRect2D) {
    553 			.offset = (VkOffset2D) { 0, 0 },
    554 			.extent = (VkExtent2D) { resolve_extent->width, resolve_extent->height },
    555 		});
    556 
    557 	radv_CmdDraw(cmd_buffer_h, 3, 1, 0, 0);
    558 	cmd_buffer->state.flush_bits |= (RADV_CMD_FLAG_FLUSH_AND_INV_CB |
    559 					 RADV_CMD_FLAG_FLUSH_AND_INV_CB_META);
    560 }
    561 
    562 static void
    563 radv_emit_set_predication_state_from_image(struct radv_cmd_buffer *cmd_buffer,
    564 				      struct radv_image *image, bool value)
    565 {
    566 	uint64_t va = 0;
    567 
    568 	if (value) {
    569 		va = radv_buffer_get_va(image->bo) + image->offset;
    570 		va += image->dcc_pred_offset;
    571 	}
    572 
    573 	si_emit_set_predication_state(cmd_buffer, va);
    574 }
    575 
    576 /**
    577  */
    578 static void
    579 radv_emit_color_decompress(struct radv_cmd_buffer *cmd_buffer,
    580                            struct radv_image *image,
    581                            const VkImageSubresourceRange *subresourceRange,
    582                            bool decompress_dcc)
    583 {
    584 	struct radv_meta_saved_state saved_state;
    585 	VkDevice device_h = radv_device_to_handle(cmd_buffer->device);
    586 	VkCommandBuffer cmd_buffer_h = radv_cmd_buffer_to_handle(cmd_buffer);
    587 	uint32_t layer_count = radv_get_layerCount(image, subresourceRange);
    588 	VkPipeline pipeline;
    589 
    590 	assert(cmd_buffer->queue_family_index == RADV_QUEUE_GENERAL);
    591 
    592 	radv_meta_save(&saved_state, cmd_buffer,
    593 		       RADV_META_SAVE_GRAPHICS_PIPELINE |
    594 		       RADV_META_SAVE_PASS);
    595 
    596 	if (decompress_dcc && image->surface.dcc_size) {
    597 		pipeline = cmd_buffer->device->meta_state.fast_clear_flush.dcc_decompress_pipeline;
    598 	} else if (image->fmask.size > 0) {
    599                pipeline = cmd_buffer->device->meta_state.fast_clear_flush.fmask_decompress_pipeline;
    600 	} else {
    601                pipeline = cmd_buffer->device->meta_state.fast_clear_flush.cmask_eliminate_pipeline;
    602 	}
    603 
    604 	if (!decompress_dcc && image->surface.dcc_size) {
    605 		radv_emit_set_predication_state_from_image(cmd_buffer, image, true);
    606 		cmd_buffer->state.predicating = true;
    607 	}
    608 	for (uint32_t layer = 0; layer < layer_count; ++layer) {
    609 		struct radv_image_view iview;
    610 
    611 		radv_image_view_init(&iview, cmd_buffer->device,
    612 				     &(VkImageViewCreateInfo) {
    613 					     .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
    614 					     .image = radv_image_to_handle(image),
    615 					     .viewType = radv_meta_get_view_type(image),
    616 					     .format = image->vk_format,
    617 					     .subresourceRange = {
    618 						     .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
    619 						     .baseMipLevel = 0,
    620 						     .levelCount = 1,
    621 						     .baseArrayLayer = subresourceRange->baseArrayLayer + layer,
    622 						     .layerCount = 1,
    623 					      },
    624 				     });
    625 
    626 		VkFramebuffer fb_h;
    627 		radv_CreateFramebuffer(device_h,
    628 				&(VkFramebufferCreateInfo) {
    629 					.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
    630 					.attachmentCount = 1,
    631 					.pAttachments = (VkImageView[]) {
    632 						radv_image_view_to_handle(&iview)
    633 					},
    634 				       .width = image->info.width,
    635 				       .height = image->info.height,
    636 				       .layers = 1
    637 				},
    638 				&cmd_buffer->pool->alloc,
    639 				&fb_h);
    640 
    641 		radv_CmdBeginRenderPass(cmd_buffer_h,
    642 				      &(VkRenderPassBeginInfo) {
    643 					      .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
    644 						      .renderPass = cmd_buffer->device->meta_state.fast_clear_flush.pass,
    645 						      .framebuffer = fb_h,
    646 						      .renderArea = {
    647 						      .offset = {
    648 							      0,
    649 							      0,
    650 						      },
    651 						      .extent = {
    652 							      image->info.width,
    653 							      image->info.height,
    654 						      }
    655 					      },
    656 					      .clearValueCount = 0,
    657 					      .pClearValues = NULL,
    658 				     },
    659 				     VK_SUBPASS_CONTENTS_INLINE);
    660 
    661 		emit_fast_clear_flush(cmd_buffer,
    662 				      &(VkExtent2D) { image->info.width, image->info.height },
    663 				      pipeline);
    664 		radv_CmdEndRenderPass(cmd_buffer_h);
    665 
    666 		radv_DestroyFramebuffer(device_h, fb_h,
    667 					&cmd_buffer->pool->alloc);
    668 
    669 	}
    670 	if (image->surface.dcc_size) {
    671 		cmd_buffer->state.predicating = false;
    672 		radv_emit_set_predication_state_from_image(cmd_buffer, image, false);
    673 	}
    674 	radv_meta_restore(&saved_state, cmd_buffer);
    675 }
    676 
    677 void
    678 radv_fast_clear_flush_image_inplace(struct radv_cmd_buffer *cmd_buffer,
    679                                     struct radv_image *image,
    680                                     const VkImageSubresourceRange *subresourceRange)
    681 {
    682 	radv_emit_color_decompress(cmd_buffer, image, subresourceRange, false);
    683 }
    684 
    685 static void
    686 radv_decompress_dcc_gfx(struct radv_cmd_buffer *cmd_buffer,
    687                         struct radv_image *image,
    688                         const VkImageSubresourceRange *subresourceRange)
    689 {
    690 	radv_emit_color_decompress(cmd_buffer, image, subresourceRange, true);
    691 }
    692 
    693 static void
    694 radv_decompress_dcc_compute(struct radv_cmd_buffer *cmd_buffer,
    695                             struct radv_image *image,
    696                             const VkImageSubresourceRange *subresourceRange)
    697 {
    698 	struct radv_meta_saved_state saved_state;
    699 	struct radv_image_view iview = {0};
    700 	struct radv_device *device = cmd_buffer->device;
    701 
    702 	/* This assumes the image is 2d with 1 layer and 1 mipmap level */
    703 	struct radv_cmd_state *state = &cmd_buffer->state;
    704 
    705 	state->flush_bits |= RADV_CMD_FLAG_FLUSH_AND_INV_CB |
    706 			     RADV_CMD_FLAG_FLUSH_AND_INV_CB_META;
    707 
    708 	radv_meta_save(&saved_state, cmd_buffer, RADV_META_SAVE_DESCRIPTORS |
    709 	                                         RADV_META_SAVE_COMPUTE_PIPELINE);
    710 
    711 	radv_CmdBindPipeline(radv_cmd_buffer_to_handle(cmd_buffer),
    712 	                     VK_PIPELINE_BIND_POINT_COMPUTE,
    713 	                     device->meta_state.fast_clear_flush.dcc_decompress_compute_pipeline);
    714 
    715 	radv_image_view_init(&iview, cmd_buffer->device,
    716 			     &(VkImageViewCreateInfo) {
    717 				     .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
    718 					     .image = radv_image_to_handle(image),
    719 					     .viewType = VK_IMAGE_VIEW_TYPE_2D,
    720 					     .format = image->vk_format,
    721 					     .subresourceRange = {
    722 						.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
    723 						.baseMipLevel = 0,
    724 						.levelCount = 1,
    725 						.baseArrayLayer = 0,
    726 						.layerCount = 1
    727 					     },
    728 			     });
    729 
    730 	radv_meta_push_descriptor_set(cmd_buffer,
    731 				      VK_PIPELINE_BIND_POINT_COMPUTE,
    732 				      device->meta_state.fast_clear_flush.dcc_decompress_compute_p_layout,
    733 				      0, /* set */
    734 				      2, /* descriptorWriteCount */
    735 				      (VkWriteDescriptorSet[]) {
    736 				              {
    737 				                       .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
    738 				                       .dstBinding = 0,
    739 				                       .dstArrayElement = 0,
    740 				                       .descriptorCount = 1,
    741 				                       .descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
    742 				                       .pImageInfo = (VkDescriptorImageInfo[]) {
    743 				                               {
    744 				                                       .sampler = VK_NULL_HANDLE,
    745 				                                       .imageView = radv_image_view_to_handle(&iview),
    746 				                                       .imageLayout = VK_IMAGE_LAYOUT_GENERAL,
    747 				                               },
    748 				                       }
    749 				              },
    750 				              {
    751 				                       .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
    752 				                       .dstBinding = 1,
    753 				                       .dstArrayElement = 0,
    754 				                       .descriptorCount = 1,
    755 				                       .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
    756 				                       .pImageInfo = (VkDescriptorImageInfo[]) {
    757 				                               {
    758 				                                       .sampler = VK_NULL_HANDLE,
    759 				                                       .imageView = radv_image_view_to_handle(&iview),
    760 				                                       .imageLayout = VK_IMAGE_LAYOUT_GENERAL,
    761 				                               },
    762 				                       }
    763 				              }
    764 				      });
    765 
    766 	radv_unaligned_dispatch(cmd_buffer, image->info.width, image->info.height, 1);
    767 
    768 	/* The fill buffer below does its own saving */
    769 	radv_meta_restore(&saved_state, cmd_buffer);
    770 
    771 	state->flush_bits |= RADV_CMD_FLAG_CS_PARTIAL_FLUSH |
    772 			     RADV_CMD_FLAG_INV_VMEM_L1;
    773 
    774 	state->flush_bits |= radv_fill_buffer(cmd_buffer, image->bo,
    775 					      image->offset + image->dcc_offset,
    776 					      image->surface.dcc_size, 0xffffffff);
    777 
    778 	state->flush_bits |= RADV_CMD_FLAG_FLUSH_AND_INV_CB |
    779 			     RADV_CMD_FLAG_FLUSH_AND_INV_CB_META;
    780 }
    781 
    782 void
    783 radv_decompress_dcc(struct radv_cmd_buffer *cmd_buffer,
    784                     struct radv_image *image,
    785                     const VkImageSubresourceRange *subresourceRange)
    786 {
    787 	if (cmd_buffer->queue_family_index == RADV_QUEUE_GENERAL)
    788 		radv_decompress_dcc_gfx(cmd_buffer, image, subresourceRange);
    789 	else
    790 		radv_decompress_dcc_compute(cmd_buffer, image, subresourceRange);
    791 }
    792