455QByteArray QShader::serialized(SerializedFormatVersion version)
const
457 static QShaderPrivate sd;
458 QShaderPrivate *dd = d ? d : &sd;
461 QDataStream ds(&buf);
462 ds.setVersion(QDataStream::Qt_5_10);
463 if (!buf.open(QIODevice::WriteOnly))
466 const int qsbVersion = QShaderPrivate::qtQsbVersion(version);
469 ds <<
int(dd->stage);
470 dd->desc.serialize(&ds, qsbVersion);
471 ds <<
int(dd->shaders.size());
472 for (
auto it = dd->shaders.cbegin(), itEnd = dd->shaders.cend(); it != itEnd; ++it) {
473 const QShaderKey &k(it.key());
474 writeShaderKey(&ds, k);
475 const QShaderCode &shader(dd->shaders.value(k));
476 ds << shader.shader();
477 ds << shader.entryPoint();
479 ds <<
int(dd->bindings.size());
480 for (
auto it = dd->bindings.cbegin(), itEnd = dd->bindings.cend(); it != itEnd; ++it) {
481 const QShaderKey &k(it.key());
482 writeShaderKey(&ds, k);
483 const NativeResourceBindingMap &map(it.value());
484 ds <<
int(map.size());
485 for (
auto mapIt = map.cbegin(), mapItEnd = map.cend(); mapIt != mapItEnd; ++mapIt) {
487 ds << mapIt.value().first;
488 ds << mapIt.value().second;
491 ds <<
int(dd->combinedImageMap.size());
492 for (
auto it = dd->combinedImageMap.cbegin(), itEnd = dd->combinedImageMap.cend(); it != itEnd; ++it) {
493 const QShaderKey &k(it.key());
494 writeShaderKey(&ds, k);
495 const SeparateToCombinedImageSamplerMappingList &list(it.value());
496 ds <<
int(list.size());
497 for (
auto listIt = list.cbegin(), listItEnd = list.cend(); listIt != listItEnd; ++listIt) {
498 ds << listIt->combinedSamplerName;
499 ds << listIt->textureBinding;
500 ds << listIt->samplerBinding;
503 if (qsbVersion > QShaderPrivate::QSB_VERSION_WITHOUT_NATIVE_SHADER_INFO) {
504 ds <<
int(dd->nativeShaderInfoMap.size());
505 for (
auto it = dd->nativeShaderInfoMap.cbegin(), itEnd = dd->nativeShaderInfoMap.cend(); it != itEnd; ++it) {
506 const QShaderKey &k(it.key());
507 writeShaderKey(&ds, k);
509 ds <<
int(it->extraBufferBindings.size());
510 for (
auto mapIt = it->extraBufferBindings.cbegin(), mapItEnd = it->extraBufferBindings.cend();
511 mapIt != mapItEnd; ++mapIt)
519 return qCompress(buf.buffer());
550QShader QShader::fromSerialized(
const QByteArray &data)
552 QByteArray udata = qUncompress(data);
554 QDataStream ds(&buf);
555 ds.setVersion(QDataStream::Qt_5_10);
556 if (!buf.open(QIODevice::ReadOnly))
561 QShaderPrivate *d = QShaderPrivate::get(&bs);
562 Q_ASSERT(d->ref.loadRelaxed() == 1);
565 d->qsbVersion = intVal;
566 if (d->qsbVersion != QShaderPrivate::QSB_VERSION
567 && d->qsbVersion != QShaderPrivate::QSB_VERSION_WITHOUT_INPUT_OUTPUT_INTERFACE_BLOCKS
568 && d->qsbVersion != QShaderPrivate::QSB_VERSION_WITHOUT_EXTENDED_STORAGE_BUFFER_INFO
569 && d->qsbVersion != QShaderPrivate::QSB_VERSION_WITHOUT_NATIVE_SHADER_INFO
570 && d->qsbVersion != QShaderPrivate::QSB_VERSION_WITHOUT_SEPARATE_IMAGES_AND_SAMPLERS
571 && d->qsbVersion != QShaderPrivate::QSB_VERSION_WITHOUT_VAR_ARRAYDIMS
572 && d->qsbVersion != QShaderPrivate::QSB_VERSION_WITH_CBOR
573 && d->qsbVersion != QShaderPrivate::QSB_VERSION_WITH_BINARY_JSON
574 && d->qsbVersion != QShaderPrivate::QSB_VERSION_WITHOUT_BINDINGS)
576 qWarning(
"Attempted to deserialize QShader with unknown version %d.", d->qsbVersion);
581 d->stage = Stage(intVal);
582 if (d->qsbVersion > QShaderPrivate::QSB_VERSION_WITH_CBOR) {
583 d->desc = QShaderDescription::deserialize(&ds, d->qsbVersion);
584 }
else if (d->qsbVersion > QShaderPrivate::QSB_VERSION_WITH_BINARY_JSON) {
585 qWarning(
"Can no longer load QShaderDescription from CBOR.");
586 d->desc = QShaderDescription();
588 qWarning(
"Can no longer load QShaderDescription from binary JSON.");
589 d->desc = QShaderDescription();
593 for (
int i = 0; i < count; ++i) {
595 readShaderKey(&ds, &k);
601 shader.setEntryPoint(s);
602 d->shaders[k] = shader;
605 if (d->qsbVersion > QShaderPrivate::QSB_VERSION_WITHOUT_BINDINGS) {
607 for (
int i = 0; i < count; ++i) {
609 readShaderKey(&ds, &k);
610 NativeResourceBindingMap map;
613 for (
int b = 0; b < mapSize; ++b) {
616 int firstNativeBinding;
617 ds >> firstNativeBinding;
618 int secondNativeBinding;
619 ds >> secondNativeBinding;
620 map.insert(binding, { firstNativeBinding, secondNativeBinding });
622 d->bindings.insert(k, map);
626 if (d->qsbVersion > QShaderPrivate::QSB_VERSION_WITHOUT_SEPARATE_IMAGES_AND_SAMPLERS) {
628 for (
int i = 0; i < count; ++i) {
630 readShaderKey(&ds, &k);
631 SeparateToCombinedImageSamplerMappingList list;
634 for (
int b = 0; b < listSize; ++b) {
635 QByteArray combinedSamplerName;
636 ds >> combinedSamplerName;
638 ds >> textureBinding;
640 ds >> samplerBinding;
641 list.append({ combinedSamplerName, textureBinding, samplerBinding });
643 d->combinedImageMap.insert(k, list);
647 if (d->qsbVersion > QShaderPrivate::QSB_VERSION_WITHOUT_NATIVE_SHADER_INFO) {
649 for (
int i = 0; i < count; ++i) {
651 readShaderKey(&ds, &k);
654 QMap<
int,
int> extraBufferBindings;
657 for (
int b = 0; b < mapSize; ++b) {
661 extraBufferBindings.insert(k, v);
663 d->nativeShaderInfoMap.insert(k, { flags, extraBufferBindings });
815 QtPrivate::QHashCombineWithSeed hash(seed);
816 seed = hash(seed, s.stage());
817 if (!s.d->shaders.isEmpty()) {
818 seed = hash(seed, s.d->shaders.firstKey());
819 seed = hash(seed, std::as_const(s.d->shaders).first());