Qt 6.x
The Qt SDK
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
177{
178 for (int i = 0; i < MAX_SHADER_RESOURCE_BINDINGS; ++i)
180 for (int i = 0; i < MAX_SHADER_RESOURCE_BINDINGS; ++i)
182}
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.find(stage);
212 if (it != shaderFileNames.end()) {
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
310 : d_ptr(new QSGMaterialShaderPrivate(this))
311{
312}
313
318 : d_ptr(&dd)
319{
320}
321
326{
327}
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
347{
350}
351
358{
360 d->shaderFileNames[toShaderStage(stage)] = filename;
361}
362
366QSGMaterialShader::Flags QSGMaterialShader::flags() const
367{
368 Q_D(const QSGMaterialShader);
369 return d->flags;
370}
371
377{
379 if (on)
380 d->flags |= flags;
381 else
382 d->flags &= ~flags;
383}
384
389{
391 d->flags = flags;
392}
393
416{
417 Q_D(const QSGMaterialShader);
418
419 if (binding >= 0 && binding < d->MAX_SHADER_RESOURCE_BINDINGS)
420 return d->combinedImageSamplerCount[binding];
421
422 return 0;
423}
424
450 QSGMaterial *newMaterial,
451 QSGMaterial *oldMaterial)
452{
454 Q_UNUSED(newMaterial);
455 Q_UNUSED(oldMaterial);
456 return false;
457}
458
491 int binding,
493 QSGMaterial *newMaterial,
494 QSGMaterial *oldMaterial)
495{
497 Q_UNUSED(binding);
499 Q_UNUSED(newMaterial);
500 Q_UNUSED(oldMaterial);
501}
502
524 QSGMaterial *newMaterial, QSGMaterial *oldMaterial)
525{
527 Q_UNUSED(ps);
528 Q_UNUSED(newMaterial);
529 Q_UNUSED(oldMaterial);
530 return false;
531}
532
751{
752 Q_ASSERT(m_data);
753 return float(static_cast<const QSGRenderer *>(m_data)->currentOpacity());
754}
755
760{
762 return float(static_cast<const QSGRenderer *>(m_data)->determinant());
763}
764
769{
771 return static_cast<const QSGRenderer *>(m_data)->currentCombinedMatrix();
772}
773
779{
781 return float(static_cast<const QSGRenderer *>(m_data)->devicePixelRatio());
782}
783
799{
801 return static_cast<const QSGRenderer *>(m_data)->currentModelViewMatrix();
802}
803
808{
810 return static_cast<const QSGRenderer *>(m_data)->currentProjectionMatrix();
811}
812
817{
819 return static_cast<const QSGRenderer *>(m_data)->viewportRect();
820}
821
826{
828 return static_cast<const QSGRenderer *>(m_data)->deviceRect();
829}
830
852{
854 return static_cast<const QSGRenderer *>(m_data)->currentUniformData();
855}
856
864{
866 return static_cast<const QSGRenderer *>(m_data)->currentResourceUpdateBatch();
867}
868
873{
875 return static_cast<const QSGRenderer *>(m_data)->currentRhi();
876}
877
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:122
void clear()
Clears the contents of the byte array and makes it null.
\inmodule QtCore
Definition qfile.h:93
iterator find(const Key &key)
Returns an iterator pointing to the item with the key in the hash.
Definition qhash.h:1258
iterator erase(const_iterator it)
Definition qhash.h:1223
iterator end() noexcept
Returns an \l{STL-style iterators}{STL-style iterator} pointing to the imaginary item after the last ...
Definition qhash.h:1206
Definition qlist.h:74
qsizetype size() const noexcept
Definition qlist.h:386
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:1694
\inmodule QtGui
Definition qrhi.h:1767
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:510
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:127
const void * constData() const
Definition qvariant.h:446
#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:162
GLsizei const GLfloat * v
[13]
GLenum GLenum GLsizei count
GLfloat GLfloat f
GLbitfield flags
GLenum GLuint texture
GLuint shader
Definition qopenglext.h:665
GLsizei GLsizei GLuint * shaders
Definition qopenglext.h:677
GLdouble s
[6]
Definition qopenglext.h:235
#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 Q_UNUSED(x)
@ desc
Describes state changes that the material wants to apply to the currently active graphics pipeline st...
\variable QShaderDescription::BlockVariable::name