diff --git a/src/amd/vulkan/meta/radv_meta_dcc_retile.c b/src/amd/vulkan/meta/radv_meta_dcc_retile.c index 4af6ae9199f..0224980b26b 100644 --- a/src/amd/vulkan/meta/radv_meta_dcc_retile.c +++ b/src/amd/vulkan/meta/radv_meta_dcc_retile.c @@ -84,10 +84,9 @@ radv_device_finish_meta_dcc_retile_state(struct radv_device *device) * BPE is always 4 at the moment and the rest is derived from the tilemode. */ static VkResult -radv_device_init_meta_dcc_retile_state(struct radv_device *device, struct radeon_surf *surf) +create_pipeline(struct radv_device *device, struct radeon_surf *surf) { VkResult result = VK_SUCCESS; - nir_shader *cs = build_dcc_retile_compute_shader(device, surf); if (!device->meta_state.dcc_retile.ds_layout) { const VkDescriptorSetLayoutBinding bindings[] = { @@ -108,7 +107,7 @@ radv_device_init_meta_dcc_retile_state(struct radv_device *device, struct radeon result = radv_meta_create_descriptor_set_layout(device, 2, bindings, &device->meta_state.dcc_retile.ds_layout); if (result != VK_SUCCESS) - goto cleanup; + return result; } if (!device->meta_state.dcc_retile.p_layout) { @@ -120,53 +119,67 @@ radv_device_init_meta_dcc_retile_state(struct radv_device *device, struct radeon result = radv_meta_create_pipeline_layout(device, &device->meta_state.dcc_retile.ds_layout, 1, &pc_range, &device->meta_state.dcc_retile.p_layout); if (result != VK_SUCCESS) - goto cleanup; + return result; } + nir_shader *cs = build_dcc_retile_compute_shader(device, surf); + result = radv_meta_create_compute_pipeline(device, cs, device->meta_state.dcc_retile.p_layout, &device->meta_state.dcc_retile.pipeline[surf->u.gfx9.swizzle_mode]); - if (result != VK_SUCCESS) - goto cleanup; -cleanup: ralloc_free(cs); return result; } +static VkResult +get_pipeline(struct radv_device *device, struct radv_image *image, VkPipeline *pipeline_out) +{ + struct radv_meta_state *state = &device->meta_state; + VkResult result = VK_SUCCESS; + + const unsigned swizzle_mode = image->planes[0].surface.u.gfx9.swizzle_mode; + + mtx_lock(&state->mtx); + if (!state->dcc_retile.pipeline[swizzle_mode]) { + result = create_pipeline(device, &image->planes[0].surface); + if (result != VK_SUCCESS) + goto fail; + } + + *pipeline_out = state->dcc_retile.pipeline[swizzle_mode]; + +fail: + mtx_unlock(&state->mtx); + return result; +} + void radv_retile_dcc(struct radv_cmd_buffer *cmd_buffer, struct radv_image *image) { struct radv_meta_saved_state saved_state; struct radv_device *device = radv_cmd_buffer_device(cmd_buffer); struct radv_buffer buffer; + VkPipeline pipeline; + VkResult result; assert(image->vk.image_type == VK_IMAGE_TYPE_2D); assert(image->vk.array_layers == 1 && image->vk.mip_levels == 1); struct radv_cmd_state *state = &cmd_buffer->state; + result = get_pipeline(device, image, &pipeline); + if (result != VK_SUCCESS) { + vk_command_buffer_set_error(&cmd_buffer->vk, result); + return; + } + state->flush_bits |= radv_dst_access_flush(cmd_buffer, VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT, VK_ACCESS_2_SHADER_READ_BIT, image); - unsigned swizzle_mode = image->planes[0].surface.u.gfx9.swizzle_mode; - - /* Compile pipelines if not already done so. */ - mtx_lock(&device->meta_state.mtx); - if (!device->meta_state.dcc_retile.pipeline[swizzle_mode]) { - VkResult ret = radv_device_init_meta_dcc_retile_state(device, &image->planes[0].surface); - if (ret != VK_SUCCESS) { - mtx_unlock(&device->meta_state.mtx); - vk_command_buffer_set_error(&cmd_buffer->vk, ret); - return; - } - } - mtx_unlock(&device->meta_state.mtx); - radv_meta_save(&saved_state, cmd_buffer, RADV_META_SAVE_DESCRIPTORS | RADV_META_SAVE_COMPUTE_PIPELINE | RADV_META_SAVE_CONSTANTS); - radv_CmdBindPipeline(radv_cmd_buffer_to_handle(cmd_buffer), VK_PIPELINE_BIND_POINT_COMPUTE, - device->meta_state.dcc_retile.pipeline[swizzle_mode]); + radv_CmdBindPipeline(radv_cmd_buffer_to_handle(cmd_buffer), VK_PIPELINE_BIND_POINT_COMPUTE, pipeline); radv_buffer_init(&buffer, device, image->bindings[0].bo, image->size, image->bindings[0].offset);