1 /****************************************************************************
2 **
3 ** Copyright (C) 2008-2012 NVIDIA Corporation.
4 ** Copyright (C) 2019 The Qt Company Ltd.
5 ** Contact: https://www.qt.io/licensing/
6 **
7 ** This file is part of Qt Quick 3D.
8 **
9 ** $QT_BEGIN_LICENSE:GPL$
10 ** Commercial License Usage
11 ** Licensees holding valid commercial Qt licenses may use this file in
12 ** accordance with the commercial license agreement provided with the
13 ** Software or, alternatively, in accordance with the terms contained in
14 ** a written agreement between you and The Qt Company. For licensing terms
15 ** and conditions see https://www.qt.io/terms-conditions. For further
16 ** information use the contact form at https://www.qt.io/contact-us.
17 **
18 ** GNU General Public License Usage
19 ** Alternatively, this file may be used under the terms of the GNU
20 ** General Public License version 3 or (at your option) any later version
21 ** approved by the KDE Free Qt Foundation. The licenses are as published by
22 ** the Free Software Foundation and appearing in the file LICENSE.GPL3
23 ** included in the packaging of this file. Please review the following
24 ** information to ensure the GNU General Public License requirements will
25 ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
26 **
27 ** $QT_END_LICENSE$
28 **
29 ****************************************************************************/
30 
31 #ifndef QSSG_RENDER_EFFECT_SYSTEM_COMMANDS_H
32 #define QSSG_RENDER_EFFECT_SYSTEM_COMMANDS_H
33 
34 //
35 //  W A R N I N G
36 //  -------------
37 //
38 // This file is not part of the Qt API.  It exists purely as an
39 // implementation detail.  This header file may change from version to
40 // version without notice, or even be removed.
41 //
42 // We mean it.
43 //
44 
45 #include <QtQuick3DRender/private/qssgrenderbasetypes_p.h>
46 
47 QT_BEGIN_NAMESPACE
48 namespace dynamic {
49 
50 enum class CommandType
51 {
52     Unknown = 0,
53     AllocateBuffer,
54     BindTarget,
55     BindBuffer,
56     BindShader,
57     ApplyInstanceValue,
58     ApplyBufferValue,
59     // Apply the depth buffer as an input texture.
60     ApplyDepthValue,
61     Render, // Render to current FBO
62     ApplyBlending,
63     ApplyRenderState, // apply a render state
64     ApplyBlitFramebuffer,
65     ApplyValue,
66     DepthStencil,
67     AllocateImage,
68     ApplyImageValue,
69     AllocateDataBuffer,
70     ApplyDataBufferValue,
71     ApplyCullMode,
72 };
73 
74 // All commands need at least two constructors.  One for when they are created that should
75 // setup all their member variables and one for when we are copying commands from an outside
76 // entity into the effect system.  We have to re-register strings in that case because we
77 // can't assume the outside entity was using the same string table we are...
78 struct QSSGCommand
79 {
80     CommandType m_type;
QSSGCommandQSSGCommand81     QSSGCommand(CommandType inType) : m_type(inType) {}
QSSGCommandQSSGCommand82     QSSGCommand() : m_type(CommandType::Unknown) {}
83     // Implemented in UICRenderEffectSystem.cpp
84 //    static quint32 getSizeofCommand(const QSSGCommand &inCommand);
85 //    static void copyConstructCommand(quint8 *inDataBuffer, const QSSGCommand &inCommand);
86 };
87 
88 enum class AllocateBufferFlagValues
89 {
90     None = 0,
91     SceneLifetime = 1,
92 };
93 
94 struct QSSGAllocateBufferFlags : public QFlags<AllocateBufferFlagValues>
95 {
QSSGAllocateBufferFlagsQSSGAllocateBufferFlags96     QSSGAllocateBufferFlags(quint32 inValues) : QFlags(inValues) {}
QSSGAllocateBufferFlagsQSSGAllocateBufferFlags97     QSSGAllocateBufferFlags() {}
setSceneLifetimeQSSGAllocateBufferFlags98     void setSceneLifetime(bool inValue) { setFlag(AllocateBufferFlagValues::SceneLifetime, inValue); }
99     // If isSceneLifetime is unset the buffer is assumed to be frame lifetime and will be
100     // released after this render operation.
isSceneLifetimeQSSGAllocateBufferFlags101     bool isSceneLifetime() const { return this->operator&(AllocateBufferFlagValues::SceneLifetime); }
102 };
103 
104 struct QSSGAllocateBuffer : public QSSGCommand
105 {
106     QByteArray m_name;
107     QSSGRenderTextureFormat m_format = QSSGRenderTextureFormat::RGBA8;
108     QSSGRenderTextureMagnifyingOp m_filterOp = QSSGRenderTextureMagnifyingOp::Linear;
109     QSSGRenderTextureCoordOp m_texCoordOp = QSSGRenderTextureCoordOp::ClampToEdge;
110     float m_sizeMultiplier = 1.0f;
111     QSSGAllocateBufferFlags m_bufferFlags;
QSSGAllocateBufferQSSGAllocateBuffer112     QSSGAllocateBuffer() : QSSGCommand(CommandType::AllocateBuffer) {}
QSSGAllocateBufferQSSGAllocateBuffer113     QSSGAllocateBuffer(const QByteArray &inName,
114                          QSSGRenderTextureFormat inFormat,
115                          QSSGRenderTextureMagnifyingOp inFilterOp,
116                          QSSGRenderTextureCoordOp inCoordOp,
117                          float inMultiplier,
118                          QSSGAllocateBufferFlags inFlags)
119         : QSSGCommand(CommandType::AllocateBuffer)
120         , m_name(inName)
121         , m_format(inFormat)
122         , m_filterOp(inFilterOp)
123         , m_texCoordOp(inCoordOp)
124         , m_sizeMultiplier(inMultiplier)
125         , m_bufferFlags(inFlags)
126     {
127     }
QSSGAllocateBufferQSSGAllocateBuffer128     QSSGAllocateBuffer(const QSSGAllocateBuffer &inOther)
129         : QSSGCommand(CommandType::AllocateBuffer)
130         , m_name(inOther.m_name)
131         , m_format(inOther.m_format)
132         , m_filterOp(inOther.m_filterOp)
133         , m_texCoordOp(inOther.m_texCoordOp)
134         , m_sizeMultiplier(inOther.m_sizeMultiplier)
135         , m_bufferFlags(inOther.m_bufferFlags)
136     {
137     }
138 };
139 
140 struct QSSGAllocateImage : public QSSGAllocateBuffer
141 {
142     QSSGRenderImageAccessType m_access = QSSGRenderImageAccessType::ReadWrite;
143 
QSSGAllocateImageQSSGAllocateImage144     QSSGAllocateImage() : QSSGAllocateBuffer() { m_type = CommandType::AllocateImage; }
QSSGAllocateImageQSSGAllocateImage145     QSSGAllocateImage(QByteArray &inName,
146                         QSSGRenderTextureFormat inFormat,
147                         QSSGRenderTextureMagnifyingOp inFilterOp,
148                         QSSGRenderTextureCoordOp inCoordOp,
149                         float inMultiplier,
150                         QSSGAllocateBufferFlags inFlags,
151                         QSSGRenderImageAccessType inAccess)
152         : QSSGAllocateBuffer(inName, inFormat, inFilterOp, inCoordOp, inMultiplier, inFlags), m_access(inAccess)
153     {
154         m_type = CommandType::AllocateImage;
155     }
156 
QSSGAllocateImageQSSGAllocateImage157     QSSGAllocateImage(const QSSGAllocateImage &inOther)
158         : QSSGAllocateBuffer(inOther.m_name, inOther.m_format, inOther.m_filterOp, inOther.m_texCoordOp, inOther.m_sizeMultiplier, inOther.m_bufferFlags)
159         , m_access(inOther.m_access)
160     {
161         m_type = CommandType::AllocateImage;
162     }
163 };
164 
165 struct QSSGAllocateDataBuffer : public QSSGCommand
166 {
167     QByteArray m_name;
168     QSSGRenderBufferType m_dataBufferType;
169     QByteArray m_wrapName;
170     QSSGRenderBufferType m_dataBufferWrapType;
171     float m_size;
172     QSSGAllocateBufferFlags m_bufferFlags;
173 
QSSGAllocateDataBufferQSSGAllocateDataBuffer174     QSSGAllocateDataBuffer() : QSSGCommand(CommandType::AllocateDataBuffer) {}
175 
QSSGAllocateDataBufferQSSGAllocateDataBuffer176     QSSGAllocateDataBuffer(const QByteArray &inName,
177                              QSSGRenderBufferType inBufferType,
178                              const QByteArray &inWrapName,
179                              QSSGRenderBufferType inBufferWrapType,
180                              float inSize,
181                              QSSGAllocateBufferFlags inFlags)
182         : QSSGCommand(CommandType::AllocateDataBuffer)
183         , m_name(inName)
184         , m_dataBufferType(inBufferType)
185         , m_wrapName(inWrapName)
186         , m_dataBufferWrapType(inBufferWrapType)
187         , m_size(inSize)
188         , m_bufferFlags(inFlags)
189     {
190     }
191 
QSSGAllocateDataBufferQSSGAllocateDataBuffer192     QSSGAllocateDataBuffer(const QSSGAllocateDataBuffer &inOther)
193         : QSSGCommand(CommandType::AllocateDataBuffer)
194         , m_name(inOther.m_name)
195         , m_dataBufferType(inOther.m_dataBufferType)
196         , m_wrapName(inOther.m_wrapName)
197         , m_dataBufferWrapType(inOther.m_dataBufferWrapType)
198         , m_size(inOther.m_size)
199         , m_bufferFlags(inOther.m_bufferFlags)
200     {
201     }
202 };
203 
204 struct QSSGBindTarget : public QSSGCommand
205 {
206     QSSGRenderTextureFormat m_outputFormat;
207 
208     explicit QSSGBindTarget(QSSGRenderTextureFormat inFormat = QSSGRenderTextureFormat::RGBA8)
QSSGCommandQSSGBindTarget209         : QSSGCommand(CommandType::BindTarget), m_outputFormat(inFormat)
210     {
211     }
QSSGBindTargetQSSGBindTarget212     QSSGBindTarget(const QSSGBindTarget &inOther)
213         : QSSGCommand(CommandType::BindTarget), m_outputFormat(inOther.m_outputFormat)
214     {
215     }
216 };
217 
218 struct QSSGBindBuffer : public QSSGCommand
219 {
220     QByteArray m_bufferName;
221     bool m_needsClear;
QSSGBindBufferQSSGBindBuffer222     QSSGBindBuffer(const QByteArray &inBufName, bool inNeedsClear)
223         : QSSGCommand(CommandType::BindBuffer), m_bufferName(inBufName), m_needsClear(inNeedsClear)
224     {
225     }
QSSGBindBufferQSSGBindBuffer226     QSSGBindBuffer(const QSSGBindBuffer &inOther)
227         : QSSGCommand(CommandType::BindBuffer), m_bufferName(inOther.m_bufferName), m_needsClear(inOther.m_needsClear)
228     {
229     }
230 };
231 
232 struct QSSGBindShader : public QSSGCommand
233 {
234     QByteArray m_shaderPath;
235     // One GLSL file can hold multiple shaders in the case of multipass effects.
236     // This makes it significantly easier for authors to reason about the shader
237     // but it means we need to #define a preprocessor token to indicate which
238     // effect we intend to compile at this point.
239     QByteArray m_shaderDefine;
240     QSSGBindShader(const QByteArray &inShaderPath, const QByteArray &inShaderDefine = QByteArray())
QSSGCommandQSSGBindShader241         : QSSGCommand(CommandType::BindShader), m_shaderPath(inShaderPath), m_shaderDefine(inShaderDefine)
242     {
243     }
QSSGBindShaderQSSGBindShader244     QSSGBindShader() : QSSGCommand(CommandType::BindShader) {}
QSSGBindShaderQSSGBindShader245     QSSGBindShader(const QSSGBindShader &inOther)
246         : QSSGCommand(CommandType::BindShader), m_shaderPath(inOther.m_shaderPath), m_shaderDefine(inOther.m_shaderDefine)
247     {
248     }
249 };
250 
251 // The value sits immediately after the 'this' object
252 // in memory.
253 // If propertyName is not valid then we attempt to apply all of the effect property values
254 // to the shader, ignoring ones that don't match up.
255 struct QSSGApplyInstanceValue : public QSSGCommand
256 {
257     // Name of value to apply in shader
258     QByteArray m_propertyName;
259     // type of value
260     QSSGRenderShaderDataType m_valueType;
261     // offset in the effect data section of value.
262     quint32 m_valueOffset;
QSSGApplyInstanceValueQSSGApplyInstanceValue263     QSSGApplyInstanceValue(const QByteArray &inName, QSSGRenderShaderDataType inValueType, quint32 inValueOffset)
264         : QSSGCommand(CommandType::ApplyInstanceValue), m_propertyName(inName), m_valueType(inValueType), m_valueOffset(inValueOffset)
265     {
266     }
267     // Default will attempt to apply all effect values to the currently bound shader
QSSGApplyInstanceValueQSSGApplyInstanceValue268     QSSGApplyInstanceValue()
269         : QSSGCommand(CommandType::ApplyInstanceValue), m_valueType(QSSGRenderShaderDataType::Unknown), m_valueOffset(0)
270     {
271     }
QSSGApplyInstanceValueQSSGApplyInstanceValue272     QSSGApplyInstanceValue(const QSSGApplyInstanceValue &inOther)
273         : QSSGCommand(CommandType::ApplyInstanceValue)
274         , m_propertyName(inOther.m_propertyName)
275         , m_valueType(inOther.m_valueType)
276         , m_valueOffset(inOther.m_valueOffset)
277     {
278     }
279 };
280 
281 struct QSSGApplyValue : public QSSGCommand
282 {
283     QByteArray m_propertyName;
284     QVariant m_value;
QSSGApplyValueQSSGApplyValue285     explicit QSSGApplyValue(const QByteArray &inName)
286         : QSSGCommand(CommandType::ApplyValue), m_propertyName(inName)
287     {
288     }
289     // Default will attempt to apply all effect values to the currently bound shader
QSSGApplyValueQSSGApplyValue290     QSSGApplyValue() : QSSGCommand(CommandType::ApplyValue) {}
291 
QSSGApplyValueQSSGApplyValue292     QSSGApplyValue(const QSSGApplyValue &inOther)
293         : QSSGCommand(CommandType::ApplyValue)
294         , m_propertyName(inOther.m_propertyName)
295         , m_value(inOther.m_value)
296     {
297     }
298 };
299 
300 // bind a buffer to a given shader parameter.
301 struct QSSGApplyBufferValue : public QSSGCommand
302 {
303     // If no buffer name is given then the special buffer [source]
304     // is assumed.
305     QByteArray m_bufferName;
306     // If no param name is given, the buffer is bound to the
307     // input texture parameter (texture0).
308     QByteArray m_paramName;
309 
QSSGApplyBufferValueQSSGApplyBufferValue310     QSSGApplyBufferValue(const QByteArray &bufferName, const QByteArray &shaderParam)
311         : QSSGCommand(CommandType::ApplyBufferValue), m_bufferName(bufferName), m_paramName(shaderParam)
312     {
313     }
QSSGApplyBufferValueQSSGApplyBufferValue314     QSSGApplyBufferValue(const QSSGApplyBufferValue &inOther)
315         : QSSGCommand(CommandType::ApplyBufferValue), m_bufferName(inOther.m_bufferName), m_paramName(inOther.m_paramName)
316     {
317     }
318 };
319 
320 // bind a buffer to a given shader parameter.
321 struct QSSGApplyImageValue : public QSSGCommand
322 {
323     QByteArray m_imageName; ///< name which the image was allocated
324     QByteArray m_paramName; ///< must match the name in the shader
325     bool m_bindAsTexture; ///< bind image as texture
326     bool m_needSync; ///< if true we add a memory barrier before usage
327 
QSSGApplyImageValueQSSGApplyImageValue328     QSSGApplyImageValue(const QByteArray &bufferName, const QByteArray &shaderParam, bool inBindAsTexture, bool inNeedSync)
329         : QSSGCommand(CommandType::ApplyImageValue)
330         , m_imageName(bufferName)
331         , m_paramName(shaderParam)
332         , m_bindAsTexture(inBindAsTexture)
333         , m_needSync(inNeedSync)
334     {
335     }
QSSGApplyImageValueQSSGApplyImageValue336     QSSGApplyImageValue(const QSSGApplyImageValue &inOther)
337         : QSSGCommand(CommandType::ApplyImageValue)
338         , m_imageName(inOther.m_imageName)
339         , m_paramName(inOther.m_paramName)
340         , m_bindAsTexture(inOther.m_bindAsTexture)
341         , m_needSync(inOther.m_needSync)
342     {
343     }
344 };
345 
346 // bind a buffer to a given shader parameter.
347 struct QSSGApplyDataBufferValue : public QSSGCommand
348 {
349     QByteArray m_paramName; ///< must match the name in the shader
350     QSSGRenderBufferType m_bindAs; ///< to which target we bind this buffer
351 
QSSGApplyDataBufferValueQSSGApplyDataBufferValue352     QSSGApplyDataBufferValue(const QByteArray &inShaderParam, QSSGRenderBufferType inBufferType)
353         : QSSGCommand(CommandType::ApplyDataBufferValue), m_paramName(inShaderParam), m_bindAs(inBufferType)
354     {
355     }
QSSGApplyDataBufferValueQSSGApplyDataBufferValue356     QSSGApplyDataBufferValue(const QSSGApplyDataBufferValue &inOther)
357         : QSSGCommand(CommandType::ApplyDataBufferValue), m_paramName(inOther.m_paramName), m_bindAs(inOther.m_bindAs)
358     {
359     }
360 };
361 
362 struct QSSGApplyDepthValue : public QSSGCommand
363 {
364     // If no param name is given, the buffer is bound to the
365     // input texture parameter (texture0).
366     QByteArray m_paramName;
QSSGApplyDepthValueQSSGApplyDepthValue367     QSSGApplyDepthValue(const QByteArray &param) : QSSGCommand(CommandType::ApplyDepthValue), m_paramName(param) {}
QSSGApplyDepthValueQSSGApplyDepthValue368     QSSGApplyDepthValue(const QSSGApplyDepthValue &inOther)
369         : QSSGCommand(CommandType::ApplyDepthValue), m_paramName(inOther.m_paramName)
370     {
371     }
372 };
373 
374 struct QSSGRender : public QSSGCommand
375 {
QSSGRenderQSSGRender376     explicit QSSGRender() : QSSGCommand(CommandType::Render) { }
377 
QSSGRenderQSSGRender378     QSSGRender(const QSSGRender &)
379         : QSSGCommand(CommandType::Render)
380     {
381     }
382 };
383 
384 struct QSSGApplyBlending : public QSSGCommand
385 {
386     QSSGRenderSrcBlendFunc m_srcBlendFunc;
387     QSSGRenderDstBlendFunc m_dstBlendFunc;
388 
QSSGApplyBlendingQSSGApplyBlending389     QSSGApplyBlending(QSSGRenderSrcBlendFunc inSrcBlendFunc, QSSGRenderDstBlendFunc inDstBlendFunc)
390         : QSSGCommand(CommandType::ApplyBlending), m_srcBlendFunc(inSrcBlendFunc), m_dstBlendFunc(inDstBlendFunc)
391     {
392     }
393 
QSSGApplyBlendingQSSGApplyBlending394     QSSGApplyBlending(const QSSGApplyBlending &inOther)
395         : QSSGCommand(CommandType::ApplyBlending), m_srcBlendFunc(inOther.m_srcBlendFunc), m_dstBlendFunc(inOther.m_dstBlendFunc)
396     {
397     }
398 };
399 
400 struct QSSGApplyRenderState : public QSSGCommand
401 {
402     QSSGRenderState m_renderState;
403     bool m_enabled;
404 
QSSGApplyRenderStateQSSGApplyRenderState405     QSSGApplyRenderState(QSSGRenderState inRenderStateValue, bool inEnabled)
406         : QSSGCommand(CommandType::ApplyRenderState), m_renderState(inRenderStateValue), m_enabled(inEnabled)
407     {
408     }
409 
QSSGApplyRenderStateQSSGApplyRenderState410     QSSGApplyRenderState(const QSSGApplyRenderState &inOther)
411         : QSSGCommand(CommandType::ApplyRenderState), m_renderState(inOther.m_renderState), m_enabled(inOther.m_enabled)
412     {
413     }
414 };
415 
416 struct QSSGApplyCullMode : public QSSGCommand
417 {
418     QSSGCullFaceMode m_cullMode;
419 
QSSGApplyCullModeQSSGApplyCullMode420     QSSGApplyCullMode(QSSGCullFaceMode cullMode)
421         : QSSGCommand(CommandType::ApplyCullMode), m_cullMode(cullMode)
422     {
423     }
424 
QSSGApplyCullModeQSSGApplyCullMode425     QSSGApplyCullMode(const QSSGApplyCullMode &inOther)
426         : QSSGCommand(CommandType::ApplyCullMode), m_cullMode(inOther.m_cullMode)
427     {
428     }
429 };
430 
431 struct QSSGApplyBlitFramebuffer : public QSSGCommand
432 {
433     // If no buffer name is given then the special buffer [source]
434     // is assumed. Which is the default render target
435     QByteArray m_sourceBufferName;
436     // If no buffer name is given then the special buffer [dest]
437     // is assumed. Which is the default render target
438     QByteArray m_destBufferName;
439 
QSSGApplyBlitFramebufferQSSGApplyBlitFramebuffer440     QSSGApplyBlitFramebuffer(const QByteArray &inSourceBufferName, const QByteArray &inDestBufferName)
441         : QSSGCommand(CommandType::ApplyBlitFramebuffer), m_sourceBufferName(inSourceBufferName), m_destBufferName(inDestBufferName)
442     {
443     }
444 
QSSGApplyBlitFramebufferQSSGApplyBlitFramebuffer445     QSSGApplyBlitFramebuffer(const QSSGApplyBlitFramebuffer &inOther)
446         : QSSGCommand(CommandType::ApplyBlitFramebuffer)
447         , m_sourceBufferName(inOther.m_sourceBufferName)
448         , m_destBufferName(inOther.m_destBufferName)
449     {
450     }
451 };
452 
453 enum class QSSGDepthStencilFlagValue
454 {
455     NoFlagValue = 0,
456     ClearStencil = 1 << 0,
457     ClearDepth = 1 << 1,
458 };
459 
460 struct QSSGDepthStencilFlags : public QFlags<QSSGDepthStencilFlagValue>
461 {
hasClearStencilQSSGDepthStencilFlags462     bool hasClearStencil() const { return operator&(QSSGDepthStencilFlagValue::ClearStencil); }
setClearStencilQSSGDepthStencilFlags463     void setClearStencil(bool value) { setFlag(QSSGDepthStencilFlagValue::ClearStencil, value); }
464 
hasClearDepthQSSGDepthStencilFlags465     bool hasClearDepth() const { return operator&(QSSGDepthStencilFlagValue::ClearDepth); }
setClearDepthQSSGDepthStencilFlags466     void setClearDepth(bool value) { setFlag(QSSGDepthStencilFlagValue::ClearDepth, value); }
467 };
468 
469 struct QSSGDepthStencil : public QSSGCommand
470 {
471     QByteArray m_bufferName;
472     QSSGDepthStencilFlags m_glags;
473     QSSGRenderStencilOp m_stencilFailOperation = QSSGRenderStencilOp::Keep;
474     QSSGRenderStencilOp m_depthPassOperation = QSSGRenderStencilOp::Keep;
475     QSSGRenderStencilOp m_depthFailOperation = QSSGRenderStencilOp::Keep;
476     QSSGRenderBoolOp m_stencilFunction = QSSGRenderBoolOp::Equal;
477     quint32 m_reference = 0;
478     quint32 m_mask = std::numeric_limits<quint32>::max();
479 
QSSGDepthStencilQSSGDepthStencil480     QSSGDepthStencil() : QSSGCommand(CommandType::DepthStencil) {}
481 
QSSGDepthStencilQSSGDepthStencil482     QSSGDepthStencil(const QByteArray &bufName,
483                        QSSGDepthStencilFlags flags,
484                        QSSGRenderStencilOp inStencilOp,
485                        QSSGRenderStencilOp inDepthPassOp,
486                        QSSGRenderStencilOp inDepthFailOp,
487                        QSSGRenderBoolOp inStencilFunc,
488                        quint32 value,
489                        quint32 mask)
490         : QSSGCommand(CommandType::DepthStencil)
491         , m_bufferName(bufName)
492         , m_glags(flags)
493         , m_stencilFailOperation(inStencilOp)
494         , m_depthPassOperation(inDepthPassOp)
495         , m_depthFailOperation(inDepthFailOp)
496         , m_stencilFunction(inStencilFunc)
497         , m_reference(value)
498         , m_mask(mask)
499     {
500     }
501 
QSSGDepthStencilQSSGDepthStencil502     QSSGDepthStencil(const QSSGDepthStencil &inOther)
503         : QSSGCommand(CommandType::DepthStencil)
504         , m_bufferName(inOther.m_bufferName)
505         , m_glags(inOther.m_glags)
506         , m_stencilFailOperation(inOther.m_stencilFailOperation)
507         , m_depthPassOperation(inOther.m_depthPassOperation)
508         , m_depthFailOperation(inOther.m_depthFailOperation)
509         , m_stencilFunction(inOther.m_stencilFunction)
510         , m_reference(inOther.m_reference)
511         , m_mask(inOther.m_mask)
512     {
513     }
514     QSSGDepthStencil& operator=(const QSSGDepthStencil&) = default;
515 };
516 }
517 QT_END_NAMESPACE
518 
519 #endif
520