33 static constexpr const char* compute_shader = R
"_(#version 450
34 layout(local_size_x = 16, local_size_y = 1, local_size_z = 1) in;
36 layout(binding = 0) uniform sampler2D src_tex;
37 layout(std430, binding = 1) writeonly buffer V210Buf {
40 layout(std140, binding = 2) uniform Params {
43 uint line_stride_words; // bytes-per-row / 4
44 uint groups_per_row; // == src_width / 6
48 vec2 flip_y(vec2 tc) {
49 #if defined(QSHADER_MSL) || defined(QSHADER_HLSL)
52 return vec2(tc.x, 1.0 - tc.y);
57 uvec3 to_yuv10(vec3 rgb) {
58 vec3 yuv = clamp(convert_from_rgb(rgb), 0.0, 1.0);
59 return uvec3(yuv * 1023.0 + 0.5);
63 uint group_x = gl_GlobalInvocationID.x;
64 uint y = gl_GlobalInvocationID.y;
65 if (group_x >= groups_per_row || int(y) >= src_size.y)
68 // Y-flip on backends that need it (matches the fragment encoders).
69 ivec2 srcSize = src_size;
70 #if defined(QSHADER_MSL) || defined(QSHADER_HLSL)
73 int src_y = srcSize.y - 1 - int(y);
76 uint x0 = group_x * 6u;
77 uvec3 a = to_yuv10(texelFetch(src_tex, ivec2(int(x0 ), src_y), 0).rgb);
78 uvec3 b = to_yuv10(texelFetch(src_tex, ivec2(int(x0 + 1u), src_y), 0).rgb);
79 uvec3 c = to_yuv10(texelFetch(src_tex, ivec2(int(x0 + 2u), src_y), 0).rgb);
80 uvec3 d = to_yuv10(texelFetch(src_tex, ivec2(int(x0 + 3u), src_y), 0).rgb);
81 uvec3 e = to_yuv10(texelFetch(src_tex, ivec2(int(x0 + 4u), src_y), 0).rgb);
82 uvec3 f = to_yuv10(texelFetch(src_tex, ivec2(int(x0 + 5u), src_y), 0).rgb);
84 uint cb01 = (a.y + b.y) >> 1;
85 uint cr01 = (a.z + b.z) >> 1;
86 uint cb23 = (c.y + d.y) >> 1;
87 uint cr23 = (c.z + d.z) >> 1;
88 uint cb45 = (e.y + f.y) >> 1;
89 uint cr45 = (e.z + f.z) >> 1;
91 // v210 packing: 6 pixels = 4 little-endian 32-bit words.
92 uint w0 = cb01 | (a.x << 10) | (cr01 << 20);
93 uint w1 = b.x | (cb23 << 10) | (c.x << 20);
94 uint w2 = cr23 | (d.x << 10) | (cb45 << 20);
95 uint w3 = e.x | (cr45 << 10) | (f.x << 20);
97 uint base = y * line_stride_words + group_x * 4u;
100 v210[base + 2u] = w2;
101 v210[base + 3u] = w3;
105 QRhiBuffer* m_paramsUBO{};
106 QRhiSampler* m_sampler{};
107 QRhiShaderResourceBindings* m_srb{};
108 QRhiComputePipeline* m_pipeline{};
111 int m_groupsPerRow{};
112 uint32_t m_lineStrideBytes{};
116 QRhi& rhi,
const RenderState& state, QRhiTexture* inputRGBA,
int width,
117 int height, QRhiBuffer* outputBuffer,
118 const QString& colorConversion = colorMatrixOut())
override
120 if(!outputBuffer || width % 6 != 0)
122 if(!rhi.isFeatureSupported(QRhi::Compute))
127 m_groupsPerRow = width / 6;
128 m_lineStrideBytes = ((width + 47) / 48) * 128;
131 m_paramsUBO = rhi.newBuffer(QRhiBuffer::Dynamic, QRhiBuffer::UniformBuffer, 32);
132 m_paramsUBO->setName(
"V210ComputeEncoder::params");
133 if(!m_paramsUBO->create())
136 m_sampler = rhi.newSampler(
137 QRhiSampler::Nearest, QRhiSampler::Nearest, QRhiSampler::None,
138 QRhiSampler::ClampToEdge, QRhiSampler::ClampToEdge);
139 if(!m_sampler->create())
142 m_srb = rhi.newShaderResourceBindings();
144 QRhiShaderResourceBinding::sampledTexture(
145 0, QRhiShaderResourceBinding::ComputeStage, inputRGBA, m_sampler),
146 QRhiShaderResourceBinding::bufferStore(
147 1, QRhiShaderResourceBinding::ComputeStage, outputBuffer),
148 QRhiShaderResourceBinding::uniformBuffer(
149 2, QRhiShaderResourceBinding::ComputeStage, m_paramsUBO),
155 state, QString::fromLatin1(compute_shader).arg(colorConversion));
156 m_pipeline = rhi.newComputePipeline();
157 m_pipeline->setShaderStage({QRhiShaderStage::Compute, cs});
158 m_pipeline->setShaderResourceBindings(m_srb);
159 if(!m_pipeline->create())
169 QRhi& rhi, QRhiCommandBuffer& cb, QRhiResourceUpdateBatch* res)
override
171 struct alignas(16) ParamsData
175 uint32_t lineStrideWords;
176 uint32_t groupsPerRow;
181 m_lineStrideBytes / 4,
182 static_cast<uint32_t
>(m_groupsPerRow),
184 res->updateDynamicBuffer(m_paramsUBO, 0,
sizeof(p), &p);
186 cb.beginComputePass(res);
187 cb.setComputePipeline(m_pipeline);
188 cb.setShaderResources(m_srb);
190 (m_groupsPerRow + 15) / 16,
196 void release()
override
QShader makeCompute(const RenderState &v, QString compute)
Compile a compute shader.
Definition score-plugin-gfx/Gfx/Graph/Utils.cpp:674