radv: skip compilation when possible with GPL fast-linking
When all shader stages have already been imported it's possible to skip radv_graphics_pipeline_compile() entirely. This makes GPL fast-linking VERY fast. Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/21068>
This commit is contained in:

committed by
Marge Bot

parent
6b513a9c6a
commit
3eb97b9d33
@@ -1895,7 +1895,8 @@ radv_emit_graphics_pipeline(struct radv_cmd_buffer *cmd_buffer)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
radv_cs_add_buffer(cmd_buffer->device->ws, cmd_buffer->cs, pipeline->base.slab_bo);
|
if (pipeline->base.slab_bo)
|
||||||
|
radv_cs_add_buffer(cmd_buffer->device->ws, cmd_buffer->cs, pipeline->base.slab_bo);
|
||||||
|
|
||||||
/* With graphics pipeline library, binaries are uploaded from a library and they hold a pointer
|
/* With graphics pipeline library, binaries are uploaded from a library and they hold a pointer
|
||||||
* to the slab BO.
|
* to the slab BO.
|
||||||
|
@@ -3427,6 +3427,64 @@ radv_pipeline_capture_shader_stats(const struct radv_device *device, VkPipelineC
|
|||||||
device->keep_shader_info;
|
device->keep_shader_info;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
radv_skip_graphics_pipeline_compile(const struct radv_graphics_pipeline *pipeline,
|
||||||
|
VkGraphicsPipelineLibraryFlagBitsEXT lib_flags,
|
||||||
|
bool fast_linking_enabled)
|
||||||
|
{
|
||||||
|
const struct radv_device *device = pipeline->base.device;
|
||||||
|
VkShaderStageFlagBits binary_stages = 0;
|
||||||
|
|
||||||
|
/* Do not skip when fast-linking isn't enabled. */
|
||||||
|
if (!fast_linking_enabled)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
/* Do not skip when the linked pipeline needs a noop FS. */
|
||||||
|
if ((lib_flags & VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_SHADER_BIT_EXT) &&
|
||||||
|
pipeline->active_stages & VK_SHADER_STAGE_FRAGMENT_BIT)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
/* Do not skip when the PS epilog needs to be compiled. */
|
||||||
|
if (!radv_pipeline_needs_dynamic_ps_epilog(pipeline) &&
|
||||||
|
(pipeline->active_stages & VK_SHADER_STAGE_FRAGMENT_BIT) &&
|
||||||
|
pipeline->base.shaders[MESA_SHADER_FRAGMENT]->info.ps.has_epilog &&
|
||||||
|
!pipeline->ps_epilog)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
/* Determine which shader stages have been imported. */
|
||||||
|
if (pipeline->base.shaders[MESA_SHADER_MESH]) {
|
||||||
|
binary_stages |= VK_SHADER_STAGE_MESH_BIT_EXT;
|
||||||
|
if (pipeline->base.shaders[MESA_SHADER_TASK]) {
|
||||||
|
binary_stages |= VK_SHADER_STAGE_TASK_BIT_EXT;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (uint32_t i = 0; i < MESA_SHADER_COMPUTE; i++) {
|
||||||
|
if (!pipeline->base.shaders[i])
|
||||||
|
continue;
|
||||||
|
|
||||||
|
binary_stages |= mesa_to_vk_shader_stage(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (device->physical_device->rad_info.gfx_level >= GFX9) {
|
||||||
|
/* On GFX9+, TES is merged with GS and VS is merged with TCS or GS. */
|
||||||
|
if (binary_stages & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) {
|
||||||
|
binary_stages |= VK_SHADER_STAGE_VERTEX_BIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (binary_stages & VK_SHADER_STAGE_GEOMETRY_BIT) {
|
||||||
|
if (binary_stages & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) {
|
||||||
|
binary_stages |= VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT;
|
||||||
|
} else {
|
||||||
|
binary_stages |= VK_SHADER_STAGE_VERTEX_BIT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Only skip compilation when all binaries have been imported. */
|
||||||
|
return binary_stages == pipeline->active_stages;
|
||||||
|
}
|
||||||
|
|
||||||
static VkResult
|
static VkResult
|
||||||
radv_graphics_pipeline_compile(struct radv_graphics_pipeline *pipeline,
|
radv_graphics_pipeline_compile(struct radv_graphics_pipeline *pipeline,
|
||||||
const VkGraphicsPipelineCreateInfo *pCreateInfo,
|
const VkGraphicsPipelineCreateInfo *pCreateInfo,
|
||||||
@@ -4940,7 +4998,7 @@ radv_graphics_pipeline_init(struct radv_graphics_pipeline *pipeline, struct radv
|
|||||||
struct radv_pipeline_layout pipeline_layout;
|
struct radv_pipeline_layout pipeline_layout;
|
||||||
struct vk_graphics_pipeline_state state = {0};
|
struct vk_graphics_pipeline_state state = {0};
|
||||||
bool fast_linking_enabled = false;
|
bool fast_linking_enabled = false;
|
||||||
VkResult result;
|
VkResult result = VK_SUCCESS;
|
||||||
|
|
||||||
pipeline->last_vgt_api_stage = MESA_SHADER_NONE;
|
pipeline->last_vgt_api_stage = MESA_SHADER_NONE;
|
||||||
|
|
||||||
@@ -4987,15 +5045,19 @@ radv_graphics_pipeline_init(struct radv_graphics_pipeline *pipeline, struct radv
|
|||||||
if (!fast_linking_enabled)
|
if (!fast_linking_enabled)
|
||||||
radv_pipeline_layout_hash(&pipeline_layout);
|
radv_pipeline_layout_hash(&pipeline_layout);
|
||||||
|
|
||||||
struct radv_pipeline_key key = radv_generate_graphics_pipeline_key(
|
|
||||||
pipeline, pCreateInfo, &state, (~imported_flags) & ALL_GRAPHICS_LIB_FLAGS);
|
|
||||||
|
|
||||||
result = radv_graphics_pipeline_compile(pipeline, pCreateInfo, &pipeline_layout, device, cache,
|
if (!radv_skip_graphics_pipeline_compile(pipeline, (~imported_flags) & ALL_GRAPHICS_LIB_FLAGS,
|
||||||
&key, (~imported_flags) & ALL_GRAPHICS_LIB_FLAGS,
|
fast_linking_enabled)) {
|
||||||
fast_linking_enabled);
|
struct radv_pipeline_key key = radv_generate_graphics_pipeline_key(
|
||||||
if (result != VK_SUCCESS) {
|
pipeline, pCreateInfo, &state, (~imported_flags) & ALL_GRAPHICS_LIB_FLAGS);
|
||||||
radv_pipeline_layout_finish(device, &pipeline_layout);
|
|
||||||
return result;
|
result = radv_graphics_pipeline_compile(pipeline, pCreateInfo, &pipeline_layout, device, cache,
|
||||||
|
&key, (~imported_flags) & ALL_GRAPHICS_LIB_FLAGS,
|
||||||
|
fast_linking_enabled);
|
||||||
|
if (result != VK_SUCCESS) {
|
||||||
|
radv_pipeline_layout_finish(device, &pipeline_layout);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t vgt_gs_out_prim_type = radv_pipeline_init_vgt_gs_out(pipeline, &state);
|
uint32_t vgt_gs_out_prim_type = radv_pipeline_init_vgt_gs_out(pipeline, &state);
|
||||||
|
Reference in New Issue
Block a user