summaryrefslogtreecommitdiffstats
path: root/src/render/frontend/qrendercapabilities.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/render/frontend/qrendercapabilities.cpp')
-rw-r--r--src/render/frontend/qrendercapabilities.cpp431
1 files changed, 431 insertions, 0 deletions
diff --git a/src/render/frontend/qrendercapabilities.cpp b/src/render/frontend/qrendercapabilities.cpp
new file mode 100644
index 000000000..f614a528c
--- /dev/null
+++ b/src/render/frontend/qrendercapabilities.cpp
@@ -0,0 +1,431 @@
+/****************************************************************************
+**
+** 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$
+**
+****************************************************************************/
+
+#include "qrendercapabilities.h"
+#include "qrendercapabilities_p.h"
+
+#include <QOffscreenSurface>
+#include <QOpenGLContext>
+#include <QOpenGLFunctions>
+#include <QOpenGLExtraFunctions>
+#include <QSet>
+#include <QDebug>
+
+#ifndef GL_MAX_UNIFORM_BLOCK_SIZE
+#define GL_MAX_UNIFORM_BLOCK_SIZE 0x8A30
+#endif
+
+#ifndef GL_MAX_UNIFORM_BLOCK_SIZE
+#define GL_MAX_UNIFORM_BLOCK_SIZE 0x8A30
+#endif
+
+#ifndef GL_MAX_SAMPLES
+#define GL_MAX_SAMPLES 0x8D57
+#endif
+
+#ifndef GL_MAX_UNIFORM_BUFFER_BINDINGS
+#define GL_MAX_UNIFORM_BUFFER_BINDINGS 0x8A2F
+#endif
+
+#ifndef GL_MAX_UNIFORM_BLOCK_SIZE
+#define GL_MAX_UNIFORM_BLOCK_SIZE 0x8A30
+#endif
+
+#ifndef GL_MAX_ARRAY_TEXTURE_LAYERS
+#define GL_MAX_ARRAY_TEXTURE_LAYERS 0x88FF
+#endif
+
+#ifndef GL_MAX_IMAGE_UNITS
+#define GL_MAX_IMAGE_UNITS 0x8F38
+#endif
+
+#ifndef GL_MAX_SHADER_STORAGE_BLOCK_SIZE
+#define GL_MAX_SHADER_STORAGE_BLOCK_SIZE 0x90DE
+#endif
+
+#ifndef GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS
+#define GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS 0x90DD
+#endif
+
+#ifndef GL_MAX_COMPUTE_WORK_GROUP_SIZE
+#define GL_MAX_COMPUTE_WORK_GROUP_SIZE 0x91BF
+#endif
+
+#ifndef GL_MAX_COMPUTE_WORK_GROUP_COUNT
+#define GL_MAX_COMPUTE_WORK_GROUP_COUNT 0x91BE
+#endif
+
+#ifndef GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS
+#define GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS 0x90EB
+#endif
+
+#ifndef GL_MAX_COMPUTE_SHARED_MEMORY_SIZE
+#define GL_MAX_COMPUTE_SHARED_MEMORY_SIZE 0x8262
+#endif
+
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DRender {
+
+/*!
+ \class Qt3DRender::QRenderCapabilities
+ \brief The QRenderCapabilities class holds settings related to available rendering engines
+ */
+
+/*!
+ \qmltype RenderCapabilities
+ \brief The QRenderCapabilities class holds settings related to available rendering engines
+ \since 5.15
+ \inqmlmodule Qt3D.Render
+ \instantiates Qt3DRender::QRenderCapabilities
+ */
+
+
+/*! \internal */
+QRenderCapabilitiesPrivate::QRenderCapabilitiesPrivate()
+ : QObjectPrivate()
+ , m_valid(false)
+{
+ QOffscreenSurface offscreen;
+ QOpenGLContext ctx;
+
+ offscreen.setFormat(QSurfaceFormat::defaultFormat());
+ offscreen.create();
+ Q_ASSERT_X(offscreen.isValid(), Q_FUNC_INFO, "Unable to create offscreen surface to gather capabilities");
+
+ ctx.setFormat(QSurfaceFormat::defaultFormat());
+ if (ctx.create()) {
+ m_valid = true;
+ ctx.makeCurrent(&offscreen);
+ const QSurfaceFormat format = ctx.format();
+ auto funcs = ctx.functions();
+
+ if (ctx.isOpenGLES())
+ m_api = QRenderCapabilities::OpenGLES;
+ else
+ m_api = QRenderCapabilities::OpenGL;
+ m_profile = static_cast<QRenderCapabilities::Profile>(format.profile());
+ m_majorVersion = format.majorVersion();
+ m_minorVersion = format.minorVersion();
+ const QSet<QByteArray> extensions = ctx.extensions();
+ std::transform(std::begin(extensions), std::end(extensions), std::back_inserter(m_extensions), [](const QByteArray &e) {
+ return QLatin1String(e.data());
+ });
+ std::sort(std::begin(m_extensions), std::end(m_extensions));
+ m_vendor = QString::fromUtf8(reinterpret_cast<const char *>(funcs->glGetString(GL_VENDOR)));
+ m_renderer = QString::fromUtf8(reinterpret_cast<const char *>(funcs->glGetString(GL_RENDERER)));
+ m_version = QString::fromUtf8(reinterpret_cast<const char *>(funcs->glGetString(GL_VERSION)));
+ m_glslVersion = QString::fromUtf8(reinterpret_cast<const char *>(funcs->glGetString(GL_SHADING_LANGUAGE_VERSION)));
+
+ funcs->glGetIntegerv(GL_MAX_SAMPLES, &m_maxSamples);
+ funcs->glGetIntegerv(GL_MAX_TEXTURE_SIZE, &m_maxTextureSize);
+ funcs->glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &m_maxTextureUnits);
+
+ if (m_majorVersion >= 3) {
+ if (m_minorVersion >= 1) {
+ m_supportsUBO = true;
+ funcs->glGetIntegerv(GL_MAX_UNIFORM_BLOCK_SIZE, &m_maxUBOSize);
+ funcs->glGetIntegerv(GL_MAX_UNIFORM_BUFFER_BINDINGS, &m_maxUBOBindings);
+ }
+
+ funcs->glGetIntegerv(GL_MAX_ARRAY_TEXTURE_LAYERS, &m_maxTextureLayers);
+ }
+ if ((m_api == QRenderCapabilities::OpenGL && m_majorVersion >= 4 && m_minorVersion >= 3) ||
+ (m_api == QRenderCapabilities::OpenGLES && m_majorVersion >= 3 && m_minorVersion >= 2)) {
+ m_supportsSSBO = true;
+ m_supportCompute = true;
+ m_supportsImageStore = true;
+ funcs->glGetIntegerv(GL_MAX_IMAGE_UNITS, &m_maxImageUnits);
+ m_supportsSSBO = true;
+ funcs->glGetIntegerv(GL_MAX_SHADER_STORAGE_BLOCK_SIZE, &m_maxSSBOSize);
+ funcs->glGetIntegerv(GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS, &m_maxSSBOBindings);
+
+ QOpenGLExtraFunctions *exfunc = nullptr;
+ if ((exfunc = ctx.extraFunctions()) != nullptr) {
+ for (int i = 0; i < 3; ++i) {
+ exfunc->glGetIntegeri_v( GL_MAX_COMPUTE_WORK_GROUP_SIZE, i, &m_maxWorkGroupSize[i] );
+ exfunc->glGetIntegeri_v( GL_MAX_COMPUTE_WORK_GROUP_COUNT, i, &m_maxWorkGroupCount[i] );
+ }
+ }
+
+ funcs->glGetIntegerv( GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS, &m_maxComputeInvocations );
+ funcs->glGetIntegerv( GL_MAX_COMPUTE_SHARED_MEMORY_SIZE, &m_maxComputeSharedMemorySize );
+ }
+
+ // TextureUnitCount, ImageUnitCount, ComputeSupport, ImageSupport, SSBO Support, UBO Support, extensions, Max RenderTargetCount would be a good start
+ }
+}
+
+const QRenderCapabilitiesPrivate *QRenderCapabilitiesPrivate::get(const QRenderCapabilities *q)
+{
+ return q->d_func();
+}
+
+QString QRenderCapabilitiesPrivate::toString() const
+{
+ QString res;
+
+ res += QString(QLatin1String("Vendor: %1\nRenderer: %2\nDriver Version: %3\nGL Version: %4.%5 (%6 Profile)\nGLSL Version: %7\n"))
+ .arg(m_vendor, m_renderer, m_version)
+ .arg(m_majorVersion).arg(m_minorVersion)
+ .arg(m_profile == QRenderCapabilities::CoreProfile ? QLatin1String("Core") : (m_profile == QRenderCapabilities::CompatibilityProfile ? QLatin1String("Compatibility") : QLatin1String("No")))
+ .arg(m_glslVersion);
+ res += QString(QLatin1String("Extensions:\n %1\n")).arg(m_extensions.join(QLatin1String("\n ")));
+ res += QString(QLatin1String("Max Texture Size: %1\nMax Texture Units: %2\nMax Texture Layers: %3\n")).arg(m_maxTextureSize).arg(m_maxTextureUnits).arg(m_maxTextureLayers);
+ res += QString(QLatin1String("Supports UBO: %1\n")).arg(m_supportsUBO ? QLatin1String("True") : QLatin1String("False"));
+ if (m_supportsUBO)
+ res += QString(QLatin1String(" Max UBO Size: %1\n Max UBO Bindings: %2\n")).arg(m_maxUBOSize).arg(m_maxUBOBindings);
+ res += QString(QLatin1String("Supports SSBO: %1\n")).arg(m_supportsSSBO ? QLatin1String("True") : QLatin1String("False"));
+ if (m_supportsSSBO)
+ res += QString(QLatin1String(" Max SSBO Size: %1\n Max SSBO Bindings: %2\n")).arg(m_maxSSBOSize).arg(m_maxSSBOBindings);
+ res += QString(QLatin1String("Supports Image Store: %1\n")).arg(m_supportsImageStore ? QLatin1String("True") : QLatin1String("False"));
+ if (m_supportsImageStore)
+ res += QString(QLatin1String(" Max Image Units: %1\n")).arg(m_maxImageUnits);
+ res += QString(QLatin1String("Supports Compute Shaders: %1\n")).arg(m_supportCompute ? QLatin1String("True") : QLatin1String("False"));
+ if (m_supportCompute)
+ res += QString(QLatin1String(" Max Work Group Size: %1, %2, %3\n Max Work Group Count: %4, %5, %6\n Max Invocations: %6\n Max Shared Memory Size: %7\n"))
+ .arg(m_maxWorkGroupSize[0]).arg(m_maxWorkGroupSize[1]).arg(m_maxWorkGroupSize[2])
+ .arg(m_maxWorkGroupCount[0]).arg(m_maxWorkGroupCount[1]).arg(m_maxWorkGroupCount[2])
+ .arg(m_maxComputeInvocations).arg(m_maxComputeSharedMemorySize);
+ return res;
+}
+
+
+QRenderCapabilities::QRenderCapabilities(QObject *parent)
+ : QObject(*new QRenderCapabilitiesPrivate, parent)
+{
+
+}
+
+/*! \internal */
+QRenderCapabilities::~QRenderCapabilities()
+{
+}
+
+
+bool QRenderCapabilities::isValid() const
+{
+ Q_D(const QRenderCapabilities);
+ return d->m_valid;
+}
+
+QRenderCapabilities::API QRenderCapabilities::api() const
+{
+ Q_D(const QRenderCapabilities);
+ return d->m_api;
+}
+
+QRenderCapabilities::Profile QRenderCapabilities::profile() const
+{
+ Q_D(const QRenderCapabilities);
+ return d->m_profile;
+}
+
+int QRenderCapabilities::majorVersion() const
+{
+ Q_D(const QRenderCapabilities);
+ return d->m_majorVersion;
+}
+
+int QRenderCapabilities::minorVersion() const
+{
+ Q_D(const QRenderCapabilities);
+ return d->m_minorVersion;
+}
+
+QStringList QRenderCapabilities::extensions() const
+{
+ Q_D(const QRenderCapabilities);
+ return d->m_extensions;
+}
+
+QString QRenderCapabilities::vendor() const
+{
+ Q_D(const QRenderCapabilities);
+ return d->m_vendor;
+}
+
+QString QRenderCapabilities::renderer() const
+{
+ Q_D(const QRenderCapabilities);
+ return d->m_renderer;
+}
+
+QString QRenderCapabilities::driverVersion() const
+{
+ Q_D(const QRenderCapabilities);
+ return d->m_version;
+}
+
+QString QRenderCapabilities::glslVersion() const
+{
+ Q_D(const QRenderCapabilities);
+ return d->m_glslVersion;
+}
+
+int QRenderCapabilities::maxSamples() const
+{
+ Q_D(const QRenderCapabilities);
+ return d->m_maxSamples;
+}
+
+int QRenderCapabilities::maxTextureSize() const
+{
+ Q_D(const QRenderCapabilities);
+ return d->m_maxTextureSize;
+}
+
+int QRenderCapabilities::maxTextureUnits() const
+{
+ Q_D(const QRenderCapabilities);
+ return d->m_maxTextureUnits;
+}
+
+int QRenderCapabilities::maxTextureLayers() const
+{
+ Q_D(const QRenderCapabilities);
+ return d->m_maxTextureLayers;
+}
+
+bool QRenderCapabilities::supportsUBO() const
+{
+ Q_D(const QRenderCapabilities);
+ return d->m_supportsUBO;
+}
+
+int QRenderCapabilities::maxUBOSize() const
+{
+ Q_D(const QRenderCapabilities);
+ return d->m_maxUBOSize;
+}
+
+int QRenderCapabilities::maxUBOBindings() const
+{
+ Q_D(const QRenderCapabilities);
+ return d->m_maxUBOBindings;
+}
+
+bool QRenderCapabilities::supportsSSBO() const
+{
+ Q_D(const QRenderCapabilities);
+ return d->m_supportsSSBO;
+}
+
+int QRenderCapabilities::maxSSBOSize() const
+{
+ Q_D(const QRenderCapabilities);
+ return d->m_maxSSBOSize;
+}
+
+int QRenderCapabilities::maxSSBOBindings() const
+{
+ Q_D(const QRenderCapabilities);
+ return d->m_maxSSBOBindings;
+}
+
+bool QRenderCapabilities::supportsImageStore() const
+{
+ Q_D(const QRenderCapabilities);
+ return d->m_supportsImageStore;
+}
+
+int QRenderCapabilities::maxImageUnits() const
+{
+ Q_D(const QRenderCapabilities);
+ return d->m_maxImageUnits;
+}
+
+bool QRenderCapabilities::supportsCompute() const
+{
+ Q_D(const QRenderCapabilities);
+ return d->m_supportCompute;
+}
+
+int QRenderCapabilities::maxWorkGroupCountX() const
+{
+ Q_D(const QRenderCapabilities);
+ return d->m_maxWorkGroupCount[0];
+}
+
+int QRenderCapabilities::maxWorkGroupCountY() const
+{
+ Q_D(const QRenderCapabilities);
+ return d->m_maxWorkGroupCount[1];
+}
+
+int QRenderCapabilities::maxWorkGroupCountZ() const
+{
+ Q_D(const QRenderCapabilities);
+ return d->m_maxWorkGroupCount[2];
+}
+
+int QRenderCapabilities::maxWorkGroupSizeX() const
+{
+ Q_D(const QRenderCapabilities);
+ return d->m_maxWorkGroupSize[0];
+}
+
+int QRenderCapabilities::maxWorkGroupSizeY() const
+{
+ Q_D(const QRenderCapabilities);
+ return d->m_maxWorkGroupSize[1];
+}
+
+int QRenderCapabilities::maxWorkGroupSizeZ() const
+{
+ Q_D(const QRenderCapabilities);
+ return d->m_maxWorkGroupSize[2];
+}
+
+int QRenderCapabilities::maxComputeInvocations() const
+{
+ Q_D(const QRenderCapabilities);
+ return d->m_maxComputeInvocations;
+}
+
+int QRenderCapabilities::maxComputeSharedMemorySize() const
+{
+ Q_D(const QRenderCapabilities);
+ return d->m_maxComputeSharedMemorySize;
+}
+
+} // namespace Qt3Drender
+
+QT_END_NAMESPACE