PR #25215 opened by Ramiro Polla (ramiro) URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/25215 Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/25215.patch
I know little about Vulkan so I asked AI to do it. My goal is to improve `libswscale/tests/swscale` but these issues got in the way. @Lynne please review. >From 30dcc3595f873c1bad1f85dab2b8c7aa526abcb8 Mon Sep 17 00:00:00 2001 From: Ramiro Polla <[email protected]> Date: Mon, 19 Oct 2026 14:04:29 +0200 Subject: [PATCH 1/3] swscale/vulkan/ops: initialize unused float lanes to zero The working vector and the unused lanes of planar float reads were filled with OpUndef. Linear ops consume the full vector, and an undefined float is not guaranteed to be finite, so a zero matrix coefficient does not reliably cancel its contribution. This made float input conversions such as gbrpf32le -> yuv444p fail on some drivers (NVIDIA). Use a 0.0 constant instead. Co-Authored-By: Claude Opus 5.5 <[email protected]> --- libswscale/vulkan/ops.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libswscale/vulkan/ops.c b/libswscale/vulkan/ops.c index 68750dc3bb..a9e45bb116 100644 --- a/libswscale/vulkan/ops.c +++ b/libswscale/vulkan/ops.c @@ -506,7 +506,7 @@ static void define_shader_consts(SwsContext *sws, const SwsOpList *ops, /* Constants */ id->u32_p = spi_OpUndef(spi, u32_type); - id->f32_p = spi_OpUndef(spi, f32_type); + id->f32_p = spi_OpConstantFloat(spi, f32_type, 0); id->f32_0 = spi_OpConstantFloat(spi, f32_type, 0); for (int i = 0; i < 5; i++) id->u32_cid[i] = spi_OpConstantUInt(spi, u32_type, i); -- 2.54.0 >From 4f4000f30d0e95adfe70ca618c1cd2fcea43dd2e Mon Sep 17 00:00:00 2001 From: Ramiro Polla <[email protected]> Date: Mon, 19 Oct 2026 14:04:29 +0200 Subject: [PATCH 2/3] tests/fate/libswscale: enable spirv backend tests Co-Authored-By: Claude Opus 5.5 <[email protected]> --- tests/fate/libswscale.mak | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tests/fate/libswscale.mak b/tests/fate/libswscale.mak index cba28068ed..7357a7d0f4 100644 --- a/tests/fate/libswscale.mak +++ b/tests/fate/libswscale.mak @@ -54,9 +54,8 @@ endif ifeq ($(ARCH_AARCH64),yes) SWS_UNSTABLE_BACKENDS-$(HAVE_NEON) += aarch64 endif -# TODO: enable spirv tests once they pass on all Vulkan devices. -# SWS_UNSTABLE_BACKENDS-$(HAVE_SPIRV_HEADERS_SPIRV_H) += spirv -# SWS_UNSTABLE_BACKENDS-$(HAVE_SPIRV_UNIFIED1_SPIRV_H) += spirv +SWS_UNSTABLE_BACKENDS-$(HAVE_SPIRV_HEADERS_SPIRV_H) += spirv +SWS_UNSTABLE_BACKENDS-$(HAVE_SPIRV_UNIFIED1_SPIRV_H) += spirv # Set -hw default for Vulkan tests. fate-sws-unscaled-spirv fate-sws-unstable-spirv: SWS_HW = -hw default -- 2.54.0 >From a62ed056d024d41cc5b2e62f26bd2c98c5e1e3eb Mon Sep 17 00:00:00 2001 From: Ramiro Polla <[email protected]> Date: Mon, 19 Oct 2026 14:14:12 +0200 Subject: [PATCH 3/3] swscale: gate Vulkan support on the SPIR-V backend being available If Vulkan was enabled but no SPIR-V headers were found, the Vulkan code in swscale was still compiled, but no backend was exported. Vulkan frames were still reported as supported by sws_test_hw_format(). Add a swscale_vulkan configure symbol, enabled when Vulkan and either SPIR-V header are available, and use it for all Vulkan code in swscale and for the spirv FATE tests. Co-Authored-By: Claude Opus 5.5 <[email protected]> --- configure | 3 +++ libswscale/format.c | 2 +- libswscale/graph.c | 8 ++++---- libswscale/ops.c | 4 ++-- libswscale/swscale.c | 4 ++-- libswscale/utils.c | 2 +- libswscale/vulkan/Makefile | 2 +- libswscale/vulkan/ops.c | 9 --------- tests/fate/libswscale.mak | 3 +-- 9 files changed, 15 insertions(+), 22 deletions(-) diff --git a/configure b/configure index d2a69d7783..7b0f157b8e 100755 --- a/configure +++ b/configure @@ -2794,6 +2794,7 @@ CONFIG_EXTRA=" snappy srtp startcode + swscale_vulkan texturedsp texturedspenc tpeldsp @@ -3363,6 +3364,8 @@ vulkan_deps="threads" vulkan_deps_any="libdl LoadLibrary" spirv_headers_spirv_h_deps="vulkan" spirv_unified1_spirv_h_deps="vulkan" +swscale_vulkan_deps="vulkan" +swscale_vulkan_if_any="spirv_headers_spirv_h spirv_unified1_spirv_h" apv_vulkan_hwaccel_deps="vulkan spirv_compiler" apv_vulkan_hwaccel_select="apv_decoder" diff --git a/libswscale/format.c b/libswscale/format.c index f8c6462982..59b0ec1afd 100644 --- a/libswscale/format.c +++ b/libswscale/format.c @@ -643,7 +643,7 @@ int sws_test_hw_format(enum AVPixelFormat format) { switch (format) { case AV_PIX_FMT_NONE: return 1; -#if CONFIG_VULKAN +#if CONFIG_SWSCALE_VULKAN case AV_PIX_FMT_VULKAN: return 1; #endif default: return 0; diff --git a/libswscale/graph.c b/libswscale/graph.c index 5a5d469a51..664dd1c1c3 100644 --- a/libswscale/graph.c +++ b/libswscale/graph.c @@ -39,7 +39,7 @@ #include "graph.h" #include "ops.h" #include "ops_dispatch.h" -#if CONFIG_VULKAN +#if CONFIG_SWSCALE_VULKAN #include "vulkan/ops.h" #endif @@ -102,7 +102,7 @@ static int frame_alloc_planes_ref(AVFrame *dst, const AVFrame *src, return 0; } -#if CONFIG_VULKAN +#if CONFIG_SWSCALE_VULKAN static int pass_alloc_output_hw(SwsPass *pass, AVFrame *avframe, AVBufferRef *dev_ref) { @@ -141,7 +141,7 @@ static int pass_alloc_output(SwsPass *pass) int ret; -#if CONFIG_VULKAN +#if CONFIG_SWSCALE_VULKAN const SwsGraph *graph = pass->graph; if (graph->src.hw_format == AV_PIX_FMT_VULKAN && graph->dst.hw_format == AV_PIX_FMT_VULKAN) { @@ -166,7 +166,7 @@ static int pass_alloc_output(SwsPass *pass) return ret; } -#if CONFIG_VULKAN +#if CONFIG_SWSCALE_VULKAN done: #endif buffer->avframe = avframe; diff --git a/libswscale/ops.c b/libswscale/ops.c index c07261c61e..59e874bec8 100644 --- a/libswscale/ops.c +++ b/libswscale/ops.c @@ -35,7 +35,7 @@ extern const SwsOpBackend backend_c; extern const SwsOpBackend backend_murder; extern const SwsOpBackend backend_aarch64; extern const SwsOpBackend backend_x86; -#if HAVE_SPIRV_HEADERS_SPIRV_H || HAVE_SPIRV_UNIFIED1_SPIRV_H +#if CONFIG_SWSCALE_VULKAN extern const SwsOpBackend backend_spirv; #endif @@ -47,7 +47,7 @@ const SwsOpBackend * const ff_sws_op_backends[] = { &backend_x86, #endif &backend_c, -#if HAVE_SPIRV_HEADERS_SPIRV_H || HAVE_SPIRV_UNIFIED1_SPIRV_H +#if CONFIG_SWSCALE_VULKAN &backend_spirv, #endif NULL diff --git a/libswscale/swscale.c b/libswscale/swscale.c index 070b0f5939..80b30bcf69 100644 --- a/libswscale/swscale.c +++ b/libswscale/swscale.c @@ -35,7 +35,7 @@ #include "config.h" #include "swscale_internal.h" #include "swscale.h" -#if CONFIG_VULKAN +#if CONFIG_SWSCALE_VULKAN #include "vulkan/ops.h" #endif @@ -1542,7 +1542,7 @@ int sws_frame_setup(SwsContext *ctx, const AVFrame *dst, const AVFrame *src) if (dev_ctx->type != AV_HWDEVICE_TYPE_VULKAN) return AVERROR(ENOTSUP); -#if CONFIG_UNSTABLE && CONFIG_VULKAN +#if CONFIG_UNSTABLE && CONFIG_SWSCALE_VULKAN ret = ff_sws_vk_init(ctx, src_hwfc->device_ref); if (ret < 0) return ret; diff --git a/libswscale/utils.c b/libswscale/utils.c index 138c1a4edd..e970b9f035 100644 --- a/libswscale/utils.c +++ b/libswscale/utils.c @@ -52,7 +52,7 @@ #include "graph.h" #include "jit.h" -#if CONFIG_VULKAN +#if CONFIG_SWSCALE_VULKAN #include "vulkan/ops.h" #endif diff --git a/libswscale/vulkan/Makefile b/libswscale/vulkan/Makefile index 396cdeb936..c3eef141cb 100644 --- a/libswscale/vulkan/Makefile +++ b/libswscale/vulkan/Makefile @@ -1,4 +1,4 @@ clean:: $(RM) $(CLEANSUFFIXES:%=libswscale/vulkan/%) -OBJS-$(CONFIG_VULKAN) += vulkan/ops.o vulkan/vulkan.o +OBJS-$(CONFIG_SWSCALE_VULKAN) += vulkan/ops.o vulkan/vulkan.o diff --git a/libswscale/vulkan/ops.c b/libswscale/vulkan/ops.c index a9e45bb116..3f8c34ecda 100644 --- a/libswscale/vulkan/ops.c +++ b/libswscale/vulkan/ops.c @@ -27,9 +27,7 @@ #include "ops.h" -#if HAVE_SPIRV_HEADERS_SPIRV_H || HAVE_SPIRV_UNIFIED1_SPIRV_H #include "spvasm.h" -#endif static void ff_sws_vk_uninit(AVRefStructOpaque opaque, void *obj) { @@ -278,7 +276,6 @@ fail: return err; } -#if HAVE_SPIRV_HEADERS_SPIRV_H || HAVE_SPIRV_UNIFIED1_SPIRV_H struct DitherData { int size; int arr_1d_id; @@ -1276,7 +1273,6 @@ static int add_ops_spirv(SwsContext *sws, VulkanPriv *p, FFVulkanOpsCtx *s, return ff_vk_shader_link(&s->vkctx, shd, spvbuf, len, "main"); } -#endif static int compile(SwsContext *sws, const SwsOpList *ops, SwsCompiledOp *out) { @@ -1296,10 +1292,7 @@ static int compile(SwsContext *sws, const SwsOpList *ops, SwsCompiledOp *out) if (err < 0) goto fail; - err = AVERROR(ENOTSUP); -#if HAVE_SPIRV_HEADERS_SPIRV_H || HAVE_SPIRV_UNIFIED1_SPIRV_H err = add_ops_spirv(sws, p, s, ops, &p->shd); -#endif if (err < 0) goto fail; @@ -1326,7 +1319,6 @@ fail: return err; } -#if HAVE_SPIRV_HEADERS_SPIRV_H || HAVE_SPIRV_UNIFIED1_SPIRV_H static int compile_spirv(SwsContext *sws, const SwsOpList *ops, SwsCompiledOp *out) { @@ -1339,4 +1331,3 @@ const SwsOpBackend backend_spirv = { .compile = compile_spirv, .hw_format = AV_PIX_FMT_VULKAN, }; -#endif diff --git a/tests/fate/libswscale.mak b/tests/fate/libswscale.mak index 7357a7d0f4..42501feca6 100644 --- a/tests/fate/libswscale.mak +++ b/tests/fate/libswscale.mak @@ -54,8 +54,7 @@ endif ifeq ($(ARCH_AARCH64),yes) SWS_UNSTABLE_BACKENDS-$(HAVE_NEON) += aarch64 endif -SWS_UNSTABLE_BACKENDS-$(HAVE_SPIRV_HEADERS_SPIRV_H) += spirv -SWS_UNSTABLE_BACKENDS-$(HAVE_SPIRV_UNIFIED1_SPIRV_H) += spirv +SWS_UNSTABLE_BACKENDS-$(CONFIG_SWSCALE_VULKAN) += spirv # Set -hw default for Vulkan tests. fate-sws-unscaled-spirv fate-sws-unstable-spirv: SWS_HW = -hw default -- 2.54.0 _______________________________________________ ffmpeg-devel mailing list -- [email protected] To unsubscribe send an email to [email protected]
