diff --git a/src/amd/vulkan/radv_pipeline.c b/src/amd/vulkan/radv_pipeline.c index a0c32f5a285..72ab2f75f3b 100644 --- a/src/amd/vulkan/radv_pipeline.c +++ b/src/amd/vulkan/radv_pipeline.c @@ -227,6 +227,9 @@ radv_pipeline_destroy(struct radv_device *device, struct radv_pipeline *pipeline ralloc_free(pipeline->retained_shaders[i].nir); } + if (gfx_pipeline_lib->base.ps_epilog) + radv_shader_part_unref(device, gfx_pipeline_lib->base.ps_epilog); + vk_free(&device->vk.alloc, gfx_pipeline_lib->base.state_data); } @@ -6202,10 +6205,33 @@ radv_graphics_lib_pipeline_init(struct radv_graphics_lib_pipeline *pipeline, result = radv_pipeline_import_graphics_info(&pipeline->base, state, pipeline_layout, pCreateInfo, imported_flags); if (result != VK_SUCCESS) - goto fail; + goto fail_layout; radv_pipeline_layout_hash(pipeline_layout); + /* Compile a PS epilog if the fragment shader output interface is present without the main + * fragment shader. + */ + if ((imported_flags & VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_OUTPUT_INTERFACE_BIT_EXT) && + !(imported_flags & VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_SHADER_BIT_EXT)) { + struct radv_blend_state blend = + radv_pipeline_init_blend_state(&pipeline->base, state); + + struct radv_pipeline_key key = + radv_generate_graphics_pipeline_key(&pipeline->base, pCreateInfo, state, &blend); + + struct radv_ps_epilog_key epilog_key = { + .spi_shader_col_format = blend.spi_shader_col_format, + .color_is_int8 = blend.col_format_is_int8, + .color_is_int10 = blend.col_format_is_int10, + .enable_mrt_output_nan_fixup = key.ps.enable_mrt_output_nan_fixup, + }; + + pipeline->base.ps_epilog = radv_create_ps_epilog(device, &epilog_key); + if (!pipeline->base.ps_epilog) + goto fail_layout; + } + if (pipeline->base.active_stages != 0) { const VkPipelineCreationFeedbackCreateInfo *creation_feedback = vk_find_struct_const(pCreateInfo->pNext, PIPELINE_CREATION_FEEDBACK_CREATE_INFO); @@ -6228,12 +6254,15 @@ radv_graphics_lib_pipeline_init(struct radv_graphics_lib_pipeline *pipeline, creation_feedback, NULL, NULL, &pipeline->base.last_vgt_api_stage); if (result != VK_SUCCESS && result != VK_PIPELINE_COMPILE_REQUIRED) - goto fail; + goto fail_shaders; } return VK_SUCCESS; -fail: +fail_shaders: + if (pipeline->base.ps_epilog) + radv_shader_part_unref(device, pipeline->base.ps_epilog); +fail_layout: radv_pipeline_layout_finish(device, pipeline_layout); return result; } diff --git a/src/amd/vulkan/radv_private.h b/src/amd/vulkan/radv_private.h index 9988a7fc119..c488d1f0238 100644 --- a/src/amd/vulkan/radv_private.h +++ b/src/amd/vulkan/radv_private.h @@ -2040,6 +2040,9 @@ struct radv_graphics_pipeline { /* For vk_graphics_pipeline_state */ void *state_data; + + /* Not NULL if graphics pipeline uses a PS epilog. */ + struct radv_shader_part *ps_epilog; }; struct radv_compute_pipeline {