tu: Implement VK_EXT_pipeline_creation_feedback

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/16562>
This commit is contained in:
Connor Abbott
2022-05-16 19:11:42 +02:00
committed by Marge Bot
parent e348f2fb38
commit 49827da6fa
3 changed files with 83 additions and 6 deletions

View File

@@ -485,7 +485,7 @@ Vulkan 1.3 -- all DONE: anv, radv, lvp
VK_EXT_extended_dynamic_state2 DONE (anv, lvp, radv, tu)
VK_EXT_inline_uniform_block DONE (anv, radv, v3dv)
VK_EXT_pipeline_creation_cache_control DONE (anv, radv, v3dv)
VK_EXT_pipeline_creation_feedback DONE (anv, radv, v3dv)
VK_EXT_pipeline_creation_feedback DONE (anv, radv, tu, v3dv)
VK_EXT_private_data DONE (anv, lvp, radv, tu, v3dv)
VK_EXT_image_robustness DONE (anv, radv, tu)
VK_EXT_shader_demote_to_helper_invocation DONE (anv, radv, tu)

View File

@@ -216,6 +216,7 @@ get_device_extensions(const struct tu_physical_device *device,
.EXT_image_robustness = true,
.EXT_primitives_generated_query = true,
.EXT_image_view_min_lod = true,
.EXT_pipeline_creation_feedback = true,
#ifndef TU_USE_KGSL
.EXT_physical_device_drm = true,
#endif

View File

@@ -2660,11 +2660,12 @@ tu_shaders_deserialize(struct vk_device *_device,
static struct tu_compiled_shaders *
tu_pipeline_cache_lookup(struct vk_pipeline_cache *cache,
const void *key_data, size_t key_size)
const void *key_data, size_t key_size,
bool *application_cache_hit)
{
struct vk_pipeline_cache_object *object =
vk_pipeline_cache_lookup_object(cache, key_data, key_size,
&tu_shaders_ops, NULL);
&tu_shaders_ops, application_cache_hit);
if (object)
return container_of(object, struct tu_compiled_shaders, base);
else
@@ -2689,6 +2690,16 @@ tu_pipeline_builder_compile_shaders(struct tu_pipeline_builder *builder,
const VkPipelineShaderStageCreateInfo *stage_infos[MESA_SHADER_STAGES] = {
NULL
};
VkPipelineCreationFeedbackEXT pipeline_feedback = {
.flags = VK_PIPELINE_CREATION_FEEDBACK_VALID_BIT,
};
VkPipelineCreationFeedbackEXT stage_feedbacks[MESA_SHADER_STAGES] = { 0 };
int64_t pipeline_start = os_time_get_nano();
const VkPipelineCreationFeedbackCreateInfo *creation_feedback =
vk_find_struct_const(builder->create_info->pNext, PIPELINE_CREATION_FEEDBACK_CREATE_INFO);
for (uint32_t i = 0; i < builder->create_info->stageCount; i++) {
gl_shader_stage stage =
vk_to_mesa_shader_stage(builder->create_info->pStages[i].stage);
@@ -2718,9 +2729,17 @@ tu_pipeline_builder_compile_shaders(struct tu_pipeline_builder *builder,
struct tu_compiled_shaders *compiled_shaders;
if (!executable_info) {
bool application_cache_hit = false;
compiled_shaders =
tu_pipeline_cache_lookup(builder->cache, &pipeline_sha1,
sizeof(pipeline_sha1));
sizeof(pipeline_sha1),
&application_cache_hit);
if (application_cache_hit && builder->cache != builder->device->mem_cache) {
pipeline_feedback.flags |=
VK_PIPELINE_CREATION_FEEDBACK_APPLICATION_PIPELINE_CACHE_HIT_BIT;
}
if (compiled_shaders)
goto done;
@@ -2736,11 +2755,16 @@ tu_pipeline_builder_compile_shaders(struct tu_pipeline_builder *builder,
if (!stage_info)
continue;
int64_t stage_start = os_time_get_nano();
nir[stage] = tu_spirv_to_nir(builder->device, builder->mem_ctx, stage_info, stage);
if (!nir[stage]) {
result = VK_ERROR_OUT_OF_HOST_MEMORY;
goto fail;
}
stage_feedbacks[stage].flags = VK_PIPELINE_CREATION_FEEDBACK_VALID_BIT;
stage_feedbacks[stage].duration += os_time_get_nano() - stage_start;
}
if (!nir[MESA_SHADER_FRAGMENT]) {
@@ -2771,6 +2795,8 @@ tu_pipeline_builder_compile_shaders(struct tu_pipeline_builder *builder,
if (!nir[stage])
continue;
int64_t stage_start = os_time_get_nano();
struct tu_shader *shader =
tu_shader_create(builder->device, nir[stage], &keys[stage],
builder->layout, builder->alloc);
@@ -2802,6 +2828,8 @@ tu_pipeline_builder_compile_shaders(struct tu_pipeline_builder *builder,
desc_sets |= shader->active_desc_sets;
shaders[stage] = shader;
stage_feedbacks[stage].duration += os_time_get_nano() - stage_start;
}
struct tu_shader *last_shader = shaders[MESA_SHADER_GEOMETRY];
@@ -2832,6 +2860,8 @@ tu_pipeline_builder_compile_shaders(struct tu_pipeline_builder *builder,
if (!shaders[stage])
continue;
int64_t stage_start = os_time_get_nano();
compiled_shaders->variants[stage] =
ir3_shader_create_variant(shaders[stage]->ir3_shader, &ir3_key,
executable_info);
@@ -2839,6 +2869,8 @@ tu_pipeline_builder_compile_shaders(struct tu_pipeline_builder *builder,
return VK_ERROR_OUT_OF_HOST_MEMORY;
compiled_shaders->push_consts[stage] = shaders[stage]->push_consts;
stage_feedbacks[stage].duration += os_time_get_nano() - stage_start;
}
uint32_t safe_constlens = ir3_trim_constlen(compiled_shaders->variants, compiler);
@@ -2851,6 +2883,8 @@ tu_pipeline_builder_compile_shaders(struct tu_pipeline_builder *builder,
continue;
if (safe_constlens & (1 << stage)) {
int64_t stage_start = os_time_get_nano();
ralloc_free(compiled_shaders->variants[stage]);
compiled_shaders->variants[stage] =
ir3_shader_create_variant(shaders[stage]->ir3_shader, &ir3_key,
@@ -2859,6 +2893,8 @@ tu_pipeline_builder_compile_shaders(struct tu_pipeline_builder *builder,
result = VK_ERROR_OUT_OF_HOST_MEMORY;
goto fail;
}
stage_feedbacks[stage].duration += os_time_get_nano() - stage_start;
}
}
@@ -2902,6 +2938,19 @@ done:
compiled_shaders->variants[MESA_SHADER_TESS_CTRL]->key.tessellation;
}
pipeline_feedback.duration = os_time_get_nano() - pipeline_start;
if (creation_feedback) {
*creation_feedback->pPipelineCreationFeedback = pipeline_feedback;
assert(builder->create_info->stageCount ==
creation_feedback->pipelineStageCreationFeedbackCount);
for (uint32_t i = 0; i < builder->create_info->stageCount; i++) {
gl_shader_stage s =
vk_to_mesa_shader_stage(builder->create_info->pStages[i].stage);
creation_feedback->pPipelineStageCreationFeedbacks[i] = stage_feedbacks[s];
}
}
return VK_SUCCESS;
fail:
@@ -3820,6 +3869,15 @@ tu_compute_pipeline_create(VkDevice device,
*pPipeline = VK_NULL_HANDLE;
VkPipelineCreationFeedbackEXT pipeline_feedback = {
.flags = VK_PIPELINE_CREATION_FEEDBACK_VALID_BIT,
};
const VkPipelineCreationFeedbackCreateInfo *creation_feedback =
vk_find_struct_const(pCreateInfo->pNext, PIPELINE_CREATION_FEEDBACK_CREATE_INFO);
int64_t pipeline_start = os_time_get_nano();
pipeline = vk_object_zalloc(&dev->vk, pAllocator, sizeof(*pipeline),
VK_OBJECT_TYPE_PIPELINE);
if (!pipeline)
@@ -3841,8 +3899,18 @@ tu_compute_pipeline_create(VkDevice device,
const bool executable_info = pCreateInfo->flags &
VK_PIPELINE_CREATE_CAPTURE_INTERNAL_REPRESENTATIONS_BIT_KHR;
if (!executable_info)
compiled = tu_pipeline_cache_lookup(cache, pipeline_sha1, sizeof(pipeline_sha1));
bool application_cache_hit = false;
if (!executable_info) {
compiled =
tu_pipeline_cache_lookup(cache, pipeline_sha1, sizeof(pipeline_sha1),
&application_cache_hit);
}
if (application_cache_hit && cache != dev->mem_cache) {
pipeline_feedback.flags |=
VK_PIPELINE_CREATION_FEEDBACK_APPLICATION_PIPELINE_CACHE_HIT_BIT;
}
char *nir_initial_disasm = NULL;
@@ -3887,6 +3955,14 @@ tu_compute_pipeline_create(VkDevice device,
compiled = tu_pipeline_cache_insert(cache, compiled);
}
pipeline_feedback.duration = os_time_get_nano() - pipeline_start;
if (creation_feedback) {
*creation_feedback->pPipelineCreationFeedback = pipeline_feedback;
assert(creation_feedback->pipelineStageCreationFeedbackCount == 1);
creation_feedback->pPipelineStageCreationFeedbacks[0] = pipeline_feedback;
}
pipeline->active_desc_sets = compiled->active_desc_sets;
struct ir3_shader_variant *v = compiled->variants[MESA_SHADER_COMPUTE];