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(vulkan)
56{
60 if (!vulkanInstance->create())
61 return q23::unexpected(u"QVulkanInstance::create failed"_s);
62
68 };
69 if (!rhi) {
70 return q23::unexpected(u"QRhi::create failed"_s);
71 }
72 return OffscreenVulkanRhi{
74 std::move(rhi),
75 };
76}
77#endif
78
79#if QT_CONFIG(metal)
81{
84}
85#endif
86
87#if defined(Q_OS_WIN)
89{
92}
93
95{
99
101 return std::unique_ptr<QRhi>{ QRhi::create(QRhi::D3D11, &params, {}, &nativeHandles) };
102}
103
105{
107 return std::unique_ptr<QRhi>{ QRhi::create(QRhi::D3D12, &params) };
108}
109
110#endif
111
112q23::expected<QByteArray, QString> readBackPlane(QRhi &rhi, quint64 handle, QSize planeSize,
113 QRhiTexture::Format format)
114{
115 std::unique_ptr<QRhiTexture> texture(
116 rhi.newTexture(format, planeSize, 1, QRhiTexture::UsedAsTransferSource));
117 if (!texture->createFrom(QRhiTexture::NativeTexture{ handle, 0 }))
118 return q23::unexpected(u"QRhiTexture::createFrom failed"_s);
119
120 QRhiResourceUpdateBatch *batch = rhi.nextResourceUpdateBatch();
121 QRhiReadbackResult result;
122 batch->readBackTexture(texture.get(), &result);
123
124 QRhiCommandBuffer *cb = nullptr;
125 if (rhi.beginOffscreenFrame(&cb) != QRhi::FrameOpSuccess || !cb)
126 return q23::unexpected(u"QRhi::beginOffscreenFrame failed"_s);
127 cb->resourceUpdate(batch);
128 rhi.endOffscreenFrame();
129
130 return result.data;
131}
132
133#if QT_CONFIG(opengl)
134
135namespace {
136
138{
139 QFile file(path);
141 return q23::unexpected(u"Could not open shader file: "_s + path);
143 if (!shader.isValid())
144 return q23::unexpected(u"Invalid/unsupported shader file: "_s + path);
145 return shader;
146}
147
148} // namespace
149
150// Unlike readBackPlane(), EXTERNAL_OES textures can't be read back directly: they're only
151// consumable by a shader (samplerExternalOES). Renders the texture through a full-screen quad
152// using this module's own externalsampler shader into a plain RGBA8 target, then reads that back.
154{
157 };
159 return q23::unexpected(u"Failed to wrap the native handle as an ExternalOES QRhiTexture"_s);
160
164 };
165 if (!targetTexture->create())
166 return q23::unexpected(u"Failed to create the readback render target texture"_s);
167
171 };
174 };
176 if (!renderTarget->create())
177 return q23::unexpected(u"Failed to create the readback render target"_s);
178
181 if (!vertexShader)
182 return q23::unexpected(vertexShader.error());
184 if (!fragmentShader)
186
190 };
191 if (!sampler->create())
192 return q23::unexpected(u"Failed to create the sampler"_s);
193
197 };
198 if (!uniformBuffer->create())
199 return q23::unexpected(u"Failed to create the uniform buffer"_s);
200
204 0,
210 });
211 if (!srb->create())
212 return q23::unexpected(u"Failed to create the shader resource bindings"_s);
213
214 // A single full-screen quad (vertexPosition: vec4, vertexTexCoord: vec2, interleaved),
215 // matching the vertex layout every one of this module's video shaders expects.
216 static constexpr float vertexData[] = {
217 // x, y, z, w, u, v
218 -1.f, -1.f, 0.f, 1.f, 0.f, 0.f, //
219 1.f, -1.f, 0.f, 1.f, 1.f, 0.f, //
220 -1.f, 1.f, 0.f, 1.f, 0.f, 1.f, //
221 1.f, 1.f, 0.f, 1.f, 1.f, 1.f,
222 };
225 };
226 if (!vertexBuffer->create())
227 return q23::unexpected(u"Failed to create the vertex buffer"_s);
228
230 inputLayout.setBindings({ { 6 * sizeof(float) } });
232 { 0, 0, QRhiVertexInputAttribute::Float4, 0 },
233 { 0, 1, QRhiVertexInputAttribute::Float2, 4 * sizeof(float) },
234 });
235
240 });
245 if (!pipeline->create())
246 return q23::unexpected(u"Failed to create the graphics pipeline"_s);
247
248 QRhiCommandBuffer *cb = nullptr;
250 return q23::unexpected(u"QRhi::beginOffscreenFrame failed"_s);
251
254
256 const QMatrix4x4 identity;
259 uniformData.opacity = 1.f;
261
262 cb->beginPass(renderTarget.get(), Qt::black, { 1.0f, 0 }, batch);
264 cb->setViewport({ 0, 0, float(size.width()), float(size.height()) });
268 cb->draw(4);
269 cb->endPass();
270
275
277
278 return result.data;
279}
280
281#endif // QT_CONFIG(opengl)
282
283} // namespace QtMultimediaTest
284
285QT_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()