Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implements Vulkan device list #970

Merged
merged 2 commits into from
Sep 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 50 additions & 1 deletion src/display_settings.cpp
Original file line number Diff line number Diff line change
@@ -1,20 +1,37 @@
#include "display_settings.hpp"
#include "vulkan.hpp"

#include <QComboBox>
#include <QGridLayout>
#include <QGroupBox>
#include <QMessageBox>
#include <QVBoxLayout>
#ifndef __APPLE__
#include <QVulkanFunctions>
#endif

#include <utility>

#ifdef __APPLE__
DisplaySettings::DisplaySettings(QWidget *parent) :
#else
DisplaySettings::DisplaySettings(QList<VkPhysicalDevice> &&vkDevices, QWidget *parent) :
#endif
QWidget(parent),
#ifndef __APPLE__
m_devices(nullptr),
#endif
m_resolutions(nullptr),
m_profile(nullptr)
{
auto layout = new QGridLayout();

#ifdef __APPLE__
layout->addWidget(buildResolution(), 0, 0);
layout->setColumnStretch(1, 1);
#else
layout->addWidget(buildDevice(std::move(vkDevices)), 0, 0);
layout->addWidget(buildResolution(), 0, 1);
#endif
layout->setRowStretch(1, 1);

setLayout(layout);
Expand Down Expand Up @@ -43,6 +60,30 @@ void DisplaySettings::setProfile(Profile *p)
}
}

#ifndef __APPLE__
QWidget *DisplaySettings::buildDevice(QList<VkPhysicalDevice> &&vkDevices)
{
// Setup group box.
auto group = new QGroupBox("Device");
auto layout = new QVBoxLayout();

// Setup device list.
m_devices = new QComboBox();

for (auto dev : vkDevices) {
auto data = new DisplayDevice(dev);

m_devices->addItem(data->name(), QVariant::fromValue(data));
}

layout->addWidget(m_devices);

group->setLayout(layout);

return group;
}
#endif

QWidget *DisplaySettings::buildResolution()
{
// Setup group box.
Expand All @@ -67,3 +108,11 @@ QWidget *DisplaySettings::buildResolution()

return group;
}

#ifndef __APPLE__
DisplayDevice::DisplayDevice(VkPhysicalDevice handle) :
m_handle(handle)
{
vkFunctions->vkGetPhysicalDeviceProperties(handle, &m_props);
}
#endif
26 changes: 26 additions & 0 deletions src/display_settings.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,45 @@

#include "core.h"

#ifndef __APPLE__
#include <QVulkanInstance>
#endif
#include <QWidget>

class QComboBox;

class DisplaySettings final : public QWidget {
public:
#ifdef __APPLE__
DisplaySettings(QWidget *parent = nullptr);
#else
DisplaySettings(QList<VkPhysicalDevice> &&vkDevices, QWidget *parent = nullptr);
#endif
~DisplaySettings() override;

void setProfile(Profile *p);
private:
#ifndef __APPLE__
QWidget *buildDevice(QList<VkPhysicalDevice> &&vkDevices);
#endif
QWidget *buildResolution();

#ifndef __APPLE__
QComboBox *m_devices;
#endif
QComboBox *m_resolutions;
Profile *m_profile;
};

#ifndef __APPLE__
class DisplayDevice : public QObject {
Q_OBJECT
public:
DisplayDevice(VkPhysicalDevice handle);

const char *name() const { return m_props.deviceName; }
private:
VkPhysicalDevice m_handle;
VkPhysicalDeviceProperties m_props;
};
#endif
22 changes: 22 additions & 0 deletions src/launch_settings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,29 @@
#include <QUrl>
#include <QVBoxLayout>

#include <utility>

#ifdef __APPLE__
LaunchSettings::LaunchSettings(ProfileList *profiles, GameListModel *games, QWidget *parent) :
#else
LaunchSettings::LaunchSettings(
ProfileList *profiles,
GameListModel *games,
QList<VkPhysicalDevice> &&vkDevices,
QWidget *parent) :
#endif
QWidget(parent),
m_display(nullptr),
m_games(nullptr),
m_profiles(nullptr)
{
auto layout = new QVBoxLayout();

#ifdef __APPLE__
layout->addWidget(buildSettings(games));
#else
layout->addWidget(buildSettings(games, std::move(vkDevices)));
#endif
layout->addLayout(buildActions(profiles));

setLayout(layout);
Expand All @@ -36,13 +50,21 @@ LaunchSettings::~LaunchSettings()
{
}

#ifdef __APPLE__
QWidget *LaunchSettings::buildSettings(GameListModel *games)
#else
QWidget *LaunchSettings::buildSettings(GameListModel *games, QList<VkPhysicalDevice> &&vkDevices)
#endif
{
// Tab.
auto tab = new QTabWidget();

// Display settings.
#ifdef __APPLE__
m_display = new DisplaySettings();
#else
m_display = new DisplaySettings(std::move(vkDevices));
#endif

tab->addTab(m_display, loadIcon(":/resources/monitor.svg"), "Display");

Expand Down
16 changes: 16 additions & 0 deletions src/launch_settings.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

#include "core.h"

#include <QList>
#ifndef __APPLE__
#include <QVulkanInstance>
#endif
#include <QWidget>

class DisplaySettings;
Expand All @@ -14,13 +18,25 @@ class QTableView;
class LaunchSettings final : public QWidget {
Q_OBJECT
public:
#ifdef __APPLE__
LaunchSettings(ProfileList *profiles, GameListModel *games, QWidget *parent = nullptr);
#else
LaunchSettings(
ProfileList *profiles,
GameListModel *games,
QList<VkPhysicalDevice> &&vkDevices,
QWidget *parent = nullptr);
#endif
~LaunchSettings() override;
signals:
void saveClicked(Profile *p);
void startClicked();
private:
#ifdef __APPLE__
QWidget *buildSettings(GameListModel *games);
#else
QWidget *buildSettings(GameListModel *games, QList<VkPhysicalDevice> &&vkDevices);
#endif
QLayout *buildActions(ProfileList *profiles);

void requestGamesContextMenu(const QPoint &pos);
Expand Down
66 changes: 64 additions & 2 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,18 @@
#endif

#include <QApplication>
#include <QList>
#include <QMessageBox>
#include <QMetaObject>
#include <QThread>
#ifndef __APPLE__
#include <QVersionNumber>
#include <QVulkanFunctions>
#include <QVulkanInstance>
#endif

#include <utility>

#ifndef _WIN32
#include <sys/resource.h>
#endif
Expand Down Expand Up @@ -92,11 +96,69 @@ int main(int argc, char *argv[])
QMessageBox::critical(
nullptr,
"Error",
QString("Failed to initialize Vulkan (%1)").arg(vulkan.errorCode()));
QString("Failed to initialize Vulkan (%1).").arg(vulkan.errorCode()));
return 1;
}

vkFunctions = vulkan.functions();

// List available devices.
QList<VkPhysicalDevice> vkDevices;

for (;;) {
// Get device count.
uint32_t count;
auto result = vkFunctions->vkEnumeratePhysicalDevices(vulkan.vkInstance(), &count, nullptr);

if (result != VK_SUCCESS) {
QMessageBox::critical(
nullptr,
"Error",
QString("Failed to get a number of Vulkan physical device (%1).").arg(result));
return 1;
} else if (!count) {
QMessageBox::critical(
nullptr,
"Error",
"No any Vulkan physical device available.");
return 1;
}

// Get devices.
vkDevices.resize(count);

result = vkFunctions->vkEnumeratePhysicalDevices(
vulkan.vkInstance(),
&count,
vkDevices.data());

if (result == VK_INCOMPLETE) {
continue;
} else if (result != VK_SUCCESS) {
QMessageBox::critical(
nullptr,
"Error",
QString("Failed to list Vulkan physical devices (%1).").arg(result));
return 1;
}

break;
}

// Filter out devices without Vulkan 1.3.
erase_if(vkDevices, [](VkPhysicalDevice dev) {
VkPhysicalDeviceProperties props;
vkFunctions->vkGetPhysicalDeviceProperties(dev, &props);
return props.apiVersion < VK_API_VERSION_1_3;
});

if (vkDevices.isEmpty()) {
QMessageBox::critical(
nullptr,
"Error",
"No any Vulkan device supports Vulkan 1.3.");
return 1;
}
#endif

// Check if no any required settings.
Expand All @@ -112,7 +174,7 @@ int main(int argc, char *argv[])
#ifdef __APPLE__
MainWindow win;
#else
MainWindow win(&vulkan);
MainWindow win(&vulkan, std::move(vkDevices));
#endif

if (!win.loadProfiles() || !win.loadGames()) {
Expand Down
9 changes: 5 additions & 4 deletions src/main_window.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,6 @@
#include <QStackedWidget>
#include <QToolBar>
#include <QUrl>
#ifndef __APPLE__
#include <QVulkanInstance>
#endif

#include <filesystem>
#include <iostream>
Expand All @@ -40,7 +37,7 @@
#ifdef __APPLE__
MainWindow::MainWindow() :
#else
MainWindow::MainWindow(QVulkanInstance *vulkan) :
MainWindow::MainWindow(QVulkanInstance *vulkan, QList<VkPhysicalDevice> &&vkDevices) :
#endif
m_main(nullptr),
m_profiles(nullptr),
Expand Down Expand Up @@ -101,7 +98,11 @@ MainWindow::MainWindow(QVulkanInstance *vulkan) :
// Launch settings.
m_profiles = new ProfileList(this);
m_games = new GameListModel(this);
#ifdef __APPLE__
m_launch = new LaunchSettings(m_profiles, m_games);
#else
m_launch = new LaunchSettings(m_profiles, m_games, std::move(vkDevices));
#endif

connect(m_launch, &LaunchSettings::saveClicked, this, &MainWindow::saveProfile);
connect(m_launch, &LaunchSettings::startClicked, this, &MainWindow::startKernel);
Expand Down
9 changes: 5 additions & 4 deletions src/main_window.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,26 @@

#include "core.hpp"

#include <QList>
#include <QMainWindow>
#include <QPointer>
#ifndef __APPLE__
#include <QVulkanInstance>
#endif

class GameListModel;
class LaunchSettings;
class LogsViewer;
class ProfileList;
class QStackedWidget;
#ifndef __APPLE__
class QVulkanInstance;
#endif
class Screen;

class MainWindow final : public QMainWindow {
public:
#ifdef __APPLE__
MainWindow();
#else
MainWindow(QVulkanInstance *vulkan);
MainWindow(QVulkanInstance *vulkan, QList<VkPhysicalDevice> &&vkDevices);
#endif
~MainWindow() override;

Expand Down