summaryrefslogtreecommitdiffstats
path: root/src/render/frontend
diff options
context:
space:
mode:
authorMike Krus <mike.krus@kdab.com>2020-04-24 13:43:56 +0100
committerMike Krus <mike.krus@kdab.com>2020-04-27 11:57:33 +0100
commit6c1758d35e20655f46ba3696671068f4862c8878 (patch)
treed4b4fc2ae8f5a4512de4eb015667b024b6a8e6b9 /src/render/frontend
parentb7967a8abcdac438a1f31800b71e219e3c52c24a (diff)
parent37735f11f9437b916b194cfd48c452c7c70682f8 (diff)
Merge remote-tracking branch 'origin/5.15' into dev
Diffstat (limited to 'src/render/frontend')
-rw-r--r--src/render/frontend/qrenderapi.h61
-rw-r--r--src/render/frontend/qrenderaspect.cpp103
-rw-r--r--src/render/frontend/qrendercapabilities.h7
-rw-r--r--src/render/frontend/qrendersettings.h2
-rw-r--r--src/render/frontend/qrendertarget.cpp3
-rw-r--r--src/render/frontend/render-frontend.pri1
6 files changed, 163 insertions, 14 deletions
diff --git a/src/render/frontend/qrenderapi.h b/src/render/frontend/qrenderapi.h
new file mode 100644
index 000000000..fc046642a
--- /dev/null
+++ b/src/render/frontend/qrenderapi.h
@@ -0,0 +1,61 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 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 QT3DRENDER_QRENDERAPI_H
+#define QT3DRENDER_QRENDERAPI_H
+
+#include <Qt3DRender/qt3drender_global.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DRender {
+
+enum class API {
+ OpenGL,
+ Vulkan,
+ DirectX,
+ Metal,
+ Null
+};
+
+} // namespace Qt3Drender
+
+QT_END_NAMESPACE
+
+#endif // QT3DRENDER_QRENDERAPI_H
diff --git a/src/render/frontend/qrenderaspect.cpp b/src/render/frontend/qrenderaspect.cpp
index 9412d3526..015f5bba2 100644
--- a/src/render/frontend/qrenderaspect.cpp
+++ b/src/render/frontend/qrenderaspect.cpp
@@ -165,6 +165,8 @@
#include <Qt3DRender/private/updatelevelofdetailjob_p.h>
#include <Qt3DRender/private/job_common_p.h>
#include <Qt3DRender/private/pickeventfilter_p.h>
+#include <Qt3DRender/private/techniquemanager_p.h>
+#include <Qt3DRender/private/qgraphicsapifilter_p.h>
#include <private/qrenderpluginfactory_p.h>
#include <private/qrenderplugin_p.h>
@@ -189,6 +191,81 @@ QT_BEGIN_NAMESPACE
using namespace Qt3DCore;
+namespace {
+
+QString dumpNode(const Qt3DCore::QEntity *n) {
+ auto formatNode = [](const Qt3DCore::QNode *n) {
+ QString res = QString(QLatin1String("%1{%2}"))
+ .arg(QLatin1String(n->metaObject()->className()))
+ .arg(n->id().id());
+ if (!n->objectName().isEmpty())
+ res += QString(QLatin1String(" (%1)")).arg(n->objectName());
+ if (!n->isEnabled())
+ res += QLatin1String(" [D]");
+ return res;
+ };
+
+ return formatNode(n);
+}
+
+QString dumpNodeFilters(const QString &filterType, const QVector<Qt3DRender::QFilterKey*> &filters) {
+ QString res;
+
+ QStringList kv;
+ for (auto filter: filters)
+ kv.push_back(QString(QLatin1String("%1: %2")).arg(filter->name(), filter->value().toString()));
+ if (kv.size())
+ res += QString(QLatin1String("%1 <%2>")).arg(filterType, kv.join(QLatin1String(", ")));
+
+ return res;
+}
+
+QStringList dumpSGFilterState(Qt3DRender::Render::TechniqueManager *manager,
+ const Qt3DRender::GraphicsApiFilterData *contextData,
+ const Qt3DCore::QNode *n, int level = 0)
+{
+ using namespace Qt3DRender;
+
+ QStringList reply;
+ const auto *entity = qobject_cast<const Qt3DCore::QEntity *>(n);
+ if (entity != nullptr) {
+ QString res = dumpNode(entity);
+ auto materials = entity->componentsOfType<QMaterial>();
+ if (materials.size() && materials.front()->effect()) {
+ auto m = materials.front();
+ const auto techniques = m->effect()->techniques();
+ for (auto t: m->effect()->techniques()) {
+ auto apiFilter = t->graphicsApiFilter();
+ if (apiFilter) {
+ auto backendTechnique = manager->lookupResource(t->id());
+ if (backendTechnique &&
+ !(*contextData == *backendTechnique->graphicsApiFilter()))
+ continue; // skip technique that doesn't match current renderer
+ }
+
+ QStringList filters;
+ filters += dumpNodeFilters(QLatin1String("T"), t->filterKeys());
+
+ const auto &renderPasses = t->renderPasses();
+ for (auto r: renderPasses)
+ filters += dumpNodeFilters(QLatin1String("RP"), r->filterKeys());
+
+ if (filters.size())
+ res += QLatin1String(" [ %1 ]").arg(filters.join(QLatin1String(" ")));
+ }
+ }
+ reply += res.rightJustified(res.length() + level * 2, ' ');
+ level++;
+ }
+
+ const auto children = n->childNodes();
+ for (auto *child: children)
+ reply += dumpSGFilterState(manager, contextData, child, level);
+
+ return reply;
+}
+
+}
namespace Qt3DRender {
#define CreateSynchronizerJobPtr(lambda, type) \
@@ -240,8 +317,11 @@ QRenderAspectPrivate::QRenderAspectPrivate(QRenderAspect::RenderType type)
m_updateWorldBoundingVolumeJob->addDependency(m_worldTransformJob);
m_updateWorldBoundingVolumeJob->addDependency(m_calculateBoundingVolumeJob);
+ m_calculateBoundingVolumeJob->addDependency(m_updateTreeEnabledJob);
m_expandBoundingVolumeJob->addDependency(m_updateWorldBoundingVolumeJob);
m_updateLevelOfDetailJob->addDependency(m_expandBoundingVolumeJob);
+ m_pickBoundingVolumeJob->addDependency(m_expandBoundingVolumeJob);
+ m_rayCastingJob->addDependency(m_expandBoundingVolumeJob);
}
/*! \internal */
@@ -537,7 +617,7 @@ QRenderAspect::~QRenderAspect()
// Called by Scene3DRenderer only
void QRenderAspectPrivate::renderInitialize(QOpenGLContext *context)
{
- if (m_renderer->api() == Render::AbstractRenderer::OpenGL)
+ if (m_renderer->api() == API::OpenGL)
m_renderer->setOpenGLContext(context);
m_renderer->initialize();
}
@@ -612,6 +692,9 @@ QVector<Qt3DCore::QAspectJobPtr> QRenderAspect::jobsToExecute(qint64 time)
const QVector<QAspectJobPtr> geometryJobs = d->createGeometryRendererJobs();
jobs.append(geometryJobs);
+ const QVector<QAspectJobPtr> preRenderingJobs = d->createPreRendererJobs();
+ 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,
// perform picking,... must still be run)
@@ -630,12 +713,8 @@ QVector<Qt3DCore::QAspectJobPtr> QRenderAspect::jobsToExecute(qint64 time)
// Create the jobs to build the frame
const bool entitiesEnabledDirty = dirtyBitsForFrame & AbstractRenderer::EntityEnabledDirty;
- if (entitiesEnabledDirty) {
+ if (entitiesEnabledDirty)
jobs.push_back(d->m_updateTreeEnabledJob);
- // This dependency is added here because we clear all dependencies
- // at the start of this function.
- d->m_calculateBoundingVolumeJob->addDependency(d->m_updateTreeEnabledJob);
- }
if (dirtyBitsForFrame & AbstractRenderer::TransformDirty) {
jobs.push_back(d->m_worldTransformJob);
@@ -663,9 +742,6 @@ QVector<Qt3DCore::QAspectJobPtr> QRenderAspect::jobsToExecute(qint64 time)
if (layersDirty)
jobs.push_back(d->m_updateEntityLayersJob);
- const QVector<QAspectJobPtr> preRenderingJobs = d->createPreRendererJobs();
- jobs.append(preRenderingJobs);
-
const QVector<QAspectJobPtr> renderBinJobs = d->m_renderer->renderBinJobs();
jobs.append(renderBinJobs);
}
@@ -686,6 +762,13 @@ QVariant QRenderAspect::executeCommand(const QStringList &args)
return Qt3DRender::QFrameGraphNodePrivate::get(fg)->dumpFrameGraph();
if (args.front() == QLatin1String("framepaths"))
return Qt3DRender::QFrameGraphNodePrivate::get(fg)->dumpFrameGraphPaths().join(QLatin1String("\n"));
+ if (args.front() == QLatin1String("filterstates")) {
+ const auto activeContextInfo = d->m_renderer->contextInfo();
+ QString res = QLatin1String("Active Graphics API: ") + activeContextInfo->toString() + QLatin1String("\n");
+ res += QLatin1String("Render Views:\n ") + Qt3DRender::QFrameGraphNodePrivate::get(fg)->dumpFrameGraphFilterState().join(QLatin1String("\n ")) + QLatin1String("\n");
+ res += QLatin1String("Scene Graph:\n ") + dumpSGFilterState(d->m_nodeManagers->techniqueManager(), activeContextInfo, d->m_root).join(QLatin1String("\n "));
+ return res;
+ }
}
if (args.front() == QLatin1String("scenegraph"))
return droot->dumpSceneGraph();
@@ -803,7 +886,7 @@ QVector<QAspectJobPtr> QRenderAspectPrivate::createPreRendererJobs() const
const auto frameMouseEvents = m_pickEventFilter->pendingMouseEvents();
const auto frameKeyEvents = m_pickEventFilter->pendingKeyEvents();
- m_renderer->setPendingEvents(frameMouseEvents, m_pickEventFilter->pendingKeyEvents());
+ m_renderer->setPendingEvents(frameMouseEvents, frameKeyEvents);
auto jobs = m_renderer->preRenderingJobs();
diff --git a/src/render/frontend/qrendercapabilities.h b/src/render/frontend/qrendercapabilities.h
index 14e233f59..512be5434 100644
--- a/src/render/frontend/qrendercapabilities.h
+++ b/src/render/frontend/qrendercapabilities.h
@@ -86,8 +86,11 @@ class Q_3DRENDERSHARED_EXPORT QRenderCapabilities : public QObject
Q_PROPERTY(int maxComputeSharedMemorySize READ maxComputeSharedMemorySize CONSTANT)
public:
enum API {
- OpenGL = QSurfaceFormat::OpenGL,
- OpenGLES = QSurfaceFormat::OpenGLES,
+ OpenGL = QSurfaceFormat::OpenGL, // 1
+ OpenGLES = QSurfaceFormat::OpenGLES, // 2
+ Vulkan = 3, // 3
+ DirectX, // 4
+ RHI, // 5
};
Q_ENUM(API)
diff --git a/src/render/frontend/qrendersettings.h b/src/render/frontend/qrendersettings.h
index 5e63b1183..be4dd27de 100644
--- a/src/render/frontend/qrendersettings.h
+++ b/src/render/frontend/qrendersettings.h
@@ -43,9 +43,9 @@
#include <Qt3DCore/qcomponent.h>
#include <Qt3DRender/qt3drender_global.h>
#include <Qt3DRender/qpickingsettings.h>
+#include <QtGui/qtguiglobal.h>
QT_BEGIN_NAMESPACE
-
namespace Qt3DRender {
class QFrameGraphNode;
diff --git a/src/render/frontend/qrendertarget.cpp b/src/render/frontend/qrendertarget.cpp
index 4471b31fa..e359d9bdd 100644
--- a/src/render/frontend/qrendertarget.cpp
+++ b/src/render/frontend/qrendertarget.cpp
@@ -134,8 +134,9 @@ void QRenderTarget::removeOutput(QRenderTargetOutput *output)
{
Q_D(QRenderTarget);
+ if (!d->m_outputs.removeOne(output))
+ return;
d->update();
- d->m_outputs.removeOne(output);
// Remove bookkeeping connection
d->unregisterDestructionHelper(output);
}
diff --git a/src/render/frontend/render-frontend.pri b/src/render/frontend/render-frontend.pri
index 934672a01..02eb74ce1 100644
--- a/src/render/frontend/render-frontend.pri
+++ b/src/render/frontend/render-frontend.pri
@@ -28,6 +28,7 @@ HEADERS += \
$$PWD/qrenderpluginfactory_p.h \
$$PWD/qrenderpluginfactoryif_p.h \
$$PWD/qlevelofdetailboundingsphere.h \
+ $$PWD/qrenderapi.h \
$$PWD/qrendercapabilities.h \
$$PWD/qrendercapabilities_p.h