anv: fix shader identifier handling

When compilation is required, we should return
VK_PIPELINE_COMPILE_REQUIRED. The spec prevents the application from
passing a module or SPIR-V code so we have nothing to compile if the
cache lookup fails :

VUID-VkPipelineShaderStageCreateInfo-stage-06844:
   If a shader module identifier is specified for this stage, a
   VkShaderModuleCreateInfo structure must not be present in the pNext
   chain

VUID-VkPipelineShaderStageCreateInfo-stage-06848:
   If a shader module identifier is specified for this stage, module
   must be VK_NULL_HANDLE

Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Cc: mesa-stable
Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/11208
Reviewed-by: Tapani Pälli <tapani.palli@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/29340>
This commit is contained in:
Lionel Landwerlin 2024-05-23 09:59:34 +03:00 committed by Marge Bot
parent bfd4db0476
commit 5f2288095b
3 changed files with 52 additions and 28 deletions

View File

@ -778,7 +778,7 @@ anv_pipeline_hash_ray_tracing_combined_shader(struct anv_ray_tracing_pipeline *p
_mesa_sha1_final(&ctx, sha1_out);
}
static nir_shader *
static VkResult
anv_pipeline_stage_get_nir(struct anv_pipeline *pipeline,
struct vk_pipeline_cache *cache,
void *mem_ctx,
@ -788,25 +788,35 @@ anv_pipeline_stage_get_nir(struct anv_pipeline *pipeline,
pipeline->device->physical->compiler;
const nir_shader_compiler_options *nir_options =
compiler->nir_options[stage->stage];
nir_shader *nir;
nir = anv_device_search_for_nir(pipeline->device, cache,
nir_options,
stage->shader_sha1,
mem_ctx);
if (nir) {
assert(nir->info.stage == stage->stage);
return nir;
stage->nir = anv_device_search_for_nir(pipeline->device, cache,
nir_options,
stage->shader_sha1,
mem_ctx);
if (stage->nir) {
assert(stage->nir->info.stage == stage->stage);
return VK_SUCCESS;
}
nir = anv_shader_stage_to_nir(pipeline->device, stage->info,
stage->key.base.robust_flags, mem_ctx);
if (nir) {
anv_device_upload_nir(pipeline->device, cache, nir, stage->shader_sha1);
return nir;
/* VkPipelineShaderStageCreateInfo:
*
* "If a pipeline is not found, pipeline compilation is not possible and
* the implementation must fail as specified by
* VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT."
*/
if (vk_pipeline_shader_stage_has_identifier(stage->info))
return VK_PIPELINE_COMPILE_REQUIRED;
stage->nir = anv_shader_stage_to_nir(pipeline->device, stage->info,
stage->key.base.robust_flags, mem_ctx);
if (stage->nir) {
anv_device_upload_nir(pipeline->device, cache,
stage->nir, stage->shader_sha1);
return VK_SUCCESS;
}
return NULL;
return vk_errorf(&pipeline->device->vk, VK_ERROR_UNKNOWN,
"Unable to load NIR");
}
static const struct vk_ycbcr_conversion_state *
@ -2026,10 +2036,10 @@ anv_graphics_pipeline_load_nir(struct anv_graphics_base_pipeline *pipeline,
* an imported library for the same stage.
*/
if (stages[s].imported.bin == NULL) {
stages[s].nir = anv_pipeline_stage_get_nir(&pipeline->base, cache,
mem_ctx, &stages[s]);
if (stages[s].nir == NULL)
return vk_error(pipeline, VK_ERROR_UNKNOWN);
VkResult result = anv_pipeline_stage_get_nir(&pipeline->base, cache,
mem_ctx, &stages[s]);
if (result != VK_SUCCESS)
return result;
} else {
stages[s].nir = need_clone ?
nir_shader_clone(mem_ctx, stages[s].imported.nir) :
@ -2232,9 +2242,9 @@ anv_graphics_pipeline_compile(struct anv_graphics_base_pipeline *pipeline,
vk_perf(VK_LOG_OBJS(cache ? &cache->base :
&pipeline->base.device->vk.base),
"Found all ISA shaders in the cache but not all NIR shaders.");
} else {
anv_graphics_lib_retain_shaders(pipeline, stages, false /* will_compile */);
}
anv_graphics_lib_retain_shaders(pipeline, stages, false /* will_compile */);
}
if (result == VK_SUCCESS)
@ -2637,10 +2647,11 @@ anv_pipeline_compile_cs(struct anv_compute_pipeline *pipeline,
.binding = UINT32_MAX,
};
stage.nir = anv_pipeline_stage_get_nir(&pipeline->base, cache, mem_ctx, &stage);
if (stage.nir == NULL) {
VkResult result = anv_pipeline_stage_get_nir(&pipeline->base, cache,
mem_ctx, &stage);
if (result != VK_SUCCESS) {
ralloc_free(mem_ctx);
return vk_error(pipeline, VK_ERROR_UNKNOWN);
return result;
}
anv_pipeline_nir_preprocess(&pipeline->base, &stage);
@ -3618,10 +3629,11 @@ anv_pipeline_compile_ray_tracing(struct anv_ray_tracing_pipeline *pipeline,
int64_t stage_start = os_time_get_nano();
stages[i].nir = anv_pipeline_stage_get_nir(&pipeline->base, cache,
tmp_pipeline_ctx, &stages[i]);
if (stages[i].nir == NULL)
return vk_error(pipeline, VK_ERROR_OUT_OF_HOST_MEMORY);
VkResult result = anv_pipeline_stage_get_nir(&pipeline->base, cache,
tmp_pipeline_ctx,
&stages[i]);
if (result != VK_SUCCESS)
return result;
anv_pipeline_nir_preprocess(&pipeline->base, &stages[i]);

View File

@ -56,6 +56,15 @@ vk_pipeline_shader_stage_is_null(const VkPipelineShaderStageCreateInfo *info)
return true;
}
bool
vk_pipeline_shader_stage_has_identifier(const VkPipelineShaderStageCreateInfo *info)
{
const VkPipelineShaderStageModuleIdentifierCreateInfoEXT *id_info =
vk_find_struct_const(info->pNext, PIPELINE_SHADER_STAGE_MODULE_IDENTIFIER_CREATE_INFO_EXT);
return id_info && id_info->identifierSize != 0;
}
static nir_shader *
get_builtin_nir(const VkPipelineShaderStageCreateInfo *info)
{

View File

@ -54,6 +54,9 @@ typedef struct VkPipelineShaderStageNirCreateInfoMESA {
bool
vk_pipeline_shader_stage_is_null(const VkPipelineShaderStageCreateInfo *info);
bool
vk_pipeline_shader_stage_has_identifier(const VkPipelineShaderStageCreateInfo *info);
VkResult
vk_pipeline_shader_stage_to_nir(struct vk_device *device,
const VkPipelineShaderStageCreateInfo *info,