This is an automated email from the git hooks/post-receive script. Git pushed a commit to branch master in repository ffmpeg.
commit 1c03b758a3cae8222c29fff7ae6e6c6fe241ffc8 Author: Niklas Haas <[email protected]> AuthorDate: Wed Oct 21 01:35:11 2026 +0200 Commit: Niklas Haas <[email protected]> CommitDate: Tue Oct 27 18:53:16 2026 +0000 swscale/uops: add SWS_UOP_FLAG_PUNNING The current CPU-based backends don't suffer any penalty or consequence of intermixing integers and float operations on the same registers. However, this is not a universal assumption - in particular, SPIR-V expects fully typed operations. In theory, older x86 CPUs also have a penalty for switching from float to int, but ENOCARE. Signed-off-by: Niklas Haas <[email protected]> --- libswscale/aarch64/ops.c | 4 +++- libswscale/tests/sws_ops.c | 3 ++- libswscale/tests/sws_ops_aarch64.c | 4 +++- libswscale/uops.c | 18 +++++++++++------- libswscale/uops.h | 1 + libswscale/uops_backend.c | 3 ++- libswscale/uops_macros_gen.c | 2 +- libswscale/x86/ops.c | 3 ++- 8 files changed, 25 insertions(+), 13 deletions(-) diff --git a/libswscale/aarch64/ops.c b/libswscale/aarch64/ops.c index 963bfec730..6bfe1824e9 100644 --- a/libswscale/aarch64/ops.c +++ b/libswscale/aarch64/ops.c @@ -225,7 +225,9 @@ static int aarch64_compile(SwsContext *ctx, const SwsOpList *ops, if (!uops) return AVERROR(ENOMEM); - const SwsUOpFlags flags = (ctx->flags & SWS_BITEXACT) ? 0 : SWS_UOP_FLAG_FMA; + SwsUOpFlags flags = SWS_UOP_FLAG_PUNNING; + if (!(ctx->flags & SWS_BITEXACT)) + flags |= SWS_UOP_FLAG_FMA; int ret = ff_sws_ops_translate(ctx, ops, flags, uops); if (ret < 0) goto error; diff --git a/libswscale/tests/sws_ops.c b/libswscale/tests/sws_ops.c index b2ca5ec41e..fa1f292ce4 100644 --- a/libswscale/tests/sws_ops.c +++ b/libswscale/tests/sws_ops.c @@ -41,7 +41,8 @@ static int print_ops(SwsContext *ctx, const SwsOpList *ops, SwsCompiledOp *out) const SwsUOpFlags flags = SWS_UOP_FLAG_EXPAND_BIT | SWS_UOP_FLAG_READ_PALETTE - | SWS_UOP_FLAG_ADD; + | SWS_UOP_FLAG_ADD + | SWS_UOP_FLAG_PUNNING; int ret = ff_sws_ops_translate(ctx, ops, flags, uops); if (ret == AVERROR(ENOTSUP)) goto fail; diff --git a/libswscale/tests/sws_ops_aarch64.c b/libswscale/tests/sws_ops_aarch64.c index 05eba0f0bb..3a56d71f59 100644 --- a/libswscale/tests/sws_ops_aarch64.c +++ b/libswscale/tests/sws_ops_aarch64.c @@ -201,7 +201,9 @@ static int collect_ops_compile(SwsContext *ctx, const SwsOpList *ops, if (!uops) return AVERROR(ENOMEM); - const SwsUOpFlags flags = (ctx->flags & SWS_BITEXACT) ? 0 : SWS_UOP_FLAG_FMA; + SwsUOpFlags flags = SWS_UOP_FLAG_PUNNING; + if (!(ctx->flags & SWS_BITEXACT)) + flags |= SWS_UOP_FLAG_FMA; ret = ff_sws_ops_translate(ctx, ops, flags, uops); if (ret == AVERROR(ENOTSUP)) { ret = 0; diff --git a/libswscale/uops.c b/libswscale/uops.c index 6f8b276d33..e55102abc6 100644 --- a/libswscale/uops.c +++ b/libswscale/uops.c @@ -206,8 +206,12 @@ int ff_sws_dither_height(const SwsDitherUOp *dither) return (1 << dither->size_log2) + max_offset; } -static SwsPixelType pixel_type_to_int(const SwsPixelType type) +/* Conditionally promotes a pixel type to integer only if allowed by the flags */ +static SwsPixelType pixel_type_to_int(SwsUOpFlags flags, const SwsPixelType type) { + if (!(flags & SWS_UOP_FLAG_PUNNING)) + return type; + switch (ff_sws_pixel_type_size(type)) { case 1: return SWS_PIXEL_U8; case 2: return SWS_PIXEL_U16; @@ -274,7 +278,7 @@ static int translate_rw_op(SwsContext *ctx, SwsUOpList *ops, SwsUOpFlags flags, /* Non-filtered reads don't care about the exact pixel contents */ if (!op->rw.filter.op) - uop.type = pixel_type_to_int(op->rw.type); + uop.type = pixel_type_to_int(flags, op->rw.type); const bool is_read = op->op == SWS_OP_READ; if (op->rw.filter.op) { @@ -327,11 +331,11 @@ static int count_idx(const int *arr, size_t size, int val) return num; } -static int translate_swizzle(SwsUOpList *ops, const SwsOp *op) +static int translate_swizzle(SwsUOpList *ops, SwsUOpFlags flags, const SwsOp *op) { SwsUOp uop = { .uop = SWS_UOP_PERMUTE, - .type = pixel_type_to_int(ff_sws_op_input_type(op)), + .type = pixel_type_to_int(flags, ff_sws_op_input_type(op)), .mask = ff_sws_comp_mask_needed(op), }; SwsMoveUOp *par = &uop.par.move; @@ -524,7 +528,7 @@ static int translate_op(SwsContext *ctx, SwsUOpList *uops, SwsUOpFlags flags, case SWS_OP_WRITE: return translate_rw_op(ctx, uops, flags, op); case SWS_OP_SWIZZLE: - return translate_swizzle(uops, op); + return translate_swizzle(uops, flags, op); case SWS_OP_DITHER: return translate_dither_op(uops, flags, op); case SWS_OP_LINEAR: @@ -573,7 +577,7 @@ static int translate_op(SwsContext *ctx, SwsUOpList *uops, SwsUOpFlags flags, const AVRational64 v = op->clear.value[i]; const SwsPixelType type = op->clear.type[i]; const SwsPixel px = ff_sws_pixel_from_q64(type, v); - uop.type = pixel_type_to_int(type); + uop.type = pixel_type_to_int(flags, type); uop.data.vec4[i] = px; if (v.num == 0) uop.par.clear.zero |= SWS_COMP(i); @@ -596,7 +600,7 @@ static int translate_op(SwsContext *ctx, SwsUOpList *uops, SwsUOpFlags flags, break; case SWS_OP_SWAP_BYTES: uop.uop = SWS_UOP_SWAP_BYTES; - uop.type = pixel_type_to_int(uop.type); + uop.type = pixel_type_to_int(flags, uop.type); break; case SWS_OP_LUT_3D: uop.uop = SWS_UOP_LUT_3D; diff --git a/libswscale/uops.h b/libswscale/uops.h index 8660de3c41..a70a6ac460 100644 --- a/libswscale/uops.h +++ b/libswscale/uops.h @@ -152,6 +152,7 @@ typedef enum SwsUOpFlagBits { SWS_UOP_FLAG_EXPAND_BIT = (1 << 2), /* backend implements SWS_UOP_EXPAND_BIT */ SWS_UOP_FLAG_READ_PALETTE = (1 << 3), /* backend implements SWS_UOP_READ_PALETTE */ SWS_UOP_FLAG_ADD = (1 << 4), /* backend implements SWS_UOP_ADD */ + SWS_UOP_FLAG_PUNNING = (1 << 5), /* allow type punning float data as int */ } SwsUOpFlagBits; typedef enum SwsUOpType { diff --git a/libswscale/uops_backend.c b/libswscale/uops_backend.c index 5dfb829b4e..aa8b4dd0b4 100644 --- a/libswscale/uops_backend.c +++ b/libswscale/uops_backend.c @@ -187,7 +187,8 @@ static int compile_c(SwsContext *ctx, const SwsOpList *ops, SwsCompiledOp *out) const SwsUOpFlags flags = SWS_UOP_FLAG_EXPAND_BIT | SWS_UOP_FLAG_READ_PALETTE - | SWS_UOP_FLAG_ADD; + | SWS_UOP_FLAG_ADD + | SWS_UOP_FLAG_PUNNING; int ret = ff_sws_ops_translate(ctx, ops, flags, uops); if (ret < 0) goto fail; diff --git a/libswscale/uops_macros_gen.c b/libswscale/uops_macros_gen.c index 4da20af67c..2af7e6fd98 100644 --- a/libswscale/uops_macros_gen.c +++ b/libswscale/uops_macros_gen.c @@ -217,7 +217,7 @@ fail: enum { COMMON_FLAGS = SWS_UOP_FLAG_EXPAND_BIT | SWS_UOP_FLAG_READ_PALETTE | - SWS_UOP_FLAG_ADD, + SWS_UOP_FLAG_ADD | SWS_UOP_FLAG_PUNNING, }; typedef struct Backend { diff --git a/libswscale/x86/ops.c b/libswscale/x86/ops.c index 7985b7a026..6337711b33 100644 --- a/libswscale/x86/ops.c +++ b/libswscale/x86/ops.c @@ -726,7 +726,8 @@ static int compile_x86(SwsContext *ctx, const SwsOpList *ops, SwsCompiledOp *out SwsUOpFlags flags = SWS_UOP_FLAG_PSHUFB | SWS_UOP_FLAG_EXPAND_BIT | SWS_UOP_FLAG_READ_PALETTE - | SWS_UOP_FLAG_ADD; + | SWS_UOP_FLAG_ADD + | SWS_UOP_FLAG_PUNNING; if (EXTERNAL_FMA3(cpu_flags)) flags |= SWS_UOP_FLAG_FMA; -- To stop receiving notification emails like this one, please contact [email protected]. _______________________________________________ ffmpeg-cvslog mailing list -- [email protected] To unsubscribe send an email to [email protected]
