Loading...
Searching...
No Matches
BGRACompute.hpp
1#pragma once
2#include <Gfx/Graph/Utils.hpp>
3#include <Gfx/Graph/encoders/ComputeEncoder.hpp>
4#include <Gfx/Graph/encoders/GPUVideoEncoder.hpp>
5
6#include <private/qrhi_p.h>
7
8namespace score::gfx
9{
10
21{
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;
24
25 layout(binding = 0) uniform sampler2D src_tex;
26 layout(std430, binding = 1) writeonly buffer BgraBuf {
27 uint bgra[];
28 };
29 layout(std140, binding = 2) uniform Params {
30 ivec2 src_size;
31 ivec2 _pad0;
32 uint line_stride_words; // bytes-per-row / 4 == width
33 uint _pad1[3];
34 };
35
36 uint to_byte(float v) {
37 return uint(clamp(v, 0.0, 1.0) * 255.0 + 0.5);
38 }
39
40 void main() {
41 uint x = gl_GlobalInvocationID.x;
42 uint y = gl_GlobalInvocationID.y;
43 if (int(x) >= src_size.x || int(y) >= src_size.y)
44 return;
45
46 #if defined(QSHADER_MSL) || defined(QSHADER_HLSL)
47 int src_y = int(y);
48 #else
49 int src_y = src_size.y - 1 - int(y);
50 #endif
51
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);
57
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;
61 }
62 )_";
63
64 QRhiBuffer* m_paramsUBO{};
65 QRhiSampler* m_sampler{};
66 QRhiShaderResourceBindings* m_srb{};
67 QRhiComputePipeline* m_pipeline{};
68 int m_width{};
69 int m_height{};
70
71 bool init(
72 QRhi& rhi, const RenderState& state, QRhiTexture* inputRGBA, int width,
73 int height, QRhiBuffer* outputBuffer,
74 const QString& /*colorConversion*/ = colorMatrixOut()) override
75 {
76 if(!outputBuffer || !rhi.isFeatureSupported(QRhi::Compute))
77 return false;
78
79 m_width = width;
80 m_height = height;
81
82 m_paramsUBO = rhi.newBuffer(QRhiBuffer::Dynamic, QRhiBuffer::UniformBuffer, 32);
83 m_paramsUBO->setName("BGRAComputeEncoder::params");
84 if(!m_paramsUBO->create())
85 return false;
86
87 m_sampler = rhi.newSampler(
88 QRhiSampler::Nearest, QRhiSampler::Nearest, QRhiSampler::None,
89 QRhiSampler::ClampToEdge, QRhiSampler::ClampToEdge);
90 if(!m_sampler->create())
91 return false;
92
93 m_srb = rhi.newShaderResourceBindings();
94 m_srb->setBindings({
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),
101 });
102 if(!m_srb->create())
103 return false;
104
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())
110 return false;
111
112 return true;
113 }
114
115 void exec(
116 QRhi& rhi, QRhiCommandBuffer& cb, QRhiResourceUpdateBatch* res) override
117 {
118 struct alignas(16) ParamsData
119 {
120 int32_t srcW, srcH;
121 int32_t pad0[2];
122 uint32_t lineStrideWords;
123 uint32_t pad1[3];
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);
126
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);
131 cb.endComputePass();
132 }
133
134 void release() override
135 {
136 delete m_pipeline; m_pipeline = nullptr;
137 delete m_srb; m_srb = nullptr;
138 delete m_sampler; m_sampler = nullptr;
139 delete m_paramsUBO; m_paramsUBO = nullptr;
140 }
141};
142
143} // namespace score::gfx
Graphics rendering pipeline for ossia score.
Definition Filter/PreviewWidget.hpp:12
QShader makeCompute(const RenderState &v, QString compute)
Compile a compute shader.
Definition score-plugin-gfx/Gfx/Graph/Utils.cpp:674
Compute-shader RGBA -> BGRA (NTV2_FBF_ARGB byte order) encoder targeting an external SSBO.
Definition BGRACompute.hpp:21
Base interface for compute-shader RGBA -> AJA-format encoders.
Definition ComputeEncoder.hpp:36
Global state associated to a rendering context.
Definition RenderState.hpp:37