vulkan: clamp GET_BITS_SMEM refills to the end of the bitstream

FILL_SMEM read up to 16*GET_BITS_SMEM bytes past the end of the buffer.
At the default depth of 4 that is exactly AV_INPUT_BUFFER_PADDING_SIZE,
so it only worked by coincidence; deeper windows faulted.

Clamp lines past the end onto the last line; nothing reads them. Issuing
each line as its own load is also ~3% faster than one indexed fetch.
This commit is contained in:
Lynne committed 2026-09-20 17:19:11 +09:00
1 parent bc1cf21643
commit e9e698f482
1 file changed
+8 -4
+8 -4
View File
@@ -276,13 +276,17 @@ struct GetBitContext {
shared u32vec4 gb_storage[gl_WorkGroupSize.x*gl_WorkGroupSize.y*gl_WorkGroupSize.z*GET_BITS_SMEM];
/* Requires a line-aligned address; LOAD64() absorbs the origin's offset,
* so refills land on line boundaries. */
* so refills land on line boundaries. Lines past the end of the buffer
* are clamped to the last one to avoid reading past the padding. */
#define FILL_SMEM(addr) \
{ \
u32vec4buf ptr = u32vec4buf(addr); \
uint64_t gb_last_line = max(gb.buf_start & ~uint64_t(15), \
(gb.buf_end - 1) & ~uint64_t(15)); \
[[unroll]] \
for (uint i = 0; i < GET_BITS_SMEM; ++i) \
gb_storage[gl_LocalInvocationIndex * GET_BITS_SMEM + i] = ptr[i].v; \
for (uint i = 0; i < GET_BITS_SMEM; ++i) { \
u32vec4buf ptr = u32vec4buf(min((addr) + 16*i, gb_last_line)); \
gb_storage[gl_LocalInvocationIndex * GET_BITS_SMEM + i] = ptr[0].v; \
} \
}
#define LOAD64() \