diff options
Diffstat (limited to 'tests/manual/rhi/hellominimalcrossgfxtriangle/main.cpp')
-rw-r--r-- | tests/manual/rhi/hellominimalcrossgfxtriangle/main.cpp | 171 |
1 files changed, 171 insertions, 0 deletions
diff --git a/tests/manual/rhi/hellominimalcrossgfxtriangle/main.cpp b/tests/manual/rhi/hellominimalcrossgfxtriangle/main.cpp new file mode 100644 index 0000000000..4ef3359ed0 --- /dev/null +++ b/tests/manual/rhi/hellominimalcrossgfxtriangle/main.cpp @@ -0,0 +1,171 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// This is a compact, minimal demo of deciding the backend at runtime while +// using the exact same shaders and rendering code without any branching +// whatsoever once the QWindow is up and the RHI is initialized. + +#include <QGuiApplication> +#include <QCommandLineParser> +#include "hellowindow.h" + +QString graphicsApiName(QRhi::Implementation graphicsApi) +{ + switch (graphicsApi) { + case QRhi::Null: + return QLatin1String("Null (no output)"); + case QRhi::OpenGLES2: + return QLatin1String("OpenGL 2.x"); + case QRhi::Vulkan: + return QLatin1String("Vulkan"); + case QRhi::D3D11: + return QLatin1String("Direct3D 11"); + case QRhi::Metal: + return QLatin1String("Metal"); + default: + break; + } + return QString(); +} + +int main(int argc, char **argv) +{ + QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); + QGuiApplication app(argc, argv); + + QRhi::Implementation graphicsApi; +#if defined(Q_OS_WIN) + graphicsApi = QRhi::D3D11; +#elif defined(Q_OS_MACOS) || defined(Q_OS_IOS) + graphicsApi = QRhi::Metal; +#elif QT_CONFIG(vulkan) + graphicsApi = QRhi::Vulkan; +#else + graphicsApi = QRhi::OpenGLES2; +#endif + + QCommandLineParser cmdLineParser; + cmdLineParser.addHelpOption(); + QCommandLineOption nullOption({ "n", "null" }, QLatin1String("Null")); + cmdLineParser.addOption(nullOption); + QCommandLineOption glOption({ "g", "opengl" }, QLatin1String("OpenGL (2.x)")); + cmdLineParser.addOption(glOption); + QCommandLineOption vkOption({ "v", "vulkan" }, QLatin1String("Vulkan")); + cmdLineParser.addOption(vkOption); + QCommandLineOption d3dOption({ "d", "d3d11" }, QLatin1String("Direct3D 11")); + cmdLineParser.addOption(d3dOption); + QCommandLineOption mtlOption({ "m", "metal" }, QLatin1String("Metal")); + cmdLineParser.addOption(mtlOption); + + cmdLineParser.process(app); + if (cmdLineParser.isSet(nullOption)) + graphicsApi = QRhi::Null; + if (cmdLineParser.isSet(glOption)) + graphicsApi = QRhi::OpenGLES2; + if (cmdLineParser.isSet(vkOption)) + graphicsApi = QRhi::Vulkan; + if (cmdLineParser.isSet(d3dOption)) + graphicsApi = QRhi::D3D11; + if (cmdLineParser.isSet(mtlOption)) + graphicsApi = QRhi::Metal; + + qDebug("Selected graphics API is %s", qPrintable(graphicsApiName(graphicsApi))); + qDebug("This is a multi-api example, use command line arguments to override:\n%s", qPrintable(cmdLineParser.helpText())); + + QSurfaceFormat fmt; + fmt.setDepthBufferSize(24); + fmt.setStencilBufferSize(8); + QSurfaceFormat::setDefaultFormat(fmt); + +#if QT_CONFIG(vulkan) + QVulkanInstance inst; + if (graphicsApi == QRhi::Vulkan) { +#ifndef Q_OS_ANDROID + inst.setLayers({ "VK_LAYER_LUNARG_standard_validation" }); +#else + inst.setLayers({ + "VK_LAYER_GOOGLE_threading", + "VK_LAYER_LUNARG_parameter_validation", + "VK_LAYER_LUNARG_object_tracker", + "VK_LAYER_LUNARG_core_validation", + "VK_LAYER_LUNARG_image", + "VK_LAYER_LUNARG_swapchain", + "VK_LAYER_GOOGLE_unique_objects"}); +#endif + inst.setExtensions({ "VK_KHR_get_physical_device_properties2" }); + if (!inst.create()) { + qWarning("Failed to create Vulkan instance, switching to OpenGL"); + graphicsApi = QRhi::OpenGLES2; + } + } +#endif + + HelloWindow w(graphicsApi); +#if QT_CONFIG(vulkan) + if (graphicsApi == QRhi::Vulkan) + w.setVulkanInstance(&inst); +#endif + w.resize(1280, 720); + w.setTitle(QCoreApplication::applicationName() + QLatin1String(" - ") + graphicsApiName(graphicsApi)); + w.show(); + + int ret = app.exec(); + + // Window::event() will not get invoked when the + // PlatformSurfaceAboutToBeDestroyed event is sent during the QWindow + // destruction. That happens only when exiting via app::quit() instead of + // the more common QWindow::close(). Take care of it: if the QPlatformWindow + // is still around (there was no close() yet), get rid of the swapchain + // while it's not too late. + if (w.handle()) + w.releaseSwapChain(); + + return ret; +} |