24 static constexpr const char* y_frag = R
"_(#version 450
25 layout(location = 0) in vec2 v_texcoord;
26 layout(location = 0) out vec4 fragColor;
27 layout(binding = 3) uniform sampler2D src_tex;
29 vec2 flip_y(vec2 tc) {
30 // Only OpenGL. The rest of the engine puts its geometry through
31 // renderer.clipSpaceCorrMatrix, which negates Y on Vulkan; this pass draws
32 // a hardcoded triangle in raw NDC and does not, so the correction it needs
33 // is not the same one. Flipping on Vulkan as well handed libav, GStreamer,
34 // NDI and every other consumer an upside-down picture.
35 #if defined(QSHADER_SPIRV) || defined(QSHADER_MSL) || defined(QSHADER_HLSL)
38 return vec2(tc.x, 1.0 - tc.y);
42 vec3 rgb = texture(src_tex, flip_y(v_texcoord)).rgb;
43 vec3 yuv = convert_from_rgb(rgb);
44 fragColor = vec4(yuv.x, 0.0, 0.0, 1.0);
48 static constexpr const char* u_frag = R
"_(#version 450
49 layout(location = 0) in vec2 v_texcoord;
50 layout(location = 0) out vec4 fragColor;
51 layout(binding = 3) uniform sampler2D src_tex;
53 vec2 flip_y(vec2 tc) {
54 // Only OpenGL. The rest of the engine puts its geometry through
55 // renderer.clipSpaceCorrMatrix, which negates Y on Vulkan; this pass draws
56 // a hardcoded triangle in raw NDC and does not, so the correction it needs
57 // is not the same one. Flipping on Vulkan as well handed libav, GStreamer,
58 // NDI and every other consumer an upside-down picture.
59 #if defined(QSHADER_SPIRV) || defined(QSHADER_MSL) || defined(QSHADER_HLSL)
62 return vec2(tc.x, 1.0 - tc.y);
66 vec3 rgb = texture(src_tex, flip_y(v_texcoord)).rgb;
67 vec3 yuv = convert_from_rgb(rgb);
68 fragColor = vec4(yuv.y, 0.0, 0.0, 1.0);
72 static constexpr const char* v_frag = R
"_(#version 450
73 layout(location = 0) in vec2 v_texcoord;
74 layout(location = 0) out vec4 fragColor;
75 layout(binding = 3) uniform sampler2D src_tex;
77 vec2 flip_y(vec2 tc) {
78 // Only OpenGL. The rest of the engine puts its geometry through
79 // renderer.clipSpaceCorrMatrix, which negates Y on Vulkan; this pass draws
80 // a hardcoded triangle in raw NDC and does not, so the correction it needs
81 // is not the same one. Flipping on Vulkan as well handed libav, GStreamer,
82 // NDI and every other consumer an upside-down picture.
83 #if defined(QSHADER_SPIRV) || defined(QSHADER_MSL) || defined(QSHADER_HLSL)
86 return vec2(tc.x, 1.0 - tc.y);
90 vec3 rgb = texture(src_tex, flip_y(v_texcoord)).rgb;
91 vec3 yuv = convert_from_rgb(rgb);
92 fragColor = vec4(yuv.z, 0.0, 0.0, 1.0);
98 QRhiTexture* texture{};
99 QRhiTextureRenderTarget* rt{};
100 QRhiRenderPassDescriptor* rp{};
101 QRhiShaderResourceBindings* srb{};
102 QRhiGraphicsPipeline* pipeline{};
103 QRhiReadbackResult readback{};
121 QRhiSampler* m_sampler{};
126 QRhi& rhi,
const RenderState& state, QRhiTexture* inputRGBA,
127 PlaneResources& plane,
int w,
int h,
const char* fragTemplate,
128 const QString& colorConversion)
130 plane.texture = rhi.newTexture(
131 QRhiTexture::R8, QSize{w, h}, 1,
132 QRhiTexture::RenderTarget | QRhiTexture::UsedAsTransferSource);
133 plane.texture->create();
135 plane.rt = rhi.newTextureRenderTarget({plane.texture});
136 plane.rp = plane.rt->newCompatibleRenderPassDescriptor();
137 plane.rt->setRenderPassDescriptor(plane.rp);
140 plane.srb = rhi.newShaderResourceBindings();
141 plane.srb->setBindings({
142 QRhiShaderResourceBinding::sampledTexture(
143 3, QRhiShaderResourceBinding::FragmentStage, inputRGBA, m_sampler),
149 QString::fromLatin1(fragTemplate).arg(colorConversion));
150 plane.pipeline = rhi.newGraphicsPipeline();
151 plane.pipeline->setShaderStages({
152 {QRhiShaderStage::Vertex, vs},
153 {QRhiShaderStage::Fragment, fs},
155 plane.pipeline->setVertexInputLayout({});
156 plane.pipeline->setShaderResourceBindings(plane.srb);
157 plane.pipeline->setRenderPassDescriptor(plane.rp);
158 plane.pipeline->create();
161 void execPlane(QRhi& rhi, QRhiCommandBuffer& cb, PlaneResources& plane,
int w,
int h)
163 cb.beginPass(plane.rt, Qt::black, {0.0f, 0});
164 cb.setGraphicsPipeline(plane.pipeline);
165 cb.setShaderResources(plane.srb);
166 cb.setViewport(QRhiViewport(0, 0, w, h));
169 auto* batch = rhi.nextResourceUpdateBatch();
170 batch->readBackTexture(QRhiReadbackDescription{plane.texture}, &plane.readback);
175 QRhi& rhi,
const RenderState& state, QRhiTexture* inputRGBA,
int width,
176 int height,
const QString& colorConversion)
override
181 m_sampler = rhi.newSampler(
182 QRhiSampler::Linear, QRhiSampler::Linear, QRhiSampler::None,
183 QRhiSampler::ClampToEdge, QRhiSampler::ClampToEdge);
186 initPlane(rhi, state, inputRGBA, m_planes[0], width, height, y_frag, colorConversion);
187 initPlane(rhi, state, inputRGBA, m_planes[1], width / 2, height / 2, u_frag, colorConversion);
188 initPlane(rhi, state, inputRGBA, m_planes[2], width / 2, height / 2, v_frag, colorConversion);
191 void exec(QRhi& rhi, QRhiCommandBuffer& cb)
override
193 execPlane(rhi, cb, m_planes[0], m_width, m_height);
194 execPlane(rhi, cb, m_planes[1], m_width / 2, m_height / 2);
195 execPlane(rhi, cb, m_planes[2], m_width / 2, m_height / 2);
200 const QRhiReadbackResult&
readback(
int plane)
const override
202 return m_planes[plane].readback;
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
void init(QRhi &rhi, const RenderState &state, QRhiTexture *inputRGBA, int width, int height, const QString &colorConversion) override
Definition I420.hpp:165