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
qmultimedia_drm_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 LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
5
6#include <QtCore/qdebug.h>
7
9
10using namespace Qt::StringLiterals;
11
12namespace QtMultimediaPrivate {
13
14namespace {
15
16// see DRM_FORMAT_MOD_VENDOR_* in drm_fourcc.h
17QString modifierVendorName(uint8_t vendor)
18{
19 switch (vendor) {
20 case 0x00:
21 return u"none"_s;
22 case 0x01:
23 return u"Intel"_s;
24 case 0x02:
25 return u"AMD"_s;
26 case 0x03:
27 return u"NVIDIA"_s;
28 case 0x04:
29 return u"Samsung"_s;
30 case 0x05:
31 return u"Qualcomm"_s;
32 case 0x06:
33 return u"Vivante"_s;
34 case 0x07:
35 return u"Broadcom"_s;
36 case 0x08:
37 return u"ARM"_s;
38 case 0x09:
39 return u"Allwinner"_s;
40 case 0x0a:
41 return u"Amlogic"_s;
42 default:
43 return u"unknown vendor 0x%1"_s.arg(vendor, 2, 16, u'0');
44 }
45}
46
47// Decodes DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(c, s, g, k, h) per the bitfield
48// layout documented in drm_fourcc.h.
49QString decodeNvidiaModifier(uint64_t payload)
50{
51 if (payload == 1)
52 return u"Tegra tiled"_s;
53 if (!(payload & 0x10))
54 return u"unknown layout, raw 0x%1"_s.arg(payload, 14, 16, u'0');
55
56 const uint32_t h = payload & 0xf;
57 const uint32_t k = (payload >> 12) & 0xff;
58 const uint32_t g = (payload >> 20) & 0x3;
59 const uint32_t s = (payload >> 22) & 0x1;
60 const uint32_t c = (payload >> 23) & 0x7;
61
62 static const QString gobHeights[] = {
63 u"8, Fermi-Volta/Tegra K1+ page kind mapping"_s,
64 u"4, G80-GT2XX page kind mapping"_s,
65 u"8, Turing+ page kind mapping"_s,
66 u"reserved"_s,
67 };
68 static const QString compressionKinds[] = {
69 u"none"_s, u"ROP/3D layout 1"_s, u"ROP/3D layout 2"_s, u"CDE horizontal"_s,
70 u"CDE vertical"_s, u"reserved"_s, u"reserved"_s, u"reserved"_s,
71 };
72
73 return u"block-linear, block height 2^%1 GOBs, page kind 0x%2, GOB height %3, "
74 "sector layout: %4, compression: %5"_s.arg(h)
75 .arg(k, 2, 16, u'0')
76 .arg(gobHeights[g])
77 .arg(s ? u"desktop GPU / Tegra Xavier+"_s : u"Tegra K1 - Parker/TX2"_s)
78 .arg(compressionKinds[c]);
79}
80
81// see I915_FORMAT_MOD_* in drm_fourcc.h
82QString decodeIntelModifier(uint64_t payload)
83{
84 switch (payload) {
85 case 1:
86 return u"X tiled"_s;
87 case 2:
88 return u"Y tiled"_s;
89 case 3:
90 return u"Yf tiled"_s;
91 case 4:
92 return u"Y tiled, CCS"_s;
93 case 5:
94 return u"Yf tiled, CCS"_s;
95 case 6:
96 return u"Y tiled, Gen12 render compression CCS"_s;
97 case 7:
98 return u"Y tiled, Gen12 media compression CCS"_s;
99 case 8:
100 return u"Y tiled, Gen12 render compression CCS with clear color"_s;
101 case 9:
102 return u"4 tiled"_s;
103 case 10:
104 return u"4 tiled, DG2 render compression CCS"_s;
105 case 11:
106 return u"4 tiled, DG2 media compression CCS"_s;
107 case 12:
108 return u"4 tiled, DG2 render compression CCS with clear color"_s;
109 default:
110 return u"unknown layout, raw 0x%1"_s.arg(payload, 14, 16, u'0');
111 }
112}
113
114// see AMD_FMT_MOD_* in drm_fourcc.h
115QString decodeAmdModifier(uint64_t payload)
116{
117 const uint32_t tileVersion = payload & 0xff;
118 if (tileVersion == 0)
119 return u"GFX8 or older, linear-compatible"_s;
120
121 static const QString tileVersions[] = {
122 {}, u"GFX9"_s, u"GFX10"_s, u"GFX10 RBPlus"_s, u"GFX11"_s,
123 };
124 static const QString dccBlockSizes[] = {
125 u"64B"_s,
126 u"128B"_s,
127 u"256B"_s,
128 u"reserved"_s,
129 };
130
131 const uint32_t tile = (payload >> 8) & 0x1f;
132 const bool dcc = (payload >> 13) & 0x1;
133
134 QString result = u"tile version %1, tile mode %2"_s
135 .arg(tileVersion < std::size(tileVersions) ? tileVersions[tileVersion]
136 : u"unknown"_s)
137 .arg(tile);
138 if (dcc) {
139 const bool dccRetile = (payload >> 14) & 0x1;
140 const bool dccPipeAlign = (payload >> 15) & 0x1;
141 const uint32_t dccMaxCompressedBlock = (payload >> 18) & 0x3;
142 result += u", DCC (retile: %1, pipe-aligned: %2, max compressed block: %3)"_s
143 .arg(dccRetile ? u"yes"_s : u"no"_s)
144 .arg(dccPipeAlign ? u"yes"_s : u"no"_s)
145 .arg(dccBlockSizes[dccMaxCompressedBlock]);
146 }
147 return result;
148}
149
150// see DRM_FORMAT_MOD_ARM_* and AFBC_FORMAT_MOD_* in drm_fourcc.h
151QString decodeArmModifier(uint64_t payload)
152{
153 const uint32_t type = (payload >> 52) & 0xf;
154 const uint64_t value = payload & 0x000fffffffffffffULL;
155
156 if (type != 0x00) // DRM_FORMAT_MOD_ARM_TYPE_AFBC
157 return u"type 0x%1, raw 0x%2"_s.arg(type).arg(value, 13, 16, u'0');
158
159 static const QString blockSizes[] = {
160 u"none"_s, u"16x16"_s, u"32x8"_s, u"64x4"_s, u"32x8_64x4"_s,
161 };
162 const uint32_t blockSize = value & 0xf;
163
164 QStringList flags;
165 if (value & (1ULL << 4))
166 flags << u"YTR"_s;
167 if (value & (1ULL << 5))
168 flags << u"split"_s;
169 if (value & (1ULL << 6))
170 flags << u"sparse"_s;
171 if (value & (1ULL << 7))
172 flags << u"CBR"_s;
173 if (value & (1ULL << 8))
174 flags << u"tiled"_s;
175 if (value & (1ULL << 9))
176 flags << u"SC"_s;
177 if (value & (1ULL << 10))
178 flags << u"double-buffered"_s;
179 if (value & (1ULL << 11))
180 flags << u"block-channel"_s;
181 if (value & (1ULL << 12))
182 flags << u"USM"_s;
183
184 return u"AFBC, superblock size %1%2"_s
185 .arg(blockSize < std::size(blockSizes) ? blockSizes[blockSize] : u"unknown"_s)
186 .arg(flags.isEmpty() ? QString() : u", flags: "_s + flags.join(u'|'));
187}
188
189// see DRM_FORMAT_MOD_BROADCOM_* in drm_fourcc.h
190QString decodeBroadcomModifier(uint64_t payload)
191{
192 const uint64_t mod = payload & 0xff;
193 const uint64_t param = (payload >> 8) & 0xffffffffffffULL;
194
195 switch (mod) {
196 case 1:
197 return u"VC4 T-tiled"_s;
198 case 2:
199 return u"SAND32, column height %1"_s.arg(param);
200 case 3:
201 return u"SAND64, column height %1"_s.arg(param);
202 case 4:
203 return u"SAND128, column height %1"_s.arg(param);
204 case 5:
205 return u"SAND256, column height %1"_s.arg(param);
206 case 6:
207 return u"UIF"_s;
208 default:
209 return u"unknown layout, raw 0x%1"_s.arg(payload, 14, 16, u'0');
210 }
211}
212
213// see DRM_FORMAT_MOD_QCOM_* in drm_fourcc.h
214QString decodeQualcommModifier(uint64_t payload)
215{
216 switch (payload) {
217 case 1:
218 return u"compressed"_s;
219 case 2:
220 return u"alternate tiled"_s;
221 case 3:
222 return u"tiled"_s;
223 default:
224 return u"unknown layout, raw 0x%1"_s.arg(payload, 14, 16, u'0');
225 }
226}
227
228// see DRM_FORMAT_MOD_VIVANTE_* in drm_fourcc.h
229QString decodeVivanteModifier(uint64_t payload)
230{
231 switch (payload) {
232 case 1:
233 return u"4x4 tiled"_s;
234 case 2:
235 return u"64x64 super-tiled"_s;
236 case 3:
237 return u"4x4 tiled, split (dual-pipe)"_s;
238 case 4:
239 return u"64x64 super-tiled, split (dual-pipe)"_s;
240 default:
241 return u"unknown layout, raw 0x%1"_s.arg(payload, 14, 16, u'0');
242 }
243}
244
245// see DRM_FORMAT_MOD_SAMSUNG_* in drm_fourcc.h
246QString decodeSamsungModifier(uint64_t payload)
247{
248 switch (payload) {
249 case 1:
250 return u"64x32 tiled"_s;
251 case 2:
252 return u"16x16 tiled"_s;
253 default:
254 return u"unknown layout, raw 0x%1"_s.arg(payload, 14, 16, u'0');
255 }
256}
257
258// see DRM_FORMAT_MOD_ALLWINNER_TILED in drm_fourcc.h
259QString decodeAllwinnerModifier(uint64_t payload)
260{
261 if (payload == 1)
262 return u"tiled"_s;
263 return u"unknown layout, raw 0x%1"_s.arg(payload, 14, 16, u'0');
264}
265
266// see DRM_FORMAT_MOD_AMLOGIC_FBC in drm_fourcc.h
267QString decodeAmlogicModifier(uint64_t payload)
268{
269 const uint32_t layout = payload & 0xff;
270 const uint32_t options = (payload >> 8) & 0xff;
271
272 QString result;
273 switch (layout) {
274 case 1:
275 result = u"FBC basic layout"_s;
276 break;
277 case 2:
278 result = u"FBC scatter layout"_s;
279 break;
280 default:
281 return u"unknown layout, raw 0x%1"_s.arg(payload, 14, 16, u'0');
282 }
283
284 if (options & 0x1)
285 result += u", memory saving"_s;
286 return result;
287}
288
289} // namespace
290
292{
293 const uint32_t code = qToUnderlying(format);
294 QString result;
295 for (int i = 0; i < 4; ++i) {
296 const char c = char((code >> (8 * i)) & 0xff);
297 result += QChar(c == ' ' ? u'_' : c);
298 }
299 return result;
300}
301
302QDebug operator<<(QDebug debug, DRMFormat format)
303{
304 const QDebugStateSaver saver(debug);
305 debug.nospace().noquote() << "DRMFormat(0x" << Qt::hex << qToUnderlying(format) << Qt::dec
306 << ", " << toString(format) << ')';
307 return debug;
308}
309
311{
312 if (modifier == DrmFormatModifierLinear)
313 return u"linear"_s;
314 if (modifier == DmaBufFormatModifierInvalid)
315 return u"invalid"_s;
316
317 const uint64_t value = qToUnderlying(modifier);
318 const uint8_t vendor = uint8_t(value >> 56);
319 const uint64_t payload = value & ((uint64_t(1) << 56) - 1);
320 const QString vendorName = modifierVendorName(vendor);
321
322 switch (vendor) {
323 case 0x01:
324 return vendorName + u", "_s + decodeIntelModifier(payload);
325 case 0x02:
326 return vendorName + u", "_s + decodeAmdModifier(payload);
327 case 0x03:
328 return vendorName + u", "_s + decodeNvidiaModifier(payload);
329 case 0x04:
330 return vendorName + u", "_s + decodeSamsungModifier(payload);
331 case 0x05:
332 return vendorName + u", "_s + decodeQualcommModifier(payload);
333 case 0x06:
334 return vendorName + u", "_s + decodeVivanteModifier(payload);
335 case 0x07:
336 return vendorName + u", "_s + decodeBroadcomModifier(payload);
337 case 0x08:
338 return vendorName + u", "_s + decodeArmModifier(payload);
339 case 0x09:
340 return vendorName + u", "_s + decodeAllwinnerModifier(payload);
341 case 0x0a:
342 return vendorName + u", "_s + decodeAmlogicModifier(payload);
343 default:
344 return u"%1, vendor-specific payload 0x%2"_s.arg(vendorName).arg(payload, 14, 16, u'0');
345 }
346}
347
348QDebug operator<<(QDebug debug, DRMModifier modifier)
349{
350 const QDebugStateSaver saver(debug);
351 debug.nospace().noquote() << "DRMModifier(0x" << Qt::hex << qToUnderlying(modifier) << Qt::dec
352 << ", " << toString(modifier) << ')';
353 return debug;
354}
355
356} // namespace QtMultimediaPrivate
357
358QT_END_NAMESPACE
Combined button and popup list for selecting options.
QString toString(DRMModifier modifier)
QString toString(DRMFormat format)