Revision control

++ // Copyright (C) 2020 The Qt Company Ltd.
++ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
++ // Qt-Security score:significant reason:default
++
++
++ #ifndef QQUICK3DSHADERUTILS_H
++ #define QQUICK3DSHADERUTILS_H
++
++ //
++ // W A R N I N G
++ // -------------
++ //
++ // This file is not part of the Qt API. It exists purely as an
++ // implementation detail. This header file may change from version to
++ // version without notice, or even be removed.
++ //
++ // We mean it.
++ //
++
++ #include <QtQuick3D/qtquick3dglobal.h>
++ #include <QtQuick3D/private/qquick3dobject_p.h>
++ #include <QtQuick3D/private/qquick3dtexture_p.h>
++ #include <QtQuick3D/private/qquick3dmaterial_p.h>
++
++ #include <QtQuick3DUtils/private/qssgrenderbasetypes_p.h>
++
++ #include <QtQuick3DRuntimeRender/private/qssgrendercommands_p.h>
++
++ QT_BEGIN_NAMESPACE
++
++ class QQuick3DShaderUtilsShader;
++ class QQmlContext;
++ class QQuick3DRenderPass;
++
++ namespace QSSGShaderUtils {
++
++ using MetaTypeList = QList<QMetaType::Type>;
++ using ResolveFunction = bool (*)(const QUrl &url, const QQmlContext *context, QByteArray &shaderData, QByteArray &shaderPathKey);
++ Q_QUICK3D_EXPORT void setResolveFunction(ResolveFunction fn);
++ Q_QUICK3D_EXPORT QByteArray resolveShader(const QUrl &fileUrl, const QQmlContext *context, QByteArray &shaderPathKey);
++ Q_QUICK3D_EXPORT MetaTypeList supportedMetatypes();
++
++
++ template<QMetaType::Type>
++ struct ShaderType
++ {
++ };
++
++ Q_QUICK3D_EXPORT QByteArray uniformTypeName(QMetaType type);
++ Q_QUICK3D_EXPORT QByteArray uniformTypeName(QSSGRenderShaderValue::Type type);
++ Q_QUICK3D_EXPORT QSSGRenderShaderValue::Type uniformType(QMetaType type);
++ }
++
++ class Q_QUICK3D_EXPORT QQuick3DShaderUtilsTextureInput : public QQuick3DObject
++ {
++ Q_OBJECT
++ Q_PROPERTY(QQuick3DTexture *texture READ texture WRITE setTexture NOTIFY textureChanged)
++ Q_PROPERTY(bool enabled MEMBER enabled NOTIFY enabledChanged)
++
++ QML_NAMED_ELEMENT(TextureInput)
++
++ public:
++ explicit QQuick3DShaderUtilsTextureInput(QQuick3DObject *p = nullptr);
++ virtual ~QQuick3DShaderUtilsTextureInput();
++ QQuick3DTexture *m_texture = nullptr;
++ bool enabled = true;
++ QByteArray name;
++ QQuick3DTexture *texture() const
++ {
++ return m_texture;
++ }
++
++ public Q_SLOTS:
++ void setTexture(QQuick3DTexture *texture);
++
++ Q_SIGNALS:
++ void textureChanged();
++ void enabledChanged();
++ };
++
++ class Q_QUICK3D_EXPORT QQuick3DShaderUtilsBuffer : public QQuick3DObject
++ {
++ Q_OBJECT
++ Q_PROPERTY(TextureFormat format READ format WRITE setFormat NOTIFY changed)
++ Q_PROPERTY(TextureFilterOperation textureFilterOperation READ textureFilterOperation WRITE setTextureFilterOperation NOTIFY changed)
++ Q_PROPERTY(TextureCoordOperation textureCoordOperation READ textureCoordOperation WRITE setTextureCoordOperation NOTIFY changed)
++ Q_PROPERTY(float sizeMultiplier MEMBER sizeMultiplier NOTIFY changed)
++ Q_PROPERTY(AllocateBufferFlagValues bufferFlags READ bufferFlags WRITE setBufferFlags NOTIFY changed)
++ Q_PROPERTY(QByteArray name MEMBER name NOTIFY changed)
++
++ QML_NAMED_ELEMENT(Buffer)
++
++ public:
++ QQuick3DShaderUtilsBuffer() = default;
++ ~QQuick3DShaderUtilsBuffer() override = default;
++
++ enum class TextureFilterOperation // must match QSSGRenderTextureFilterOp
++ {
++ Unknown = 0,
++ Nearest,
++ Linear
++ };
++ Q_ENUM(TextureFilterOperation)
++
++ enum class TextureCoordOperation // must match QSSGRenderTextureCoordOp
++ {
++ Unknown = 0,
++ ClampToEdge,
++ MirroredRepeat,
++ Repeat
++ };
++ Q_ENUM(TextureCoordOperation)
++
++ enum class AllocateBufferFlagValues
++ {
++ None = 0,
++ SceneLifetime = 1
++ };
++ Q_ENUM(AllocateBufferFlagValues)
++
++ enum class TextureFormat {
++ Unknown = 0,
++ RGBA8,
++ RGBA16F,
++ RGBA32F,
++ R8,
++ R16,
++ R16F,
++ R32F
++ };
++ Q_ENUM(TextureFormat)
++
++ QSSGAllocateBuffer command {};
++ TextureFilterOperation textureFilterOperation() const { return TextureFilterOperation(command.m_filterOp); }
++ void setTextureFilterOperation(TextureFilterOperation op);
++
++ TextureCoordOperation textureCoordOperation() const { return TextureCoordOperation(command.m_texCoordOp); }
++ void setTextureCoordOperation(TextureCoordOperation texCoordOp);
++ float &sizeMultiplier = command.m_sizeMultiplier;
++ QSSGCommand *cloneCommand() { return new QSSGAllocateBuffer(command); }
++
++ TextureFormat format() const;
++ void setFormat(TextureFormat format);
++
++ AllocateBufferFlagValues bufferFlags() const { return AllocateBufferFlagValues(int(command.m_bufferFlags)); }
++ void setBufferFlags(AllocateBufferFlagValues flag);
++
++ QByteArray &name = command.m_name;
++
++ static QSSGRenderTextureFormat::Format mapTextureFormat(QQuick3DShaderUtilsBuffer::TextureFormat fmt);
++ static QQuick3DShaderUtilsBuffer::TextureFormat mapRenderTextureFormat(QSSGRenderTextureFormat::Format fmt);
++
++ Q_SIGNALS:
++ void changed();
++ };
++
++ class Q_QUICK3D_EXPORT QQuick3DShaderUtilsRenderCommand : public QQuick3DObject
++ {
++ Q_OBJECT
++
++ QML_NAMED_ELEMENT(Command)
++
++ public:
++ QQuick3DShaderUtilsRenderCommand() = default;
++ ~QQuick3DShaderUtilsRenderCommand() override = default;
++ virtual QSSGCommand *cloneCommand() { Q_ASSERT(0); return nullptr; }
++ virtual int bufferCount() const { return 0; }
++ virtual QQuick3DShaderUtilsBuffer *bufferAt(int idx) const { Q_UNUSED(idx); return nullptr; }
++
++ Q_SIGNALS:
++ void changed();
++ };
++
++ class Q_QUICK3D_EXPORT QQuick3DShaderUtilsBufferInput : public QQuick3DShaderUtilsRenderCommand
++ {
++ Q_OBJECT
++ Q_PROPERTY(QQuick3DShaderUtilsBuffer *buffer READ buffer WRITE setBuffer)
++ Q_PROPERTY(QByteArray sampler MEMBER sampler)
++
++ QML_NAMED_ELEMENT(BufferInput)
++
++ public:
++ QQuick3DShaderUtilsBufferInput() = default;
++ ~QQuick3DShaderUtilsBufferInput() override = default;
++ QSSGApplyBufferValue command { QByteArray(), QByteArray() };
++ QByteArray &sampler = command.m_samplerName;
++ QSSGCommand *cloneCommand() override { return new QSSGApplyBufferValue(command); }
++
++ int bufferCount() const override { return (m_buffer != nullptr) ? 1 : 0; }
++ QQuick3DShaderUtilsBuffer *bufferAt(int idx) const override
++ {
++ Q_ASSERT(idx < 1 && idx >= 0);
++ return (m_buffer && idx == 0) ? m_buffer : nullptr;
++ }
++
++ QQuick3DShaderUtilsBuffer *buffer() const { return m_buffer; }
++ void setBuffer(QQuick3DShaderUtilsBuffer *buffer) {
++ if (m_buffer == buffer)
++ return;
++
++ if (buffer) {
++ Q_ASSERT(!buffer->name.isEmpty());
++ command.m_bufferName = buffer->name;
++ }
++ m_buffer = buffer;
++ }
++
++ QQuick3DShaderUtilsBuffer *m_buffer = nullptr;
++
++ };
++
++ class Q_QUICK3D_EXPORT QQuick3DRenderPassTargetBlend
++ {
++ Q_GADGET
++ Q_PROPERTY(bool enable MEMBER enable)
++ Q_PROPERTY(ColorMask colorWrite MEMBER colorWrite)
++ Q_PROPERTY(BlendFactor srcColor MEMBER srcColor)
++ Q_PROPERTY(BlendFactor dstColor MEMBER dstColor)
++ Q_PROPERTY(BlendOperation opColor MEMBER opColor)
++ Q_PROPERTY(BlendFactor srcAlpha MEMBER srcAlpha)
++ Q_PROPERTY(BlendFactor dstAlpha MEMBER dstAlpha)
++ Q_PROPERTY(BlendOperation opAlpha MEMBER opAlpha)
++ QML_VALUE_TYPE(renderTargetBlend)
++ QML_ADDED_IN_VERSION(6, 11)
++
++ public:
++ enum ColorMaskComponent : quint32 {
++ R = 1 << 0,
++ G = 1 << 1,
++ B = 1 << 2,
++ A = 1 << 3,
++ };
++ Q_DECLARE_FLAGS(ColorMask, ColorMaskComponent)
++
++ enum class BlendFactor {
++ Zero,
++ One,
++ SrcColor,
++ OneMinusSrcColor,
++ DstColor,
++ OneMinusDstColor,
++ SrcAlpha,
++ OneMinusSrcAlpha,
++ DstAlpha,
++ OneMinusDstAlpha,
++ ConstantColor,
++ OneMinusConstantColor,
++ ConstantAlpha,
++ OneMinusConstantAlpha,
++ SrcAlphaSaturate,
++ Src1Color,
++ OneMinusSrc1Color,
++ Src1Alpha,
++ OneMinusSrc1Alpha
++ };
++ Q_ENUM(BlendFactor)
++
++ enum class BlendOperation {
++ Add,
++ Subtract,
++ ReverseSubtract,
++ Min,
++ Max
++ };
++ Q_ENUM(BlendOperation)
++
++ ColorMask colorWrite = ColorMask(0xF); // R | G | B | A
++ bool enable = false;
++ BlendFactor srcColor = BlendFactor::One;
++ BlendFactor dstColor = BlendFactor::OneMinusSrcAlpha;
++ BlendOperation opColor = BlendOperation::Add;
++ BlendFactor srcAlpha = BlendFactor::One;
++ BlendFactor dstAlpha = BlendFactor::OneMinusSrcAlpha;
++ BlendOperation opAlpha = BlendOperation::Add;
++
++ bool operator==(const QQuick3DRenderPassTargetBlend &other) const
++ {
++ return colorWrite == other.colorWrite
++ && enable == other.enable
++ && srcColor == other.srcColor
++ && dstColor == other.dstColor
++ && opColor == other.opColor
++ && srcAlpha == other.srcAlpha
++ && dstAlpha == other.dstAlpha
++ && opAlpha == other.opAlpha;
++ }
++
++ QQuick3DRenderPassTargetBlend() = default;
++ QQuick3DRenderPassTargetBlend(QRhiGraphicsPipeline::TargetBlend targetBlend)
++ : colorWrite(ColorMask(targetBlend.colorWrite.toInt()))
++ , enable(targetBlend.enable)
++ , srcColor(BlendFactor(targetBlend.srcColor))
++ , dstColor(BlendFactor(targetBlend.dstColor))
++ , opColor(BlendOperation(targetBlend.opColor))
++ , srcAlpha(BlendFactor(targetBlend.srcAlpha))
++ , dstAlpha(BlendFactor(targetBlend.dstAlpha))
++ , opAlpha(BlendOperation(targetBlend.opAlpha))
++ {
++ }
++
++ QRhiGraphicsPipeline::TargetBlend toRhiTargetBlend() const
++ {
++ QRhiGraphicsPipeline::TargetBlend tb;
++ tb.colorWrite = QRhiGraphicsPipeline::ColorMask(colorWrite.toInt());
++ tb.enable = enable;
++ tb.srcColor = QRhiGraphicsPipeline::BlendFactor(int(srcColor));
++ tb.dstColor = QRhiGraphicsPipeline::BlendFactor(int(dstColor));
++ tb.opColor = QRhiGraphicsPipeline::BlendOp(int(opColor));
++ tb.srcAlpha = QRhiGraphicsPipeline::BlendFactor(int(srcAlpha));
++ tb.dstAlpha = QRhiGraphicsPipeline::BlendFactor(int(dstAlpha));
++ tb.opAlpha = QRhiGraphicsPipeline::BlendOp(int(opAlpha));
++ return tb;
++ }
++ };
++
++ namespace QQuick3DRenderTargetBlendForeign
++ {
++ Q_NAMESPACE_EXPORT(Q_QUICK3D_EXPORT)
++ QML_FOREIGN_NAMESPACE(QQuick3DRenderPassTargetBlend)
++ QML_NAMED_ELEMENT(RenderTargetBlend)
++ QML_ADDED_IN_VERSION(6, 11)
++ }
++
++ class Q_QUICK3D_EXPORT QQuick3DShaderUtilsPipelineStateOverride : public QQuick3DShaderUtilsRenderCommand
++ {
++ Q_OBJECT
++ Q_PROPERTY(bool depthTestEnabled READ depthTestEnabled WRITE setDepthTestEnabled RESET resetDepthTestEnabled NOTIFY depthTestEnabledChanged)
++ Q_PROPERTY(bool depthWriteEnabled READ depthWriteEnabled WRITE setDepthWriteEnabled RESET resetDepthWriteEnabled NOTIFY depthWriteEnabledChanged)
++ Q_PROPERTY(bool blendEnabled READ blendEnabled WRITE setBlendEnabled RESET resetBlendEnabled NOTIFY blendEnabledChanged FINAL)
++ Q_PROPERTY(bool usesStencilReference READ usesStencilReference WRITE setUsesStencilReference RESET resetUsesStencilReference NOTIFY usesStencilReferenceChanged)
++ Q_PROPERTY(bool usesScissor READ usesScissor WRITE setUsesScissor RESET resetUsesScissor NOTIFY usesScissorChanged)
++ Q_PROPERTY(CompareOperation depthFunction READ depthFunction WRITE setDepthFunction RESET resetDepthFunction NOTIFY depthFunctionChanged)
++ Q_PROPERTY(CullMode cullMode READ cullMode WRITE setCullMode RESET resetCullMode NOTIFY cullModeChanged)
++ Q_PROPERTY(PolygonMode polygonMode READ polygonMode WRITE setPolygonMode RESET resetPolygonMode NOTIFY polygonModeChanged)
++ Q_PROPERTY(quint32 stencilWriteMask READ stencilWriteMask WRITE setStencilWriteMask RESET resetStencilWriteMask NOTIFY stencilWriteMaskChanged)
++ Q_PROPERTY(quint32 stencilReference READ stencilReference WRITE setStencilReference RESET resetStencilReference NOTIFY stencilReferenceChanged)
++ Q_PROPERTY(QRectF viewport READ viewport WRITE setViewport RESET resetViewport NOTIFY viewportChanged)
++ Q_PROPERTY(QRect scissor READ scissor WRITE setScissor RESET resetScissor NOTIFY scissorChanged)
++ Q_PROPERTY(QQuick3DRenderPassTargetBlend targetBlend0 READ targetBlend0 WRITE setTargetBlend0 RESET resetTargetBlend0 NOTIFY targetBlend0Changed)
++ Q_PROPERTY(QQuick3DRenderPassTargetBlend targetBlend1 READ targetBlend1 WRITE setTargetBlend1 RESET resetTargetBlend1 NOTIFY targetBlend1Changed)
++ Q_PROPERTY(QQuick3DRenderPassTargetBlend targetBlend2 READ targetBlend2 WRITE setTargetBlend2 RESET resetTargetBlend2 NOTIFY targetBlend2Changed)
++ Q_PROPERTY(QQuick3DRenderPassTargetBlend targetBlend3 READ targetBlend3 WRITE setTargetBlend3 RESET resetTargetBlend3 NOTIFY targetBlend3Changed)
++ Q_PROPERTY(QQuick3DRenderPassTargetBlend targetBlend4 READ targetBlend4 WRITE setTargetBlend4 RESET resetTargetBlend4 NOTIFY targetBlend4Changed)
++ Q_PROPERTY(QQuick3DRenderPassTargetBlend targetBlend5 READ targetBlend5 WRITE setTargetBlend5 RESET resetTargetBlend5 NOTIFY targetBlend5Changed)
++ Q_PROPERTY(QQuick3DRenderPassTargetBlend targetBlend6 READ targetBlend6 WRITE setTargetBlend6 RESET resetTargetBlend6 NOTIFY targetBlend6Changed)
++ Q_PROPERTY(QQuick3DRenderPassTargetBlend targetBlend7 READ targetBlend7 WRITE setTargetBlend7 RESET resetTargetBlend7 NOTIFY targetBlend7Changed)
++ QML_NAMED_ELEMENT(PipelineStateOverride)
++ QML_ADDED_IN_VERSION(6, 11)
++
++ public:
++ enum class CompareOperation {
++ Never,
++ Less,
++ Equal,
++ LessOrEqual,
++ Greater,
++ NotEqual,
++ GreaterOrEqual,
++ Always
++ };
++ Q_ENUM(CompareOperation)
++
++ enum class CullMode {
++ None,
++ Front,
++ Back
++ };
++ Q_ENUM(CullMode)
++
++ enum class PolygonMode {
++ Fill,
++ Line
++ };
++ Q_ENUM(PolygonMode)
++
++ QQuick3DShaderUtilsPipelineStateOverride();
++ ~QQuick3DShaderUtilsPipelineStateOverride() override;
++
++ bool depthTestEnabled() const;
++ void setDepthTestEnabled(bool newDepthTestEnabled);
++ void resetDepthTestEnabled();
++ bool depthWriteEnabled() const;
++ void setDepthWriteEnabled(bool newDepthWriteEnabled);
++ void resetDepthWriteEnabled();
++
++ bool blendEnabled() const;
++ void setBlendEnabled(bool newBlendEnabled);
++ void resetBlendEnabled();
++
++ bool usesStencilReference() const;
++ void setUsesStencilReference(bool newUsesStencilReference);
++ void resetUsesStencilReference();
++
++ bool usesScissor() const;
++ void setUsesScissor(bool newUsesScissor);
++ void resetUsesScissor();
++
++ CompareOperation depthFunction() const;
++ void setDepthFunction(CompareOperation newDepthFunction);
++ void resetDepthFunction();
++
++ CullMode cullMode() const;
++ void setCullMode(CullMode newCullMode);
++ void resetCullMode();
++
++ PolygonMode polygonMode() const;
++ void setPolygonMode(PolygonMode newPolygonMode);
++ void resetPolygonMode();
++
++ quint32 stencilWriteMask() const;
++ void setStencilWriteMask(quint32 newStencilWriteMask);
++ void resetStencilWriteMask();
++
++ quint32 stencilReference() const;
++ void setStencilReference(quint32 newStencilReference);
++ void resetStencilReference();
++
++ QRectF viewport() const;
++ void setViewport(const QRectF &newViewport);
++ void resetViewport();
++
++ QRect scissor() const;
++ void setScissor(const QRect &newScissor);
++ void resetScissor();
++
++ QQuick3DRenderPassTargetBlend targetBlend0() const;
++ void setTargetBlend0(const QQuick3DRenderPassTargetBlend &newTargetBlend0);
++ void resetTargetBlend0();
++
++ QQuick3DRenderPassTargetBlend targetBlend1() const;
++ void setTargetBlend1(const QQuick3DRenderPassTargetBlend &newTargetBlend1);
++ void resetTargetBlend1();
++
++ QQuick3DRenderPassTargetBlend targetBlend2() const;
++ void setTargetBlend2(const QQuick3DRenderPassTargetBlend &newTargetBlend2);
++ void resetTargetBlend2();
++
++ QQuick3DRenderPassTargetBlend targetBlend3() const;
++ void setTargetBlend3(const QQuick3DRenderPassTargetBlend &newTargetBlend3);
++ void resetTargetBlend3();
++
++ QQuick3DRenderPassTargetBlend targetBlend4() const;
++ void setTargetBlend4(const QQuick3DRenderPassTargetBlend &newTargetBlend4);
++ void resetTargetBlend4();
++
++ QQuick3DRenderPassTargetBlend targetBlend5() const;
++ void setTargetBlend5(const QQuick3DRenderPassTargetBlend &newTargetBlend5);
++ void resetTargetBlend5();
++
++ QQuick3DRenderPassTargetBlend targetBlend6() const;
++ void setTargetBlend6(const QQuick3DRenderPassTargetBlend &newTargetBlend6);
++ void resetTargetBlend6();
++
++ QQuick3DRenderPassTargetBlend targetBlend7() const;
++ void setTargetBlend7(const QQuick3DRenderPassTargetBlend &newTargetBlend7);
++ void resetTargetBlend7();
++
++ Q_SIGNALS:
++ void depthTestEnabledChanged();
++ void depthWriteEnabledChanged();
++ void blendEnabledChanged();
++ void usesStencilReferenceChanged();
++ void usesScissorChanged();
++ void depthFunctionChanged();
++ void cullModeChanged();
++ void polygonModeChanged();
++ void stencilWriteMaskChanged();
++ void stencilReferenceChanged();
++ void viewportChanged();
++ void scissorChanged();
++ void targetBlend0Changed();
++ void targetBlend1Changed();
++ void targetBlend2Changed();
++ void targetBlend3Changed();
++ void targetBlend4Changed();
++ void targetBlend5Changed();
++ void targetBlend6Changed();
++ void targetBlend7Changed();
++
++ private:
++ QSSGCommand *cloneCommand() override { return new QSSGPipelineStateOverrideCommand(command); }
++ QSSGPipelineStateOverrideCommand command { };
++ };
++
++
++ class Q_QUICK3D_EXPORT QQuick3DShaderUtilsApplyValue : public QQuick3DShaderUtilsRenderCommand
++ {
++ Q_OBJECT
++ Q_PROPERTY(QByteArray target MEMBER target)
++ Q_PROPERTY(QVariant value MEMBER value)
++
++ QML_NAMED_ELEMENT(SetUniformValue)
++
++ public:
++ QQuick3DShaderUtilsApplyValue() = default;
++ ~QQuick3DShaderUtilsApplyValue() override = default;
++ QSSGCommand *cloneCommand() override { return new QSSGApplyValue(command); }
++ QSSGApplyValue command { };
++ QVariant &value = command.m_value;
++ QByteArray &target = command.m_propertyName;
++ };
++
++ class Q_QUICK3D_EXPORT QQuick3DShaderUtilsRenderablesFilter : public QQuick3DShaderUtilsRenderCommand
++ {
++ Q_OBJECT
++
++ Q_PROPERTY(quint32 layerMask MEMBER layerMask)
++ Q_PROPERTY(RenderableTypes renderableTypes READ renderableTypes WRITE setRenderableTypes)
++ QML_NAMED_ELEMENT(RenderablesFilter)
++ QML_ADDED_IN_VERSION(6, 11)
++
++ public:
++ enum class RenderableType : quint32 {
++ None = 0x0,
++ Opaque = 0x1,
++ Transparent = 0x2,
++ };
++ Q_DECLARE_FLAGS(RenderableTypes, RenderableType)
++ Q_FLAG(RenderableTypes)
++
++ QQuick3DShaderUtilsRenderablesFilter() = default;
++ ~QQuick3DShaderUtilsRenderablesFilter() override;
++
++ RenderableTypes renderableTypes() const;
++ void setRenderableTypes(RenderableTypes types);
++
++ QSSGCommand *cloneCommand() override { return new QSSGRenderablesFilterCommand(command); }
++ QSSGRenderablesFilterCommand command { };
++
++ quint32 &layerMask = command.layerMask;
++ };
++
++ class Q_QUICK3D_EXPORT QQuick3DShaderUtilsRenderPassTexture : public QQuick3DObject
++ {
++ Q_OBJECT
++ Q_PROPERTY(TextureFormat format READ format WRITE setFormat FINAL)
++ QML_NAMED_ELEMENT(RenderPassTexture)
++ QML_ADDED_IN_VERSION(6, 11)
++
++ public:
++ enum class TextureFormat {
++ Unknown = 0,
++ RGBA8,
++ RGBA16F,
++ RGBA32F,
++ R8,
++ R16,
++ R16F,
++ R32F,
++ Depth16,
++ Depth24,
++ Depth32,
++ Depth24Stencil8,
++ };
++ Q_ENUM(TextureFormat)
++
++ QQuick3DShaderUtilsRenderPassTexture() = default;
++ ~QQuick3DShaderUtilsRenderPassTexture() override;
++
++ TextureFormat format() const;
++ void setFormat(TextureFormat newFormat);
++
++ std::shared_ptr<QSSGAllocateTexture> command;
++
++ private:
++ friend class QQuick3DShaderUtilsRenderPassColorAttachment;
++ friend class QQuick3DShaderUtilsRenderPassDepthTextureAttachment;
++
++
++ private:
++ static QSSGRenderTextureFormat asRenderTextureFormat(QQuick3DShaderUtilsRenderPassTexture::TextureFormat fmt);
++ static QQuick3DShaderUtilsRenderPassTexture::TextureFormat fromRenderTextureFormat(QSSGRenderTextureFormat fmt);
++ };
++
++ // Class for user defined color attachments in render passes
++ class Q_QUICK3D_EXPORT QQuick3DShaderUtilsRenderPassColorAttachment : public QQuick3DShaderUtilsRenderCommand
++ {
++ Q_OBJECT
++ Q_PROPERTY(QQuick3DShaderUtilsRenderPassTexture *target MEMBER target)
++ Q_PROPERTY(QByteArray name READ name WRITE setName FINAL)
++ QML_NAMED_ELEMENT(ColorAttachment)
++ QML_ADDED_IN_VERSION(6, 11)
++
++ public:
++ QQuick3DShaderUtilsRenderPassColorAttachment() = default;
++ ~QQuick3DShaderUtilsRenderPassColorAttachment() override;
++
++ QByteArray name() const;
++ void setName(const QByteArray &newName);
++
++ QSSGCommand *cloneCommand() override;
++
++ private:
++ QPointer<QQuick3DShaderUtilsRenderPassTexture> target;
++ QByteArray m_name;
++ };
++
++ class Q_QUICK3D_EXPORT QQuick3DShaderUtilsRenderPassDepthTextureAttachment : public QQuick3DShaderUtilsRenderCommand
++ {
++ Q_OBJECT
++ Q_PROPERTY(QQuick3DShaderUtilsRenderPassTexture *target MEMBER target)
++ QML_NAMED_ELEMENT(DepthTextureAttachment)
++ QML_ADDED_IN_VERSION(6, 11)
++
++ public:
++ QQuick3DShaderUtilsRenderPassDepthTextureAttachment() = default;
++ ~QQuick3DShaderUtilsRenderPassDepthTextureAttachment() override;
++
++ QSSGCommand *cloneCommand() override;
++
++ QPointer<QQuick3DShaderUtilsRenderPassTexture> target;
++ };
++
++ class Q_QUICK3D_EXPORT QQuick3DShaderUtilsRenderPassDepthStencilAttachment : public QQuick3DShaderUtilsRenderCommand
++ {
++ Q_OBJECT
++ QML_NAMED_ELEMENT(DepthStencilAttachment)
++ QML_ADDED_IN_VERSION(6, 11)
++
++ public:
++ QQuick3DShaderUtilsRenderPassDepthStencilAttachment() = default;
++ ~QQuick3DShaderUtilsRenderPassDepthStencilAttachment() override;
++
++ QSSGCommand *cloneCommand() override;
++
++ };
++
++ class Q_QUICK3D_EXPORT QQuick3DShaderUtilsRenderPassAddDefine : public QQuick3DShaderUtilsRenderCommand
++ {
++ Q_OBJECT
++ Q_PROPERTY(QByteArray name READ name WRITE setName NOTIFY nameChanged)
++ Q_PROPERTY(int value READ value WRITE setValue NOTIFY valueChanged)
++ QML_NAMED_ELEMENT(AddDefine)
++ QML_ADDED_IN_VERSION(6, 11)
++
++ public:
++ QQuick3DShaderUtilsRenderPassAddDefine();
++ ~QQuick3DShaderUtilsRenderPassAddDefine() override;
++
++ QSSGCommand *cloneCommand() override;
++
++ QByteArray name() const;
++ void setName(const QByteArray &newName);
++
++ int value() const;
++ void setValue(int newValue);
++
++ QSSGAddShaderDefine command;
++
++ Q_SIGNALS:
++ void nameChanged();
++ void valueChanged();
++ };
++
++ class Q_QUICK3D_EXPORT QQuick3DShaderUtilsSubRenderPass : public QQuick3DShaderUtilsRenderCommand
++ {
++ Q_OBJECT
++ Q_PROPERTY(QQuick3DRenderPass *renderPass READ renderPass WRITE setRenderPass NOTIFY renderPassChanged FINAL)
++ QML_NAMED_ELEMENT(SubRenderPass)
++ QML_ADDED_IN_VERSION(6, 11)
++
++ public:
++ QQuick3DShaderUtilsSubRenderPass() = default;
++ ~QQuick3DShaderUtilsSubRenderPass() override;
++
++ QQuick3DRenderPass *renderPass() const;
++ void setRenderPass(QQuick3DRenderPass *newRenderPass);
++
++ QSSGCommand *cloneCommand() override;
++
++ signals:
++ void renderPassChanged();
++
++ protected:
++ virtual QSSGRenderGraphObject *updateSpatialNode(QSSGRenderGraphObject *node) final;
++ virtual void itemChange(ItemChange change, const ItemChangeData &value) final;
++
++ private:
++ void updateSceneManager(QQuick3DSceneManager *sceneManager);
++
++ QPointer<QQuick3DRenderPass> m_renderPass;
++ mutable bool m_hasWarnedAboutInvalidId = false;
++ };
++
++ class Q_QUICK3D_EXPORT QQuick3DShaderUtilsRenderPass : public QQuick3DObject
++ {
++ Q_OBJECT
++ Q_PROPERTY(QQmlListProperty<QQuick3DShaderUtilsRenderCommand> commands READ commands)
++ Q_PROPERTY(QQuick3DShaderUtilsBuffer *output MEMBER outputBuffer)
++ Q_PROPERTY(QQmlListProperty<QQuick3DShaderUtilsShader> shaders READ shaders)
++ QML_NAMED_ELEMENT(Pass)
++ QML_ADDED_IN_VERSION(6, 11)
++
++ public:
++ QQuick3DShaderUtilsRenderPass() = default;
++ ~QQuick3DShaderUtilsRenderPass() override;
++
++ static void qmlAppendCommand(QQmlListProperty<QQuick3DShaderUtilsRenderCommand> *list, QQuick3DShaderUtilsRenderCommand *command);
++ static QQuick3DShaderUtilsRenderCommand *qmlCommandAt(QQmlListProperty<QQuick3DShaderUtilsRenderCommand> *list, qsizetype index);
++ static qsizetype qmlCommandCount(QQmlListProperty<QQuick3DShaderUtilsRenderCommand> *list);
++ static void qmlCommandClear(QQmlListProperty<QQuick3DShaderUtilsRenderCommand> *list);
++
++ static void qmlAppendShader(QQmlListProperty<QQuick3DShaderUtilsShader> *list, QQuick3DShaderUtilsShader *shader);
++ static QQuick3DShaderUtilsShader *qmlShaderAt(QQmlListProperty<QQuick3DShaderUtilsShader> *list, qsizetype index);
++ static qsizetype qmlShaderCount(QQmlListProperty<QQuick3DShaderUtilsShader> *list);
++ static void qmlShaderClear(QQmlListProperty<QQuick3DShaderUtilsShader> *list);
++
++ QQmlListProperty<QQuick3DShaderUtilsRenderCommand> commands();
++ QVector<QQuick3DShaderUtilsRenderCommand *> m_commands;
++ QQuick3DShaderUtilsBuffer *outputBuffer = nullptr;
++ QQmlListProperty<QQuick3DShaderUtilsShader> shaders();
++ QVarLengthArray<QQuick3DShaderUtilsShader *, 2> m_shaders;
++
++ Q_SIGNALS:
++ void changed();
++ };
++
++ class Q_QUICK3D_EXPORT QQuick3DShaderUtilsShader : public QQuick3DObject
++ {
++ Q_OBJECT
++ Q_PROPERTY(QUrl shader MEMBER shader NOTIFY shaderChanged)
++ Q_PROPERTY(Stage stage MEMBER stage NOTIFY stageChanged)
++
++ QML_NAMED_ELEMENT(Shader)
++
++ public:
++ QQuick3DShaderUtilsShader() = default;
++ virtual ~QQuick3DShaderUtilsShader() = default;
++ enum class Stage : quint8
++ {
++ Vertex = 0,
++ Fragment = 1
++ };
++ Q_ENUM(Stage)
++
++ QUrl shader;
++ Stage stage = Stage::Fragment;
++
++ Q_SIGNALS:
++ void shaderChanged();
++ void stageChanged();
++ };
++
++ template<typename T, typename std::enable_if_t<std::is_base_of_v<QQuick3DObject, T>, bool> = true>
++ class QQuick3DSuperClassInfo
++ {
++ public:
++ QQuick3DSuperClassInfo() = default;
++
++ static const char *superClassName()
++ {
++ return T::staticMetaObject.className();
++ }
++ };
++
++ class QQuick3DPropertyChangedTracker;
++
++ class QQuick3DPropertyWatcher : public QObject
++ {
++ Q_OBJECT
++ public:
++ QQuick3DPropertyWatcher(QQuick3DPropertyChangedTracker *tracker, QMetaProperty property);
++
++ public Q_SLOTS:
++ void onValuePropertyChanged();
++ void onPointerPropertyChanged();
++
++ private:
++ QQuick3DPropertyChangedTracker *m_tracker = nullptr;
++ QMetaProperty m_property;
++ };
++
++ class Q_QUICK3D_EXPORT QQuick3DPropertyChangedTracker
++ {
++ public:
++ enum class DirtyPropertyHint
++ {
++ Value,
++ Reference,
++ };
++
++ template<typename T>
++ explicit QQuick3DPropertyChangedTracker(QQuick3DObject *owner, QQuick3DSuperClassInfo<T> info)
++ : m_owner(owner)
++ , m_superClassName(info.superClassName())
++ {
++ Q_ASSERT(m_owner != nullptr);
++ }
++ virtual ~QQuick3DPropertyChangedTracker();
++
++ using UniformProperty = QSSGUserShaderAugmentation::Property;
++ using UniformPropertyList = QVector<UniformProperty>;
++ protected:
++ friend class QQuick3DPropertyWatcher;
++
++ // Will re-use already extracted list and update dirty properties
++ QList<UniformProperty> extractProperties();
++
++ void addPropertyWatcher(QMetaProperty property, DirtyPropertyHint hint, QQuick3DObject *object = nullptr);
++
++ virtual void markTrackedPropertyDirty(QMetaProperty property, DirtyPropertyHint hint) = 0;
++
++ struct Tracked
++ {
++ QQuick3DPropertyWatcher *watcher = nullptr;
++ QPointer<QQuick3DObject> object;
++ int pid = -1;
++ };
++
++ QHash<int, Tracked> m_trackedProperties;
++ QQuick3DObject *m_owner = nullptr;
++ const char *m_superClassName = nullptr;
++ QList<UniformProperty> m_propertyList; // always sorted by propertyIndex
++
++ private:
++ std::optional<UniformProperty> createOrUpdateTrackedProperty(const QMetaProperty property, bool addWatchers);
++ std::vector<int> m_dirtyProperties;
++ bool m_extracted = false;
++ };
++
++ QT_END_NAMESPACE
++
++ Q_DECLARE_OPAQUE_POINTER(QQuick3DShaderUtilsTextureInput)
++
++ #endif // QQUICK3DSHADERUTILS_H