Loading...
Searching...
No Matches
BGRA.hpp
1#pragma once
2#include <Gfx/Graph/encoders/GPUVideoEncoder.hpp>
3
4namespace score::gfx
5{
6
20{
21 // Output byte order in memory (the RGBA8 texel bytes [0,1,2,3]).
22 // NOTE: these are *memory* byte orders, which do NOT match AJA's NTV2_FBF_*
23 // names — see the AJA FBF->memory mapping in AJAOutputNode (verified against
24 // ntv2transcode.cpp ConvertARGBYCbCrTo*).
25 enum class Swizzle
26 {
27 BGRA, // (b,g,r,a) — DXGI B8G8R8A8, QImage RGB32, NTV2_FBF_ARGB
28 RGBA, // (r,g,b,a) — straight passthrough, NTV2_FBF_ABGR
29 ABGR, // (a,b,g,r)
30 ARGB // (a,r,g,b) — NTV2_FBF_RGBA
31 };
32 Swizzle m_swizzle{Swizzle::BGRA};
33
34 explicit BGRAEncoder(Swizzle s = Swizzle::BGRA)
35 : m_swizzle{s}
36 {
37 }
38
39 // %1 = the output swizzle expression.
40 static constexpr const char* frag = R"_(#version 450
41 layout(location = 0) in vec2 v_texcoord;
42 layout(location = 0) out vec4 fragColor;
43 layout(binding = 3) uniform sampler2D src_tex;
44
45 vec2 flip_y(vec2 tc) {
46 // Only OpenGL. The rest of the engine puts its geometry through
47 // renderer.clipSpaceCorrMatrix, which negates Y on Vulkan; this pass draws
48 // a hardcoded triangle in raw NDC and does not, so the correction it needs
49 // is not the same one. Flipping on Vulkan as well handed libav, GStreamer,
50 // NDI and every other consumer an upside-down picture.
51 #if defined(QSHADER_SPIRV) || defined(QSHADER_MSL) || defined(QSHADER_HLSL)
52 return tc;
53 #else
54 return vec2(tc.x, 1.0 - tc.y);
55 #endif
56 }
57
58 void main() {
59 vec4 c = texture(src_tex, flip_y(v_texcoord));
60 fragColor = %1;
61 }
62 )_";
63
64 QRhiTexture* m_outTexture{};
65 QRhiTextureRenderTarget* m_renderTarget{};
66 QRhiRenderPassDescriptor* m_rpDesc{};
67 QRhiSampler* m_sampler{};
68 QRhiShaderResourceBindings* m_srb{};
69 QRhiGraphicsPipeline* m_pipeline{};
70 QRhiReadbackResult m_readback{};
71 int m_width{};
72 int m_height{};
73 bool m_readbackEnabled{true};
74
75 void init(
76 QRhi& rhi, const RenderState& state, QRhiTexture* inputRGBA, int width,
77 int height, const QString& /*colorConversion*/ = colorMatrixOut()) override
78 {
79 m_width = width;
80 m_height = height;
81
82 m_outTexture = rhi.newTexture(
83 QRhiTexture::RGBA8, QSize{width, height}, 1,
84 QRhiTexture::RenderTarget | QRhiTexture::UsedAsTransferSource);
85 m_outTexture->create();
86
87 m_renderTarget = rhi.newTextureRenderTarget({m_outTexture});
88 m_rpDesc = m_renderTarget->newCompatibleRenderPassDescriptor();
89 m_renderTarget->setRenderPassDescriptor(m_rpDesc);
90 m_renderTarget->create();
91
92 m_sampler = rhi.newSampler(
93 QRhiSampler::Linear, QRhiSampler::Linear, QRhiSampler::None,
94 QRhiSampler::ClampToEdge, QRhiSampler::ClampToEdge);
95 m_sampler->create();
96
97 m_srb = rhi.newShaderResourceBindings();
98 m_srb->setBindings({
99 QRhiShaderResourceBinding::sampledTexture(
100 3, QRhiShaderResourceBinding::FragmentStage, inputRGBA, m_sampler),
101 });
102 m_srb->create();
103
104 const char* swiz = (m_swizzle == Swizzle::RGBA) ? "vec4(c.r, c.g, c.b, c.a)"
105 : (m_swizzle == Swizzle::ABGR)
106 ? "vec4(c.a, c.b, c.g, c.r)"
107 : (m_swizzle == Swizzle::ARGB)
108 ? "vec4(c.a, c.r, c.g, c.b)"
109 : "vec4(c.b, c.g, c.r, c.a)";
110 auto [vertS, fragS] = makeShaders(
111 state, QString::fromLatin1(vertex_shader),
112 QString::fromLatin1(frag).arg(QString::fromLatin1(swiz)));
113
114 m_pipeline = rhi.newGraphicsPipeline();
115 m_pipeline->setShaderStages({
116 {QRhiShaderStage::Vertex, vertS},
117 {QRhiShaderStage::Fragment, fragS},
118 });
119 m_pipeline->setVertexInputLayout({});
120 m_pipeline->setShaderResourceBindings(m_srb);
121 m_pipeline->setRenderPassDescriptor(m_rpDesc);
122 m_pipeline->create();
123 }
124
125 void exec(QRhi& rhi, QRhiCommandBuffer& cb) override
126 {
127 cb.beginPass(m_renderTarget, Qt::black, {0.0f, 0});
128 cb.setGraphicsPipeline(m_pipeline);
129 cb.setShaderResources(m_srb);
130 cb.setViewport(QRhiViewport(0, 0, m_width, m_height));
131 cb.draw(3);
132
133 if(m_readbackEnabled)
134 {
135 auto* readbackBatch = rhi.nextResourceUpdateBatch();
136 readbackBatch->readBackTexture(QRhiReadbackDescription{m_outTexture}, &m_readback);
137 cb.endPass(readbackBatch);
138 }
139 else
140 {
141 cb.endPass();
143 }
145 int planeCount() const override { return 1; }
147 const QRhiReadbackResult& readback(int) const override { return m_readback; }
148 QRhiTexture* outputTexture() const noexcept override { return m_outTexture; }
149 void setReadbackEnabled(bool e) noexcept override { m_readbackEnabled = e; }
150
151 void release() override
152 {
153 delete m_pipeline;
154 m_pipeline = nullptr;
155 delete m_srb;
156 m_srb = nullptr;
157 delete m_sampler;
158 m_sampler = nullptr;
159 delete m_rpDesc;
160 m_rpDesc = nullptr;
161 delete m_renderTarget;
162 m_renderTarget = nullptr;
163 delete m_outTexture;
164 m_outTexture = nullptr;
165 }
166};
167
168} // namespace score::gfx
Graphics rendering pipeline for ossia score.
Definition Filter/PreviewWidget.hpp:11
std::pair< QShader, QShader > makeShaders(const RenderState &v, QString vert, QString frag, int multiViewCount)
Get a pair of compiled vertex / fragment shaders from GLSL 4.5 sources.
Definition score-plugin-gfx/Gfx/Graph/Utils.cpp:1238
Cross-backend RGBA -> BGRA byte-order encoder.
Definition BGRA.hpp:20
const QRhiReadbackResult & readback(int) const override
Get the readback result for a given plane. Valid after endOffscreenFrame.
Definition BGRA.hpp:144
int planeCount() const override
Number of readback planes (1 for UYVY, 2 for NV12, 3 for I420).
Definition BGRA.hpp:142
void exec(QRhi &rhi, QRhiCommandBuffer &cb) override
Definition BGRA.hpp:122
void release() override
Release all GPU resources.
Definition BGRA.hpp:148
QRhiTexture * outputTexture() const noexcept override
Definition BGRA.hpp:145
void init(QRhi &rhi, const RenderState &state, QRhiTexture *inputRGBA, int width, int height, const QString &=colorMatrixOut()) override
Definition BGRA.hpp:72
void setReadbackEnabled(bool e) noexcept override
Definition BGRA.hpp:146
Base class for GPU-side video format conversion (RGBA to YUV).
Definition GPUVideoEncoder.hpp:30
static constexpr const char * vertex_shader
Definition GPUVideoEncoder.hpp:74