This is an automated email from the git hooks/post-receive script.

Git pushed a commit to branch master
in repository ffmpeg.

commit 1b5041c785f1e735e14ef2db2c98a786ef180954
Author:     Lynne <[email protected]>
AuthorDate: Wed Sep 9 01:09:50 2026 +0900
Commit:     Lynne <[email protected]>
CommitDate: Sun Sep 20 17:19:28 2026 +0900

    vulkan: keep the iDCT scale factors separable
    
    The 8x8 scale table was 64 specialization constants indexed per
    coefficient. The index is divergent, so nothing folds and every
    coefficient costs a load from the constant-data segment.
    
    The table is an outer product, s[y]*s[x], so pass the eight 1D factors
    instead: the x factor hoists out of the coefficient loop and the y
    factor folds once the loop is unrolled. ProRes RAW's gain of 8 becomes
    a literal in its shader.
    
    Reassociation moves a few samples in ten thousand by an LSB or so,
    well below the existing float iDCT error; PSNR versus software is
    unchanged.
---
 libavcodec/vulkan/apv_idct.comp.glsl        |  7 +++++--
 libavcodec/vulkan/dct.glsl                  | 16 ++++------------
 libavcodec/vulkan/prores_idct.comp.glsl     |  7 +++++--
 libavcodec/vulkan/prores_raw_idct.comp.glsl |  9 +++++++--
 libavcodec/vulkan_apv.c                     |  7 +++----
 libavcodec/vulkan_prores.c                  |  7 +++----
 libavcodec/vulkan_prores_raw.c              |  7 +++----
 7 files changed, 30 insertions(+), 30 deletions(-)

diff --git a/libavcodec/vulkan/apv_idct.comp.glsl 
b/libavcodec/vulkan/apv_idct.comp.glsl
index ba37fb1073..c66df279af 100644
--- a/libavcodec/vulkan/apv_idct.comp.glsl
+++ b/libavcodec/vulkan/apv_idct.comp.glsl
@@ -106,6 +106,9 @@ void main(void)
     /* blocks fully outside the coded area have nothing stored for them */
     const bool oob = pos.x >= cstride || pos.y >= cheight;
 
+    /* Loop-invariant column scale */
+    const float col_scale = norm * idct_scale[col];
+
     [[unroll]]
     for (uint y = 0u; y < 8u; y++) {
         /* load */
@@ -114,9 +117,9 @@ void main(void)
                                                  pos.x + int(col))]);
         /* dequant + norm */
         int   qs    = level_scale * int(q_matrix[comp][col][y]) * (1 << 
qp_shift);
-        float v     = float(coeff * qs) * norm;
+        float v     = float(coeff * qs) * col_scale;
         /* scale */
-        blocks[block][y * 9u + col] = v * idct_scale[y * 8u + col];
+        blocks[block][y * 9u + col] = v * idct_scale[y];
     }
     barrier();
 
diff --git a/libavcodec/vulkan/dct.glsl b/libavcodec/vulkan/dct.glsl
index 76f799b3e1..179c0406e0 100644
--- a/libavcodec/vulkan/dct.glsl
+++ b/libavcodec/vulkan/dct.glsl
@@ -39,20 +39,12 @@
 layout (constant_id = 16) const uint32_t nb_blocks = 1;
 layout (constant_id = 17) const uint32_t nb_components = 1;
 
+/* Coefficient (y, x) is scaled by sv[y]*sv[x]. Kept separable, as a
+ * 64-entry table costs a divergent load per coefficient. */
 #define V(I) layout(constant_id = (18 + I)) const float sv##I = I;
-V( 0) V( 1) V( 2) V( 3) V( 4) V( 5) V( 6) V( 7) V( 8) V( 9) V(10) V(11) V(12)
-V(13) V(14) V(15) V(16) V(17) V(18) V(19) V(20) V(21) V(22) V(23) V(24) V(25)
-V(26) V(27) V(28) V(29) V(30) V(31) V(32) V(33) V(34) V(35) V(36) V(37) V(38)
-V(39) V(40) V(41) V(42) V(43) V(44) V(45) V(46) V(47) V(48) V(49) V(50) V(51)
-V(52) V(53) V(54) V(55) V(56) V(57) V(58) V(59) V(60) V(61) V(62) V(63)
+V( 0) V( 1) V( 2) V( 3) V( 4) V( 5) V( 6) V( 7)
 
-const float idct_scale[64] = {
-     sv0,  sv1,  sv2,  sv3,  sv4,  sv5,  sv6,  sv7,  sv8,  sv9, sv10, sv11, 
sv12,
-    sv13, sv14, sv15, sv16, sv17, sv18, sv19, sv20, sv21, sv22, sv23, sv24, 
sv25,
-    sv26, sv27, sv28, sv29, sv30, sv31, sv32, sv33, sv34, sv35, sv36, sv37, 
sv38,
-    sv39, sv40, sv41, sv42, sv43, sv44, sv45, sv46, sv47, sv48, sv49, sv50, 
sv51,
-    sv52, sv53, sv54, sv55, sv56, sv57, sv58, sv59, sv60, sv61, sv62, sv63
-};
+const float idct_scale[8] = { sv0, sv1, sv2, sv3, sv4, sv5, sv6, sv7 };
 
 /* Padded by 1 row to avoid bank conflicts */
 shared float blocks[nb_blocks][nb_components*8*(8 + 1)];
diff --git a/libavcodec/vulkan/prores_idct.comp.glsl 
b/libavcodec/vulkan/prores_idct.comp.glsl
index 8ef22b0384..8c7fb60c79 100644
--- a/libavcodec/vulkan/prores_idct.comp.glsl
+++ b/libavcodec/vulkan/prores_idct.comp.glsl
@@ -82,11 +82,14 @@ void main(void)
         uint8_t qidx = quant_idx[(gid.y >> 1) * mb_width + (gid.x >> (4 - 
chroma_shift))];
         int qscale = qidx > 128 ? (qidx - 96) << 2 : qidx, mat = int(gid.z != 
0) << 6;
 
+        /* Loop-invariant column scale */
+        const float col_scale = norm * idct_scale[idx];
+
         [[unroll]] for (uint i = 0; i < 8; ++i) {
             uint cidx = (i << 3) + idx;
             int   c = sign_extend(int(get_px(comp, ivec2(gid.x, (gid.y << 3) + 
i))), 16);
-            float v = float(c * qscale * int(qmat[mat + cidx])) * norm;
-            blocks[block][i * 9 + idx] = v * idct_scale[cidx];
+            float v = float(c * qscale * int(qmat[mat + cidx])) * col_scale;
+            blocks[block][i * 9 + idx] = v * idct_scale[i];
         }
     }
 
diff --git a/libavcodec/vulkan/prores_raw_idct.comp.glsl 
b/libavcodec/vulkan/prores_raw_idct.comp.glsl
index dcc8626d48..ebaa43c999 100644
--- a/libavcodec/vulkan/prores_raw_idct.comp.glsl
+++ b/libavcodec/vulkan/prores_raw_idct.comp.glsl
@@ -88,13 +88,18 @@ void main(void)
     }
     barrier();
 
+    const float norm = 8.0; /* DCT normalization const */
+
+    /* Loop-invariant column scale */
+    const float col_scale = float(qscale) * norm * idct_scale[ROW_ID];
+
     [[unroll]]
     for (uint y = 0; y < 8; y++) {
         uint block_off = y*8 + ROW_ID;
         int v = int(imageLoad(dst, offs + 2*ivec2(BLOCK_ID*8, 0) + 
scan[block_off])[0]);
         /* Dequantize (coeff * qmat * qscale), matching the reference decoder 
*/
-        float vf = float(sign_extend(v, 16)) * float(qmat_buf[block_off]) * 
float(qscale);
-        blocks[BLOCK_ID][COMP_ID*72 + y*9 + ROW_ID] = vf * 
idct_scale[block_off];
+        float vf = float(sign_extend(v, 16)) * float(qmat_buf[block_off]) * 
col_scale;
+        blocks[BLOCK_ID][COMP_ID*72 + y*9 + ROW_ID] = vf * idct_scale[y];
     }
 
     /* Column-wise iDCT */
diff --git a/libavcodec/vulkan_apv.c b/libavcodec/vulkan_apv.c
index 1ad5ab0a41..e9c469e6ad 100644
--- a/libavcodec/vulkan_apv.c
+++ b/libavcodec/vulkan_apv.c
@@ -406,7 +406,7 @@ static int init_idct_shader(AVCodecContext *avctx, 
FFVulkanContext *s,
     AVHWFramesContext *dec_frames_ctx;
     dec_frames_ctx = (AVHWFramesContext *)avctx->hw_frames_ctx->data;
 
-    SPEC_LIST_CREATE(sl, 1 + 64, (1 + 64)*sizeof(uint32_t))
+    SPEC_LIST_CREATE(sl, 1 + 8, (1 + 8)*sizeof(uint32_t))
     SPEC_LIST_ADD(sl, 16, 32, 8); /* nb_blocks per workgroup */
 
     const double idct_8_scales[8] = {
@@ -415,9 +415,8 @@ static int init_idct_shader(AVCodecContext *avctx, 
FFVulkanContext *s,
         cos(4.0*M_PI/16.0) / 2.0, cos(5.0*M_PI/16.0) / 2.0,
         cos(6.0*M_PI/16.0) / 2.0, cos(7.0*M_PI/16.0) / 2.0,
     };
-    for (int i = 0; i < 64; i++)
-        SPEC_LIST_ADD(sl, 18 + i, 32,
-                      av_float2int(idct_8_scales[i >> 3]*idct_8_scales[i & 
7]));
+    for (int i = 0; i < 8; i++)
+        SPEC_LIST_ADD(sl, 18 + i, 32, av_float2int(idct_8_scales[i]));
 
     ff_vk_shader_load(shd, VK_SHADER_STAGE_COMPUTE_BIT, sl,
                       (uint32_t []) { 32, 2, 1 }, 0);
diff --git a/libavcodec/vulkan_prores.c b/libavcodec/vulkan_prores.c
index ff4185fb79..d8d7808ef8 100644
--- a/libavcodec/vulkan_prores.c
+++ b/libavcodec/vulkan_prores.c
@@ -419,7 +419,7 @@ static int init_idct_shader(AVCodecContext *avctx, 
FFVulkanContext *s,
     AVHWFramesContext *dec_frames_ctx;
     dec_frames_ctx = (AVHWFramesContext *)avctx->hw_frames_ctx->data;
 
-    SPEC_LIST_CREATE(sl, 2 + 64, (2 + 64)*sizeof(uint32_t))
+    SPEC_LIST_CREATE(sl, 2 + 8, (2 + 8)*sizeof(uint32_t))
     SPEC_LIST_ADD(sl,  0, 32, interlaced);
     SPEC_LIST_ADD(sl, 16, 32, 4*2); /* nb_blocks */
 
@@ -429,9 +429,8 @@ static int init_idct_shader(AVCodecContext *avctx, 
FFVulkanContext *s,
         cos(4.0*M_PI/16.0) / 2.0, cos(5.0*M_PI/16.0) / 2.0,
         cos(6.0*M_PI/16.0) / 2.0, cos(7.0*M_PI/16.0) / 2.0,
     };
-    for (int i = 0; i < 64; i++)
-        SPEC_LIST_ADD(sl, 18 + i, 32,
-                      av_float2int(idct_8_scales[i >> 3]*idct_8_scales[i & 
7]));
+    for (int i = 0; i < 8; i++)
+        SPEC_LIST_ADD(sl, 18 + i, 32, av_float2int(idct_8_scales[i]));
 
     ff_vk_shader_load(shd,
                       VK_SHADER_STAGE_COMPUTE_BIT, sl,
diff --git a/libavcodec/vulkan_prores_raw.c b/libavcodec/vulkan_prores_raw.c
index b93b21ad1e..45936b68a4 100644
--- a/libavcodec/vulkan_prores_raw.c
+++ b/libavcodec/vulkan_prores_raw.c
@@ -336,7 +336,7 @@ static int init_idct_shader(AVCodecContext *avctx, 
FFVulkanContext *s,
                             int version)
 {
     int err;
-    SPEC_LIST_CREATE(sl, 2 + 64, (2 + 64)*sizeof(uint32_t))
+    SPEC_LIST_CREATE(sl, 2 + 8, (2 + 8)*sizeof(uint32_t))
 
     int nb_blocks = version == 0 ? 8 : 16;
     SPEC_LIST_ADD(sl, 16, 32, nb_blocks);
@@ -348,9 +348,8 @@ static int init_idct_shader(AVCodecContext *avctx, 
FFVulkanContext *s,
         cos(4.0*M_PI/16.0) / 2.0, cos(5.0*M_PI/16.0) / 2.0,
         cos(6.0*M_PI/16.0) / 2.0, cos(7.0*M_PI/16.0) / 2.0,
     };
-    for (int i = 0; i < 64; i++)
-        SPEC_LIST_ADD(sl, 18 + i, 32,
-                      av_float2int(8*idct_8_scales[i >> 3]*idct_8_scales[i & 
7]));
+    for (int i = 0; i < 8; i++)
+        SPEC_LIST_ADD(sl, 18 + i, 32, av_float2int(idct_8_scales[i]));
 
     ff_vk_shader_load(shd, VK_SHADER_STAGE_COMPUTE_BIT, sl,
                       (uint32_t []) { 8, nb_blocks, 4 }, 0);

-- 
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