1 | // Copyright (C) 2015 Klaralvdalens Datakonsult AB (KDAB). |
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 "qcomputecommand.h" |
5 | #include "qcomputecommand_p.h" |
6 | |
7 | QT_BEGIN_NAMESPACE |
8 | |
9 | namespace Qt3DRender { |
10 | |
11 | /*! |
12 | \class Qt3DRender::QComputeCommand |
13 | \since 5.7 |
14 | \inmodule Qt3DRender |
15 | \brief QComponent to issue work for the compute shader on GPU. |
16 | |
17 | A Qt3DRender::QComputeCommand is used to issue work for the compute shader. |
18 | The compute shader is specified in the QMaterial component of the same entity the |
19 | QComputeCommand is added to. The workGroupX, workGroupY and workGroupZ properties |
20 | specify the work group sizes for the compute shader invocation. Qt3DRender::QDispatchCompute |
21 | node needs to be present in the FrameGraph to actually issue the commands. |
22 | |
23 | \note If the rendering policy is set to Qt3DRender::QRenderSettings::OnDemand and there are no |
24 | changes to the scene, the ComputeCommand will not be invoked repeatedly. |
25 | The Qt3DRender::QRenderSettings::Always render policy must be set for the ComputeCommand |
26 | to be repeatedly invoked if there are no other changes to the scene that triggers rendering a |
27 | new frame. |
28 | */ |
29 | |
30 | /*! |
31 | \qmltype ComputeCommand |
32 | \since 5.7 |
33 | \inqmlmodule Qt3D.Render |
34 | \inherits Component3D |
35 | \instantiates Qt3DRender::QComputeCommand |
36 | \brief Component to issue work for the compute shader on GPU. |
37 | |
38 | A ComputeCommand is used to issue work for the compute shader. |
39 | The compute shader is specified in the Material component of the same entity the |
40 | ComputeCommand is added to. The workGroupX, workGroupY and workGroupZ properties |
41 | specify the work group sizes for the compute shader invocation. DispatchCompute |
42 | node needs to be present in the FrameGraph to actually issue the commands. The execution behavior |
43 | of the compute command can be controlled with the run type property. |
44 | |
45 | \note If the rendering policy is set to RenderSettings.OnDemand, the run |
46 | type is set to Continuous and there are no changes to the scene, the |
47 | ComputeCommand will not be invoked repeatedly. The RenderSettings.Always |
48 | render policy must be set for the ComputeCommand to be repeatedly invoked |
49 | if there are no other changes to the scene that triggers rendering a new |
50 | frame. |
51 | */ |
52 | |
53 | /*! |
54 | \qmlproperty int ComputeCommand::workGroupX |
55 | Specifies X workgroup size. |
56 | */ |
57 | |
58 | /*! |
59 | \qmlproperty enumeration ComputeCommand::runType |
60 | |
61 | Specifies whether the compute command should be performed every frame or |
62 | manually triggered. |
63 | |
64 | \value ComputeCommand.Continuous Compute command is executed everyframe. This is the |
65 | default. |
66 | |
67 | \value ComputeCommand.Manual CompouteCommand is executed for a given number of frames and |
68 | then the component disables itself. |
69 | */ |
70 | |
71 | /*! |
72 | \qmlproperty int ComputeCommand::workGroupY |
73 | Specifies Y workgroup size. |
74 | */ |
75 | |
76 | /*! |
77 | \qmlproperty int ComputeCommand::workGroupZ |
78 | Specifies Z workgroup size. |
79 | */ |
80 | |
81 | /*! |
82 | \property QComputeCommand::workGroupX |
83 | Specifies X workgroup size. |
84 | */ |
85 | |
86 | /*! |
87 | \property QComputeCommand::workGroupY |
88 | Specifies Y workgroup size. |
89 | */ |
90 | |
91 | /*! |
92 | \property QComputeCommand::workGroupZ |
93 | Specifies Z workgroup size. |
94 | */ |
95 | |
96 | /*! |
97 | \property QComputeCommand::runType |
98 | |
99 | Specifies whether the compute command should be performed every frame or |
100 | manually triggered. |
101 | |
102 | If set to Continuous, Compute command is executed everyframe. This is the |
103 | default. |
104 | |
105 | If set to Manual CompouteCommand is executed for a given number of frames |
106 | and then the component disables itself. |
107 | */ |
108 | |
109 | QComputeCommandPrivate::QComputeCommandPrivate() |
110 | : Qt3DCore::QComponentPrivate() |
111 | , m_workGroupX(1) |
112 | , m_workGroupY(1) |
113 | , m_workGroupZ(1) |
114 | , m_runType(QComputeCommand::Continuous) |
115 | , m_frameCount(0) |
116 | { |
117 | } |
118 | |
119 | void QComputeCommandPrivate::setFrameCount(int frameCount) |
120 | { |
121 | m_frameCount = frameCount; |
122 | update(); |
123 | } |
124 | |
125 | /*! |
126 | The constructor creates a new Qt3DRender::QComputeCommand instance with the |
127 | specified \a parent. |
128 | */ |
129 | QComputeCommand::QComputeCommand(Qt3DCore::QNode *parent) |
130 | : Qt3DCore::QComponent(*new QComputeCommandPrivate, parent) |
131 | { |
132 | } |
133 | |
134 | /*! \internal */ |
135 | QComputeCommand::~QComputeCommand() |
136 | { |
137 | } |
138 | |
139 | int QComputeCommand::workGroupX() const |
140 | { |
141 | Q_D(const QComputeCommand); |
142 | return d->m_workGroupX; |
143 | } |
144 | |
145 | int QComputeCommand::workGroupY() const |
146 | { |
147 | Q_D(const QComputeCommand); |
148 | return d->m_workGroupY; |
149 | } |
150 | |
151 | int QComputeCommand::workGroupZ() const |
152 | { |
153 | Q_D(const QComputeCommand); |
154 | return d->m_workGroupZ; |
155 | } |
156 | |
157 | QComputeCommand::RunType QComputeCommand::runType() const |
158 | { |
159 | Q_D(const QComputeCommand); |
160 | return d->m_runType; |
161 | } |
162 | |
163 | /*! |
164 | Sets the workgroup for the first dimension to \a workGroupX. |
165 | */ |
166 | void QComputeCommand::setWorkGroupX(int workGroupX) |
167 | { |
168 | Q_D(QComputeCommand); |
169 | if (d->m_workGroupX != workGroupX) { |
170 | d->m_workGroupX = workGroupX; |
171 | emit workGroupXChanged(); |
172 | } |
173 | } |
174 | |
175 | /*! |
176 | Sets the workgroup for the second dimension to \a workGroupY. |
177 | */ |
178 | void QComputeCommand::setWorkGroupY(int workGroupY) |
179 | { |
180 | Q_D(QComputeCommand); |
181 | if (d->m_workGroupY != workGroupY) { |
182 | d->m_workGroupY = workGroupY; |
183 | emit workGroupYChanged(); |
184 | } |
185 | } |
186 | |
187 | /*! |
188 | Sets the workgroup for the third dimension to \a workGroupZ. |
189 | */ |
190 | void QComputeCommand::setWorkGroupZ(int workGroupZ) |
191 | { |
192 | Q_D(QComputeCommand); |
193 | if (d->m_workGroupZ != workGroupZ) { |
194 | d->m_workGroupZ = workGroupZ; |
195 | emit workGroupZChanged(); |
196 | } |
197 | } |
198 | |
199 | void QComputeCommand::setRunType(QComputeCommand::RunType runType) |
200 | { |
201 | Q_D(QComputeCommand); |
202 | if (d->m_runType != runType) { |
203 | d->m_runType = runType; |
204 | emit runTypeChanged(); |
205 | } |
206 | } |
207 | |
208 | /*! |
209 | When the run type is set to Manual, calling trigger will make the compute |
210 | command be executed for the next \a frameCount frames. Upon completion of |
211 | the execution, the enabled property will be set to false. |
212 | */ |
213 | void QComputeCommand::trigger(int frameCount) |
214 | { |
215 | if (isEnabled()) |
216 | qWarning() << Q_FUNC_INFO << "is triggered while it hasn't finished executing" ; |
217 | |
218 | Q_D(QComputeCommand); |
219 | d->setFrameCount(frameCount); |
220 | setEnabled(true); |
221 | } |
222 | |
223 | /*! |
224 | When the run type is set to Manual, calling trigger will make the compute |
225 | command be executed for the next \a frameCount frames. Upon completion of |
226 | the execution, the enabled property will be set to false. The size of the |
227 | workgroup previously set will be overridden with \a workGroupX, \a |
228 | workGroupY, \a workGroupZ. |
229 | */ |
230 | void QComputeCommand::trigger(int workGroupX, int workGroupY, int workGroupZ, int frameCount) |
231 | { |
232 | if (isEnabled()) |
233 | qWarning() << Q_FUNC_INFO << "is triggered while it hasn't finished executing" ; |
234 | |
235 | setWorkGroupX(workGroupX); |
236 | setWorkGroupY(workGroupY); |
237 | setWorkGroupZ(workGroupZ); |
238 | Q_D(QComputeCommand); |
239 | d->setFrameCount(frameCount); |
240 | setEnabled(true); |
241 | } |
242 | |
243 | } // Render |
244 | |
245 | QT_END_NAMESPACE |
246 | |
247 | #include "moc_qcomputecommand.cpp" |
248 | |