Revision control

++ // Copyright (C) 2017 The Qt Company Ltd.
++ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
++
++ #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::asprintf("Number of physical devices: %d\n", int(m_window->availablePhysicalDevices().count()));
++
++ QVulkanFunctions *f = inst->functions();
++ VkPhysicalDeviceProperties props;
++ f->vkGetPhysicalDeviceProperties(m_window->physicalDevice(), &props);
++ info += QString::asprintf("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::asprintf(" %s v%u\n", layer.name.constData(), layer.version);
++ info += QStringLiteral("Enabled instance layers:\n");
++ for (const QByteArray &layer : inst->layers())
++ info += QString::asprintf(" %s\n", layer.constData());
++
++ info += QStringLiteral("Supported instance extensions:\n");
++ for (const QVulkanExtension &ext : inst->supportedExtensions())
++ info += QString::asprintf(" %s v%u\n", ext.name.constData(), ext.version);
++ info += QStringLiteral("Enabled instance extensions:\n");
++ for (const QByteArray &ext : inst->extensions())
++ info += QString::asprintf(" %s\n", ext.constData());
++
++ info += QString::asprintf("Color format: %u\nDepth-stencil format: %u\n",
++ m_window->colorFormat(), m_window->depthStencilFormat());
++
++ info += QStringLiteral("Supported sample counts:");
++ const QList<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);
++ }