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:
Steveice10 2023-06-05 07:29:05 -07:00 committed by GitHub
parent 5b7cc76ba3
commit 54c499ed5b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 166 additions and 11 deletions

View file

@ -1,3 +1,3 @@
#!/bin/sh -ex #!/bin/sh -ex
brew install ccache ninja || true brew install ccache glslang ninja || true

View file

@ -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

14
.gitmodules vendored
View file

@ -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

View file

@ -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)

View file

@ -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()

View file

@ -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;

View file

@ -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;

View file

@ -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

@ -0,0 +1 @@
Subproject commit 1e4955adbcd9b3f5eaf2129e918ca057baed6520

1
externals/sirit vendored Submodule

@ -0,0 +1 @@
Subproject commit 4ab79a8c023aa63caaa93848b09b9fe8b183b1a9

1
externals/vma vendored Submodule

@ -0,0 +1 @@
Subproject commit 0e89587db3ebee4d463f191bd296374c5fafc8ea

1
externals/vulkan-headers vendored Submodule

@ -0,0 +1 @@
Subproject commit bae9700cd9425541a0f6029957f005e5ad3ef660

View file

@ -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})

View file

@ -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();
} }

View file

@ -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;