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]

Reply via email to