summaryrefslogtreecommitdiffstats
path: root/src/gui/rhi/qshaderdescription.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/rhi/qshaderdescription.cpp')
-rw-r--r--src/gui/rhi/qshaderdescription.cpp1398
1 files changed, 1086 insertions, 312 deletions
diff --git a/src/gui/rhi/qshaderdescription.cpp b/src/gui/rhi/qshaderdescription.cpp
index 2c79acb1c7..f64daf02ef 100644
--- a/src/gui/rhi/qshaderdescription.cpp
+++ b/src/gui/rhi/qshaderdescription.cpp
@@ -1,44 +1,8 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the Qt Gui module
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qshaderdescription_p_p.h"
-#include "qshader_p_p.h"
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include "qshaderdescription_p.h"
+#include "qshader_p.h"
#include <QDebug>
#include <QDataStream>
#include <QJsonObject>
@@ -48,11 +12,22 @@ QT_BEGIN_NAMESPACE
/*!
\class QShaderDescription
- \internal
+ \ingroup painting-3D
\inmodule QtGui
+ \since 6.6
\brief Describes the interface of a shader.
+ \warning The QRhi family of classes in the Qt Gui module, including QShader
+ and QShaderDescription, offer limited compatibility guarantees. There are
+ no source or binary compatibility guarantees for these classes, meaning the
+ API is only guaranteed to work with the Qt version the application was
+ developed against. Source incompatible changes are however aimed to be kept
+ at a minimum and will only be made in minor releases (6.7, 6.8, and so on).
+ To use these classes in an application, link to
+ \c{Qt::GuiPrivate} (if using CMake), and include the headers with the \c
+ rhi prefix, for example \c{#include <rhi/qshaderdescription.h>}.
+
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
@@ -87,8 +62,6 @@ QT_BEGIN_NAMESPACE
float opacity;
} ubuf;
- out gl_PerVertex { vec4 gl_Position; };
-
void main()
{
v_color = color;
@@ -222,6 +195,7 @@ QT_BEGIN_NAMESPACE
\value SamplerRect
\value SamplerBuffer
\value SamplerExternalOES
+ \value Sampler For separate samplers.
\value Image1D
\value Image2D
\value Image2DMS
@@ -235,28 +209,179 @@ QT_BEGIN_NAMESPACE
\value ImageRect
\value ImageBuffer
\value Struct
+ \value Half
+ \value Half2
+ \value Half3
+ \value Half4
*/
/*!
- \class QShaderDescription::InOutVariable
- \internal
+ \enum QShaderDescription::ImageFormat
+ Image format.
+
+ \value ImageFormatUnknown
+ \value ImageFormatRgba32f
+ \value ImageFormatRgba16f
+ \value ImageFormatR32f
+ \value ImageFormatRgba8
+ \value ImageFormatRgba8Snorm
+ \value ImageFormatRg32f
+ \value ImageFormatRg16f
+ \value ImageFormatR11fG11fB10f
+ \value ImageFormatR16f
+ \value ImageFormatRgba16
+ \value ImageFormatRgb10A2
+ \value ImageFormatRg16
+ \value ImageFormatRg8
+ \value ImageFormatR16
+ \value ImageFormatR8
+ \value ImageFormatRgba16Snorm
+ \value ImageFormatRg16Snorm
+ \value ImageFormatRg8Snorm
+ \value ImageFormatR16Snorm
+ \value ImageFormatR8Snorm
+ \value ImageFormatRgba32i
+ \value ImageFormatRgba16i
+ \value ImageFormatRgba8i
+ \value ImageFormatR32i
+ \value ImageFormatRg32i
+ \value ImageFormatRg16i
+ \value ImageFormatRg8i
+ \value ImageFormatR16i
+ \value ImageFormatR8i
+ \value ImageFormatRgba32ui
+ \value ImageFormatRgba16ui
+ \value ImageFormatRgba8ui
+ \value ImageFormatR32ui
+ \value ImageFormatRgb10a2ui
+ \value ImageFormatRg32ui
+ \value ImageFormatRg16ui
+ \value ImageFormatRg8ui
+ \value ImageFormatR16ui
+ \value ImageFormatR8ui
+ */
+
+/*!
+ \enum QShaderDescription::ImageFlag
+ Image flags.
+
+ \value ReadOnlyImage
+ \value WriteOnlyImage
+ */
+
+/*!
+ \enum QShaderDescription::QualifierFlag
+ Qualifier flags.
+
+ \value QualifierReadOnly
+ \value QualifierWriteOnly
+ \value QualifierCoherent
+ \value QualifierVolatile
+ \value QualifierRestrict
+ */
+
+/*!
+ \struct QShaderDescription::InOutVariable
\inmodule QtGui
+ \since 6.6
\brief Describes an input or output variable in the shader.
+
+ \note This is a RHI API with limited compatibility guarantees, see \l QShaderDescription
+ for details.
*/
/*!
- \class QShaderDescription::BlockVariable
- \internal
+ \variable QShaderDescription::InOutVariable::name
+ */
+
+/*!
+ \variable QShaderDescription::InOutVariable::type
+ */
+
+/*!
+ \variable QShaderDescription::InOutVariable::location
+ */
+
+/*!
+ \variable QShaderDescription::InOutVariable::binding
+ */
+
+/*!
+ \variable QShaderDescription::InOutVariable::descriptorSet
+ */
+
+/*!
+ \variable QShaderDescription::InOutVariable::imageFormat
+ */
+
+/*!
+ \variable QShaderDescription::InOutVariable::imageFlags
+ */
+
+/*!
+ \variable QShaderDescription::InOutVariable::arrayDims
+ */
+
+/*!
+ \variable QShaderDescription::InOutVariable::perPatch
+ */
+
+/*!
+ \variable QShaderDescription::InOutVariable::structMembers
+ */
+
+/*!
+ \struct QShaderDescription::BlockVariable
\inmodule QtGui
+ \since 6.6
\brief Describes a member of a uniform or push constant block.
+
+ \note This is a RHI API with limited compatibility guarantees, see \l QShaderDescription
+ for details.
*/
/*!
- \class QShaderDescription::UniformBlock
- \internal
+ \variable QShaderDescription::BlockVariable::name
+ */
+
+/*!
+ \variable QShaderDescription::BlockVariable::type
+ */
+
+/*!
+ \variable QShaderDescription::BlockVariable::offset
+ */
+
+/*!
+ \variable QShaderDescription::BlockVariable::size
+ */
+
+/*!
+ \variable QShaderDescription::BlockVariable::arrayDims
+ */
+
+/*!
+ \variable QShaderDescription::BlockVariable::arrayStride
+ */
+
+/*!
+ \variable QShaderDescription::BlockVariable::matrixStride
+ */
+
+/*!
+ \variable QShaderDescription::BlockVariable::matrixIsRowMajor
+ */
+
+/*!
+ \variable QShaderDescription::BlockVariable::structMembers
+ */
+
+/*!
+ \struct QShaderDescription::UniformBlock
\inmodule QtGui
+ \since 6.6
\brief Describes a uniform block.
@@ -264,22 +389,157 @@ QT_BEGIN_NAMESPACE
(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.
+
+ \note This is a RHI API with limited compatibility guarantees, see \l QShaderDescription
+ for details.
*/
/*!
- \class QShaderDescription::PushConstantBlock
- \internal
+ \variable QShaderDescription::UniformBlock::blockName
+ */
+
+/*!
+ \variable QShaderDescription::UniformBlock::structName
+ */
+
+/*!
+ \variable QShaderDescription::UniformBlock::size
+ */
+
+/*!
+ \variable QShaderDescription::UniformBlock::binding
+ */
+
+/*!
+ \variable QShaderDescription::UniformBlock::descriptorSet
+ */
+
+/*!
+ \variable QShaderDescription::UniformBlock::members
+ */
+
+/*!
+ \struct QShaderDescription::PushConstantBlock
\inmodule QtGui
+ \since 6.6
\brief Describes a push constant block.
+
+ \note This is a RHI API with limited compatibility guarantees, see \l QShaderDescription
+ for details.
*/
/*!
- \class QShaderDescription::StorageBlock
- \internal
+ \variable QShaderDescription::PushConstantBlock::name
+ */
+
+/*!
+ \variable QShaderDescription::PushConstantBlock::size
+ */
+
+/*!
+ \variable QShaderDescription::PushConstantBlock::members
+ */
+
+/*!
+ \struct QShaderDescription::StorageBlock
\inmodule QtGui
+ \since 6.6
\brief Describes a shader storage block.
+
+ \note This is a RHI API with limited compatibility guarantees, see \l QShaderDescription
+ for details.
+ */
+
+/*!
+ \variable QShaderDescription::StorageBlock::blockName
+ */
+
+/*!
+ \variable QShaderDescription::StorageBlock::instanceName
+ */
+
+/*!
+ \variable QShaderDescription::StorageBlock::knownSize
+ */
+
+/*!
+ \variable QShaderDescription::StorageBlock::binding
+ */
+
+/*!
+ \variable QShaderDescription::StorageBlock::descriptorSet
+ */
+
+/*!
+ \variable QShaderDescription::StorageBlock::members
+ */
+
+/*!
+ \variable QShaderDescription::StorageBlock::runtimeArrayStride
+ */
+
+/*!
+ \variable QShaderDescription::StorageBlock::qualifierFlags
+ */
+
+/*!
+ \struct QShaderDescription::BuiltinVariable
+ \inmodule QtGui
+ \since 6.6
+
+ \brief Describes a built-in variable.
+
+ \note This is a RHI API with limited compatibility guarantees, see \l QShaderDescription
+ for details.
+ */
+
+/*!
+ \variable QShaderDescription::BuiltinVariable::type
+ */
+
+/*!
+ \variable QShaderDescription::BuiltinVariable::varType
+ */
+
+/*!
+ \variable QShaderDescription::BuiltinVariable::arrayDims
+ */
+
+/*!
+ \enum QShaderDescription::BuiltinType
+ Built-in variable type.
+
+ \value PositionBuiltin
+ \value PointSizeBuiltin
+ \value ClipDistanceBuiltin
+ \value CullDistanceBuiltin
+ \value VertexIdBuiltin
+ \value InstanceIdBuiltin
+ \value PrimitiveIdBuiltin
+ \value InvocationIdBuiltin
+ \value LayerBuiltin
+ \value ViewportIndexBuiltin
+ \value TessLevelOuterBuiltin
+ \value TessLevelInnerBuiltin
+ \value TessCoordBuiltin
+ \value PatchVerticesBuiltin
+ \value FragCoordBuiltin
+ \value PointCoordBuiltin
+ \value FrontFacingBuiltin
+ \value SampleIdBuiltin
+ \value SamplePositionBuiltin
+ \value SampleMaskBuiltin
+ \value FragDepthBuiltin
+ \value NumWorkGroupsBuiltin
+ \value WorkgroupSizeBuiltin
+ \value WorkgroupIdBuiltin
+ \value LocalInvocationIdBuiltin
+ \value GlobalInvocationIdBuiltin
+ \value LocalInvocationIndexBuiltin
+ \value VertexIndexBuiltin
+ \value InstanceIndexBuiltin
*/
/*!
@@ -302,7 +562,7 @@ void QShaderDescription::detach()
}
/*!
- \internal
+ Constructs a copy of \a other.
*/
QShaderDescription::QShaderDescription(const QShaderDescription &other)
: d(other.d)
@@ -311,7 +571,7 @@ QShaderDescription::QShaderDescription(const QShaderDescription &other)
}
/*!
- \internal
+ Assigns \a other to this object.
*/
QShaderDescription &QShaderDescription::operator=(const QShaderDescription &other)
{
@@ -336,7 +596,9 @@ 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();
+ || !d->combinedImageSamplers.isEmpty() || !d->storageImages.isEmpty()
+ || !d->separateImages.isEmpty() || !d->separateSamplers.isEmpty()
+ || !d->inBuiltins.isEmpty() || !d->outBuiltins.isEmpty();
}
/*!
@@ -352,13 +614,14 @@ QByteArray QShaderDescription::toJson() const
}
/*!
- Serializes this QShaderDescription to \a stream.
+ Serializes this QShaderDescription to \a stream. \a version specifies
+ the qsb version.
\sa deserialize(), toJson()
*/
-void QShaderDescription::serialize(QDataStream *stream) const
+void QShaderDescription::serialize(QDataStream *stream, int version) const
{
- d->writeToStream(stream);
+ d->writeToStream(stream, version);
}
/*!
@@ -436,6 +699,7 @@ QList<QShaderDescription::PushConstantBlock> QShaderDescription::pushConstantBlo
"blockName": "StuffSsbo",
"instanceName": "buf",
"knownSize": 16,
+ "runtimeArrayStride": 16
"members": [
{
"name": "whatever",
@@ -473,7 +737,10 @@ QList<QShaderDescription::PushConstantBlock> QShaderDescription::pushConstantBlo
\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.
+ excludes the size of the last member since that will only be known at run time. The
+ stride in bytes between array items for a last member with undefined array size is
+ \c runtimeArrayStride. This value is determined according to the specified buffer
+ memory layout standard (std140, std430) rules.
\note SSBOs are not available with some graphics APIs, such as, OpenGL 2.x or
OpenGL ES older than 3.1.
@@ -510,6 +777,16 @@ QList<QShaderDescription::InOutVariable> QShaderDescription::combinedImageSample
return d->combinedImageSamplers;
}
+QList<QShaderDescription::InOutVariable> QShaderDescription::separateImages() const
+{
+ return d->separateImages;
+}
+
+QList<QShaderDescription::InOutVariable> QShaderDescription::separateSamplers() const
+{
+ return d->separateSamplers;
+}
+
/*!
\return the list of image variables.
@@ -538,7 +815,26 @@ QList<QShaderDescription::InOutVariable> QShaderDescription::storageImages() con
}
/*!
- Returns the local size of a compute shader.
+ \return the list of active builtins used as input. For example, a
+ tessellation evaluation shader reading the value of gl_TessCoord and
+ gl_Position will have TessCoordBuiltin and PositionBuiltin listed here.
+ */
+QVector<QShaderDescription::BuiltinVariable> QShaderDescription::inputBuiltinVariables() const
+{
+ return d->inBuiltins;
+}
+
+/*!
+ \return the list of active built-in variables used as input. For example, a
+ vertex shader will very often have PositionBuiltin as an output built-in.
+ */
+QVector<QShaderDescription::BuiltinVariable> QShaderDescription::outputBuiltinVariables() const
+{
+ return d->outBuiltins;
+}
+
+/*!
+ \return the local size of a compute shader.
For example, for a compute shader with the following declaration the
function returns { 256, 16, 1}.
@@ -552,146 +848,346 @@ std::array<uint, 3> QShaderDescription::computeShaderLocalSize() const
return d->localSize;
}
-static struct TypeTab {
- QString k;
+/*!
+ \return the number of output vertices.
+
+ For example, for a tessellation control shader with the following
+ declaration the function returns 3.
+
+ \badcode
+ layout(vertices = 3) out;
+ \endcode
+ */
+uint QShaderDescription::tessellationOutputVertexCount() const
+{
+ return d->tessOutVertCount;
+}
+
+/*!
+ \enum QShaderDescription::TessellationMode
+
+ \value UnknownTessellationMode
+ \value TrianglesTessellationMode
+ \value QuadTessellationMode
+ \value IsolineTessellationMode
+ */
+
+/*!
+ \return the tessellation execution mode for a tessellation control or
+ evaluation shader.
+
+ When not set, the returned value is UnknownTessellationMode.
+
+ For example, for a tessellation evaluation shader with the following
+ declaration the function returns TrianglesTessellationMode.
+
+ \badcode
+ layout(triangles) in;
+ \endcode
+ */
+QShaderDescription::TessellationMode QShaderDescription::tessellationMode() const
+{
+ return d->tessMode;
+}
+
+/*!
+ \enum QShaderDescription::TessellationWindingOrder
+
+ \value UnknownTessellationWindingOrder
+ \value CwTessellationWindingOrder
+ \value CcwTessellationWindingOrder
+ */
+
+/*!
+ \return the tessellation winding order for a tessellation control or
+ evaluation shader.
+
+ When not set, the returned value is UnknownTessellationWindingOrder.
+
+ For example, for a tessellation evaluation shader with the following
+ declaration the function returns CcwTessellationWindingOrder.
+
+ \badcode
+ layout(triangles, fractional_odd_spacing, ccw) in;
+ \endcode
+ */
+QShaderDescription::TessellationWindingOrder QShaderDescription::tessellationWindingOrder() const
+{
+ return d->tessWind;
+}
+
+/*!
+ \enum QShaderDescription::TessellationPartitioning
+
+ \value UnknownTessellationPartitioning
+ \value EqualTessellationPartitioning
+ \value FractionalEvenTessellationPartitioning
+ \value FractionalOddTessellationPartitioning
+ */
+
+/*!
+ \return the tessellation partitioning mode for a tessellation control or
+ evaluation shader.
+
+ When not set, the returned value is UnknownTessellationPartitioning.
+
+ For example, for a tessellation evaluation shader with the following
+ declaration the function returns FractionalOddTessellationPartitioning.
+
+ \badcode
+ layout(triangles, fractional_odd_spacing, ccw) in;
+ \endcode
+ */
+QShaderDescription::TessellationPartitioning QShaderDescription::tessellationPartitioning() const
+{
+ return d->tessPart;
+}
+
+static const struct TypeTab {
+ const char k[20];
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("samplerExternalOES"), QShaderDescription::SamplerExternalOES },
-
- { 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)
+ { "float", QShaderDescription::Float },
+ { "vec2", QShaderDescription::Vec2 },
+ { "vec3", QShaderDescription::Vec3 },
+ { "vec4", QShaderDescription::Vec4 },
+ { "mat2", QShaderDescription::Mat2 },
+ { "mat3", QShaderDescription::Mat3 },
+ { "mat4", QShaderDescription::Mat4 },
+
+ { "struct", QShaderDescription::Struct },
+
+ { "sampler1D", QShaderDescription::Sampler1D },
+ { "sampler2D", QShaderDescription::Sampler2D },
+ { "sampler2DMS", QShaderDescription::Sampler2DMS },
+ { "sampler3D", QShaderDescription::Sampler3D },
+ { "samplerCube", QShaderDescription::SamplerCube },
+ { "sampler1DArray", QShaderDescription::Sampler1DArray },
+ { "sampler2DArray", QShaderDescription::Sampler2DArray },
+ { "sampler2DMSArray", QShaderDescription::Sampler2DMSArray },
+ { "sampler3DArray", QShaderDescription::Sampler3DArray },
+ { "samplerCubeArray", QShaderDescription::SamplerCubeArray },
+ { "samplerRect", QShaderDescription::SamplerRect },
+ { "samplerBuffer", QShaderDescription::SamplerBuffer },
+ { "samplerExternalOES", QShaderDescription::SamplerExternalOES },
+ { "sampler", QShaderDescription::Sampler },
+
+ { "mat2x3", QShaderDescription::Mat2x3 },
+ { "mat2x4", QShaderDescription::Mat2x4 },
+ { "mat3x2", QShaderDescription::Mat3x2 },
+ { "mat3x4", QShaderDescription::Mat3x4 },
+ { "mat4x2", QShaderDescription::Mat4x2 },
+ { "mat4x3", QShaderDescription::Mat4x3 },
+
+ { "int", QShaderDescription::Int },
+ { "ivec2", QShaderDescription::Int2 },
+ { "ivec3", QShaderDescription::Int3 },
+ { "ivec4", QShaderDescription::Int4 },
+
+ { "uint", QShaderDescription::Uint },
+ { "uvec2", QShaderDescription::Uint2 },
+ { "uvec3", QShaderDescription::Uint3 },
+ { "uvec4", QShaderDescription::Uint4 },
+
+ { "bool", QShaderDescription::Bool },
+ { "bvec2", QShaderDescription::Bool2 },
+ { "bvec3", QShaderDescription::Bool3 },
+ { "bvec4", QShaderDescription::Bool4 },
+
+ { "double", QShaderDescription::Double },
+ { "dvec2", QShaderDescription::Double2 },
+ { "dvec3", QShaderDescription::Double3 },
+ { "dvec4", QShaderDescription::Double4 },
+ { "dmat2", QShaderDescription::DMat2 },
+ { "dmat3", QShaderDescription::DMat3 },
+ { "dmat4", QShaderDescription::DMat4 },
+ { "dmat2x3", QShaderDescription::DMat2x3 },
+ { "dmat2x4", QShaderDescription::DMat2x4 },
+ { "dmat3x2", QShaderDescription::DMat3x2 },
+ { "dmat3x4", QShaderDescription::DMat3x4 },
+ { "dmat4x2", QShaderDescription::DMat4x2 },
+ { "dmat4x3", QShaderDescription::DMat4x3 },
+
+ { "image1D", QShaderDescription::Image1D },
+ { "image2D", QShaderDescription::Image2D },
+ { "image2DMS", QShaderDescription::Image2DMS },
+ { "image3D", QShaderDescription::Image3D },
+ { "imageCube", QShaderDescription::ImageCube },
+ { "image1DArray", QShaderDescription::Image1DArray },
+ { "image2DArray", QShaderDescription::Image2DArray },
+ { "image2DMSArray", QShaderDescription::Image2DMSArray },
+ { "image3DArray", QShaderDescription::Image3DArray },
+ { "imageCubeArray", QShaderDescription::ImageCubeArray },
+ { "imageRect", QShaderDescription::ImageRect },
+ { "imageBuffer", QShaderDescription::ImageBuffer },
+
+ { "half", QShaderDescription::Half },
+ { "half2", QShaderDescription::Half2 },
+ { "half3", QShaderDescription::Half3 },
+ { "half4", QShaderDescription::Half4 } };
+
+static QLatin1StringView typeStr(QShaderDescription::VariableType t)
{
for (size_t i = 0; i < sizeof(typeTab) / sizeof(TypeTab); ++i) {
if (typeTab[i].v == t)
- return typeTab[i].k;
+ return QLatin1StringView(typeTab[i].k);
}
- return QString();
+ return {};
}
-static struct ImageFormatTab {
- QString k;
+static const struct ImageFormatTab {
+ const char k[15];
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 }
+ { "unknown", QShaderDescription::ImageFormatUnknown },
+ { "rgba32f", QShaderDescription::ImageFormatRgba32f },
+ { "rgba16", QShaderDescription::ImageFormatRgba16f },
+ { "r32f", QShaderDescription::ImageFormatR32f },
+ { "rgba8", QShaderDescription::ImageFormatRgba8 },
+ { "rgba8_snorm", QShaderDescription::ImageFormatRgba8Snorm },
+ { "rg32f", QShaderDescription::ImageFormatRg32f },
+ { "rg16f", QShaderDescription::ImageFormatRg16f },
+ { "r11f_g11f_b10f", QShaderDescription::ImageFormatR11fG11fB10f },
+ { "r16f", QShaderDescription::ImageFormatR16f },
+ { "rgba16", QShaderDescription::ImageFormatRgba16 },
+ { "rgb10_a2", QShaderDescription::ImageFormatRgb10A2 },
+ { "rg16", QShaderDescription::ImageFormatRg16 },
+ { "rg8", QShaderDescription::ImageFormatRg8 },
+ { "r16", QShaderDescription::ImageFormatR16 },
+ { "r8", QShaderDescription::ImageFormatR8 },
+ { "rgba16_snorm", QShaderDescription::ImageFormatRgba16Snorm },
+ { "rg16_snorm", QShaderDescription::ImageFormatRg16Snorm },
+ { "rg8_snorm", QShaderDescription::ImageFormatRg8Snorm },
+ { "r16_snorm", QShaderDescription::ImageFormatR16Snorm },
+ { "r8_snorm", QShaderDescription::ImageFormatR8Snorm },
+ { "rgba32i", QShaderDescription::ImageFormatRgba32i },
+ { "rgba16i", QShaderDescription::ImageFormatRgba16i },
+ { "rgba8i", QShaderDescription::ImageFormatRgba8i },
+ { "r32i", QShaderDescription::ImageFormatR32i },
+ { "rg32i", QShaderDescription::ImageFormatRg32i },
+ { "rg16i", QShaderDescription::ImageFormatRg16i },
+ { "rg8i", QShaderDescription::ImageFormatRg8i },
+ { "r16i", QShaderDescription::ImageFormatR16i },
+ { "r8i", QShaderDescription::ImageFormatR8i },
+ { "rgba32ui", QShaderDescription::ImageFormatRgba32ui },
+ { "rgba16ui", QShaderDescription::ImageFormatRgba16ui },
+ { "rgba8ui", QShaderDescription::ImageFormatRgba8ui },
+ { "r32ui", QShaderDescription::ImageFormatR32ui },
+ { "rgb10_a2ui", QShaderDescription::ImageFormatRgb10a2ui },
+ { "rg32ui", QShaderDescription::ImageFormatRg32ui },
+ { "rg16ui", QShaderDescription::ImageFormatRg16ui },
+ { "rg8ui", QShaderDescription::ImageFormatRg8ui },
+ { "r16ui", QShaderDescription::ImageFormatR16ui },
+ { "r8ui", QShaderDescription::ImageFormatR8ui }
};
-static QString imageFormatStr(const QShaderDescription::ImageFormat &f)
+static QLatin1StringView imageFormatStr(QShaderDescription::ImageFormat f)
{
for (size_t i = 0; i < sizeof(imageFormatTab) / sizeof(ImageFormatTab); ++i) {
if (imageFormatTab[i].v == f)
- return imageFormatTab[i].k;
+ return QLatin1StringView(imageFormatTab[i].k);
}
- return QString();
+ return {};
+}
+
+static const struct BuiltinTypeTab {
+ const char k[21];
+ QShaderDescription::BuiltinType v;
+} builtinTypeTab[] = {
+ { "Position", QShaderDescription::PositionBuiltin },
+ { "PointSize", QShaderDescription::PointSizeBuiltin },
+ { "ClipDistance", QShaderDescription::ClipDistanceBuiltin },
+ { "CullDistance", QShaderDescription::CullDistanceBuiltin },
+ { "VertexId", QShaderDescription::VertexIdBuiltin },
+ { "InstanceId", QShaderDescription::InstanceIdBuiltin },
+ { "PrimitiveId", QShaderDescription::PrimitiveIdBuiltin },
+ { "InvocationId", QShaderDescription::InvocationIdBuiltin },
+ { "Layer", QShaderDescription::LayerBuiltin },
+ { "ViewportIndex", QShaderDescription::ViewportIndexBuiltin },
+ { "TessLevelOuter", QShaderDescription::TessLevelOuterBuiltin },
+ { "TessLevelInner", QShaderDescription::TessLevelInnerBuiltin },
+ { "TessCoord", QShaderDescription::TessCoordBuiltin },
+ { "PatchVertices", QShaderDescription::PatchVerticesBuiltin },
+ { "FragCoord", QShaderDescription::FragCoordBuiltin },
+ { "PointCoord", QShaderDescription::PointCoordBuiltin },
+ { "FrontFacing", QShaderDescription::FrontFacingBuiltin },
+ { "SampleId", QShaderDescription::SampleIdBuiltin },
+ { "SamplePosition", QShaderDescription::SamplePositionBuiltin },
+ { "SampleMask", QShaderDescription::SampleMaskBuiltin },
+ { "FragDepth", QShaderDescription::FragDepthBuiltin },
+ { "NumWorkGroups", QShaderDescription::NumWorkGroupsBuiltin },
+ { "WorkgroupSize", QShaderDescription::WorkgroupSizeBuiltin },
+ { "WorkgroupId", QShaderDescription::WorkgroupIdBuiltin },
+ { "LocalInvocationId", QShaderDescription::LocalInvocationIdBuiltin },
+ { "GlobalInvocationId", QShaderDescription::GlobalInvocationIdBuiltin },
+ { "LocalInvocationIndex", QShaderDescription::LocalInvocationIndexBuiltin },
+ { "VertexIndex", QShaderDescription::VertexIndexBuiltin },
+ { "InstanceIndex", QShaderDescription::InstanceIndexBuiltin }
+};
+
+static QLatin1StringView builtinTypeStr(QShaderDescription::BuiltinType t)
+{
+ for (size_t i = 0; i < sizeof(builtinTypeTab) / sizeof(BuiltinTypeTab); ++i) {
+ if (builtinTypeTab[i].v == t)
+ return QLatin1StringView(builtinTypeTab[i].k);
+ }
+ return {};
+}
+
+static const struct TessellationModeTab {
+ const char k[10];
+ QShaderDescription::TessellationMode v;
+} tessellationModeTab[] {
+ { "unknown", QShaderDescription::UnknownTessellationMode },
+ { "triangles", QShaderDescription::TrianglesTessellationMode },
+ { "quad", QShaderDescription::QuadTessellationMode },
+ { "isoline", QShaderDescription::IsolineTessellationMode }
+};
+
+static QLatin1StringView tessModeStr(QShaderDescription::TessellationMode mode)
+{
+ for (size_t i = 0; i < sizeof(tessellationModeTab) / sizeof(TessellationModeTab); ++i) {
+ if (tessellationModeTab[i].v == mode)
+ return QLatin1StringView(tessellationModeTab[i].k);
+ }
+ return {};
+}
+
+static const struct TessellationWindingOrderTab {
+ const char k[8];
+ QShaderDescription::TessellationWindingOrder v;
+} tessellationWindingOrderTab[] {
+ { "unknown", QShaderDescription::UnknownTessellationWindingOrder },
+ { "cw", QShaderDescription::CwTessellationWindingOrder },
+ { "ccw", QShaderDescription::CcwTessellationWindingOrder }
+};
+
+static QLatin1StringView tessWindStr(QShaderDescription::TessellationWindingOrder w)
+{
+ for (size_t i = 0; i < sizeof(tessellationWindingOrderTab) / sizeof(TessellationWindingOrderTab); ++i) {
+ if (tessellationWindingOrderTab[i].v == w)
+ return QLatin1StringView(tessellationWindingOrderTab[i].k);
+ }
+ return {};
+}
+
+static const struct TessellationPartitioningTab {
+ const char k[24];
+ QShaderDescription::TessellationPartitioning v;
+} tessellationPartitioningTab[] {
+ { "unknown", QShaderDescription::UnknownTessellationPartitioning },
+ { "equal_spacing", QShaderDescription::EqualTessellationPartitioning },
+ { "fractional_even_spacing", QShaderDescription::FractionalEvenTessellationPartitioning },
+ { "fractional_odd_spacing", QShaderDescription::FractionalOddTessellationPartitioning }
+};
+
+static QLatin1StringView tessPartStr(QShaderDescription::TessellationPartitioning p)
+{
+ for (size_t i = 0; i < sizeof(tessellationPartitioningTab) / sizeof(TessellationPartitioningTab); ++i) {
+ if (tessellationPartitioningTab[i].v == p)
+ return QLatin1StringView(tessellationPartitioningTab[i].k);
+ }
+ return {};
}
#ifndef QT_NO_DEBUG_STREAM
@@ -708,7 +1204,11 @@ QDebug operator<<(QDebug dbg, const QShaderDescription &sd)
<< " pcBlocks " << d->pushConstantBlocks
<< " storageBlocks " << d->storageBlocks
<< " combinedSamplers " << d->combinedImageSamplers
- << " images " << d->storageImages
+ << " storageImages " << d->storageImages
+ << " separateImages " << d->separateImages
+ << " separateSamplers " << d->separateSamplers
+ << " inBuiltins " << d->inBuiltins
+ << " outBuiltins " << d->outBuiltins
<< ')';
} else {
dbg.nospace() << "QShaderDescription(null)";
@@ -721,6 +1221,8 @@ QDebug operator<<(QDebug dbg, const QShaderDescription::InOutVariable &var)
{
QDebugStateSaver saver(dbg);
dbg.nospace() << "InOutVariable(" << typeStr(var.type) << ' ' << var.name;
+ if (var.perPatch)
+ dbg.nospace() << " per-patch";
if (var.location >= 0)
dbg.nospace() << " location=" << var.location;
if (var.binding >= 0)
@@ -733,6 +1235,8 @@ QDebug operator<<(QDebug dbg, const QShaderDescription::InOutVariable &var)
dbg.nospace() << " imageFlags=" << var.imageFlags;
if (!var.arrayDims.isEmpty())
dbg.nospace() << " array=" << var.arrayDims;
+ if (!var.structMembers.isEmpty())
+ dbg.nospace() << " structMembers=" << var.structMembers;
dbg.nospace() << ')';
return dbg;
}
@@ -740,8 +1244,10 @@ QDebug operator<<(QDebug dbg, const QShaderDescription::InOutVariable &var)
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;
+ dbg.nospace() << "BlockVariable(" << typeStr(var.type) << ' ' << var.name;
+ if (var.offset != -1)
+ dbg.nospace() << " offset=" << var.offset;
+ dbg.nospace() << " size=" << var.size;
if (!var.arrayDims.isEmpty())
dbg.nospace() << " array=" << var.arrayDims;
if (var.arrayStride)
@@ -786,111 +1292,169 @@ QDebug operator<<(QDebug dbg, const QShaderDescription::StorageBlock &blk)
dbg.nospace() << " binding=" << blk.binding;
if (blk.descriptorSet >= 0)
dbg.nospace() << " set=" << blk.descriptorSet;
+ if (blk.runtimeArrayStride)
+ dbg.nospace() << " runtimeArrayStride=" << blk.runtimeArrayStride;
+ if (blk.qualifierFlags)
+ dbg.nospace() << " qualifierFlags=" << blk.qualifierFlags;
dbg.nospace() << ' ' << blk.members << ')';
return dbg;
}
+
+QDebug operator<<(QDebug dbg, const QShaderDescription::BuiltinVariable &builtin)
+{
+ QDebugStateSaver saver(dbg);
+ dbg.nospace() << "BuiltinVariable(type=" << builtinTypeStr(builtin.type);
+ dbg.nospace() << " varType=" << typeStr(builtin.varType);
+ if (!builtin.arrayDims.isEmpty())
+ dbg.nospace() << " array=" << builtin.arrayDims;
+ dbg.nospace() << ")";
+ 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");
+#define JSON_KEY(key) static constexpr QLatin1StringView key ## Key() noexcept { return QLatin1StringView( #key ); }
+JSON_KEY(name)
+JSON_KEY(type)
+JSON_KEY(location)
+JSON_KEY(binding)
+JSON_KEY(set)
+JSON_KEY(perPatch)
+JSON_KEY(imageFormat)
+JSON_KEY(imageFlags)
+JSON_KEY(offset)
+JSON_KEY(arrayDims)
+JSON_KEY(arrayStride)
+JSON_KEY(matrixStride)
+JSON_KEY(matrixRowMajor)
+JSON_KEY(structMembers)
+JSON_KEY(members)
+JSON_KEY(inputs)
+JSON_KEY(outputs)
+JSON_KEY(uniformBlocks)
+JSON_KEY(blockName)
+JSON_KEY(structName)
+JSON_KEY(instanceName)
+JSON_KEY(size)
+JSON_KEY(knownSize)
+JSON_KEY(pushConstantBlocks)
+JSON_KEY(storageBlocks)
+JSON_KEY(combinedImageSamplers)
+JSON_KEY(storageImages)
+JSON_KEY(inBuiltins)
+JSON_KEY(outBuiltins)
+JSON_KEY(computeLocalSize)
+JSON_KEY(tessellationOutputVertexCount)
+JSON_KEY(tessellationMode)
+JSON_KEY(tessellationWindingOrder)
+JSON_KEY(tessellationPartitioning)
+JSON_KEY(separateImages)
+JSON_KEY(separateSamplers)
+JSON_KEY(runtimeArrayStride)
+JSON_KEY(qualifierFlags)
+#undef JSON_KEY
static void addDeco(QJsonObject *obj, const QShaderDescription::InOutVariable &v)
{
if (v.location >= 0)
- (*obj)[locationKey] = v.location;
+ (*obj)[locationKey()] = v.location;
if (v.binding >= 0)
- (*obj)[bindingKey] = v.binding;
+ (*obj)[bindingKey()] = v.binding;
if (v.descriptorSet >= 0)
- (*obj)[setKey] = v.descriptorSet;
+ (*obj)[setKey()] = v.descriptorSet;
+ if (v.perPatch)
+ (*obj)[perPatchKey()] = v.perPatch;
if (v.imageFormat != QShaderDescription::ImageFormatUnknown)
- (*obj)[imageFormatKey] = imageFormatStr(v.imageFormat);
+ (*obj)[imageFormatKey()] = imageFormatStr(v.imageFormat);
if (v.imageFlags)
- (*obj)[imageFlagsKey] = int(v.imageFlags);
+ (*obj)[imageFlagsKey()] = int(v.imageFlags);
if (!v.arrayDims.isEmpty()) {
QJsonArray dimArr;
for (int dim : v.arrayDims)
dimArr.append(dim);
- (*obj)[arrayDimsKey] = dimArr;
+ (*obj)[arrayDimsKey()] = dimArr;
}
}
-static void serializeDecorations(QDataStream *stream, const QShaderDescription::InOutVariable &v)
+static void serializeDecorations(QDataStream *stream, const QShaderDescription::InOutVariable &v, int version)
{
(*stream) << v.location;
(*stream) << v.binding;
(*stream) << v.descriptorSet;
(*stream) << int(v.imageFormat);
(*stream) << int(v.imageFlags);
- (*stream) << int(v.arrayDims.count());
+ (*stream) << int(v.arrayDims.size());
for (int dim : v.arrayDims)
(*stream) << dim;
+ if (version > QShaderPrivate::QSB_VERSION_WITHOUT_NATIVE_SHADER_INFO)
+ (*stream) << quint8(v.perPatch);
}
-static QJsonObject inOutObject(const QShaderDescription::InOutVariable &v)
+static void serializeBuiltinVar(QDataStream *stream, const QShaderDescription::BuiltinVariable &v, int version)
{
- QJsonObject obj;
- obj[nameKey] = QString::fromUtf8(v.name);
- obj[typeKey] = typeStr(v.type);
- addDeco(&obj, v);
- return obj;
-}
-
-static void serializeInOutVar(QDataStream *stream, const QShaderDescription::InOutVariable &v)
-{
- (*stream) << QString::fromUtf8(v.name);
(*stream) << int(v.type);
- serializeDecorations(stream, v);
+ if (version > QShaderPrivate::QSB_VERSION_WITHOUT_INPUT_OUTPUT_INTERFACE_BLOCKS) {
+ (*stream) << int(v.varType);
+ (*stream) << int(v.arrayDims.size());
+ for (int dim : v.arrayDims)
+ (*stream) << dim;
+ }
}
static QJsonObject blockMemberObject(const QShaderDescription::BlockVariable &v)
{
QJsonObject obj;
- obj[nameKey] = QString::fromUtf8(v.name);
- obj[typeKey] = typeStr(v.type);
- obj[offsetKey] = v.offset;
- obj[sizeKey] = v.size;
+ obj[nameKey()] = QString::fromUtf8(v.name);
+ obj[typeKey()] = typeStr(v.type);
+ if (v.offset != -1)
+ 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;
+ obj[arrayDimsKey()] = dimArr;
}
if (v.arrayStride)
- obj[arrayStrideKey] = v.arrayStride;
+ obj[arrayStrideKey()] = v.arrayStride;
if (v.matrixStride)
- obj[matrixStrideKey] = v.matrixStride;
+ obj[matrixStrideKey()] = v.matrixStride;
if (v.matrixIsRowMajor)
- obj[matrixRowMajorKey] = true;
+ 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 QJsonObject inOutObject(const QShaderDescription::InOutVariable &v)
+{
+ QJsonObject obj;
+ obj[nameKey()] = QString::fromUtf8(v.name);
+ obj[typeKey()] = typeStr(v.type);
+ addDeco(&obj, v);
if (!v.structMembers.isEmpty()) {
QJsonArray arr;
for (const QShaderDescription::BlockVariable &sv : v.structMembers)
arr.append(blockMemberObject(sv));
- obj[structMembersKey] = arr;
+ obj[structMembersKey()] = arr;
+ }
+ return obj;
+}
+
+static QJsonObject builtinObject(const QShaderDescription::BuiltinVariable &v)
+{
+ QJsonObject obj;
+
+ obj[nameKey()] = builtinTypeStr(v.type);
+ obj[typeKey()] = typeStr(v.varType);
+ if (!v.arrayDims.isEmpty()) {
+ QJsonArray dimArr;
+ for (int dim : v.arrayDims)
+ dimArr.append(dim);
+ obj[arrayDimsKey()] = dimArr;
}
return obj;
}
@@ -901,174 +1465,272 @@ static void serializeBlockMemberVar(QDataStream *stream, const QShaderDescriptio
(*stream) << int(v.type);
(*stream) << v.offset;
(*stream) << v.size;
- (*stream) << int(v.arrayDims.count());
+ (*stream) << int(v.arrayDims.size());
for (int dim : v.arrayDims)
(*stream) << dim;
(*stream) << v.arrayStride;
(*stream) << v.matrixStride;
(*stream) << v.matrixIsRowMajor;
- (*stream) << int(v.structMembers.count());
+ (*stream) << int(v.structMembers.size());
for (const QShaderDescription::BlockVariable &sv : v.structMembers)
serializeBlockMemberVar(stream, sv);
}
+static void serializeInOutVar(QDataStream *stream, const QShaderDescription::InOutVariable &v,
+ int version)
+{
+ (*stream) << QString::fromUtf8(v.name);
+ (*stream) << int(v.type);
+ serializeDecorations(stream, v, version);
+ if (version > QShaderPrivate::QSB_VERSION_WITHOUT_INPUT_OUTPUT_INTERFACE_BLOCKS) {
+ (*stream) << int(v.structMembers.size());
+ for (const QShaderDescription::BlockVariable &sv : v.structMembers)
+ serializeBlockMemberVar(stream, sv);
+ }
+}
+
QJsonDocument QShaderDescriptionPrivate::makeDoc()
{
QJsonObject root;
QJsonArray jinputs;
- for (const QShaderDescription::InOutVariable &v : qAsConst(inVars))
+ for (const QShaderDescription::InOutVariable &v : std::as_const(inVars))
jinputs.append(inOutObject(v));
if (!jinputs.isEmpty())
- root[inputsKey] = jinputs;
+ root[inputsKey()] = jinputs;
QJsonArray joutputs;
- for (const QShaderDescription::InOutVariable &v : qAsConst(outVars))
+ for (const QShaderDescription::InOutVariable &v : std::as_const(outVars))
joutputs.append(inOutObject(v));
if (!joutputs.isEmpty())
- root[outputsKey] = joutputs;
+ root[outputsKey()] = joutputs;
QJsonArray juniformBlocks;
for (const QShaderDescription::UniformBlock &b : uniformBlocks) {
QJsonObject juniformBlock;
- juniformBlock[blockNameKey] = QString::fromUtf8(b.blockName);
- juniformBlock[structNameKey] = QString::fromUtf8(b.structName);
- juniformBlock[sizeKey] = b.size;
+ juniformBlock[blockNameKey()] = QString::fromUtf8(b.blockName);
+ juniformBlock[structNameKey()] = QString::fromUtf8(b.structName);
+ juniformBlock[sizeKey()] = b.size;
if (b.binding >= 0)
- juniformBlock[bindingKey] = b.binding;
+ juniformBlock[bindingKey()] = b.binding;
if (b.descriptorSet >= 0)
- juniformBlock[setKey] = b.descriptorSet;
+ juniformBlock[setKey()] = b.descriptorSet;
QJsonArray members;
for (const QShaderDescription::BlockVariable &v : b.members)
members.append(blockMemberObject(v));
- juniformBlock[membersKey] = members;
+ juniformBlock[membersKey()] = members;
juniformBlocks.append(juniformBlock);
}
if (!juniformBlocks.isEmpty())
- root[uniformBlocksKey] = juniformBlocks;
+ root[uniformBlocksKey()] = juniformBlocks;
QJsonArray jpushConstantBlocks;
for (const QShaderDescription::PushConstantBlock &b : pushConstantBlocks) {
QJsonObject jpushConstantBlock;
- jpushConstantBlock[nameKey] = QString::fromUtf8(b.name);
- jpushConstantBlock[sizeKey] = b.size;
+ jpushConstantBlock[nameKey()] = QString::fromUtf8(b.name);
+ jpushConstantBlock[sizeKey()] = b.size;
QJsonArray members;
for (const QShaderDescription::BlockVariable &v : b.members)
members.append(blockMemberObject(v));
- jpushConstantBlock[membersKey] = members;
+ jpushConstantBlock[membersKey()] = members;
jpushConstantBlocks.append(jpushConstantBlock);
}
if (!jpushConstantBlocks.isEmpty())
- root[pushConstantBlocksKey] = jpushConstantBlocks;
+ root[pushConstantBlocksKey()] = jpushConstantBlocks;
QJsonArray jstorageBlocks;
for (const QShaderDescription::StorageBlock &b : storageBlocks) {
QJsonObject jstorageBlock;
- jstorageBlock[blockNameKey] = QString::fromUtf8(b.blockName);
- jstorageBlock[instanceNameKey] = QString::fromUtf8(b.instanceName);
- jstorageBlock[knownSizeKey] = b.knownSize;
+ jstorageBlock[blockNameKey()] = QString::fromUtf8(b.blockName);
+ jstorageBlock[instanceNameKey()] = QString::fromUtf8(b.instanceName);
+ jstorageBlock[knownSizeKey()] = b.knownSize;
if (b.binding >= 0)
- jstorageBlock[bindingKey] = b.binding;
+ jstorageBlock[bindingKey()] = b.binding;
if (b.descriptorSet >= 0)
- jstorageBlock[setKey] = b.descriptorSet;
+ jstorageBlock[setKey()] = b.descriptorSet;
+ if (b.runtimeArrayStride)
+ jstorageBlock[runtimeArrayStrideKey()] = b.runtimeArrayStride;
+ if (b.qualifierFlags)
+ jstorageBlock[qualifierFlagsKey()] = int(b.qualifierFlags);
QJsonArray members;
for (const QShaderDescription::BlockVariable &v : b.members)
members.append(blockMemberObject(v));
- jstorageBlock[membersKey] = members;
+ jstorageBlock[membersKey()] = members;
jstorageBlocks.append(jstorageBlock);
}
if (!jstorageBlocks.isEmpty())
- root[storageBlocksKey] = jstorageBlocks;
+ root[storageBlocksKey()] = jstorageBlocks;
QJsonArray jcombinedSamplers;
- for (const QShaderDescription::InOutVariable &v : qAsConst(combinedImageSamplers)) {
+ for (const QShaderDescription::InOutVariable &v : std::as_const(combinedImageSamplers)) {
QJsonObject sampler;
- sampler[nameKey] = QString::fromUtf8(v.name);
- sampler[typeKey] = typeStr(v.type);
+ sampler[nameKey()] = QString::fromUtf8(v.name);
+ sampler[typeKey()] = typeStr(v.type);
addDeco(&sampler, v);
jcombinedSamplers.append(sampler);
}
if (!jcombinedSamplers.isEmpty())
- root[combinedImageSamplersKey] = jcombinedSamplers;
+ root[combinedImageSamplersKey()] = jcombinedSamplers;
QJsonArray jstorageImages;
- for (const QShaderDescription::InOutVariable &v : qAsConst(storageImages)) {
+ for (const QShaderDescription::InOutVariable &v : std::as_const(storageImages)) {
QJsonObject image;
- image[nameKey] = QString::fromUtf8(v.name);
- image[typeKey] = typeStr(v.type);
+ image[nameKey()] = QString::fromUtf8(v.name);
+ image[typeKey()] = typeStr(v.type);
addDeco(&image, v);
jstorageImages.append(image);
}
if (!jstorageImages.isEmpty())
- root[storageImagesKey] = jstorageImages;
+ root[storageImagesKey()] = jstorageImages;
+
+ QJsonArray jinBuiltins;
+ for (const QShaderDescription::BuiltinVariable &v : std::as_const(inBuiltins))
+ jinBuiltins.append(builtinObject(v));
+ if (!jinBuiltins.isEmpty())
+ root[inBuiltinsKey()] = jinBuiltins;
+
+ QJsonArray joutBuiltins;
+ for (const QShaderDescription::BuiltinVariable &v : std::as_const(outBuiltins))
+ joutBuiltins.append(builtinObject(v));
+ if (!joutBuiltins.isEmpty())
+ root[outBuiltinsKey()] = joutBuiltins;
+
+ if (localSize[0] || localSize[1] || localSize[2]) {
+ QJsonArray jlocalSize;
+ for (size_t i = 0; i < 3; ++i)
+ jlocalSize.append(QJsonValue(int(localSize[i])));
+ root[computeLocalSizeKey()] = jlocalSize;
+ }
+
+ if (tessOutVertCount)
+ root[tessellationOutputVertexCountKey()] = int(tessOutVertCount);
+
+ if (tessMode != QShaderDescription::UnknownTessellationMode)
+ root[tessellationModeKey()] = tessModeStr(tessMode);
+
+ if (tessWind != QShaderDescription::UnknownTessellationWindingOrder)
+ root[tessellationWindingOrderKey()] = tessWindStr(tessWind);
- QJsonArray jlocalSize;
- for (int i = 0; i < 3; ++i)
- jlocalSize.append(QJsonValue(int(localSize[i])));
- root[localSizeKey] = jlocalSize;
+ if (tessPart != QShaderDescription::UnknownTessellationPartitioning)
+ root[tessellationPartitioningKey()] = tessPartStr(tessPart);
+
+ QJsonArray jseparateImages;
+ for (const QShaderDescription::InOutVariable &v : std::as_const(separateImages)) {
+ QJsonObject image;
+ image[nameKey()] = QString::fromUtf8(v.name);
+ image[typeKey()] = typeStr(v.type);
+ addDeco(&image, v);
+ jseparateImages.append(image);
+ }
+ if (!jseparateImages.isEmpty())
+ root[separateImagesKey()] = jseparateImages;
+
+ QJsonArray jseparateSamplers;
+ for (const QShaderDescription::InOutVariable &v : std::as_const(separateSamplers)) {
+ QJsonObject sampler;
+ sampler[nameKey()] = QString::fromUtf8(v.name);
+ sampler[typeKey()] = typeStr(v.type);
+ addDeco(&sampler, v);
+ jseparateSamplers.append(sampler);
+ }
+ if (!jseparateSamplers.isEmpty())
+ root[separateSamplersKey()] = jseparateSamplers;
return QJsonDocument(root);
}
-void QShaderDescriptionPrivate::writeToStream(QDataStream *stream)
+void QShaderDescriptionPrivate::writeToStream(QDataStream *stream, int version)
{
- (*stream) << int(inVars.count());
- for (const QShaderDescription::InOutVariable &v : qAsConst(inVars))
- serializeInOutVar(stream, v);
+ (*stream) << int(inVars.size());
+ for (const QShaderDescription::InOutVariable &v : std::as_const(inVars))
+ serializeInOutVar(stream, v, version);
- (*stream) << int(outVars.count());
- for (const QShaderDescription::InOutVariable &v : qAsConst(outVars))
- serializeInOutVar(stream, v);
+ (*stream) << int(outVars.size());
+ for (const QShaderDescription::InOutVariable &v : std::as_const(outVars))
+ serializeInOutVar(stream, v, version);
- (*stream) << int(uniformBlocks.count());
+ (*stream) << int(uniformBlocks.size());
for (const QShaderDescription::UniformBlock &b : uniformBlocks) {
(*stream) << QString::fromUtf8(b.blockName);
(*stream) << QString::fromUtf8(b.structName);
(*stream) << b.size;
(*stream) << b.binding;
(*stream) << b.descriptorSet;
- (*stream) << int(b.members.count());
+ (*stream) << int(b.members.size());
for (const QShaderDescription::BlockVariable &v : b.members)
serializeBlockMemberVar(stream, v);
}
- (*stream) << int(pushConstantBlocks.count());
+ (*stream) << int(pushConstantBlocks.size());
for (const QShaderDescription::PushConstantBlock &b : pushConstantBlocks) {
(*stream) << QString::fromUtf8(b.name);
(*stream) << b.size;
- (*stream) << int(b.members.count());
+ (*stream) << int(b.members.size());
for (const QShaderDescription::BlockVariable &v : b.members)
serializeBlockMemberVar(stream, v);
}
- (*stream) << int(storageBlocks.count());
+ (*stream) << int(storageBlocks.size());
for (const QShaderDescription::StorageBlock &b : storageBlocks) {
(*stream) << QString::fromUtf8(b.blockName);
(*stream) << QString::fromUtf8(b.instanceName);
(*stream) << b.knownSize;
(*stream) << b.binding;
(*stream) << b.descriptorSet;
- (*stream) << int(b.members.count());
+ (*stream) << int(b.members.size());
for (const QShaderDescription::BlockVariable &v : b.members)
serializeBlockMemberVar(stream, v);
+ if (version > QShaderPrivate::QSB_VERSION_WITHOUT_EXTENDED_STORAGE_BUFFER_INFO) {
+ (*stream) << b.runtimeArrayStride;
+ (*stream) << b.qualifierFlags;
+ }
}
- (*stream) << int(combinedImageSamplers.count());
- for (const QShaderDescription::InOutVariable &v : qAsConst(combinedImageSamplers)) {
+ (*stream) << int(combinedImageSamplers.size());
+ for (const QShaderDescription::InOutVariable &v : std::as_const(combinedImageSamplers)) {
(*stream) << QString::fromUtf8(v.name);
(*stream) << int(v.type);
- serializeDecorations(stream, v);
+ serializeDecorations(stream, v, version);
}
- (*stream) << int(storageImages.count());
- for (const QShaderDescription::InOutVariable &v : qAsConst(storageImages)) {
+ (*stream) << int(storageImages.size());
+ for (const QShaderDescription::InOutVariable &v : std::as_const(storageImages)) {
(*stream) << QString::fromUtf8(v.name);
(*stream) << int(v.type);
- serializeDecorations(stream, v);
+ serializeDecorations(stream, v, version);
}
for (size_t i = 0; i < 3; ++i)
- (*stream) << localSize[i];
+ (*stream) << quint32(localSize[i]);
+
+ (*stream) << int(separateImages.size());
+ for (const QShaderDescription::InOutVariable &v : std::as_const(separateImages)) {
+ (*stream) << QString::fromUtf8(v.name);
+ (*stream) << int(v.type);
+ serializeDecorations(stream, v, version);
+ }
+
+ (*stream) << int(separateSamplers.size());
+ for (const QShaderDescription::InOutVariable &v : std::as_const(separateSamplers)) {
+ (*stream) << QString::fromUtf8(v.name);
+ (*stream) << int(v.type);
+ serializeDecorations(stream, v, version);
+ }
+
+ if (version > QShaderPrivate::QSB_VERSION_WITHOUT_NATIVE_SHADER_INFO) {
+ (*stream) << quint32(tessOutVertCount);
+ (*stream) << quint32(tessMode);
+ (*stream) << quint32(tessWind);
+ (*stream) << quint32(tessPart);
+
+ (*stream) << int(inBuiltins.size());
+ for (const QShaderDescription::BuiltinVariable &v : std::as_const(inBuiltins))
+ serializeBuiltinVar(stream, v, version);
+
+ (*stream) << int(outBuiltins.size());
+ for (const QShaderDescription::BuiltinVariable &v : std::as_const(outBuiltins))
+ serializeBuiltinVar(stream, v, version);
+ }
}
static void deserializeDecorations(QDataStream *stream, int version, QShaderDescription::InOutVariable *v)
@@ -1088,18 +1750,29 @@ static void deserializeDecorations(QDataStream *stream, int version, QShaderDesc
for (int i = 0; i < f; ++i)
(*stream) >> v->arrayDims[i];
}
+
+ if (version > QShaderPrivate::QSB_VERSION_WITHOUT_NATIVE_SHADER_INFO) {
+ quint8 b;
+ (*stream) >> b;
+ v->perPatch = b;
+ }
}
-static QShaderDescription::InOutVariable deserializeInOutVar(QDataStream *stream, int version)
+static QShaderDescription::BuiltinVariable deserializeBuiltinVar(QDataStream *stream, int version)
{
- QShaderDescription::InOutVariable var;
- QString tmp;
- (*stream) >> tmp;
- var.name = tmp.toUtf8();
+ QShaderDescription::BuiltinVariable var;
int t;
(*stream) >> t;
- var.type = QShaderDescription::VariableType(t);
- deserializeDecorations(stream, version, &var);
+ var.type = QShaderDescription::BuiltinType(t);
+ if (version > QShaderPrivate::QSB_VERSION_WITHOUT_INPUT_OUTPUT_INTERFACE_BLOCKS) {
+ (*stream) >> t;
+ var.varType = QShaderDescription::VariableType(t);
+ int count;
+ (*stream) >> count;
+ var.arrayDims.resize(count);
+ for (int i = 0; i < count; ++i)
+ (*stream) >> var.arrayDims[i];
+ }
return var;
}
@@ -1129,6 +1802,26 @@ static QShaderDescription::BlockVariable deserializeBlockMemberVar(QDataStream *
return var;
}
+static QShaderDescription::InOutVariable deserializeInOutVar(QDataStream *stream, int version)
+{
+ QShaderDescription::InOutVariable var;
+ QString tmp;
+ (*stream) >> tmp;
+ var.name = tmp.toUtf8();
+ int t;
+ (*stream) >> t;
+ var.type = QShaderDescription::VariableType(t);
+ deserializeDecorations(stream, version, &var);
+ if (version > QShaderPrivate::QSB_VERSION_WITHOUT_INPUT_OUTPUT_INTERFACE_BLOCKS) {
+ int count;
+ (*stream) >> count;
+ var.structMembers.resize(count);
+ for (int i = 0; i < count; ++i)
+ var.structMembers[i] = deserializeBlockMemberVar(stream, version);
+ }
+ return var;
+}
+
void QShaderDescriptionPrivate::loadFromStream(QDataStream *stream, int version)
{
Q_ASSERT(ref.loadRelaxed() == 1); // must be detached
@@ -1192,6 +1885,11 @@ void QShaderDescriptionPrivate::loadFromStream(QDataStream *stream, int version)
storageBlocks[i].members.resize(memberCount);
for (int memberIdx = 0; memberIdx < memberCount; ++memberIdx)
storageBlocks[i].members[memberIdx] = deserializeBlockMemberVar(stream, version);
+
+ if (version > QShaderPrivate::QSB_VERSION_WITHOUT_EXTENDED_STORAGE_BUFFER_INFO) {
+ (*stream) >> storageBlocks[i].runtimeArrayStride;
+ (*stream) >> storageBlocks[i].qualifierFlags;
+ }
}
(*stream) >> count;
@@ -1218,8 +1916,59 @@ void QShaderDescriptionPrivate::loadFromStream(QDataStream *stream, int version)
deserializeDecorations(stream, version, &storageImages[i]);
}
- for (size_t i = 0; i < 3; ++i)
- (*stream) >> localSize[i];
+ for (size_t i = 0; i < 3; ++i) {
+ quint32 v;
+ (*stream) >> v;
+ localSize[i] = v;
+ }
+
+ if (version > QShaderPrivate::QSB_VERSION_WITHOUT_SEPARATE_IMAGES_AND_SAMPLERS) {
+ (*stream) >> count;
+ separateImages.resize(count);
+ for (int i = 0; i < count; ++i) {
+ QString tmp;
+ (*stream) >> tmp;
+ separateImages[i].name = tmp.toUtf8();
+ int t;
+ (*stream) >> t;
+ separateImages[i].type = QShaderDescription::VariableType(t);
+ deserializeDecorations(stream, version, &separateImages[i]);
+ }
+
+ (*stream) >> count;
+ separateSamplers.resize(count);
+ for (int i = 0; i < count; ++i) {
+ QString tmp;
+ (*stream) >> tmp;
+ separateSamplers[i].name = tmp.toUtf8();
+ int t;
+ (*stream) >> t;
+ separateSamplers[i].type = QShaderDescription::VariableType(t);
+ deserializeDecorations(stream, version, &separateSamplers[i]);
+ }
+ }
+
+ if (version > QShaderPrivate::QSB_VERSION_WITHOUT_NATIVE_SHADER_INFO) {
+ quint32 v;
+ (*stream) >> v;
+ tessOutVertCount = v;
+ (*stream) >> v;
+ tessMode = QShaderDescription::TessellationMode(v);
+ (*stream) >> v;
+ tessWind = QShaderDescription::TessellationWindingOrder(v);
+ (*stream) >> v;
+ tessPart = QShaderDescription::TessellationPartitioning(v);
+
+ (*stream) >> count;
+ inBuiltins.resize(count);
+ for (int i = 0; i < count; ++i)
+ inBuiltins[i] = deserializeBuiltinVar(stream, version);
+
+ (*stream) >> count;
+ outBuiltins.resize(count);
+ for (int i = 0; i < count; ++i)
+ outBuiltins[i] = deserializeBuiltinVar(stream, version);
+ }
}
/*!
@@ -1239,8 +1988,16 @@ bool operator==(const QShaderDescription &lhs, const QShaderDescription &rhs) no
&& lhs.d->pushConstantBlocks == rhs.d->pushConstantBlocks
&& lhs.d->storageBlocks == rhs.d->storageBlocks
&& lhs.d->combinedImageSamplers == rhs.d->combinedImageSamplers
+ && lhs.d->separateImages == rhs.d->separateImages
+ && lhs.d->separateSamplers == rhs.d->separateSamplers
&& lhs.d->storageImages == rhs.d->storageImages
- && lhs.d->localSize == rhs.d->localSize;
+ && lhs.d->inBuiltins == rhs.d->inBuiltins
+ && lhs.d->outBuiltins == rhs.d->outBuiltins
+ && lhs.d->localSize == rhs.d->localSize
+ && lhs.d->tessOutVertCount == rhs.d->tessOutVertCount
+ && lhs.d->tessMode == rhs.d->tessMode
+ && lhs.d->tessWind == rhs.d->tessWind
+ && lhs.d->tessPart == rhs.d->tessPart;
}
/*!
@@ -1258,7 +2015,9 @@ bool operator==(const QShaderDescription::InOutVariable &lhs, const QShaderDescr
&& lhs.descriptorSet == rhs.descriptorSet
&& lhs.imageFormat == rhs.imageFormat
&& lhs.imageFlags == rhs.imageFlags
- && lhs.arrayDims == rhs.arrayDims;
+ && lhs.arrayDims == rhs.arrayDims
+ && lhs.perPatch == rhs.perPatch
+ && lhs.structMembers == rhs.structMembers;
}
/*!
@@ -1322,7 +2081,22 @@ bool operator==(const QShaderDescription::StorageBlock &lhs, const QShaderDescri
&& lhs.knownSize == rhs.knownSize
&& lhs.binding == rhs.binding
&& lhs.descriptorSet == rhs.descriptorSet
+ && lhs.runtimeArrayStride == rhs.runtimeArrayStride
+ && lhs.qualifierFlags == rhs.qualifierFlags
&& lhs.members == rhs.members;
}
+/*!
+ Returns \c true if the two BuiltinVariable objects \a lhs and \a rhs are
+ equal.
+
+ \relates QShaderDescription::BuiltinVariable
+ */
+bool operator==(const QShaderDescription::BuiltinVariable &lhs, const QShaderDescription::BuiltinVariable &rhs) noexcept
+{
+ return lhs.type == rhs.type
+ && lhs.varType == rhs.varType
+ && lhs.arrayDims == rhs.arrayDims;
+}
+
QT_END_NAMESPACE