22 static constexpr const char* compute_shader = R
"_(#version 450
23 layout(local_size_x = 16, local_size_y = 16, local_size_z = 1) in;
25 layout(binding = 0) uniform sampler2D src_tex;
26 layout(std430, binding = 1) writeonly buffer BgraBuf {
29 layout(std140, binding = 2) uniform Params {
32 uint line_stride_words; // bytes-per-row / 4 == width
36 uint to_byte(float v) {
37 return uint(clamp(v, 0.0, 1.0) * 255.0 + 0.5);
41 uint x = gl_GlobalInvocationID.x;
42 uint y = gl_GlobalInvocationID.y;
43 if (int(x) >= src_size.x || int(y) >= src_size.y)
46 #if defined(QSHADER_MSL) || defined(QSHADER_HLSL)
49 int src_y = src_size.y - 1 - int(y);
52 vec4 c = texelFetch(src_tex, ivec2(int(x), src_y), 0);
53 uint B = to_byte(c.b);
54 uint G = to_byte(c.g);
55 uint R = to_byte(c.r);
56 uint A = to_byte(c.a);
58 // NTV2_FBF_ARGB byte order in memory: B, G, R, A
59 uint w = B | (G << 8) | (R << 16) | (A << 24);
60 bgra[y * line_stride_words + x] = w;
64 QRhiBuffer* m_paramsUBO{};
65 QRhiSampler* m_sampler{};
66 QRhiShaderResourceBindings* m_srb{};
67 QRhiComputePipeline* m_pipeline{};
72 QRhi& rhi,
const RenderState& state, QRhiTexture* inputRGBA,
int width,
73 int height, QRhiBuffer* outputBuffer,
74 const QString& = colorMatrixOut())
override
76 if(!outputBuffer || !rhi.isFeatureSupported(QRhi::Compute))
82 m_paramsUBO = rhi.newBuffer(QRhiBuffer::Dynamic, QRhiBuffer::UniformBuffer, 32);
83 m_paramsUBO->setName(
"BGRAComputeEncoder::params");
84 if(!m_paramsUBO->create())
87 m_sampler = rhi.newSampler(
88 QRhiSampler::Nearest, QRhiSampler::Nearest, QRhiSampler::None,
89 QRhiSampler::ClampToEdge, QRhiSampler::ClampToEdge);
90 if(!m_sampler->create())
93 m_srb = rhi.newShaderResourceBindings();
95 QRhiShaderResourceBinding::sampledTexture(
96 0, QRhiShaderResourceBinding::ComputeStage, inputRGBA, m_sampler),
97 QRhiShaderResourceBinding::bufferStore(
98 1, QRhiShaderResourceBinding::ComputeStage, outputBuffer),
99 QRhiShaderResourceBinding::uniformBuffer(
100 2, QRhiShaderResourceBinding::ComputeStage, m_paramsUBO),
105 QShader cs =
makeCompute(state, QString::fromLatin1(compute_shader));
106 m_pipeline = rhi.newComputePipeline();
107 m_pipeline->setShaderStage({QRhiShaderStage::Compute, cs});
108 m_pipeline->setShaderResourceBindings(m_srb);
109 if(!m_pipeline->create())
116 QRhi& rhi, QRhiCommandBuffer& cb, QRhiResourceUpdateBatch* res)
override
118 struct alignas(16) ParamsData
122 uint32_t lineStrideWords;
124 } p{m_width, m_height, {0, 0},
static_cast<uint32_t
>(m_width), {0, 0, 0}};
125 res->updateDynamicBuffer(m_paramsUBO, 0,
sizeof(p), &p);
127 cb.beginComputePass(res);
128 cb.setComputePipeline(m_pipeline);
129 cb.setShaderResources(m_srb);
130 cb.dispatch((m_width + 15) / 16, (m_height + 15) / 16, 1);
134 void release()
override
136 delete m_pipeline; m_pipeline =
nullptr;
137 delete m_srb; m_srb =
nullptr;
138 delete m_sampler; m_sampler =
nullptr;
QShader makeCompute(const RenderState &v, QString compute)
Compile a compute shader.
Definition score-plugin-gfx/Gfx/Graph/Utils.cpp:674