Commit ba178cb81f for ffmpeg

commit ba178cb81f360aeac7ae4b0e8c47132e7711cc1b
Author: Mark Thompson <sw@jkqxz.net>
Date:   Sun Oct 25 13:55:54 2026 +0000

    lavc/apv: Improve AVX2 transquant

    Replace the row matmul with a second butterfly step, but fuse it with
    parts of the transpose and rounding to reduce instructions.

    CPU: Intel(R) Xeon(R) Gold 6252 CPU @ 2.10GHz
      decode_transquant_10_c:       332.5
    Before:
      decode_transquant_10_avx2:     87.6 ( 3.80x)
    After:
      decode_transquant_10_avx2:     65.4 ( 5.08x)

diff --git a/libavcodec/x86/apv_dsp.asm b/libavcodec/x86/apv_dsp.asm
index 3ea28f62fd..78098b38de 100644
--- a/libavcodec/x86/apv_dsp.asm
+++ b/libavcodec/x86/apv_dsp.asm
@@ -22,30 +22,24 @@

 SECTION_RODATA 32

-; Full matrix for row transform.
-tmatrix_row:
-    dw  64,  89,  84,  75,  64,  50,  35,  18
-    dw  64, -18, -84,  50,  64, -75, -35,  89
-    dw  64,  75,  35, -18, -64, -89, -84, -50
-    dw  64, -50, -35,  89, -64, -18,  84, -75
-    dw  64,  50, -35, -89, -64,  18,  84,  75
-    dw  64, -75,  35,  18, -64,  89, -84,  50
-    dw  64,  18, -84, -50,  64,  75, -35, -89
-    dw  64, -89,  84, -75,  64, -50,  35, -18
-
-; Constant pairs for broadcast in column transform.
-tmatrix_col_even:
-    dw  64,  64,  64, -64
-    dw  84,  35,  35, -84
-tmatrix_col_odd:
-    dw  89,  75,  50,  18
-    dw  75, -18, -89, -50
-    dw  50, -89,  18,  75
-    dw  18, -50,  75, -89
-
-; Memory targets for vpbroadcastd (register version requires AVX512).
+; Constant pairs for the 1-D transform butterfly, expanded so that they
+; can be used directly as memory operands.
+tmatrix_even_a: times 8 dw  64,  64
+tmatrix_even_b: times 8 dw  64, -64
+tmatrix_even_c: times 8 dw  84,  35
+tmatrix_even_d: times 8 dw  35, -84
+tmatrix_odd_0a: times 8 dw  89,  50
+tmatrix_odd_0b: times 8 dw  75,  18
+tmatrix_odd_1a: times 8 dw  75, -89
+tmatrix_odd_1b: times 8 dw -18, -50
+tmatrix_odd_2a: times 8 dw  50,  18
+tmatrix_odd_2b: times 8 dw -89,  75
+tmatrix_odd_3a: times 8 dw  18,  75
+tmatrix_odd_3b: times 8 dw -50, -89
+
 cextern pd_1
 cextern pd_64
+vec_1_19: times 8 dd 1 << 19

 SECTION .text

@@ -58,11 +52,65 @@ SECTION .text

 INIT_YMM avx2

-cglobal apv_decode_transquant, 5, 7, 16, output, pitch, input, qmatrix, bit_depth, qp_shift, tmp
+; One pass of the 1-D DCT, as a butterfly.
+; 16-bit input rows in m12-m15 as pairs 04 26 15 37.
+; 32-bit output rows in m8-m15.
+; The rounding constant is already added to the output.
+
+%macro TRANSFORM_PASS 1 ; (rounding constant)
+    ; Even part, from rows 0, 2, 4 and 6.
+    vpmaddwd  m8,  m12, [tmatrix_even_a]
+    vpmaddwd  m9,  m12, [tmatrix_even_b]
+    vpmaddwd  m10, m13, [tmatrix_even_c]
+    vpmaddwd  m11, m13, [tmatrix_even_d]
+    vpaddd    m8,  m8,  %1
+    vpaddd    m9,  m9,  %1
+    vpaddd    m0,  m8,  m10
+    vpaddd    m1,  m9,  m11
+    vpsubd    m2,  m9,  m11
+    vpsubd    m3,  m8,  m10
+
+    ; Odd part, from rows 1, 3, 5 and 7.
+    vpmaddwd  m8,  m14, [tmatrix_odd_0a]
+    vpmaddwd  m9,  m15, [tmatrix_odd_0b]
+    vpmaddwd  m10, m14, [tmatrix_odd_1a]
+    vpmaddwd  m11, m15, [tmatrix_odd_1b]
+    vpaddd    m4,  m8,  m9
+    vpaddd    m5,  m10, m11
+    vpmaddwd  m8,  m14, [tmatrix_odd_2a]
+    vpmaddwd  m9,  m15, [tmatrix_odd_2b]
+    vpmaddwd  m10, m14, [tmatrix_odd_3a]
+    vpmaddwd  m11, m15, [tmatrix_odd_3b]
+    vpaddd    m6,  m8,  m9
+    vpaddd    m7,  m10, m11
+
+    ; Combine.
+    vpaddd    m8,  m0,  m4
+    vpaddd    m9,  m1,  m5
+    vpaddd    m10, m2,  m6
+    vpaddd    m11, m3,  m7
+    vpsubd    m12, m3,  m7
+    vpsubd    m13, m2,  m6
+    vpsubd    m14, m1,  m5
+    vpsubd    m15, m0,  m4
+%endmacro
+
+cglobal apv_decode_transquant, 5, 7, 16, 32, output, pitch, input, qmatrix, bit_depth, qp_shift, tmp
+
+    ; Building rounding constant to for the final normalisation and
+    ; store it on the stack for use later.
+
+    mova      m0,  [pd_1]
+    mov       tmpd, 19
+    sub       tmpd, bit_depthd
+    movd      xm1, tmpd
+    vpslld    m0,  m0,  xm1
+    vpaddd    m0,  m0,  [vec_1_19]
+    mova      [rsp], m0

     ; Load input and dequantise

-    vpbroadcastd  m10, [pd_1]
+    mova      m10, [pd_1]
     lea       tmpd, [bit_depthd - 2]
     movd      xm8, qp_shiftm
     movd      xm9, tmpd
@@ -74,7 +122,7 @@ cglobal apv_decode_transquant, 5, 7, 16, output, pitch, input, qmatrix, bit_dept
     ; m10 = vector 1 << (bd_shift - 1)
     ; m11 = qmatrix load

-%macro LOAD_AND_DEQUANT 2 ; (xmm input, constant offset)
+%macro LOAD_AND_DEQUANT 2 ; (register, constant offset)
     vpmovsxwd m%1, [inputq   + %2]
     vpmovsxwd m11, [qmatrixq + %2]
     vpmaddwd  m%1, m%1, m11
@@ -94,164 +142,125 @@ cglobal apv_decode_transquant, 5, 7, 16, output, pitch, input, qmatrix, bit_dept
     LOAD_AND_DEQUANT 7, 0x70

     ; mN = row N words 0 1 2 3 0 1 2 3 4 5 6 7 4 5 6 7
+    ; Interleave pairs of rows for the butterfly input.

-    ; Transform columns
-    ; This applies a 1-D DCT butterfly
-
-    vpunpcklwd  m12, m0,  m4
-    vpunpcklwd  m13, m2,  m6
-    vpunpcklwd  m14, m1,  m3
-    vpunpcklwd  m15, m5,  m7
-
-    ; m12 = rows 0 and 4 interleaved
-    ; m13 = rows 2 and 6 interleaved
-    ; m14 = rows 1 and 3 interleaved
-    ; m15 = rows 5 and 7 interleaved
-
-    lea         tmpq, [tmatrix_col_even]
-    vpbroadcastd   m0, [tmpq + 0x00]
-    vpbroadcastd   m1, [tmpq + 0x04]
-    vpbroadcastd   m2, [tmpq + 0x08]
-    vpbroadcastd   m3, [tmpq + 0x0c]
-
-    vpmaddwd  m4,  m12, m0
-    vpmaddwd  m5,  m12, m1
-    vpmaddwd  m6,  m13, m2
-    vpmaddwd  m7,  m13, m3
-    vpaddd    m8,  m4,  m6
-    vpaddd    m9,  m5,  m7
-    vpsubd    m10, m5,  m7
-    vpsubd    m11, m4,  m6
-
-    lea         tmpq, [tmatrix_col_odd]
-    vpbroadcastd   m0, [tmpq + 0x00]
-    vpbroadcastd   m1, [tmpq + 0x04]
-    vpbroadcastd   m2, [tmpq + 0x08]
-    vpbroadcastd   m3, [tmpq + 0x0c]
-
-    vpmaddwd  m4,  m14, m0
-    vpmaddwd  m5,  m15, m1
-    vpmaddwd  m6,  m14, m2
-    vpmaddwd  m7,  m15, m3
-    vpaddd    m12, m4,  m5
-    vpaddd    m13, m6,  m7
-
-    vpbroadcastd   m0, [tmpq + 0x10]
-    vpbroadcastd   m1, [tmpq + 0x14]
-    vpbroadcastd   m2, [tmpq + 0x18]
-    vpbroadcastd   m3, [tmpq + 0x1c]
-
-    vpmaddwd  m4,  m14, m0
-    vpmaddwd  m5,  m15, m1
-    vpmaddwd  m6,  m14, m2
-    vpmaddwd  m7,  m15, m3
-    vpaddd    m14, m4,  m5
-    vpaddd    m15, m6,  m7
-
-    vpaddd    m0,  m8,  m12
-    vpaddd    m1,  m9,  m13
-    vpaddd    m2,  m10, m14
-    vpaddd    m3,  m11, m15
-    vpsubd    m4,  m11, m15
-    vpsubd    m5,  m10, m14
-    vpsubd    m6,  m9,  m13
-    vpsubd    m7,  m8,  m12
-
-    ; Mid-transform normalisation
-    ; Note that outputs here are fitted to 16 bits
-
-    vpbroadcastd  m8, [pd_64]
-
-%macro NORMALISE 1
-    vpaddd    m%1, m%1, m8
-    vpsrad    m%1, m%1, 7
-    vpackssdw m%1, m%1, m%1
-    vpermq    m%1, m%1, q3120
-%endmacro
+    vpunpcklwd m12, m0,  m4
+    vpunpcklwd m13, m2,  m6
+    vpunpcklwd m14, m1,  m5
+    vpunpcklwd m15, m3,  m7

-    NORMALISE 0
-    NORMALISE 1
-    NORMALISE 2
-    NORMALISE 3
-    NORMALISE 4
-    NORMALISE 5
-    NORMALISE 6
-    NORMALISE 7
-
-    ; mN = row N words 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7
-
-    ; Transform rows
-    ; This multiplies the rows directly by the transform matrix,
-    ; avoiding the need to transpose anything
-
-    lea       tmpq, [tmatrix_row]
-    mova      m12, [tmpq + 0x00]
-    mova      m13, [tmpq + 0x20]
-    mova      m14, [tmpq + 0x40]
-    mova      m15, [tmpq + 0x60]
-
-%macro TRANS_ROW_STEP 1
-    vpmaddwd  m8,  m%1, m12
-    vpmaddwd  m9,  m%1, m13
-    vpmaddwd  m10, m%1, m14
-    vpmaddwd  m11, m%1, m15
-    vphaddd   m8,  m8,  m9
-    vphaddd   m10, m10, m11
-    vphaddd   m%1, m8,  m10
-%endmacro
+    ; Transform columns.

-    TRANS_ROW_STEP 0
-    TRANS_ROW_STEP 1
-    TRANS_ROW_STEP 2
-    TRANS_ROW_STEP 3
-    TRANS_ROW_STEP 4
-    TRANS_ROW_STEP 5
-    TRANS_ROW_STEP 6
-    TRANS_ROW_STEP 7
+    TRANSFORM_PASS [pd_64]

-    ; Renormalise, clip and store output
+    ; Mid-transform normalisation.  The rounding constant was already
+    ; added by the transform pass; outputs here are fitted to 16 bits.

-    vpbroadcastd  m14, [pd_1]
-    mov       tmpd, 20
-    sub       tmpd, bit_depthd
-    movd      xm9, tmpd
-    dec       tmpd
-    movd      xm13, tmpd
-    movd      xm15, bit_depthd
-    vpslld    m8,  m14, xm13
-    vpslld    m12, m14, xm15
-    vpsrld    m10, m12, 1
-    vpsubd    m12, m12, m14
-
-    ; m8  = vector 1 << (bd_shift - 1)
-    ; m9  = scalar bd_shift
-    ; m10 = vector 1 << (bit_depth - 1)
-    ; m12 = vector (1 << bit_depth) - 1
+    vpsrad    m8,  m8,  7
+    vpsrad    m9,  m9,  7
+    vpsrad    m10, m10, 7
+    vpsrad    m11, m11, 7
+    vpsrad    m12, m12, 7
+    vpsrad    m13, m13, 7
+    vpsrad    m14, m14, 7
+    vpsrad    m15, m15, 7

-%macro NORMALISE_AND_STORE_10 2
-    vpaddd    m%1, m%1, m8
-    vpaddd    m%2, m%2, m8
-    vpsrad    m%1, m%1, xm9
-    vpsrad    m%2, m%2, xm9
-    vpaddd    m%1, m%1, m10
-    vpaddd    m%2, m%2, m10
-    vpminsd   m%1, m%1, m12
-    vpminsd   m%2, m%2, m12
-    ; m%1 = A0-3 A4-7
-    ; m%2 = B0-3 B4-7
-    vpackusdw m%1, m%1, m%2
-    ; m%1 = A0-3 B0-3 A4-7 B4-7
-    vpermq    m%1, m%1, q3120
-    ; m%1 = A0-3 A4-7 B0-3 B4-7
-    mova      [outputq], xm%1
-    vextracti128  [outputq + pitchq], m%1, 1
-    lea       outputq, [outputq + 2*pitchq]
-%endmacro
+    ; Transpose, recombining into the paired rows for the butterfly.
+
+    vpackssdw m0,  m8,  m9
+    vpackssdw m1,  m10, m11
+    vpackssdw m2,  m12, m13
+    vpackssdw m3,  m14, m15
+
+    vperm2i128 m4, m0, m2, 0x20
+    vperm2i128 m5, m1, m3, 0x20
+    vperm2i128 m6, m0, m2, 0x31
+    vperm2i128 m7, m1, m3, 0x31
+
+    vpslld    m8,  m6,  16
+    vpslld    m9,  m7,  16
+    vpsrld    m10, m4,  16
+    vpsrld    m11, m5,  16
+    vpblendw  m8,  m4,  m8,  0xaa
+    vpblendw  m9,  m5,  m9,  0xaa
+    vpblendw  m10, m10, m6,  0xaa
+    vpblendw  m11, m11, m7,  0xaa

-    NORMALISE_AND_STORE_10 0, 1
-    NORMALISE_AND_STORE_10 2, 3
-    NORMALISE_AND_STORE_10 4, 5
-    NORMALISE_AND_STORE_10 6, 7
+    vshufps   m12, m8,  m9,  q2020
+    vshufps   m13, m8,  m9,  q3131
+    vshufps   m14, m10, m11, q2020
+    vshufps   m15, m10, m11, q3131
+
+    ; Transform rows.
+
+    TRANSFORM_PASS [rsp]
+
+    ; Renormalise, clip and store output.  The rounding constant was
+    ; already added by the transform pass, and here we split the shift
+    ; on either side of the pack (20 - bit_depth -> 4 and 16 - bit_depth)
+    ; so that the saturation precisely captures the clip we want.
+
+    mov       tmpd, 16
+    sub       tmpd, bit_depthd
+    movd      xm0, tmpd
+
+    vpsrad    m8,  m8,  4
+    vpsrad    m9,  m9,  4
+    vpsrad    m10, m10, 4
+    vpsrad    m11, m11, 4
+    vpsrad    m12, m12, 4
+    vpsrad    m13, m13, 4
+    vpsrad    m14, m14, 4
+    vpsrad    m15, m15, 4
+
+    vpackusdw m3,  m8,  m12
+    vpackusdw m4,  m9,  m13
+    vpackusdw m5,  m10, m14
+    vpackusdw m6,  m11, m15
+
+    vpsrlw    m3,  m3,  xm0
+    vpsrlw    m4,  m4,  xm0
+    vpsrlw    m5,  m5,  xm0
+    vpsrlw    m6,  m6,  xm0
+
+    ; Transpose back for output.
+
+    vpunpcklwd m7,  m3, m4
+    vpunpckhwd m8,  m3, m4
+    vpunpcklwd m9,  m5, m6
+    vpunpckhwd m10, m5, m6
+
+    vpunpckldq m11, m7, m9
+    vpunpckhdq m12, m7, m9
+    vpunpckldq m13, m8, m10
+    vpunpckhdq m14, m8, m10
+
+    vpunpcklqdq m0, m11, m13
+    vpunpckhqdq m1, m11, m13
+    vpunpcklqdq m2, m12, m14
+    vpunpckhqdq m3, m12, m14
+
+    ; mN = rows N and N+4
+
+    ; Indexing from outputq reaches rows 0, 1, 2 and 4; indexing from a
+    ; second base at row 7 with the pitch negated reaches rows 7, 6, 5
+    ; and 3.  The negation means every store relative to outputq has to
+    ; come first.
+
+    lea       tmpq, [outputq + 8*pitchq]
+    sub       tmpq, pitchq
+
+    mova          [outputq],              xm0     ; row 0
+    mova          [outputq +   pitchq],   xm1     ; row 1
+    mova          [outputq + 2*pitchq],   xm2     ; row 2
+    vextracti128  [outputq + 4*pitchq],   m0, 1   ; row 4
+
+    neg       pitchq
+
+    mova          [tmpq    + 4*pitchq],   xm3     ; row 3
+    vextracti128  [tmpq    + 2*pitchq],   m1, 1   ; row 5
+    vextracti128  [tmpq    +   pitchq],   m2, 1   ; row 6
+    vextracti128  [tmpq],                 m3, 1   ; row 7

     RET