diff options
author | Paul Lemire <paul.lemire@kdab.com> | 2015-11-09 11:19:56 +0100 |
---|---|---|
committer | Paul Lemire <paul.lemire@kdab.com> | 2015-11-24 11:45:02 +0000 |
commit | ae6e9f6b25a77064190de1f65358e3bb98e2a37b (patch) | |
tree | a15d2d0a93143a6df9aa39e18762d9265a5ee851 /tests/benchmarks | |
parent | 026d855e495f29a91ab36d44839531de399d5ce4 (diff) |
jobs benchmarks
Change-Id: I0585281d2ba3e109b8ab8e45762e5101f7ea2163
Reviewed-by: Sean Harmer <sean.harmer@kdab.com>
Diffstat (limited to 'tests/benchmarks')
-rw-r--r-- | tests/benchmarks/benchmarks.pro | 3 | ||||
-rw-r--r-- | tests/benchmarks/render/jobs/jobs.pro | 9 | ||||
-rw-r--r-- | tests/benchmarks/render/jobs/tst_bench_jobs.cpp | 386 | ||||
-rw-r--r-- | tests/benchmarks/render/render.pro | 3 |
4 files changed, 400 insertions, 1 deletions
diff --git a/tests/benchmarks/benchmarks.pro b/tests/benchmarks/benchmarks.pro index c17962420..bcaf713c6 100644 --- a/tests/benchmarks/benchmarks.pro +++ b/tests/benchmarks/benchmarks.pro @@ -1,3 +1,4 @@ TEMPLATE = subdirs SUBDIRS = \ - core + core \ + render diff --git a/tests/benchmarks/render/jobs/jobs.pro b/tests/benchmarks/render/jobs/jobs.pro new file mode 100644 index 000000000..0eb6017e2 --- /dev/null +++ b/tests/benchmarks/render/jobs/jobs.pro @@ -0,0 +1,9 @@ +TARGET = tst_bench_jobs + +TEMPLATE = app + +QT += testlib core core-private 3dcore 3dcore-private 3drender 3drender-private 3dquick qml + +SOURCES += tst_bench_jobs.cpp + +DEFINES += QT3D_RENDER_UNIT_TESTS diff --git a/tests/benchmarks/render/jobs/tst_bench_jobs.cpp b/tests/benchmarks/render/jobs/tst_bench_jobs.cpp new file mode 100644 index 000000000..2614c4e4c --- /dev/null +++ b/tests/benchmarks/render/jobs/tst_bench_jobs.cpp @@ -0,0 +1,386 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the Qt3D module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtTest/QtTest> +#include <QMatrix4x4> +#include <Qt3DCore/QEntity> +#include <Qt3DCore/QCamera> +#include <Qt3DCore/QTransform> +#include <Qt3DCore/QNodeVisitor> +#include <Qt3DRender/QMaterial> +#include <Qt3DRender/QFrameGraph> +#include <Qt3DRender/QForwardRenderer> +#include <Qt3DRender/QPhongMaterial> +#include <Qt3DRender/QCylinderMesh> +#include <Qt3DRender/private/managers_p.h> + +#include <Qt3DCore/private/qresourcemanager_p.h> +#include <Qt3DRender/qrenderaspect.h> +#include <Qt3DRender/private/qrenderaspect_p.h> +#include <Qt3DRender/private/renderer_p.h> +#include <Qt3DRender/private/nodemanagers_p.h> +#include <Qt3DRender/private/updateworldtransformjob_p.h> +#include <Qt3DQuick/QQmlAspectEngine> +#include <Qt3DCore/private/qaspectjobmanager_p.h> +#include <Qt3DCore/private/qaspectengine_p.h> +#include <Qt3DCore/private/qaspectmanager_p.h> +#include <Qt3DCore/private/qaspectthread_p.h> +#include <QQmlComponent> +#include <QScopedPointer> + +class TestAspect : public Qt3DRender::QRenderAspect +{ + Q_OBJECT +public: + TestAspect(bool withWindow = false) + : Qt3DRender::QRenderAspect(QRenderAspect::Synchronous) + , m_jobManager(new Qt3DCore::QAspectJobManager()) + { + Qt3DCore::QAbstractAspectPrivate::get(this)->m_jobManager = m_jobManager.data(); + if (!withWindow) { + d_func()->m_renderer->createAllocators(m_jobManager.data()); + } else { + m_window.reset(new QWindow()); + m_window->resize(1024, 768); + + QSurfaceFormat format; + if (QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGL) { + format.setVersion(4, 3); + format.setProfile(QSurfaceFormat::CoreProfile); + } + format.setDepthBufferSize( 24 ); + format.setSamples( 4 ); + format.setStencilBufferSize(8); + m_window->setFormat(format); + m_window->create(); + + QVariantMap data; + data.insert(QStringLiteral("surface"), QVariant::fromValue(static_cast<QSurface *>(m_window.data()))); + data.insert(QStringLiteral("eventSource"), QVariant::fromValue(m_window.data())); + QRenderAspect::onInitialize(data); + } + } + + QVector<Qt3DCore::QAspectJobPtr> worldTransformJob() + { + d_func()->m_worldTransformJob->setRoot(d_func()->m_renderer->renderSceneRoot()); + return QVector<Qt3DCore::QAspectJobPtr>() << d_func()->m_worldTransformJob; + } + + QVector<Qt3DCore::QAspectJobPtr> updateBoundingJob() + { + d_func()->m_updateBoundingVolumeJob->setRoot(d_func()->m_renderer->renderSceneRoot()); + return QVector<Qt3DCore::QAspectJobPtr>() << d_func()->m_updateBoundingVolumeJob; + } + + QVector<Qt3DCore::QAspectJobPtr> calculateBoundingVolumeJob() + { + d_func()->m_calculateBoundingVolumeJob->setRoot(d_func()->m_renderer->renderSceneRoot()); + return QVector<Qt3DCore::QAspectJobPtr>() << d_func()->m_calculateBoundingVolumeJob; + } + + QVector<Qt3DCore::QAspectJobPtr> framePreparationJob() + { + d_func()->m_framePreparationJob->setRoot(d_func()->m_renderer->renderSceneRoot()); + return QVector<Qt3DCore::QAspectJobPtr>() << d_func()->m_framePreparationJob; + } + + QVector<Qt3DCore::QAspectJobPtr> frameCleanupJob() + { + return QVector<Qt3DCore::QAspectJobPtr>() << d_func()->m_cleanupJob; + } + + QVector<Qt3DCore::QAspectJobPtr> renderBinJobs() + { + return d_func()->m_renderer->createRenderBinJobs(); + } + + void setRootEntity(Qt3DCore::QEntity *root) + { + if (!m_window) { + Qt3DCore::QNodeVisitor visitor; + visitor.traverse(root, this, &TestAspect::visitNode); + d_func()->m_renderer->m_renderSceneRoot = + d_func()->m_renderer->nodeManagers() + ->lookupResource<Qt3DRender::Render::Entity, Qt3DRender::Render::EntityManager>(root->id()); + } else { + QRenderAspect::setRootEntity(root); + } + } + + void visitNode(Qt3DCore::QNode *node) + { + QAbstractAspect::createBackendNode(node); + } + +private: + QScopedPointer<Qt3DCore::QAspectJobManager> m_jobManager; + QScopedPointer<QWindow> m_window; +}; + +Qt3DCore::QEntity *loadFromQML(const QUrl &source) +{ + QQmlEngine qmlEngine; + QQmlComponent *component = new QQmlComponent(&qmlEngine, source); + + while (component->isLoading()) + QThread::usleep(250); + + QObject *rootObj = component->create(); + return qobject_cast<Qt3DCore::QEntity *>(rootObj); +} + +Qt3DCore::QEntity *buildBigScene() +{ + Qt3DCore::QEntity *root = new Qt3DCore::QEntity(); + + // Camera + Qt3DCore::QCamera *cameraEntity = new Qt3DCore::QCamera(root); + cameraEntity->setObjectName(QStringLiteral("cameraEntity")); + cameraEntity->lens()->setPerspectiveProjection(45.0f, 16.0f/9.0f, 0.1f, 1000.0f); + cameraEntity->setPosition(QVector3D(0, -250.0f, -50.0f)); + cameraEntity->setUpVector(QVector3D(0, 1, 0)); + cameraEntity->setViewCenter(QVector3D(0, 0, 0)); + + // FrameGraph + Qt3DRender::QFrameGraph *frameGraph = new Qt3DRender::QFrameGraph(); + Qt3DRender::QForwardRenderer *forwardRenderer = new Qt3DRender::QForwardRenderer(); + forwardRenderer->setCamera(cameraEntity); + forwardRenderer->setClearColor(Qt::black); + frameGraph->setActiveFrameGraph(forwardRenderer); + root->addComponent(frameGraph); + + + const float radius = 100.0f; + const int max = 1000; + const float det = 1.0f / max; + // Scene + for (int i = 0; i < max; i++) { + Qt3DCore::QEntity *e = new Qt3DCore::QEntity(); + Qt3DCore::QTransform *transform = new Qt3DCore::QTransform(); + Qt3DRender::QCylinderMesh *mesh = new Qt3DRender::QCylinderMesh(); + Qt3DRender::QPhongMaterial *material = new Qt3DRender::QPhongMaterial(); + mesh->setRings(50.0f); + mesh->setSlices(30.0f); + mesh->setRadius(2.5f); + mesh->setLength(5.0f); + + const float angle = M_PI * 2.0f * i * det * 10.; + + material->setDiffuse(QColor(qFabs(qCos(angle)) * 255, 204, 75)); + material->setAmbient(Qt::black); + material->setSpecular(Qt::white); + material->setShininess(150.0f); + + QMatrix4x4 m; + m.translate(QVector3D(radius * qCos(angle), 200.* i * det, radius * qSin(angle))); + m.rotate(30.0f * i, QVector3D(1.0f, 0.0f, 0.0f)); + m.rotate(45.0f * i, QVector3D(0.0f, 0.0f, 1.0f)); + transform->setMatrix(m); + + e->addComponent(transform); + e->addComponent(mesh); + e->addComponent(material); + e->setParent(root); + } + + return root; +} + +class tst_benchJobs : public QObject +{ + Q_OBJECT + +private: + Qt3DCore::QEntity *m_bigSceneRoot; + +public: + tst_benchJobs() + : m_bigSceneRoot(buildBigScene()) + {} + +private Q_SLOTS: + + void updateTransformJob_data() + { + QTest::addColumn<Qt3DCore::QEntity*>("rootEntity"); + QTest::newRow("bigscene") << m_bigSceneRoot; + } + + void updateTransformJob() + { + // GIVEN + QFETCH(Qt3DCore::QEntity*, rootEntity); + TestAspect aspect; + + aspect.setRootEntity(qobject_cast<Qt3DCore::QEntity *>(rootEntity)); + + // WHEN + QVector<Qt3DCore::QAspectJobPtr> jobs = aspect.worldTransformJob(); + + QBENCHMARK { + aspect.jobManager()->enqueueJobs(jobs); + aspect.jobManager()->waitForAllJobs(); + } + } + + void updateBoundingJob_data() + { + QTest::addColumn<Qt3DCore::QEntity*>("rootEntity"); + QTest::newRow("bigscene") << m_bigSceneRoot; + } + + void updateBoundingJob() + { + // GIVEN + QFETCH(Qt3DCore::QEntity*, rootEntity); + TestAspect aspect; + + aspect.setRootEntity(qobject_cast<Qt3DCore::QEntity *>(rootEntity)); + + // WHEN + QVector<Qt3DCore::QAspectJobPtr> jobs = aspect.updateBoundingJob(); + + QBENCHMARK { + aspect.jobManager()->enqueueJobs(jobs); + aspect.jobManager()->waitForAllJobs(); + } + } + + void calculateBoundingVolumeJob_data() + { + QTest::addColumn<Qt3DCore::QEntity*>("rootEntity"); + QTest::newRow("bigscene") << m_bigSceneRoot; + } + + void calculateBoundingVolumeJob() + { + // GIVEN + QFETCH(Qt3DCore::QEntity*, rootEntity); + TestAspect aspect; + + aspect.setRootEntity(qobject_cast<Qt3DCore::QEntity *>(rootEntity)); + + // WHEN + QVector<Qt3DCore::QAspectJobPtr> jobs = aspect.calculateBoundingVolumeJob(); + + QBENCHMARK { + aspect.jobManager()->enqueueJobs(jobs); + aspect.jobManager()->waitForAllJobs(); + } + } + + void framePreparationJob_data() + { + QTest::addColumn<Qt3DCore::QEntity*>("rootEntity"); + QTest::newRow("bigscene") << m_bigSceneRoot; + } + + void framePreparationJob() + { + // GIVEN + QFETCH(Qt3DCore::QEntity*, rootEntity); + TestAspect aspect; + + aspect.setRootEntity(qobject_cast<Qt3DCore::QEntity *>(rootEntity)); + + // WHEN + QVector<Qt3DCore::QAspectJobPtr> jobs = aspect.framePreparationJob(); + + QBENCHMARK { + aspect.jobManager()->enqueueJobs(jobs); + aspect.jobManager()->waitForAllJobs(); + } + } + + void frameCleanupJob_data() + { + QTest::addColumn<Qt3DCore::QEntity*>("rootEntity"); + QTest::newRow("bigscene") << m_bigSceneRoot; + } + + void frameCleanupJob() + { + // GIVEN + QFETCH(Qt3DCore::QEntity*, rootEntity); + TestAspect aspect; + + aspect.setRootEntity(qobject_cast<Qt3DCore::QEntity *>(rootEntity)); + + // WHEN + QVector<Qt3DCore::QAspectJobPtr> jobs = aspect.frameCleanupJob(); + QBENCHMARK { + aspect.jobManager()->enqueueJobs(jobs); + aspect.jobManager()->waitForAllJobs(); + } + } + + /* Note: The renderer still needs to be simplified to run + these jobs + void renderBinJobs_data() + { + QTest::addColumn<Qt3DCore::QEntity*>("rootEntity"); + QTest::newRow("bigscene") << m_bigSceneRoot; + } + + void renderBinJobs() + { + // GIVEN + QFETCH(Qt3DCore::QEntity*, rootEntity); + QScopedPointer<QThread> aspectThread(new QThread); + TestAspect aspect(true); + aspect.moveToThread(aspectThread.data()); + + qDebug() << 1; + + aspect.setRootEntity(qobject_cast<Qt3DCore::QEntity *>(rootEntity)); + qDebug() << 2; + + // WHEN + QVector<Qt3DCore::QAspectJobPtr> jobs = aspect.renderBinJobs(); + qDebug() << 3; + QBENCHMARK { + qDebug() << 4; + aspect.jobManager()->enqueueJobs(jobs); + aspect.jobManager()->waitForAllJobs(); + } + } + */ +}; + +QTEST_MAIN(tst_benchJobs) + +#include "tst_bench_jobs.moc" diff --git a/tests/benchmarks/render/render.pro b/tests/benchmarks/render/render.pro new file mode 100644 index 000000000..6accd1788 --- /dev/null +++ b/tests/benchmarks/render/render.pro @@ -0,0 +1,3 @@ +TEMPLATE=subdirs + +SUBDIRS += jobs |