crueter 3 months ago
parent
commit
f8aaa55a38
No known key found for this signature in database GPG Key ID: 425ACD2D4830EBC6
  1. 11
      CMakeModules/EdenModule.cmake
  2. 3
      src/CMakeLists.txt
  3. 1
      src/Eden/Config/GlobalConfigureDialog.qml
  4. 4
      src/Eden/Config/fields/BaseField.qml
  5. 4
      src/Eden/Config/fields/ConfigComboBox.qml
  6. 20
      src/Eden/Config/pages/SettingsList.qml
  7. 19
      src/Eden/Config/pages/cpu/CpuGeneralPage.qml
  8. 42
      src/Eden/Config/pages/graphics/RendererPage.qml
  9. 1
      src/Eden/Interface/CMakeLists.txt
  10. 150
      src/Eden/Interface/GraphicsDeviceInterface.cpp
  11. 74
      src/Eden/Interface/GraphicsDeviceInterface.h
  12. 2
      src/Eden/Interface/SettingsInterface.h
  13. 3
      src/Eden/Main/CMakeLists.txt
  14. 2
      src/qt_common/CMakeLists.txt
  15. 4
      src/qt_common/qt_common.cpp
  16. 4
      src/qt_common/util/vk_device_info.cpp
  17. 71
      src/qt_common/util/vk_device_info.h
  18. 6
      src/yuzu/CMakeLists.txt
  19. 2
      src/yuzu/configuration/configure_dialog.cpp
  20. 2
      src/yuzu/configuration/configure_dialog.h
  21. 36
      src/yuzu/configuration/configure_graphics.cpp
  22. 2
      src/yuzu/configuration/configure_graphics.h
  23. 2
      src/yuzu/configuration/configure_per_game.cpp
  24. 2
      src/yuzu/configuration/configure_per_game.h
  25. 548
      src/yuzu/main.cpp
  26. 4
      src/yuzu/main_window.cpp
  27. 36
      src/yuzu/vk_device_info.h

11
CMakeModules/EdenModule.cmake

@ -10,14 +10,12 @@ function(EdenModule)
set(oneValueArgs
NAME
URI
NATIVE
)
NATIVE)
set(multiValueArgs
LIBRARIES
QML_FILES
SOURCES
)
SOURCES)
cmake_parse_arguments(MODULE "" "${oneValueArgs}" "${multiValueArgs}"
"${ARGN}")
@ -30,14 +28,12 @@ function(EdenModule)
qt_add_qml_module(${LIB_NAME}
URI ${MODULE_URI}
NO_PLUGIN
VERSION 0.1
QML_FILES ${MODULE_QML_FILES}
SOURCES ${MODULE_SOURCES}
${MODULE_UNPARSED_ARGUMENTS}
)
${MODULE_UNPARSED_ARGUMENTS})
add_library(Eden::${MODULE_NAME} ALIAS ${LIB_NAME})
@ -46,4 +42,5 @@ function(EdenModule)
endif()
target_link_libraries(${LIB_NAME} PRIVATE Carboxyl::Base Carboxyl::Styles)
target_link_libraries(${LIB_NAME} PUBLIC ${LIB_NAME}plugin)
endfunction()

3
src/CMakeLists.txt

@ -241,6 +241,7 @@ endif()
if (ENABLE_QT)
add_subdirectory(qt_common)
add_subdirectory(Eden)
add_subdirectory(yuzu)
endif()
if (ENABLE_WEB_SERVICE)
@ -251,3 +252,5 @@ if (ANDROID)
add_subdirectory(android/app/src/main/jni)
target_include_directories(yuzu-android PRIVATE android/app/src/main)
endif()
include(GenerateDepHashes)

1
src/Eden/Config/GlobalConfigureDialog.qml

@ -48,7 +48,6 @@ Dialog {
left: parent.left
leftMargin: 10
bottom: parent.bottom
}
contentWidth: 100
contentHeight: 60

4
src/Eden/Config/fields/BaseField.qml

@ -61,10 +61,12 @@ Item {
z: 2
force: field.forceCheckbox
height: 40
height: 30
anchors {
left: help.right
leftMargin: -5
verticalCenter: parent.verticalCenter
}
}

4
src/Eden/Config/fields/ConfigComboBox.qml

@ -8,6 +8,8 @@ import Eden.Config
BaseField {
id: field
property var runtimeModel: null
contentItem: ComboBox {
id: control
enabled: enable
@ -16,7 +18,7 @@ BaseField {
Layout.rightMargin: 10
font.pixelSize: 14
model: setting.combo
model: runtimeModel !== null ? runtimeModel : setting.combo
currentIndex: -1

20
src/Eden/Config/pages/SettingsList.qml

@ -32,18 +32,18 @@ ListView {
Layout.fillHeight: true
Layout.fillWidth: true
Layout.leftMargin: 5
spacing: 0
Layout.leftMargin: 0
spacing: 5
model: SettingsInterface.category(category, idInclude, idExclude)
Rectangle {
anchors.fill: parent
color: "transparent"
// Rectangle {
// anchors.fill: parent
// color: "transparent"
border {
color: inset ? palette.text : "transparent"
width: 1
}
}
// border {
// color: inset ? palette.text : "transparent"
// width: 1
// }
// }
}

19
src/Eden/Config/pages/cpu/CpuGeneralPage.qml

@ -15,9 +15,28 @@ PageScrollView {
ColumnLayout {
width: scroll.width - scroll.effectiveScrollBarWidth
// TODO: backend handling
ConfigComboBox {
Layout.fillWidth: true
id: acc
setting: SettingsInterface.setting("cpu_accuracy")
}
SettingsList {
id: cpu
category: SettingsCategories.Cpu
idExclude: ["cpu_accuracy"]
}
SectionHeader {
text: qsTr("Unsafe Optimizations")
visible: acc.value === 2
}
SettingsList {
id: unsafe
category: SettingsCategories.CpuUnsafe
visible: acc.value === 2
}
}
}

42
src/Eden/Config/pages/graphics/RendererPage.qml

@ -10,14 +10,56 @@ PageScrollView {
function apply() {
gfx.apply()
api.apply()
dev.apply()
shader.apply()
vsync.apply()
}
GraphicsDeviceInterface {
id: gdi
api: api.value
device: dev.value
vsyncMode: vsync.value
}
ColumnLayout {
width: scroll.width - scroll.effectiveScrollBarWidth
ConfigComboBox {
Layout.fillWidth: true
id: api
setting: SettingsInterface.setting("backend")
}
ConfigComboBox {
Layout.fillWidth: true
id: dev
setting: SettingsInterface.setting("vulkan_device")
runtimeModel: gdi.devices
visible: gdi.isVulkan
}
ConfigComboBox {
Layout.fillWidth: true
id: shader
setting: SettingsInterface.setting("shader_backend")
visible: gdi.isOpenGL
}
ConfigComboBox {
Layout.fillWidth: true
id: vsync
setting: SettingsInterface.setting("use_vsync")
runtimeModel: gdi.vsyncModes
visible: gdi.isOpenGL || gdi.isVulkan
}
SettingsList {
id: gfx
category: SettingsCategories.Renderer
idExclude: ["vulkan_device", "backend", "shader_backend", "use_vsync"]
}
}
}

1
src/Eden/Interface/CMakeLists.txt

@ -13,6 +13,7 @@ EdenModule(
MetaObjectHelper.h
QMLConfig.h
TitleManager.h TitleManager.cpp
GraphicsDeviceInterface.h GraphicsDeviceInterface.cpp
LIBRARIES
Qt6::Quick
Qt6::Core

150
src/Eden/Interface/GraphicsDeviceInterface.cpp

@ -0,0 +1,150 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
#include "GraphicsDeviceInterface.h"
#include <QWindow>
#include "common/settings.h"
#include "common/settings_enums.h"
#include "qt_common/qt_common.h"
static const QString TranslateVSyncMode(VkPresentModeKHR mode,
Settings::RendererBackend backend) {
switch (mode) {
case VK_PRESENT_MODE_IMMEDIATE_KHR:
return backend == Settings::RendererBackend::OpenGL
? QtCommon::tr("Off")
: QStringLiteral("Immediate (%1)").arg(QtCommon::tr("VSync Off"));
case VK_PRESENT_MODE_MAILBOX_KHR:
return QStringLiteral("Mailbox (%1)").arg(QtCommon::tr("Recommended"));
case VK_PRESENT_MODE_FIFO_KHR:
return backend == Settings::RendererBackend::OpenGL
? QtCommon::tr("On")
: QStringLiteral("FIFO (%1)").arg(QtCommon::tr("VSync On"));
case VK_PRESENT_MODE_FIFO_RELAXED_KHR:
return QStringLiteral("FIFO Relaxed");
default:
return {};
break;
}
}
GraphicsDeviceInterface::GraphicsDeviceInterface(QQuickItem *parent)
: QQuickItem(parent)
{}
QStringList GraphicsDeviceInterface::devices()
{
return vulkan_devices;
}
void GraphicsDeviceInterface::populateDevices()
{
vulkan_devices.clear();
vulkan_devices.reserve(records.size());
device_present_modes.clear();
device_present_modes.reserve(records.size());
for (const auto &record : records) {
vulkan_devices.push_back(QString::fromStdString(record.name));
device_present_modes.push_back(record.vsync_support);
// if (record.has_broken_compute) {
// expose_compute_option();
// }
}
emit devicesChanged();
}
void GraphicsDeviceInterface::populateVsync()
{
if (m_api == Settings::RendererBackend::Null) {
return;
}
const auto &present_modes = //< relevant vector of present modes for the selected device or API
m_isVulkan && m_device > -1 ? device_present_modes[m_device] : default_present_modes;
m_vsyncModes.clear();
m_vsyncModes.reserve(present_modes.size());
for (const auto present_mode : present_modes) {
const auto mode_name = TranslateVSyncMode(present_mode, m_api);
if (mode_name.isEmpty()) {
continue;
}
m_vsyncModes.append(mode_name);
}
emit vsyncModesChanged(m_vsyncModes);
}
Settings::RendererBackend GraphicsDeviceInterface::api() const
{
return m_api;
}
void GraphicsDeviceInterface::setApi(const Settings::RendererBackend &newApi)
{
if (m_api == newApi)
return;
m_api = newApi;
emit apiChanged(m_api);
m_isOpenGL = newApi == Settings::RendererBackend::OpenGL;
m_isVulkan = newApi == Settings::RendererBackend::Vulkan;
emit isOpenGLChanged(m_isOpenGL);
emit isVulkanChanged(m_isVulkan);
}
void GraphicsDeviceInterface::componentComplete()
{
VkDeviceInfo::PopulateRecords(records, (QWindow *) window());
populateDevices();
populateVsync();
}
bool GraphicsDeviceInterface::isOpenGL() const
{
return m_isOpenGL;
}
bool GraphicsDeviceInterface::isVulkan() const
{
return m_isVulkan;
}
int GraphicsDeviceInterface::device() const
{
return m_device;
}
void GraphicsDeviceInterface::setDevice(int newDevice)
{
if (m_device == newDevice)
return;
m_device = newDevice;
emit deviceChanged(m_device);
populateVsync();
}
QStringList GraphicsDeviceInterface::vsyncModes() const
{
return m_vsyncModes;
}
int GraphicsDeviceInterface::vsyncMode() const
{
return m_vsyncMode;
}
void GraphicsDeviceInterface::setVsyncMode(int newVsyncMode)
{
if (m_vsyncMode == newVsyncMode)
return;
m_vsyncMode = newVsyncMode;
emit vsyncModeChanged(m_vsyncMode);
}

74
src/Eden/Interface/GraphicsDeviceInterface.h

@ -0,0 +1,74 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
#pragma once
#include <QQuickItem>
#include "qt_common/util/vk_device_info.h"
class GraphicsDeviceInterface : public QQuickItem
{
Q_OBJECT
QML_ELEMENT
Q_PROPERTY(QStringList devices READ devices NOTIFY devicesChanged)
Q_PROPERTY(QStringList vsyncModes READ vsyncModes NOTIFY vsyncModesChanged)
Q_PROPERTY(Settings::RendererBackend api READ api WRITE setApi NOTIFY apiChanged)
Q_PROPERTY(int device READ device WRITE setDevice NOTIFY deviceChanged)
Q_PROPERTY(int vsyncMode READ vsyncMode WRITE setVsyncMode NOTIFY vsyncModeChanged)
Q_PROPERTY(bool isOpenGL READ isOpenGL NOTIFY isOpenGLChanged)
Q_PROPERTY(bool isVulkan READ isVulkan NOTIFY isVulkanChanged)
public:
explicit GraphicsDeviceInterface(QQuickItem *parent = nullptr);
QStringList devices();
Settings::RendererBackend api() const;
void setApi(const Settings::RendererBackend &newApi);
bool isOpenGL() const;
bool isVulkan() const;
int device() const;
void setDevice(int newDevice);
QStringList vsyncModes() const;
int vsyncMode() const;
void setVsyncMode(int newVsyncMode);
protected:
void componentComplete();
signals:
void apiChanged(Settings::RendererBackend api);
void devicesChanged();
void isOpenGLChanged(bool isOpenGL);
void isVulkanChanged(bool isVulkan);
void deviceChanged(int device);
void vsyncModesChanged(QStringList vsyncModes);
void vsyncModeChanged(int vsyncMode);
private:
std::vector<VkDeviceInfo::Record> records{};
QStringList vulkan_devices;
QStringList m_vsyncModes;
std::vector<std::vector<VkPresentModeKHR>> device_present_modes;
void populateDevices();
void populateVsync();
Settings::RendererBackend m_api;
bool m_isOpenGL;
bool m_isVulkan;
int m_device;
int m_vsyncMode;
};

2
src/Eden/Interface/SettingsInterface.h

@ -53,7 +53,7 @@ Q_ENUM_NS(Category)
class SettingsInterface : public QObject {
Q_OBJECT
QML_ELEMENT
public:
explicit SettingsInterface(QObject* parent = nullptr);

3
src/Eden/Main/CMakeLists.txt

@ -18,5 +18,6 @@ EdenModule(
GameCarouselCard.qml
GameCarousel.qml
LIBRARIES Eden::Interface
LIBRARIES
Eden::Interface
)

2
src/qt_common/CMakeLists.txt

@ -31,6 +31,8 @@ add_library(qt_common STATIC
discord/discord.h
util/fs.h util/fs.cpp
util/vk_device_info.cpp
util/vk_device_info.h
)
if (UNIX)

4
src/qt_common/qt_common.cpp

@ -108,12 +108,12 @@ Core::Frontend::EmuWindow::WindowSystemInfo GetWindowSystemInfo(QWindow* window)
const QString tr(const char* str)
{
return QGuiApplication::tr(str);
return rootObject->tr(str);
}
const QString tr(const std::string& str)
{
return QGuiApplication::tr(str.c_str());
return rootObject->tr(str.c_str());
}
static void LogRuntimes() {

4
src/yuzu/vk_device_info.cpp → src/qt_common/util/vk_device_info.cpp

@ -4,12 +4,10 @@
// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include <utility>
#include <vector>
#include "qt_common/qt_common.h"
#include "common/dynamic_library.h"
#include "common/logging/log.h"
#include "video_core/vulkan_common/vulkan_device.h"
#include "video_core/vulkan_common/vulkan_instance.h"
@ -17,7 +15,7 @@
#include "video_core/vulkan_common/vulkan_surface.h"
#include "video_core/vulkan_common/vulkan_wrapper.h"
#include "vulkan/vulkan_core.h"
#include "yuzu/vk_device_info.h"
#include "qt_common/util/vk_device_info.h"
class QWindow;

71
src/qt_common/util/vk_device_info.h

@ -0,0 +1,71 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include "common/settings_enums.h"
#include "vulkan/vulkan_core.h"
#include <string>
#include <string_view>
#include <vector>
class QWindow;
static const std::vector<VkPresentModeKHR>
default_present_modes{VK_PRESENT_MODE_IMMEDIATE_KHR, VK_PRESENT_MODE_FIFO_KHR};
// Converts a setting to a present mode (or vice versa)
static inline constexpr VkPresentModeKHR VSyncSettingToMode(Settings::VSyncMode mode)
{
switch (mode) {
case Settings::VSyncMode::Immediate:
return VK_PRESENT_MODE_IMMEDIATE_KHR;
case Settings::VSyncMode::Mailbox:
return VK_PRESENT_MODE_MAILBOX_KHR;
case Settings::VSyncMode::Fifo:
return VK_PRESENT_MODE_FIFO_KHR;
case Settings::VSyncMode::FifoRelaxed:
return VK_PRESENT_MODE_FIFO_RELAXED_KHR;
default:
return VK_PRESENT_MODE_FIFO_KHR;
}
}
static inline constexpr Settings::VSyncMode PresentModeToSetting(VkPresentModeKHR mode)
{
switch (mode) {
case VK_PRESENT_MODE_IMMEDIATE_KHR:
return Settings::VSyncMode::Immediate;
case VK_PRESENT_MODE_MAILBOX_KHR:
return Settings::VSyncMode::Mailbox;
case VK_PRESENT_MODE_FIFO_KHR:
return Settings::VSyncMode::Fifo;
case VK_PRESENT_MODE_FIFO_RELAXED_KHR:
return Settings::VSyncMode::FifoRelaxed;
default:
return Settings::VSyncMode::Fifo;
}
}
namespace VkDeviceInfo {
// Short class to record Vulkan driver information for configuration purposes
class Record
{
public:
explicit Record(std::string_view name,
const std::vector<VkPresentModeKHR>& vsync_modes,
bool has_broken_compute);
~Record();
const std::string name;
const std::vector<VkPresentModeKHR> vsync_support;
const bool has_broken_compute;
};
void PopulateRecords(std::vector<Record>& records, QWindow* window);
} // namespace VkDeviceInfo

6
src/yuzu/CMakeLists.txt

@ -214,8 +214,8 @@ add_executable(yuzu
util/url_request_interceptor.h
util/util.cpp
util/util.h
vk_device_info.cpp
vk_device_info.h
compatdb.cpp
compatdb.h
user_data_migration.cpp
@ -237,7 +237,7 @@ add_executable(yuzu
main_window.h main_window.cpp
)
set_target_properties(yuzu PROPERTIES OUTPUT_NAME "eden")
set_target_properties(yuzu PROPERTIES OUTPUT_NAME "eden-widgets")
if (YUZU_CRASH_DUMPS)
target_sources(yuzu PRIVATE

2
src/yuzu/configuration/configure_dialog.cpp

@ -10,7 +10,7 @@
#include "common/settings_enums.h"
#include "core/core.h"
#include "ui_configure.h"
#include "vk_device_info.h"
#include "qt_common/util/vk_device_info.h"
#include "yuzu/configuration/configure_applets.h"
#include "yuzu/configuration/configure_audio.h"
#include "yuzu/configuration/configure_cpu.h"

2
src/yuzu/configuration/configure_dialog.h

@ -12,7 +12,7 @@
#include "configuration/shared_widget.h"
#include "yuzu/configuration/configuration_shared.h"
#include "qt_common/config/shared_translation.h"
#include "yuzu/vk_device_info.h"
#include "qt_common/util/vk_device_info.h"
namespace Core {
class System;

36
src/yuzu/configuration/configure_graphics.cpp

@ -45,41 +45,7 @@
#include "yuzu/configuration/shared_widget.h"
#include "qt_common/qt_common.h"
#include "qt_common/config/uisettings.h"
#include "yuzu/vk_device_info.h"
static const std::vector<VkPresentModeKHR> default_present_modes{VK_PRESENT_MODE_IMMEDIATE_KHR,
VK_PRESENT_MODE_FIFO_KHR};
// Converts a setting to a present mode (or vice versa)
static constexpr VkPresentModeKHR VSyncSettingToMode(Settings::VSyncMode mode) {
switch (mode) {
case Settings::VSyncMode::Immediate:
return VK_PRESENT_MODE_IMMEDIATE_KHR;
case Settings::VSyncMode::Mailbox:
return VK_PRESENT_MODE_MAILBOX_KHR;
case Settings::VSyncMode::Fifo:
return VK_PRESENT_MODE_FIFO_KHR;
case Settings::VSyncMode::FifoRelaxed:
return VK_PRESENT_MODE_FIFO_RELAXED_KHR;
default:
return VK_PRESENT_MODE_FIFO_KHR;
}
}
static constexpr Settings::VSyncMode PresentModeToSetting(VkPresentModeKHR mode) {
switch (mode) {
case VK_PRESENT_MODE_IMMEDIATE_KHR:
return Settings::VSyncMode::Immediate;
case VK_PRESENT_MODE_MAILBOX_KHR:
return Settings::VSyncMode::Mailbox;
case VK_PRESENT_MODE_FIFO_KHR:
return Settings::VSyncMode::Fifo;
case VK_PRESENT_MODE_FIFO_RELAXED_KHR:
return Settings::VSyncMode::FifoRelaxed;
default:
return Settings::VSyncMode::Fifo;
}
}
#include "qt_common/util/vk_device_info.h"
ConfigureGraphics::ConfigureGraphics(
const Core::System& system_, std::vector<VkDeviceInfo::Record>& records_,

2
src/yuzu/configuration/configure_graphics.h

@ -19,7 +19,7 @@
#include "common/common_types.h"
#include "common/settings_enums.h"
#include "qt_common/config/shared_translation.h"
#include "vk_device_info.h"
#include "qt_common/util/vk_device_info.h"
#include "yuzu/configuration/configuration_shared.h"
class QPushButton;

2
src/yuzu/configuration/configure_per_game.cpp

@ -43,7 +43,7 @@
#include "yuzu/configuration/configure_network.h"
#include "qt_common/config/uisettings.h"
#include "yuzu/util/util.h"
#include "yuzu/vk_device_info.h"
#include "qt_common/util/vk_device_info.h"
ConfigurePerGame::ConfigurePerGame(QWidget* parent, u64 title_id_, const std::string& file_name,
std::vector<VkDeviceInfo::Record>& vk_device_records,

2
src/yuzu/configuration/configure_per_game.h

@ -16,7 +16,7 @@
#include "configuration/shared_widget.h"
#include "core/file_sys/vfs/vfs_types.h"
#include "frontend_common/config.h"
#include "vk_device_info.h"
#include "qt_common/util/vk_device_info.h"
#include "yuzu/configuration/configuration_shared.h"
#include "qt_common/config/qt_config.h"
#include "qt_common/config/shared_translation.h"

548
src/yuzu/main.cpp

@ -20,6 +20,554 @@
#ifdef _WIN32
#include <QScreen>
<<<<<<< HEAD
||||||| parent of ee74fc3d5c (real vulkan device info (#1))
#include <QCheckBox>
#include <QStringLiteral>
#ifdef HAVE_SDL2
#include <SDL.h> // For SDL ScreenSaver functions
#endif
#include <fmt/ranges.h>
#include "common/detached_tasks.h"
#include "common/fs/fs.h"
#include "common/fs/path_util.h"
#include "common/fs/ryujinx_compat.h"
#include "common/literals.h"
#include "common/logging/backend.h"
#include "common/logging/log.h"
#include "common/memory_detect.h"
#include "common/scm_rev.h"
#include "common/scope_exit.h"
#ifdef _WIN32
#include "core/core_timing.h"
#include "common/windows/timer_resolution.h"
#endif
#ifdef ARCHITECTURE_x86_64
#include "common/x64/cpu_detect.h"
#endif
#include "common/settings.h"
#include "core/core.h"
#include "core/crypto/key_manager.h"
#include "core/file_sys/card_image.h"
#include "core/file_sys/common_funcs.h"
#include "core/file_sys/content_archive.h"
#include "core/file_sys/control_metadata.h"
#include "core/file_sys/patch_manager.h"
#include "core/file_sys/registered_cache.h"
#include "core/file_sys/romfs.h"
#include "core/file_sys/savedata_factory.h"
#include "core/file_sys/submission_package.h"
#include "core/hle/kernel/k_process.h"
#include "core/hle/service/acc/profile_manager.h"
#include "core/hle/service/am/am.h"
#include "core/hle/service/filesystem/filesystem.h"
#include "core/hle/service/sm/sm.h"
#include "core/loader/loader.h"
#include "core/perf_stats.h"
#include "frontend_common/config.h"
#include "input_common/drivers/tas_input.h"
#include "input_common/drivers/virtual_amiibo.h"
#include "input_common/main.h"
#include "ui_main.h"
#include "yuzu/util/overlay_dialog.h"
#include "video_core/gpu.h"
#include "video_core/renderer_base.h"
#include "video_core/shader_notify.h"
#include "yuzu/about_dialog.h"
#include "yuzu/bootmanager.h"
#include "yuzu/compatibility_list.h"
#include "yuzu/configuration/configure_dialog.h"
#include "yuzu/configuration/configure_input_per_game.h"
#include "qt_common/config/qt_config.h"
#include "yuzu/debugger/console.h"
#include "yuzu/debugger/controller.h"
#include "yuzu/debugger/wait_tree.h"
#include "yuzu/data_dialog.h"
#include "yuzu/deps_dialog.h"
#include "yuzu/ryujinx_dialog.h"
#include "qt_common/discord/discord.h"
#include "yuzu/game_list.h"
#include "yuzu/game_list_p.h"
#include "yuzu/install_dialog.h"
#include "yuzu/loading_screen.h"
#include "yuzu/main.h"
#include "frontend_common/play_time_manager.h"
#include "yuzu/startup_checks.h"
#include "qt_common/config/uisettings.h"
#include "yuzu/util/clickable_label.h"
#include "yuzu/vk_device_info.h"
#ifdef _WIN32
#include <QPlatformSurfaceEvent>
#include <dwmapi.h>
#include <windows.h>
#ifdef _MSC_VER
#pragma comment(lib, "Dwmapi.lib")
#endif
static inline void ApplyWindowsTitleBarDarkMode(HWND hwnd, bool enabled) {
if (!hwnd)
return;
BOOL val = enabled ? TRUE : FALSE;
// 20 = Win11/21H2+
if (SUCCEEDED(DwmSetWindowAttribute(hwnd, 20, &val, sizeof(val))))
return;
// 19 = pre-21H2
DwmSetWindowAttribute(hwnd, 19, &val, sizeof(val));
}
static inline void ApplyDarkToTopLevel(QWidget* w, bool on) {
if (!w || !w->isWindow())
return;
ApplyWindowsTitleBarDarkMode(reinterpret_cast<HWND>(w->winId()), on);
}
namespace {
struct TitlebarFilter final : QObject {
bool dark;
explicit TitlebarFilter(bool is_dark) : QObject(qApp), dark(is_dark) {}
void setDark(bool is_dark) {
dark = is_dark;
}
void onFocusChanged(QWidget*, QWidget* now) {
if (now)
ApplyDarkToTopLevel(now->window(), dark);
}
bool eventFilter(QObject* obj, QEvent* ev) override {
if (auto* w = qobject_cast<QWidget*>(obj)) {
switch (ev->type()) {
case QEvent::WinIdChange:
case QEvent::Show:
case QEvent::ShowToParent:
case QEvent::Polish:
case QEvent::WindowStateChange:
case QEvent::ZOrderChange:
ApplyDarkToTopLevel(w, dark);
break;
default:
break;
}
}
return QObject::eventFilter(obj, ev);
}
};
static TitlebarFilter* g_filter = nullptr;
static QMetaObject::Connection g_focusConn;
} // namespace
static void ApplyGlobalDarkTitlebar(bool is_dark) {
if (!g_filter) {
g_filter = new TitlebarFilter(is_dark);
qApp->installEventFilter(g_filter);
g_focusConn = QObject::connect(qApp, &QApplication::focusChanged, g_filter,
&TitlebarFilter::onFocusChanged);
} else {
g_filter->setDark(is_dark);
}
for (QWidget* w : QApplication::topLevelWidgets())
ApplyDarkToTopLevel(w, is_dark);
}
static void RemoveTitlebarFilter() {
if (!g_filter)
return;
qApp->removeEventFilter(g_filter);
QObject::disconnect(g_focusConn);
g_filter->deleteLater();
g_filter = nullptr;
}
#endif
#ifdef YUZU_CRASH_DUMPS
#include "yuzu/breakpad.h"
#endif
using namespace Common::Literals;
#ifdef USE_DISCORD_PRESENCE
#include "qt_common/discord/discord_impl.h"
#endif
#ifdef QT_STATICPLUGIN
Q_IMPORT_PLUGIN(QWindowsIntegrationPlugin);
#endif
#ifdef _WIN32
#include <windows.h>
extern "C" {
// tells Nvidia and AMD drivers to use the dedicated GPU by default on laptops with switchable
// graphics
__declspec(dllexport) unsigned long NvOptimusEnablement = 0x00000001;
__declspec(dllexport) int AmdPowerXpressRequestHighPerformance = 1;
}
#endif
constexpr int default_mouse_hide_timeout = 2500;
constexpr int default_input_update_timeout = 1;
constexpr size_t CopyBufferSize = 1_MiB;
/**
* "Callouts" are one-time instructional messages shown to the user. In the config settings, there
* is a bitfield "callout_flags" options, used to track if a message has already been shown to the
* user. This is 32-bits - if we have more than 32 callouts, we should retire and recycle old ones.
*/
enum class CalloutFlag : uint32_t {
DRDDeprecation = 0x2,
};
const int GMainWindow::max_recent_files_item;
static void RemoveCachedContents() {
const auto cache_dir = Common::FS::GetEdenPath(Common::FS::EdenPath::CacheDir);
const auto offline_fonts = cache_dir / "fonts";
const auto offline_manual = cache_dir / "offline_web_applet_manual";
const auto offline_legal_information = cache_dir / "offline_web_applet_legal_information";
const auto offline_system_data = cache_dir / "offline_web_applet_system_data";
Common::FS::RemoveDirRecursively(offline_fonts);
Common::FS::RemoveDirRecursively(offline_manual);
Common::FS::RemoveDirRecursively(offline_legal_information);
Common::FS::RemoveDirRecursively(offline_system_data);
}
static void LogRuntimes() {
#ifdef _MSC_VER
// It is possible that the name of the dll will change.
// vcruntime140.dll is for 2015 and onwards
static constexpr char runtime_dll_name[] = "vcruntime140.dll";
UINT sz = GetFileVersionInfoSizeA(runtime_dll_name, nullptr);
bool runtime_version_inspection_worked = false;
if (sz > 0) {
std::vector<u8> buf(sz);
if (GetFileVersionInfoA(runtime_dll_name, 0, sz, buf.data())) {
VS_FIXEDFILEINFO* pvi;
sz = sizeof(VS_FIXEDFILEINFO);
if (VerQueryValueA(buf.data(), "\\", reinterpret_cast<LPVOID*>(&pvi), &sz)) {
if (pvi->dwSignature == VS_FFI_SIGNATURE) {
runtime_version_inspection_worked = true;
LOG_INFO(Frontend, "MSVC Compiler: {} Runtime: {}.{}.{}.{}", _MSC_VER,
pvi->dwProductVersionMS >> 16, pvi->dwProductVersionMS & 0xFFFF,
pvi->dwProductVersionLS >> 16, pvi->dwProductVersionLS & 0xFFFF);
}
}
}
}
if (!runtime_version_inspection_worked) {
LOG_INFO(Frontend, "Unable to inspect {}", runtime_dll_name);
}
#endif
LOG_INFO(Frontend, "Qt Compile: {} Runtime: {}", QT_VERSION_STR, qVersion());
}
static QString PrettyProductName() {
#ifdef _WIN32
// After Windows 10 Version 2004, Microsoft decided to switch to a different notation: 20H2
// With that notation change they changed the registry key used to denote the current version
QSettings windows_registry(
QStringLiteral("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion"),
QSettings::NativeFormat);
const QString release_id = windows_registry.value(QStringLiteral("ReleaseId")).toString();
if (release_id == QStringLiteral("2009")) {
const u32 current_build = windows_registry.value(QStringLiteral("CurrentBuild")).toUInt();
const QString display_version =
windows_registry.value(QStringLiteral("DisplayVersion")).toString();
const u32 ubr = windows_registry.value(QStringLiteral("UBR")).toUInt();
u32 version = 10;
if (current_build >= 22000) {
version = 11;
}
return QStringLiteral("Windows %1 Version %2 (Build %3.%4)")
.arg(QString::number(version), display_version, QString::number(current_build),
QString::number(ubr));
}
#endif
return QSysInfo::prettyProductName();
}
#ifdef _WIN32
=======
#include <QCheckBox>
#include <QStringLiteral>
#ifdef HAVE_SDL2
#include <SDL.h> // For SDL ScreenSaver functions
#endif
#include <fmt/ranges.h>
#include "common/detached_tasks.h"
#include "common/fs/fs.h"
#include "common/fs/path_util.h"
#include "common/fs/ryujinx_compat.h"
#include "common/literals.h"
#include "common/logging/backend.h"
#include "common/logging/log.h"
#include "common/memory_detect.h"
#include "common/scm_rev.h"
#include "common/scope_exit.h"
#ifdef _WIN32
#include "core/core_timing.h"
#include "common/windows/timer_resolution.h"
#endif
#ifdef ARCHITECTURE_x86_64
#include "common/x64/cpu_detect.h"
#endif
#include "common/settings.h"
#include "core/core.h"
#include "core/crypto/key_manager.h"
#include "core/file_sys/card_image.h"
#include "core/file_sys/common_funcs.h"
#include "core/file_sys/content_archive.h"
#include "core/file_sys/control_metadata.h"
#include "core/file_sys/patch_manager.h"
#include "core/file_sys/registered_cache.h"
#include "core/file_sys/romfs.h"
#include "core/file_sys/savedata_factory.h"
#include "core/file_sys/submission_package.h"
#include "core/hle/kernel/k_process.h"
#include "core/hle/service/acc/profile_manager.h"
#include "core/hle/service/am/am.h"
#include "core/hle/service/filesystem/filesystem.h"
#include "core/hle/service/sm/sm.h"
#include "core/loader/loader.h"
#include "core/perf_stats.h"
#include "frontend_common/config.h"
#include "input_common/drivers/tas_input.h"
#include "input_common/drivers/virtual_amiibo.h"
#include "input_common/main.h"
#include "ui_main.h"
#include "yuzu/util/overlay_dialog.h"
#include "video_core/gpu.h"
#include "video_core/renderer_base.h"
#include "video_core/shader_notify.h"
#include "yuzu/about_dialog.h"
#include "yuzu/bootmanager.h"
#include "yuzu/compatibility_list.h"
#include "yuzu/configuration/configure_dialog.h"
#include "yuzu/configuration/configure_input_per_game.h"
#include "qt_common/config/qt_config.h"
#include "yuzu/debugger/console.h"
#include "yuzu/debugger/controller.h"
#include "yuzu/debugger/wait_tree.h"
#include "yuzu/data_dialog.h"
#include "yuzu/deps_dialog.h"
#include "yuzu/ryujinx_dialog.h"
#include "qt_common/discord/discord.h"
#include "yuzu/game_list.h"
#include "yuzu/game_list_p.h"
#include "yuzu/install_dialog.h"
#include "yuzu/loading_screen.h"
#include "yuzu/main.h"
#include "frontend_common/play_time_manager.h"
#include "yuzu/startup_checks.h"
#include "qt_common/config/uisettings.h"
#include "yuzu/util/clickable_label.h"
#include "qt_common/util/vk_device_info.h"
#ifdef _WIN32
#include <QPlatformSurfaceEvent>
#include <dwmapi.h>
#include <windows.h>
#ifdef _MSC_VER
#pragma comment(lib, "Dwmapi.lib")
#endif
static inline void ApplyWindowsTitleBarDarkMode(HWND hwnd, bool enabled) {
if (!hwnd)
return;
BOOL val = enabled ? TRUE : FALSE;
// 20 = Win11/21H2+
if (SUCCEEDED(DwmSetWindowAttribute(hwnd, 20, &val, sizeof(val))))
return;
// 19 = pre-21H2
DwmSetWindowAttribute(hwnd, 19, &val, sizeof(val));
}
static inline void ApplyDarkToTopLevel(QWidget* w, bool on) {
if (!w || !w->isWindow())
return;
ApplyWindowsTitleBarDarkMode(reinterpret_cast<HWND>(w->winId()), on);
}
namespace {
struct TitlebarFilter final : QObject {
bool dark;
explicit TitlebarFilter(bool is_dark) : QObject(qApp), dark(is_dark) {}
void setDark(bool is_dark) {
dark = is_dark;
}
void onFocusChanged(QWidget*, QWidget* now) {
if (now)
ApplyDarkToTopLevel(now->window(), dark);
}
bool eventFilter(QObject* obj, QEvent* ev) override {
if (auto* w = qobject_cast<QWidget*>(obj)) {
switch (ev->type()) {
case QEvent::WinIdChange:
case QEvent::Show:
case QEvent::ShowToParent:
case QEvent::Polish:
case QEvent::WindowStateChange:
case QEvent::ZOrderChange:
ApplyDarkToTopLevel(w, dark);
break;
default:
break;
}
}
return QObject::eventFilter(obj, ev);
}
};
static TitlebarFilter* g_filter = nullptr;
static QMetaObject::Connection g_focusConn;
} // namespace
static void ApplyGlobalDarkTitlebar(bool is_dark) {
if (!g_filter) {
g_filter = new TitlebarFilter(is_dark);
qApp->installEventFilter(g_filter);
g_focusConn = QObject::connect(qApp, &QApplication::focusChanged, g_filter,
&TitlebarFilter::onFocusChanged);
} else {
g_filter->setDark(is_dark);
}
for (QWidget* w : QApplication::topLevelWidgets())
ApplyDarkToTopLevel(w, is_dark);
}
static void RemoveTitlebarFilter() {
if (!g_filter)
return;
qApp->removeEventFilter(g_filter);
QObject::disconnect(g_focusConn);
g_filter->deleteLater();
g_filter = nullptr;
}
#endif
#ifdef YUZU_CRASH_DUMPS
#include "yuzu/breakpad.h"
#endif
using namespace Common::Literals;
#ifdef USE_DISCORD_PRESENCE
#include "qt_common/discord/discord_impl.h"
#endif
#ifdef QT_STATICPLUGIN
Q_IMPORT_PLUGIN(QWindowsIntegrationPlugin);
#endif
#ifdef _WIN32
#include <windows.h>
extern "C" {
// tells Nvidia and AMD drivers to use the dedicated GPU by default on laptops with switchable
// graphics
__declspec(dllexport) unsigned long NvOptimusEnablement = 0x00000001;
__declspec(dllexport) int AmdPowerXpressRequestHighPerformance = 1;
}
#endif
constexpr int default_mouse_hide_timeout = 2500;
constexpr int default_input_update_timeout = 1;
constexpr size_t CopyBufferSize = 1_MiB;
/**
* "Callouts" are one-time instructional messages shown to the user. In the config settings, there
* is a bitfield "callout_flags" options, used to track if a message has already been shown to the
* user. This is 32-bits - if we have more than 32 callouts, we should retire and recycle old ones.
*/
enum class CalloutFlag : uint32_t {
DRDDeprecation = 0x2,
};
const int GMainWindow::max_recent_files_item;
static void RemoveCachedContents() {
const auto cache_dir = Common::FS::GetEdenPath(Common::FS::EdenPath::CacheDir);
const auto offline_fonts = cache_dir / "fonts";
const auto offline_manual = cache_dir / "offline_web_applet_manual";
const auto offline_legal_information = cache_dir / "offline_web_applet_legal_information";
const auto offline_system_data = cache_dir / "offline_web_applet_system_data";
Common::FS::RemoveDirRecursively(offline_fonts);
Common::FS::RemoveDirRecursively(offline_manual);
Common::FS::RemoveDirRecursively(offline_legal_information);
Common::FS::RemoveDirRecursively(offline_system_data);
}
static void LogRuntimes() {
#ifdef _MSC_VER
// It is possible that the name of the dll will change.
// vcruntime140.dll is for 2015 and onwards
static constexpr char runtime_dll_name[] = "vcruntime140.dll";
UINT sz = GetFileVersionInfoSizeA(runtime_dll_name, nullptr);
bool runtime_version_inspection_worked = false;
if (sz > 0) {
std::vector<u8> buf(sz);
if (GetFileVersionInfoA(runtime_dll_name, 0, sz, buf.data())) {
VS_FIXEDFILEINFO* pvi;
sz = sizeof(VS_FIXEDFILEINFO);
if (VerQueryValueA(buf.data(), "\\", reinterpret_cast<LPVOID*>(&pvi), &sz)) {
if (pvi->dwSignature == VS_FFI_SIGNATURE) {
runtime_version_inspection_worked = true;
LOG_INFO(Frontend, "MSVC Compiler: {} Runtime: {}.{}.{}.{}", _MSC_VER,
pvi->dwProductVersionMS >> 16, pvi->dwProductVersionMS & 0xFFFF,
pvi->dwProductVersionLS >> 16, pvi->dwProductVersionLS & 0xFFFF);
}
}
}
}
if (!runtime_version_inspection_worked) {
LOG_INFO(Frontend, "Unable to inspect {}", runtime_dll_name);
}
#endif
LOG_INFO(Frontend, "Qt Compile: {} Runtime: {}", QT_VERSION_STR, qVersion());
}
static QString PrettyProductName() {
#ifdef _WIN32
// After Windows 10 Version 2004, Microsoft decided to switch to a different notation: 20H2
// With that notation change they changed the registry key used to denote the current version
QSettings windows_registry(
QStringLiteral("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion"),
QSettings::NativeFormat);
const QString release_id = windows_registry.value(QStringLiteral("ReleaseId")).toString();
if (release_id == QStringLiteral("2009")) {
const u32 current_build = windows_registry.value(QStringLiteral("CurrentBuild")).toUInt();
const QString display_version =
windows_registry.value(QStringLiteral("DisplayVersion")).toString();
const u32 ubr = windows_registry.value(QStringLiteral("UBR")).toUInt();
u32 version = 10;
if (current_build >= 22000) {
version = 11;
}
return QStringLiteral("Windows %1 Version %2 (Build %3.%4)")
.arg(QString::number(version), display_version, QString::number(current_build),
QString::number(ubr));
}
#endif
return QSysInfo::prettyProductName();
}
#ifdef _WIN32
>>>>>>> ee74fc3d5c (real vulkan device info (#1))
static void OverrideWindowsFont() {
// Qt5 chooses these fonts on Windows and they have fairly ugly alphanumeric/cyrillic characters
// Asking to use "MS Shell Dlg 2" gives better other chars while leaving the Chinese Characters.

4
src/yuzu/main_window.cpp

@ -28,7 +28,7 @@
#include "ryujinx_dialog.h"
#include "set_play_time_dialog.h"
#include "util/util.h"
#include "vk_device_info.h"
#include "qt_common/util/vk_device_info.h"
#include "applets/qt_amiibo_settings.h"
#include "applets/qt_controller.h"
@ -2820,7 +2820,7 @@ void MainWindow::OnMenuLoadFile() {
is_load_file_select_active = true;
const QString extensions =
QStringLiteral("*.")
.append(GameList::supported_file_extensions.join(QStringLiteral(" *.")))
.append(QtCommon::supported_file_extensions.join(QStringLiteral(" *.")))
.append(QStringLiteral(" main"));
const QString file_filter = tr("Switch Executable (%1);;All Files (*.*)",
"%1 is an identifier for the Switch executable file extensions.")

36
src/yuzu/vk_device_info.h

@ -1,36 +0,0 @@
// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <algorithm>
#include <iterator>
#include <memory>
#include <string>
#include <string_view>
#include <vector>
#include "common/common_types.h"
#include "vulkan/vulkan_core.h"
class QWindow;
namespace Settings {
enum class VSyncMode : u32;
}
// #include "common/settings.h"
namespace VkDeviceInfo {
// Short class to record Vulkan driver information for configuration purposes
class Record {
public:
explicit Record(std::string_view name, const std::vector<VkPresentModeKHR>& vsync_modes,
bool has_broken_compute);
~Record();
const std::string name;
const std::vector<VkPresentModeKHR> vsync_support;
const bool has_broken_compute;
};
void PopulateRecords(std::vector<Record>& records, QWindow* window);
} // namespace VkDeviceInfo
Loading…
Cancel
Save