mirror of https://gitlab.freedesktop.org/mesa/mesa
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:
parent
bfd4db0476
commit
5f2288095b
|
@ -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]);
|
||||
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in New Issue