summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/render/backend/abstractrenderer_p.h1
-rw-r--r--src/render/backend/managers_p.h5
-rw-r--r--src/render/backend/nodemanagers.cpp2
-rw-r--r--src/render/backend/nodemanagers_p.h3
-rw-r--r--src/render/frontend/qrenderaspect.cpp15
-rw-r--r--src/render/jobs/job_common_p.h3
-rw-r--r--src/render/jobs/sendbuffercapturejob.cpp6
-rw-r--r--src/render/jobs/sendbuffercapturejob_p.h1
-rw-r--r--src/render/renderers/opengl/graphicshelpers/glfence_p.h73
-rw-r--r--src/render/renderers/opengl/graphicshelpers/graphicshelperes2.cpp27
-rw-r--r--src/render/renderers/opengl/graphicshelpers/graphicshelperes2_p.h6
-rw-r--r--src/render/renderers/opengl/graphicshelpers/graphicshelperes3.cpp52
-rw-r--r--src/render/renderers/opengl/graphicshelpers/graphicshelperes3_p.h6
-rw-r--r--src/render/renderers/opengl/graphicshelpers/graphicshelpergl2.cpp28
-rw-r--r--src/render/renderers/opengl/graphicshelpers/graphicshelpergl2_p.h6
-rw-r--r--src/render/renderers/opengl/graphicshelpers/graphicshelpergl3_2.cpp32
-rw-r--r--src/render/renderers/opengl/graphicshelpers/graphicshelpergl3_2_p.h6
-rw-r--r--src/render/renderers/opengl/graphicshelpers/graphicshelpergl3_3.cpp32
-rw-r--r--src/render/renderers/opengl/graphicshelpers/graphicshelpergl3_3_p.h6
-rw-r--r--src/render/renderers/opengl/graphicshelpers/graphicshelpergl4.cpp35
-rw-r--r--src/render/renderers/opengl/graphicshelpers/graphicshelpergl4_p.h6
-rw-r--r--src/render/renderers/opengl/graphicshelpers/graphicshelperinterface_p.h9
-rw-r--r--src/render/renderers/opengl/graphicshelpers/graphicshelpers.pri3
-rw-r--r--src/render/renderers/opengl/graphicshelpers/submissioncontext.cpp27
-rw-r--r--src/render/renderers/opengl/graphicshelpers/submissioncontext_p.h9
-rw-r--r--src/render/renderers/opengl/jobs/renderviewjobutils.cpp12
-rw-r--r--src/render/renderers/opengl/renderer/renderer.cpp115
-rw-r--r--src/render/renderers/opengl/renderer/renderer_p.h13
-rw-r--r--src/render/renderers/opengl/renderer/renderview_p.h10
-rw-r--r--tests/auto/render/commons/testrenderer.h1
-rw-r--r--tests/auto/render/graphicshelpergl2/tst_graphicshelpergl2.cpp33
-rw-r--r--tests/auto/render/graphicshelpergl3_2/tst_graphicshelpergl3_2.cpp99
-rw-r--r--tests/auto/render/graphicshelpergl3_3/tst_graphicshelpergl3_3.cpp99
-rw-r--r--tests/auto/render/graphicshelpergl4/tst_graphicshelpergl4.cpp101
-rw-r--r--tests/auto/render/renderer/tst_renderer.cpp115
35 files changed, 957 insertions, 40 deletions
diff --git a/src/render/backend/abstractrenderer_p.h b/src/render/backend/abstractrenderer_p.h
index f1bdca7be..f19db066c 100644
--- a/src/render/backend/abstractrenderer_p.h
+++ b/src/render/backend/abstractrenderer_p.h
@@ -153,6 +153,7 @@ public:
virtual bool shouldRender() = 0;
virtual void skipNextFrame() = 0;
+ virtual QVector<Qt3DCore::QAspectJobPtr> preRenderingJobs() = 0;
virtual QVector<Qt3DCore::QAspectJobPtr> renderBinJobs() = 0;
virtual Qt3DCore::QAspectJobPtr pickBoundingVolumeJob() = 0;
virtual Qt3DCore::QAspectJobPtr rayCastingJob() = 0;
diff --git a/src/render/backend/managers_p.h b/src/render/backend/managers_p.h
index b62e2f3e0..eb219fd1e 100644
--- a/src/render/backend/managers_p.h
+++ b/src/render/backend/managers_p.h
@@ -72,6 +72,7 @@
#include <Qt3DRender/private/shaderdata_p.h>
#include <Qt3DRender/private/handle_types_p.h>
#include <Qt3DRender/private/glbuffer_p.h>
+#include <Qt3DRender/private/glfence_p.h>
#include <Qt3DRender/private/textureimage_p.h>
#include <Qt3DRender/private/attribute_p.h>
#include <Qt3DRender/private/geometry_p.h>
@@ -317,6 +318,10 @@ class GLBufferManager : public Qt3DCore::QResourceManager<
{
};
+class GLFenceManager : public QHash<Qt3DCore::QNodeId, GLFence>
+{
+};
+
class TextureImageManager : public Qt3DCore::QResourceManager<
TextureImage,
Qt3DCore::QNodeId,
diff --git a/src/render/backend/nodemanagers.cpp b/src/render/backend/nodemanagers.cpp
index 5db35082d..584ddd65c 100644
--- a/src/render/backend/nodemanagers.cpp
+++ b/src/render/backend/nodemanagers.cpp
@@ -85,6 +85,7 @@ NodeManagers::NodeManagers()
, m_parameterManager(new ParameterManager())
, m_shaderDataManager(new ShaderDataManager())
, m_glBufferManager(new GLBufferManager())
+ , m_glFenceManager(new GLFenceManager())
, m_bufferManager(new BufferManager())
, m_attributeManager(new AttributeManager())
, m_geometryManager(new GeometryManager())
@@ -128,6 +129,7 @@ NodeManagers::~NodeManagers()
delete m_parameterManager;
delete m_shaderDataManager;
delete m_glBufferManager;
+ delete m_glFenceManager;
delete m_textureImageManager;
delete m_bufferManager;
delete m_attributeManager;
diff --git a/src/render/backend/nodemanagers_p.h b/src/render/backend/nodemanagers_p.h
index 9277d4385..2c4926894 100644
--- a/src/render/backend/nodemanagers_p.h
+++ b/src/render/backend/nodemanagers_p.h
@@ -87,6 +87,7 @@ class AttachmentManager;
class ParameterManager;
class ShaderDataManager;
class GLBufferManager;
+class GLFenceManager;
class TextureImageManager;
class FilterKeyManager;
class FrameGraphManager;
@@ -210,6 +211,7 @@ public:
inline ParameterManager *parameterManager() const Q_DECL_NOEXCEPT { return m_parameterManager; }
inline ShaderDataManager *shaderDataManager() const Q_DECL_NOEXCEPT { return m_shaderDataManager; }
inline GLBufferManager *glBufferManager() const Q_DECL_NOEXCEPT { return m_glBufferManager; }
+ inline GLFenceManager *glFenceManager() const Q_DECL_NOEXCEPT { return m_glFenceManager; }
inline TextureImageManager *textureImageManager() const Q_DECL_NOEXCEPT { return m_textureImageManager; }
inline BufferManager *bufferManager() const Q_DECL_NOEXCEPT { return m_bufferManager; }
inline AttributeManager *attributeManager() const Q_DECL_NOEXCEPT { return m_attributeManager; }
@@ -255,6 +257,7 @@ private:
ParameterManager *m_parameterManager;
ShaderDataManager *m_shaderDataManager;
GLBufferManager *m_glBufferManager;
+ GLFenceManager *m_glFenceManager;
BufferManager *m_bufferManager;
AttributeManager *m_attributeManager;
GeometryManager *m_geometryManager;
diff --git a/src/render/frontend/qrenderaspect.cpp b/src/render/frontend/qrenderaspect.cpp
index ccec826ff..795073ce0 100644
--- a/src/render/frontend/qrenderaspect.cpp
+++ b/src/render/frontend/qrenderaspect.cpp
@@ -88,6 +88,8 @@
#include <Qt3DRender/qproximityfilter.h>
#include <Qt3DRender/qshaderprogrambuilder.h>
#include <Qt3DRender/qblitframebuffer.h>
+#include <Qt3DRender/qsetfence.h>
+#include <Qt3DRender/qwaitfence.h>
#include <Qt3DCore/qarmature.h>
#include <Qt3DCore/qjoint.h>
#include <Qt3DCore/qskeletonloader.h>
@@ -150,6 +152,8 @@
#include <Qt3DRender/private/joint_p.h>
#include <Qt3DRender/private/loadskeletonjob_p.h>
#include <Qt3DRender/private/proximityfilter_p.h>
+#include <Qt3DRender/private/setfence_p.h>
+#include <Qt3DRender/private/waitfence_p.h>
#include <private/qrenderpluginfactory_p.h>
#include <private/qrenderplugin_p.h>
@@ -291,6 +295,8 @@ void QRenderAspectPrivate::registerBackendTypes()
q->registerBackendType<QMemoryBarrier>(QSharedPointer<Render::FrameGraphNodeFunctor<Render::MemoryBarrier, QMemoryBarrier> >::create(m_renderer));
q->registerBackendType<QProximityFilter>(QSharedPointer<Render::FrameGraphNodeFunctor<Render::ProximityFilter, QProximityFilter> >::create(m_renderer));
q->registerBackendType<QBlitFramebuffer>(QSharedPointer<Render::FrameGraphNodeFunctor<Render::BlitFramebuffer, QBlitFramebuffer> >::create(m_renderer));
+ q->registerBackendType<QSetFence>(QSharedPointer<Render::FrameGraphNodeFunctor<Render::SetFence, QSetFence> >::create(m_renderer));
+ q->registerBackendType<QWaitFence>(QSharedPointer<Render::FrameGraphNodeFunctor<Render::WaitFence, QWaitFence> >::create(m_renderer));
// Picking
q->registerBackendType<QObjectPicker>(QSharedPointer<Render::NodeFunctor<Render::ObjectPicker, Render::ObjectPickerManager> >::create(m_renderer));
@@ -361,6 +367,8 @@ void QRenderAspectPrivate::unregisterBackendTypes()
unregisterBackendType<QRenderCapture>();
unregisterBackendType<QBufferCapture>();
unregisterBackendType<QMemoryBarrier>();
+ unregisterBackendType<QSetFence>();
+ unregisterBackendType<QWaitFence>();
// Picking
unregisterBackendType<QObjectPicker>();
@@ -502,11 +510,8 @@ QVector<Qt3DCore::QAspectJobPtr> QRenderAspect::jobsToExecute(qint64 time)
const QVector<QAspectJobPtr> geometryJobs = d->createGeometryRendererJobs();
jobs.append(geometryJobs);
-
- // Add all jobs to queue
- // Note: the getter is also responsible for returning a job ready to run
- jobs.append(d->m_renderer->pickBoundingVolumeJob());
- jobs.append(d->m_renderer->rayCastingJob());
+ const QVector<QAspectJobPtr> preRenderingJobs = d->m_renderer->preRenderingJobs();
+ jobs.append(preRenderingJobs);
// Don't spawn any rendering jobs, if the renderer decides to skip this frame
// Note: this only affects rendering jobs (jobs that load buffers,
diff --git a/src/render/jobs/job_common_p.h b/src/render/jobs/job_common_p.h
index 2ae7d81ff..e776d452d 100644
--- a/src/render/jobs/job_common_p.h
+++ b/src/render/jobs/job_common_p.h
@@ -107,7 +107,8 @@ namespace JobTypes {
SyncFilterEntityByLayer,
SyncMaterialGatherer,
UpdateLayerEntity,
- SendTextureChangesToFrontend
+ SendTextureChangesToFrontend,
+ SendSetFenceHandlesToFrontend,
};
} // JobTypes
diff --git a/src/render/jobs/sendbuffercapturejob.cpp b/src/render/jobs/sendbuffercapturejob.cpp
index eae26ba6c..8683ea9f2 100644
--- a/src/render/jobs/sendbuffercapturejob.cpp
+++ b/src/render/jobs/sendbuffercapturejob.cpp
@@ -67,6 +67,12 @@ void SendBufferCaptureJob::addRequest(QPair<Buffer *, QByteArray> request)
m_pendingSendBufferCaptures.push_back(request);
}
+// Called by aspect thread jobs to execute (no concurrency at that point)
+bool SendBufferCaptureJob::hasRequests() const
+{
+ return m_pendingSendBufferCaptures.size() > 0;
+}
+
void SendBufferCaptureJob::run()
{
QMutexLocker locker(&m_mutex);
diff --git a/src/render/jobs/sendbuffercapturejob_p.h b/src/render/jobs/sendbuffercapturejob_p.h
index 771497e2f..854414ec6 100644
--- a/src/render/jobs/sendbuffercapturejob_p.h
+++ b/src/render/jobs/sendbuffercapturejob_p.h
@@ -75,6 +75,7 @@ public:
~SendBufferCaptureJob();
void addRequest(QPair<Buffer*, QByteArray> request);
+ bool hasRequests() const;
void run() final;
diff --git a/src/render/renderers/opengl/graphicshelpers/glfence_p.h b/src/render/renderers/opengl/graphicshelpers/glfence_p.h
new file mode 100644
index 000000000..366065048
--- /dev/null
+++ b/src/render/renderers/opengl/graphicshelpers/glfence_p.h
@@ -0,0 +1,73 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 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:LGPL$
+** 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.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef GLFENCE_P_H
+#define GLFENCE_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of other Qt classes. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtGlobal>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DRender {
+
+namespace Render {
+
+// GLsync is a pointer to a struct (unlike the rest of GL which used int ids)
+// We cannot reference GLsync as it's only available since 3.2 We use FenceId
+// to wrap that around and trust the GLHelpers will convert them accordingly.
+using GLFence = void *;
+
+} // namespace Render
+} // namespace Qt3DRender
+
+QT_END_NAMESPACE
+
+
+#endif // GLFENCE_P_H
diff --git a/src/render/renderers/opengl/graphicshelpers/graphicshelperes2.cpp b/src/render/renderers/opengl/graphicshelpers/graphicshelperes2.cpp
index 2b2645505..f41f0f0f3 100644
--- a/src/render/renderers/opengl/graphicshelpers/graphicshelperes2.cpp
+++ b/src/render/renderers/opengl/graphicshelpers/graphicshelperes2.cpp
@@ -290,6 +290,33 @@ void GraphicsHelperES2::drawBuffer(GLenum mode)
qWarning() << "glDrawBuffer is not supported with OpenGL ES 2";
}
+void *GraphicsHelperES2::fenceSync()
+{
+ qWarning() << "Fences are not supported by OpenGL ES 2.0 (since OpenGL ES 3.0)";
+ return nullptr;
+}
+
+void GraphicsHelperES2::clientWaitSync(void *, GLuint64 )
+{
+ qWarning() << "Fences are not supported by OpenGL ES 2.0 (since OpenGL ES 3.0)";
+}
+
+void GraphicsHelperES2::waitSync(void *)
+{
+ qWarning() << "Fences are not supported by OpenGL ES 2.0 (since OpenGL ES 3.0)";
+}
+
+bool GraphicsHelperES2::wasSyncSignaled(void *)
+{
+ qWarning() << "Fences are not supported by OpenGL ES 2.0 (since OpenGL ES 3.0)";
+ return false;
+}
+
+void GraphicsHelperES2::deleteSync(void *)
+{
+ qWarning() << "Fences are not supported by OpenGL ES 2.0 (since OpenGL ES 3.0)";
+}
+
void GraphicsHelperES2::blendEquation(GLenum mode)
{
m_funcs->glBlendEquation(mode);
diff --git a/src/render/renderers/opengl/graphicshelpers/graphicshelperes2_p.h b/src/render/renderers/opengl/graphicshelpers/graphicshelperes2_p.h
index 1c6df41b6..8c8dd34e9 100644
--- a/src/render/renderers/opengl/graphicshelpers/graphicshelperes2_p.h
+++ b/src/render/renderers/opengl/graphicshelpers/graphicshelperes2_p.h
@@ -132,6 +132,12 @@ public:
void readBuffer(GLenum mode) override;
void drawBuffer(GLenum mode) override;
+ void *fenceSync() override;
+ void clientWaitSync(void *sync, GLuint64 nanoSecTimeout) override;
+ void waitSync(void *sync) override;
+ bool wasSyncSignaled(void *sync) override;
+ void deleteSync(void *sync) override;
+
void glUniform1fv(GLint location, GLsizei count, const GLfloat *value) override;
void glUniform2fv(GLint location, GLsizei count, const GLfloat *value) override;
void glUniform3fv(GLint location, GLsizei count, const GLfloat *value) override;
diff --git a/src/render/renderers/opengl/graphicshelpers/graphicshelperes3.cpp b/src/render/renderers/opengl/graphicshelpers/graphicshelperes3.cpp
index 34c1e7448..5e5d2e001 100644
--- a/src/render/renderers/opengl/graphicshelpers/graphicshelperes3.cpp
+++ b/src/render/renderers/opengl/graphicshelpers/graphicshelperes3.cpp
@@ -147,6 +147,26 @@ QT_BEGIN_NAMESPACE
#define GL_READ_FRAMEBUFFER 0x8CA8
#endif
+#ifndef GL_SIGNALED
+#define GL_SIGNALED 0x9119
+#endif
+
+#ifndef GL_SYNC_STATUS
+#define GL_SYNC_STATUS 0x9114
+#endif
+
+#ifndef GL_TIMEOUT_IGNORED
+#define GL_TIMEOUT_IGNORED 0xFFFFFFFFFFFFFFFFull
+#endif
+
+#ifndef GL_SYNC_GPU_COMMANDS_COMPLETE
+#define GL_SYNC_GPU_COMMANDS_COMPLETE 0x9117
+#endif
+
+#ifndef GL_SYNC_FLUSH_COMMANDS_BIT
+#define GL_SYNC_FLUSH_COMMANDS_BIT 0x00000001
+#endif
+
namespace Qt3DRender {
namespace Render {
@@ -307,6 +327,7 @@ bool GraphicsHelperES3::supportsFeature(GraphicsHelperInterface::Feature feature
case BlitFramebuffer:
case UniformBufferObject:
case MapBuffer:
+ case Fences:
return true;
default:
return false;
@@ -439,6 +460,37 @@ uint GraphicsHelperES3::uniformByteSize(const ShaderUniform &description)
return arrayStride ? rawByteSize * arrayStride : rawByteSize;
}
+void *GraphicsHelperES3::fenceSync()
+{
+ return m_extraFuncs->glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
+}
+
+void GraphicsHelperES3::clientWaitSync(void *sync, GLuint64 nanoSecTimeout)
+{
+ m_extraFuncs->glClientWaitSync(static_cast<GLsync>(sync), GL_SYNC_FLUSH_COMMANDS_BIT, nanoSecTimeout);
+}
+
+void GraphicsHelperES3::waitSync(void *sync)
+{
+ m_extraFuncs->glWaitSync(static_cast<GLsync>(sync), 0, GL_TIMEOUT_IGNORED);
+}
+
+bool GraphicsHelperES3::wasSyncSignaled(void *sync)
+{
+ GLint v;
+ m_extraFuncs->glGetSynciv(static_cast<GLsync>(sync),
+ GL_SYNC_STATUS,
+ sizeof(v),
+ nullptr,
+ &v);
+ return v == GL_SIGNALED;
+}
+
+void GraphicsHelperES3::deleteSync(void *sync)
+{
+ m_extraFuncs->glDeleteSync(static_cast<GLsync>(sync));
+}
+
void GraphicsHelperES3::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter)
{
m_extraFuncs->glBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
diff --git a/src/render/renderers/opengl/graphicshelpers/graphicshelperes3_p.h b/src/render/renderers/opengl/graphicshelpers/graphicshelperes3_p.h
index d4467cf7f..dc5cef10c 100644
--- a/src/render/renderers/opengl/graphicshelpers/graphicshelperes3_p.h
+++ b/src/render/renderers/opengl/graphicshelpers/graphicshelperes3_p.h
@@ -90,6 +90,12 @@ public:
UniformType uniformTypeFromGLType(GLenum glType) override;
uint uniformByteSize(const ShaderUniform &description) override;
+ void *fenceSync() override;
+ void clientWaitSync(void *sync, GLuint64 nanoSecTimeout) override;
+ void waitSync(void *sync) override;
+ bool wasSyncSignaled(void *sync) override;
+ void deleteSync(void *sync) override;
+
protected:
QOpenGLExtraFunctions *m_extraFuncs = nullptr;
};
diff --git a/src/render/renderers/opengl/graphicshelpers/graphicshelpergl2.cpp b/src/render/renderers/opengl/graphicshelpers/graphicshelpergl2.cpp
index 6da8a9b6f..b6f3412b2 100644
--- a/src/render/renderers/opengl/graphicshelpers/graphicshelpergl2.cpp
+++ b/src/render/renderers/opengl/graphicshelpers/graphicshelpergl2.cpp
@@ -272,6 +272,33 @@ void GraphicsHelperGL2::drawBuffer(GLenum mode)
m_funcs->glDrawBuffer(mode);
}
+void *GraphicsHelperGL2::fenceSync()
+{
+ qWarning() << "Fences are not supported by OpenGL 2.0 (since OpenGL 3.2)";
+ return nullptr;
+}
+
+void GraphicsHelperGL2::clientWaitSync(void *, GLuint64 )
+{
+ qWarning() << "Fences are not supported by OpenGL 2.0 (since OpenGL 3.2)";
+}
+
+void GraphicsHelperGL2::waitSync(void *)
+{
+ qWarning() << "Fences are not supported by OpenGL 2.0 (since OpenGL 3.2)";
+}
+
+bool GraphicsHelperGL2::wasSyncSignaled(void *)
+{
+ qWarning() << "Fences are not supported by OpenGL 2.0 (since OpenGL 3.2)";
+ return false;
+}
+
+void GraphicsHelperGL2::deleteSync(void *)
+{
+ qWarning() << "Fences are not supported by OpenGL 2.0 (since OpenGL 3.2)";
+}
+
void GraphicsHelperGL2::blendEquation(GLenum mode)
{
m_funcs->glBlendEquation(mode);
@@ -412,6 +439,7 @@ bool GraphicsHelperGL2::supportsFeature(GraphicsHelperInterface::Feature feature
case MRT:
return (m_fboFuncs != nullptr);
case TextureDimensionRetrieval:
+ case MapBuffer:
return true;
default:
return false;
diff --git a/src/render/renderers/opengl/graphicshelpers/graphicshelpergl2_p.h b/src/render/renderers/opengl/graphicshelpers/graphicshelpergl2_p.h
index 2db75004f..b142b2623 100644
--- a/src/render/renderers/opengl/graphicshelpers/graphicshelpergl2_p.h
+++ b/src/render/renderers/opengl/graphicshelpers/graphicshelpergl2_p.h
@@ -132,6 +132,12 @@ public:
void readBuffer(GLenum mode) override;
void drawBuffer(GLenum mode) override;
+ void *fenceSync() override;
+ void clientWaitSync(void *sync, GLuint64 nanoSecTimeout) override;
+ void waitSync(void *sync) override;
+ bool wasSyncSignaled(void *sync) override;
+ void deleteSync(void *sync) override;
+
void glUniform1fv(GLint location, GLsizei count, const GLfloat *value) override;
void glUniform2fv(GLint location, GLsizei count, const GLfloat *value) override;
void glUniform3fv(GLint location, GLsizei count, const GLfloat *value) override;
diff --git a/src/render/renderers/opengl/graphicshelpers/graphicshelpergl3_2.cpp b/src/render/renderers/opengl/graphicshelpers/graphicshelpergl3_2.cpp
index a35c4e37f..5ff1a2ba5 100644
--- a/src/render/renderers/opengl/graphicshelpers/graphicshelpergl3_2.cpp
+++ b/src/render/renderers/opengl/graphicshelpers/graphicshelpergl3_2.cpp
@@ -334,6 +334,37 @@ void GraphicsHelperGL3_2::drawBuffer(GLenum mode)
m_funcs->glDrawBuffer(mode);
}
+void *GraphicsHelperGL3_2::fenceSync()
+{
+ return m_funcs->glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
+}
+
+void GraphicsHelperGL3_2::clientWaitSync(void *sync, GLuint64 nanoSecTimeout)
+{
+ m_funcs->glClientWaitSync(static_cast<GLsync>(sync), GL_SYNC_FLUSH_COMMANDS_BIT, nanoSecTimeout);
+}
+
+void GraphicsHelperGL3_2::waitSync(void *sync)
+{
+ m_funcs->glWaitSync(static_cast<GLsync>(sync), 0, GL_TIMEOUT_IGNORED);
+}
+
+bool GraphicsHelperGL3_2::wasSyncSignaled(void *sync)
+{
+ GLint v;
+ m_funcs->glGetSynciv(static_cast<GLsync>(sync),
+ GL_SYNC_STATUS,
+ sizeof(v),
+ nullptr,
+ &v);
+ return v == GL_SIGNALED;
+}
+
+void GraphicsHelperGL3_2::deleteSync(void *sync)
+{
+ m_funcs->glDeleteSync(static_cast<GLsync>(sync));
+}
+
void GraphicsHelperGL3_2::blendEquation(GLenum mode)
{
m_funcs->glBlendEquation(mode);
@@ -481,6 +512,7 @@ bool GraphicsHelperGL3_2::supportsFeature(GraphicsHelperInterface::Feature featu
case TextureDimensionRetrieval:
case BindableFragmentOutputs:
case BlitFramebuffer:
+ case Fences:
return true;
case Tessellation:
return !m_tessFuncs.isNull();
diff --git a/src/render/renderers/opengl/graphicshelpers/graphicshelpergl3_2_p.h b/src/render/renderers/opengl/graphicshelpers/graphicshelpergl3_2_p.h
index 133295fd7..9e81345ad 100644
--- a/src/render/renderers/opengl/graphicshelpers/graphicshelpergl3_2_p.h
+++ b/src/render/renderers/opengl/graphicshelpers/graphicshelpergl3_2_p.h
@@ -134,6 +134,12 @@ public:
void readBuffer(GLenum mode) override;
void drawBuffer(GLenum mode) override;
+ void *fenceSync() override;
+ void clientWaitSync(void *sync, GLuint64 nanoSecTimeout) override;
+ void waitSync(void *sync) override;
+ bool wasSyncSignaled(void *sync) override;
+ void deleteSync(void *sync) override;
+
void glUniform1fv(GLint location, GLsizei count, const GLfloat *value) override;
void glUniform2fv(GLint location, GLsizei count, const GLfloat *value) override;
void glUniform3fv(GLint location, GLsizei count, const GLfloat *value) override;
diff --git a/src/render/renderers/opengl/graphicshelpers/graphicshelpergl3_3.cpp b/src/render/renderers/opengl/graphicshelpers/graphicshelpergl3_3.cpp
index b2512d84a..81081943d 100644
--- a/src/render/renderers/opengl/graphicshelpers/graphicshelpergl3_3.cpp
+++ b/src/render/renderers/opengl/graphicshelpers/graphicshelpergl3_3.cpp
@@ -330,6 +330,37 @@ void GraphicsHelperGL3_3::drawBuffer(GLenum mode)
m_funcs->glDrawBuffer(mode);
}
+void *GraphicsHelperGL3_3::fenceSync()
+{
+ return m_funcs->glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
+}
+
+void GraphicsHelperGL3_3::clientWaitSync(void *sync, GLuint64 nanoSecTimeout)
+{
+ m_funcs->glClientWaitSync(static_cast<GLsync>(sync), GL_SYNC_FLUSH_COMMANDS_BIT, nanoSecTimeout);
+}
+
+void GraphicsHelperGL3_3::waitSync(void *sync)
+{
+ m_funcs->glWaitSync(static_cast<GLsync>(sync), 0, GL_TIMEOUT_IGNORED);
+}
+
+bool GraphicsHelperGL3_3::wasSyncSignaled(void *sync)
+{
+ GLint v;
+ m_funcs->glGetSynciv(static_cast<GLsync>(sync),
+ GL_SYNC_STATUS,
+ sizeof(v),
+ nullptr,
+ &v);
+ return v == GL_SIGNALED;
+}
+
+void GraphicsHelperGL3_3::deleteSync(void *sync)
+{
+ m_funcs->glDeleteSync(static_cast<GLsync>(sync));
+}
+
void GraphicsHelperGL3_3::blendEquation(GLenum mode)
{
m_funcs->glBlendEquation(mode);
@@ -477,6 +508,7 @@ bool GraphicsHelperGL3_3::supportsFeature(GraphicsHelperInterface::Feature featu
case TextureDimensionRetrieval:
case BindableFragmentOutputs:
case BlitFramebuffer:
+ case Fences:
return true;
case Tessellation:
return !m_tessFuncs.isNull();
diff --git a/src/render/renderers/opengl/graphicshelpers/graphicshelpergl3_3_p.h b/src/render/renderers/opengl/graphicshelpers/graphicshelpergl3_3_p.h
index 0ecdd3620..c480e5258 100644
--- a/src/render/renderers/opengl/graphicshelpers/graphicshelpergl3_3_p.h
+++ b/src/render/renderers/opengl/graphicshelpers/graphicshelpergl3_3_p.h
@@ -134,6 +134,12 @@ public:
void readBuffer(GLenum mode) override;
void drawBuffer(GLenum mode) override;
+ void *fenceSync() override;
+ void clientWaitSync(void *sync, GLuint64 nanoSecTimeout) override;
+ void waitSync(void *sync) override;
+ bool wasSyncSignaled(void *sync) override;
+ void deleteSync(void *sync) override;
+
void glUniform1fv(GLint location, GLsizei count, const GLfloat *value) override;
void glUniform2fv(GLint location, GLsizei count, const GLfloat *value) override;
void glUniform3fv(GLint location, GLsizei count, const GLfloat *value) override;
diff --git a/src/render/renderers/opengl/graphicshelpers/graphicshelpergl4.cpp b/src/render/renderers/opengl/graphicshelpers/graphicshelpergl4.cpp
index ce1b8ac2b..22cbf7428 100644
--- a/src/render/renderers/opengl/graphicshelpers/graphicshelpergl4.cpp
+++ b/src/render/renderers/opengl/graphicshelpers/graphicshelpergl4.cpp
@@ -400,6 +400,39 @@ void GraphicsHelperGL4::drawBuffer(GLenum mode)
m_funcs->glDrawBuffer(mode);
}
+void *GraphicsHelperGL4::fenceSync()
+{
+ return m_funcs->glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
+}
+
+void GraphicsHelperGL4::clientWaitSync(void *sync, GLuint64 nanoSecTimeout)
+{
+ qDebug() << Q_FUNC_INFO << sync << static_cast<GLsync>(sync);
+ GLenum e = m_funcs->glClientWaitSync(static_cast<GLsync>(sync), GL_SYNC_FLUSH_COMMANDS_BIT, nanoSecTimeout);
+ qDebug() << e;
+}
+
+void GraphicsHelperGL4::waitSync(void *sync)
+{
+ m_funcs->glWaitSync(static_cast<GLsync>(sync), 0, GL_TIMEOUT_IGNORED);
+}
+
+bool GraphicsHelperGL4::wasSyncSignaled(void *sync)
+{
+ GLint v = 0;
+ m_funcs->glGetSynciv(static_cast<GLsync>(sync),
+ GL_SYNC_STATUS,
+ sizeof(v),
+ nullptr,
+ &v);
+ return v == GL_SIGNALED;
+}
+
+void GraphicsHelperGL4::deleteSync(void *sync)
+{
+ m_funcs->glDeleteSync(static_cast<GLsync>(sync));
+}
+
void GraphicsHelperGL4::glUniform1fv(GLint location, GLsizei count, const GLfloat *values)
{
m_funcs->glUniform1fv(location, count, values);
@@ -746,6 +779,8 @@ bool GraphicsHelperGL4::supportsFeature(GraphicsHelperInterface::Feature feature
case DrawBuffersBlend:
case BlitFramebuffer:
case IndirectDrawing:
+ case MapBuffer:
+ case Fences:
return true;
default:
return false;
diff --git a/src/render/renderers/opengl/graphicshelpers/graphicshelpergl4_p.h b/src/render/renderers/opengl/graphicshelpers/graphicshelpergl4_p.h
index 3020b16d8..da62f4212 100644
--- a/src/render/renderers/opengl/graphicshelpers/graphicshelpergl4_p.h
+++ b/src/render/renderers/opengl/graphicshelpers/graphicshelpergl4_p.h
@@ -132,6 +132,12 @@ public:
void readBuffer(GLenum mode) override;
void drawBuffer(GLenum mode) override;
+ void *fenceSync() override;
+ void clientWaitSync(void *sync, GLuint64 nanoSecTimeout) override;
+ void waitSync(void *sync) override;
+ bool wasSyncSignaled(void *sync) override;
+ void deleteSync(void *sync) override;
+
void glUniform1fv(GLint location, GLsizei count, const GLfloat *value) override;
void glUniform2fv(GLint location, GLsizei count, const GLfloat *value) override;
void glUniform3fv(GLint location, GLsizei count, const GLfloat *value) override;
diff --git a/src/render/renderers/opengl/graphicshelpers/graphicshelperinterface_p.h b/src/render/renderers/opengl/graphicshelpers/graphicshelperinterface_p.h
index e41325cb7..2a1688b7f 100644
--- a/src/render/renderers/opengl/graphicshelpers/graphicshelperinterface_p.h
+++ b/src/render/renderers/opengl/graphicshelpers/graphicshelperinterface_p.h
@@ -82,7 +82,8 @@ public:
DrawBuffersBlend,
BlitFramebuffer,
IndirectDrawing,
- MapBuffer
+ MapBuffer,
+ Fences
};
enum FBOBindMode {
@@ -155,6 +156,12 @@ public:
virtual void readBuffer(GLenum mode) = 0;
virtual void drawBuffer(GLenum mode) = 0;
+ virtual void *fenceSync() = 0;
+ virtual void clientWaitSync(void *sync, GLuint64 nanoSecTimeout) = 0;
+ virtual void waitSync(void *sync) = 0;
+ virtual bool wasSyncSignaled(void *sync) = 0;
+ virtual void deleteSync(void *sync) = 0;
+
virtual void glUniform1fv(GLint location, GLsizei count, const GLfloat *value) = 0;
virtual void glUniform2fv(GLint location, GLsizei count, const GLfloat *value) = 0;
virtual void glUniform3fv(GLint location, GLsizei count, const GLfloat *value) = 0;
diff --git a/src/render/renderers/opengl/graphicshelpers/graphicshelpers.pri b/src/render/renderers/opengl/graphicshelpers/graphicshelpers.pri
index 9b25be0eb..5c9479d2b 100644
--- a/src/render/renderers/opengl/graphicshelpers/graphicshelpers.pri
+++ b/src/render/renderers/opengl/graphicshelpers/graphicshelpers.pri
@@ -13,7 +13,8 @@ HEADERS += \
$$PWD/graphicshelpergl3_3_p.h \
$$PWD/graphicshelpergl4_p.h \
$$PWD/graphicshelpergl3_2_p.h \
- $$PWD/submissioncontext_p.h
+ $$PWD/submissioncontext_p.h \
+ $$PWD/glfence_p.h
SOURCES += \
$$PWD/graphicscontext.cpp \
diff --git a/src/render/renderers/opengl/graphicshelpers/submissioncontext.cpp b/src/render/renderers/opengl/graphicshelpers/submissioncontext.cpp
index e7ebf3322..7900db879 100644
--- a/src/render/renderers/opengl/graphicshelpers/submissioncontext.cpp
+++ b/src/render/renderers/opengl/graphicshelpers/submissioncontext.cpp
@@ -1258,6 +1258,33 @@ void SubmissionContext::clearStencilValue(int stencil)
}
}
+GLFence SubmissionContext::fenceSync()
+{
+ return m_glHelper->fenceSync();
+}
+
+void SubmissionContext::clientWaitSync(GLFence sync, GLuint64 nanoSecTimeout)
+{
+ qDebug() << Q_FUNC_INFO << sync;
+ m_glHelper->clientWaitSync(sync, nanoSecTimeout);
+}
+
+void SubmissionContext::waitSync(GLFence sync)
+{
+ qDebug() << Q_FUNC_INFO << sync;
+ m_glHelper->waitSync(sync);
+}
+
+bool SubmissionContext::wasSyncSignaled(GLFence sync)
+{
+ return m_glHelper->wasSyncSignaled(sync);
+}
+
+void SubmissionContext::deleteSync(GLFence sync)
+{
+ m_glHelper->deleteSync(sync);
+}
+
// It will be easier if the QGraphicContext applies the QUniformPack
// than the other way around
bool SubmissionContext::setParameters(ShaderParameterPack &parameterPack)
diff --git a/src/render/renderers/opengl/graphicshelpers/submissioncontext_p.h b/src/render/renderers/opengl/graphicshelpers/submissioncontext_p.h
index d502a8b27..dbfaef148 100644
--- a/src/render/renderers/opengl/graphicshelpers/submissioncontext_p.h
+++ b/src/render/renderers/opengl/graphicshelpers/submissioncontext_p.h
@@ -59,6 +59,7 @@
#include <Qt3DRender/qattribute.h>
#include <Qt3DRender/private/handle_types_p.h>
#include <Qt3DRender/private/shadercache_p.h>
+#include <Qt3DRender/private/glfence_p.h>
QT_BEGIN_NAMESPACE
@@ -163,6 +164,14 @@ public:
void clearDepthValue(float depth);
void clearStencilValue(int stencil);
+
+ // Fences
+ GLFence fenceSync();
+ void clientWaitSync(GLFence sync, GLuint64 nanoSecTimeout);
+ void waitSync(GLFence sync);
+ bool wasSyncSignaled(GLFence sync);
+ void deleteSync(GLFence sync);
+
private:
void initialize();
diff --git a/src/render/renderers/opengl/jobs/renderviewjobutils.cpp b/src/render/renderers/opengl/jobs/renderviewjobutils.cpp
index 629e7e935..9dd7faacc 100644
--- a/src/render/renderers/opengl/jobs/renderviewjobutils.cpp
+++ b/src/render/renderers/opengl/jobs/renderviewjobutils.cpp
@@ -68,6 +68,7 @@
#include <Qt3DRender/private/techniquemanager_p.h>
#include <Qt3DRender/private/memorybarrier_p.h>
#include <Qt3DRender/private/blitframebuffer_p.h>
+#include <Qt3DRender/private/waitfence_p.h>
QT_BEGIN_NAMESPACE
@@ -272,6 +273,17 @@ void setRenderViewConfigFromFrameGraphLeafNode(RenderView *rv, const FrameGraphN
break;
}
+ case FrameGraphNode::WaitFence: {
+ const Render::WaitFence *waitFence = static_cast<const Render::WaitFence *>(node);
+ rv->appendWaitFence(waitFence->data());
+ break;
+ }
+
+ case FrameGraphNode::SetFence: {
+ rv->appendInsertFenceId(node->peerId());
+ break;
+ }
+
default:
// Should never get here
qCWarning(Backend) << "Unhandled FrameGraphNode type";
diff --git a/src/render/renderers/opengl/renderer/renderer.cpp b/src/render/renderers/opengl/renderer/renderer.cpp
index 79afda1cc..d71256484 100644
--- a/src/render/renderers/opengl/renderer/renderer.cpp
+++ b/src/render/renderers/opengl/renderer/renderer.cpp
@@ -91,6 +91,7 @@
#include <Qt3DRender/private/renderviewbuilder_p.h>
#include <Qt3DRender/private/commandthread_p.h>
#include <Qt3DRender/private/glcommands_p.h>
+#include <Qt3DRender/private/setfence_p.h>
#include <Qt3DRender/qcameralens.h>
#include <Qt3DCore/private/qeventfilterservice_p.h>
@@ -195,6 +196,7 @@ Renderer::Renderer(QRenderAspect::RenderType type)
, m_vaoGathererJob(Render::GenericLambdaJobPtr<std::function<void ()>>::create([this] { lookForAbandonedVaos(); }, JobTypes::DirtyVaoGathering))
, m_textureGathererJob(Render::GenericLambdaJobPtr<std::function<void ()>>::create([this] { lookForDirtyTextures(); }, JobTypes::DirtyTextureGathering))
, m_sendTextureChangesToFrontendJob(Render::GenericLambdaJobPtr<std::function<void ()>>::create([this] { sendTextureChangesToFrontend(); }, JobTypes::SendTextureChangesToFrontend))
+ , m_sendSetFenceHandlesToFrontendJob(Render::GenericLambdaJobPtr<std::function<void ()>>::create([this] { sendSetFenceHandlesToFrontend(); }, JobTypes::SendSetFenceHandlesToFrontend))
, m_introspectShaderJob(Render::GenericLambdaJobPtr<std::function<void ()>>::create([this] { reloadDirtyShaders(); }, JobTypes::DirtyShaderGathering))
, m_syncTextureLoadingJob(Render::GenericLambdaJobPtr<std::function<void ()>>::create([] {}, JobTypes::SyncTextureLoading))
, m_ownedContext(false)
@@ -1194,6 +1196,22 @@ void Renderer::sendTextureChangesToFrontend()
}
}
+// Executed in a job
+void Renderer::sendSetFenceHandlesToFrontend()
+{
+ const QVector<QPair<Qt3DCore::QNodeId, GLFence>> updatedSetFence = std::move(m_updatedSetFences);
+ FrameGraphManager *fgManager = m_nodesManager->frameGraphManager();
+ for (const auto &pair : updatedSetFence) {
+ FrameGraphNode *fgNode = fgManager->lookupNode(pair.first);
+ if (fgNode != nullptr) { // Node could have been deleted before we got a chance to notify it
+ Q_ASSERT(fgNode->nodeType() == FrameGraphNode::SetFence);
+ SetFence *setFenceNode = static_cast<SetFence *>(fgNode);
+ setFenceNode->setHandleType(QSetFence::OpenGLFenceId);
+ setFenceNode->setHandle(QVariant::fromValue(pair.second));
+ }
+ }
+}
+
// Render Thread (or QtQuick RenderThread when using Scene3D)
// Scene3D: When using Scene3D rendering, we can't assume that when
// updateGLResources is called, the resource handles points to still existing
@@ -1207,6 +1225,25 @@ void Renderer::sendTextureChangesToFrontend()
void Renderer::updateGLResources()
{
{
+ // Update active fence objects:
+ // - Destroy fences that have reached their signaled state
+ GLFenceManager *fenceManager = m_nodesManager->glFenceManager();
+ const auto end = fenceManager->end();
+ auto it = fenceManager->begin();
+ while (it != end) {
+ const GLFence fence = it.value();
+ if (m_submissionContext->wasSyncSignaled(fence)) {
+ // Fence was signaled, we delete it
+ // before removing the entry from the manager
+ m_submissionContext->deleteSync(fence);
+ it = fenceManager->erase(it);
+ } else {
+ ++it;
+ }
+ }
+ }
+
+ {
Profiling::GLTimeRecorder recorder(Profiling::BufferUpload);
const QVector<HBuffer> dirtyBufferHandles = std::move(m_dirtyBuffers);
for (const HBuffer &handle: dirtyBufferHandles) {
@@ -1397,6 +1434,7 @@ void Renderer::cleanupTexture(Qt3DCore::QNodeId cleanedUpTextureId)
glTextureManager->abandon(glTexture, cleanedUpTextureId);
}
+// Called by SubmitRenderView
void Renderer::downloadGLBuffers()
{
lookForDownloadableBuffers();
@@ -1481,6 +1519,45 @@ Renderer::ViewSubmissionResultData Renderer::submitRenderViews(const QVector<Ren
if (renderView->memoryBarrier() != QMemoryBarrier::None)
m_submissionContext->memoryBarrier(renderView->memoryBarrier());
+
+ // Insert Fence into command stream if needed
+ const Qt3DCore::QNodeIdVector insertFenceIds = renderView->insertFenceIds();
+ GLFenceManager *fenceManager = m_nodesManager->glFenceManager();
+ for (const Qt3DCore::QNodeId insertFenceId : insertFenceIds) {
+ // If the fence is not in the manager, then it hasn't been inserted
+ // into the command stream yet.
+ if (fenceManager->find(insertFenceId) == fenceManager->end()) {
+ // Insert fence into command stream
+ GLFence glFence = m_submissionContext->fenceSync();
+ // Record glFence
+ fenceManager->insert(insertFenceId, glFence);
+ // Add entry for notification changes to be sent
+ m_updatedSetFences.push_back({insertFenceId, glFence});
+ }
+ // If it is in the manager, then it hasn't been signaled yet,
+ // nothing we can do but try at the next frame
+ }
+
+ // Wait for fences if needed
+ const QVector<QWaitFenceData> waitFences = renderView->waitFences();
+ for (const QWaitFenceData &waitFence : waitFences) {
+ // TO DO
+ if (waitFence.handleType != QWaitFence::OpenGLFenceId) {
+ qWarning() << "WaitFence handleType should be OpenGLFenceId when using the Qt 3D OpenGL renderer";
+ continue;
+ }
+ GLFence fence = reinterpret_cast<GLFence>(waitFence.handle.value<qintptr>());
+ if (fence == nullptr)
+ continue;
+
+ if (waitFence.waitOnCPU) {
+ m_submissionContext->clientWaitSync(fence,
+ waitFence.timeout);
+ } else {
+ m_submissionContext->waitSync(fence);
+ }
+ }
+
// Note: the RenderStateSet is allocated once per RV if needed
// and it contains a list of StateVariant value types
RenderStateSet *renderViewStateSet = renderView->stateSet();
@@ -1646,6 +1723,33 @@ void Renderer::skipNextFrame()
m_submitRenderViewsSemaphore.release(1);
}
+// Jobs we may have to run even if no rendering will happen
+QVector<QAspectJobPtr> Renderer::preRenderingJobs()
+{
+ QVector<QAspectJobPtr> jobs;
+
+ // Do we need to notify any texture about property changes?
+ if (m_updatedTextureProperties.size() > 0)
+ jobs.push_back(m_sendTextureChangesToFrontendJob);
+
+ // Do we need to notify frontend about fence change?
+ if (m_updatedSetFences.size() > 0)
+ jobs.push_back(m_sendSetFenceHandlesToFrontendJob);
+
+ const QVector<Qt3DCore::QNodeId> pendingCaptureIds = takePendingRenderCaptureSendRequests();
+ if (pendingCaptureIds.size() > 0) {
+ m_sendRenderCaptureJob->setPendingCaptureRequests(pendingCaptureIds);
+ jobs.push_back(m_sendRenderCaptureJob);
+ }
+ if (m_sendBufferCaptureJob->hasRequests())
+ jobs.push_back(m_sendBufferCaptureJob);
+
+ jobs.append(pickBoundingVolumeJob());
+ jobs.append(rayCastingJob());
+
+ return jobs;
+}
+
// Waits to be told to create jobs for the next frame
// Called by QRenderAspect jobsToExecute context of QAspectThread
// Returns all the jobs (and with proper dependency chain) required
@@ -1702,17 +1806,6 @@ QVector<Qt3DCore::QAspectJobPtr> Renderer::renderBinJobs()
renderBinJobs.push_back(m_updateLevelOfDetailJob);
renderBinJobs.push_back(m_cleanupJob);
- const QVector<Qt3DCore::QNodeId> pendingCaptureIds = takePendingRenderCaptureSendRequests();
- if (pendingCaptureIds.size() > 0) {
- m_sendRenderCaptureJob->setPendingCaptureRequests(pendingCaptureIds);
- renderBinJobs.push_back(m_sendRenderCaptureJob);
- }
-
- // Do we need to notify any texture about property changes?
- if (m_updatedTextureProperties.size() > 0)
- renderBinJobs.push_back(m_sendTextureChangesToFrontendJob);
-
- renderBinJobs.push_back(m_sendBufferCaptureJob);
renderBinJobs.append(bufferJobs);
// Jobs to prepare GL Resource upload
diff --git a/src/render/renderers/opengl/renderer/renderer_p.h b/src/render/renderers/opengl/renderer/renderer_p.h
index 5bd03142f..93d6fdbfa 100644
--- a/src/render/renderers/opengl/renderer/renderer_p.h
+++ b/src/render/renderers/opengl/renderer/renderer_p.h
@@ -80,6 +80,7 @@
#include <Qt3DRender/private/updateentitylayersjob_p.h>
#include <Qt3DRender/private/renderercache_p.h>
#include <Qt3DRender/private/texture_p.h>
+#include <Qt3DRender/private/glfence_p.h>
#include <QHash>
#include <QMatrix4x4>
@@ -96,6 +97,10 @@
#include <functional>
+#if defined(QT_BUILD_INTERNAL)
+class tst_Renderer;
+#endif
+
QT_BEGIN_NAMESPACE
class QSurface;
@@ -195,6 +200,7 @@ public:
bool shouldRender() override;
void skipNextFrame() override;
+ QVector<Qt3DCore::QAspectJobPtr> preRenderingJobs() override;
QVector<Qt3DCore::QAspectJobPtr> renderBinJobs() override;
Qt3DCore::QAspectJobPtr pickBoundingVolumeJob() override;
Qt3DCore::QAspectJobPtr rayCastingJob() override;
@@ -373,6 +379,7 @@ private:
GenericLambdaJobPtr<std::function<void ()>> m_vaoGathererJob;
GenericLambdaJobPtr<std::function<void ()>> m_textureGathererJob;
GenericLambdaJobPtr<std::function<void ()>> m_sendTextureChangesToFrontendJob;
+ GenericLambdaJobPtr<std::function<void ()>> m_sendSetFenceHandlesToFrontendJob;
IntrospectShadersJobPtr m_introspectShaderJob;
SynchronizerJobPtr m_syncTextureLoadingJob;
@@ -383,6 +390,7 @@ private:
void lookForDirtyTextures();
void reloadDirtyShaders();
void sendTextureChangesToFrontend();
+ void sendSetFenceHandlesToFrontend();
QMutex m_abandonedVaosMutex;
QVector<HVao> m_abandonedVaos;
@@ -392,6 +400,7 @@ private:
QVector<HShader> m_dirtyShaders;
QVector<HTexture> m_dirtyTextures;
QVector<QPair<Texture::TextureUpdateInfo, Qt3DCore::QNodeIdVector>> m_updatedTextureProperties;
+ QVector<QPair<Qt3DCore::QNodeId, GLFence>> m_updatedSetFences;
bool m_ownedContext;
@@ -403,6 +412,10 @@ private:
friend class Qt3DRender::Debug::CommandExecuter;
#endif
+#ifdef QT_BUILD_INTERNAL
+ friend class ::tst_Renderer;
+#endif
+
QMetaObject::Connection m_contextConnection;
RendererCache m_cache;
};
diff --git a/src/render/renderers/opengl/renderer/renderview_p.h b/src/render/renderers/opengl/renderer/renderview_p.h
index cb3c74917..7ebcdb6bd 100644
--- a/src/render/renderers/opengl/renderer/renderview_p.h
+++ b/src/render/renderers/opengl/renderer/renderview_p.h
@@ -65,6 +65,7 @@
#include <Qt3DRender/private/qmemorybarrier_p.h>
#include <Qt3DRender/private/qrendercapture_p.h>
#include <Qt3DRender/private/qblitframebuffer_p.h>
+#include <Qt3DRender/private/qwaitfence_p.h>
#include <Qt3DCore/private/qframeallocator_p.h>
#include <Qt3DRender/private/aligned_malloc_p.h>
@@ -174,6 +175,13 @@ public:
inline void appendProximityFilterId(const Qt3DCore::QNodeId proximityFilterId) { m_data.m_proximityFilterIds.push_back(proximityFilterId); }
inline Qt3DCore::QNodeIdVector proximityFilterIds() const { return m_data.m_proximityFilterIds; }
+ inline void appendInsertFenceId(const Qt3DCore::QNodeId setFenceId) { m_insertFenceIds.push_back(setFenceId); }
+ // We prefix with get to avoid confusion when it is called
+ inline Qt3DCore::QNodeIdVector insertFenceIds() const { return m_insertFenceIds; }
+
+ inline void appendWaitFence(const QWaitFenceData &data) { m_waitFences.push_back(data); }
+ inline QVector<QWaitFenceData> waitFences() const { return m_waitFences; }
+
inline void setRenderPassFilter(const RenderPassFilter *rpFilter) Q_DECL_NOTHROW { m_data.m_passFilter = rpFilter; }
inline const RenderPassFilter *renderPassFilter() const Q_DECL_NOTHROW { return m_data.m_passFilter; }
@@ -320,6 +328,8 @@ private:
bool m_frustumCulling:1;
int m_workGroups[3];
QMemoryBarrier::Operations m_memoryBarrier;
+ QVector<Qt3DCore::QNodeId> m_insertFenceIds;
+ QVector<QWaitFenceData> m_waitFences;
// We do not use pointers to RenderNodes or Drawable's here so that the
// render aspect is free to change the drawables on the next frame whilst
diff --git a/tests/auto/render/commons/testrenderer.h b/tests/auto/render/commons/testrenderer.h
index 466cebe14..f19b3211b 100644
--- a/tests/auto/render/commons/testrenderer.h
+++ b/tests/auto/render/commons/testrenderer.h
@@ -57,6 +57,7 @@ public:
bool isRunning() const override { return true; }
bool shouldRender() override { return true; }
void skipNextFrame() override {}
+ QVector<Qt3DCore::QAspectJobPtr> preRenderingJobs() override { return QVector<Qt3DCore::QAspectJobPtr>(); }
QVector<Qt3DCore::QAspectJobPtr> renderBinJobs() override { return QVector<Qt3DCore::QAspectJobPtr>(); }
Qt3DCore::QAspectJobPtr pickBoundingVolumeJob() override { return Qt3DCore::QAspectJobPtr(); }
Qt3DCore::QAspectJobPtr rayCastingJob() override { return Qt3DCore::QAspectJobPtr(); }
diff --git a/tests/auto/render/graphicshelpergl2/tst_graphicshelpergl2.cpp b/tests/auto/render/graphicshelpergl2/tst_graphicshelpergl2.cpp
index 584b675ee..c34372f70 100644
--- a/tests/auto/render/graphicshelpergl2/tst_graphicshelpergl2.cpp
+++ b/tests/auto/render/graphicshelpergl2/tst_graphicshelpergl2.cpp
@@ -926,6 +926,9 @@ private Q_SLOTS:
SUPPORTS_FEATURE(GraphicsHelperInterface::DrawBuffersBlend, false);
SUPPORTS_FEATURE(GraphicsHelperInterface::Tessellation, false);
SUPPORTS_FEATURE(GraphicsHelperInterface::BlitFramebuffer, false);
+ SUPPORTS_FEATURE(GraphicsHelperInterface::IndirectDrawing, false);
+ SUPPORTS_FEATURE(GraphicsHelperInterface::MapBuffer, true);
+ SUPPORTS_FEATURE(GraphicsHelperInterface::Fences, false);
}
@@ -1524,6 +1527,36 @@ private Q_SLOTS:
// Not supported by GL2
}
+ void fenceSync()
+ {
+ QSKIP("Initialization failed, OpenGL 2.0 functions not supported");
+ // Not supported by GL2
+ }
+
+ void clientWaitSync()
+ {
+ QSKIP("Initialization failed, OpenGL 2.0 functions not supported");
+ // Not supported by GL2
+ }
+
+ void waitSync()
+ {
+ QSKIP("Initialization failed, OpenGL 2.0 functions not supported");
+ // Not supported by GL2
+ }
+
+ void wasSyncSignaled()
+ {
+ QSKIP("Initialization failed, OpenGL 2.0 functions not supported");
+ // Not supported by GL2
+ }
+
+ void deleteSync()
+ {
+ QSKIP("Initialization failed, OpenGL 2.0 functions not supported");
+ // Not supported by GL2
+ }
+
private:
QScopedPointer<QWindow> m_window;
QOpenGLContext m_glContext;
diff --git a/tests/auto/render/graphicshelpergl3_2/tst_graphicshelpergl3_2.cpp b/tests/auto/render/graphicshelpergl3_2/tst_graphicshelpergl3_2.cpp
index 648eaaddb..3ef8de6ec 100644
--- a/tests/auto/render/graphicshelpergl3_2/tst_graphicshelpergl3_2.cpp
+++ b/tests/auto/render/graphicshelpergl3_2/tst_graphicshelpergl3_2.cpp
@@ -2151,6 +2151,105 @@ private Q_SLOTS:
QCOMPARE(p, GL_FRONT);
}
+ void fenceSync()
+ {
+ if (!m_initializationSuccessful)
+ QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported");
+
+ m_func->glGetError();
+
+ // WHEN
+ GLsync sync = reinterpret_cast<GLsync>(m_glHelper.fenceSync());
+
+ // THEN
+ QVERIFY(sync != nullptr);
+ QCOMPARE(m_func->glIsSync(sync), GL_TRUE);
+ const GLint error = m_func->glGetError();
+ QVERIFY(error == 0);
+ }
+
+ void clientWaitSync()
+ {
+ if (!m_initializationSuccessful)
+ QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported");
+
+ m_func->glGetError();
+
+ // WHEN
+ QElapsedTimer t;
+ t.start();
+
+ GLsync sync = reinterpret_cast<GLsync>(m_glHelper.fenceSync());
+
+ m_glHelper.clientWaitSync(sync, 1000000);
+
+ // THEN
+ const GLint error = m_func->glGetError();
+ QVERIFY(error == 0);
+ qDebug() << t.nsecsElapsed();
+ }
+
+ void waitSync()
+ {
+ if (!m_initializationSuccessful)
+ QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported");
+
+ m_func->glGetError();
+
+ // WHEN
+ GLsync sync = reinterpret_cast<GLsync>(m_glHelper.fenceSync());
+ m_func->glFlush();
+ m_glHelper.waitSync(sync);
+
+ // THEN
+ const GLint error = m_func->glGetError();
+ QVERIFY(error == 0);
+ }
+
+ void wasSyncSignaled()
+ {
+ if (!m_initializationSuccessful)
+ QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported");
+
+ m_func->glGetError();
+
+ // WHEN
+ GLsync sync = reinterpret_cast<GLsync>(m_glHelper.fenceSync());
+ m_func->glFlush();
+ m_glHelper.waitSync(sync);
+
+ // THEN
+ const GLint error = m_func->glGetError();
+ QVERIFY(error == 0);
+
+ // Shouldn't loop forever
+ while (!m_glHelper.wasSyncSignaled(sync))
+ ;
+ }
+
+ void deleteSync()
+ {
+ if (!m_initializationSuccessful)
+ QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported");
+
+ m_func->glGetError();
+
+ // WHEN
+ GLsync sync = reinterpret_cast<GLsync>(m_glHelper.fenceSync());
+ m_glHelper.clientWaitSync(sync, GLuint64(-1));
+
+ // THEN
+ const GLint error = m_func->glGetError();
+ QVERIFY(error == 0);
+ QVERIFY(m_glHelper.wasSyncSignaled(sync) == true);
+
+ // WHEN
+ m_glHelper.deleteSync(sync);
+
+ // THEN
+ QCOMPARE(m_func->glIsSync(sync), GL_FALSE);
+ }
+
private:
QScopedPointer<QWindow> m_window;
QOpenGLContext m_glContext;
diff --git a/tests/auto/render/graphicshelpergl3_3/tst_graphicshelpergl3_3.cpp b/tests/auto/render/graphicshelpergl3_3/tst_graphicshelpergl3_3.cpp
index 06a3c41cd..a6a41ffd4 100644
--- a/tests/auto/render/graphicshelpergl3_3/tst_graphicshelpergl3_3.cpp
+++ b/tests/auto/render/graphicshelpergl3_3/tst_graphicshelpergl3_3.cpp
@@ -2251,6 +2251,105 @@ private Q_SLOTS:
QCOMPARE(p, GL_FRONT);
}
+ void fenceSync()
+ {
+ if (!m_initializationSuccessful)
+ QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported");
+
+ m_func->glGetError();
+
+ // WHEN
+ GLsync sync = reinterpret_cast<GLsync>(m_glHelper.fenceSync());
+
+ // THEN
+ QVERIFY(sync != nullptr);
+ QCOMPARE(m_func->glIsSync(sync), GL_TRUE);
+ const GLint error = m_func->glGetError();
+ QVERIFY(error == 0);
+ }
+
+ void clientWaitSync()
+ {
+ if (!m_initializationSuccessful)
+ QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported");
+
+ m_func->glGetError();
+
+ // WHEN
+ QElapsedTimer t;
+ t.start();
+
+ GLsync sync = reinterpret_cast<GLsync>(m_glHelper.fenceSync());
+
+ m_glHelper.clientWaitSync(sync, 1000000);
+
+ // THEN
+ const GLint error = m_func->glGetError();
+ QVERIFY(error == 0);
+ qDebug() << t.nsecsElapsed();
+ }
+
+ void waitSync()
+ {
+ if (!m_initializationSuccessful)
+ QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported");
+
+ m_func->glGetError();
+
+ // WHEN
+ GLsync sync = reinterpret_cast<GLsync>(m_glHelper.fenceSync());
+ m_func->glFlush();
+ m_glHelper.waitSync(sync);
+
+ // THEN
+ const GLint error = m_func->glGetError();
+ QVERIFY(error == 0);
+ }
+
+ void wasSyncSignaled()
+ {
+ if (!m_initializationSuccessful)
+ QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported");
+
+ m_func->glGetError();
+
+ // WHEN
+ GLsync sync = reinterpret_cast<GLsync>(m_glHelper.fenceSync());
+ m_func->glFlush();
+ m_glHelper.waitSync(sync);
+
+ // THEN
+ const GLint error = m_func->glGetError();
+ QVERIFY(error == 0);
+
+ // Shouldn't loop forever
+ while (!m_glHelper.wasSyncSignaled(sync))
+ ;
+ }
+
+ void deleteSync()
+ {
+ if (!m_initializationSuccessful)
+ QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported");
+
+ m_func->glGetError();
+
+ // WHEN
+ GLsync sync = reinterpret_cast<GLsync>(m_glHelper.fenceSync());
+ m_glHelper.clientWaitSync(sync, GLuint64(-1));
+
+ // THEN
+ const GLint error = m_func->glGetError();
+ QVERIFY(error == 0);
+ QVERIFY(m_glHelper.wasSyncSignaled(sync) == true);
+
+ // WHEN
+ m_glHelper.deleteSync(sync);
+
+ // THEN
+ QCOMPARE(m_func->glIsSync(sync), GL_FALSE);
+ }
+
private:
QScopedPointer<QWindow> m_window;
QOpenGLContext m_glContext;
diff --git a/tests/auto/render/graphicshelpergl4/tst_graphicshelpergl4.cpp b/tests/auto/render/graphicshelpergl4/tst_graphicshelpergl4.cpp
index 39bd15021..6632f65de 100644
--- a/tests/auto/render/graphicshelpergl4/tst_graphicshelpergl4.cpp
+++ b/tests/auto/render/graphicshelpergl4/tst_graphicshelpergl4.cpp
@@ -1430,7 +1430,7 @@ private Q_SLOTS:
void supportsFeature()
{
- for (int i = 0; i <= GraphicsHelperInterface::BlitFramebuffer; ++i)
+ for (int i = 0; i <= GraphicsHelperInterface::Fences; ++i)
QVERIFY(m_glHelper.supportsFeature(static_cast<GraphicsHelperInterface::Feature>(i)));
}
@@ -2349,6 +2349,105 @@ private Q_SLOTS:
QCOMPARE(p, GL_FRONT);
}
+ void fenceSync()
+ {
+ if (!m_initializationSuccessful)
+ QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported");
+
+ m_func->glGetError();
+
+ // WHEN
+ GLsync sync = reinterpret_cast<GLsync>(m_glHelper.fenceSync());
+
+ // THEN
+ QVERIFY(sync != nullptr);
+ QCOMPARE(m_func->glIsSync(sync), GL_TRUE);
+ const GLint error = m_func->glGetError();
+ QVERIFY(error == 0);
+ }
+
+ void clientWaitSync()
+ {
+ if (!m_initializationSuccessful)
+ QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported");
+
+ m_func->glGetError();
+
+ // WHEN
+ QElapsedTimer t;
+ t.start();
+
+ GLsync sync = reinterpret_cast<GLsync>(m_glHelper.fenceSync());
+
+ m_glHelper.clientWaitSync(sync, 1000000);
+
+ // THEN
+ const GLint error = m_func->glGetError();
+ QVERIFY(error == 0);
+ qDebug() << t.nsecsElapsed();
+ }
+
+ void waitSync()
+ {
+ if (!m_initializationSuccessful)
+ QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported");
+
+ m_func->glGetError();
+
+ // WHEN
+ GLsync sync = reinterpret_cast<GLsync>(m_glHelper.fenceSync());
+ m_func->glFlush();
+ m_glHelper.waitSync(sync);
+
+ // THEN
+ const GLint error = m_func->glGetError();
+ QVERIFY(error == 0);
+ }
+
+ void wasSyncSignaled()
+ {
+ if (!m_initializationSuccessful)
+ QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported");
+
+ m_func->glGetError();
+
+ // WHEN
+ GLsync sync = reinterpret_cast<GLsync>(m_glHelper.fenceSync());
+ m_func->glFlush();
+ m_glHelper.waitSync(sync);
+
+ // THEN
+ const GLint error = m_func->glGetError();
+ QVERIFY(error == 0);
+
+ // Shouldn't loop forever
+ while (!m_glHelper.wasSyncSignaled(sync))
+ ;
+ }
+
+ void deleteSync()
+ {
+ if (!m_initializationSuccessful)
+ QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported");
+
+ m_func->glGetError();
+
+ // WHEN
+ GLsync sync = reinterpret_cast<GLsync>(m_glHelper.fenceSync());
+ m_glHelper.clientWaitSync(sync, GLuint64(-1));
+
+ // THEN
+ const GLint error = m_func->glGetError();
+ QVERIFY(error == 0);
+ QVERIFY(m_glHelper.wasSyncSignaled(sync) == true);
+
+ // WHEN
+ m_glHelper.deleteSync(sync);
+
+ // THEN
+ QCOMPARE(m_func->glIsSync(sync), GL_FALSE);
+ }
+
private:
QScopedPointer<QWindow> m_window;
QOpenGLContext m_glContext;
diff --git a/tests/auto/render/renderer/tst_renderer.cpp b/tests/auto/render/renderer/tst_renderer.cpp
index 9f6007181..bd1f7185e 100644
--- a/tests/auto/render/renderer/tst_renderer.cpp
+++ b/tests/auto/render/renderer/tst_renderer.cpp
@@ -44,6 +44,88 @@ public :
~tst_Renderer() {}
private Q_SLOTS:
+
+ void checkPreRenderBinJobs()
+ {
+ // GIVEN
+ Qt3DRender::Render::NodeManagers nodeManagers;
+ Qt3DRender::Render::Renderer renderer(Qt3DRender::QRenderAspect::Synchronous);
+ Qt3DRender::Render::OffscreenSurfaceHelper offscreenHelper(&renderer);
+ Qt3DRender::Render::RenderSettings settings;
+ // owned by FG manager
+ Qt3DRender::Render::ViewportNode *fgRoot = new Qt3DRender::Render::ViewportNode();
+ const Qt3DCore::QNodeId fgRootId = Qt3DCore::QNodeId::createId();
+
+ nodeManagers.frameGraphManager()->appendNode(fgRootId, fgRoot);
+ settings.setActiveFrameGraphId(fgRootId);
+
+ renderer.setNodeManagers(&nodeManagers);
+ renderer.setSettings(&settings);
+ renderer.setOffscreenSurfaceHelper(&offscreenHelper);
+ renderer.initialize();
+
+ // Ensure invoke calls are performed
+ QCoreApplication::processEvents();
+
+ // WHEN (nothing dirty, no buffers, no layers to be rebuilt, no materials to be rebuilt)
+ QVector<Qt3DCore::QAspectJobPtr> jobs = renderer.preRenderingJobs();
+
+ // THEN
+ QCOMPARE(jobs.size(),
+ 1 + // PickBoundingVolumeJob
+ 1); // RayCastingJob
+
+ // WHEN
+ renderer.addRenderCaptureSendRequest(Qt3DCore::QNodeId::createId());
+ jobs = renderer.preRenderingJobs();
+
+ // THEN
+ QCOMPARE(jobs.size(),
+ 1 + // PickBoundingVolumeJob
+ 1 + // RayCastingJob
+ 1); // SendRenderCaptureJob
+
+ // WHEN
+ renderer.m_sendBufferCaptureJob->addRequest({nullptr, {}});
+ jobs = renderer.preRenderingJobs();
+
+ // THEN
+ QCOMPARE(jobs.size(),
+ 1 + // PickBoundingVolumeJob
+ 1 + // RayCastingJob
+ 1); // SendBufferCaptureJob
+ // Note: pending render buffer captures are only cleared when the job is run
+
+ // WHEN
+ renderer.m_updatedSetFences.push_back({Qt3DCore::QNodeId(), nullptr});
+ jobs = renderer.preRenderingJobs();
+
+ // THEN
+ QCOMPARE(jobs.size(),
+ 1 + // PickBoundingVolumeJob
+ 1 + // RayCastingJob
+ 1 + // SendBufferCaptureJob
+ 1); // SendSetFenceHandlesJob
+ // Note: pending set fence handles are only cleared when the job is run
+
+ // WHEN
+ renderer.m_updatedTextureProperties.push_back({{}, {}});
+ jobs = renderer.preRenderingJobs();
+
+ // THEN
+ QCOMPARE(jobs.size(),
+ 1 + // PickBoundingVolumeJob
+ 1 + // RayCastingJob
+ 1 + // SendBufferCaptureJob
+ 1 + // SendSetFenceHandlesJob
+ 1); // SendTextureChangesToFrontend
+
+ // Note: pending texture changes are only cleared when the job is run
+
+ // Properly shutdown command thread
+ renderer.shutdown();
+ }
+
void checkRenderBinJobs()
{
// GIVEN
@@ -90,7 +172,6 @@ private Q_SLOTS:
QCOMPARE(jobs.size(),
1 + // updateLevelOfDetailJob
1 + // cleanupJob
- 1 + // sendBufferCaptureJob
1 + // VAOGatherer
1 + // updateSkinningPaletteJob
singleRenderViewJobCount); // Only valid for the first call to renderBinJobs(), since subsequent calls won't have the renderqueue reset
@@ -98,19 +179,6 @@ private Q_SLOTS:
renderer.clearDirtyBits(Qt3DRender::Render::AbstractRenderer::AllDirty);
// WHEN
- renderer.addRenderCaptureSendRequest(Qt3DCore::QNodeId::createId());
- jobs = renderer.renderBinJobs();
-
- // THEN
- QCOMPARE(jobs.size(),
- 1 + // updateLevelOfDetailJob
- 1 + // cleanupJob
- 1 + // sendBufferCaptureJob
- 1 + // sendRenderCaptureJob
- 1 + // VAOGatherer
- 1); // updateSkinningPaletteJob
-
- // WHEN
renderer.markDirty(Qt3DRender::Render::AbstractRenderer::EntityEnabledDirty, nullptr);
jobs = renderer.renderBinJobs();
@@ -118,7 +186,6 @@ private Q_SLOTS:
QCOMPARE(jobs.size(),
1 + // updateLevelOfDetailJob
1 + // cleanupJob
- 1 + // sendBufferCaptureJob
1 + // VAOGatherer
1 + // updateSkinningPaletteJob
1); // EntityEnabledDirty
@@ -133,7 +200,6 @@ private Q_SLOTS:
QCOMPARE(jobs.size(),
1 + // updateLevelOfDetailJob
1 + // cleanupJob
- 1 + // sendBufferCaptureJob
1 + // VAOGatherer
1 + // WorldTransformJob
1 + // UpdateWorldBoundingVolume
@@ -151,7 +217,6 @@ private Q_SLOTS:
QCOMPARE(jobs.size(),
1 + // updateLevelOfDetailJob
1 + // cleanupJob
- 1 + // sendBufferCaptureJob
1 + // VAOGatherer
1 + // CalculateBoundingVolumeJob
1 + // UpdateMeshTriangleListJob
@@ -168,7 +233,6 @@ private Q_SLOTS:
QCOMPARE(jobs.size(),
1 + // updateLevelOfDetailJob
1 + // cleanupJob
- 1 + // sendBufferCaptureJob
1 + // VAOGatherer
1 + // updateSkinningPaletteJob
1); // BufferGathererJob
@@ -183,7 +247,6 @@ private Q_SLOTS:
QCOMPARE(jobs.size(),
1 + // updateLevelOfDetailJob
1 + // cleanupJob
- 1 + // sendBufferCaptureJob
1 + // VAOGatherer
1 + // TexturesGathererJob
1 + // updateSkinningPaletteJob
@@ -191,6 +254,19 @@ private Q_SLOTS:
renderer.clearDirtyBits(Qt3DRender::Render::AbstractRenderer::AllDirty);
+
+ // WHEN
+ renderer.markDirty(Qt3DRender::Render::AbstractRenderer::FrameGraphDirty, nullptr);
+ jobs = renderer.renderBinJobs();
+
+ QCOMPARE(jobs.size(),
+ 1 + // updateLevelOfDetailJob
+ 1 + // cleanupJob
+ 1 + // VAOGatherer
+ 1); // updateSkinningPaletteJob
+
+ renderer.clearDirtyBits(Qt3DRender::Render::AbstractRenderer::AllDirty);
+
// WHEN
renderer.markDirty(Qt3DRender::Render::AbstractRenderer::AllDirty, nullptr);
jobs = renderer.renderBinJobs();
@@ -208,7 +284,6 @@ private Q_SLOTS:
1 + // updateSkinningPaletteJob
1 + // updateLevelOfDetailJob
1 + // cleanupJob
- 1 + // sendBufferCaptureJob
1 + // VAOGatherer
1 + // BufferGathererJob
1 + // TexturesGathererJob