From 54c499ed5b840102f5d25321d7015d25e6bf0ba2 Mon Sep 17 00:00:00 2001 From: Steveice10 <1269164+Steveice10@users.noreply.github.com> Date: Mon, 5 Jun 2023 07:29:05 -0700 Subject: [PATCH] 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 --- .ci/macos/deps.sh | 2 +- .github/workflows/ci.yml | 13 +++++++++-- .gitmodules | 18 +++++++++++--- CMakeLists.txt | 14 ++++++++--- CMakeModules/DownloadExternals.cmake | 24 +++++++++++++++++++ dist/qt_themes/default/style.qss | 14 +++++++++++ dist/qt_themes/qdarkstyle/style.qss | 28 ++++++++++++++++++++++ externals/CMakeLists.txt | 20 +++++++++++++++- externals/glslang | 1 + externals/sirit | 1 + externals/vma | 1 + externals/vulkan-headers | 1 + src/citra_qt/CMakeLists.txt | 2 +- src/citra_qt/main.cpp | 35 ++++++++++++++++++++++++++++ src/citra_qt/main.h | 3 +++ 15 files changed, 166 insertions(+), 11 deletions(-) create mode 160000 externals/glslang create mode 160000 externals/sirit create mode 160000 externals/vma create mode 160000 externals/vulkan-headers diff --git a/.ci/macos/deps.sh b/.ci/macos/deps.sh index ec9bb4311f..ac2775b599 100755 --- a/.ci/macos/deps.sh +++ b/.ci/macos/deps.sh @@ -1,3 +1,3 @@ #!/bin/sh -ex -brew install ccache ninja || true +brew install ccache glslang ninja || true diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f2f4a9880f..b5e3d7c894 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -150,6 +150,14 @@ jobs: shell: bash - name: Set up MSVC 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 run: ./.ci/windows-msvc/build.sh shell: bash @@ -186,8 +194,9 @@ jobs: echo $GIT_TAG_NAME - name: Deps run: | - sudo apt-get update - sudo apt-get install ccache apksigner -y + sudo add-apt-repository -y ppa:theofficialgman/gpu-tools + sudo apt-get update -y + sudo apt-get install ccache glslang-dev glslang-tools apksigner -y - name: Build run: ./.ci/android/build.sh - name: Copy and sign artifacts diff --git a/.gitmodules b/.gitmodules index c3944b1f8f..6d0b09029e 100644 --- a/.gitmodules +++ b/.gitmodules @@ -64,6 +64,18 @@ [submodule "dds-ktx"] path = externals/dds-ktx url = https://github.com/septag/dds-ktx -[submodule "externals/openal-soft"] - path = externals/openal-soft - url = https://github.com/kcat/openal-soft +[submodule "openal-soft"] + path = externals/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 diff --git a/CMakeLists.txt b/CMakeLists.txt index 5353e3b729..82d99ca7bd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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(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) option(CITRA_WARNINGS_AS_ERRORS "Enable warnings as errors" ON) @@ -282,10 +284,16 @@ find_package(tsl-robin-map QUIET) # ====================================== 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 - find_library(COCOA_LIBRARY Cocoa) - find_library(AVFOUNDATION_LIBRARY AVFoundation) - set(PLATFORM_LIBRARIES ${COCOA_LIBRARY} ${AVFOUNDATION_LIBRARY} ${IOKIT_LIBRARY} ${COREVIDEO_LIBRARY}) + find_library(COCOA_LIBRARY Cocoa REQUIRED) + find_library(AVFOUNDATION_LIBRARY AVFoundation REQUIRED) + set(PLATFORM_LIBRARIES ${COCOA_LIBRARY} ${AVFOUNDATION_LIBRARY} ${MOLTENVK_LIBRARY}) elseif (WIN32) set(PLATFORM_LIBRARIES winmm ws2_32) if (MINGW) diff --git a/CMakeModules/DownloadExternals.cmake b/CMakeModules/DownloadExternals.cmake index 38a8151ca3..99bce5aeb9 100644 --- a/CMakeModules/DownloadExternals.cmake +++ b/CMakeModules/DownloadExternals.cmake @@ -100,6 +100,30 @@ function(download_qt_external target prefix_var) set(${prefix_var} "${prefix}" PARENT_SCOPE) 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) set(${prefix_var} "${CMAKE_BINARY_DIR}/externals/${lib_name}" PARENT_SCOPE) endfunction() diff --git a/dist/qt_themes/default/style.qss b/dist/qt_themes/default/style.qss index e467504b6b..8e7a56f97e 100644 --- a/dist/qt_themes/default/style.qss +++ b/dist/qt_themes/default/style.qss @@ -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 { color: #A5A5A5; font-weight: bold; diff --git a/dist/qt_themes/qdarkstyle/style.qss b/dist/qt_themes/qdarkstyle/style.qss index 318f78b7a0..7d6df72b68 100644 --- a/dist/qt_themes/qdarkstyle/style.qss +++ b/dist/qt_themes/qdarkstyle/style.qss @@ -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 { border: 1px solid #76797C; background-color: #5A7566; diff --git a/externals/CMakeLists.txt b/externals/CMakeLists.txt index 13f8fd99b9..90ba2f5685 100644 --- a/externals/CMakeLists.txt +++ b/externals/CMakeLists.txt @@ -93,6 +93,13 @@ endif() # 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 add_subdirectory(inih) @@ -106,16 +113,19 @@ target_include_directories(nihstro-headers INTERFACE ./nihstro/include) if (MSVC) target_compile_options(nihstro-headers INTERFACE /W0) endif() + # Open Source Archives add_subdirectory(open_source_archives) # SoundTouch - set(INTEGER_SAMPLES ON CACHE BOOL "") set(SOUNDSTRETCH OFF CACHE BOOL "") set(SOUNDTOUCH_DLL OFF CACHE BOOL "") add_subdirectory(soundtouch EXCLUDE_FROM_ALL) +# sirit +add_subdirectory(sirit EXCLUDE_FROM_ALL) + # Teakra add_subdirectory(teakra EXCLUDE_FROM_ALL) @@ -205,3 +215,11 @@ if (ENABLE_OPENAL) set(LIBTYPE "STATIC" CACHE STRING "") add_subdirectory(openal-soft EXCLUDE_FROM_ALL) 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) diff --git a/externals/glslang b/externals/glslang new file mode 160000 index 0000000000..1e4955adbc --- /dev/null +++ b/externals/glslang @@ -0,0 +1 @@ +Subproject commit 1e4955adbcd9b3f5eaf2129e918ca057baed6520 diff --git a/externals/sirit b/externals/sirit new file mode 160000 index 0000000000..4ab79a8c02 --- /dev/null +++ b/externals/sirit @@ -0,0 +1 @@ +Subproject commit 4ab79a8c023aa63caaa93848b09b9fe8b183b1a9 diff --git a/externals/vma b/externals/vma new file mode 160000 index 0000000000..0e89587db3 --- /dev/null +++ b/externals/vma @@ -0,0 +1 @@ +Subproject commit 0e89587db3ebee4d463f191bd296374c5fafc8ea diff --git a/externals/vulkan-headers b/externals/vulkan-headers new file mode 160000 index 0000000000..bae9700cd9 --- /dev/null +++ b/externals/vulkan-headers @@ -0,0 +1 @@ +Subproject commit bae9700cd9425541a0f6029957f005e5ad3ef660 diff --git a/src/citra_qt/CMakeLists.txt b/src/citra_qt/CMakeLists.txt index 1ef141b701..eebcca567e 100644 --- a/src/citra_qt/CMakeLists.txt +++ b/src/citra_qt/CMakeLists.txt @@ -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 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) target_include_directories(citra-qt PRIVATE ${Qt6Gui_PRIVATE_INCLUDE_DIRS}) diff --git a/src/citra_qt/main.cpp b/src/citra_qt/main.cpp index 7327307ede..c9d26ebc3f 100644 --- a/src/citra_qt/main.cpp +++ b/src/citra_qt/main.cpp @@ -358,6 +358,22 @@ void GMainWindow::InitializeWidgets() { 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->GetStatusIcon()); @@ -1990,6 +2006,7 @@ void GMainWindow::OnConfigure() { } UpdateSecondaryWindowVisibility(); UpdateBootHomeMenuState(); + UpdateAPIIndicator(); } else { Settings::values.input_profiles = old_input_profiles; 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(Settings::values.graphics_api.GetValue()); + if (update) { + api_index = (api_index + 1) % graphics_apis.size(); + Settings::values.graphics_api = static_cast(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() { ShowMouseCursor(); } diff --git a/src/citra_qt/main.h b/src/citra_qt/main.h index 9fa06ee794..ddc242543f 100644 --- a/src/citra_qt/main.h +++ b/src/citra_qt/main.h @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include "citra_qt/compatibility_list.h" @@ -261,6 +262,7 @@ private: void HideMouseCursor(); void ShowMouseCursor(); void OpenPerGameConfiguration(u64 title_id, const QString& file_name); + void UpdateAPIIndicator(bool update = false); std::unique_ptr ui; Core::System& system; @@ -278,6 +280,7 @@ private: QLabel* emu_speed_label = nullptr; QLabel* game_fps_label = nullptr; QLabel* emu_frametime_label = nullptr; + QPushButton* graphics_api_button = nullptr; QTimer status_bar_update_timer; bool message_label_used_for_movie = false;