Prepare for Vulkan backend (#6595)
* externals: Add libraries required for vulkan * build: Add support for downloading bundled MoltenVK. * ci: Install tools needed for Vulkan. * citra_qt: Add API status indicator --------- Co-authored-by: GPUCode <geoster3d@gmail.com>
This commit is contained in:
parent
5b7cc76ba3
commit
54c499ed5b
15 changed files with 166 additions and 11 deletions
|
@ -1,3 +1,3 @@
|
||||||
#!/bin/sh -ex
|
#!/bin/sh -ex
|
||||||
|
|
||||||
brew install ccache ninja || true
|
brew install ccache glslang ninja || true
|
||||||
|
|
13
.github/workflows/ci.yml
vendored
13
.github/workflows/ci.yml
vendored
|
@ -150,6 +150,14 @@ jobs:
|
||||||
shell: bash
|
shell: bash
|
||||||
- name: Set up MSVC
|
- name: Set up MSVC
|
||||||
uses: ilammy/msvc-dev-cmd@v1
|
uses: ilammy/msvc-dev-cmd@v1
|
||||||
|
- name: Setup Vulkan SDK
|
||||||
|
uses: humbletim/setup-vulkan-sdk@v1.2.0
|
||||||
|
with:
|
||||||
|
vulkan-query-version: latest
|
||||||
|
vulkan-components: Glslang
|
||||||
|
vulkan-use-cache: true
|
||||||
|
- name: Test glslangValidator
|
||||||
|
run: glslangValidator --version
|
||||||
- name: Build
|
- name: Build
|
||||||
run: ./.ci/windows-msvc/build.sh
|
run: ./.ci/windows-msvc/build.sh
|
||||||
shell: bash
|
shell: bash
|
||||||
|
@ -186,8 +194,9 @@ jobs:
|
||||||
echo $GIT_TAG_NAME
|
echo $GIT_TAG_NAME
|
||||||
- name: Deps
|
- name: Deps
|
||||||
run: |
|
run: |
|
||||||
sudo apt-get update
|
sudo add-apt-repository -y ppa:theofficialgman/gpu-tools
|
||||||
sudo apt-get install ccache apksigner -y
|
sudo apt-get update -y
|
||||||
|
sudo apt-get install ccache glslang-dev glslang-tools apksigner -y
|
||||||
- name: Build
|
- name: Build
|
||||||
run: ./.ci/android/build.sh
|
run: ./.ci/android/build.sh
|
||||||
- name: Copy and sign artifacts
|
- name: Copy and sign artifacts
|
||||||
|
|
18
.gitmodules
vendored
18
.gitmodules
vendored
|
@ -64,6 +64,18 @@
|
||||||
[submodule "dds-ktx"]
|
[submodule "dds-ktx"]
|
||||||
path = externals/dds-ktx
|
path = externals/dds-ktx
|
||||||
url = https://github.com/septag/dds-ktx
|
url = https://github.com/septag/dds-ktx
|
||||||
[submodule "externals/openal-soft"]
|
[submodule "openal-soft"]
|
||||||
path = externals/openal-soft
|
path = externals/openal-soft
|
||||||
url = https://github.com/kcat/openal-soft
|
url = https://github.com/kcat/openal-soft
|
||||||
|
[submodule "glslang"]
|
||||||
|
path = externals/glslang
|
||||||
|
url = https://github.com/KhronosGroup/glslang
|
||||||
|
[submodule "vma"]
|
||||||
|
path = externals/vma
|
||||||
|
url = https://github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator
|
||||||
|
[submodule "vulkan-headers"]
|
||||||
|
path = externals/vulkan-headers
|
||||||
|
url = https://github.com/KhronosGroup/Vulkan-Headers
|
||||||
|
[submodule "sirit"]
|
||||||
|
path = externals/sirit
|
||||||
|
url = https://github.com/yuzu-emu/sirit
|
||||||
|
|
|
@ -59,6 +59,8 @@ option(USE_SYSTEM_BOOST "Use the system Boost libs (instead of the bundled ones)
|
||||||
|
|
||||||
CMAKE_DEPENDENT_OPTION(ENABLE_FDK "Use FDK AAC decoder" OFF "NOT ENABLE_FFMPEG_AUDIO_DECODER;NOT ENABLE_MF" OFF)
|
CMAKE_DEPENDENT_OPTION(ENABLE_FDK "Use FDK AAC decoder" OFF "NOT ENABLE_FFMPEG_AUDIO_DECODER;NOT ENABLE_MF" OFF)
|
||||||
|
|
||||||
|
CMAKE_DEPENDENT_OPTION(CITRA_USE_BUNDLED_MOLTENVK "Download the bundled MoltenVK" ON "APPLE" OFF)
|
||||||
|
|
||||||
CMAKE_DEPENDENT_OPTION(CITRA_BUNDLE_LIBRARIES "Bundle dependent libraries with the output executables" ON "APPLE" OFF)
|
CMAKE_DEPENDENT_OPTION(CITRA_BUNDLE_LIBRARIES "Bundle dependent libraries with the output executables" ON "APPLE" OFF)
|
||||||
|
|
||||||
option(CITRA_WARNINGS_AS_ERRORS "Enable warnings as errors" ON)
|
option(CITRA_WARNINGS_AS_ERRORS "Enable warnings as errors" ON)
|
||||||
|
@ -282,10 +284,16 @@ find_package(tsl-robin-map QUIET)
|
||||||
# ======================================
|
# ======================================
|
||||||
|
|
||||||
if (APPLE)
|
if (APPLE)
|
||||||
|
if (CITRA_USE_BUNDLED_MOLTENVK)
|
||||||
|
download_moltenvk()
|
||||||
|
endif()
|
||||||
|
find_library(MOLTENVK_LIBRARY MoltenVK REQUIRED)
|
||||||
|
message(STATUS "Using MoltenVK at ${MOLTENVK_LIBRARY}.")
|
||||||
|
|
||||||
# Umbrella framework for everything GUI-related
|
# Umbrella framework for everything GUI-related
|
||||||
find_library(COCOA_LIBRARY Cocoa)
|
find_library(COCOA_LIBRARY Cocoa REQUIRED)
|
||||||
find_library(AVFOUNDATION_LIBRARY AVFoundation)
|
find_library(AVFOUNDATION_LIBRARY AVFoundation REQUIRED)
|
||||||
set(PLATFORM_LIBRARIES ${COCOA_LIBRARY} ${AVFOUNDATION_LIBRARY} ${IOKIT_LIBRARY} ${COREVIDEO_LIBRARY})
|
set(PLATFORM_LIBRARIES ${COCOA_LIBRARY} ${AVFOUNDATION_LIBRARY} ${MOLTENVK_LIBRARY})
|
||||||
elseif (WIN32)
|
elseif (WIN32)
|
||||||
set(PLATFORM_LIBRARIES winmm ws2_32)
|
set(PLATFORM_LIBRARIES winmm ws2_32)
|
||||||
if (MINGW)
|
if (MINGW)
|
||||||
|
|
|
@ -100,6 +100,30 @@ function(download_qt_external target prefix_var)
|
||||||
set(${prefix_var} "${prefix}" PARENT_SCOPE)
|
set(${prefix_var} "${prefix}" PARENT_SCOPE)
|
||||||
endfunction()
|
endfunction()
|
||||||
|
|
||||||
|
function(download_moltenvk)
|
||||||
|
if (IOS)
|
||||||
|
set(MOLTENVK_PLATFORM "iOS")
|
||||||
|
else()
|
||||||
|
set(MOLTENVK_PLATFORM "macOS")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(MOLTENVK_DIR "${CMAKE_BINARY_DIR}/externals/MoltenVK")
|
||||||
|
set(MOLTENVK_TAR "${CMAKE_BINARY_DIR}/externals/MoltenVK.tar")
|
||||||
|
if (NOT EXISTS ${MOLTENVK_DIR})
|
||||||
|
if (NOT EXISTS ${MOLTENVK_TAR})
|
||||||
|
file(DOWNLOAD https://github.com/KhronosGroup/MoltenVK/releases/latest/download/MoltenVK-all.tar
|
||||||
|
${MOLTENVK_TAR} SHOW_PROGRESS)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
execute_process(COMMAND ${CMAKE_COMMAND} -E tar xf "${MOLTENVK_TAR}"
|
||||||
|
WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/externals")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Add the MoltenVK library path to the prefix so find_library can locate it.
|
||||||
|
list(APPEND CMAKE_PREFIX_PATH "${MOLTENVK_DIR}/MoltenVK/dylib/${MOLTENVK_PLATFORM}")
|
||||||
|
set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} PARENT_SCOPE)
|
||||||
|
endfunction()
|
||||||
|
|
||||||
function(get_external_prefix lib_name prefix_var)
|
function(get_external_prefix lib_name prefix_var)
|
||||||
set(${prefix_var} "${CMAKE_BINARY_DIR}/externals/${lib_name}" PARENT_SCOPE)
|
set(${prefix_var} "${CMAKE_BINARY_DIR}/externals/${lib_name}" PARENT_SCOPE)
|
||||||
endfunction()
|
endfunction()
|
||||||
|
|
14
dist/qt_themes/default/style.qss
vendored
14
dist/qt_themes/default/style.qss
vendored
|
@ -1,3 +1,17 @@
|
||||||
|
QPushButton#GraphicsAPIStatusBarButton {
|
||||||
|
color: #656565;
|
||||||
|
border: 1px solid transparent;
|
||||||
|
background-color: transparent;
|
||||||
|
padding: 0px 3px 0px 3px;
|
||||||
|
text-align: center;
|
||||||
|
min-width: 60px;
|
||||||
|
min-height: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QPushButton#GraphicsAPIStatusBarButton:hover {
|
||||||
|
border: 1px solid #76797C;
|
||||||
|
}
|
||||||
|
|
||||||
QPushButton#3DOptionStatusBarButton {
|
QPushButton#3DOptionStatusBarButton {
|
||||||
color: #A5A5A5;
|
color: #A5A5A5;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
|
|
28
dist/qt_themes/qdarkstyle/style.qss
vendored
28
dist/qt_themes/qdarkstyle/style.qss
vendored
|
@ -1,3 +1,31 @@
|
||||||
|
QPushButton#TogglableStatusBarButton {
|
||||||
|
color: #959595;
|
||||||
|
border: 1px solid transparent;
|
||||||
|
background-color: transparent;
|
||||||
|
padding: 0px 3px 0px 3px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
QPushButton#TogglableStatusBarButton:checked {
|
||||||
|
color: palette(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
QPushButton#TogglableStatusBarButton:hover {
|
||||||
|
border: 1px solid #76797C;
|
||||||
|
}
|
||||||
|
|
||||||
|
QPushButton#GraphicsAPIStatusBarButton {
|
||||||
|
color: #656565;
|
||||||
|
border: 1px solid transparent;
|
||||||
|
background-color: transparent;
|
||||||
|
padding: 0px 3px 0px 3px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
QPushButton#GraphicsAPIStatusBarButton:hover {
|
||||||
|
border: 1px solid #76797C;
|
||||||
|
}
|
||||||
|
|
||||||
QToolTip {
|
QToolTip {
|
||||||
border: 1px solid #76797C;
|
border: 1px solid #76797C;
|
||||||
background-color: #5A7566;
|
background-color: #5A7566;
|
||||||
|
|
20
externals/CMakeLists.txt
vendored
20
externals/CMakeLists.txt
vendored
|
@ -93,6 +93,13 @@ endif()
|
||||||
# Glad
|
# Glad
|
||||||
add_subdirectory(glad)
|
add_subdirectory(glad)
|
||||||
|
|
||||||
|
# glslang
|
||||||
|
set(SKIP_GLSLANG_INSTALL ON)
|
||||||
|
set(ENABLE_GLSLANG_BINARIES OFF)
|
||||||
|
set(ENABLE_SPVREMAPPER OFF)
|
||||||
|
set(ENABLE_CTEST OFF)
|
||||||
|
add_subdirectory(glslang)
|
||||||
|
|
||||||
# inih
|
# inih
|
||||||
add_subdirectory(inih)
|
add_subdirectory(inih)
|
||||||
|
|
||||||
|
@ -106,16 +113,19 @@ target_include_directories(nihstro-headers INTERFACE ./nihstro/include)
|
||||||
if (MSVC)
|
if (MSVC)
|
||||||
target_compile_options(nihstro-headers INTERFACE /W0)
|
target_compile_options(nihstro-headers INTERFACE /W0)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Open Source Archives
|
# Open Source Archives
|
||||||
add_subdirectory(open_source_archives)
|
add_subdirectory(open_source_archives)
|
||||||
|
|
||||||
# SoundTouch
|
# SoundTouch
|
||||||
|
|
||||||
set(INTEGER_SAMPLES ON CACHE BOOL "")
|
set(INTEGER_SAMPLES ON CACHE BOOL "")
|
||||||
set(SOUNDSTRETCH OFF CACHE BOOL "")
|
set(SOUNDSTRETCH OFF CACHE BOOL "")
|
||||||
set(SOUNDTOUCH_DLL OFF CACHE BOOL "")
|
set(SOUNDTOUCH_DLL OFF CACHE BOOL "")
|
||||||
add_subdirectory(soundtouch EXCLUDE_FROM_ALL)
|
add_subdirectory(soundtouch EXCLUDE_FROM_ALL)
|
||||||
|
|
||||||
|
# sirit
|
||||||
|
add_subdirectory(sirit EXCLUDE_FROM_ALL)
|
||||||
|
|
||||||
# Teakra
|
# Teakra
|
||||||
add_subdirectory(teakra EXCLUDE_FROM_ALL)
|
add_subdirectory(teakra EXCLUDE_FROM_ALL)
|
||||||
|
|
||||||
|
@ -205,3 +215,11 @@ if (ENABLE_OPENAL)
|
||||||
set(LIBTYPE "STATIC" CACHE STRING "")
|
set(LIBTYPE "STATIC" CACHE STRING "")
|
||||||
add_subdirectory(openal-soft EXCLUDE_FROM_ALL)
|
add_subdirectory(openal-soft EXCLUDE_FROM_ALL)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
# VMA
|
||||||
|
add_library(vma INTERFACE)
|
||||||
|
target_include_directories(vma INTERFACE ./vma/include)
|
||||||
|
|
||||||
|
# vulkan-headers
|
||||||
|
add_library(vulkan-headers INTERFACE)
|
||||||
|
target_include_directories(vulkan-headers INTERFACE ./vulkan-headers/include)
|
||||||
|
|
1
externals/glslang
vendored
Submodule
1
externals/glslang
vendored
Submodule
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit 1e4955adbcd9b3f5eaf2129e918ca057baed6520
|
1
externals/sirit
vendored
Submodule
1
externals/sirit
vendored
Submodule
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit 4ab79a8c023aa63caaa93848b09b9fe8b183b1a9
|
1
externals/vma
vendored
Submodule
1
externals/vma
vendored
Submodule
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit 0e89587db3ebee4d463f191bd296374c5fafc8ea
|
1
externals/vulkan-headers
vendored
Submodule
1
externals/vulkan-headers
vendored
Submodule
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit bae9700cd9425541a0f6029957f005e5ad3ef660
|
|
@ -289,7 +289,7 @@ create_target_directory_groups(citra-qt)
|
||||||
|
|
||||||
target_link_libraries(citra-qt PRIVATE audio_core citra_common citra_core input_common network video_core)
|
target_link_libraries(citra-qt PRIVATE audio_core citra_common citra_core input_common network video_core)
|
||||||
target_link_libraries(citra-qt PRIVATE Boost::boost glad nihstro-headers Qt6::Widgets Qt6::Multimedia Qt6::Concurrent)
|
target_link_libraries(citra-qt PRIVATE Boost::boost glad nihstro-headers Qt6::Widgets Qt6::Multimedia Qt6::Concurrent)
|
||||||
target_link_libraries(citra-qt PRIVATE ${PLATFORM_LIBRARIES} Threads::Threads)
|
target_link_libraries(citra-qt PRIVATE ${PLATFORM_LIBRARIES} Threads::Threads vulkan-headers)
|
||||||
|
|
||||||
if (NOT WIN32)
|
if (NOT WIN32)
|
||||||
target_include_directories(citra-qt PRIVATE ${Qt6Gui_PRIVATE_INCLUDE_DIRS})
|
target_include_directories(citra-qt PRIVATE ${Qt6Gui_PRIVATE_INCLUDE_DIRS})
|
||||||
|
|
|
@ -358,6 +358,22 @@ void GMainWindow::InitializeWidgets() {
|
||||||
statusBar()->addPermanentWidget(label);
|
statusBar()->addPermanentWidget(label);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Setup Graphics API button
|
||||||
|
graphics_api_button = new QPushButton();
|
||||||
|
graphics_api_button->setObjectName(QStringLiteral("GraphicsAPIStatusBarButton"));
|
||||||
|
graphics_api_button->setFocusPolicy(Qt::NoFocus);
|
||||||
|
UpdateAPIIndicator();
|
||||||
|
|
||||||
|
connect(graphics_api_button, &QPushButton::clicked, this, [this] {
|
||||||
|
if (emulation_running) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
UpdateAPIIndicator(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
statusBar()->insertPermanentWidget(0, graphics_api_button);
|
||||||
|
|
||||||
statusBar()->addPermanentWidget(multiplayer_state->GetStatusText());
|
statusBar()->addPermanentWidget(multiplayer_state->GetStatusText());
|
||||||
statusBar()->addPermanentWidget(multiplayer_state->GetStatusIcon());
|
statusBar()->addPermanentWidget(multiplayer_state->GetStatusIcon());
|
||||||
|
|
||||||
|
@ -1990,6 +2006,7 @@ void GMainWindow::OnConfigure() {
|
||||||
}
|
}
|
||||||
UpdateSecondaryWindowVisibility();
|
UpdateSecondaryWindowVisibility();
|
||||||
UpdateBootHomeMenuState();
|
UpdateBootHomeMenuState();
|
||||||
|
UpdateAPIIndicator();
|
||||||
} else {
|
} else {
|
||||||
Settings::values.input_profiles = old_input_profiles;
|
Settings::values.input_profiles = old_input_profiles;
|
||||||
Settings::values.touch_from_button_maps = old_touch_from_button_maps;
|
Settings::values.touch_from_button_maps = old_touch_from_button_maps;
|
||||||
|
@ -2313,6 +2330,24 @@ void GMainWindow::ShowMouseCursor() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GMainWindow::UpdateAPIIndicator(bool update) {
|
||||||
|
static std::array graphics_apis = {QStringLiteral("SOFTWARE"), QStringLiteral("OPENGL")};
|
||||||
|
|
||||||
|
static std::array graphics_api_colors = {QStringLiteral("#3ae400"), QStringLiteral("#00ccdd")};
|
||||||
|
|
||||||
|
u32 api_index = static_cast<u32>(Settings::values.graphics_api.GetValue());
|
||||||
|
if (update) {
|
||||||
|
api_index = (api_index + 1) % graphics_apis.size();
|
||||||
|
Settings::values.graphics_api = static_cast<Settings::GraphicsAPI>(api_index);
|
||||||
|
}
|
||||||
|
|
||||||
|
const QString style_sheet = QStringLiteral("QPushButton { font-weight: bold; color: %0; }")
|
||||||
|
.arg(graphics_api_colors[api_index]);
|
||||||
|
|
||||||
|
graphics_api_button->setText(graphics_apis[api_index]);
|
||||||
|
graphics_api_button->setStyleSheet(style_sheet);
|
||||||
|
}
|
||||||
|
|
||||||
void GMainWindow::OnMouseActivity() {
|
void GMainWindow::OnMouseActivity() {
|
||||||
ShowMouseCursor();
|
ShowMouseCursor();
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <QMainWindow>
|
#include <QMainWindow>
|
||||||
|
#include <QPushButton>
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
#include <QTranslator>
|
#include <QTranslator>
|
||||||
#include "citra_qt/compatibility_list.h"
|
#include "citra_qt/compatibility_list.h"
|
||||||
|
@ -261,6 +262,7 @@ private:
|
||||||
void HideMouseCursor();
|
void HideMouseCursor();
|
||||||
void ShowMouseCursor();
|
void ShowMouseCursor();
|
||||||
void OpenPerGameConfiguration(u64 title_id, const QString& file_name);
|
void OpenPerGameConfiguration(u64 title_id, const QString& file_name);
|
||||||
|
void UpdateAPIIndicator(bool update = false);
|
||||||
|
|
||||||
std::unique_ptr<Ui::MainWindow> ui;
|
std::unique_ptr<Ui::MainWindow> ui;
|
||||||
Core::System& system;
|
Core::System& system;
|
||||||
|
@ -278,6 +280,7 @@ private:
|
||||||
QLabel* emu_speed_label = nullptr;
|
QLabel* emu_speed_label = nullptr;
|
||||||
QLabel* game_fps_label = nullptr;
|
QLabel* game_fps_label = nullptr;
|
||||||
QLabel* emu_frametime_label = nullptr;
|
QLabel* emu_frametime_label = nullptr;
|
||||||
|
QPushButton* graphics_api_button = nullptr;
|
||||||
QTimer status_bar_update_timer;
|
QTimer status_bar_update_timer;
|
||||||
bool message_label_used_for_movie = false;
|
bool message_label_used_for_movie = false;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue