From 001990031256673edde563517f0cfc048e565a9e Mon Sep 17 00:00:00 2001 From: Samuel Pitoiset Date: Thu, 2 Jan 2025 13:49:33 +0100 Subject: [PATCH] radv/meta: do not create redundant pipeline layout objects Signed-off-by: Samuel Pitoiset Part-of: --- src/amd/vulkan/meta/radv_meta_blit.c | 40 ++++--- src/amd/vulkan/meta/radv_meta_bufimage.c | 112 ++++++++++++------- src/amd/vulkan/meta/radv_meta_clear.c | 78 ++++++++----- src/amd/vulkan/meta/radv_meta_dcc_retile.c | 42 ++++--- src/amd/vulkan/meta/radv_meta_fmask_copy.c | 24 ++-- src/amd/vulkan/meta/radv_meta_fmask_expand.c | 24 ++-- 6 files changed, 205 insertions(+), 115 deletions(-) diff --git a/src/amd/vulkan/meta/radv_meta_blit.c b/src/amd/vulkan/meta/radv_meta_blit.c index 634d5341326..039085caf17 100644 --- a/src/amd/vulkan/meta/radv_meta_blit.c +++ b/src/amd/vulkan/meta/radv_meta_blit.c @@ -163,21 +163,9 @@ translate_sampler_dim(VkImageType type) } static VkResult -get_pipeline(struct radv_device *device, const struct radv_image_view *src_iview, - const struct radv_image_view *dst_iview, VkPipeline *pipeline_out, VkPipelineLayout *layout_out) +get_pipeline_layout(struct radv_device *device, VkPipelineLayout *layout_out) { - const VkImageAspectFlags aspect = src_iview->vk.aspects; - const struct radv_image *src_image = src_iview->image; - const struct radv_image *dst_image = dst_iview->image; - const enum glsl_sampler_dim tex_dim = translate_sampler_dim(src_image->vk.image_type); - unsigned fs_key = 0; - char key_data[64]; - VkResult result; - - if (src_image->vk.aspects == VK_IMAGE_ASPECT_COLOR_BIT) - fs_key = radv_format_meta_fs_key(device, dst_image->vk.format); - - snprintf(key_data, sizeof(key_data), "radv-blit-%d-%d-%d", src_image->vk.aspects, src_image->vk.image_type, fs_key); + const char *key_data = "radv-blit"; const VkDescriptorSetLayoutBinding binding = { .binding = 0, @@ -195,11 +183,31 @@ get_pipeline(struct radv_device *device, const struct radv_image_view *src_iview const VkPushConstantRange pc_range = {VK_SHADER_STAGE_VERTEX_BIT, 0, 20}; - result = vk_meta_get_pipeline_layout(&device->vk, &device->meta_state.device, &desc_info, &pc_range, key_data, - strlen(key_data), layout_out); + return vk_meta_get_pipeline_layout(&device->vk, &device->meta_state.device, &desc_info, &pc_range, key_data, + strlen(key_data), layout_out); +} + +static VkResult +get_pipeline(struct radv_device *device, const struct radv_image_view *src_iview, + const struct radv_image_view *dst_iview, VkPipeline *pipeline_out, VkPipelineLayout *layout_out) +{ + const VkImageAspectFlags aspect = src_iview->vk.aspects; + const struct radv_image *src_image = src_iview->image; + const struct radv_image *dst_image = dst_iview->image; + const enum glsl_sampler_dim tex_dim = translate_sampler_dim(src_image->vk.image_type); + unsigned fs_key = 0; + char key_data[64]; + VkResult result; + + result = get_pipeline_layout(device, layout_out); if (result != VK_SUCCESS) return result; + if (src_image->vk.aspects == VK_IMAGE_ASPECT_COLOR_BIT) + fs_key = radv_format_meta_fs_key(device, dst_image->vk.format); + + snprintf(key_data, sizeof(key_data), "radv-blit-%d-%d-%d", src_image->vk.aspects, src_image->vk.image_type, fs_key); + nir_shader *fs; nir_shader *vs = build_nir_vertex_shader(device); diff --git a/src/amd/vulkan/meta/radv_meta_bufimage.c b/src/amd/vulkan/meta/radv_meta_bufimage.c index 93241acff33..dee717c5225 100644 --- a/src/amd/vulkan/meta/radv_meta_bufimage.c +++ b/src/amd/vulkan/meta/radv_meta_bufimage.c @@ -56,14 +56,9 @@ build_nir_itob_compute_shader(struct radv_device *dev, bool is_3d) } static VkResult -get_itob_pipeline(struct radv_device *device, const struct radv_image *image, VkPipeline *pipeline_out, - VkPipelineLayout *layout_out) +get_itob_pipeline_layout(struct radv_device *device, VkPipelineLayout *layout_out) { - const bool is_3d = image->vk.image_type == VK_IMAGE_TYPE_3D; - char key_data[64]; - VkResult result; - - snprintf(key_data, sizeof(key_data), "radv-itob-%d", is_3d); + const char *key_data = "radv-itob"; const VkDescriptorSetLayoutBinding bindings[] = { { @@ -92,11 +87,24 @@ get_itob_pipeline(struct radv_device *device, const struct radv_image *image, Vk .size = 16, }; - result = vk_meta_get_pipeline_layout(&device->vk, &device->meta_state.device, &desc_info, &pc_range, key_data, - strlen(key_data), layout_out); + return vk_meta_get_pipeline_layout(&device->vk, &device->meta_state.device, &desc_info, &pc_range, key_data, + strlen(key_data), layout_out); +} + +static VkResult +get_itob_pipeline(struct radv_device *device, const struct radv_image *image, VkPipeline *pipeline_out, + VkPipelineLayout *layout_out) +{ + const bool is_3d = image->vk.image_type == VK_IMAGE_TYPE_3D; + char key_data[64]; + VkResult result; + + result = get_itob_pipeline_layout(device, layout_out); if (result != VK_SUCCESS) return result; + snprintf(key_data, sizeof(key_data), "radv-itob-%d", is_3d); + VkPipeline pipeline_from_cache = vk_meta_lookup_pipeline(&device->meta_state.device, key_data, strlen(key_data)); if (pipeline_from_cache != VK_NULL_HANDLE) { *pipeline_out = pipeline_from_cache; @@ -168,14 +176,9 @@ build_nir_btoi_compute_shader(struct radv_device *dev, bool is_3d) } static VkResult -get_btoi_pipeline(struct radv_device *device, const struct radv_image *image, VkPipeline *pipeline_out, - VkPipelineLayout *layout_out) +get_btoi_pipeline_layout(struct radv_device *device, VkPipelineLayout *layout_out) { - const bool is_3d = image->vk.image_type == VK_IMAGE_TYPE_3D; - char key_data[64]; - VkResult result; - - snprintf(key_data, sizeof(key_data), "radv-btoi-%d", is_3d); + const char *key_data = "radv-btoi"; const VkDescriptorSetLayoutBinding bindings[] = { { @@ -204,11 +207,24 @@ get_btoi_pipeline(struct radv_device *device, const struct radv_image *image, Vk .size = 16, }; - result = vk_meta_get_pipeline_layout(&device->vk, &device->meta_state.device, &desc_info, &pc_range, key_data, - strlen(key_data), layout_out); + return vk_meta_get_pipeline_layout(&device->vk, &device->meta_state.device, &desc_info, &pc_range, key_data, + strlen(key_data), layout_out); +} + +static VkResult +get_btoi_pipeline(struct radv_device *device, const struct radv_image *image, VkPipeline *pipeline_out, + VkPipelineLayout *layout_out) +{ + const bool is_3d = image->vk.image_type == VK_IMAGE_TYPE_3D; + char key_data[64]; + VkResult result; + + result = get_btoi_pipeline_layout(device, layout_out); if (result != VK_SUCCESS) return result; + snprintf(key_data, sizeof(key_data), "radv-btoi-%d", is_3d); + VkPipeline pipeline_from_cache = vk_meta_lookup_pipeline(&device->meta_state.device, key_data, strlen(key_data)); if (pipeline_from_cache != VK_NULL_HANDLE) { *pipeline_out = pipeline_from_cache; @@ -410,16 +426,9 @@ build_nir_itoi_compute_shader(struct radv_device *dev, bool src_3d, bool dst_3d, } static VkResult -get_itoi_pipeline(struct radv_device *device, const struct radv_image *src_image, const struct radv_image *dst_image, - int samples, VkPipeline *pipeline_out, VkPipelineLayout *layout_out) +get_itoi_pipeline_layout(struct radv_device *device, VkPipelineLayout *layout_out) { - const bool src_3d = src_image->vk.image_type == VK_IMAGE_TYPE_3D; - const bool dst_3d = dst_image->vk.image_type == VK_IMAGE_TYPE_3D; - const uint32_t samples_log2 = ffs(samples) - 1; - VkResult result; - char key_data[64]; - - snprintf(key_data, sizeof(key_data), "radv-itoi-%d-%d-%d", src_3d, dst_3d, samples_log2); + const char *key_data = "radv-itoi"; const VkDescriptorSetLayoutBinding bindings[] = { { @@ -448,11 +457,26 @@ get_itoi_pipeline(struct radv_device *device, const struct radv_image *src_image .size = 24, }; - result = vk_meta_get_pipeline_layout(&device->vk, &device->meta_state.device, &desc_info, &pc_range, key_data, - strlen(key_data), layout_out); + return vk_meta_get_pipeline_layout(&device->vk, &device->meta_state.device, &desc_info, &pc_range, key_data, + strlen(key_data), layout_out); +} + +static VkResult +get_itoi_pipeline(struct radv_device *device, const struct radv_image *src_image, const struct radv_image *dst_image, + int samples, VkPipeline *pipeline_out, VkPipelineLayout *layout_out) +{ + const bool src_3d = src_image->vk.image_type == VK_IMAGE_TYPE_3D; + const bool dst_3d = dst_image->vk.image_type == VK_IMAGE_TYPE_3D; + const uint32_t samples_log2 = ffs(samples) - 1; + VkResult result; + char key_data[64]; + + result = get_itoi_pipeline_layout(device, layout_out); if (result != VK_SUCCESS) return result; + snprintf(key_data, sizeof(key_data), "radv-itoi-%d-%d-%d", src_3d, dst_3d, samples_log2); + VkPipeline pipeline_from_cache = vk_meta_lookup_pipeline(&device->meta_state.device, key_data, strlen(key_data)); if (pipeline_from_cache != VK_NULL_HANDLE) { *pipeline_out = pipeline_from_cache; @@ -639,16 +663,9 @@ build_nir_cleari_compute_shader(struct radv_device *dev, bool is_3d, int samples } static VkResult -get_cleari_pipeline(struct radv_device *device, const struct radv_image *image, VkPipeline *pipeline_out, - VkPipelineLayout *layout_out) +get_cleari_pipeline_layout(struct radv_device *device, VkPipelineLayout *layout_out) { - const bool is_3d = image->vk.image_type == VK_IMAGE_TYPE_3D; - const uint32_t samples = image->vk.samples; - const uint32_t samples_log2 = ffs(samples) - 1; - char key_data[64]; - VkResult result; - - snprintf(key_data, sizeof(key_data), "radv-cleari-%d-%d", is_3d, samples_log2); + const char *key_data = "radv-cleari"; const VkDescriptorSetLayoutBinding binding = { .binding = 0, @@ -669,11 +686,26 @@ get_cleari_pipeline(struct radv_device *device, const struct radv_image *image, .size = 20, }; - result = vk_meta_get_pipeline_layout(&device->vk, &device->meta_state.device, &desc_info, &pc_range, key_data, - strlen(key_data), layout_out); + return vk_meta_get_pipeline_layout(&device->vk, &device->meta_state.device, &desc_info, &pc_range, key_data, + strlen(key_data), layout_out); +} + +static VkResult +get_cleari_pipeline(struct radv_device *device, const struct radv_image *image, VkPipeline *pipeline_out, + VkPipelineLayout *layout_out) +{ + const bool is_3d = image->vk.image_type == VK_IMAGE_TYPE_3D; + const uint32_t samples = image->vk.samples; + const uint32_t samples_log2 = ffs(samples) - 1; + char key_data[64]; + VkResult result; + + result = get_cleari_pipeline_layout(device, layout_out); if (result != VK_SUCCESS) return result; + snprintf(key_data, sizeof(key_data), "radv-cleari-%d-%d", is_3d, samples_log2); + VkPipeline pipeline_from_cache = vk_meta_lookup_pipeline(&device->meta_state.device, key_data, strlen(key_data)); if (pipeline_from_cache != VK_NULL_HANDLE) { *pipeline_out = pipeline_from_cache; diff --git a/src/amd/vulkan/meta/radv_meta_clear.c b/src/amd/vulkan/meta/radv_meta_clear.c index 659a02a4ad8..6f211a85dba 100644 --- a/src/amd/vulkan/meta/radv_meta_clear.c +++ b/src/amd/vulkan/meta/radv_meta_clear.c @@ -54,6 +54,20 @@ build_color_shaders(struct radv_device *dev, struct nir_shader **out_vs, struct *out_fs = fs_b.shader; } +static VkResult +get_color_pipeline_layout(struct radv_device *device, VkPipelineLayout *layout_out) +{ + const char *key_data = "radv-clear-color"; + + const VkPushConstantRange pc_range = { + .stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT, + .size = 16, + }; + + return vk_meta_get_pipeline_layout(&device->vk, &device->meta_state.device, NULL, &pc_range, key_data, + strlen(key_data), layout_out); +} + static VkResult get_color_pipeline(struct radv_device *device, uint32_t samples, uint32_t frag_output, VkFormat format, VkPipeline *pipeline_out, VkPipelineLayout *layout_out) @@ -62,18 +76,12 @@ get_color_pipeline(struct radv_device *device, uint32_t samples, uint32_t frag_o char key_data[64]; VkResult result; - snprintf(key_data, sizeof(key_data), "radv-clear-color-%d-%d-%d", samples, frag_output, fs_key); - - const VkPushConstantRange pc_range = { - .stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT, - .size = 16, - }; - - result = vk_meta_get_pipeline_layout(&device->vk, &device->meta_state.device, NULL, &pc_range, key_data, - strlen(key_data), layout_out); + result = get_color_pipeline_layout(device, layout_out); if (result != VK_SUCCESS) return result; + snprintf(key_data, sizeof(key_data), "radv-clear-color-%d-%d-%d", samples, frag_output, fs_key); + VkPipeline pipeline_from_cache = vk_meta_lookup_pipeline(&device->meta_state.device, key_data, strlen(key_data)); if (pipeline_from_cache != VK_NULL_HANDLE) { *pipeline_out = pipeline_from_cache; @@ -309,6 +317,22 @@ static bool radv_can_fast_clear_depth(struct radv_cmd_buffer *cmd_buffer, const const VkClearRect *clear_rect, const VkClearDepthStencilValue clear_value, uint32_t view_mask); +static VkResult +get_depth_stencil_pipeline_layout(struct radv_device *device, bool unrestricted, VkPipelineLayout *layout_out) +{ + char key_data[64]; + + snprintf(key_data, sizeof(key_data), "radv-clear-ds-%d", unrestricted); + + const VkPushConstantRange pc_range = { + .stageFlags = unrestricted ? VK_SHADER_STAGE_FRAGMENT_BIT : VK_SHADER_STAGE_VERTEX_BIT, + .size = 4, + }; + + return vk_meta_get_pipeline_layout(&device->vk, &device->meta_state.device, NULL, &pc_range, key_data, + strlen(key_data), layout_out); +} + static VkResult get_depth_stencil_pipeline(struct radv_device *device, int samples, VkImageAspectFlags aspects, bool fast, VkPipeline *pipeline_out, VkPipelineLayout *layout_out) @@ -317,18 +341,12 @@ get_depth_stencil_pipeline(struct radv_device *device, int samples, VkImageAspec char key_data[64]; VkResult result; - snprintf(key_data, sizeof(key_data), "radv-clear-ds-%d-%d-%d-%d", aspects, samples, fast, unrestricted); - - const VkPushConstantRange pc_range = { - .stageFlags = unrestricted ? VK_SHADER_STAGE_FRAGMENT_BIT : VK_SHADER_STAGE_VERTEX_BIT, - .size = 4, - }; - - result = vk_meta_get_pipeline_layout(&device->vk, &device->meta_state.device, NULL, &pc_range, key_data, - strlen(key_data), layout_out); + result = get_depth_stencil_pipeline_layout(device, unrestricted, layout_out); if (result != VK_SUCCESS) return result; + snprintf(key_data, sizeof(key_data), "radv-clear-ds-%d-%d-%d-%d", aspects, samples, fast, unrestricted); + VkPipeline pipeline_from_cache = vk_meta_lookup_pipeline(&device->meta_state.device, key_data, strlen(key_data)); if (pipeline_from_cache != VK_NULL_HANDLE) { *pipeline_out = pipeline_from_cache; @@ -1013,13 +1031,9 @@ radv_clear_dcc(struct radv_cmd_buffer *cmd_buffer, struct radv_image *image, con } static VkResult -get_clear_dcc_comp_to_single_pipeline(struct radv_device *device, bool is_msaa, VkPipeline *pipeline_out, - VkPipelineLayout *layout_out) +get_clear_dcc_comp_to_single_pipeline_layout(struct radv_device *device, VkPipelineLayout *layout_out) { - char key_data[64]; - VkResult result; - - snprintf(key_data, sizeof(key_data), "radv-clear-dcc-comp-to-single-%d", is_msaa); + const char *key_data = "radv-clear-dcc-comp-to-single"; const VkDescriptorSetLayoutBinding binding = { .binding = 0, @@ -1040,11 +1054,23 @@ get_clear_dcc_comp_to_single_pipeline(struct radv_device *device, bool is_msaa, .size = 24, }; - result = vk_meta_get_pipeline_layout(&device->vk, &device->meta_state.device, &desc_info, &pc_range, key_data, - strlen(key_data), layout_out); + return vk_meta_get_pipeline_layout(&device->vk, &device->meta_state.device, &desc_info, &pc_range, key_data, + strlen(key_data), layout_out); +} + +static VkResult +get_clear_dcc_comp_to_single_pipeline(struct radv_device *device, bool is_msaa, VkPipeline *pipeline_out, + VkPipelineLayout *layout_out) +{ + char key_data[64]; + VkResult result; + + result = get_clear_dcc_comp_to_single_pipeline_layout(device, layout_out); if (result != VK_SUCCESS) return result; + snprintf(key_data, sizeof(key_data), "radv-clear-dcc-comp-to-single-%d", is_msaa); + VkPipeline pipeline_from_cache = vk_meta_lookup_pipeline(&device->meta_state.device, key_data, strlen(key_data)); if (pipeline_from_cache != VK_NULL_HANDLE) { *pipeline_out = pipeline_from_cache; diff --git a/src/amd/vulkan/meta/radv_meta_dcc_retile.c b/src/amd/vulkan/meta/radv_meta_dcc_retile.c index a6f83a77731..470345f4295 100644 --- a/src/amd/vulkan/meta/radv_meta_dcc_retile.c +++ b/src/amd/vulkan/meta/radv_meta_dcc_retile.c @@ -59,23 +59,10 @@ build_dcc_retile_compute_shader(struct radv_device *dev, struct radeon_surf *sur return b.shader; } -/* - * This take a surface, but the only things used are: - * - BPE - * - DCC equations - * - DCC block size - * - * BPE is always 4 at the moment and the rest is derived from the tilemode. - */ static VkResult -get_pipeline(struct radv_device *device, struct radv_image *image, VkPipeline *pipeline_out, - VkPipelineLayout *layout_out) +get_pipeline_layout(struct radv_device *device, VkPipelineLayout *layout_out) { - const unsigned swizzle_mode = image->planes[0].surface.u.gfx9.swizzle_mode; - char key_data[64]; - VkResult result; - - snprintf(key_data, sizeof(key_data), "radv-dcc-retile-%d", swizzle_mode); + const char *key_data = "radv-dcc-retile"; const VkDescriptorSetLayoutBinding bindings[] = { { @@ -105,11 +92,32 @@ get_pipeline(struct radv_device *device, struct radv_image *image, VkPipeline *p .size = 16, }; - result = vk_meta_get_pipeline_layout(&device->vk, &device->meta_state.device, &desc_info, &pc_range, key_data, - strlen(key_data), layout_out); + return vk_meta_get_pipeline_layout(&device->vk, &device->meta_state.device, &desc_info, &pc_range, key_data, + strlen(key_data), layout_out); +} + +/* + * This take a surface, but the only things used are: + * - BPE + * - DCC equations + * - DCC block size + * + * BPE is always 4 at the moment and the rest is derived from the tilemode. + */ +static VkResult +get_pipeline(struct radv_device *device, struct radv_image *image, VkPipeline *pipeline_out, + VkPipelineLayout *layout_out) +{ + const unsigned swizzle_mode = image->planes[0].surface.u.gfx9.swizzle_mode; + char key_data[64]; + VkResult result; + + result = get_pipeline_layout(device, layout_out); if (result != VK_SUCCESS) return result; + snprintf(key_data, sizeof(key_data), "radv-dcc-retile-%d", swizzle_mode); + VkPipeline pipeline_from_cache = vk_meta_lookup_pipeline(&device->meta_state.device, key_data, strlen(key_data)); if (pipeline_from_cache != VK_NULL_HANDLE) { *pipeline_out = pipeline_from_cache; diff --git a/src/amd/vulkan/meta/radv_meta_fmask_copy.c b/src/amd/vulkan/meta/radv_meta_fmask_copy.c index 8e469e089cb..8da9eb74420 100644 --- a/src/amd/vulkan/meta/radv_meta_fmask_copy.c +++ b/src/amd/vulkan/meta/radv_meta_fmask_copy.c @@ -83,13 +83,9 @@ build_fmask_copy_compute_shader(struct radv_device *dev, int samples) } static VkResult -get_pipeline(struct radv_device *device, uint32_t samples_log2, VkPipeline *pipeline_out, VkPipelineLayout *layout_out) +get_pipeline_layout(struct radv_device *device, VkPipelineLayout *layout_out) { - const uint32_t samples = 1 << samples_log2; - char key_data[64]; - VkResult result; - - snprintf(key_data, sizeof(key_data), "radv-fmask-copy-%d", samples); + const char *key_data = "radv-fmask-copy"; const VkDescriptorSetLayoutBinding bindings[] = { { @@ -113,11 +109,23 @@ get_pipeline(struct radv_device *device, uint32_t samples_log2, VkPipeline *pipe .pBindings = bindings, }; - result = vk_meta_get_pipeline_layout(&device->vk, &device->meta_state.device, &desc_info, NULL, key_data, - strlen(key_data), layout_out); + return vk_meta_get_pipeline_layout(&device->vk, &device->meta_state.device, &desc_info, NULL, key_data, + strlen(key_data), layout_out); +} + +static VkResult +get_pipeline(struct radv_device *device, uint32_t samples_log2, VkPipeline *pipeline_out, VkPipelineLayout *layout_out) +{ + const uint32_t samples = 1 << samples_log2; + char key_data[64]; + VkResult result; + + result = get_pipeline_layout(device, layout_out); if (result != VK_SUCCESS) return result; + snprintf(key_data, sizeof(key_data), "radv-fmask-copy-%d", samples); + VkPipeline pipeline_from_cache = vk_meta_lookup_pipeline(&device->meta_state.device, key_data, strlen(key_data)); if (pipeline_from_cache != VK_NULL_HANDLE) { *pipeline_out = pipeline_from_cache; diff --git a/src/amd/vulkan/meta/radv_meta_fmask_expand.c b/src/amd/vulkan/meta/radv_meta_fmask_expand.c index 0da8170383c..86bd06eee8c 100644 --- a/src/amd/vulkan/meta/radv_meta_fmask_expand.c +++ b/src/amd/vulkan/meta/radv_meta_fmask_expand.c @@ -50,13 +50,9 @@ build_fmask_expand_compute_shader(struct radv_device *device, int samples) } static VkResult -get_pipeline(struct radv_device *device, uint32_t samples_log2, VkPipeline *pipeline_out, VkPipelineLayout *layout_out) +get_pipeline_layout(struct radv_device *device, VkPipelineLayout *layout_out) { - const uint32_t samples = 1 << samples_log2; - char key_data[64]; - VkResult result; - - snprintf(key_data, sizeof(key_data), "radv-fmask-expand-%d", samples); + const char *key_data = "radv-fmask-expand"; const VkDescriptorSetLayoutBinding bindings[] = { { @@ -80,11 +76,23 @@ get_pipeline(struct radv_device *device, uint32_t samples_log2, VkPipeline *pipe .pBindings = bindings, }; - result = vk_meta_get_pipeline_layout(&device->vk, &device->meta_state.device, &desc_info, NULL, key_data, - strlen(key_data), layout_out); + return vk_meta_get_pipeline_layout(&device->vk, &device->meta_state.device, &desc_info, NULL, key_data, + strlen(key_data), layout_out); +} + +static VkResult +get_pipeline(struct radv_device *device, uint32_t samples_log2, VkPipeline *pipeline_out, VkPipelineLayout *layout_out) +{ + const uint32_t samples = 1 << samples_log2; + char key_data[64]; + VkResult result; + + result = get_pipeline_layout(device, layout_out); if (result != VK_SUCCESS) return result; + snprintf(key_data, sizeof(key_data), "radv-fmask-expand-%d", samples); + VkPipeline pipeline_from_cache = vk_meta_lookup_pipeline(&device->meta_state.device, key_data, strlen(key_data)); if (pipeline_from_cache != VK_NULL_HANDLE) { *pipeline_out = pipeline_from_cache;