summaryrefslogtreecommitdiffstats
path: root/examples/vulkan/hellovulkanwidget/hellovulkanwidget.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'examples/vulkan/hellovulkanwidget/hellovulkanwidget.cpp')
-rw-r--r--examples/vulkan/hellovulkanwidget/hellovulkanwidget.cpp185
1 files changed, 185 insertions, 0 deletions
diff --git a/examples/vulkan/hellovulkanwidget/hellovulkanwidget.cpp b/examples/vulkan/hellovulkanwidget/hellovulkanwidget.cpp
new file mode 100644
index 0000000000..81daa9bb96
--- /dev/null
+++ b/examples/vulkan/hellovulkanwidget/hellovulkanwidget.cpp
@@ -0,0 +1,185 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 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$
+**
+****************************************************************************/
+
+#include "hellovulkanwidget.h"
+#include <QVulkanFunctions>
+#include <QApplication>
+#include <QVBoxLayout>
+#include <QPlainTextEdit>
+#include <QPushButton>
+#include <QLCDNumber>
+#include <QFileDialog>
+#include <QMessageBox>
+#include <QTabWidget>
+
+MainWindow::MainWindow(VulkanWindow *w, QPlainTextEdit *logWidget)
+ : m_window(w)
+{
+ QWidget *wrapper = QWidget::createWindowContainer(w);
+
+ m_info = new QPlainTextEdit;
+ m_info->setReadOnly(true);
+
+ m_number = new QLCDNumber(3);
+ m_number->setSegmentStyle(QLCDNumber::Filled);
+
+ QPushButton *grabButton = new QPushButton(tr("&Grab"));
+ grabButton->setFocusPolicy(Qt::NoFocus);
+
+ connect(grabButton, &QPushButton::clicked, this, &MainWindow::onGrabRequested);
+
+ QPushButton *quitButton = new QPushButton(tr("&Quit"));
+ quitButton->setFocusPolicy(Qt::NoFocus);
+
+ connect(quitButton, &QPushButton::clicked, qApp, &QCoreApplication::quit);
+
+ QVBoxLayout *layout = new QVBoxLayout;
+ m_infoTab = new QTabWidget(this);
+ m_infoTab->addTab(m_info, tr("Vulkan Info"));
+ m_infoTab->addTab(logWidget, tr("Debug Log"));
+ layout->addWidget(m_infoTab, 2);
+ layout->addWidget(m_number, 1);
+ layout->addWidget(wrapper, 5);
+ layout->addWidget(grabButton, 1);
+ layout->addWidget(quitButton, 1);
+ setLayout(layout);
+}
+
+void MainWindow::onVulkanInfoReceived(const QString &text)
+{
+ m_info->setPlainText(text);
+}
+
+void MainWindow::onFrameQueued(int colorValue)
+{
+ m_number->display(colorValue);
+}
+
+void MainWindow::onGrabRequested()
+{
+ if (!m_window->supportsGrab()) {
+ QMessageBox::warning(this, tr("Cannot grab"), tr("This swapchain does not support readbacks."));
+ return;
+ }
+
+ QImage img = m_window->grab();
+
+ // Our startNextFrame() implementation is synchronous so img is ready to be
+ // used right here.
+
+ QFileDialog fd(this);
+ fd.setAcceptMode(QFileDialog::AcceptSave);
+ fd.setDefaultSuffix("png");
+ fd.selectFile("test.png");
+ if (fd.exec() == QDialog::Accepted)
+ img.save(fd.selectedFiles().first());
+}
+
+QVulkanWindowRenderer *VulkanWindow::createRenderer()
+{
+ return new VulkanRenderer(this);
+}
+
+VulkanRenderer::VulkanRenderer(VulkanWindow *w)
+ : TriangleRenderer(w)
+{
+}
+
+void VulkanRenderer::initResources()
+{
+ TriangleRenderer::initResources();
+
+ QVulkanInstance *inst = m_window->vulkanInstance();
+ m_devFuncs = inst->deviceFunctions(m_window->device());
+
+ QString info;
+ info += QString().sprintf("Number of physical devices: %d\n", m_window->availablePhysicalDevices().count());
+
+ QVulkanFunctions *f = inst->functions();
+ VkPhysicalDeviceProperties props;
+ f->vkGetPhysicalDeviceProperties(m_window->physicalDevice(), &props);
+ info += QString().sprintf("Active physical device name: '%s' version %d.%d.%d\nAPI version %d.%d.%d\n",
+ props.deviceName,
+ VK_VERSION_MAJOR(props.driverVersion), VK_VERSION_MINOR(props.driverVersion),
+ VK_VERSION_PATCH(props.driverVersion),
+ VK_VERSION_MAJOR(props.apiVersion), VK_VERSION_MINOR(props.apiVersion),
+ VK_VERSION_PATCH(props.apiVersion));
+
+ info += QStringLiteral("Supported instance layers:\n");
+ for (const QVulkanLayer &layer : inst->supportedLayers())
+ info += QString().sprintf(" %s v%u\n", layer.name.constData(), layer.version);
+ info += QStringLiteral("Enabled instance layers:\n");
+ for (const QByteArray &layer : inst->layers())
+ info += QString().sprintf(" %s\n", layer.constData());
+
+ info += QStringLiteral("Supported instance extensions:\n");
+ for (const QVulkanExtension &ext : inst->supportedExtensions())
+ info += QString().sprintf(" %s v%u\n", ext.name.constData(), ext.version);
+ info += QStringLiteral("Enabled instance extensions:\n");
+ for (const QByteArray &ext : inst->extensions())
+ info += QString().sprintf(" %s\n", ext.constData());
+
+ info += QString().sprintf("Color format: %u\nDepth-stencil format: %u\n",
+ m_window->colorFormat(), m_window->depthStencilFormat());
+
+ info += QStringLiteral("Supported sample counts:");
+ const QVector<int> sampleCounts = m_window->supportedSampleCounts();
+ for (int count : sampleCounts)
+ info += QLatin1Char(' ') + QString::number(count);
+ info += QLatin1Char('\n');
+
+ emit static_cast<VulkanWindow *>(m_window)->vulkanInfoReceived(info);
+}
+
+void VulkanRenderer::startNextFrame()
+{
+ TriangleRenderer::startNextFrame();
+ emit static_cast<VulkanWindow *>(m_window)->frameQueued(int(m_rotation) % 360);
+}