hasvk: Account for unsupported shaderStorageImageReadWithoutFormat.

When mpv creates the bwdif_vulkan filter we can sometimes see
exactly what's happening:
shaderStorageImageReadWithoutFormat support is false, but
shaderStorageImageWriteWithoutFormat support is true.
SPIR-V complains and then the GPU hangs since elk can't do the
necessary lowering. See here:
if (var->data.image.format == PIPE_FORMAT_NONE)
   return false;
To make deinterlacing work again the fix probably needs to be in
FFmpeg. See its commit 779763181f85bf25c53af5789d8b9b99d3bb0d1d.

Assisted-by: Claude
This commit is contained in:
dancingmirrors authored and elwrcl committed 2026-07-21 22:25:26 +03:00
1 parent cd1018d5ea
commit 22ce819de6
1 file changed
+47 -2
+47 -2
View File
@@ -463,7 +463,32 @@ shared_type_info(const struct glsl_type *type, unsigned *size, unsigned *align)
*align = comp_size * (length == 3 ? 4 : length);
}
static void
static bool
anv_nir_has_formatless_image_read(nir_shader *nir)
{
nir_foreach_function_impl(impl, nir) {
nir_foreach_block(block, impl) {
nir_foreach_instr(instr, block) {
if (instr->type != nir_instr_type_intrinsic)
continue;
nir_intrinsic_instr *intrin = nir_instr_as_intrinsic(instr);
if (intrin->intrinsic != nir_intrinsic_image_deref_load &&
intrin->intrinsic != nir_intrinsic_image_deref_sparse_load)
continue;
nir_deref_instr *deref = nir_src_as_deref(intrin->src[0]);
nir_variable *var = nir_deref_instr_get_variable(deref);
if (var && var->data.image.format == PIPE_FORMAT_NONE)
return true;
}
}
}
return false;
}
static VkResult
anv_pipeline_lower_nir(struct anv_pipeline *pipeline,
void *mem_ctx,
struct anv_pipeline_stage *stage,
@@ -491,6 +516,14 @@ anv_pipeline_lower_nir(struct anv_pipeline *pipeline,
nir_shader_gather_info(nir, nir_shader_get_entrypoint(nir));
if (!pdevice->vk.supported_features.shaderStorageImageReadWithoutFormat &&
anv_nir_has_formatless_image_read(nir)) {
return vk_errorf(pipeline, VK_ERROR_FEATURE_NOT_PRESENT,
"shader reads a storage image without a format, which "
"is not supported "
"(shaderStorageImageReadWithoutFormat)");
}
NIR_PASS(_, nir, elk_nir_lower_storage_image,
&(struct elk_nir_lower_storage_image_opts) {
.devinfo = compiler->devinfo,
@@ -579,6 +612,8 @@ anv_pipeline_lower_nir(struct anv_pipeline *pipeline,
}
stage->nir = nir;
return VK_SUCCESS;
}
static void
@@ -1303,7 +1338,12 @@ anv_graphics_pipeline_compile(struct anv_graphics_pipeline *pipeline,
void *stage_ctx = ralloc_context(NULL);
anv_pipeline_lower_nir(&pipeline->base, stage_ctx, &stages[s], layout);
result = anv_pipeline_lower_nir(&pipeline->base, stage_ctx,
&stages[s], layout);
if (result != VK_SUCCESS) {
ralloc_free(stage_ctx);
goto fail;
}
if (prev_stage && s < MESA_SHADER_FRAGMENT) {
prev_stage->nir->info.outputs_written |= stages[s].nir->info.inputs_read &
@@ -1499,7 +1539,12 @@ anv_pipeline_compile_cs(struct anv_compute_pipeline *pipeline,
return vk_error(pipeline, VK_ERROR_UNKNOWN);
}
VkResult result =
anv_pipeline_lower_nir(&pipeline->base, mem_ctx, &stage, layout);
if (result != VK_SUCCESS) {
ralloc_free(mem_ctx);
return result;
}
unsigned local_size = stage.nir->info.workgroup_size[0] *
stage.nir->info.workgroup_size[1] *