summaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorPaul Lemire <paul.lemire@kdab.com>2019-10-15 09:05:05 +0200
committerPaul Lemire <paul.lemire@kdab.com>2019-10-24 11:54:58 +0200
commited97ebb1884b36f7e71b295ebae99fd962832bd3 (patch)
treed80110b468949839e96ed3f54fd70832b412bcb2 /tests
parent3b649e32327fa561c75b5ccb762f12e8fd8c18a9 (diff)
Add manual test to check manual trigger mode on ComputeCommands
Change-Id: I8048795277828ecba7d46dbc846685e606b2b8b9 Reviewed-by: Mike Krus <mike.krus@kdab.com>
Diffstat (limited to 'tests')
-rw-r--r--tests/manual/compute-manual/ComputeFrameGraph.qml91
-rw-r--r--tests/manual/compute-manual/ComputeMaterial.qml118
-rw-r--r--tests/manual/compute-manual/ParticlesScene.qml200
-rw-r--r--tests/manual/compute-manual/compute-manual.pro14
-rw-r--r--tests/manual/compute-manual/compute-manual.qrc11
-rw-r--r--tests/manual/compute-manual/main.cpp66
-rw-r--r--tests/manual/compute-manual/main.qml109
-rw-r--r--tests/manual/compute-manual/particles.comp31
-rw-r--r--tests/manual/compute-manual/particles.frag33
-rw-r--r--tests/manual/compute-manual/particles.vert27
-rw-r--r--tests/manual/manual.pro2
11 files changed, 702 insertions, 0 deletions
diff --git a/tests/manual/compute-manual/ComputeFrameGraph.qml b/tests/manual/compute-manual/ComputeFrameGraph.qml
new file mode 100644
index 000000000..47d57161c
--- /dev/null
+++ b/tests/manual/compute-manual/ComputeFrameGraph.qml
@@ -0,0 +1,91 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import Qt3D.Core 2.14
+import Qt3D.Render 2.14
+
+Viewport {
+ property alias camera: selector.camera
+
+ RenderSurfaceSelector {
+ id: surfaceSelector
+
+ // Clear Buffer
+ ClearBuffers {
+ buffers: ClearBuffers.ColorDepthBuffer
+ NoDraw {}
+ }
+
+ // Compute Pass
+ DispatchCompute {
+ // 1024 x 1024 particles
+ // We will launch 1024 local workgroup that will work
+ // on 1024 particles each
+ workGroupX: 1024; workGroupY: 1; workGroupZ: 1
+ TechniqueFilter {
+ matchAll: [
+ FilterKey { name: "type"; value: "compute"}
+ ]
+ }
+ }
+
+ // Draw particles from buffer computed in the Compute Pass
+ CameraSelector {
+ id: selector
+ TechniqueFilter {
+ MemoryBarrier { waitFor: MemoryBarrier.VertexAttributeArray }
+ matchAll: [
+ FilterKey { name: "type"; value: "draw"}
+ ]
+ }
+ }
+ }
+}
+
diff --git a/tests/manual/compute-manual/ComputeMaterial.qml b/tests/manual/compute-manual/ComputeMaterial.qml
new file mode 100644
index 000000000..9116a8b66
--- /dev/null
+++ b/tests/manual/compute-manual/ComputeMaterial.qml
@@ -0,0 +1,118 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import Qt3D.Core 2.14
+import Qt3D.Render 2.14
+
+Material {
+ property Buffer dataBuffer;
+ property real particleStep: 0.4
+ property real finalCollisionFactor: 0.2
+
+ parameters: [
+ Parameter { name: "particleStep"; value: particleStep },
+ Parameter { name: "finalCollisionFactor"; value: finalCollisionFactor }
+ ]
+
+ ShaderProgram {
+ id: computeShader
+ computeShaderCode: loadSource("qrc:/particles.comp")
+ }
+
+ ShaderProgram {
+ id: drawShader
+ vertexShaderCode: loadSource("qrc:/particles.vert")
+ fragmentShaderCode: loadSource("qrc:/particles.frag")
+ }
+
+ effect: Effect {
+ techniques: [
+ Technique {
+ renderPasses: [
+ RenderPass {
+ shaderProgram: computeShader
+ // We set the buffer as the parameter data
+ parameters: [
+ Parameter { name: "Particles"; value: dataBuffer }
+ ]
+ }
+ ]
+ filterKeys: [
+ FilterKey { name: "type"; value: "compute" }
+ ]
+ graphicsApiFilter {
+ api: GraphicsApiFilter.OpenGL
+ profile: GraphicsApiFilter.CoreProfile
+ majorVersion: 4
+ minorVersion: 3
+ }
+ },
+ Technique {
+ renderPasses: [
+ RenderPass {
+ shaderProgram: drawShader
+ // We assume the mesh to be drawn will also receive
+ // Vertex buffers attributes that will be used to position and color
+ }
+ ]
+ filterKeys: [
+ FilterKey { name: "type"; value: "draw" }
+ ]
+ graphicsApiFilter {
+ api: GraphicsApiFilter.OpenGL
+ profile: GraphicsApiFilter.CoreProfile
+ majorVersion: 4
+ minorVersion: 3
+ }
+ }
+ ] // techniques
+ }
+}
+
diff --git a/tests/manual/compute-manual/ParticlesScene.qml b/tests/manual/compute-manual/ParticlesScene.qml
new file mode 100644
index 000000000..68572f6b4
--- /dev/null
+++ b/tests/manual/compute-manual/ParticlesScene.qml
@@ -0,0 +1,200 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import Qt3D.Core 2.14
+import Qt3D.Render 2.14
+import Qt3D.Extras 2.14
+import Qt3D.Input 2.14
+
+Entity {
+
+ property alias computeMode: particlesComputeJob.runType
+
+ function triggerCompute(frames) {
+ particlesComputeJob.trigger(frames)
+ }
+
+ components: [
+ RenderSettings {
+ ComputeFrameGraph {
+ camera: sceneCamera
+ }
+ // explicitly set RenderingPolicy to AlwaysRender, as changes in the
+ // scene won't be reflected in actual Qt scene-graph changes (due to
+ // GPU compute calls)
+ renderPolicy: RenderSettings.Always
+ },
+ InputSettings {}
+ ]
+
+ FirstPersonCameraController { camera: sceneCamera }
+
+ Camera {
+ id: sceneCamera
+ projectionType: CameraLens.PerspectiveProjection
+ viewCenter: Qt.vector3d(0, 0, 0)
+ position: Qt.vector3d(0, 20, -800)
+ nearPlane: 0.1
+ farPlane: 1000
+ fieldOfView: 60
+ }
+
+ property int particlesCount: 1024 * 1024
+ readonly property int floatSize: 4
+
+ function buildParticlesBuffer() {
+ var byteSizeOfParticleData = 8;
+ var bufferData = new Float32Array(particlesCount * byteSizeOfParticleData);
+ for (var x = 0; x < 1024; ++x) {
+ for (var z = 0; z < 1024; ++z) {
+ var i = x * 1024 + z;
+ var positionIdx = i * byteSizeOfParticleData;
+ var colorIdx = i * byteSizeOfParticleData + 8;
+
+ bufferData[positionIdx] = -1024 + x * 2;
+ bufferData[positionIdx + 1] = 0;
+ bufferData[positionIdx + 2] = -1024 + z * 2;
+ bufferData[positionIdx + 3] = 1.0;
+
+ bufferData[colorIdx] = 0.25 + Math.sin(x / 1024) * 0.75;
+ bufferData[colorIdx + 1] = 0.25 + Math.sin(z / 1024) * 0.75;
+ bufferData[colorIdx + 2] = 0.25 + Math.sin(x / 1024) * 0.75;
+ bufferData[colorIdx + 3] = 1.0;
+ }
+ }
+ return bufferData
+ }
+
+ Buffer {
+ id: particleBuffer
+ type: Buffer.VertexBuffer
+ // struct ParticleData
+ // {
+ // vec3 position; // Aligned to 4 floats
+ // vec3 color; // Aligned to 4 floats
+ // };
+ data: buildParticlesBuffer()
+ }
+
+ Attribute {
+ id: particlePositionDataAttribute
+ name: "particlePosition"
+ attributeType: Attribute.VertexAttribute
+ vertexBaseType: Attribute.Float
+ vertexSize: 3
+ divisor: 1
+ byteStride: 8 * floatSize
+ buffer: particleBuffer
+ }
+
+ Attribute {
+ id: particleColorDataAttribute
+ name: "particleColor"
+ attributeType: Attribute.VertexAttribute
+ vertexBaseType: Attribute.Float
+ vertexSize: 3
+ divisor: 1
+ byteOffset: 4 * floatSize
+ byteStride: 8 * floatSize
+ buffer: particleBuffer
+ }
+
+ ComputeMaterial {
+ id: computeMaterial
+ dataBuffer: particleBuffer
+ }
+
+ ComputeCommand {
+ id: particlesComputeJob
+ onRunTypeChanged: {
+ // Don't forget to re-enable the command
+ // when switching back to continuous
+ if (runType === ComputeCommand.Continuous)
+ enabled = true
+ }
+ }
+
+ Entity {
+ id: particleComputeEntity
+ components: [
+ particlesComputeJob,
+ computeMaterial
+ ]
+ }
+
+ SphereGeometry {
+ id: sphereGeometry
+ rings: 10
+ slices: 10
+ radius: 1
+ // Additional Attributes
+ attributes: [
+ particlePositionDataAttribute,
+ particleColorDataAttribute
+ ]
+ }
+
+ Entity {
+ id: particleRenderEntity
+ readonly property GeometryRenderer particlesRenderer: GeometryRenderer {
+ instanceCount: particlesCount
+ indexOffset: 0
+ firstInstance: 0
+ primitiveType: GeometryRenderer.Triangles
+ geometry: sphereGeometry
+ }
+
+ components: [
+ particlesRenderer,
+ computeMaterial
+ ]
+ }
+}
+
diff --git a/tests/manual/compute-manual/compute-manual.pro b/tests/manual/compute-manual/compute-manual.pro
new file mode 100644
index 000000000..e2a9116db
--- /dev/null
+++ b/tests/manual/compute-manual/compute-manual.pro
@@ -0,0 +1,14 @@
+!include( ../manual.pri ) {
+ error( "Couldn't find the manual.pri file!" )
+}
+
+QT += 3dcore 3drender 3dquick 3dinput quick qml
+
+HEADERS += \
+
+
+RESOURCES += \
+ compute-manual.qrc
+
+SOURCES += \
+ main.cpp
diff --git a/tests/manual/compute-manual/compute-manual.qrc b/tests/manual/compute-manual/compute-manual.qrc
new file mode 100644
index 000000000..0f94fddd5
--- /dev/null
+++ b/tests/manual/compute-manual/compute-manual.qrc
@@ -0,0 +1,11 @@
+<RCC>
+ <qresource prefix="/">
+ <file>main.qml</file>
+ <file>ComputeFrameGraph.qml</file>
+ <file>ComputeMaterial.qml</file>
+ <file>particles.frag</file>
+ <file>particles.vert</file>
+ <file>ParticlesScene.qml</file>
+ <file>particles.comp</file>
+ </qresource>
+</RCC>
diff --git a/tests/manual/compute-manual/main.cpp b/tests/manual/compute-manual/main.cpp
new file mode 100644
index 000000000..afc9df36a
--- /dev/null
+++ b/tests/manual/compute-manual/main.cpp
@@ -0,0 +1,66 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QGuiApplication>
+#include <QQuickView>
+
+int main(int argc, char* argv[])
+{
+ QGuiApplication app(argc, argv);
+
+ QQuickView view;
+
+ view.resize(1024, 1024);
+ view.setResizeMode(QQuickView::SizeRootObjectToView);
+ view.setSource(QUrl("qrc:/main.qml"));
+ view.show();
+
+ return app.exec();
+}
diff --git a/tests/manual/compute-manual/main.qml b/tests/manual/compute-manual/main.qml
new file mode 100644
index 000000000..a76c8ae0c
--- /dev/null
+++ b/tests/manual/compute-manual/main.qml
@@ -0,0 +1,109 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.14
+import QtQuick.Scene3D 2.14
+import QtQuick.Controls 2.14
+import QtQuick.Layouts 1.1
+import Qt3D.Render 2.14
+
+Item {
+
+ Scene3D {
+ anchors.fill: parent
+ aspects: ["input", "logic"]
+ focus: true
+ ParticlesScene {
+ id: scene
+ computeMode: runModeCombo.currentIndex === 0 ? ComputeCommand.Continuous : ComputeCommand.Manual
+ }
+ }
+
+ RowLayout {
+ id: colorLayout
+ anchors.left: parent.left
+ anchors.leftMargin: 35
+ anchors.bottom: parent.bottom
+ anchors.bottomMargin: 35
+ spacing: 15
+
+ RowLayout {
+ Text {
+ text: "Run Mode:"
+ color: "white"
+ }
+ ComboBox {
+ id: runModeCombo
+ model: ["Continuous", "Manual"]
+ }
+ }
+ RowLayout {
+ visible: runModeCombo.currentIndex === 1
+ Text {
+ color: "white"
+ text: "Frames"
+ }
+ SpinBox {
+ id: frameCountSpinBox
+ value: 5
+ from: 1
+ to: 10
+ stepSize: 1
+ }
+ Button {
+ text: "Trigger"
+ onClicked: {
+ // Trigger Compute Manual
+ scene.triggerCompute(frameCountSpinBox.value)
+ }
+ }
+ }
+ }
+}
diff --git a/tests/manual/compute-manual/particles.comp b/tests/manual/compute-manual/particles.comp
new file mode 100644
index 000000000..b05e49c1d
--- /dev/null
+++ b/tests/manual/compute-manual/particles.comp
@@ -0,0 +1,31 @@
+#version 430 core
+
+uniform float time;
+
+layout (local_size_x = 1024) in;
+
+struct ParticleData
+{
+ vec4 position;
+ vec4 color;
+};
+
+// Particles from previouse frame
+layout (std430, binding = 0) coherent buffer Particles
+{
+ ParticleData particles[];
+} data;
+
+void main(void)
+{
+ uint globalId = gl_GlobalInvocationID.x;
+
+ // Retrieve current particle from previous frame
+ ParticleData currentParticle = data.particles[globalId];
+
+ // New position = old position + sin(time)
+ currentParticle.position = currentParticle.position + vec4(0.0, 1.0, 0.0, 0.0) * sin(time * globalId);
+
+ // Save updated particle
+ data.particles[globalId] = currentParticle;
+}
diff --git a/tests/manual/compute-manual/particles.frag b/tests/manual/compute-manual/particles.frag
new file mode 100644
index 000000000..3f11b9868
--- /dev/null
+++ b/tests/manual/compute-manual/particles.frag
@@ -0,0 +1,33 @@
+#version 430 core
+
+out vec4 color;
+
+in VertexBlock
+{
+ flat vec3 color;
+ vec3 pos;
+ vec3 normal;
+} frag_in;
+
+const vec4 lightPosition = vec4(0.0, 0.0, 0.0, 0.0);
+const vec3 lightIntensity = vec3(1.0, 1.0, 1.0);
+const vec3 ka = vec3(0.1, 0.1, 0.1);
+const vec3 ks = vec3(0.8, 0.8, 0.8);
+const float shininess = 50.0;
+
+vec3 ads()
+{
+ vec3 n = normalize( frag_in.normal);
+ vec3 s = normalize( vec3(lightPosition) - frag_in.pos );
+ vec3 v = normalize( -frag_in.pos );
+ vec3 h = normalize( v + s );
+ return lightIntensity * (ka +
+ frag_in.color * max( dot(s, frag_in.normal ), 0.0 ) +
+ ks * pow( max( dot( h, n ), 0.0 ), shininess ) );
+}
+
+
+void main(void)
+{
+ color = vec4(ads(), 1.0);
+}
diff --git a/tests/manual/compute-manual/particles.vert b/tests/manual/compute-manual/particles.vert
new file mode 100644
index 000000000..5f2da2a00
--- /dev/null
+++ b/tests/manual/compute-manual/particles.vert
@@ -0,0 +1,27 @@
+#version 430 core
+
+in vec3 vertexPosition;
+in vec3 vertexNormal;
+
+in vec3 particlePosition;
+in vec3 particleColor;
+
+out VertexBlock
+{
+ flat vec3 color;
+ vec3 pos;
+ vec3 normal;
+} v_out;
+
+uniform mat4 mvp;
+uniform mat3 modelViewNormal;
+uniform mat4 modelView;
+
+void main(void)
+{
+ vec4 pos = vec4(vertexPosition.xyz, 1.0) + vec4(particlePosition, 0.0);
+ gl_Position = mvp * pos;
+ v_out.pos = vec4(modelView * pos).xyz;
+ v_out.normal = normalize(modelViewNormal * vertexNormal);
+ v_out.color = mix(particleColor * 0.2, particleColor, smoothstep(0.5, 0.8, abs(v_out.normal).z));
+}
diff --git a/tests/manual/manual.pro b/tests/manual/manual.pro
index 1182886d3..9c2461b29 100644
--- a/tests/manual/manual.pro
+++ b/tests/manual/manual.pro
@@ -69,6 +69,8 @@ SUBDIRS += \
scene3d-in-sync \
compressed_textures
+!macos:!uikit: SUBDIRS += compute-manual
+
qtHaveModule(multimedia): {
SUBDIRS += \
sharedtexture \