aboutsummaryrefslogtreecommitdiffstats
path: root/src/quick/scenegraph/coreapi/qsgmaterialshader.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/quick/scenegraph/coreapi/qsgmaterialshader.cpp')
-rw-r--r--src/quick/scenegraph/coreapi/qsgmaterialshader.cpp282
1 files changed, 224 insertions, 58 deletions
diff --git a/src/quick/scenegraph/coreapi/qsgmaterialshader.cpp b/src/quick/scenegraph/coreapi/qsgmaterialshader.cpp
index 45e7a6fb4e..a661e47765 100644
--- a/src/quick/scenegraph/coreapi/qsgmaterialshader.cpp
+++ b/src/quick/scenegraph/coreapi/qsgmaterialshader.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQuick module of the Qt Toolkit.
-**
-** $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$
-**
-****************************************************************************/
+// Copyright (C) 2019 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 "qsgmaterial.h"
#include "qsgrenderer_p.h"
@@ -212,9 +176,9 @@ QShader QSGMaterialShaderPrivate::loadShader(const QString &filename)
void QSGMaterialShaderPrivate::clearCachedRendererData()
{
for (int i = 0; i < MAX_SHADER_RESOURCE_BINDINGS; ++i)
- textureBindingTable[i] = nullptr;
+ textureBindingTable[i].clear();
for (int i = 0; i < MAX_SHADER_RESOURCE_BINDINGS; ++i)
- samplerBindingTable[i] = nullptr;
+ samplerBindingTable[i].clear();
}
static inline QRhiShaderResourceBinding::StageFlags toSrbStage(QShader::Stage stage)
@@ -237,14 +201,15 @@ void QSGMaterialShaderPrivate::prepare(QShader::Variant vertexShaderVariant)
ubufSize = 0;
ubufStages = { };
memset(static_cast<void *>(combinedImageSamplerBindings), 0, sizeof(combinedImageSamplerBindings));
+ memset(static_cast<void *>(combinedImageSamplerCount), 0, sizeof(combinedImageSamplerCount));
vertexShader = fragmentShader = nullptr;
masterUniformData.clear();
clearCachedRendererData();
for (QShader::Stage stage : { QShader::VertexStage, QShader::FragmentStage }) {
- auto it = shaderFileNames.find(stage);
- if (it != shaderFileNames.end()) {
+ auto it = shaderFileNames.constFind(stage);
+ if (it != shaderFileNames.cend()) {
QString fn = *it;
const QShader s = loadShader(*it);
if (!s.isValid())
@@ -282,7 +247,7 @@ void QSGMaterialShaderPrivate::prepare(QShader::Variant vertexShaderVariant)
const QShaderDescription desc = it->shader.description();
const QVector<QShaderDescription::UniformBlock> ubufs = desc.uniformBlocks();
- const int ubufCount = ubufs.count();
+ const int ubufCount = ubufs.size();
if (ubufCount > 1) {
qWarning("Multiple uniform blocks found in shader. "
"This should be avoided as Qt Quick supports only one.");
@@ -307,14 +272,25 @@ void QSGMaterialShaderPrivate::prepare(QShader::Variant vertexShaderVariant)
}
const QVector<QShaderDescription::InOutVariable> imageSamplers = desc.combinedImageSamplers();
- const int imageSamplersCount = imageSamplers.count();
+ const int imageSamplersCount = imageSamplers.size();
for (int i = 0; i < imageSamplersCount; ++i) {
const QShaderDescription::InOutVariable &var(imageSamplers[i]);
- if (var.binding >= 0 && var.binding < MAX_SHADER_RESOURCE_BINDINGS)
+
+ if (var.binding < 0)
+ continue;
+
+ if (var.binding < MAX_SHADER_RESOURCE_BINDINGS) {
combinedImageSamplerBindings[var.binding] |= toSrbStage(it->shader.stage());
- else
+
+ int count = 1;
+ for (int dim : var.arrayDims)
+ count *= dim;
+
+ combinedImageSamplerCount[var.binding] = count;
+ } else {
qWarning("Encountered invalid combined image sampler (%s) binding %d",
var.name.constData(), var.binding);
+ }
}
if (it.key() == QShader::VertexStage)
@@ -360,8 +336,7 @@ static inline QShader::Stage toShaderStage(QSGMaterialShader::Stage stage)
case QSGMaterialShader::FragmentStage:
return QShader::FragmentStage;
default:
- Q_UNREACHABLE();
- return QShader::VertexStage;
+ Q_UNREACHABLE_RETURN(QShader::VertexStage);
}
}
@@ -386,6 +361,33 @@ void QSGMaterialShader::setShaderFileName(Stage stage, const QString &filename)
}
/*!
+ Sets the \a filename for the shader for the specified \a stage.
+
+ The file is expected to contain a serialized QShader.
+
+ This overload is used when enabling \l{QSGMaterial::viewCount()}{multiview}
+ rendering, in particular when the \l{Qt Shader Tools Build System
+ Integration}{build system's MULTIVIEW convenience option} is used.
+
+ \a viewCount should be 2, 3, or 4. The \a filename is adjusted automatically
+ based on this.
+
+ \since 6.8
+ */
+void QSGMaterialShader::setShaderFileName(Stage stage, const QString &filename, int viewCount)
+{
+ Q_D(QSGMaterialShader);
+ if (viewCount == 2)
+ d->shaderFileNames[toShaderStage(stage)] = filename + QStringLiteral(".mv2qsb");
+ else if (viewCount == 3)
+ d->shaderFileNames[toShaderStage(stage)] = filename + QStringLiteral(".mv3qsb");
+ else if (viewCount == 4)
+ d->shaderFileNames[toShaderStage(stage)] = filename + QStringLiteral(".mv4qsb");
+ else
+ d->shaderFileNames[toShaderStage(stage)] = filename;
+}
+
+/*!
\return the currently set flags for this material shader.
*/
QSGMaterialShader::Flags QSGMaterialShader::flags() const
@@ -417,6 +419,37 @@ void QSGMaterialShader::setFlags(Flags flags)
}
/*!
+ Returns the number of elements in the combined image sampler variable at \a
+ binding. This value is introspected from the shader code. The variable may
+ be an array, and may have more than one dimension.
+
+ The count reflects the total number of combined image sampler items in the
+ variable. In the following example, the count for \c{srcA} is 1, \c{srcB}
+ is 4, and \c{srcC} is 6.
+
+ \badcode
+ layout (binding = 0) uniform sampler2D srcA;
+ layout (binding = 1) uniform sampler2D srcB[4];
+ layout (binding = 2) uniform sampler2D srcC[2][3];
+ \endcode
+
+ This count is the number of QSGTexture pointers in the texture parameter
+ of \l{QSGMaterialShader::updateSampledImage}.
+
+ \sa QSGMaterialShader::updateSampledImage
+ \since 6.4
+ */
+int QSGMaterialShader::combinedImageSamplerCount(int binding) const
+{
+ Q_D(const QSGMaterialShader);
+
+ if (binding >= 0 && binding < d->MAX_SHADER_RESOURCE_BINDINGS)
+ return d->combinedImageSamplerCount[binding];
+
+ return 0;
+}
+
+/*!
This function is called by the scene graph to get the contents of the
shader program's uniform buffer updated. The implementation is not expected
to perform any real graphics operations, it is merely responsible for
@@ -451,27 +484,35 @@ bool QSGMaterialShader::updateUniformData(RenderState &state,
}
/*!
- This function is called by the scene graph to prepare using a sampled image
- in the shader, typically in form of a combined image sampler.
+ This function is called by the scene graph to prepare use of sampled images
+ in the shader, typically in the form of combined image samplers.
\a binding is the binding number of the sampler. The function is called for
each combined image sampler variable in the shader code associated with the
QSGMaterialShader.
- When *\a{texture} is null, it must be set to a QSGTexture pointer before
- returning. When non-null, it is up to the material to decide if a new
- \c{QSGTexture *} is stored to it, or if it updates some parameters on the
- already known QSGTexture. The ownership of the QSGTexture is not
- transferred.
+ \a{texture} is an array of QSGTexture pointers. The number of elements in
+ the array matches the number of elements in the image sampler variable
+ specified in the shader code. This variable may be an array, and may have
+ more than one dimension. The number of elements in the array may be
+ found via \l{QSGMaterialShader::combinedImageSamplerCount}
+
+ When an element in \a{texture} is null, it must be set to a valid
+ QSGTexture pointer before returning. When non-null, it is up to the
+ material to decide if a new \c{QSGTexture *} is stored to it, or if it
+ updates some parameters on the already known QSGTexture. The ownership of
+ the QSGTexture is not transferred.
The current rendering \a state is passed from the scene graph. Where
relevant, it is up to the material to trigger enqueuing texture data
- uploads.
+ uploads via QSGTexture::commitTextureOperations().
The subclass specific state can be extracted from \a newMaterial.
\a oldMaterial can be used to minimize changes. When \a oldMaterial is null,
this shader was just activated.
+
+ \sa QSGMaterialShader::combinedImageSamplerCount
*/
void QSGMaterialShader::updateSampledImage(RenderState &state,
int binding,
@@ -586,6 +627,12 @@ bool QSGMaterialShader::updateGraphicsPipelineState(RenderState &state, Graphics
updatePipelineState() implementation, if there is one. The scenegraph will
then internally apply these changes to the active graphics pipeline state,
then rolling them back as appropriate.
+
+ When updateGraphicsPipelineState() is called, the struct has all members
+ set to a valid value to reflect the renderer's current state. Not changing
+ any values (or not reimplementing the function) indicates that the material
+ is fine with the defaults (which are dynamic however, depending on
+ QSGMaterial flags, for example).
*/
/*!
@@ -633,6 +680,98 @@ bool QSGMaterialShader::updateGraphicsPipelineState(RenderState &state, Graphics
*/
/*!
+ \enum QSGMaterialShader::GraphicsPipelineState::PolygonMode
+ \since 6.4
+ \brief Specifies the polygon rasterization mode
+
+ Polygon Mode (Triangle Fill Mode in Metal, Fill Mode in D3D) specifies
+ the fill mode used when rasterizing polygons. Polygons may be drawn as
+ solids (Fill), or as a wire mesh (Line).
+
+ \warning OpenGL ES does not support the \c{Line} polygon mode. OpenGL ES
+ will rasterize all polygons as filled no matter what polygon mode is set.
+ Using \c{Line} will make your application non-portable.
+
+ \value Fill The interior of the polygon is filled (default)
+ \value Line Boundary edges of the polygon are drawn as line segments.
+ */
+
+/*!
+ \variable QSGMaterialShader::GraphicsPipelineState::blendEnable
+ \since 5.14
+ \brief Enables blending.
+
+ \note Changing this flag should be done with care, and is best avoided.
+ Rather, materials should always use the QSGMaterial::Blend flag to indicate
+ that they wish to use blending. Changing this value from false to true for
+ a material that did not declare QSGMaterial::Blend can lead to unexpected
+ visual results.
+ */
+
+/*!
+ \variable QSGMaterialShader::GraphicsPipelineState::srcColor
+ \since 5.14
+ \brief Source blending factor, either RGB or RGBA depending on separateBlendFactors.
+ */
+
+/*!
+ \variable QSGMaterialShader::GraphicsPipelineState::dstColor
+ \since 5.14
+ \brief Destination blending factor, either RGB or RGBA depending on separateBlendFactors.
+ */
+
+/*!
+ \variable QSGMaterialShader::GraphicsPipelineState::colorWrite
+ \since 5.14
+ \brief Color write mask.
+ */
+
+/*!
+ \variable QSGMaterialShader::GraphicsPipelineState::blendConstant
+ \since 5.14
+ \brief Blend constant applicable when a blending factor is set to use a constant value.
+ */
+
+/*!
+ \variable QSGMaterialShader::GraphicsPipelineState::cullMode
+ \since 5.14
+ \brief Cull mode.
+ */
+
+/*!
+ \variable QSGMaterialShader::GraphicsPipelineState::polygonMode
+ \since 6.4
+ \brief Polygon rasterization mode.
+ */
+
+/*!
+ \variable QSGMaterialShader::GraphicsPipelineState::separateBlendFactors
+ \since 6.5
+ \brief Indicates that alpha blending factors are specified separately.
+
+ False by default, meaning both RGB and alpha blending factors are defined
+ by srcColor and dstColor. When set to true, the alpha blending factors are
+ taken from srcAlpha and dstAlpha instead, and srcColor and dstColor applies
+ only to RGB.
+ */
+
+/*!
+ \variable QSGMaterialShader::GraphicsPipelineState::srcAlpha
+ \since 6.5
+ \brief Source alpha blending factor.
+
+ Applies only when separateBlendFactors is set to true.
+ */
+
+/*!
+ \variable QSGMaterialShader::GraphicsPipelineState::dstAlpha
+ \since 6.5
+ \brief Destination alpha blending factor.
+
+ Applies only when separateBlendFactors is set to true.
+ */
+
+/*!
Returns the accumulated opacity to be used for rendering.
*/
float QSGMaterialShader::RenderState::opacity() const
@@ -656,7 +795,16 @@ float QSGMaterialShader::RenderState::determinant() const
QMatrix4x4 QSGMaterialShader::RenderState::combinedMatrix() const
{
Q_ASSERT(m_data);
- return static_cast<const QSGRenderer *>(m_data)->currentCombinedMatrix();
+ return static_cast<const QSGRenderer *>(m_data)->currentCombinedMatrix(0);
+}
+
+/*!
+ \internal
+ */
+QMatrix4x4 QSGMaterialShader::RenderState::combinedMatrix(int index) const
+{
+ Q_ASSERT(m_data);
+ return static_cast<const QSGRenderer *>(m_data)->currentCombinedMatrix(index);
}
/*!
@@ -695,7 +843,25 @@ QMatrix4x4 QSGMaterialShader::RenderState::modelViewMatrix() const
QMatrix4x4 QSGMaterialShader::RenderState::projectionMatrix() const
{
Q_ASSERT(m_data);
- return static_cast<const QSGRenderer *>(m_data)->currentProjectionMatrix();
+ return static_cast<const QSGRenderer *>(m_data)->currentProjectionMatrix(0);
+}
+
+/*!
+ \internal
+ */
+QMatrix4x4 QSGMaterialShader::RenderState::projectionMatrix(int index) const
+{
+ Q_ASSERT(m_data);
+ return static_cast<const QSGRenderer *>(m_data)->currentProjectionMatrix(index);
+}
+
+/*!
+ \internal
+ */
+int QSGMaterialShader::RenderState::projectionMatrixCount() const
+{
+ Q_ASSERT(m_data);
+ return static_cast<const QSGRenderer *>(m_data)->projectionMatrixCount();
}
/*!