Files
mxl-multiviewer/shaders/v210_decode.comp
T
2026-05-24 21:17:44 +03:00

85 lines
2.4 KiB
Plaintext

#version 450
layout(local_size_x = 16, local_size_y = 16) in;
layout(binding = 0) readonly buffer V210Data {
uint data[];
} v210;
layout(binding = 1, rgba8) uniform writeonly image2D dstImage;
layout(push_constant) uniform PushConstants {
uint srcWidth;
uint srcHeight;
uint srcStrideBytes;
uint dstWidth;
uint dstHeight;
};
void main()
{
ivec2 dstPos = ivec2(gl_GlobalInvocationID.xy);
if (dstPos.x >= int(dstWidth) || dstPos.y >= int(dstHeight))
return;
uint sx = uint(dstPos.x) * srcWidth / dstWidth;
uint sy = uint(dstPos.y) * srcHeight / dstHeight;
uint group = sx / 6;
uint pos = sx % 6;
uint strideWords = srcStrideBytes / 4;
uint lineOffset = sy * strideWords;
uint groupOffset = lineOffset + group * 4;
uint w0 = v210.data[groupOffset + 0];
uint w1 = v210.data[groupOffset + 1];
uint w2 = v210.data[groupOffset + 2];
uint w3 = v210.data[groupOffset + 3];
uint cb0 = (w0 >> 0) & 0x3FFu;
uint y0 = (w0 >> 10) & 0x3FFu;
uint cr0 = (w0 >> 20) & 0x3FFu;
uint y1 = (w1 >> 0) & 0x3FFu;
uint cb2 = (w1 >> 10) & 0x3FFu;
uint y2 = (w1 >> 20) & 0x3FFu;
uint cr2 = (w2 >> 0) & 0x3FFu;
uint y3 = (w2 >> 10) & 0x3FFu;
uint cb4 = (w2 >> 20) & 0x3FFu;
uint y4 = (w3 >> 0) & 0x3FFu;
uint cr4 = (w3 >> 10) & 0x3FFu;
uint y5 = (w3 >> 20) & 0x3FFu;
uint y10, cb10, cr10;
switch (pos)
{
case 0u: y10 = y0; cb10 = cb0; cr10 = cr0; break;
case 1u: y10 = y1; cb10 = cb0; cr10 = cr0; break;
case 2u: y10 = y2; cb10 = cb2; cr10 = cr2; break;
case 3u: y10 = y3; cb10 = cb2; cr10 = cr2; break;
case 4u: y10 = y4; cb10 = cb4; cr10 = cr4; break;
default: y10 = y5; cb10 = cb4; cr10 = cr4; break;
}
// BT.709 limited-range YCbCr to RGB. v210 stores 10-bit video-range
// samples: Y [64, 940], Cb/Cr centered at 512.
int yp = int(y10) - 64;
int cbp = int(cb10) - 512;
int crp = int(cr10) - 512;
int yp8 = yp >> 2;
int cbp8 = cbp >> 2;
int crp8 = crp >> 2;
int r = (298 * yp8 + 459 * crp8 + 128) >> 8;
int g = (298 * yp8 - 137 * crp8 - 55 * cbp8 + 128) >> 8;
int b = (298 * yp8 + 541 * cbp8 + 128) >> 8;
r = clamp(r, 0, 255);
g = clamp(g, 0, 255);
b = clamp(b, 0, 255);
imageStore(dstImage, dstPos, vec4(float(r) / 255.0, float(g) / 255.0, float(b) / 255.0, 1.0));
}