Qt 6.x
The Qt SDK
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
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:
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
206 {
207 return TexturChannelBits(getValue(inKeySet));
208 }
209
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('=');
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 };
256
257 explicit QSSGShaderKeyImageMap(const char *inName = "") : QSSGShaderKeyUnsigned<5>(inName) {}
258
259 bool getBitValue(ImageMapBits imageBit, QSSGDataView<quint32> inKeySet) const
260 {
261 return (getValue(inKeySet) & imageBit) ? true : false;
262 }
263
264 void setBitValue(ImageMapBits imageBit, bool inValue, QSSGDataRef<quint32> inKeySet)
265 {
266 quint32 theValue = getValue(inKeySet);
267 quint32 mask = imageBit;
268 if (inValue) {
269 theValue = theValue | mask;
270 } else {
271 mask = ~mask;
272 theValue = theValue & mask;
273 }
274 setValue(inKeySet, theValue);
275 }
276
277 bool isEnabled(QSSGDataView<quint32> inKeySet) const { return getBitValue(Enabled, inKeySet); }
278 void setEnabled(QSSGDataRef<quint32> inKeySet, bool val) { setBitValue(Enabled, val, inKeySet); }
279
280 bool isEnvMap(QSSGDataView<quint32> inKeySet) const { return getBitValue(EnvMap, inKeySet); }
281 void setEnvMap(QSSGDataRef<quint32> inKeySet, bool val) { setBitValue(EnvMap, val, inKeySet); }
282
283 bool isLightProbe(QSSGDataView<quint32> inKeySet) const { return getBitValue(LightProbe, inKeySet); }
284 void setLightProbe(QSSGDataRef<quint32> inKeySet, bool val) { setBitValue(LightProbe, val, inKeySet); }
285
286 bool isIdentityTransform(QSSGDataView<quint32> inKeySet) const { return getBitValue(Identity, inKeySet); }
288
289 bool isUsingUV1(QSSGDataView<quint32> inKeySet) const { return getBitValue(UsesUV1, inKeySet); }
290 void setUsesUV1(QSSGDataRef<quint32> inKeySet, bool val) { setBitValue(UsesUV1, val, inKeySet); }
291
292 void toString(QByteArray &ioStr, QSSGDataView<quint32> inKeySet) const
293 {
294 ioStr.append(name);
295 ioStr.append(QByteArrayView("={"));
296 internalToString(ioStr, QByteArrayView("enabled"), isEnabled(inKeySet));
297 ioStr.append(';');
298 internalToString(ioStr, QByteArrayView("envMap"), isEnvMap(inKeySet));
299 ioStr.append(';');
300 internalToString(ioStr, QByteArrayView("lightProbe"), isLightProbe(inKeySet));
301 ioStr.append(';');
302 internalToString(ioStr, QByteArrayView("identity"), isIdentityTransform(inKeySet));
303 ioStr.append(';');
304 internalToString(ioStr, QByteArrayView("usesUV1"), isUsingUV1(inKeySet));
305 ioStr.append('}');
306 }
307};
308
310{
311 explicit QSSGShaderKeySpecularModel(const char *inName = "") : QSSGShaderKeyUnsigned<2>(inName) {}
312
314 {
315 setValue(inKeySet, quint32(inModel));
316 }
317
319 {
320 return static_cast<QSSGRenderDefaultMaterial::MaterialSpecularModel>(getValue(inKeySet));
321 }
322
323 void toString(QByteArray &ioStr, QSSGDataView<quint32> inKeySet) const
324 {
325 ioStr.append(name);
326 ioStr.append('=');
327 switch (getSpecularModel(inKeySet)) {
329 ioStr.append(QByteArrayView("KGGX"));
330 break;
332 ioStr.append(QByteArrayView("Default"));
333 break;
334 }
335 ioStr.append(';');
336 }
337 void fromString(const QByteArray &ioStr, QSSGDataRef<quint32> inKeySet)
338 {
339 const qsizetype nameLen = name.size();
340 const int strOffset = ioStr.indexOf(name);
341 if (strOffset >= 0) {
342 /* The key is stored as name=specularMode; */
343 if (ioStr[strOffset + nameLen] != '=')
344 return;
345 const int codeOffsetBegin = strOffset + nameLen + 1;
346 int codeOffset = 0;
347 while (ioStr[codeOffsetBegin + codeOffset] != ';')
348 codeOffset++;
349 const QByteArray val = ioStr.mid(codeOffsetBegin, codeOffset);
350 if (val == QByteArrayView("KGGX"))
352 if (val == QByteArrayView("Default"))
354 }
355 }
356};
357
359{
360 explicit QSSGShaderKeyAlphaMode(const char *inName = "") : QSSGShaderKeyUnsigned<2>(inName) {}
361
363 {
364 setValue(inKeySet, quint32(inMode));
365 }
366
368 {
369 return static_cast<QSSGRenderDefaultMaterial::MaterialAlphaMode>(getValue(inKeySet));
370 }
371
372 void toString(QByteArray &ioStr, QSSGDataView<quint32> inKeySet) const
373 {
374 ioStr.append(name);
375 ioStr.append('=');
376 switch (getAlphaMode(inKeySet)) {
378 ioStr.append(QByteArrayView("Default"));
379 break;
381 ioStr.append(QByteArrayView("Mask"));
382 break;
384 ioStr.append(QByteArrayView("Blend"));
385 break;
387 ioStr.append(QByteArrayView("Opaque"));
388 break;
389 }
390 ioStr.append(';');
391 }
392 void fromString(const QByteArray &ioStr, QSSGDataRef<quint32> inKeySet)
393 {
394 const qsizetype nameLen = name.size();
395 const qsizetype strOffset = ioStr.indexOf(name);
396 if (strOffset >= 0) {
397 /* The key is stored as name=alphaMode; */
398 if (ioStr[strOffset + nameLen] != '=')
399 return;
400 const int codeOffsetBegin = strOffset + nameLen + 1;
401 int codeOffset = 0;
402 while (ioStr[codeOffsetBegin + codeOffset] != ';')
403 codeOffset++;
404 const QByteArray val = ioStr.mid(codeOffsetBegin, codeOffset);
405 if (val == QByteArrayView("Default"))
407 if (val == QByteArrayView("Mask"))
409 if (val == QByteArrayView("Blend"))
411 if (val == QByteArrayView("Opaque"))
413 }
414 }
415};
416
418{
420 Position = 1 << 0,
421 Normal = 1 << 1,
422 TexCoord0 = 1 << 2,
423 TexCoord1 = 1 << 3,
424 Tangent = 1 << 4,
425 Binormal = 1 << 5,
426 Color = 1 << 6,
428 TexCoordLightmap = 1 << 8
429 };
430
431 explicit QSSGShaderKeyVertexAttribute(const char *inName = "") : QSSGShaderKeyUnsigned<9>(inName) {}
432
434 {
435 return (getValue(inKeySet) & bit) ? true : false;
436 }
438 {
439 quint32 v = getValue(inKeySet);
440 v = value ? (v | bit) : (v & ~bit);
441 setValue(inKeySet, v);
442 }
443
444 void toString(QByteArray &ioStr, QSSGDataView<quint32> inKeySet) const
445 {
446 ioStr.append(name);
447 ioStr.append(QByteArrayView("={"));
448 internalToString(ioStr, QByteArrayView("position"), getBitValue(Position, inKeySet));
449 ioStr.append(';');
450 internalToString(ioStr, QByteArrayView("normal"), getBitValue(Normal, inKeySet));
451 ioStr.append(';');
452 internalToString(ioStr, QByteArrayView("texcoord0"), getBitValue(TexCoord0, inKeySet));
453 ioStr.append(';');
454 internalToString(ioStr, QByteArrayView("texcoord1"), getBitValue(TexCoord1, inKeySet));
455 ioStr.append(';');
456 internalToString(ioStr, QByteArrayView("tangent"), getBitValue(Tangent, inKeySet));
457 ioStr.append(';');
458 internalToString(ioStr, QByteArrayView("binormal"), getBitValue(Binormal, inKeySet));
459 ioStr.append(';');
460 internalToString(ioStr, QByteArrayView("color"), getBitValue(Color, inKeySet));
461 ioStr.append(';');
462 internalToString(ioStr, QByteArrayView("texcoordlightmap"), getBitValue(TexCoordLightmap, inKeySet));
463 ioStr.append('}');
464 internalToString(ioStr, QByteArrayView("joint&weight"), getBitValue(JointAndWeight, inKeySet));
465 ioStr.append('}');
466 }
467 void fromString(const QByteArray &ioStr, QSSGDataRef<quint32> inKeySet)
468 {
469 const qsizetype nameLen = name.size();
470 const qsizetype strOffset = ioStr.indexOf(name);
471 if (strOffset >= 0) {
472 /* The key is stored as name={;;;;;;} */
473 if (ioStr[strOffset + nameLen] != '=')
474 return;
475 if (ioStr[strOffset + nameLen + 1] != '{')
476 return;
477 const int codeOffsetBegin = strOffset + nameLen + 2;
478 int codeOffset = 0;
479 while (ioStr[codeOffsetBegin + codeOffset] != '}')
480 codeOffset++;
481 const QByteArray val = ioStr.mid(codeOffsetBegin, codeOffset);
482 const QVector<QByteArray> list = val.split(';');
483 if (list.size() != 8)
484 return;
485 setBitValue(Position, inKeySet, getBoolValue(list[0], QByteArrayView("position")));
486 setBitValue(Normal, inKeySet, getBoolValue(list[1], QByteArrayView("normal")));
487 setBitValue(TexCoord0, inKeySet, getBoolValue(list[2], QByteArrayView("texcoord0")));
488 setBitValue(TexCoord1, inKeySet, getBoolValue(list[3], QByteArrayView("texcoord1")));
489 setBitValue(Tangent, inKeySet, getBoolValue(list[4], QByteArrayView("tangent")));
490 setBitValue(Binormal, inKeySet, getBoolValue(list[5], QByteArrayView("binormal")));
491 setBitValue(Color, inKeySet, getBoolValue(list[6], QByteArrayView("color")));
492 setBitValue(TexCoordLightmap, inKeySet, getBoolValue(list[7], QByteArrayView("texcoordlightmap")));
493 }
494 }
495};
496
498{
499 enum {
501 };
502 enum {
504 };
514 // single channel images
525
528 };
540 };
541
583
585 : m_hasLighting("hasLighting")
586 , m_hasIbl("hasIbl")
587 , m_lightCount("lightCount")
588 , m_specularEnabled("specularEnabled")
589 , m_fresnelEnabled("fresnelEnabled")
590 , m_vertexColorsEnabled("vertexColorsEnabled")
591 , m_specularModel("specularModel")
592 , m_boneCount("boneCount")
593 , m_isDoubleSided("isDoubleSided")
594 , m_overridesPosition("overridesPosition")
595 , m_usesProjectionMatrix("usesProjectionMatrix")
596 , m_usesInverseProjectionMatrix("usesInverseProjectionMatrix")
597 , m_usesPointsTopology("usesPointsTopology")
598 , m_usesVarColor("usesVarColor")
599 , m_alphaMode("alphaMode")
600 , m_vertexAttributes("vertexAttributes")
601 , m_usesFloatJointIndices("usesFloatJointIndices")
602 , m_usesInstancing("usesInstancing")
603 , m_targetCount("targetCount")
604 , m_targetPositionOffset("targetPositionOffset")
605 , m_targetNormalOffset("targetNormalOffset")
606 , m_targetTangentOffset("targetTangentOffset")
607 , m_targetBinormalOffset("targetBinormalOffset")
608 , m_targetTexCoord0Offset("targetTexCoord0Offset")
609 , m_targetTexCoord1Offset("targetTexCoord1Offset")
610 , m_targetColorOffset("targetColorOffset")
611 , m_blendParticles("blendParticles")
612 , m_clearcoatEnabled("clearcoatEnabled")
613 , m_transmissionEnabled("transmissionEnabled")
614 , m_specularAAEnabled("specularAAEnabled")
615 , m_lightmapEnabled("lightmapEnabled")
616 , m_specularGlossyEnabled("specularGlossyEnabled")
617 , m_debugMode("debugMode")
618 , m_fogEnabled("fogEnabled")
619 {
620 m_lightFlags[0].name = "light0HasPosition";
621 m_lightFlags[1].name = "light1HasPosition";
622 m_lightFlags[2].name = "light2HasPosition";
623 m_lightFlags[3].name = "light3HasPosition";
624 m_lightFlags[4].name = "light4HasPosition";
625 m_lightFlags[5].name = "light5HasPosition";
626 m_lightFlags[6].name = "light6HasPosition";
627 m_lightFlags[7].name = "light7HasPosition";
628 m_lightFlags[8].name = "light8HasPosition";
629 m_lightFlags[9].name = "light9HasPosition";
630 m_lightFlags[10].name = "light10HasPosition";
631 m_lightFlags[11].name = "light11HasPosition";
632 m_lightFlags[12].name = "light12HasPosition";
633 m_lightFlags[13].name = "light13HasPosition";
634 m_lightFlags[14].name = "light14HasPosition";
635
636 m_lightSpotFlags[0].name = "light0HasSpot";
637 m_lightSpotFlags[1].name = "light1HasSpot";
638 m_lightSpotFlags[2].name = "light2HasSpot";
639 m_lightSpotFlags[3].name = "light3HasSpot";
640 m_lightSpotFlags[4].name = "light4HasSpot";
641 m_lightSpotFlags[5].name = "light5HasSpot";
642 m_lightSpotFlags[6].name = "light6HasSpot";
643 m_lightSpotFlags[7].name = "light7HasSpot";
644 m_lightSpotFlags[8].name = "light8HasSpot";
645 m_lightSpotFlags[9].name = "light9HasSpot";
646 m_lightSpotFlags[10].name = "light10HasSpot";
647 m_lightSpotFlags[11].name = "light11HasSpot";
648 m_lightSpotFlags[12].name = "light12HasSpot";
649 m_lightSpotFlags[13].name = "light13HasSpot";
650 m_lightSpotFlags[14].name = "light14HasSpot";
651
652 m_lightAreaFlags[0].name = "light0HasArea";
653 m_lightAreaFlags[1].name = "light1HasArea";
654 m_lightAreaFlags[2].name = "light2HasArea";
655 m_lightAreaFlags[3].name = "light3HasArea";
656 m_lightAreaFlags[4].name = "light4HasArea";
657 m_lightAreaFlags[5].name = "light5HasArea";
658 m_lightAreaFlags[6].name = "light6HasArea";
659 m_lightAreaFlags[7].name = "light7HasArea";
660 m_lightAreaFlags[8].name = "light8HasArea";
661 m_lightAreaFlags[9].name = "light9HasArea";
662 m_lightAreaFlags[10].name = "light10HasArea";
663 m_lightAreaFlags[11].name = "light11HasArea";
664 m_lightAreaFlags[12].name = "light12HasArea";
665 m_lightAreaFlags[13].name = "light13HasArea";
666 m_lightAreaFlags[14].name = "light14HasArea";
667
668 m_lightShadowFlags[0].name = "light0HasShadow";
669 m_lightShadowFlags[1].name = "light1HasShadow";
670 m_lightShadowFlags[2].name = "light2HasShadow";
671 m_lightShadowFlags[3].name = "light3HasShadow";
672 m_lightShadowFlags[4].name = "light4HasShadow";
673 m_lightShadowFlags[5].name = "light5HasShadow";
674 m_lightShadowFlags[6].name = "light6HasShadow";
675 m_lightShadowFlags[7].name = "light7HasShadow";
676 m_lightShadowFlags[8].name = "light8HasShadow";
677 m_lightShadowFlags[9].name = "light9HasShadow";
678 m_lightShadowFlags[10].name = "light10HasShadow";
679 m_lightShadowFlags[11].name = "light11HasShadow";
680 m_lightShadowFlags[12].name = "light12HasShadow";
681 m_lightShadowFlags[13].name = "light13HasShadow";
682 m_lightShadowFlags[14].name = "light14HasShadow";
683
684 m_imageMaps[0].name = "diffuseMap";
685 m_imageMaps[1].name = "emissiveMap";
686 m_imageMaps[2].name = "specularMap";
687 m_imageMaps[3].name = "baseColorMap";
688 m_imageMaps[4].name = "bumpMap";
689 m_imageMaps[5].name = "specularAmountMap";
690 m_imageMaps[6].name = "normalMap";
691 m_imageMaps[7].name = "clearcoatNormalMap";
692 m_imageMaps[8].name = "opacityMap";
693 m_imageMaps[9].name = "roughnessMap";
694 m_imageMaps[10].name = "metalnessMap";
695 m_imageMaps[11].name = "occlusionMap";
696 m_imageMaps[12].name = "translucencyMap";
697 m_imageMaps[13].name = "heightMap";
698 m_imageMaps[14].name = "clearcoatMap";
699 m_imageMaps[15].name = "clearcoatRoughnessMap";
700 m_imageMaps[16].name = "transmissionMap";
701 m_imageMaps[17].name = "thicknessMap";
702
703 m_textureChannels[0].name = "opacityMap_channel";
704 m_textureChannels[1].name = "roughnessMap_channel";
705 m_textureChannels[2].name = "metalnessMap_channel";
706 m_textureChannels[3].name = "occlusionMap_channel";
707 m_textureChannels[4].name = "translucencyMap_channel";
708 m_textureChannels[5].name = "heightMap_channel";
709 m_textureChannels[6].name = "clearcoatMap_channel";
710 m_textureChannels[7].name = "clearcoatRoughnessMap_channel";
711 m_textureChannels[8].name = "transmissionMap_channel";
712 m_textureChannels[9].name = "thicknessMap_channel";
713
714 init();
715 }
716
717 template<typename TVisitor>
718 void visitProperties(TVisitor &inVisitor)
719 {
720 inVisitor.visit(m_hasLighting);
721 inVisitor.visit(m_hasIbl);
722 inVisitor.visit(m_lightCount);
723
724 for (auto &lightFlag : m_lightFlags)
725 inVisitor.visit(lightFlag);
726
727 for (auto &lightSpotFlag : m_lightSpotFlags)
728 inVisitor.visit(lightSpotFlag);
729
730 for (auto &lightAreaFlag : m_lightAreaFlags)
731 inVisitor.visit(lightAreaFlag);
732
733 for (auto &lightShadowFlag : m_lightShadowFlags)
734 inVisitor.visit(lightShadowFlag);
735
736 inVisitor.visit(m_specularEnabled);
737 inVisitor.visit(m_fresnelEnabled);
738 inVisitor.visit(m_vertexColorsEnabled);
739 inVisitor.visit(m_specularModel);
740
741 for (quint32 idx = 0, end = ImageMapCount; idx < end; ++idx)
742 inVisitor.visit(m_imageMaps[idx]);
743
744 for (auto &textureChannel : m_textureChannels)
745 inVisitor.visit(textureChannel);
746
747 inVisitor.visit(m_boneCount);
748 inVisitor.visit(m_isDoubleSided);
749 inVisitor.visit(m_overridesPosition);
750 inVisitor.visit(m_usesProjectionMatrix);
751 inVisitor.visit(m_usesInverseProjectionMatrix);
752 inVisitor.visit(m_usesPointsTopology);
753 inVisitor.visit(m_usesVarColor);
754 inVisitor.visit(m_alphaMode);
755 inVisitor.visit(m_vertexAttributes);
756 inVisitor.visit(m_usesFloatJointIndices);
757 inVisitor.visit(m_usesInstancing);
758 inVisitor.visit(m_targetCount);
759 inVisitor.visit(m_targetPositionOffset);
760 inVisitor.visit(m_targetNormalOffset);
761 inVisitor.visit(m_targetTangentOffset);
762 inVisitor.visit(m_targetBinormalOffset);
763 inVisitor.visit(m_targetTexCoord0Offset);
764 inVisitor.visit(m_targetTexCoord1Offset);
765 inVisitor.visit(m_targetColorOffset);
766 inVisitor.visit(m_blendParticles);
767 inVisitor.visit(m_clearcoatEnabled);
768 inVisitor.visit(m_transmissionEnabled);
769 inVisitor.visit(m_specularAAEnabled);
770 inVisitor.visit(m_lightmapEnabled);
771 inVisitor.visit(m_specularGlossyEnabled);
772 inVisitor.visit(m_debugMode);
773 inVisitor.visit(m_fogEnabled);
774 }
775
777 {
780 template<typename TPropType>
781 void visit(TPropType &inProp)
782 {
783 // if we cross the 32 bit border we just move
784 // to the next dword.
785 // This cost a few extra bits but prevents tedious errors like
786 // loosing shader key bits because they got moved beyond the 32 border
787 quint32 bit = m_offset % 32;
788 if (bit + TPropType::BitWidth > 32) {
789 m_offset += 32 - bit;
790 }
791
792 inProp.setOffset(m_offset);
793 m_offset += TPropType::BitWidth;
794 }
795 };
796
798 {
800 template<typename P>
801 constexpr void visit(const P &prop)
802 {
803 size += prop.name.size();
804 }
805 };
806
808 {
811
812 template<typename P>
813 void visit(P &prop)
814 {
815 offsetVisitor.visit(prop);
817 }
818 };
819
820 void init()
821 {
822 InitVisitor visitor;
823 visitProperties(visitor);
824
825 // If this assert fires, then the default material key needs more bits.
826 Q_ASSERT(visitor.offsetVisitor.m_offset < 416);
827 // This is so we can do some guestimate of how big the string buffer needs
828 // to be to avoid doing a lot of allocations when concatenating the strings.
830 }
831};
832
834{
835 enum {
837 };
838 quint32 m_dataBuffer[DataBufferSize]; // 13 * 4 * 8 = 416 bits
840
841 explicit QSSGShaderDefaultMaterialKey(size_t inFeatureSetHash) : m_featureSetHash(inFeatureSetHash)
842 {
843 for (size_t idx = 0; idx < DataBufferSize; ++idx)
844 m_dataBuffer[idx] = 0;
845 }
846
848 {
849 for (size_t idx = 0; idx < DataBufferSize; ++idx)
850 m_dataBuffer[idx] = 0;
851 }
852
853 size_t hash() const
854 {
855 size_t retval = 0;
856 for (size_t idx = 0; idx < DataBufferSize; ++idx)
857 retval = retval ^ qHash(m_dataBuffer[idx]);
858 return retval ^ m_featureSetHash;
859 }
860
862 {
863 bool retval = true;
864 for (size_t idx = 0; idx < DataBufferSize && retval; ++idx)
865 retval = m_dataBuffer[idx] == other.m_dataBuffer[idx];
866 return retval && m_featureSetHash == other.m_featureSetHash;
867 }
868
869 // Cast operators to make getting properties easier.
872
874 {
878 template<typename TPropType>
879 void visit(const TPropType &prop)
880 {
881 const qsizetype originalSize = m_str.size();
882 if (m_str.size())
883 m_str.append(';');
884 prop.toString(m_str, m_keyStore);
885 // if the only thing we added was the semicolon
886 // then nuke the semicolon
887 if (originalSize && m_str.size() == (originalSize + 1))
888 m_str.resize(originalSize);
889 }
890 };
891
893 {
897
898 template<typename TPropType>
899 void visit(TPropType &prop)
900 {
901 prop.fromString(m_str, m_keyStore);
902 }
903 };
904
905 void toString(QByteArray &ioString, const QSSGShaderDefaultMaterialKeyProperties &inProperties) const
906 {
907 ioString.reserve(inProperties.m_stringBufferSizeHint);
908 StringVisitor theVisitor(ioString, *this);
909 const_cast<QSSGShaderDefaultMaterialKeyProperties &>(inProperties).visitProperties(theVisitor);
910 }
912 {
913 StringInVisitor theVisitor(ioString, *this);
914 inProperties.visitProperties(theVisitor);
915 }
917 {
919 ret.resize(sizeof(m_dataBuffer));
920 memcpy(ret.data(), m_dataBuffer, sizeof(m_dataBuffer));
921 return ret;
922 }
923 bool fromByteArray(const QByteArray &data) const
924 {
925 if (data.size() != sizeof(m_dataBuffer))
926 return false;
927 memcpy((void *)m_dataBuffer, data.data(), sizeof(m_dataBuffer));
928 return true;
929 }
930};
931
932Q_STATIC_ASSERT(std::is_trivially_destructible<QSSGShaderDefaultMaterialKey>::value);
933
934
936{
937 return key.hash();
938}
939
941
942#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:474
void reserve(qsizetype size)
Attempts to allocate memory for at least size bytes.
Definition qbytearray.h:557
qsizetype indexOf(char c, qsizetype from=0) const
This is an overloaded member function, provided for convenience. It differs from the above function o...
QByteArray right(qsizetype len) const
Returns a byte array that contains the last len bytes of this byte array.
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
Returns a byte array containing len bytes from this byte array, starting at position pos.
\inmodule QtCore
Definition qchar.h:48
Definition qlist.h:74
qsizetype size() const noexcept
Definition qlist.h:386
qsizetype size() const
Returns the number of characters in this string.
Definition qstring.h:182
QString mid(qsizetype position, qsizetype n=-1) const
Returns a string that contains n characters of this string, starting at the specified position index.
Definition qstring.cpp:5204
static QString static QString qsizetype indexOf(QChar c, qsizetype from=0, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Definition qstring.cpp:4420
QString str
[2]
Combined button and popup list for selecting options.
#define Q_STATIC_ASSERT(Condition)
Definition qassert.h:105
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
GLenum GLuint buffer
GLenum GLuint GLenum GLsizei const GLchar * buf
GLenum target
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLenum GLuint GLintptr offset
GLuint name
GLint GLint GLint GLint GLint GLint GLint GLbitfield mask
GLuint GLfloat * val
GLdouble s
[6]
Definition qopenglext.h:235
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:45
int qint32
Definition qtypes.h:44
ptrdiff_t qsizetype
Definition qtypes.h:70
QList< int > list
[14]
QSharedPointer< T > other(t)
[5]
QGraphicsItem * item
\inmodule QtCore \reentrant
Definition qchar.h:17
qsizetype size() const
QSSGShaderKeyUnsigned< 8 > m_targetTexCoord1Offset
QSSGShaderKeyBoolean m_lightSpotFlags[LightCount]
QSSGShaderKeyTextureChannel m_textureChannels[SingleChannelImageCount]
QSSGShaderKeyBoolean m_lightAreaFlags[LightCount]
QSSGShaderKeyImageMap m_imageMaps[ImageMapCount]
QSSGShaderKeyUnsigned< 8 > m_targetPositionOffset
QSSGShaderKeyUnsigned< 8 > m_targetTexCoord0Offset
QSSGShaderKeyVertexAttribute m_vertexAttributes
QSSGShaderKeyBoolean m_lightFlags[LightCount]
QSSGShaderKeyUnsigned< 8 > m_targetBinormalOffset
QSSGShaderKeyBoolean m_lightShadowFlags[LightCount]
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 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)
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