Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qsgmaterialshader.cpp
Go to the documentation of this file.
1// Copyright (C) 2019 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include "qsgmaterial.h"
5#include "qsgrenderer_p.h"
7#include <QtCore/QFile>
8
10
167{
168 QFile f(filename);
169 if (!f.open(QIODevice::ReadOnly)) {
170 qWarning() << "Failed to find shader" << filename;
171 return QShader();
172 }
173 return QShader::fromSerialized(f.readAll());
174}
175
183
184static inline QRhiShaderResourceBinding::StageFlags toSrbStage(QShader::Stage stage)
185{
186 switch (stage) {
191 default:
192 Q_UNREACHABLE();
193 break;
194 }
195 return { };
196}
197
199{
200 ubufBinding = -1;
201 ubufSize = 0;
202 ubufStages = { };
203 memset(static_cast<void *>(combinedImageSamplerBindings), 0, sizeof(combinedImageSamplerBindings));
204 memset(static_cast<void *>(combinedImageSamplerCount), 0, sizeof(combinedImageSamplerCount));
205 vertexShader = fragmentShader = nullptr;
207
209
211 auto it = shaderFileNames.constFind(stage);
212 if (it != shaderFileNames.cend()) {
213 QString fn = *it;
214 const QShader s = loadShader(*it);
215 if (!s.isValid())
216 continue;
217 shaders[stage] = ShaderStageData(s);
218 // load only once, subsequent prepare() calls will have it all in shaders already
220 }
221 }
222
223 auto vsIt = shaders.find(QShader::VertexStage);
224 if (vsIt != shaders.end()) {
225 vsIt->shaderVariant = vertexShaderVariant;
226 vsIt->vertexInputLocations.clear();
227 vsIt->qt_order_attrib_location = -1;
228
229 const QShaderDescription desc = vsIt->shader.description();
230 const QVector<QShaderDescription::InOutVariable> vertexInputs = desc.inputVariables();
231 for (const QShaderDescription::InOutVariable &v : vertexInputs) {
232 if (vertexShaderVariant == QShader::BatchableVertexShader
233 && v.name == QByteArrayLiteral("_qt_order")) {
234 vsIt->qt_order_attrib_location = v.location;
235 } else {
236 vsIt->vertexInputLocations.append(v.location);
237 }
238 }
239
240 if (vsIt->vertexInputLocations.contains(vsIt->qt_order_attrib_location)) {
241 qWarning("Vertex input clash in rewritten (batchable) vertex shader at input location %d. "
242 "Vertex shaders must avoid using this location.", vsIt->qt_order_attrib_location);
243 }
244 }
245
246 for (auto it = shaders.begin(); it != shaders.end(); ++it) {
247 const QShaderDescription desc = it->shader.description();
248
249 const QVector<QShaderDescription::UniformBlock> ubufs = desc.uniformBlocks();
250 const int ubufCount = ubufs.size();
251 if (ubufCount > 1) {
252 qWarning("Multiple uniform blocks found in shader. "
253 "This should be avoided as Qt Quick supports only one.");
254 }
255 for (int i = 0; i < ubufCount; ++i) {
256 const QShaderDescription::UniformBlock &ubuf(ubufs[i]);
257 if (ubufBinding == -1 && ubuf.binding >= 0) {
258 ubufBinding = ubuf.binding;
259 ubufSize = ubuf.size;
260 ubufStages |= toSrbStage(it->shader.stage());
262 } else if (ubufBinding == ubuf.binding && ubuf.binding >= 0) {
263 if (ubuf.size > ubufSize) {
264 ubufSize = ubuf.size;
266 }
267 ubufStages |= toSrbStage(it->shader.stage());
268 } else {
269 qWarning("Uniform block %s (binding %d) ignored", ubuf.blockName.constData(),
270 ubuf.binding);
271 }
272 }
273
274 const QVector<QShaderDescription::InOutVariable> imageSamplers = desc.combinedImageSamplers();
275 const int imageSamplersCount = imageSamplers.size();
276 for (int i = 0; i < imageSamplersCount; ++i) {
277 const QShaderDescription::InOutVariable &var(imageSamplers[i]);
278
279 if (var.binding < 0)
280 continue;
281
282 if (var.binding < MAX_SHADER_RESOURCE_BINDINGS) {
283 combinedImageSamplerBindings[var.binding] |= toSrbStage(it->shader.stage());
284
285 int count = 1;
286 for (int dim : var.arrayDims)
287 count *= dim;
288
290 } else {
291 qWarning("Encountered invalid combined image sampler (%s) binding %d",
292 var.name.constData(), var.binding);
293 }
294 }
295
296 if (it.key() == QShader::VertexStage)
297 vertexShader = &it.value();
298 else if (it.key() == QShader::FragmentStage)
299 fragmentShader = &it.value();
300 }
301
303 qWarning("No rewriter-inserted attribute found, this should not happen.");
304}
305
313
321
328
329// We have our own enum as QShader is not initially public. Internally
330// everything works with QShader::Stage however. So convert.
332{
333 switch (stage) {
338 default:
339 Q_UNREACHABLE_RETURN(QShader::VertexStage);
340 }
341}
342
351
358{
360 d->shaderFileNames[toShaderStage(stage)] = filename;
361}
362
377void QSGMaterialShader::setShaderFileName(Stage stage, const QString &filename, int viewCount)
378{
380 if (viewCount == 2)
381 d->shaderFileNames[toShaderStage(stage)] = filename + QStringLiteral(".mv2qsb");
382 else if (viewCount == 3)
383 d->shaderFileNames[toShaderStage(stage)] = filename + QStringLiteral(".mv3qsb");
384 else if (viewCount == 4)
385 d->shaderFileNames[toShaderStage(stage)] = filename + QStringLiteral(".mv4qsb");
386 else
387 d->shaderFileNames[toShaderStage(stage)] = filename;
388}
389
393QSGMaterialShader::Flags QSGMaterialShader::flags() const
394{
395 Q_D(const QSGMaterialShader);
396 return d->flags;
397}
398
404{
406 if (on)
407 d->flags |= flags;
408 else
409 d->flags &= ~flags;
410}
411
416{
418 d->flags = flags;
419}
420
443{
444 Q_D(const QSGMaterialShader);
445
446 if (binding >= 0 && binding < d->MAX_SHADER_RESOURCE_BINDINGS)
447 return d->combinedImageSamplerCount[binding];
448
449 return 0;
450}
451
477 QSGMaterial *newMaterial,
478 QSGMaterial *oldMaterial)
479{
481 Q_UNUSED(newMaterial);
482 Q_UNUSED(oldMaterial);
483 return false;
484}
485
518 int binding,
520 QSGMaterial *newMaterial,
521 QSGMaterial *oldMaterial)
522{
524 Q_UNUSED(binding);
526 Q_UNUSED(newMaterial);
527 Q_UNUSED(oldMaterial);
528}
529
551 QSGMaterial *newMaterial, QSGMaterial *oldMaterial)
552{
554 Q_UNUSED(ps);
555 Q_UNUSED(newMaterial);
556 Q_UNUSED(oldMaterial);
557 return false;
558}
559
801{
802 Q_ASSERT(m_data);
803 return float(static_cast<const QSGRenderer *>(m_data)->currentOpacity());
804}
805
810{
812 return float(static_cast<const QSGRenderer *>(m_data)->determinant());
813}
814
819{
821 return static_cast<const QSGRenderer *>(m_data)->currentCombinedMatrix(0);
822}
823
828{
830 return static_cast<const QSGRenderer *>(m_data)->currentCombinedMatrix(index);
831}
832
838{
840 return float(static_cast<const QSGRenderer *>(m_data)->devicePixelRatio());
841}
842
858{
860 return static_cast<const QSGRenderer *>(m_data)->currentModelViewMatrix();
861}
862
867{
869 return static_cast<const QSGRenderer *>(m_data)->currentProjectionMatrix(0);
870}
871
876{
878 return static_cast<const QSGRenderer *>(m_data)->currentProjectionMatrix(index);
879}
880
885{
887 return static_cast<const QSGRenderer *>(m_data)->projectionMatrixCount();
888}
889
894{
896 return static_cast<const QSGRenderer *>(m_data)->viewportRect();
897}
898
903{
905 return static_cast<const QSGRenderer *>(m_data)->deviceRect();
906}
907
929{
931 return static_cast<const QSGRenderer *>(m_data)->currentUniformData();
932}
933
941{
943 return static_cast<const QSGRenderer *>(m_data)->currentResourceUpdateBatch();
944}
945
950{
952 return static_cast<const QSGRenderer *>(m_data)->currentRhi();
953}
954
NSData * m_data
\inmodule QtCore
Definition qbytearray.h:57
QByteArray & fill(char c, qsizetype size=-1)
Sets every byte in the byte array to ch.
const char * constData() const noexcept
Returns a pointer to the const data stored in the byte array.
Definition qbytearray.h:124
void clear()
Clears the contents of the byte array and makes it null.
\inmodule QtCore
Definition qfile.h:93
const_iterator constFind(const Key &key) const noexcept
Definition qhash.h:1299
iterator erase(const_iterator it)
Definition qhash.h:1233
const_iterator cend() const noexcept
Definition qhash.h:1218
The QMatrix4x4 class represents a 4x4 transformation matrix in 3D space.
Definition qmatrix4x4.h:25
\inmodule QtCore\reentrant
Definition qrect.h:30
\inmodule QtGui
Definition qrhi.h:1731
\inmodule QtGuiPrivate \inheaderfile rhi/qrhi.h
Definition qrhi.h:1804
QVarLengthArray< QRhiSampler *, 4 > samplerBindingTable[MAX_SHADER_RESOURCE_BINDINGS]
ShaderStageData * fragmentShader
QRhiShaderResourceBinding::StageFlags combinedImageSamplerBindings[MAX_SHADER_RESOURCE_BINDINGS]
int combinedImageSamplerCount[MAX_SHADER_RESOURCE_BINDINGS]
static const int MAX_SHADER_RESOURCE_BINDINGS
QRhiShaderResourceBinding::StageFlags ubufStages
void prepare(QShader::Variant vertexShaderVariant)
QVarLengthArray< QSGTexture *, 4 > textureBindingTable[MAX_SHADER_RESOURCE_BINDINGS]
QHash< QShader::Stage, QString > shaderFileNames
static QShader loadShader(const QString &filename)
Encapsulates the current rendering state during a call to QSGMaterialShader::updateUniformData() and ...
QRect viewportRect() const
Returns the viewport rect of the surface being rendered to.
QRect deviceRect() const
Returns the device rect of the surface being rendered to.
float determinant() const
Returns the modelview determinant to be used for rendering.
float devicePixelRatio() const
Returns the ratio between physical pixels and device-independent pixels to be used for rendering.
QMatrix4x4 modelViewMatrix() const
Returns the model view matrix.
QByteArray * uniformData()
Returns a pointer to the data for the uniform (constant) buffer in the shader.
QMatrix4x4 combinedMatrix() const
Returns the matrix combined of modelview matrix and project matrix.
QMatrix4x4 projectionMatrix() const
Returns the projection matrix.
QRhi * rhi()
Returns the current QRhi.
float opacity() const
\variable QSGMaterialShader::GraphicsPipelineState::blendEnable
QRhiResourceUpdateBatch * resourceUpdateBatch()
Returns a resource update batch to which upload and copy operatoins can be queued.
The QSGMaterialShader class represents a graphics API independent shader program.
void setShader(Stage stage, const QShader &shader)
Sets the shader for the specified stage.
virtual bool updateUniformData(RenderState &state, QSGMaterial *newMaterial, QSGMaterial *oldMaterial)
This function is called by the scene graph to get the contents of the shader program's uniform buffer...
virtual bool updateGraphicsPipelineState(RenderState &state, GraphicsPipelineState *ps, QSGMaterial *newMaterial, QSGMaterial *oldMaterial)
This function is called by the scene graph to enable the material to provide a custom set of graphics...
void setShaderFileName(Stage stage, const QString &filename)
Sets the filename for the shader for the specified stage.
int combinedImageSamplerCount(int binding) const
Returns the number of elements in the combined image sampler variable at binding.
virtual void updateSampledImage(RenderState &state, int binding, QSGTexture **texture, QSGMaterial *newMaterial, QSGMaterial *oldMaterial)
This function is called by the scene graph to prepare use of sampled images in the shader,...
QSGMaterialShader()
Constructs a new QSGMaterialShader.
void setFlag(Flags flags, bool on=true)
Sets the flags on this material shader if on is true; otherwise clears the specified flags.
void setFlags(Flags flags)
Sets the flags for this material shader.
The QSGMaterial class encapsulates rendering state for a shader program.
Definition qsgmaterial.h:15
The renderer class is the abstract baseclass used for rendering the QML scene graph.
\inmodule QtQuick
Definition qsgtexture.h:20
iterator begin()
Definition qset.h:136
iterator end()
Definition qset.h:140
\inmodule QtGui
Definition qshader.h:81
static QShader fromSerialized(const QByteArray &data)
Creates a new QShader instance from the given data.
Definition qshader.cpp:540
Variant
Describes what kind of shader code an entry contains.
Definition qshader.h:103
@ BatchableVertexShader
Definition qshader.h:105
Stage
Describes the stage of the graphics pipeline the shader is suitable for.
Definition qshader.h:83
@ VertexStage
Definition qshader.h:84
@ FragmentStage
Definition qshader.h:88
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
const void * constData() const
Definition qvariant.h:451
#define this
Definition dialogs.cpp:9
b clear()
QSet< QString >::iterator it
else opt state
[0]
Combined button and popup list for selecting options.
#define QByteArrayLiteral(str)
Definition qbytearray.h:52
Flags
#define qWarning
Definition qlogging.h:166
GLsizei const GLfloat * v
[13]
GLuint index
[2]
GLenum GLenum GLsizei count
GLfloat GLfloat f
GLbitfield flags
GLenum GLuint texture
GLdouble s
[6]
Definition qopenglext.h:235
GLuint shader
Definition qopenglext.h:665
GLsizei GLsizei GLuint * shaders
Definition qopenglext.h:677
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
static QShader::Stage toShaderStage(QRhiShaderStage::Type type)
static QShader::Stage toShaderStage(QSGMaterialShader::Stage stage)
static QRhiShaderResourceBinding::StageFlags toSrbStage(QShader::Stage stage)
#define QStringLiteral(str)
#define Q_UNUSED(x)
Describes state changes that the material wants to apply to the currently active graphics pipeline st...
\variable QShaderDescription::BlockVariable::name