Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
rhi_support.cpp
Go to the documentation of this file.
1// Copyright (C) 2026 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
3
5
6#include <QtMultimedia/private/qvideotexturehelper_p.h>
7#include <QtMultimedia/qvideoframeformat.h>
8
9#include <QtCore/qfile.h>
10
12
13namespace QtMultimediaTest {
14
15using namespace Qt::Literals;
16
18{
19 QRhiNullInitParams params;
20 return std::unique_ptr<QRhi>{ QRhi::create(QRhi::Null, &params) };
21}
22
23#if QT_CONFIG(opengl)
25{
28 };
29
35 };
36 if (!rhi)
37 return q23::unexpected(u"QRhi::create failed"_s);
38
39 return OffscreenGlRhi{
41 std::move(rhi),
42 };
43}
44
46{
50}
51#endif
52
53#if QT_CONFIG(metal)
55{
58}
59#endif
60
61#if defined(Q_OS_WIN)
63{
66}
67
69{
73
76}
77
79{
81 return std::unique_ptr<QRhi>{ QRhi::create(QRhi::D3D12, &params) };
82}
83
84#endif
85
86q23::expected<QByteArray, QString> readBackPlane(QRhi &rhi, quint64 handle, QSize planeSize,
87 QRhiTexture::Format format)
88{
89 std::unique_ptr<QRhiTexture> texture(
90 rhi.newTexture(format, planeSize, 1, QRhiTexture::UsedAsTransferSource));
91 if (!texture->createFrom(QRhiTexture::NativeTexture{ handle, 0 }))
92 return q23::unexpected(u"QRhiTexture::createFrom failed"_s);
93
94 QRhiResourceUpdateBatch *batch = rhi.nextResourceUpdateBatch();
95 QRhiReadbackResult result;
96 batch->readBackTexture(texture.get(), &result);
97
98 QRhiCommandBuffer *cb = nullptr;
99 if (rhi.beginOffscreenFrame(&cb) != QRhi::FrameOpSuccess || !cb)
100 return q23::unexpected(u"QRhi::beginOffscreenFrame failed"_s);
101 cb->resourceUpdate(batch);
102 rhi.endOffscreenFrame();
103
104 return result.data;
105}
106
107#if QT_CONFIG(opengl)
108
109namespace {
110
112{
113 QFile file(path);
115 return q23::unexpected(u"Could not open shader file: "_s + path);
117 if (!shader.isValid())
118 return q23::unexpected(u"Invalid/unsupported shader file: "_s + path);
119 return shader;
120}
121
122} // namespace
123
124// Unlike readBackPlane(), EXTERNAL_OES textures can't be read back directly: they're only
125// consumable by a shader (samplerExternalOES). Renders the texture through a full-screen quad
126// using this module's own externalsampler shader into a plain RGBA8 target, then reads that back.
128{
131 };
133 return q23::unexpected(u"Failed to wrap the native handle as an ExternalOES QRhiTexture"_s);
134
138 };
139 if (!targetTexture->create())
140 return q23::unexpected(u"Failed to create the readback render target texture"_s);
141
145 };
148 };
150 if (!renderTarget->create())
151 return q23::unexpected(u"Failed to create the readback render target"_s);
152
155 if (!vertexShader)
156 return q23::unexpected(vertexShader.error());
158 if (!fragmentShader)
160
164 };
165 if (!sampler->create())
166 return q23::unexpected(u"Failed to create the sampler"_s);
167
171 };
172 if (!uniformBuffer->create())
173 return q23::unexpected(u"Failed to create the uniform buffer"_s);
174
178 0,
184 });
185 if (!srb->create())
186 return q23::unexpected(u"Failed to create the shader resource bindings"_s);
187
188 // A single full-screen quad (vertexPosition: vec4, vertexTexCoord: vec2, interleaved),
189 // matching the vertex layout every one of this module's video shaders expects.
190 static constexpr float vertexData[] = {
191 // x, y, z, w, u, v
192 -1.f, -1.f, 0.f, 1.f, 0.f, 0.f, //
193 1.f, -1.f, 0.f, 1.f, 1.f, 0.f, //
194 -1.f, 1.f, 0.f, 1.f, 0.f, 1.f, //
195 1.f, 1.f, 0.f, 1.f, 1.f, 1.f,
196 };
199 };
200 if (!vertexBuffer->create())
201 return q23::unexpected(u"Failed to create the vertex buffer"_s);
202
204 inputLayout.setBindings({ { 6 * sizeof(float) } });
206 { 0, 0, QRhiVertexInputAttribute::Float4, 0 },
207 { 0, 1, QRhiVertexInputAttribute::Float2, 4 * sizeof(float) },
208 });
209
214 });
219 if (!pipeline->create())
220 return q23::unexpected(u"Failed to create the graphics pipeline"_s);
221
222 QRhiCommandBuffer *cb = nullptr;
224 return q23::unexpected(u"QRhi::beginOffscreenFrame failed"_s);
225
228
230 const QMatrix4x4 identity;
233 uniformData.opacity = 1.f;
235
236 cb->beginPass(renderTarget.get(), Qt::black, { 1.0f, 0 }, batch);
238 cb->setViewport({ 0, 0, float(size.width()), float(size.height()) });
242 cb->draw(4);
243 cb->endPass();
244
249
251
252 return result.data;
253}
254
255#endif // QT_CONFIG(opengl)
256
257} // namespace QtMultimediaTest
258
259QT_END_NAMESPACE
Combined button and popup list for selecting options.
q23::expected< QByteArray, QString > readBackPlane(QRhi &rhi, quint64 handle, QSize planeSize, QRhiTexture::Format format)
std::unique_ptr< QRhi > createNullRhi()