Commit 22a34144f6 for ffmpeg
commit 22a34144f6e7cc0b89be5217ca5d86268379d714
Author: Lynne <dev@lynne.ee>
Date: Sun Sep 27 01:34:16 2026 +0900
ffv1enc_vulkan: code the unary prefix without renormalisation checks
The zero flag, the ones of the unary prefix and its terminator can only
shrink the range, so they are now coded without renormalisation checks,
and the range is checked once after the terminator. When it underflowed
on the way, they are coded again from the saved coder state, with the
checks, which happens for about a quarter of the symbols.
The output is unchanged. Encoding a 6464x4852 16-bit RGB frame with
1024 slices on an RX 6900 XT, with the frame in VRAM, goes from
53.2/51.2 ms to 52.9/50.1 ms with context model 1/0.
diff --git a/libavcodec/vulkan/rangecoder_subgroup.glsl b/libavcodec/vulkan/rangecoder_subgroup.glsl
index c9ccaf74ce..f8ae202495 100644
--- a/libavcodec/vulkan/rangecoder_subgroup.glsl
+++ b/libavcodec/vulkan/rangecoder_subgroup.glsl
@@ -192,11 +192,26 @@ void put_isymbol_tail(int e, uint st24, uint a, bool neg)
s[11 + i] = subgroupBroadcast(st24, 22 + i);
s[20] = subgroupBroadcast(st24, 11 + e);
- put_rac(s[0], false);
+ uint range = rc.range;
+ uint top = rc_top;
+ uint r = rac_range1(rc.range, s[0]);
+ rc.range -= r;
+ rc_top -= r;
[[unroll]] for (int i = 0; i < 9; i++)
if (i < e)
- put_rac(s[1 + i], true);
- put_rac(s[1 + e], false);
+ rc.range = rac_range1(rc.range, s[1 + i]);
+ r = rac_range1(rc.range, s[1 + e]);
+ rc.range -= r;
+ rc_top -= r;
+ [[dont_flatten]] if (rc.range < 0x100) {
+ rc.range = range;
+ rc_top = top;
+ put_rac(s[0], false);
+ [[unroll]] for (int i = 0; i < 9; i++)
+ if (i < e)
+ put_rac(s[1 + i], true);
+ put_rac(s[1 + e], false);
+ }
[[unroll]] for (int i = 8; i >= 0; i--)
if (i < e)
put_rac(s[11 + i], bitfieldExtract(a, i, 1) != 0);