/****************************************************************************
**
** Copyright (C) 2019 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the Qt Gui module
**
** $QT_BEGIN_LICENSE:LGPL3$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see http://www.qt.io/terms-conditions. For further
** information use the contact form at http://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPLv3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or later as published by the Free
** Software Foundation and appearing in the file LICENSE.GPL included in
** the packaging of this file. Please review the following information to
** ensure the GNU General Public License version 2.0 requirements will be
** met: http://www.gnu.org/licenses/gpl-2.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qshaderdescription_p_p.h"
#include "qshader_p_p.h"
#include <QDebug>
#include <QDataStream>
#include <QJsonObject>
#include <QJsonArray>
#include <QCborValue>
#include <QCborMap>
#include <QCborArray>

QT_BEGIN_NAMESPACE

/*!
    \class QShaderDescription
    \internal
    \inmodule QtGui

    \brief Describes the interface of a shader.

    A shader typically has a set of inputs and outputs. A vertex shader for
    example has a number of input variables and may use one or more uniform
    buffers to access data (e.g. a modelview matrix) provided by the
    application. The shader for the fragment stage receives data from the
    vertex stage (in a simple setup) and may also rely on data from uniform
    buffers, images, and samplers.

    When it comes to vertex inputs and the layout of the uniform buffers (what
    are the names of the members? what is there size, offset, and so on),
    applications and frameworks may need to discover this dynamically at run
    time. This is typical when the shader is not built-in but provided by an
    external entity, like the user.

    Modern and lean graphics APIs may no longer provide a way to query shader
    reflection information at run time. Therefore, such data is now
    automatically generated by QShaderBaker and is provided as a
    QShaderDescription object for each and every QShader.

    \section2 Example

    Take the following vertex shader:

    \badcode
        #version 440

        layout(location = 0) in vec4 position;
        layout(location = 1) in vec3 color;
        layout(location = 0) out vec3 v_color;

        layout(std140, binding = 0) uniform buf {
            mat4 mvp;
            float opacity;
        } ubuf;

        out gl_PerVertex { vec4 gl_Position; };

        void main()
        {
            v_color = color;
            gl_Position = ubuf.mvp * position;
        }
    \endcode

    This shader has two inputs: \c position at location 0 with a type of \c
    vec4, and \c color at location 1 with a type of \c vec3. It has one output:
    \c v_color, although this is typically not interesting for applications.
    What is more important, there is a uniform block at binding 0 with a size
    of 68 bytes and two members, a 4x4 matrix named \c mvp at offset 0, and a
    float \c opacity at offset 64.

    All this is described by a QShaderDescription object. QShaderDescription
    can also be serialized to JSON and CBOR, and can be deserialized
    from CBOR. In practice this is rarely needed since QShader
    takes care of the associated QShaderDescription automatically, but if the
    QShaderDescription of the above shader would be written out as JSON, it
    would look like the following:

    \badcode
        {
            "inputs": [
                {
                    "location": 1,
                    "name": "color",
                    "type": "vec3"
                },
                {
                    "location": 0,
                    "name": "position",
                    "type": "vec4"
                }
            ],
            "outputs": [
                {
                    "location": 0,
                    "name": "v_color",
                    "type": "vec3"
                }
            ],
            "uniformBlocks": [
                {
                    "binding": 0,
                    "blockName": "buf",
                    "members": [
                        {
                            "matrixStride": 16,
                            "name": "mvp",
                            "offset": 0,
                            "size": 64,
                            "type": "mat4"
                        },
                        {
                            "name": "opacity",
                            "offset": 64,
                            "size": 4,
                            "type": "float"
                        }
                    ],
                    "set": 0,
                    "size": 68,
                    "structName": "ubuf"
                }
            ]
        }
    \endcode

    The C++ API allows accessing a data structure like the above. For
    simplicity the inner structs only contain public data members, also
    considering that their layout is unlikely to change in the future.

    \sa QShaderBaker, QShader
 */

/*!
    \enum QShaderDescription::VariableType
    Represents the type of a variable or block member.

    \value Unknown
    \value Float
    \value Vec2
    \value Vec3
    \value Vec4
    \value Mat2
    \value Mat2x3
    \value Mat2x4
    \value Mat3
    \value Mat3x2
    \value Mat3x4
    \value Mat4
    \value Mat4x2
    \value Mat4x3
    \value Int
    \value Int2
    \value Int3
    \value Int4
    \value Uint
    \value Uint2
    \value Uint3
    \value Uint4
    \value Bool
    \value Bool2
    \value Bool3
    \value Bool4
    \value Double
    \value Double2
    \value Double3
    \value Double4
    \value DMat2
    \value DMat2x3
    \value DMat2x4
    \value DMat3
    \value DMat3x2
    \value DMat3x4
    \value DMat4
    \value DMat4x2
    \value DMat4x3
    \value Sampler1D
    \value Sampler2D
    \value Sampler2DMS
    \value Sampler3D
    \value SamplerCube
    \value Sampler1DArray
    \value Sampler2DArray
    \value Sampler2DMSArray
    \value Sampler3DArray
    \value SamplerCubeArray
    \value SamplerRect
    \value SamplerBuffer
    \value Image1D
    \value Image2D
    \value Image2DMS
    \value Image3D
    \value ImageCube
    \value Image1DArray
    \value Image2DArray
    \value Image2DMSArray
    \value Image3DArray
    \value ImageCubeArray
    \value ImageRect
    \value ImageBuffer
    \value Struct
 */

/*!
    \class QShaderDescription::InOutVariable
    \internal
    \inmodule QtGui

    \brief Describes an input or output variable in the shader.
 */

/*!
    \class QShaderDescription::BlockVariable
    \internal
    \inmodule QtGui

    \brief Describes a member of a uniform or push constant block.
 */

/*!
    \class QShaderDescription::UniformBlock
    \internal
    \inmodule QtGui

    \brief Describes a uniform block.

    \note When translating to shading languages without uniform block support
    (like GLSL 120 or GLSL/ES 100), uniform blocks are replaced with ordinary
    uniforms in a struct. The name of the struct, and so the prefix for the
    uniforms generated from the block members, is given by structName.
 */

/*!
    \class QShaderDescription::PushConstantBlock
    \internal
    \inmodule QtGui

    \brief Describes a push constant block.
 */

/*!
    \class QShaderDescription::StorageBlock
    \internal
    \inmodule QtGui

    \brief Describes a shader storage block.
 */

/*!
    Constructs a new, empty QShaderDescription.

    \note Being empty implies that isValid() returns \c false for the
    newly constructed instance.
 */
QShaderDescription::QShaderDescription()
    : d(new QShaderDescriptionPrivate)
{
}

/*!
    \internal
 */
void QShaderDescription::detach()
{
    qAtomicDetach(d);
}

/*!
    \internal
 */
QShaderDescription::QShaderDescription(const QShaderDescription &other)
    : d(other.d)
{
    d->ref.ref();
}

/*!
    \internal
 */
QShaderDescription &QShaderDescription::operator=(const QShaderDescription &other)
{
    qAtomicAssign(d, other.d);
    return *this;
}

/*!
    Destructor.
 */
QShaderDescription::~QShaderDescription()
{
    if (!d->ref.deref())
        delete d;
}

/*!
   \return true if the QShaderDescription contains at least one entry in one of
   the variable and block lists.
 */
bool QShaderDescription::isValid() const
{
    return !d->inVars.isEmpty() || !d->outVars.isEmpty()
        || !d->uniformBlocks.isEmpty() || !d->pushConstantBlocks.isEmpty() || !d->storageBlocks.isEmpty()
        || !d->combinedImageSamplers.isEmpty() || !d->storageImages.isEmpty();
}

/*!
   \return a serialized binary version of the data in CBOR (Concise Binary
   Object Representation) format.

   \sa QCborValue, toJson()
 */
QByteArray QShaderDescription::toCbor() const
{
    return QCborValue::fromJsonValue(d->makeDoc().object()).toCbor();
}

/*!
    \return a serialized JSON text version of the data.

    \note There is no deserialization method provided for JSON text.

    \sa toCbor()
 */
QByteArray QShaderDescription::toJson() const
{
    return d->makeDoc().toJson();
}

void QShaderDescription::serialize(QDataStream *stream) const
{
    d->writeToStream(stream);
}

#if QT_CONFIG(binaryjson) && QT_DEPRECATED_SINCE(5, 15)
/*!
    \deprecated

    Deserializes the given binary JSON \a data and returns a new
    QShaderDescription.

    \sa fromCbor()
 */
QShaderDescription QShaderDescription::fromBinaryJson(const QByteArray &data)
{
    QShaderDescription desc;
QT_WARNING_PUSH
QT_WARNING_DISABLE_DEPRECATED
    QShaderDescriptionPrivate::get(&desc)->loadDoc(QJsonDocument::fromBinaryData(data));
QT_WARNING_POP
    return desc;
}
#endif

/*!
    Deserializes the given CBOR \a data and returns a new QShaderDescription.
 */
QShaderDescription QShaderDescription::fromCbor(const QByteArray &data)
{
    QShaderDescription desc;
    const QCborValue cbor = QCborValue::fromCbor(data);
    if (cbor.isMap()) {
        const QJsonDocument doc(cbor.toMap().toJsonObject());
        QShaderDescriptionPrivate::get(&desc)->loadDoc(doc);
    }
    if (cbor.isArray()) {
        const QJsonDocument doc(cbor.toArray().toJsonArray());
        QShaderDescriptionPrivate::get(&desc)->loadDoc(doc);
    }
    return desc;
}

QShaderDescription QShaderDescription::deserialize(QDataStream *stream, int version)
{
    QShaderDescription desc;
    QShaderDescriptionPrivate::get(&desc)->loadFromStream(stream, version);
    return desc;
}

/*!
    \return the list of input variables. This includes vertex inputs (sometimes
    called attributes) for the vertex stage, and inputs for other stages
    (sometimes called varyings).
 */
QVector<QShaderDescription::InOutVariable> QShaderDescription::inputVariables() const
{
    return d->inVars;
}

/*!
    \return the list of output variables.
 */
QVector<QShaderDescription::InOutVariable> QShaderDescription::outputVariables() const
{
    return d->outVars;
}

/*!
    \return the list of uniform blocks.
 */
QVector<QShaderDescription::UniformBlock> QShaderDescription::uniformBlocks() const
{
    return d->uniformBlocks;
}

/*!
    \return the list of push constant blocks.

    \note Avoid relying on push constant blocks for shaders that are to be used
    in combination with the Qt Rendering Hardware Interface since that
    currently has no support for them.
 */
QVector<QShaderDescription::PushConstantBlock> QShaderDescription::pushConstantBlocks() const
{
    return d->pushConstantBlocks;
}

/*!
    \return the list of shader storage blocks.

    For example, with GLSL/Vulkan shaders as source, the declaration

    \badcode
        struct Stuff {
            vec2 a;
            vec2 b;
        };
        layout(std140, binding = 0) buffer StuffSsbo {
            vec4 whatever;
            Stuff stuff[];
        } buf;
    \endcode

    generates the following: (shown as textual JSON here)

    \badcode
        "storageBlocks": [ {
            "binding": 0,
            "blockName": "StuffSsbo",
            "instanceName": "buf",
            "knownSize": 16,
            "members": [
                {
                    "name": "whatever",
                    "offset": 0,
                    "size": 16,
                    "type": "vec4"
                },
                {
                    "arrayDims": [
                        0
                    ],
                    "name": "stuff",
                    "offset": 16,
                    "size": 0,
                    "structMembers": [
                        {
                            "name": "a",
                            "offset": 0,
                            "size": 8,
                            "type": "vec2"
                        },
                        {
                            "name": "b",
                            "offset": 8,
                            "size": 8,
                            "type": "vec2"
                        }
                    ],
                    "type": "struct"
                }
            ],
            "set": 0
        } ]
    \endcode

    \note The size of the last member in the storage block is undefined. This shows
    up as \c size 0 and an array dimension of \c{[0]}. The storage block's \c knownSize
    excludes the size of the last member since that will only be known at run time.

    \note SSBOs are not available with some graphics APIs, such as, OpenGL 2.x or
    OpenGL ES older than 3.1.
 */
QVector<QShaderDescription::StorageBlock> QShaderDescription::storageBlocks() const
{
    return d->storageBlocks;
}

/*!
    \return the list of combined image samplers

    With GLSL/Vulkan shaders as source a \c{layout(binding = 1) uniform sampler2D tex;}
    uniform generates the following: (shown as textual JSON here)

    \badcode
       "combinedImageSamplers": [
            {
                "binding": 1,
                "name": "tex",
                "set": 0,
                "type": "sampler2D"
            }
        ]
    \endcode

    This does not mean that other language versions of the shader must also use
    a combined image sampler, especially considering that the concept may not
    exist everywhere. For instance, a HLSL version will likely just use a
    Texture2D and SamplerState object with registers t1 and s1, respectively.
  */
QVector<QShaderDescription::InOutVariable> QShaderDescription::combinedImageSamplers() const
{
    return d->combinedImageSamplers;
}

/*!
    \return the list of image variables.

    These will likely occur in compute shaders. For example,
    \c{layout (binding = 0, rgba8) uniform readonly image2D inputImage;}
    generates the following: (shown as textual JSON here)

    \badcode
       "storageImages": [
            {
                "binding": 0,
                "imageFormat": "rgba8",
                "name": "inputImage",
                "set": 0,
                "type": "image2D"
            }
        ]
    \endcode

    \note Separate image objects are not compatible with some graphics APIs,
    such as, OpenGL 2.x or OpenGL ES older than 3.1.
  */
QVector<QShaderDescription::InOutVariable> QShaderDescription::storageImages() const
{
    return d->storageImages;
}

/*!
    Returns the local size of a compute shader.

    For example, for a compute shader with the following declaration the
    function returns { 256, 16, 1}.

    \badcode
        layout(local_size_x = 256, local_size_y = 16, local_size_z = 1) in;
    \endcode
 */
std::array<uint, 3> QShaderDescription::computeShaderLocalSize() const
{
    return d->localSize;
}

static struct TypeTab {
    QString k;
    QShaderDescription::VariableType v;
} typeTab[] = {
    { QLatin1String("float"), QShaderDescription::Float },
    { QLatin1String("vec2"), QShaderDescription::Vec2 },
    { QLatin1String("vec3"), QShaderDescription::Vec3 },
    { QLatin1String("vec4"), QShaderDescription::Vec4 },
    { QLatin1String("mat2"), QShaderDescription::Mat2 },
    { QLatin1String("mat3"), QShaderDescription::Mat3 },
    { QLatin1String("mat4"), QShaderDescription::Mat4 },

    { QLatin1String("struct"), QShaderDescription::Struct },

    { QLatin1String("sampler1D"), QShaderDescription::Sampler1D },
    { QLatin1String("sampler2D"), QShaderDescription::Sampler2D },
    { QLatin1String("sampler2DMS"), QShaderDescription::Sampler2DMS },
    { QLatin1String("sampler3D"), QShaderDescription::Sampler3D },
    { QLatin1String("samplerCube"), QShaderDescription::SamplerCube },
    { QLatin1String("sampler1DArray"), QShaderDescription::Sampler1DArray },
    { QLatin1String("sampler2DArray"), QShaderDescription::Sampler2DArray },
    { QLatin1String("sampler2DMSArray"), QShaderDescription::Sampler2DMSArray },
    { QLatin1String("sampler3DArray"), QShaderDescription::Sampler3DArray },
    { QLatin1String("samplerCubeArray"), QShaderDescription::SamplerCubeArray },
    { QLatin1String("samplerRect"), QShaderDescription::SamplerRect },
    { QLatin1String("samplerBuffer"), QShaderDescription::SamplerBuffer },

    { QLatin1String("mat2x3"), QShaderDescription::Mat2x3 },
    { QLatin1String("mat2x4"), QShaderDescription::Mat2x4 },
    { QLatin1String("mat3x2"), QShaderDescription::Mat3x2 },
    { QLatin1String("mat3x4"), QShaderDescription::Mat3x4 },
    { QLatin1String("mat4x2"), QShaderDescription::Mat4x2 },
    { QLatin1String("mat4x3"), QShaderDescription::Mat4x3 },

    { QLatin1String("int"), QShaderDescription::Int },
    { QLatin1String("ivec2"), QShaderDescription::Int2 },
    { QLatin1String("ivec3"), QShaderDescription::Int3 },
    { QLatin1String("ivec4"), QShaderDescription::Int4 },

    { QLatin1String("uint"), QShaderDescription::Uint },
    { QLatin1String("uvec2"), QShaderDescription::Uint2 },
    { QLatin1String("uvec3"), QShaderDescription::Uint3 },
    { QLatin1String("uvec4"), QShaderDescription::Uint4 },

    { QLatin1String("bool"), QShaderDescription::Bool },
    { QLatin1String("bvec2"), QShaderDescription::Bool2 },
    { QLatin1String("bvec3"), QShaderDescription::Bool3 },
    { QLatin1String("bvec4"), QShaderDescription::Bool4 },

    { QLatin1String("double"), QShaderDescription::Double },
    { QLatin1String("dvec2"), QShaderDescription::Double2 },
    { QLatin1String("dvec3"), QShaderDescription::Double3 },
    { QLatin1String("dvec4"), QShaderDescription::Double4 },
    { QLatin1String("dmat2"), QShaderDescription::DMat2 },
    { QLatin1String("dmat3"), QShaderDescription::DMat3 },
    { QLatin1String("dmat4"), QShaderDescription::DMat4 },
    { QLatin1String("dmat2x3"), QShaderDescription::DMat2x3 },
    { QLatin1String("dmat2x4"), QShaderDescription::DMat2x4 },
    { QLatin1String("dmat3x2"), QShaderDescription::DMat3x2 },
    { QLatin1String("dmat3x4"), QShaderDescription::DMat3x4 },
    { QLatin1String("dmat4x2"), QShaderDescription::DMat4x2 },
    { QLatin1String("dmat4x3"), QShaderDescription::DMat4x3 },

    { QLatin1String("image1D"), QShaderDescription::Image1D },
    { QLatin1String("image2D"), QShaderDescription::Image2D },
    { QLatin1String("image2DMS"), QShaderDescription::Image2DMS },
    { QLatin1String("image3D"), QShaderDescription::Image3D },
    { QLatin1String("imageCube"), QShaderDescription::ImageCube },
    { QLatin1String("image1DArray"), QShaderDescription::Image1DArray },
    { QLatin1String("image2DArray"), QShaderDescription::Image2DArray },
    { QLatin1String("image2DMSArray"), QShaderDescription::Image2DMSArray },
    { QLatin1String("image3DArray"), QShaderDescription::Image3DArray },
    { QLatin1String("imageCubeArray"), QShaderDescription::ImageCubeArray },
    { QLatin1String("imageRect"), QShaderDescription::ImageRect },
    { QLatin1String("imageBuffer"), QShaderDescription::ImageBuffer }
};

static QString typeStr(const QShaderDescription::VariableType &t)
{
    for (size_t i = 0; i < sizeof(typeTab) / sizeof(TypeTab); ++i) {
        if (typeTab[i].v == t)
            return typeTab[i].k;
    }
    return QString();
}

static QShaderDescription::VariableType mapType(const QString &t)
{
    for (size_t i = 0; i < sizeof(typeTab) / sizeof(TypeTab); ++i) {
        if (typeTab[i].k == t)
            return typeTab[i].v;
    }
    return QShaderDescription::Unknown;
}

static struct ImageFormatTab {
    QString k;
    QShaderDescription::ImageFormat v;
} imageFormatTab[] {
    { QLatin1String("unknown"), QShaderDescription::ImageFormatUnknown },
    { QLatin1String("rgba32f"), QShaderDescription::ImageFormatRgba32f },
    { QLatin1String("rgba16"), QShaderDescription::ImageFormatRgba16f },
    { QLatin1String("r32f"), QShaderDescription::ImageFormatR32f },
    { QLatin1String("rgba8"), QShaderDescription::ImageFormatRgba8 },
    { QLatin1String("rgba8_snorm"), QShaderDescription::ImageFormatRgba8Snorm },
    { QLatin1String("rg32f"), QShaderDescription::ImageFormatRg32f },
    { QLatin1String("rg16f"), QShaderDescription::ImageFormatRg16f },
    { QLatin1String("r11f_g11f_b10f"), QShaderDescription::ImageFormatR11fG11fB10f },
    { QLatin1String("r16f"), QShaderDescription::ImageFormatR16f },
    { QLatin1String("rgba16"), QShaderDescription::ImageFormatRgba16 },
    { QLatin1String("rgb10_a2"), QShaderDescription::ImageFormatRgb10A2 },
    { QLatin1String("rg16"), QShaderDescription::ImageFormatRg16 },
    { QLatin1String("rg8"), QShaderDescription::ImageFormatRg8 },
    { QLatin1String("r16"), QShaderDescription::ImageFormatR16 },
    { QLatin1String("r8"), QShaderDescription::ImageFormatR8 },
    { QLatin1String("rgba16_snorm"), QShaderDescription::ImageFormatRgba16Snorm },
    { QLatin1String("rg16_snorm"), QShaderDescription::ImageFormatRg16Snorm },
    { QLatin1String("rg8_snorm"), QShaderDescription::ImageFormatRg8Snorm },
    { QLatin1String("r16_snorm"), QShaderDescription::ImageFormatR16Snorm },
    { QLatin1String("r8_snorm"), QShaderDescription::ImageFormatR8Snorm },
    { QLatin1String("rgba32i"), QShaderDescription::ImageFormatRgba32i },
    { QLatin1String("rgba16i"), QShaderDescription::ImageFormatRgba16i },
    { QLatin1String("rgba8i"), QShaderDescription::ImageFormatRgba8i },
    { QLatin1String("r32i"), QShaderDescription::ImageFormatR32i },
    { QLatin1String("rg32i"), QShaderDescription::ImageFormatRg32i },
    { QLatin1String("rg16i"), QShaderDescription::ImageFormatRg16i },
    { QLatin1String("rg8i"), QShaderDescription::ImageFormatRg8i },
    { QLatin1String("r16i"), QShaderDescription::ImageFormatR16i },
    { QLatin1String("r8i"), QShaderDescription::ImageFormatR8i },
    { QLatin1String("rgba32ui"), QShaderDescription::ImageFormatRgba32ui },
    { QLatin1String("rgba16ui"), QShaderDescription::ImageFormatRgba16ui },
    { QLatin1String("rgba8ui"), QShaderDescription::ImageFormatRgba8ui },
    { QLatin1String("r32ui"), QShaderDescription::ImageFormatR32ui },
    { QLatin1String("rgb10_a2ui"), QShaderDescription::ImageFormatRgb10a2ui },
    { QLatin1String("rg32ui"), QShaderDescription::ImageFormatRg32ui },
    { QLatin1String("rg16ui"), QShaderDescription::ImageFormatRg16ui },
    { QLatin1String("rg8ui"), QShaderDescription::ImageFormatRg8ui },
    { QLatin1String("r16ui"), QShaderDescription::ImageFormatR16ui },
    { QLatin1String("r8ui"), QShaderDescription::ImageFormatR8ui }
};

static QString imageFormatStr(const QShaderDescription::ImageFormat &f)
{
    for (size_t i = 0; i < sizeof(imageFormatTab) / sizeof(ImageFormatTab); ++i) {
        if (imageFormatTab[i].v == f)
            return imageFormatTab[i].k;
    }
    return QString();
}

static QShaderDescription::ImageFormat mapImageFormat(const QString &f)
{
    for (size_t i = 0; i < sizeof(imageFormatTab) / sizeof(ImageFormatTab); ++i) {
        if (imageFormatTab[i].k == f)
            return imageFormatTab[i].v;
    }
    return QShaderDescription::ImageFormatUnknown;
}

#ifndef QT_NO_DEBUG_STREAM
QDebug operator<<(QDebug dbg, const QShaderDescription &sd)
{
    const QShaderDescriptionPrivate *d = sd.d;
    QDebugStateSaver saver(dbg);

    if (sd.isValid()) {
        dbg.nospace() << "QShaderDescription("
                      << "inVars " << d->inVars
                      << " outVars " << d->outVars
                      << " uniformBlocks " << d->uniformBlocks
                      << " pcBlocks " << d->pushConstantBlocks
                      << " storageBlocks " << d->storageBlocks
                      << " combinedSamplers " << d->combinedImageSamplers
                      << " images " << d->storageImages
                      << ')';
    } else {
        dbg.nospace() << "QShaderDescription(null)";
    }

    return dbg;
}

QDebug operator<<(QDebug dbg, const QShaderDescription::InOutVariable &var)
{
    QDebugStateSaver saver(dbg);
    dbg.nospace() << "InOutVariable(" << typeStr(var.type) << ' ' << var.name;
    if (var.location >= 0)
        dbg.nospace() << " location=" << var.location;
    if (var.binding >= 0)
        dbg.nospace() << " binding=" << var.binding;
    if (var.descriptorSet >= 0)
        dbg.nospace() << " set=" << var.descriptorSet;
    if (var.imageFormat != QShaderDescription::ImageFormatUnknown)
        dbg.nospace() << " imageFormat=" << imageFormatStr(var.imageFormat);
    if (var.imageFlags)
        dbg.nospace() << " imageFlags=" << var.imageFlags;
    if (!var.arrayDims.isEmpty())
        dbg.nospace() << " array=" << var.arrayDims;
    dbg.nospace() << ')';
    return dbg;
}

QDebug operator<<(QDebug dbg, const QShaderDescription::BlockVariable &var)
{
    QDebugStateSaver saver(dbg);
    dbg.nospace() << "BlockVariable(" << typeStr(var.type) << ' ' << var.name
                  << " offset=" << var.offset << " size=" << var.size;
    if (!var.arrayDims.isEmpty())
        dbg.nospace() << " array=" << var.arrayDims;
    if (var.arrayStride)
        dbg.nospace() << " arrayStride=" << var.arrayStride;
    if (var.matrixStride)
        dbg.nospace() << " matrixStride=" << var.matrixStride;
    if (var.matrixIsRowMajor)
        dbg.nospace() << " [rowmaj]";
    if (!var.structMembers.isEmpty())
        dbg.nospace() << " structMembers=" << var.structMembers;
    dbg.nospace() << ')';
    return dbg;
}

QDebug operator<<(QDebug dbg, const QShaderDescription::UniformBlock &blk)
{
    QDebugStateSaver saver(dbg);
    dbg.nospace() << "UniformBlock(" << blk.blockName << ' ' << blk.structName << " size=" << blk.size;
    if (blk.binding >= 0)
        dbg.nospace() << " binding=" << blk.binding;
    if (blk.descriptorSet >= 0)
        dbg.nospace() << " set=" << blk.descriptorSet;
    dbg.nospace() << ' ' << blk.members << ')';
    return dbg;
}

QDebug operator<<(QDebug dbg, const QShaderDescription::PushConstantBlock &blk)
{
    QDebugStateSaver saver(dbg);
    dbg.nospace() << "PushConstantBlock(" << blk.name << " size=" << blk.size << ' ' << blk.members << ')';
    return dbg;
}

QDebug operator<<(QDebug dbg, const QShaderDescription::StorageBlock &blk)
{
    QDebugStateSaver saver(dbg);
    dbg.nospace() << "StorageBlock(" << blk.blockName << ' ' << blk.instanceName << " knownSize=" << blk.knownSize;
    if (blk.binding >= 0)
        dbg.nospace() << " binding=" << blk.binding;
    if (blk.descriptorSet >= 0)
        dbg.nospace() << " set=" << blk.descriptorSet;
    dbg.nospace() << ' ' << blk.members << ')';
    return dbg;
}
#endif

static const QString nameKey = QLatin1String("name");
static const QString typeKey = QLatin1String("type");
static const QString locationKey = QLatin1String("location");
static const QString bindingKey = QLatin1String("binding");
static const QString setKey = QLatin1String("set");
static const QString imageFormatKey = QLatin1String("imageFormat");
static const QString imageFlagsKey = QLatin1String("imageFlags");
static const QString offsetKey = QLatin1String("offset");
static const QString arrayDimsKey = QLatin1String("arrayDims");
static const QString arrayStrideKey = QLatin1String("arrayStride");
static const QString matrixStrideKey = QLatin1String("matrixStride");
static const QString matrixRowMajorKey = QLatin1String("matrixRowMajor");
static const QString structMembersKey = QLatin1String("structMembers");
static const QString membersKey = QLatin1String("members");
static const QString inputsKey = QLatin1String("inputs");
static const QString outputsKey = QLatin1String("outputs");
static const QString uniformBlocksKey = QLatin1String("uniformBlocks");
static const QString blockNameKey = QLatin1String("blockName");
static const QString structNameKey = QLatin1String("structName");
static const QString instanceNameKey = QLatin1String("instanceName");
static const QString sizeKey = QLatin1String("size");
static const QString knownSizeKey = QLatin1String("knownSize");
static const QString pushConstantBlocksKey = QLatin1String("pushConstantBlocks");
static const QString storageBlocksKey = QLatin1String("storageBlocks");
static const QString combinedImageSamplersKey = QLatin1String("combinedImageSamplers");
static const QString storageImagesKey = QLatin1String("storageImages");
static const QString localSizeKey = QLatin1String("localSize");

static void addDeco(QJsonObject *obj, const QShaderDescription::InOutVariable &v)
{
    if (v.location >= 0)
        (*obj)[locationKey] = v.location;
    if (v.binding >= 0)
        (*obj)[bindingKey] = v.binding;
    if (v.descriptorSet >= 0)
        (*obj)[setKey] = v.descriptorSet;
    if (v.imageFormat != QShaderDescription::ImageFormatUnknown)
        (*obj)[imageFormatKey] = imageFormatStr(v.imageFormat);
    if (v.imageFlags)
        (*obj)[imageFlagsKey] = int(v.imageFlags);
    if (!v.arrayDims.isEmpty()) {
        QJsonArray dimArr;
        for (int dim : v.arrayDims)
            dimArr.append(dim);
        (*obj)[arrayDimsKey] = dimArr;
    }
}

static void serializeDecorations(QDataStream *stream, const QShaderDescription::InOutVariable &v)
{
    (*stream) << v.location;
    (*stream) << v.binding;
    (*stream) << v.descriptorSet;
    (*stream) << int(v.imageFormat);
    (*stream) << int(v.imageFlags);
    (*stream) << v.arrayDims.count();
    for (int dim : v.arrayDims)
        (*stream) << dim;
}

static QJsonObject inOutObject(const QShaderDescription::InOutVariable &v)
{
    QJsonObject obj;
    obj[nameKey] = v.name;
    obj[typeKey] = typeStr(v.type);
    addDeco(&obj, v);
    return obj;
}

static void serializeInOutVar(QDataStream *stream, const QShaderDescription::InOutVariable &v)
{
    (*stream) << v.name;
    (*stream) << int(v.type);
    serializeDecorations(stream, v);
}

static QJsonObject blockMemberObject(const QShaderDescription::BlockVariable &v)
{
    QJsonObject obj;
    obj[nameKey] = v.name;
    obj[typeKey] = typeStr(v.type);
    obj[offsetKey] = v.offset;
    obj[sizeKey] = v.size;
    if (!v.arrayDims.isEmpty()) {
        QJsonArray dimArr;
        for (int dim : v.arrayDims)
            dimArr.append(dim);
        obj[arrayDimsKey] = dimArr;
    }
    if (v.arrayStride)
        obj[arrayStrideKey] = v.arrayStride;
    if (v.matrixStride)
        obj[matrixStrideKey] = v.matrixStride;
    if (v.matrixIsRowMajor)
        obj[matrixRowMajorKey] = true;
    if (!v.structMembers.isEmpty()) {
        QJsonArray arr;
        for (const QShaderDescription::BlockVariable &sv : v.structMembers)
            arr.append(blockMemberObject(sv));
        obj[structMembersKey] = arr;
    }
    return obj;
}

static void serializeBlockMemberVar(QDataStream *stream, const QShaderDescription::BlockVariable &v)
{
    (*stream) << v.name;
    (*stream) << int(v.type);
    (*stream) << v.offset;
    (*stream) << v.size;
    (*stream) << v.arrayDims.count();
    for (int dim : v.arrayDims)
        (*stream) << dim;
    (*stream) << v.arrayStride;
    (*stream) << v.matrixStride;
    (*stream) << v.matrixIsRowMajor;
    (*stream) << v.structMembers.count();
    for (const QShaderDescription::BlockVariable &sv : v.structMembers)
        serializeBlockMemberVar(stream, sv);
}

QJsonDocument QShaderDescriptionPrivate::makeDoc()
{
    QJsonObject root;

    QJsonArray jinputs;
    for (const QShaderDescription::InOutVariable &v : qAsConst(inVars))
        jinputs.append(inOutObject(v));
    if (!jinputs.isEmpty())
        root[inputsKey] = jinputs;

    QJsonArray joutputs;
    for (const QShaderDescription::InOutVariable &v : qAsConst(outVars))
        joutputs.append(inOutObject(v));
    if (!joutputs.isEmpty())
        root[outputsKey] = joutputs;

    QJsonArray juniformBlocks;
    for (const QShaderDescription::UniformBlock &b : uniformBlocks) {
        QJsonObject juniformBlock;
        juniformBlock[blockNameKey] = b.blockName;
        juniformBlock[structNameKey] = b.structName;
        juniformBlock[sizeKey] = b.size;
        if (b.binding >= 0)
            juniformBlock[bindingKey] = b.binding;
        if (b.descriptorSet >= 0)
            juniformBlock[setKey] = b.descriptorSet;
        QJsonArray members;
        for (const QShaderDescription::BlockVariable &v : b.members)
            members.append(blockMemberObject(v));
        juniformBlock[membersKey] = members;
        juniformBlocks.append(juniformBlock);
    }
    if (!juniformBlocks.isEmpty())
        root[uniformBlocksKey] = juniformBlocks;

    QJsonArray jpushConstantBlocks;
    for (const QShaderDescription::PushConstantBlock &b : pushConstantBlocks) {
        QJsonObject jpushConstantBlock;
        jpushConstantBlock[nameKey] = b.name;
        jpushConstantBlock[sizeKey] = b.size;
        QJsonArray members;
        for (const QShaderDescription::BlockVariable &v : b.members)
            members.append(blockMemberObject(v));
        jpushConstantBlock[membersKey] = members;
        jpushConstantBlocks.append(jpushConstantBlock);
    }
    if (!jpushConstantBlocks.isEmpty())
        root[pushConstantBlocksKey] = jpushConstantBlocks;

    QJsonArray jstorageBlocks;
    for (const QShaderDescription::StorageBlock &b : storageBlocks) {
        QJsonObject jstorageBlock;
        jstorageBlock[blockNameKey] = b.blockName;
        jstorageBlock[instanceNameKey] = b.instanceName;
        jstorageBlock[knownSizeKey] = b.knownSize;
        if (b.binding >= 0)
            jstorageBlock[bindingKey] = b.binding;
        if (b.descriptorSet >= 0)
            jstorageBlock[setKey] = b.descriptorSet;
        QJsonArray members;
        for (const QShaderDescription::BlockVariable &v : b.members)
            members.append(blockMemberObject(v));
        jstorageBlock[membersKey] = members;
        jstorageBlocks.append(jstorageBlock);
    }
    if (!jstorageBlocks.isEmpty())
        root[storageBlocksKey] = jstorageBlocks;

    QJsonArray jcombinedSamplers;
    for (const QShaderDescription::InOutVariable &v : qAsConst(combinedImageSamplers)) {
        QJsonObject sampler;
        sampler[nameKey] = v.name;
        sampler[typeKey] = typeStr(v.type);
        addDeco(&sampler, v);
        jcombinedSamplers.append(sampler);
    }
    if (!jcombinedSamplers.isEmpty())
        root[combinedImageSamplersKey] = jcombinedSamplers;

    QJsonArray jstorageImages;
    for (const QShaderDescription::InOutVariable &v : qAsConst(storageImages)) {
        QJsonObject image;
        image[nameKey] = v.name;
        image[typeKey] = typeStr(v.type);
        addDeco(&image, v);
        jstorageImages.append(image);
    }
    if (!jstorageImages.isEmpty())
        root[storageImagesKey] = jstorageImages;

    QJsonArray jlocalSize;
    for (int i = 0; i < 3; ++i)
        jlocalSize.append(QJsonValue(int(localSize[i])));
    root[localSizeKey] = jlocalSize;

    return QJsonDocument(root);
}

void QShaderDescriptionPrivate::writeToStream(QDataStream *stream)
{
    (*stream) << inVars.count();
    for (const QShaderDescription::InOutVariable &v : qAsConst(inVars))
        serializeInOutVar(stream, v);

    (*stream) << outVars.count();
    for (const QShaderDescription::InOutVariable &v : qAsConst(outVars))
        serializeInOutVar(stream, v);

    (*stream) << uniformBlocks.count();
    for (const QShaderDescription::UniformBlock &b : uniformBlocks) {
        (*stream) << b.blockName;
        (*stream) << b.structName;
        (*stream) << b.size;
        (*stream) << b.binding;
        (*stream) << b.descriptorSet;
        (*stream) << b.members.count();
        for (const QShaderDescription::BlockVariable &v : b.members)
            serializeBlockMemberVar(stream, v);
    }

    (*stream) << pushConstantBlocks.count();
    for (const QShaderDescription::PushConstantBlock &b : pushConstantBlocks) {
        (*stream) << b.name;
        (*stream) << b.size;
        (*stream) << b.members.count();
        for (const QShaderDescription::BlockVariable &v : b.members)
            serializeBlockMemberVar(stream, v);
    }

    (*stream) << storageBlocks.count();
    for (const QShaderDescription::StorageBlock &b : storageBlocks) {
        (*stream) << b.blockName;
        (*stream) << b.instanceName;
        (*stream) << b.knownSize;
        (*stream) << b.binding;
        (*stream) << b.descriptorSet;
        (*stream) << b.members.count();
        for (const QShaderDescription::BlockVariable &v : b.members)
            serializeBlockMemberVar(stream, v);
    }

    (*stream) << combinedImageSamplers.count();
    for (const QShaderDescription::InOutVariable &v : qAsConst(combinedImageSamplers)) {
        (*stream) << v.name;
        (*stream) << int(v.type);
        serializeDecorations(stream, v);
    }

    (*stream) << storageImages.count();
    for (const QShaderDescription::InOutVariable &v : qAsConst(storageImages)) {
        (*stream) << v.name;
        (*stream) << int(v.type);
        serializeDecorations(stream, v);
    }

    for (size_t i = 0; i < 3; ++i)
        (*stream) << localSize[i];
}

static QShaderDescription::InOutVariable inOutVar(const QJsonObject &obj)
{
    QShaderDescription::InOutVariable var;
    var.name = obj[nameKey].toString();
    var.type = mapType(obj[typeKey].toString());
    if (obj.contains(locationKey))
        var.location = obj[locationKey].toInt();
    if (obj.contains(bindingKey))
        var.binding = obj[bindingKey].toInt();
    if (obj.contains(setKey))
        var.descriptorSet = obj[setKey].toInt();
    if (obj.contains(imageFormatKey))
        var.imageFormat = mapImageFormat(obj[imageFormatKey].toString());
    if (obj.contains(imageFlagsKey))
        var.imageFlags = QShaderDescription::ImageFlags(obj[imageFlagsKey].toInt());
    if (obj.contains(arrayDimsKey)) {
        QJsonArray dimArr = obj[arrayDimsKey].toArray();
        for (int i = 0; i < dimArr.count(); ++i)
            var.arrayDims.append(dimArr.at(i).toInt());
    }
    return var;
}

static void deserializeDecorations(QDataStream *stream, int version, QShaderDescription::InOutVariable *v)
{
    (*stream) >> v->location;
    (*stream) >> v->binding;
    (*stream) >> v->descriptorSet;
    int f;
    (*stream) >> f;
    v->imageFormat = QShaderDescription::ImageFormat(f);
    (*stream) >> f;
    v->imageFlags = QShaderDescription::ImageFlags(f);

    if (version > QShaderPrivate::QSB_VERSION_WITHOUT_VAR_ARRAYDIMS) {
        (*stream) >> f;
        v->arrayDims.resize(f);
        for (int i = 0; i < f; ++i)
            (*stream) >> v->arrayDims[i];
    }
}

static QShaderDescription::InOutVariable deserializeInOutVar(QDataStream *stream, int version)
{
    QShaderDescription::InOutVariable var;
    (*stream) >> var.name;
    int t;
    (*stream) >> t;
    var.type = QShaderDescription::VariableType(t);
    deserializeDecorations(stream, version, &var);
    return var;
}

static QShaderDescription::BlockVariable blockVar(const QJsonObject &obj)
{
    QShaderDescription::BlockVariable var;
    var.name = obj[nameKey].toString();
    var.type = mapType(obj[typeKey].toString());
    var.offset = obj[offsetKey].toInt();
    var.size = obj[sizeKey].toInt();
    if (obj.contains(arrayDimsKey)) {
        QJsonArray dimArr = obj[arrayDimsKey].toArray();
        for (int i = 0; i < dimArr.count(); ++i)
            var.arrayDims.append(dimArr.at(i).toInt());
    }
    if (obj.contains(arrayStrideKey))
        var.arrayStride = obj[arrayStrideKey].toInt();
    if (obj.contains(matrixStrideKey))
        var.matrixStride = obj[matrixStrideKey].toInt();
    if (obj.contains(matrixRowMajorKey))
        var.matrixIsRowMajor = obj[matrixRowMajorKey].toBool();
    if (obj.contains(structMembersKey)) {
        QJsonArray arr = obj[structMembersKey].toArray();
        for (int i = 0; i < arr.count(); ++i)
            var.structMembers.append(blockVar(arr.at(i).toObject()));
    }
    return var;
}

static QShaderDescription::BlockVariable deserializeBlockMemberVar(QDataStream *stream, int version)
{
    QShaderDescription::BlockVariable var;
    (*stream) >> var.name;
    int t;
    (*stream) >> t;
    var.type = QShaderDescription::VariableType(t);
    (*stream) >> var.offset;
    (*stream) >> var.size;
    int count;
    (*stream) >> count;
    var.arrayDims.resize(count);
    for (int i = 0; i < count; ++i)
        (*stream) >> var.arrayDims[i];
    (*stream) >> var.arrayStride;
    (*stream) >> var.matrixStride;
    (*stream) >> var.matrixIsRowMajor;
    (*stream) >> count;
    var.structMembers.resize(count);
    for (int i = 0; i < count; ++i)
        var.structMembers[i] = deserializeBlockMemberVar(stream, version);
    return var;
}

void QShaderDescriptionPrivate::loadDoc(const QJsonDocument &doc)
{
    if (doc.isNull()) {
        qWarning("QShaderDescription: JSON document is empty");
        return;
    }

    Q_ASSERT(ref.loadRelaxed() == 1); // must be detached

    inVars.clear();
    outVars.clear();
    uniformBlocks.clear();
    pushConstantBlocks.clear();
    storageBlocks.clear();
    combinedImageSamplers.clear();
    storageImages.clear();

    QJsonObject root = doc.object();

    if (root.contains(inputsKey)) {
        QJsonArray inputs = root[inputsKey].toArray();
        for (int i = 0; i < inputs.count(); ++i)
            inVars.append(inOutVar(inputs[i].toObject()));
    }

    if (root.contains(outputsKey)) {
        QJsonArray outputs = root[outputsKey].toArray();
        for (int i = 0; i < outputs.count(); ++i)
            outVars.append(inOutVar(outputs[i].toObject()));
    }

    if (root.contains(uniformBlocksKey)) {
        QJsonArray ubs = root[uniformBlocksKey].toArray();
        for (int i = 0; i < ubs.count(); ++i) {
            QJsonObject ubObj = ubs[i].toObject();
            QShaderDescription::UniformBlock ub;
            ub.blockName = ubObj[blockNameKey].toString();
            ub.structName = ubObj[structNameKey].toString();
            ub.size = ubObj[sizeKey].toInt();
            if (ubObj.contains(bindingKey))
                ub.binding = ubObj[bindingKey].toInt();
            if (ubObj.contains(setKey))
                ub.descriptorSet = ubObj[setKey].toInt();
            QJsonArray members = ubObj[membersKey].toArray();
            for (const QJsonValue &member : members)
                ub.members.append(blockVar(member.toObject()));
            uniformBlocks.append(ub);
        }
    }

    if (root.contains(pushConstantBlocksKey)) {
        QJsonArray pcs = root[pushConstantBlocksKey].toArray();
        for (int i = 0; i < pcs.count(); ++i) {
            QJsonObject pcObj = pcs[i].toObject();
            QShaderDescription::PushConstantBlock pc;
            pc.name = pcObj[nameKey].toString();
            pc.size = pcObj[sizeKey].toInt();
            QJsonArray members = pcObj[membersKey].toArray();
            for (const QJsonValue &member : members)
                pc.members.append(blockVar(member.toObject()));
            pushConstantBlocks.append(pc);
        }
    }

    if (root.contains(storageBlocksKey)) {
        QJsonArray ubs = root[storageBlocksKey].toArray();
        for (int i = 0; i < ubs.count(); ++i) {
            QJsonObject sbObj = ubs[i].toObject();
            QShaderDescription::StorageBlock sb;
            sb.blockName = sbObj[blockNameKey].toString();
            sb.instanceName = sbObj[instanceNameKey].toString();
            sb.knownSize = sbObj[knownSizeKey].toInt();
            if (sbObj.contains(bindingKey))
                sb.binding = sbObj[bindingKey].toInt();
            if (sbObj.contains(setKey))
                sb.descriptorSet = sbObj[setKey].toInt();
            QJsonArray members = sbObj[membersKey].toArray();
            for (const QJsonValue &member : members)
                sb.members.append(blockVar(member.toObject()));
            storageBlocks.append(sb);
        }
    }

    if (root.contains(combinedImageSamplersKey)) {
        QJsonArray samplers = root[combinedImageSamplersKey].toArray();
        for (int i = 0; i < samplers.count(); ++i)
            combinedImageSamplers.append(inOutVar(samplers[i].toObject()));
    }

    if (root.contains(storageImagesKey)) {
        QJsonArray images = root[storageImagesKey].toArray();
        for (int i = 0; i < images.count(); ++i)
            storageImages.append(inOutVar(images[i].toObject()));
    }

    if (root.contains(localSizeKey)) {
        QJsonArray localSizeArr = root[localSizeKey].toArray();
        if (localSizeArr.count() == 3) {
            for (int i = 0; i < 3; ++i)
                localSize[i] = localSizeArr[i].toInt();
        }
    }
}

void QShaderDescriptionPrivate::loadFromStream(QDataStream *stream, int version)
{
    Q_ASSERT(ref.loadRelaxed() == 1); // must be detached

    int count;
    (*stream) >> count;
    inVars.resize(count);
    for (int i = 0; i < count; ++i)
        inVars[i] = deserializeInOutVar(stream, version);

    (*stream) >> count;
    outVars.resize(count);
    for (int i = 0; i < count; ++i)
        outVars[i] = deserializeInOutVar(stream, version);

    (*stream) >> count;
    uniformBlocks.resize(count);
    for (int i = 0; i < count; ++i) {
        (*stream) >> uniformBlocks[i].blockName;
        (*stream) >> uniformBlocks[i].structName;
        (*stream) >> uniformBlocks[i].size;
        (*stream) >> uniformBlocks[i].binding;
        (*stream) >> uniformBlocks[i].descriptorSet;
        int memberCount;
        (*stream) >> memberCount;
        uniformBlocks[i].members.resize(memberCount);
        for (int memberIdx = 0; memberIdx < memberCount; ++memberIdx)
            uniformBlocks[i].members[memberIdx] = deserializeBlockMemberVar(stream, version);
    }

    (*stream) >> count;
    pushConstantBlocks.resize(count);
    for (int i = 0; i < count; ++i) {
        (*stream) >> pushConstantBlocks[i].name;
        (*stream) >> pushConstantBlocks[i].size;
        int memberCount;
        (*stream) >> memberCount;
        pushConstantBlocks[i].members.resize(memberCount);
        for (int memberIdx = 0; memberIdx < memberCount; ++memberIdx)
            pushConstantBlocks[i].members[memberIdx] = deserializeBlockMemberVar(stream, version);
    }

    (*stream) >> count;
    storageBlocks.resize(count);
    for (int i = 0; i < count; ++i) {
        (*stream) >> storageBlocks[i].blockName;
        (*stream) >> storageBlocks[i].instanceName;
        (*stream) >> storageBlocks[i].knownSize;
        (*stream) >> storageBlocks[i].binding;
        (*stream) >> storageBlocks[i].descriptorSet;
        int memberCount;
        (*stream) >> memberCount;
        storageBlocks[i].members.resize(memberCount);
        for (int memberIdx = 0; memberIdx < memberCount; ++memberIdx)
            storageBlocks[i].members[memberIdx] = deserializeBlockMemberVar(stream, version);
    }

    (*stream) >> count;
    combinedImageSamplers.resize(count);
    for (int i = 0; i < count; ++i) {
        (*stream) >> combinedImageSamplers[i].name;
        int t;
        (*stream) >> t;
        combinedImageSamplers[i].type = QShaderDescription::VariableType(t);
        deserializeDecorations(stream, version, &combinedImageSamplers[i]);
    }

    (*stream) >> count;
    storageImages.resize(count);
    for (int i = 0; i < count; ++i) {
        (*stream) >> storageImages[i].name;
        int t;
        (*stream) >> t;
        storageImages[i].type = QShaderDescription::VariableType(t);
        deserializeDecorations(stream, version, &storageImages[i]);
    }

    for (size_t i = 0; i < 3; ++i)
        (*stream) >> localSize[i];
}

/*!
    Returns \c true if the two QShaderDescription objects \a lhs and \a rhs are
    equal.

    \relates QShaderDescription
 */
bool operator==(const QShaderDescription &lhs, const QShaderDescription &rhs) Q_DECL_NOTHROW
{
    if (lhs.d == rhs.d)
        return true;

    return lhs.d->inVars == rhs.d->inVars
            && lhs.d->outVars == rhs.d->outVars
            && lhs.d->uniformBlocks == rhs.d->uniformBlocks
            && lhs.d->pushConstantBlocks == rhs.d->pushConstantBlocks
            && lhs.d->storageBlocks == rhs.d->storageBlocks
            && lhs.d->combinedImageSamplers == rhs.d->combinedImageSamplers
            && lhs.d->storageImages == rhs.d->storageImages
            && lhs.d->localSize == rhs.d->localSize;
}

/*!
    Returns \c true if the two InOutVariable objects \a lhs and \a rhs are
    equal.

    \relates QShaderDescription::InOutVariable
 */
bool operator==(const QShaderDescription::InOutVariable &lhs, const QShaderDescription::InOutVariable &rhs) Q_DECL_NOTHROW
{
    return lhs.name == rhs.name
            && lhs.type == rhs.type
            && lhs.location == rhs.location
            && lhs.binding == rhs.binding
            && lhs.descriptorSet == rhs.descriptorSet
            && lhs.imageFormat == rhs.imageFormat
            && lhs.imageFlags == rhs.imageFlags
            && lhs.arrayDims == rhs.arrayDims;
}

/*!
    Returns \c true if the two BlockVariable objects \a lhs and \a rhs are
    equal.

    \relates QShaderDescription::BlockVariable
 */
bool operator==(const QShaderDescription::BlockVariable &lhs, const QShaderDescription::BlockVariable &rhs) Q_DECL_NOTHROW
{
    return lhs.name == rhs.name
            && lhs.type == rhs.type
            && lhs.offset == rhs.offset
            && lhs.size == rhs.size
            && lhs.arrayDims == rhs.arrayDims
            && lhs.arrayStride == rhs.arrayStride
            && lhs.matrixStride == rhs.matrixStride
            && lhs.matrixIsRowMajor == rhs.matrixIsRowMajor
            && lhs.structMembers == rhs.structMembers;
}

/*!
    Returns \c true if the two UniformBlock objects \a lhs and \a rhs are
    equal.

    \relates QShaderDescription::UniformBlock
 */
bool operator==(const QShaderDescription::UniformBlock &lhs, const QShaderDescription::UniformBlock &rhs) Q_DECL_NOTHROW
{
    return lhs.blockName == rhs.blockName
            && lhs.structName == rhs.structName
            && lhs.size == rhs.size
            && lhs.binding == rhs.binding
            && lhs.descriptorSet == rhs.descriptorSet
            && lhs.members == rhs.members;
}

/*!
    Returns \c true if the two PushConstantBlock objects \a lhs and \a rhs are
    equal.

    \relates QShaderDescription::PushConstantBlock
 */
bool operator==(const QShaderDescription::PushConstantBlock &lhs, const QShaderDescription::PushConstantBlock &rhs) Q_DECL_NOTHROW
{
    return lhs.name == rhs.name
            && lhs.size == rhs.size
            && lhs.members == rhs.members;
}

/*!
    Returns \c true if the two StorageBlock objects \a lhs and \a rhs are
    equal.

    \relates QShaderDescription::StorageBlock
 */
bool operator==(const QShaderDescription::StorageBlock &lhs, const QShaderDescription::StorageBlock &rhs) Q_DECL_NOTHROW
{
    return lhs.blockName == rhs.blockName
            && lhs.instanceName == rhs.instanceName
            && lhs.knownSize == rhs.knownSize
            && lhs.binding == rhs.binding
            && lhs.descriptorSet == rhs.descriptorSet
            && lhs.members == rhs.members;
}

QT_END_NAMESPACE
