Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qssgrendershaderkeys_p.h
Go to the documentation of this file.
1// Copyright (C) 2008-2012 NVIDIA Corporation.
2// Copyright (C) 2019 The Qt Company Ltd.
3// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
4
5#ifndef QSSG_RENDER_SHADER_KEY_H
6#define QSSG_RENDER_SHADER_KEY_H
7
8//
9// W A R N I N G
10// -------------
11//
12// This file is not part of the Qt API. It exists purely as an
13// implementation detail. This header file may change from version to
14// version without notice, or even be removed.
15//
16// We mean it.
17//
18
19#include <QtQuick3DUtils/private/qssgdataref_p.h>
20#include <QtQuick3DUtils/private/qssgrenderbasetypes_p.h>
21#include <QtQuick3DRuntimeRender/private/qssgrenderdefaultmaterial_p.h>
22#include <QtQuick3DRuntimeRender/private/qssgrhicontext_p.h>
23
25// We have an ever expanding set of properties we like to hash into one or more 32 bit
26// quantities.
27// Furthermore we would like this set of properties to be convertable to string
28// So the shader cache file itself is somewhat human readable/diagnosable.
29// To do this we create a set of objects that act as properties to the master shader key.
30// These objects are tallied in order to figure out their actual offset into the shader key's
31// data store. They are also run through in order to create the string shader cache key.
32
34{
37 explicit constexpr QSSGShaderKeyPropertyBase(const char *inName = "") : name(inName), offset(0) {}
38 quint32 getOffset() const { return offset; }
39 void setOffset(quint32 of) { offset = of; }
40
41 template<quint32 TBitWidth>
43 {
44 quint32 bit = offset % 32;
45 quint32 startValue = (1 << TBitWidth) - 1;
46 quint32 mask = startValue << bit;
47 return mask;
48 }
49
50 quint32 getIdx() const { return offset / 32; }
51
52protected:
53 void internalToString(QByteArray &ioStr, const QByteArrayView &inBuffer) const
54 {
55 ioStr.append(name);
56 ioStr.append('=');
57 ioStr.append(inBuffer);
58 }
59
60 static void internalToString(QByteArray &ioStr, const QByteArrayView &name, bool inValue)
61 {
62 if (inValue) {
63 ioStr.append(name);
64 ioStr.append('=');
65 ioStr.append(inValue ? QByteArrayView("true") : QByteArrayView("false"));
66 }
67 }
68 static bool getBoolValue(const QByteArray& str, const QByteArrayView &name)
69 {
70 const int index = str.indexOf(name);
71 if (index < 0)
72 return false;
73 const qsizetype nameLen = name.size();
74 if (str[index + nameLen] != '=')
75 return false;
76 if (str.mid(index + nameLen + 1, 4) == QByteArrayView("true"))
77 return true;
78 return false;
79 }
80};
81
83{
84 enum {
86 };
87
88 explicit constexpr QSSGShaderKeyBoolean(const char *inName = "") : QSSGShaderKeyPropertyBase(inName) {}
89
90 quint32 getMask() const { return getMaskTemplate<BitWidth>(); }
91 void setValue(QSSGDataRef<quint32> inDataStore, bool inValue) const
92 {
93 const qint32 idx = qint32(getIdx());
94 Q_ASSERT(idx >= 0 && idx <= INT32_MAX);
95 Q_ASSERT(inDataStore.size() > idx);
97 quint32 &target = inDataStore[idx];
98 if (inValue) {
99 target = target | mask;
100 } else {
101 mask = ~mask;
102 target = target & mask;
103 }
104 }
105
106 bool getValue(QSSGDataView<quint32> inDataStore) const
107 {
108 quint32 idx = getIdx();
109 quint32 mask = getMask();
110 const quint32 &target = inDataStore[idx];
111 return (target & mask) ? true : false;
112 }
113
114 void toString(QByteArray &ioStr, QSSGDataView<quint32> inKeySet) const
115 {
116 bool isHigh = getValue(inKeySet);
117 internalToString(ioStr, name, isHigh);
118 }
119 void fromString(const QByteArray &ioStr, QSSGDataRef<quint32> inKeySet)
120 {
121 setValue(inKeySet, getBoolValue(ioStr, name));
122 }
123};
124
125template<quint32 TBitWidth>
127{
128 enum {
129 BitWidth = TBitWidth,
130 };
131 explicit constexpr QSSGShaderKeyUnsigned(const char *inName = "") : QSSGShaderKeyPropertyBase(inName) {}
132 quint32 getMask() const { return getMaskTemplate<BitWidth>(); }
133 void setValue(QSSGDataRef<quint32> inDataStore, quint32 inValue) const
134 {
135 quint32 startValue = (1 << TBitWidth) - 1;
136 // Ensure inValue is within range of bit width.
137 inValue = inValue & startValue;
138 quint32 bit = offset % 32;
139 quint32 mask = getMask();
140 quint32 idx = getIdx();
141 inValue = inValue << bit;
142 quint32 &target = inDataStore[idx];
143 // Get rid of existing value
144 quint32 inverseMask = ~mask;
145 target = target & inverseMask;
146 target = target | inValue;
147 }
148
149 quint32 getValue(QSSGDataView<quint32> inDataStore) const
150 {
151 quint32 idx = getIdx();
152 quint32 bit = offset % 32;
153 quint32 mask = getMask();
154 const quint32 &target = inDataStore[idx];
155
156 quint32 retval = target & mask;
157 retval = retval >> bit;
158 return retval;
159 }
160
161 void toString(QByteArray &ioStr, QSSGDataView<quint32> inKeySet) const
162 {
163 quint32 value = getValue(inKeySet);
164 char buf[64];
165 memset(buf, 0, sizeof (buf));
166 toStr(value, toDataRef(buf, 64));
167 internalToString(ioStr, buf);
168 }
169
170 void fromString(const QByteArray &ioStr, QSSGDataRef<quint32> inKeySet)
171 {
172 const qsizetype nameLen = name.size();
173 const qsizetype strOffset = ioStr.indexOf(name);
174 if (strOffset >= 0) {
175 /* The key is stored as name=val */
176 if (ioStr[strOffset + nameLen] != '=')
177 return;
178 const QByteArray s = ioStr.right(ioStr.size() - strOffset - nameLen - 1);
179 int i = 0;
180 while (QChar(QLatin1Char(s[i])).isDigit())
181 i++;
182 const quint32 value = s.left(i).toInt();
183 setValue(inKeySet, value);
184 }
185 }
186
187private:
188 static quint32 toStr(quint32 item, QSSGDataRef<char> buffer)
189 {
190 // hope the buffer is big enough...
191 return static_cast<quint32>(::snprintf(buffer.begin(), buffer.size(), "%u", item));
192 }
193};
194
196{
198 R = 0,
199 G = 1,
200 B = 2,
201 A = 3,
202 };
203 explicit QSSGShaderKeyTextureChannel(const char *inName = "") : QSSGShaderKeyUnsigned<2>(inName) {}
204
205 TexturChannelBits getTextureChannel(QSSGDataView<quint32> inKeySet) const
206 {
207 return TexturChannelBits(getValue(inKeySet));
208 }
209
210 void setTextureChannel(TexturChannelBits channel, QSSGDataRef<quint32> inKeySet)
211 {
212 setValue(inKeySet, quint32(channel));
213 }
214 static constexpr char textureChannelToChar[4] = {
215 'R',
216 'G',
217 'B',
218 'A'
219 };
220 void toString(QByteArray &ioStr, QSSGDataView<quint32> inKeySet) const
221 {
222 ioStr.append(name);
223 ioStr.append('=');
224 ioStr.append(textureChannelToChar[getTextureChannel(inKeySet)]);
225 }
226 void fromString(const QByteArray &ioStr, QSSGDataRef<quint32> inKeySet)
227 {
228 const qsizetype nameLen = name.size();
229 const qsizetype strOffset = ioStr.indexOf(name);
230 if (strOffset >= 0) {
231 /* The key is stored as name=ch */
232 if (ioStr[strOffset + nameLen] != '=')
233 return;
234 const char ch = ioStr[strOffset + nameLen + 1];
235 if (ch == 'R')
237 else if (ch == 'G')
239 else if (ch == 'B')
241 else if (ch == 'A')
243 }
244 }
245};
246
248{
250 Enabled = 1 << 0,
251 EnvMap = 1 << 1,
252 LightProbe = 1 << 2,
253 Identity = 1 << 3,
254 UsesUV1 = 1 << 4,
255 Linear = 1 << 5
256 };
257
258 explicit QSSGShaderKeyImageMap(const char *inName = "") : QSSGShaderKeyUnsigned<6>(inName) {}
259
260 bool getBitValue(ImageMapBits imageBit, QSSGDataView<quint32> inKeySet) const
261 {
262 return (getValue(inKeySet) & imageBit) ? true : false;
263 }
264
265 void setBitValue(ImageMapBits imageBit, bool inValue, QSSGDataRef<quint32> inKeySet)
266 {
267 quint32 theValue = getValue(inKeySet);
268 quint32 mask = imageBit;
269 if (inValue) {
270 theValue = theValue | mask;
271 } else {
272 mask = ~mask;
273 theValue = theValue & mask;
274 }
275 setValue(inKeySet, theValue);
276 }
277
278 bool isEnabled(QSSGDataView<quint32> inKeySet) const { return getBitValue(Enabled, inKeySet); }
279 void setEnabled(QSSGDataRef<quint32> inKeySet, bool val) { setBitValue(Enabled, val, inKeySet); }
280
281 bool isEnvMap(QSSGDataView<quint32> inKeySet) const { return getBitValue(EnvMap, inKeySet); }
282 void setEnvMap(QSSGDataRef<quint32> inKeySet, bool val) { setBitValue(EnvMap, val, inKeySet); }
283
284 bool isLightProbe(QSSGDataView<quint32> inKeySet) const { return getBitValue(LightProbe, inKeySet); }
285 void setLightProbe(QSSGDataRef<quint32> inKeySet, bool val) { setBitValue(LightProbe, val, inKeySet); }
286
287 bool isIdentityTransform(QSSGDataView<quint32> inKeySet) const { return getBitValue(Identity, inKeySet); }
288 void setIdentityTransform(QSSGDataRef<quint32> inKeySet, bool val) { setBitValue(Identity, val, inKeySet); }
289
290 bool isUsingUV1(QSSGDataView<quint32> inKeySet) const { return getBitValue(UsesUV1, inKeySet); }
291 void setUsesUV1(QSSGDataRef<quint32> inKeySet, bool val) { setBitValue(UsesUV1, val, inKeySet); }
292
293 bool isLinear(QSSGDataView<quint32> inKeySet) const { return getBitValue(Linear, inKeySet); }
294 void setLinear(QSSGDataRef<quint32> inKeySet, bool val) { setBitValue(Linear, val, inKeySet); }
295
296 void toString(QByteArray &ioStr, QSSGDataView<quint32> inKeySet) const
297 {
298 ioStr.append(name);
299 ioStr.append(QByteArrayView("={"));
300 internalToString(ioStr, QByteArrayView("enabled"), isEnabled(inKeySet));
301 ioStr.append(';');
302 internalToString(ioStr, QByteArrayView("envMap"), isEnvMap(inKeySet));
303 ioStr.append(';');
304 internalToString(ioStr, QByteArrayView("lightProbe"), isLightProbe(inKeySet));
305 ioStr.append(';');
306 internalToString(ioStr, QByteArrayView("identity"), isIdentityTransform(inKeySet));
307 ioStr.append(';');
308 internalToString(ioStr, QByteArrayView("usesUV1"), isUsingUV1(inKeySet));
309 ioStr.append(';');
310 internalToString(ioStr, QByteArrayView("linear"), isLinear(inKeySet));
311 ioStr.append('}');
312 }
313};
314
316{
317 explicit QSSGShaderKeySpecularModel(const char *inName = "") : QSSGShaderKeyUnsigned<2>(inName) {}
318
319 void setSpecularModel(QSSGDataRef<quint32> inKeySet, QSSGRenderDefaultMaterial::MaterialSpecularModel inModel)
320 {
321 setValue(inKeySet, quint32(inModel));
322 }
323
325 {
326 return static_cast<QSSGRenderDefaultMaterial::MaterialSpecularModel>(getValue(inKeySet));
327 }
328
329 void toString(QByteArray &ioStr, QSSGDataView<quint32> inKeySet) const
330 {
331 ioStr.append(name);
332 ioStr.append('=');
333 switch (getSpecularModel(inKeySet)) {
335 ioStr.append(QByteArrayView("KGGX"));
336 break;
338 ioStr.append(QByteArrayView("Default"));
339 break;
340 }
341 ioStr.append(';');
342 }
343 void fromString(const QByteArray &ioStr, QSSGDataRef<quint32> inKeySet)
344 {
345 const qsizetype nameLen = name.size();
346 const int strOffset = ioStr.indexOf(name);
347 if (strOffset >= 0) {
348 /* The key is stored as name=specularMode; */
349 if (ioStr[strOffset + nameLen] != '=')
350 return;
351 const int codeOffsetBegin = strOffset + nameLen + 1;
352 int codeOffset = 0;
353 while (ioStr[codeOffsetBegin + codeOffset] != ';')
354 codeOffset++;
355 const QByteArray val = ioStr.mid(codeOffsetBegin, codeOffset);
356 if (val == QByteArrayView("KGGX"))
358 if (val == QByteArrayView("Default"))
360 }
361 }
362};
363
365{
366 explicit QSSGShaderKeyAlphaMode(const char *inName = "") : QSSGShaderKeyUnsigned<2>(inName) {}
367
368 void setAlphaMode(QSSGDataRef<quint32> inKeySet, QSSGRenderDefaultMaterial::MaterialAlphaMode inMode)
369 {
370 setValue(inKeySet, quint32(inMode));
371 }
372
373 QSSGRenderDefaultMaterial::MaterialAlphaMode getAlphaMode(QSSGDataView<quint32> inKeySet) const
374 {
375 return static_cast<QSSGRenderDefaultMaterial::MaterialAlphaMode>(getValue(inKeySet));
376 }
377
378 void toString(QByteArray &ioStr, QSSGDataView<quint32> inKeySet) const
379 {
380 ioStr.append(name);
381 ioStr.append('=');
382 switch (getAlphaMode(inKeySet)) {
384 ioStr.append(QByteArrayView("Default"));
385 break;
387 ioStr.append(QByteArrayView("Mask"));
388 break;
390 ioStr.append(QByteArrayView("Blend"));
391 break;
393 ioStr.append(QByteArrayView("Opaque"));
394 break;
395 }
396 ioStr.append(';');
397 }
398 void fromString(const QByteArray &ioStr, QSSGDataRef<quint32> inKeySet)
399 {
400 const qsizetype nameLen = name.size();
401 const qsizetype strOffset = ioStr.indexOf(name);
402 if (strOffset >= 0) {
403 /* The key is stored as name=alphaMode; */
404 if (ioStr[strOffset + nameLen] != '=')
405 return;
406 const int codeOffsetBegin = strOffset + nameLen + 1;
407 int codeOffset = 0;
408 while (ioStr[codeOffsetBegin + codeOffset] != ';')
409 codeOffset++;
410 const QByteArray val = ioStr.mid(codeOffsetBegin, codeOffset);
411 if (val == QByteArrayView("Default"))
413 if (val == QByteArrayView("Mask"))
415 if (val == QByteArrayView("Blend"))
417 if (val == QByteArrayView("Opaque"))
419 }
420 }
421};
422
424{
426 Position = 1 << 0,
427 Normal = 1 << 1,
428 TexCoord0 = 1 << 2,
429 TexCoord1 = 1 << 3,
430 Tangent = 1 << 4,
431 Binormal = 1 << 5,
432 Color = 1 << 6,
434 TexCoordLightmap = 1 << 8
435 };
436
437 explicit QSSGShaderKeyVertexAttribute(const char *inName = "") : QSSGShaderKeyUnsigned<9>(inName) {}
438
439 bool getBitValue(VertexAttributeBits bit, QSSGDataView<quint32> inKeySet) const
440 {
441 return (getValue(inKeySet) & bit) ? true : false;
442 }
443 void setBitValue(VertexAttributeBits bit, QSSGDataRef<quint32> inKeySet, bool value) const
444 {
445 quint32 v = getValue(inKeySet);
446 v = value ? (v | bit) : (v & ~bit);
447 setValue(inKeySet, v);
448 }
449
450 void toString(QByteArray &ioStr, QSSGDataView<quint32> inKeySet) const
451 {
452 ioStr.append(name);
453 ioStr.append(QByteArrayView("={"));
454 internalToString(ioStr, QByteArrayView("position"), getBitValue(Position, inKeySet));
455 ioStr.append(';');
456 internalToString(ioStr, QByteArrayView("normal"), getBitValue(Normal, inKeySet));
457 ioStr.append(';');
458 internalToString(ioStr, QByteArrayView("texcoord0"), getBitValue(TexCoord0, inKeySet));
459 ioStr.append(';');
460 internalToString(ioStr, QByteArrayView("texcoord1"), getBitValue(TexCoord1, inKeySet));
461 ioStr.append(';');
462 internalToString(ioStr, QByteArrayView("tangent"), getBitValue(Tangent, inKeySet));
463 ioStr.append(';');
464 internalToString(ioStr, QByteArrayView("binormal"), getBitValue(Binormal, inKeySet));
465 ioStr.append(';');
466 internalToString(ioStr, QByteArrayView("color"), getBitValue(Color, inKeySet));
467 ioStr.append(';');
468 internalToString(ioStr, QByteArrayView("texcoordlightmap"), getBitValue(TexCoordLightmap, inKeySet));
469 ioStr.append('}');
470 internalToString(ioStr, QByteArrayView("joint&weight"), getBitValue(JointAndWeight, inKeySet));
471 ioStr.append('}');
472 }
473 void fromString(const QByteArray &ioStr, QSSGDataRef<quint32> inKeySet)
474 {
475 const qsizetype nameLen = name.size();
476 const qsizetype strOffset = ioStr.indexOf(name);
477 if (strOffset >= 0) {
478 /* The key is stored as name={;;;;;;} */
479 if (ioStr[strOffset + nameLen] != '=')
480 return;
481 if (ioStr[strOffset + nameLen + 1] != '{')
482 return;
483 const int codeOffsetBegin = strOffset + nameLen + 2;
484 int codeOffset = 0;
485 while (ioStr[codeOffsetBegin + codeOffset] != '}')
486 codeOffset++;
487 const QByteArray val = ioStr.mid(codeOffsetBegin, codeOffset);
488 const QVector<QByteArray> list = val.split(';');
489 if (list.size() != 8)
490 return;
491 setBitValue(Position, inKeySet, getBoolValue(list[0], QByteArrayView("position")));
492 setBitValue(Normal, inKeySet, getBoolValue(list[1], QByteArrayView("normal")));
493 setBitValue(TexCoord0, inKeySet, getBoolValue(list[2], QByteArrayView("texcoord0")));
494 setBitValue(TexCoord1, inKeySet, getBoolValue(list[3], QByteArrayView("texcoord1")));
495 setBitValue(Tangent, inKeySet, getBoolValue(list[4], QByteArrayView("tangent")));
496 setBitValue(Binormal, inKeySet, getBoolValue(list[5], QByteArrayView("binormal")));
497 setBitValue(Color, inKeySet, getBoolValue(list[6], QByteArrayView("color")));
498 setBitValue(TexCoordLightmap, inKeySet, getBoolValue(list[7], QByteArrayView("texcoordlightmap")));
499 }
500 }
501};
502
504{
505 enum {
507 };
508 enum {
510 };
550
553 QSSGShaderKeyUnsigned<4> m_lightCount;
568 QSSGShaderKeyUnsigned<16> m_vertexColorRedMask;
569 QSSGShaderKeyUnsigned<16> m_vertexColorGreenMask;
570 QSSGShaderKeyUnsigned<16> m_vertexColorBlueMask;
571 QSSGShaderKeyUnsigned<16> m_vertexColorAlphaMask;
575 QSSGShaderKeyUnsigned<16> m_boneCount;
587 QSSGShaderKeyUnsigned<8> m_targetCount;
588 QSSGShaderKeyUnsigned<8> m_targetPositionOffset;
589 QSSGShaderKeyUnsigned<8> m_targetNormalOffset;
590 QSSGShaderKeyUnsigned<8> m_targetTangentOffset;
591 QSSGShaderKeyUnsigned<8> m_targetBinormalOffset;
592 QSSGShaderKeyUnsigned<8> m_targetTexCoord0Offset;
593 QSSGShaderKeyUnsigned<8> m_targetTexCoord1Offset;
594 QSSGShaderKeyUnsigned<8> m_targetColorOffset;
601 QSSGShaderKeyUnsigned<4> m_debugMode;
603 QSSGShaderKeyUnsigned<3> m_viewCount;
605
607 : m_hasLighting("hasLighting")
608 , m_hasIbl("hasIbl")
609 , m_lightCount("lightCount")
610 , m_specularEnabled("specularEnabled")
611 , m_fresnelEnabled("fresnelEnabled")
612 , m_baseColorSingleChannelEnabled("baseColorSingleChannelEnabled")
613 , m_specularSingleChannelEnabled("specularSingleChannelEnabled")
614 , m_emissiveSingleChannelEnabled("emissiveSingleChannelEnabled")
615 , m_invertOpacityMapValue("invertOpacityMapValue")
616 , m_vertexColorsEnabled("vertexColorsEnabled")
617 , m_vertexColorsMaskEnabled("vertexColorsMaskEnabled")
618 , m_vertexColorRedMask("vertexColorRedMask")
619 , m_vertexColorGreenMask("vertexColorGreenMask")
620 , m_vertexColorBlueMask("vertexColorBlueMask")
621 , m_vertexColorAlphaMask("vertexColorAlphaMask")
622 , m_specularModel("specularModel")
623 , m_boneCount("boneCount")
624 , m_isDoubleSided("isDoubleSided")
625 , m_overridesPosition("overridesPosition")
626 , m_usesProjectionMatrix("usesProjectionMatrix")
627 , m_usesInverseProjectionMatrix("usesInverseProjectionMatrix")
628 , m_usesPointsTopology("usesPointsTopology")
629 , m_usesVarColor("usesVarColor")
630 , m_alphaMode("alphaMode")
631 , m_vertexAttributes("vertexAttributes")
632 , m_usesFloatJointIndices("usesFloatJointIndices")
633 , m_usesInstancing("usesInstancing")
634 , m_targetCount("targetCount")
635 , m_targetPositionOffset("targetPositionOffset")
636 , m_targetNormalOffset("targetNormalOffset")
637 , m_targetTangentOffset("targetTangentOffset")
638 , m_targetBinormalOffset("targetBinormalOffset")
639 , m_targetTexCoord0Offset("targetTexCoord0Offset")
640 , m_targetTexCoord1Offset("targetTexCoord1Offset")
641 , m_targetColorOffset("targetColorOffset")
642 , m_blendParticles("blendParticles")
643 , m_clearcoatEnabled("clearcoatEnabled")
644 , m_transmissionEnabled("transmissionEnabled")
645 , m_specularAAEnabled("specularAAEnabled")
646 , m_lightmapEnabled("lightmapEnabled")
647 , m_specularGlossyEnabled("specularGlossyEnabled")
648 , m_debugMode("debugMode")
649 , m_fogEnabled("fogEnabled")
650 , m_viewCount("viewCount")
651 , m_usesViewIndex("usesViewIndex")
652 {
653 m_lightFlags[0].name = "light0HasPosition";
654 m_lightFlags[1].name = "light1HasPosition";
655 m_lightFlags[2].name = "light2HasPosition";
656 m_lightFlags[3].name = "light3HasPosition";
657 m_lightFlags[4].name = "light4HasPosition";
658 m_lightFlags[5].name = "light5HasPosition";
659 m_lightFlags[6].name = "light6HasPosition";
660 m_lightFlags[7].name = "light7HasPosition";
661 m_lightFlags[8].name = "light8HasPosition";
662 m_lightFlags[9].name = "light9HasPosition";
663 m_lightFlags[10].name = "light10HasPosition";
664 m_lightFlags[11].name = "light11HasPosition";
665 m_lightFlags[12].name = "light12HasPosition";
666 m_lightFlags[13].name = "light13HasPosition";
667 m_lightFlags[14].name = "light14HasPosition";
668
669 m_lightSpotFlags[0].name = "light0HasSpot";
670 m_lightSpotFlags[1].name = "light1HasSpot";
671 m_lightSpotFlags[2].name = "light2HasSpot";
672 m_lightSpotFlags[3].name = "light3HasSpot";
673 m_lightSpotFlags[4].name = "light4HasSpot";
674 m_lightSpotFlags[5].name = "light5HasSpot";
675 m_lightSpotFlags[6].name = "light6HasSpot";
676 m_lightSpotFlags[7].name = "light7HasSpot";
677 m_lightSpotFlags[8].name = "light8HasSpot";
678 m_lightSpotFlags[9].name = "light9HasSpot";
679 m_lightSpotFlags[10].name = "light10HasSpot";
680 m_lightSpotFlags[11].name = "light11HasSpot";
681 m_lightSpotFlags[12].name = "light12HasSpot";
682 m_lightSpotFlags[13].name = "light13HasSpot";
683 m_lightSpotFlags[14].name = "light14HasSpot";
684
685 m_lightAreaFlags[0].name = "light0HasArea";
686 m_lightAreaFlags[1].name = "light1HasArea";
687 m_lightAreaFlags[2].name = "light2HasArea";
688 m_lightAreaFlags[3].name = "light3HasArea";
689 m_lightAreaFlags[4].name = "light4HasArea";
690 m_lightAreaFlags[5].name = "light5HasArea";
691 m_lightAreaFlags[6].name = "light6HasArea";
692 m_lightAreaFlags[7].name = "light7HasArea";
693 m_lightAreaFlags[8].name = "light8HasArea";
694 m_lightAreaFlags[9].name = "light9HasArea";
695 m_lightAreaFlags[10].name = "light10HasArea";
696 m_lightAreaFlags[11].name = "light11HasArea";
697 m_lightAreaFlags[12].name = "light12HasArea";
698 m_lightAreaFlags[13].name = "light13HasArea";
699 m_lightAreaFlags[14].name = "light14HasArea";
700
701 m_lightShadowFlags[0].name = "light0HasShadow";
702 m_lightShadowFlags[1].name = "light1HasShadow";
703 m_lightShadowFlags[2].name = "light2HasShadow";
704 m_lightShadowFlags[3].name = "light3HasShadow";
705 m_lightShadowFlags[4].name = "light4HasShadow";
706 m_lightShadowFlags[5].name = "light5HasShadow";
707 m_lightShadowFlags[6].name = "light6HasShadow";
708 m_lightShadowFlags[7].name = "light7HasShadow";
709 m_lightShadowFlags[8].name = "light8HasShadow";
710 m_lightShadowFlags[9].name = "light9HasShadow";
711 m_lightShadowFlags[10].name = "light10HasShadow";
712 m_lightShadowFlags[11].name = "light11HasShadow";
713 m_lightShadowFlags[12].name = "light12HasShadow";
714 m_lightShadowFlags[13].name = "light13HasShadow";
715 m_lightShadowFlags[14].name = "light14HasShadow";
716
717 m_imageMaps[0].name = "diffuseMap";
718 m_imageMaps[1].name = "emissiveMap";
719 m_imageMaps[2].name = "specularMap";
720 m_imageMaps[3].name = "baseColorMap";
721 m_imageMaps[4].name = "bumpMap";
722 m_imageMaps[5].name = "specularAmountMap";
723 m_imageMaps[6].name = "normalMap";
724 m_imageMaps[7].name = "clearcoatNormalMap";
725 m_imageMaps[8].name = "opacityMap";
726 m_imageMaps[9].name = "roughnessMap";
727 m_imageMaps[10].name = "metalnessMap";
728 m_imageMaps[11].name = "occlusionMap";
729 m_imageMaps[12].name = "translucencyMap";
730 m_imageMaps[13].name = "heightMap";
731 m_imageMaps[14].name = "clearcoatMap";
732 m_imageMaps[15].name = "clearcoatRoughnessMap";
733 m_imageMaps[16].name = "transmissionMap";
734 m_imageMaps[17].name = "thicknessMap";
735
736 m_textureChannels[0].name = "opacityMap_channel";
737 m_textureChannels[1].name = "roughnessMap_channel";
738 m_textureChannels[2].name = "metalnessMap_channel";
739 m_textureChannels[3].name = "occlusionMap_channel";
740 m_textureChannels[4].name = "translucencyMap_channel";
741 m_textureChannels[5].name = "heightMap_channel";
742 m_textureChannels[6].name = "clearcoatMap_channel";
743 m_textureChannels[7].name = "clearcoatRoughnessMap_channel";
744 m_textureChannels[8].name = "transmissionMap_channel";
745 m_textureChannels[9].name = "thicknessMap_channel";
746 m_textureChannels[10].name = "baseColorMap_channel";
747 m_textureChannels[11].name = "specularAmountMap_channel";
748
749 init();
750 }
751
752 template<typename TVisitor>
753 void visitProperties(TVisitor &inVisitor)
754 {
755 inVisitor.visit(m_hasLighting);
756 inVisitor.visit(m_hasIbl);
757 inVisitor.visit(m_lightCount);
758
759 for (auto &lightFlag : m_lightFlags)
760 inVisitor.visit(lightFlag);
761
762 for (auto &lightSpotFlag : m_lightSpotFlags)
763 inVisitor.visit(lightSpotFlag);
764
765 for (auto &lightAreaFlag : m_lightAreaFlags)
766 inVisitor.visit(lightAreaFlag);
767
768 for (auto &lightShadowFlag : m_lightShadowFlags)
769 inVisitor.visit(lightShadowFlag);
770
771 inVisitor.visit(m_specularEnabled);
772 inVisitor.visit(m_fresnelEnabled);
773 inVisitor.visit(m_fresnelScaleBiasEnabled);
774 inVisitor.visit(m_clearcoatFresnelScaleBiasEnabled);
775 inVisitor.visit(m_baseColorSingleChannelEnabled);
776 inVisitor.visit(m_specularSingleChannelEnabled);
777 inVisitor.visit(m_emissiveSingleChannelEnabled);
778 inVisitor.visit(m_invertOpacityMapValue);
779 inVisitor.visit(m_vertexColorsEnabled);
780 inVisitor.visit(m_vertexColorsMaskEnabled);
781 inVisitor.visit(m_vertexColorRedMask);
782 inVisitor.visit(m_vertexColorGreenMask);
783 inVisitor.visit(m_vertexColorBlueMask);
784 inVisitor.visit(m_vertexColorAlphaMask);
785 inVisitor.visit(m_specularModel);
786
787 for (quint32 idx = 0, end = ImageMapCount; idx < end; ++idx)
788 inVisitor.visit(m_imageMaps[idx]);
789
790 for (auto &textureChannel : m_textureChannels)
791 inVisitor.visit(textureChannel);
792
793 inVisitor.visit(m_boneCount);
794 inVisitor.visit(m_isDoubleSided);
795 inVisitor.visit(m_overridesPosition);
796 inVisitor.visit(m_usesProjectionMatrix);
797 inVisitor.visit(m_usesInverseProjectionMatrix);
798 inVisitor.visit(m_usesPointsTopology);
799 inVisitor.visit(m_usesVarColor);
800 inVisitor.visit(m_alphaMode);
801 inVisitor.visit(m_vertexAttributes);
802 inVisitor.visit(m_usesFloatJointIndices);
803 inVisitor.visit(m_usesInstancing);
804 inVisitor.visit(m_targetCount);
805 inVisitor.visit(m_targetPositionOffset);
806 inVisitor.visit(m_targetNormalOffset);
807 inVisitor.visit(m_targetTangentOffset);
808 inVisitor.visit(m_targetBinormalOffset);
809 inVisitor.visit(m_targetTexCoord0Offset);
810 inVisitor.visit(m_targetTexCoord1Offset);
811 inVisitor.visit(m_targetColorOffset);
812 inVisitor.visit(m_blendParticles);
813 inVisitor.visit(m_clearcoatEnabled);
814 inVisitor.visit(m_transmissionEnabled);
815 inVisitor.visit(m_specularAAEnabled);
816 inVisitor.visit(m_lightmapEnabled);
817 inVisitor.visit(m_specularGlossyEnabled);
818 inVisitor.visit(m_debugMode);
819 inVisitor.visit(m_fogEnabled);
820 inVisitor.visit(m_viewCount);
821 inVisitor.visit(m_usesViewIndex);
822 }
823
825 {
828 template<typename TPropType>
829 void visit(TPropType &inProp)
830 {
831 // if we cross the 32 bit border we just move
832 // to the next dword.
833 // This cost a few extra bits but prevents tedious errors like
834 // loosing shader key bits because they got moved beyond the 32 border
835 quint32 bit = m_offset % 32;
836 if (bit + TPropType::BitWidth > 32) {
837 m_offset += 32 - bit;
838 }
839
840 inProp.setOffset(m_offset);
841 m_offset += TPropType::BitWidth;
842 }
843 };
844
846 {
848 template<typename P>
849 constexpr void visit(const P &prop)
850 {
851 size += prop.name.size();
852 }
853 };
854
856 {
859
860 template<typename P>
861 void visit(P &prop)
862 {
863 offsetVisitor.visit(prop);
865 }
866 };
867
868 void init()
869 {
870 InitVisitor visitor;
871 visitProperties(visitor);
872
873 // If this assert fires, then the default material key needs more bits.
874 Q_ASSERT(visitor.offsetVisitor.m_offset < 416);
875 // This is so we can do some guestimate of how big the string buffer needs
876 // to be to avoid doing a lot of allocations when concatenating the strings.
878 }
879};
880
882{
883 enum {
885 };
886 quint32 m_dataBuffer[DataBufferSize]; // 13 * 4 * 8 = 416 bits
888
889 explicit QSSGShaderDefaultMaterialKey(size_t inFeatureSetHash) : m_featureSetHash(inFeatureSetHash)
890 {
891 for (size_t idx = 0; idx < DataBufferSize; ++idx)
892 m_dataBuffer[idx] = 0;
893 }
894
896 {
897 for (size_t idx = 0; idx < DataBufferSize; ++idx)
898 m_dataBuffer[idx] = 0;
899 }
900
901 size_t hash() const
902 {
903 size_t retval = 0;
904 for (size_t idx = 0; idx < DataBufferSize; ++idx)
905 retval = retval ^ qHash(m_dataBuffer[idx]);
906 return retval ^ m_featureSetHash;
907 }
908
910 {
911 bool retval = true;
912 for (size_t idx = 0; idx < DataBufferSize && retval; ++idx)
913 retval = m_dataBuffer[idx] == other.m_dataBuffer[idx];
914 return retval && m_featureSetHash == other.m_featureSetHash;
915 }
916
917 // Cast operators to make getting properties easier.
918 operator QSSGDataRef<quint32>() { return toDataRef(m_dataBuffer, DataBufferSize); }
919 operator QSSGDataView<quint32>() const { return toDataView(m_dataBuffer, DataBufferSize); }
920
922 {
924 QSSGDataView<quint32> m_keyStore;
925 StringVisitor(QByteArray &s, QSSGDataView<quint32> ks) : m_str(s), m_keyStore(ks) {}
926 template<typename TPropType>
927 void visit(const TPropType &prop)
928 {
929 const qsizetype originalSize = m_str.size();
930 if (m_str.size())
931 m_str.append(';');
932 prop.toString(m_str, m_keyStore);
933 // if the only thing we added was the semicolon
934 // then nuke the semicolon
935 if (originalSize && m_str.size() == (originalSize + 1))
936 m_str.resize(originalSize);
937 }
938 };
939
941 {
943 QSSGDataRef<quint32> m_keyStore;
944 StringInVisitor(const QByteArray &s, QSSGDataRef<quint32> ks) : m_str(s), m_keyStore(ks) {}
945
946 template<typename TPropType>
947 void visit(TPropType &prop)
948 {
949 prop.fromString(m_str, m_keyStore);
950 }
951 };
952
953 void toString(QByteArray &ioString, const QSSGShaderDefaultMaterialKeyProperties &inProperties) const
954 {
955 ioString.reserve(inProperties.m_stringBufferSizeHint);
956 StringVisitor theVisitor(ioString, *this);
957 const_cast<QSSGShaderDefaultMaterialKeyProperties &>(inProperties).visitProperties(theVisitor);
958 }
960 {
961 StringInVisitor theVisitor(ioString, *this);
962 inProperties.visitProperties(theVisitor);
963 }
965 {
967 ret.resize(sizeof(m_dataBuffer));
968 memcpy(ret.data(), m_dataBuffer, sizeof(m_dataBuffer));
969 return ret;
970 }
971 bool fromByteArray(const QByteArray &data) const
972 {
973 if (data.size() != sizeof(m_dataBuffer))
974 return false;
975 memcpy((void *)m_dataBuffer, data.data(), sizeof(m_dataBuffer));
976 return true;
977 }
978};
979
980Q_STATIC_ASSERT(std::is_trivially_destructible<QSSGShaderDefaultMaterialKey>::value);
981
982
984{
985 return key.hash();
986}
987
989
990#endif
IOBluetoothL2CAPChannel * channel
\inmodule QtCore
Definition qbytearray.h:57
qsizetype size() const noexcept
Returns the number of bytes in this byte array.
Definition qbytearray.h:494
QByteArray left(qsizetype n) const &
Definition qbytearray.h:169
int toInt(bool *ok=nullptr, int base=10) const
Returns the byte array converted to an int using base base, which is ten by default.
QByteArray right(qsizetype n) const &
Definition qbytearray.h:181
void resize(qsizetype size)
Sets the size of the byte array to size bytes.
QByteArray & append(char c)
This is an overloaded member function, provided for convenience. It differs from the above function o...
QByteArray mid(qsizetype index, qsizetype len=-1) const &
\inmodule QtCore
qsizetype size() const noexcept
Definition qlist.h:397
qsizetype indexOf(QLatin1StringView s, qsizetype from=0, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Definition qstring.cpp:4517
QString mid(qsizetype position, qsizetype n=-1) const &
Definition qstring.cpp:5300
QString str
[2]
Combined button and popup list for selecting options.
#define Q_STATIC_ASSERT(Condition)
Definition qassert.h:108
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
return ret
GLsizei const GLfloat * v
[13]
GLuint64 key
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLuint index
[2]
GLuint GLuint end
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLenum GLuint buffer
GLenum GLuint GLenum GLsizei const GLchar * buf
GLenum target
GLenum GLuint GLintptr offset
GLuint name
GLint GLint GLint GLint GLint GLint GLint GLbitfield mask
GLdouble s
[6]
Definition qopenglext.h:235
GLuint GLfloat * val
static QT_BEGIN_NAMESPACE bool isDigit(ushort ch)
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
QSSGDataView< T > toDataView(const T &type)
QSSGDataRef< T > toDataRef(T &type)
size_t qHash(const QSSGShaderDefaultMaterialKey &key)
#define QSSG_MAX_NUM_LIGHTS
unsigned int quint32
Definition qtypes.h:50
int qint32
Definition qtypes.h:49
ptrdiff_t qsizetype
Definition qtypes.h:165
QList< int > list
[14]
QSharedPointer< T > other(t)
[5]
QGraphicsItem * item
\inmodule QtCore \reentrant
Definition qchar.h:18
QSSGShaderKeyUnsigned< 8 > m_targetTexCoord1Offset
QSSGShaderKeyBoolean m_lightSpotFlags[LightCount]
QSSGShaderKeyTextureChannel m_textureChannels[SingleChannelImageCount]
QSSGShaderKeyUnsigned< 16 > m_vertexColorAlphaMask
QSSGShaderKeyBoolean m_lightAreaFlags[LightCount]
QSSGShaderKeyImageMap m_imageMaps[ImageMapCount]
QSSGShaderKeyUnsigned< 8 > m_targetPositionOffset
QSSGShaderKeyUnsigned< 8 > m_targetTexCoord0Offset
QSSGShaderKeyUnsigned< 16 > m_vertexColorBlueMask
QSSGShaderKeyVertexAttribute m_vertexAttributes
QSSGShaderKeyBoolean m_lightFlags[LightCount]
QSSGShaderKeyUnsigned< 8 > m_targetBinormalOffset
QSSGShaderKeyUnsigned< 16 > m_vertexColorGreenMask
QSSGShaderKeyBoolean m_lightShadowFlags[LightCount]
QSSGShaderKeyUnsigned< 16 > m_vertexColorRedMask
StringInVisitor(const QByteArray &s, QSSGDataRef< quint32 > ks)
StringVisitor(QByteArray &s, QSSGDataView< quint32 > ks)
void toString(QByteArray &ioString, const QSSGShaderDefaultMaterialKeyProperties &inProperties) const
quint32 m_dataBuffer[DataBufferSize]
QSSGShaderDefaultMaterialKey(size_t inFeatureSetHash)
bool operator==(const QSSGShaderDefaultMaterialKey &other) const
void fromString(QByteArray &ioString, QSSGShaderDefaultMaterialKeyProperties &inProperties)
bool fromByteArray(const QByteArray &data) const
void toString(QByteArray &ioStr, QSSGDataView< quint32 > inKeySet) const
QSSGRenderDefaultMaterial::MaterialAlphaMode getAlphaMode(QSSGDataView< quint32 > inKeySet) const
QSSGShaderKeyAlphaMode(const char *inName="")
void setAlphaMode(QSSGDataRef< quint32 > inKeySet, QSSGRenderDefaultMaterial::MaterialAlphaMode inMode)
void fromString(const QByteArray &ioStr, QSSGDataRef< quint32 > inKeySet)
void setValue(QSSGDataRef< quint32 > inDataStore, bool inValue) const
void toString(QByteArray &ioStr, QSSGDataView< quint32 > inKeySet) const
constexpr QSSGShaderKeyBoolean(const char *inName="")
bool getValue(QSSGDataView< quint32 > inDataStore) const
void fromString(const QByteArray &ioStr, QSSGDataRef< quint32 > inKeySet)
void setIdentityTransform(QSSGDataRef< quint32 > inKeySet, bool val)
void setBitValue(ImageMapBits imageBit, bool inValue, QSSGDataRef< quint32 > inKeySet)
void setEnabled(QSSGDataRef< quint32 > inKeySet, bool val)
bool isUsingUV1(QSSGDataView< quint32 > inKeySet) const
QSSGShaderKeyImageMap(const char *inName="")
void toString(QByteArray &ioStr, QSSGDataView< quint32 > inKeySet) const
bool isIdentityTransform(QSSGDataView< quint32 > inKeySet) const
bool isEnabled(QSSGDataView< quint32 > inKeySet) const
bool isLightProbe(QSSGDataView< quint32 > inKeySet) const
void setLinear(QSSGDataRef< quint32 > inKeySet, bool val)
void setUsesUV1(QSSGDataRef< quint32 > inKeySet, bool val)
bool isEnvMap(QSSGDataView< quint32 > inKeySet) const
bool getBitValue(ImageMapBits imageBit, QSSGDataView< quint32 > inKeySet) const
void setLightProbe(QSSGDataRef< quint32 > inKeySet, bool val)
bool isLinear(QSSGDataView< quint32 > inKeySet) const
void setEnvMap(QSSGDataRef< quint32 > inKeySet, bool val)
static void internalToString(QByteArray &ioStr, const QByteArrayView &name, bool inValue)
constexpr QSSGShaderKeyPropertyBase(const char *inName="")
void internalToString(QByteArray &ioStr, const QByteArrayView &inBuffer) const
static bool getBoolValue(const QByteArray &str, const QByteArrayView &name)
QSSGRenderDefaultMaterial::MaterialSpecularModel getSpecularModel(QSSGDataView< quint32 > inKeySet) const
void setSpecularModel(QSSGDataRef< quint32 > inKeySet, QSSGRenderDefaultMaterial::MaterialSpecularModel inModel)
void fromString(const QByteArray &ioStr, QSSGDataRef< quint32 > inKeySet)
void toString(QByteArray &ioStr, QSSGDataView< quint32 > inKeySet) const
QSSGShaderKeySpecularModel(const char *inName="")
void fromString(const QByteArray &ioStr, QSSGDataRef< quint32 > inKeySet)
void setTextureChannel(TexturChannelBits channel, QSSGDataRef< quint32 > inKeySet)
static constexpr char textureChannelToChar[4]
TexturChannelBits getTextureChannel(QSSGDataView< quint32 > inKeySet) const
void toString(QByteArray &ioStr, QSSGDataView< quint32 > inKeySet) const
QSSGShaderKeyTextureChannel(const char *inName="")
void fromString(const QByteArray &ioStr, QSSGDataRef< quint32 > inKeySet)
constexpr QSSGShaderKeyUnsigned(const char *inName="")
void setValue(QSSGDataRef< quint32 > inDataStore, quint32 inValue) const
quint32 getValue(QSSGDataView< quint32 > inDataStore) const
void toString(QByteArray &ioStr, QSSGDataView< quint32 > inKeySet) const
void toString(QByteArray &ioStr, QSSGDataView< quint32 > inKeySet) const
bool getBitValue(VertexAttributeBits bit, QSSGDataView< quint32 > inKeySet) const
QSSGShaderKeyVertexAttribute(const char *inName="")
void fromString(const QByteArray &ioStr, QSSGDataRef< quint32 > inKeySet)
void setBitValue(VertexAttributeBits bit, QSSGDataRef< quint32 > inKeySet, bool value) const