citra-emu
/
citra
Archived
1
0
Fork 0

Compare commits

..

10 Commits

Author SHA1 Message Date
Tobias 0ff3440232
tools: Add reset submodules script (#7465)
Co-authored-by: merry <8682882+merryhime@users.noreply.github.com>
2024-03-03 13:39:55 +02:00
liushuyu 69e758d738
dedicated_room: properly initialize logging (#7468) 2024-02-27 20:36:28 +05:30
Steveice10 f4768cd26c
video_core: Remove pre-compilation of Vulkan host-shaders. (#7461) 2024-02-26 10:26:44 -08:00
Théo B e0d2c1308e
log: fix SOC_U::Accept LOG_DEBUG call, and ensure such mistakes get picked up at compile time (#7463)
* fix SOC_U::Accept invalid log function

* make logging get checked at compile time
- ensures log strings match the amount and type (if the format specifies an integer, for example) of the arguments
- if at any later point a runtime-generated string is used as the log format, FmtLogMessage might require an overload taking a fmt::runtime_format_string<> as the format argument type, everything else being equal. wrap the generated string with fmt::runtime() before passing to the LOG_X function

* formatting fix: aligning the arguments
2024-02-25 21:43:29 -08:00
Steveice10 4f9fc88bb3
apt: Improve accuracy of applet slot states on system applet launch. (#7456) 2024-02-23 16:18:16 -08:00
GPUCode d857743075
Downgrade blend factor crash to warning (#7459)
* pica_to_vk: Downgrade assert to warning

* pica_to_gl: Downgrade unreachable to warning
2024-02-22 15:43:44 -08:00
kylon b5042a5257
Core: update kernel config memory to latest 11.17 (#7460) 2024-02-22 15:43:33 -08:00
Wunk e524542a40
vk_texture_runtime: Use boost-`static_vector` (#7455)
* vk_texture_runtime: Use boost-`static_vector` for image init-barriers

Uses `static_vector` rather than `std::array`+`u32` when passing input
parameters into the initialization barriers.

* vk_texture_runtime: Use boost-`static_vector` for framebuffer attachments

* vk_texture_runtime: Use boost-`static_vector` for surface uploads
2024-02-22 02:35:57 +02:00
Steveice10 3a4ebb1413
file_util: Make sure portable user path is absolute. (#7448) 2024-02-18 15:21:53 -08:00
Steveice10 cbe8987036
ci: Update action versions. (#7449) 2024-02-18 08:23:15 -08:00
26 changed files with 200 additions and 213 deletions

View File

@ -12,13 +12,13 @@ jobs:
if: ${{ !github.head_ref }} if: ${{ !github.head_ref }}
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
with: with:
submodules: recursive submodules: recursive
- name: Pack - name: Pack
run: ./.ci/source.sh run: ./.ci/source.sh
- name: Upload - name: Upload
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v4
with: with:
name: source name: source
path: artifacts/ path: artifacts/
@ -37,11 +37,11 @@ jobs:
OS: linux OS: linux
TARGET: ${{ matrix.target }} TARGET: ${{ matrix.target }}
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
with: with:
submodules: recursive submodules: recursive
- name: Set up cache - name: Set up cache
uses: actions/cache@v3 uses: actions/cache@v4
with: with:
path: ${{ env.CCACHE_DIR }} path: ${{ env.CCACHE_DIR }}
key: ${{ runner.os }}-${{ matrix.target }}-${{ github.sha }} key: ${{ runner.os }}-${{ matrix.target }}-${{ github.sha }}
@ -53,7 +53,7 @@ jobs:
run: ./.ci/pack.sh run: ./.ci/pack.sh
if: ${{ matrix.target == 'appimage' }} if: ${{ matrix.target == 'appimage' }}
- name: Upload - name: Upload
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v4
if: ${{ matrix.target == 'appimage' }} if: ${{ matrix.target == 'appimage' }}
with: with:
name: ${{ env.OS }}-${{ env.TARGET }} name: ${{ env.OS }}-${{ env.TARGET }}
@ -70,24 +70,24 @@ jobs:
OS: macos OS: macos
TARGET: ${{ matrix.target }} TARGET: ${{ matrix.target }}
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
with: with:
submodules: recursive submodules: recursive
- name: Set up cache - name: Set up cache
uses: actions/cache@v3 uses: actions/cache@v4
with: with:
path: ${{ env.CCACHE_DIR }} path: ${{ env.CCACHE_DIR }}
key: ${{ runner.os }}-${{ matrix.target }}-${{ github.sha }} key: ${{ runner.os }}-${{ matrix.target }}-${{ github.sha }}
restore-keys: | restore-keys: |
${{ runner.os }}-${{ matrix.target }}- ${{ runner.os }}-${{ matrix.target }}-
- name: Install tools - name: Install tools
run: brew install ccache glslang ninja run: brew install ccache ninja
- name: Build - name: Build
run: ./.ci/macos.sh run: ./.ci/macos.sh
- name: Prepare outputs for caching - name: Prepare outputs for caching
run: mv build/bundle $OS-$TARGET run: mv build/bundle $OS-$TARGET
- name: Cache outputs for universal build - name: Cache outputs for universal build
uses: actions/cache/save@v3 uses: actions/cache/save@v4
with: with:
path: ${{ env.OS }}-${{ env.TARGET }} path: ${{ env.OS }}-${{ env.TARGET }}
key: ${{ runner.os }}-${{ matrix.target }}-${{ github.sha }}-${{ github.run_id }}-${{ github.run_attempt }} key: ${{ runner.os }}-${{ matrix.target }}-${{ github.sha }}-${{ github.run_id }}-${{ github.run_attempt }}
@ -98,15 +98,15 @@ jobs:
OS: macos OS: macos
TARGET: universal TARGET: universal
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- name: Download x86_64 build from cache - name: Download x86_64 build from cache
uses: actions/cache/restore@v3 uses: actions/cache/restore@v4
with: with:
path: ${{ env.OS }}-x86_64 path: ${{ env.OS }}-x86_64
key: ${{ runner.os }}-x86_64-${{ github.sha }}-${{ github.run_id }}-${{ github.run_attempt }} key: ${{ runner.os }}-x86_64-${{ github.sha }}-${{ github.run_id }}-${{ github.run_attempt }}
fail-on-cache-miss: true fail-on-cache-miss: true
- name: Download ARM64 build from cache - name: Download ARM64 build from cache
uses: actions/cache/restore@v3 uses: actions/cache/restore@v4
with: with:
path: ${{ env.OS }}-arm64 path: ${{ env.OS }}-arm64
key: ${{ runner.os }}-arm64-${{ github.sha }}-${{ github.run_id }}-${{ github.run_attempt }} key: ${{ runner.os }}-arm64-${{ github.sha }}-${{ github.run_id }}-${{ github.run_attempt }}
@ -118,7 +118,7 @@ jobs:
- name: Pack - name: Pack
run: ./.ci/pack.sh run: ./.ci/pack.sh
- name: Upload - name: Upload
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v4
with: with:
name: ${{ env.OS }}-${{ env.TARGET }} name: ${{ env.OS }}-${{ env.TARGET }}
path: artifacts/ path: artifacts/
@ -137,11 +137,11 @@ jobs:
OS: windows OS: windows
TARGET: ${{ matrix.target }} TARGET: ${{ matrix.target }}
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
with: with:
submodules: recursive submodules: recursive
- name: Set up cache - name: Set up cache
uses: actions/cache@v3 uses: actions/cache@v4
with: with:
path: ${{ env.CCACHE_DIR }} path: ${{ env.CCACHE_DIR }}
key: ${{ runner.os }}-${{ matrix.target }}-${{ github.sha }} key: ${{ runner.os }}-${{ matrix.target }}-${{ github.sha }}
@ -153,13 +153,6 @@ jobs:
- name: Install extra tools (MSVC) - name: Install extra tools (MSVC)
run: choco install ccache ninja wget run: choco install ccache ninja wget
if: ${{ matrix.target == 'msvc' }} if: ${{ matrix.target == 'msvc' }}
- name: Set up Vulkan SDK (MSVC)
uses: humbletim/setup-vulkan-sdk@v1.2.0
if: ${{ matrix.target == 'msvc' }}
with:
vulkan-query-version: latest
vulkan-components: SPIRV-Tools, Glslang
vulkan-use-cache: true
- name: Set up MSYS2 - name: Set up MSYS2
uses: msys2/setup-msys2@v2 uses: msys2/setup-msys2@v2
if: ${{ matrix.target == 'msys2' }} if: ${{ matrix.target == 'msys2' }}
@ -168,10 +161,8 @@ jobs:
update: true update: true
install: git make p7zip install: git make p7zip
pacboy: >- pacboy: >-
toolchain:p ccache:p cmake:p ninja:p glslang:p toolchain:p ccache:p cmake:p ninja:p
qt6-base:p qt6-multimedia:p qt6-multimedia-wmf:p qt6-tools:p qt6-translations:p qt6-base:p qt6-multimedia:p qt6-multimedia-wmf:p qt6-tools:p qt6-translations:p
- name: Test glslang
run: glslang --version || glslangValidator --version
- name: Disable line ending translation - name: Disable line ending translation
run: git config --global core.autocrlf input run: git config --global core.autocrlf input
- name: Build - name: Build
@ -179,7 +170,7 @@ jobs:
- name: Pack - name: Pack
run: ./.ci/pack.sh run: ./.ci/pack.sh
- name: Upload - name: Upload
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v4
with: with:
name: ${{ env.OS }}-${{ env.TARGET }} name: ${{ env.OS }}-${{ env.TARGET }}
path: artifacts/ path: artifacts/
@ -192,11 +183,11 @@ jobs:
OS: android OS: android
TARGET: universal TARGET: universal
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
with: with:
submodules: recursive submodules: recursive
- name: Set up cache - name: Set up cache
uses: actions/cache@v3 uses: actions/cache@v4
with: with:
path: | path: |
~/.gradle/caches ~/.gradle/caches
@ -215,7 +206,7 @@ jobs:
run: | run: |
sudo add-apt-repository -y ppa:theofficialgman/gpu-tools sudo add-apt-repository -y ppa:theofficialgman/gpu-tools
sudo apt-get update -y sudo apt-get update -y
sudo apt-get install ccache glslang-dev glslang-tools apksigner -y sudo apt-get install ccache apksigner -y
- name: Build - name: Build
run: JAVA_HOME=$JAVA_HOME_17_X64 ./.ci/android.sh run: JAVA_HOME=$JAVA_HOME_17_X64 ./.ci/android.sh
env: env:
@ -228,7 +219,7 @@ jobs:
env: env:
UNPACKED: 1 UNPACKED: 1
- name: Upload - name: Upload
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v4
with: with:
name: ${{ env.OS }}-${{ env.TARGET }} name: ${{ env.OS }}-${{ env.TARGET }}
path: src/android/app/artifacts/ path: src/android/app/artifacts/
@ -242,18 +233,18 @@ jobs:
OS: ios OS: ios
TARGET: arm64 TARGET: arm64
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
with: with:
submodules: recursive submodules: recursive
- name: Set up cache - name: Set up cache
uses: actions/cache@v3 uses: actions/cache@v4
with: with:
path: ${{ env.CCACHE_DIR }} path: ${{ env.CCACHE_DIR }}
key: ${{ runner.os }}-ios-${{ github.sha }} key: ${{ runner.os }}-ios-${{ github.sha }}
restore-keys: | restore-keys: |
${{ runner.os }}-ios- ${{ runner.os }}-ios-
- name: Install tools - name: Install tools
run: brew install ccache glslang ninja run: brew install ccache ninja
- name: Build - name: Build
run: ./.ci/ios.sh run: ./.ci/ios.sh
release: release:
@ -261,7 +252,7 @@ jobs:
needs: [windows, linux, macos-universal, android, source] needs: [windows, linux, macos-universal, android, source]
if: ${{ startsWith(github.ref, 'refs/tags/') }} if: ${{ startsWith(github.ref, 'refs/tags/') }}
steps: steps:
- uses: actions/download-artifact@v3 - uses: actions/download-artifact@v4
- name: Create release - name: Create release
uses: actions/create-release@v1 uses: actions/create-release@v1
env: env:

View File

@ -13,7 +13,7 @@ jobs:
image: citraemu/build-environments:linux-fresh image: citraemu/build-environments:linux-fresh
options: -u 1001 options: -u 1001
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
with: with:
fetch-depth: 0 fetch-depth: 0
- name: Build - name: Build

View File

@ -20,11 +20,11 @@ jobs:
if: ${{ github.event.inputs.nightly != 'false' && github.repository == 'citra-emu/citra' }} if: ${{ github.event.inputs.nightly != 'false' && github.repository == 'citra-emu/citra' }}
steps: steps:
# this checkout is required to make sure the GitHub Actions scripts are available # this checkout is required to make sure the GitHub Actions scripts are available
- uses: actions/checkout@v3 - uses: actions/checkout@v4
name: Pre-checkout name: Pre-checkout
with: with:
submodules: false submodules: false
- uses: actions/github-script@v6 - uses: actions/github-script@v7
id: check-changes id: check-changes
name: 'Check for new changes' name: 'Check for new changes'
env: env:
@ -38,7 +38,7 @@ jobs:
return checkBaseChanges(github, context); return checkBaseChanges(github, context);
- run: npm install execa@5 - run: npm install execa@5
if: ${{ steps.check-changes.outputs.result == 'true' }} if: ${{ steps.check-changes.outputs.result == 'true' }}
- uses: actions/checkout@v3 - uses: actions/checkout@v4
name: Checkout name: Checkout
if: ${{ steps.check-changes.outputs.result == 'true' }} if: ${{ steps.check-changes.outputs.result == 'true' }}
with: with:
@ -46,7 +46,7 @@ jobs:
fetch-depth: 0 fetch-depth: 0
submodules: true submodules: true
token: ${{ secrets.ALT_GITHUB_TOKEN }} token: ${{ secrets.ALT_GITHUB_TOKEN }}
- uses: actions/github-script@v6 - uses: actions/github-script@v7
name: 'Update and tag new commits' name: 'Update and tag new commits'
if: ${{ steps.check-changes.outputs.result == 'true' }} if: ${{ steps.check-changes.outputs.result == 'true' }}
env: env:
@ -62,11 +62,11 @@ jobs:
if: ${{ github.event.inputs.canary != 'false' && github.repository == 'citra-emu/citra' }} if: ${{ github.event.inputs.canary != 'false' && github.repository == 'citra-emu/citra' }}
steps: steps:
# this checkout is required to make sure the GitHub Actions scripts are available # this checkout is required to make sure the GitHub Actions scripts are available
- uses: actions/checkout@v3 - uses: actions/checkout@v4
name: Pre-checkout name: Pre-checkout
with: with:
submodules: false submodules: false
- uses: actions/github-script@v6 - uses: actions/github-script@v7
id: check-changes id: check-changes
name: 'Check for new changes' name: 'Check for new changes'
env: env:
@ -79,7 +79,7 @@ jobs:
return checkCanaryChanges(github, context); return checkCanaryChanges(github, context);
- run: npm install execa@5 - run: npm install execa@5
if: ${{ steps.check-changes.outputs.result == 'true' }} if: ${{ steps.check-changes.outputs.result == 'true' }}
- uses: actions/checkout@v3 - uses: actions/checkout@v4
name: Checkout name: Checkout
if: ${{ steps.check-changes.outputs.result == 'true' }} if: ${{ steps.check-changes.outputs.result == 'true' }}
with: with:
@ -87,7 +87,7 @@ jobs:
fetch-depth: 0 fetch-depth: 0
submodules: true submodules: true
token: ${{ secrets.ALT_GITHUB_TOKEN }} token: ${{ secrets.ALT_GITHUB_TOKEN }}
- uses: actions/github-script@v6 - uses: actions/github-script@v7
name: 'Check and merge canary changes' name: 'Check and merge canary changes'
if: ${{ steps.check-changes.outputs.result == 'true' }} if: ${{ steps.check-changes.outputs.result == 'true' }}
env: env:

View File

@ -10,7 +10,7 @@ jobs:
container: citraemu/build-environments:linux-fresh container: citraemu/build-environments:linux-fresh
if: ${{ github.repository == 'citra-emu/citra' }} if: ${{ github.repository == 'citra-emu/citra' }}
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
with: with:
submodules: recursive submodules: recursive
fetch-depth: 0 fetch-depth: 0

View File

@ -3197,8 +3197,10 @@ int main(int argc, char* argv[]) {
QApplication::setHighDpiScaleFactorRoundingPolicy(rounding_policy); QApplication::setHighDpiScaleFactorRoundingPolicy(rounding_policy);
#ifdef __APPLE__ #ifdef __APPLE__
std::string bin_path = FileUtil::GetBundleDirectory() + DIR_SEP + ".."; auto bundle_dir = FileUtil::GetBundleDirectory();
chdir(bin_path.c_str()); if (bundle_dir) {
FileUtil::SetCurrentDir(bundle_dir.value() + "..");
}
#endif #endif
#ifdef ENABLE_OPENGL #ifdef ENABLE_OPENGL

View File

@ -13,7 +13,6 @@
#endif #endif
// The user data dir // The user data dir
#define ROOT_DIR "."
#define USERDATA_DIR "user" #define USERDATA_DIR "user"
#ifdef USER_DIR #ifdef USER_DIR
#define EMU_DATA_DIR USER_DIR #define EMU_DATA_DIR USER_DIR

View File

@ -634,6 +634,10 @@ std::optional<std::string> GetCurrentDir() {
std::string strDir = dir; std::string strDir = dir;
#endif #endif
free(dir); free(dir);
if (!strDir.ends_with(DIR_SEP)) {
strDir += DIR_SEP;
}
return strDir; return strDir;
} // namespace FileUtil } // namespace FileUtil
@ -646,17 +650,36 @@ bool SetCurrentDir(const std::string& directory) {
} }
#if defined(__APPLE__) #if defined(__APPLE__)
std::string GetBundleDirectory() { std::optional<std::string> GetBundleDirectory() {
CFURLRef BundleRef;
char AppBundlePath[MAXPATHLEN];
// Get the main bundle for the app // Get the main bundle for the app
BundleRef = CFBundleCopyBundleURL(CFBundleGetMainBundle()); CFBundleRef bundle_ref = CFBundleGetMainBundle();
CFStringRef BundlePath = CFURLCopyFileSystemPath(BundleRef, kCFURLPOSIXPathStyle); if (!bundle_ref) {
CFStringGetFileSystemRepresentation(BundlePath, AppBundlePath, sizeof(AppBundlePath)); return {};
CFRelease(BundleRef); }
CFRelease(BundlePath);
return AppBundlePath; CFURLRef bundle_url_ref = CFBundleCopyBundleURL(bundle_ref);
if (!bundle_url_ref) {
return {};
}
SCOPE_EXIT({ CFRelease(bundle_url_ref); });
CFStringRef bundle_path_ref = CFURLCopyFileSystemPath(bundle_url_ref, kCFURLPOSIXPathStyle);
if (!bundle_path_ref) {
return {};
}
SCOPE_EXIT({ CFRelease(bundle_path_ref); });
char app_bundle_path[MAXPATHLEN];
if (!CFStringGetFileSystemRepresentation(bundle_path_ref, app_bundle_path,
sizeof(app_bundle_path))) {
return {};
}
std::string path_str(app_bundle_path);
if (!path_str.ends_with(DIR_SEP)) {
path_str += DIR_SEP;
}
return path_str;
} }
#endif #endif
@ -732,22 +755,6 @@ static const std::string& GetHomeDirectory() {
} }
#endif #endif
std::string GetSysDirectory() {
std::string sysDir;
#if defined(__APPLE__)
sysDir = GetBundleDirectory();
sysDir += DIR_SEP;
sysDir += SYSDATA_DIR;
#else
sysDir = SYSDATA_DIR;
#endif
sysDir += DIR_SEP;
LOG_DEBUG(Common_Filesystem, "Setting to {}:", sysDir);
return sysDir;
}
namespace { namespace {
std::unordered_map<UserPath, std::string> g_paths; std::unordered_map<UserPath, std::string> g_paths;
std::unordered_map<UserPath, std::string> g_default_paths; std::unordered_map<UserPath, std::string> g_default_paths;
@ -777,8 +784,10 @@ void SetUserPath(const std::string& path) {
g_paths.emplace(UserPath::ConfigDir, user_path + CONFIG_DIR DIR_SEP); g_paths.emplace(UserPath::ConfigDir, user_path + CONFIG_DIR DIR_SEP);
g_paths.emplace(UserPath::CacheDir, user_path + CACHE_DIR DIR_SEP); g_paths.emplace(UserPath::CacheDir, user_path + CACHE_DIR DIR_SEP);
#else #else
if (FileUtil::Exists(ROOT_DIR DIR_SEP USERDATA_DIR)) { auto current_dir = FileUtil::GetCurrentDir();
user_path = ROOT_DIR DIR_SEP USERDATA_DIR DIR_SEP; if (current_dir.has_value() &&
FileUtil::Exists(current_dir.value() + USERDATA_DIR DIR_SEP)) {
user_path = current_dir.value() + USERDATA_DIR DIR_SEP;
g_paths.emplace(UserPath::ConfigDir, user_path + CONFIG_DIR DIR_SEP); g_paths.emplace(UserPath::ConfigDir, user_path + CONFIG_DIR DIR_SEP);
g_paths.emplace(UserPath::CacheDir, user_path + CACHE_DIR DIR_SEP); g_paths.emplace(UserPath::CacheDir, user_path + CACHE_DIR DIR_SEP);
} else { } else {

View File

@ -193,11 +193,8 @@ void SetCurrentRomPath(const std::string& path);
// Update the Global Path with the new value // Update the Global Path with the new value
void UpdateUserPath(UserPath path, const std::string& filename); void UpdateUserPath(UserPath path, const std::string& filename);
// Returns the path to where the sys file are
[[nodiscard]] std::string GetSysDirectory();
#ifdef __APPLE__ #ifdef __APPLE__
[[nodiscard]] std::string GetBundleDirectory(); [[nodiscard]] std::optional<std::string> GetBundleDirectory();
#endif #endif
#ifdef _WIN32 #ifdef _WIN32

View File

@ -451,7 +451,7 @@ void SetColorConsoleBackendEnabled(bool enabled) {
} }
void FmtLogMessageImpl(Class log_class, Level log_level, const char* filename, void FmtLogMessageImpl(Class log_class, Level log_level, const char* filename,
unsigned int line_num, const char* function, const char* format, unsigned int line_num, const char* function, fmt::string_view format,
const fmt::format_args& args) { const fmt::format_args& args) {
if (!initialization_in_progress_suppress_logging) { if (!initialization_in_progress_suppress_logging) {
Impl::Instance().PushEntry(log_class, log_level, filename, line_num, function, Impl::Instance().PushEntry(log_class, log_level, filename, line_num, function,

View File

@ -24,12 +24,12 @@ constexpr const char* TrimSourcePath(std::string_view source) {
/// Logs a message to the global logger, using fmt /// Logs a message to the global logger, using fmt
void FmtLogMessageImpl(Class log_class, Level log_level, const char* filename, void FmtLogMessageImpl(Class log_class, Level log_level, const char* filename,
unsigned int line_num, const char* function, const char* format, unsigned int line_num, const char* function, fmt::string_view format,
const fmt::format_args& args); const fmt::format_args& args);
template <typename... Args> template <typename... Args>
void FmtLogMessage(Class log_class, Level log_level, const char* filename, unsigned int line_num, void FmtLogMessage(Class log_class, Level log_level, const char* filename, unsigned int line_num,
const char* function, const char* format, const Args&... args) { const char* function, fmt::format_string<Args...> format, const Args&... args) {
FmtLogMessageImpl(log_class, log_level, filename, line_num, function, format, FmtLogMessageImpl(log_class, log_level, filename, line_num, function, format,
fmt::make_format_args(args...)); fmt::make_format_args(args...));
} }

View File

@ -14,18 +14,18 @@ namespace ConfigMem {
Handler::Handler() { Handler::Handler() {
std::memset(&config_mem, 0, sizeof(config_mem)); std::memset(&config_mem, 0, sizeof(config_mem));
// Values extracted from firmware 11.2.0-35E // Values extracted from firmware 11.17.0-50E
config_mem.kernel_version_min = 0x34; config_mem.kernel_version_min = 0x3a;
config_mem.kernel_version_maj = 0x2; config_mem.kernel_version_maj = 0x2;
config_mem.ns_tid = 0x0004013000008002; config_mem.ns_tid = 0x0004013000008002;
config_mem.sys_core_ver = 0x2; config_mem.sys_core_ver = 0x2;
config_mem.unit_info = 0x1; // Bit 0 set for Retail config_mem.unit_info = 0x1; // Bit 0 set for Retail
config_mem.prev_firm = 0x1; config_mem.prev_firm = 0x1;
config_mem.ctr_sdk_ver = 0x0000F297; config_mem.ctr_sdk_ver = 0x0000F450;
config_mem.firm_version_min = 0x34; config_mem.firm_version_min = 0x3a;
config_mem.firm_version_maj = 0x2; config_mem.firm_version_maj = 0x2;
config_mem.firm_sys_core_ver = 0x2; config_mem.firm_sys_core_ver = 0x2;
config_mem.firm_ctr_sdk_ver = 0x0000F297; config_mem.firm_ctr_sdk_ver = 0x0000F450;
} }
ConfigMemDef& Handler::GetConfigMem() { ConfigMemDef& Handler::GetConfigMem() {

View File

@ -210,10 +210,10 @@ void Process::Set3dsxKernelCaps() {
}; };
// Similar to Rosalina, we set kernel version to a recent one. // Similar to Rosalina, we set kernel version to a recent one.
// This is 11.2.0, to be consistent with core/hle/kernel/config_mem.cpp // This is 11.17.0, to be consistent with core/hle/kernel/config_mem.cpp
// TODO: refactor kernel version out so it is configurable and consistent // TODO: refactor kernel version out so it is configurable and consistent
// among all relevant places. // among all relevant places.
kernel_version = 0x234; kernel_version = 0x23a;
} }
void Process::Run(s32 main_thread_priority, u32 stack_size) { void Process::Run(s32 main_thread_priority, u32 stack_size) {

View File

@ -373,7 +373,10 @@ ResultVal<AppletManager::InitializeResult> AppletManager::Initialize(AppletId ap
if (active_slot == AppletSlot::Error) { if (active_slot == AppletSlot::Error) {
active_slot = slot; active_slot = slot;
// Wake up the application. // APT automatically calls enable on the first registered applet.
Enable(attributes);
// Wake up the applet.
SendParameter({ SendParameter({
.sender_id = AppletId::None, .sender_id = AppletId::None,
.destination_id = app_id, .destination_id = app_id,
@ -398,7 +401,8 @@ Result AppletManager::Enable(AppletAttributes attributes) {
auto slot_data = GetAppletSlot(slot); auto slot_data = GetAppletSlot(slot);
slot_data->registered = true; slot_data->registered = true;
if (slot_data->attributes.applet_pos == AppletPos::System && if (slot_data->applet_id != AppletId::None &&
slot_data->attributes.applet_pos == AppletPos::System &&
slot_data->attributes.is_home_menu) { slot_data->attributes.is_home_menu) {
slot_data->attributes.raw |= attributes.raw; slot_data->attributes.raw |= attributes.raw;
LOG_DEBUG(Service_APT, "Updated home menu attributes to {:08X}.", LOG_DEBUG(Service_APT, "Updated home menu attributes to {:08X}.",
@ -786,16 +790,23 @@ Result AppletManager::PrepareToStartSystemApplet(AppletId applet_id) {
Result AppletManager::StartSystemApplet(AppletId applet_id, std::shared_ptr<Kernel::Object> object, Result AppletManager::StartSystemApplet(AppletId applet_id, std::shared_ptr<Kernel::Object> object,
const std::vector<u8>& buffer) { const std::vector<u8>& buffer) {
auto source_applet_id = AppletId::None; auto source_applet_id = AppletId::Application;
if (last_system_launcher_slot != AppletSlot::Error) { if (last_system_launcher_slot != AppletSlot::Error) {
const auto slot_data = GetAppletSlot(last_system_launcher_slot); const auto launcher_slot_data = GetAppletSlot(last_system_launcher_slot);
source_applet_id = slot_data->applet_id; source_applet_id = launcher_slot_data->applet_id;
// If a system applet is launching another system applet, reset the slot to avoid conflicts. // APT generally clears and terminates the caller of StartSystemApplet. This helps in
// This is needed because system applets won't necessarily call CloseSystemApplet before // situations such as a system applet launching another system applet, which would
// exiting. // otherwise deadlock.
if (last_system_launcher_slot == AppletSlot::SystemApplet) { // TODO: In real APT, the check for AppletSlot::Application does not exist; there is
slot_data->Reset(); // TODO: something wrong with our implementation somewhere that makes this necessary.
// TODO: Otherwise, games that attempt to launch system applets will be cleared and
// TODO: emulation will crash.
if (!launcher_slot_data->registered ||
(last_system_launcher_slot != AppletSlot::Application &&
!launcher_slot_data->attributes.no_exit_on_system_applet)) {
launcher_slot_data->Reset();
// TODO: Implement launcher process termination.
} }
} }

View File

@ -152,6 +152,7 @@ union AppletAttributes {
u32 raw; u32 raw;
BitField<0, 3, AppletPos> applet_pos; BitField<0, 3, AppletPos> applet_pos;
BitField<28, 1, u32> no_exit_on_system_applet;
BitField<29, 1, u32> is_home_menu; BitField<29, 1, u32> is_home_menu;
AppletAttributes() : raw(0) {} AppletAttributes() : raw(0) {}

View File

@ -1014,8 +1014,8 @@ void SOC_U::Accept(Kernel::HLERequestContext& ctx) {
ctr_addr_buf.resize(async_data->max_addr_len); ctr_addr_buf.resize(async_data->max_addr_len);
} }
LOG_DEBUG(Service_SOC, "called, pid={}, fd={}, ret={}", async_data->socket_handle, LOG_DEBUG(Service_SOC, "called, pid={}, fd={}, ret={}", async_data->pid,
static_cast<s32>(async_data->ret)); async_data->socket_handle, static_cast<s32>(async_data->ret));
IPC::RequestBuilder rb(ctx, 0x04, 2, 2); IPC::RequestBuilder rb(ctx, 0x04, 2, 2);
rb.Push(ResultSuccess); rb.Push(ResultSuccess);

View File

@ -152,6 +152,7 @@ static void SaveBanList(const Network::Room::BanList& ban_list, const std::strin
static void InitializeLogging(const std::string& log_file) { static void InitializeLogging(const std::string& log_file) {
Common::Log::Initialize(log_file); Common::Log::Initialize(log_file);
Common::Log::SetColorConsoleBackendEnabled(true); Common::Log::SetColorConsoleBackendEnabled(true);
Common::Log::Start();
} }
/// Application entry point /// Application entry point

View File

@ -26,17 +26,6 @@ set(SHADER_FILES
vulkan_blit_depth_stencil.frag vulkan_blit_depth_stencil.frag
) )
find_program(GLSLANG "glslang")
if ("${GLSLANG}" STREQUAL "GLSLANG-NOTFOUND")
find_program(GLSLANG "glslangValidator")
if ("${GLSLANG}" STREQUAL "GLSLANG-NOTFOUND")
message(FATAL_ERROR "Required program `glslang` (or `glslangValidator`) not found.")
endif()
endif()
set(MACROS "-Dgl_VertexID=gl_VertexIndex")
set(QUIET_FLAG "--quiet")
set(SHADER_INCLUDE ${CMAKE_CURRENT_BINARY_DIR}/include) set(SHADER_INCLUDE ${CMAKE_CURRENT_BINARY_DIR}/include)
set(SHADER_DIR ${SHADER_INCLUDE}/video_core/host_shaders) set(SHADER_DIR ${SHADER_INCLUDE}/video_core/host_shaders)
set(HOST_SHADERS_INCLUDE ${SHADER_INCLUDE} PARENT_SCOPE) set(HOST_SHADERS_INCLUDE ${SHADER_INCLUDE} PARENT_SCOPE)
@ -44,28 +33,9 @@ set(HOST_SHADERS_INCLUDE ${SHADER_INCLUDE} PARENT_SCOPE)
set(INPUT_FILE ${CMAKE_CURRENT_SOURCE_DIR}/source_shader.h.in) set(INPUT_FILE ${CMAKE_CURRENT_SOURCE_DIR}/source_shader.h.in)
set(HEADER_GENERATOR ${CMAKE_CURRENT_SOURCE_DIR}/StringShaderHeader.cmake) set(HEADER_GENERATOR ${CMAKE_CURRENT_SOURCE_DIR}/StringShaderHeader.cmake)
# Check if `--quiet` is available on host's glslang version
# glslang prints to STDERR iff an unrecognized flag is passed to it
execute_process(
COMMAND
${GLSLANG} ${QUIET_FLAG}
ERROR_VARIABLE
GLSLANG_ERROR
# STDOUT variable defined to silence unnecessary output during CMake configuration
OUTPUT_VARIABLE
GLSLANG_OUTPUT
)
if (NOT GLSLANG_ERROR STREQUAL "")
message(WARNING "Refusing to use unavailable flag `${QUIET_FLAG}` on `${GLSLANG}`")
set(QUIET_FLAG "")
endif()
foreach(FILENAME IN ITEMS ${SHADER_FILES}) foreach(FILENAME IN ITEMS ${SHADER_FILES})
string(REPLACE "." "_" SHADER_NAME ${FILENAME}) string(REPLACE "." "_" SHADER_NAME ${FILENAME})
set(SOURCE_FILE ${CMAKE_CURRENT_SOURCE_DIR}/${FILENAME}) set(SOURCE_FILE ${CMAKE_CURRENT_SOURCE_DIR}/${FILENAME})
# Skip generating source headers on Vulkan exclusive files
if (NOT ${FILENAME} MATCHES "vulkan.*")
set(SOURCE_HEADER_FILE ${SHADER_DIR}/${SHADER_NAME}.h) set(SOURCE_HEADER_FILE ${SHADER_DIR}/${SHADER_NAME}.h)
add_custom_command( add_custom_command(
OUTPUT OUTPUT
@ -79,22 +49,6 @@ foreach(FILENAME IN ITEMS ${SHADER_FILES})
# HEADER_GENERATOR should be included here but msbuild seems to assume it's always modified # HEADER_GENERATOR should be included here but msbuild seems to assume it's always modified
) )
set(SHADER_HEADERS ${SHADER_HEADERS} ${SOURCE_HEADER_FILE}) set(SHADER_HEADERS ${SHADER_HEADERS} ${SOURCE_HEADER_FILE})
endif()
# Skip compiling to SPIR-V OpenGL exclusive files
if (NOT ${FILENAME} MATCHES "opengl.*")
get_filename_component(FILE_NAME ${SHADER_NAME} NAME)
string(TOUPPER ${FILE_NAME}_SPV SPIRV_VARIABLE_NAME)
set(SPIRV_HEADER_FILE ${SHADER_DIR}/${SHADER_NAME}_spv.h)
add_custom_command(
OUTPUT
${SPIRV_HEADER_FILE}
COMMAND
${GLSLANG} --target-env vulkan1.1 --glsl-version 450 ${QUIET_FLAG} ${MACROS} --variable-name ${SPIRV_VARIABLE_NAME} -o ${SPIRV_HEADER_FILE} ${SOURCE_FILE}
MAIN_DEPENDENCY
${SOURCE_FILE}
)
set(SHADER_HEADERS ${SHADER_HEADERS} ${SPIRV_HEADER_FILE})
endif()
endforeach() endforeach()
set(SHADER_SOURCES ${SHADER_FILES}) set(SHADER_SOURCES ${SHADER_FILES})

View File

@ -8,6 +8,10 @@ layout(location = 0) out vec2 dst_coord;
layout(location = 0) uniform mediump ivec2 dst_size; layout(location = 0) uniform mediump ivec2 dst_size;
#ifdef VULKAN
#define gl_VertexID gl_VertexIndex
#endif
const vec2 vertices[4] = const vec2 vertices[4] =
vec2[4](vec2(-1.0, -1.0), vec2(1.0, -1.0), vec2(-1.0, 1.0), vec2(1.0, 1.0)); vec2[4](vec2(-1.0, -1.0), vec2(1.0, -1.0), vec2(-1.0, 1.0), vec2(1.0, 1.0));

View File

@ -10,6 +10,7 @@ out gl_PerVertex {
layout(location = 0) out vec2 texcoord; layout(location = 0) out vec2 texcoord;
#ifdef VULKAN #ifdef VULKAN
#define gl_VertexID gl_VertexIndex
#define BEGIN_PUSH_CONSTANTS layout(push_constant) uniform PushConstants { #define BEGIN_PUSH_CONSTANTS layout(push_constant) uniform PushConstants {
#define END_PUSH_CONSTANTS }; #define END_PUSH_CONSTANTS };
#define UNIFORM(n) #define UNIFORM(n)

View File

@ -5,6 +5,10 @@
//? #version 430 core //? #version 430 core
layout(location = 0) out vec2 tex_coord; layout(location = 0) out vec2 tex_coord;
#ifdef VULKAN
#define gl_VertexID gl_VertexIndex
#endif
const vec2 vertices[4] = const vec2 vertices[4] =
vec2[4](vec2(-1.0, -1.0), vec2(1.0, -1.0), vec2(-1.0, 1.0), vec2(1.0, 1.0)); vec2[4](vec2(-1.0, -1.0), vec2(1.0, -1.0), vec2(-1.0, 1.0), vec2(1.0, 1.0));

View File

@ -148,8 +148,6 @@ inline GLenum BlendFunc(Pica::FramebufferRegs::BlendFactor factor) {
// Range check table for input // Range check table for input
if (index >= blend_func_table.size()) { if (index >= blend_func_table.size()) {
LOG_CRITICAL(Render_OpenGL, "Unknown blend factor {}", index); LOG_CRITICAL(Render_OpenGL, "Unknown blend factor {}", index);
UNREACHABLE();
return GL_ONE; return GL_ONE;
} }

View File

@ -96,7 +96,10 @@ inline vk::BlendFactor BlendFunc(Pica::FramebufferRegs::BlendFactor factor) {
}}; }};
const auto index = static_cast<std::size_t>(factor); const auto index = static_cast<std::size_t>(factor);
ASSERT_MSG(index < blend_func_table.size(), "Unknown blend factor {}", index); if (index >= blend_func_table.size()) {
LOG_CRITICAL(Render_Vulkan, "Unknown blend factor {}", index);
return vk::BlendFactor::eOne;
}
return blend_func_table[index]; return blend_func_table[index];
} }

View File

@ -15,10 +15,10 @@
#include "video_core/renderer_vulkan/vk_memory_util.h" #include "video_core/renderer_vulkan/vk_memory_util.h"
#include "video_core/renderer_vulkan/vk_shader_util.h" #include "video_core/renderer_vulkan/vk_shader_util.h"
#include "video_core/host_shaders/vulkan_present_anaglyph_frag_spv.h" #include "video_core/host_shaders/vulkan_present_anaglyph_frag.h"
#include "video_core/host_shaders/vulkan_present_frag_spv.h" #include "video_core/host_shaders/vulkan_present_frag.h"
#include "video_core/host_shaders/vulkan_present_interlaced_frag_spv.h" #include "video_core/host_shaders/vulkan_present_interlaced_frag.h"
#include "video_core/host_shaders/vulkan_present_vert_spv.h" #include "video_core/host_shaders/vulkan_present_vert.h"
#include <vk_mem_alloc.h> #include <vk_mem_alloc.h>
@ -225,10 +225,14 @@ void RendererVulkan::LoadFBToScreenInfo(const Pica::FramebufferConfig& framebuff
void RendererVulkan::CompileShaders() { void RendererVulkan::CompileShaders() {
vk::Device device = instance.GetDevice(); vk::Device device = instance.GetDevice();
present_vertex_shader = CompileSPV(VULKAN_PRESENT_VERT_SPV, device); present_vertex_shader =
present_shaders[0] = CompileSPV(VULKAN_PRESENT_FRAG_SPV, device); Compile(HostShaders::VULKAN_PRESENT_VERT, vk::ShaderStageFlagBits::eVertex, device);
present_shaders[1] = CompileSPV(VULKAN_PRESENT_ANAGLYPH_FRAG_SPV, device); present_shaders[0] =
present_shaders[2] = CompileSPV(VULKAN_PRESENT_INTERLACED_FRAG_SPV, device); Compile(HostShaders::VULKAN_PRESENT_FRAG, vk::ShaderStageFlagBits::eFragment, device);
present_shaders[1] = Compile(HostShaders::VULKAN_PRESENT_ANAGLYPH_FRAG,
vk::ShaderStageFlagBits::eFragment, device);
present_shaders[2] = Compile(HostShaders::VULKAN_PRESENT_INTERLACED_FRAG,
vk::ShaderStageFlagBits::eFragment, device);
auto properties = instance.GetPhysicalDevice().getProperties(); auto properties = instance.GetPhysicalDevice().getProperties();
for (std::size_t i = 0; i < present_samplers.size(); i++) { for (std::size_t i = 0; i < present_samplers.size(); i++) {

View File

@ -10,10 +10,10 @@
#include "video_core/renderer_vulkan/vk_shader_util.h" #include "video_core/renderer_vulkan/vk_shader_util.h"
#include "video_core/renderer_vulkan/vk_texture_runtime.h" #include "video_core/renderer_vulkan/vk_texture_runtime.h"
#include "video_core/host_shaders/format_reinterpreter/vulkan_d24s8_to_rgba8_comp_spv.h" #include "video_core/host_shaders/format_reinterpreter/vulkan_d24s8_to_rgba8_comp.h"
#include "video_core/host_shaders/full_screen_triangle_vert_spv.h" #include "video_core/host_shaders/full_screen_triangle_vert.h"
#include "video_core/host_shaders/vulkan_blit_depth_stencil_frag_spv.h" #include "video_core/host_shaders/vulkan_blit_depth_stencil_frag.h"
#include "video_core/host_shaders/vulkan_depth_to_buffer_comp_spv.h" #include "video_core/host_shaders/vulkan_depth_to_buffer_comp.h"
namespace Vulkan { namespace Vulkan {
@ -189,10 +189,14 @@ BlitHelper::BlitHelper(const Instance& instance_, Scheduler& scheduler_, Descrip
PipelineLayoutCreateInfo(&compute_buffer_provider.Layout(), true))}, PipelineLayoutCreateInfo(&compute_buffer_provider.Layout(), true))},
two_textures_pipeline_layout{ two_textures_pipeline_layout{
device.createPipelineLayout(PipelineLayoutCreateInfo(&two_textures_provider.Layout()))}, device.createPipelineLayout(PipelineLayoutCreateInfo(&two_textures_provider.Layout()))},
full_screen_vert{CompileSPV(FULL_SCREEN_TRIANGLE_VERT_SPV, device)}, full_screen_vert{Compile(HostShaders::FULL_SCREEN_TRIANGLE_VERT,
d24s8_to_rgba8_comp{CompileSPV(VULKAN_D24S8_TO_RGBA8_COMP_SPV, device)}, vk::ShaderStageFlagBits::eVertex, device)},
depth_to_buffer_comp{CompileSPV(VULKAN_DEPTH_TO_BUFFER_COMP_SPV, device)}, d24s8_to_rgba8_comp{Compile(HostShaders::VULKAN_D24S8_TO_RGBA8_COMP,
blit_depth_stencil_frag{CompileSPV(VULKAN_BLIT_DEPTH_STENCIL_FRAG_SPV, device)}, vk::ShaderStageFlagBits::eCompute, device)},
depth_to_buffer_comp{Compile(HostShaders::VULKAN_DEPTH_TO_BUFFER_COMP,
vk::ShaderStageFlagBits::eCompute, device)},
blit_depth_stencil_frag{Compile(HostShaders::VULKAN_BLIT_DEPTH_STENCIL_FRAG,
vk::ShaderStageFlagBits::eFragment, device)},
d24s8_to_rgba8_pipeline{MakeComputePipeline(d24s8_to_rgba8_comp, compute_pipeline_layout)}, d24s8_to_rgba8_pipeline{MakeComputePipeline(d24s8_to_rgba8_comp, compute_pipeline_layout)},
depth_to_buffer_pipeline{ depth_to_buffer_pipeline{
MakeComputePipeline(depth_to_buffer_comp, compute_buffer_pipeline_layout)}, MakeComputePipeline(depth_to_buffer_comp, compute_buffer_pipeline_layout)},

View File

@ -3,6 +3,7 @@
// Refer to the license.txt file included. // Refer to the license.txt file included.
#include <boost/container/small_vector.hpp> #include <boost/container/small_vector.hpp>
#include <boost/container/static_vector.hpp>
#include "common/literals.h" #include "common/literals.h"
#include "common/microprofile.h" #include "common/microprofile.h"
@ -119,9 +120,9 @@ u32 UnpackDepthStencil(const VideoCore::StagingData& data, vk::Format dest) {
} }
boost::container::small_vector<vk::ImageMemoryBarrier, 3> MakeInitBarriers( boost::container::small_vector<vk::ImageMemoryBarrier, 3> MakeInitBarriers(
vk::ImageAspectFlags aspect, std::span<const vk::Image> images, std::size_t num_images) { vk::ImageAspectFlags aspect, std::span<const vk::Image> images) {
boost::container::small_vector<vk::ImageMemoryBarrier, 3> barriers; boost::container::small_vector<vk::ImageMemoryBarrier, 3> barriers;
for (std::size_t i = 0; i < num_images; i++) { for (const vk::Image& image : images) {
barriers.push_back(vk::ImageMemoryBarrier{ barriers.push_back(vk::ImageMemoryBarrier{
.srcAccessMask = vk::AccessFlagBits::eNone, .srcAccessMask = vk::AccessFlagBits::eNone,
.dstAccessMask = vk::AccessFlagBits::eNone, .dstAccessMask = vk::AccessFlagBits::eNone,
@ -129,7 +130,7 @@ boost::container::small_vector<vk::ImageMemoryBarrier, 3> MakeInitBarriers(
.newLayout = vk::ImageLayout::eGeneral, .newLayout = vk::ImageLayout::eGeneral,
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.image = images[i], .image = image,
.subresourceRange{ .subresourceRange{
.aspectMask = aspect, .aspectMask = aspect,
.baseMipLevel = 0, .baseMipLevel = 0,
@ -219,11 +220,10 @@ Handle MakeHandle(const Instance* instance, u32 width, u32 height, u32 levels, T
} }
vk::UniqueFramebuffer MakeFramebuffer(vk::Device device, vk::RenderPass render_pass, u32 width, vk::UniqueFramebuffer MakeFramebuffer(vk::Device device, vk::RenderPass render_pass, u32 width,
u32 height, std::span<const vk::ImageView> attachments, u32 height, std::span<const vk::ImageView> attachments) {
u32 num_attachments) {
const vk::FramebufferCreateInfo framebuffer_info = { const vk::FramebufferCreateInfo framebuffer_info = {
.renderPass = render_pass, .renderPass = render_pass,
.attachmentCount = num_attachments, .attachmentCount = static_cast<u32>(attachments.size()),
.pAttachments = attachments.data(), .pAttachments = attachments.data(),
.width = width, .width = width,
.height = height, .height = height,
@ -715,8 +715,7 @@ Surface::Surface(TextureRuntime& runtime_, const VideoCore::SurfaceParams& param
ASSERT_MSG(format != vk::Format::eUndefined && levels >= 1, ASSERT_MSG(format != vk::Format::eUndefined && levels >= 1,
"Image allocation parameters are invalid"); "Image allocation parameters are invalid");
u32 num_images = 0; boost::container::static_vector<vk::Image, 3> raw_images;
std::array<vk::Image, 3> raw_images;
vk::ImageCreateFlags flags{}; vk::ImageCreateFlags flags{};
if (texture_type == VideoCore::TextureType::CubeMap) { if (texture_type == VideoCore::TextureType::CubeMap) {
@ -729,18 +728,18 @@ Surface::Surface(TextureRuntime& runtime_, const VideoCore::SurfaceParams& param
const bool need_format_list = is_mutable && instance->IsImageFormatListSupported(); const bool need_format_list = is_mutable && instance->IsImageFormatListSupported();
handles[0] = MakeHandle(instance, width, height, levels, texture_type, format, traits.usage, handles[0] = MakeHandle(instance, width, height, levels, texture_type, format, traits.usage,
flags, traits.aspect, need_format_list, DebugName(false)); flags, traits.aspect, need_format_list, DebugName(false));
raw_images[num_images++] = handles[0].image; raw_images.emplace_back(handles[0].image);
if (res_scale != 1) { if (res_scale != 1) {
handles[1] = handles[1] =
MakeHandle(instance, GetScaledWidth(), GetScaledHeight(), levels, texture_type, format, MakeHandle(instance, GetScaledWidth(), GetScaledHeight(), levels, texture_type, format,
traits.usage, flags, traits.aspect, need_format_list, DebugName(true)); traits.usage, flags, traits.aspect, need_format_list, DebugName(true));
raw_images[num_images++] = handles[1].image; raw_images.emplace_back(handles[1].image);
} }
runtime->renderpass_cache.EndRendering(); runtime->renderpass_cache.EndRendering();
scheduler->Record([raw_images, num_images, aspect = traits.aspect](vk::CommandBuffer cmdbuf) { scheduler->Record([raw_images, aspect = traits.aspect](vk::CommandBuffer cmdbuf) {
const auto barriers = MakeInitBarriers(aspect, raw_images, num_images); const auto barriers = MakeInitBarriers(aspect, raw_images);
cmdbuf.pipelineBarrier(vk::PipelineStageFlagBits::eTopOfPipe, cmdbuf.pipelineBarrier(vk::PipelineStageFlagBits::eTopOfPipe,
vk::PipelineStageFlagBits::eTopOfPipe, vk::PipelineStageFlagBits::eTopOfPipe,
vk::DependencyFlagBits::eByRegion, {}, {}, barriers); vk::DependencyFlagBits::eByRegion, {}, {}, barriers);
@ -758,8 +757,7 @@ Surface::Surface(TextureRuntime& runtime_, const VideoCore::SurfaceBase& surface
const bool has_normal = mat && mat->Map(MapType::Normal); const bool has_normal = mat && mat->Map(MapType::Normal);
const vk::Format format = traits.native; const vk::Format format = traits.native;
u32 num_images = 0; boost::container::static_vector<vk::Image, 2> raw_images;
std::array<vk::Image, 2> raw_images;
vk::ImageCreateFlags flags{}; vk::ImageCreateFlags flags{};
if (texture_type == VideoCore::TextureType::CubeMap) { if (texture_type == VideoCore::TextureType::CubeMap) {
@ -769,23 +767,23 @@ Surface::Surface(TextureRuntime& runtime_, const VideoCore::SurfaceBase& surface
const std::string debug_name = DebugName(false, true); const std::string debug_name = DebugName(false, true);
handles[0] = MakeHandle(instance, mat->width, mat->height, levels, texture_type, format, handles[0] = MakeHandle(instance, mat->width, mat->height, levels, texture_type, format,
traits.usage, flags, traits.aspect, false, debug_name); traits.usage, flags, traits.aspect, false, debug_name);
raw_images[num_images++] = handles[0].image; raw_images.emplace_back(handles[0].image);
if (res_scale != 1) { if (res_scale != 1) {
handles[1] = MakeHandle(instance, mat->width, mat->height, levels, texture_type, handles[1] = MakeHandle(instance, mat->width, mat->height, levels, texture_type,
vk::Format::eR8G8B8A8Unorm, traits.usage, flags, traits.aspect, vk::Format::eR8G8B8A8Unorm, traits.usage, flags, traits.aspect,
false, debug_name); false, debug_name);
raw_images[num_images++] = handles[1].image; raw_images.emplace_back(handles[1].image);
} }
if (has_normal) { if (has_normal) {
handles[2] = MakeHandle(instance, mat->width, mat->height, levels, texture_type, format, handles[2] = MakeHandle(instance, mat->width, mat->height, levels, texture_type, format,
traits.usage, flags, traits.aspect, false, debug_name); traits.usage, flags, traits.aspect, false, debug_name);
raw_images[num_images++] = handles[2].image; raw_images.emplace_back(handles[2].image);
} }
runtime->renderpass_cache.EndRendering(); runtime->renderpass_cache.EndRendering();
scheduler->Record([raw_images, num_images, aspect = traits.aspect](vk::CommandBuffer cmdbuf) { scheduler->Record([raw_images, aspect = traits.aspect](vk::CommandBuffer cmdbuf) {
const auto barriers = MakeInitBarriers(aspect, raw_images, num_images); const auto barriers = MakeInitBarriers(aspect, raw_images);
cmdbuf.pipelineBarrier(vk::PipelineStageFlagBits::eTopOfPipe, cmdbuf.pipelineBarrier(vk::PipelineStageFlagBits::eTopOfPipe,
vk::PipelineStageFlagBits::eTopOfPipe, vk::PipelineStageFlagBits::eTopOfPipe,
vk::DependencyFlagBits::eByRegion, {}, {}, barriers); vk::DependencyFlagBits::eByRegion, {}, {}, barriers);
@ -825,11 +823,10 @@ void Surface::Upload(const VideoCore::BufferTextureCopy& upload,
scheduler->Record([buffer = runtime->upload_buffer.Handle(), format = traits.native, params, scheduler->Record([buffer = runtime->upload_buffer.Handle(), format = traits.native, params,
staging, upload](vk::CommandBuffer cmdbuf) { staging, upload](vk::CommandBuffer cmdbuf) {
u32 num_copies = 1; boost::container::static_vector<vk::BufferImageCopy, 2> buffer_image_copies;
std::array<vk::BufferImageCopy, 2> buffer_image_copies;
const auto rect = upload.texture_rect; const auto rect = upload.texture_rect;
buffer_image_copies[0] = vk::BufferImageCopy{ buffer_image_copies.emplace_back(vk::BufferImageCopy{
.bufferOffset = upload.buffer_offset, .bufferOffset = upload.buffer_offset,
.bufferRowLength = rect.GetWidth(), .bufferRowLength = rect.GetWidth(),
.bufferImageHeight = rect.GetHeight(), .bufferImageHeight = rect.GetHeight(),
@ -841,15 +838,16 @@ void Surface::Upload(const VideoCore::BufferTextureCopy& upload,
}, },
.imageOffset = {static_cast<s32>(rect.left), static_cast<s32>(rect.bottom), 0}, .imageOffset = {static_cast<s32>(rect.left), static_cast<s32>(rect.bottom), 0},
.imageExtent = {rect.GetWidth(), rect.GetHeight(), 1}, .imageExtent = {rect.GetWidth(), rect.GetHeight(), 1},
}; });
if (params.aspect & vk::ImageAspectFlagBits::eStencil) { if (params.aspect & vk::ImageAspectFlagBits::eStencil) {
buffer_image_copies[0].imageSubresource.aspectMask = vk::ImageAspectFlagBits::eDepth; buffer_image_copies[0].imageSubresource.aspectMask = vk::ImageAspectFlagBits::eDepth;
vk::BufferImageCopy& stencil_copy = buffer_image_copies[1];
vk::BufferImageCopy& stencil_copy =
buffer_image_copies.emplace_back(buffer_image_copies[0]);
stencil_copy = buffer_image_copies[0]; stencil_copy = buffer_image_copies[0];
stencil_copy.bufferOffset += UnpackDepthStencil(staging, format); stencil_copy.bufferOffset += UnpackDepthStencil(staging, format);
stencil_copy.imageSubresource.aspectMask = vk::ImageAspectFlagBits::eStencil; stencil_copy.imageSubresource.aspectMask = vk::ImageAspectFlagBits::eStencil;
num_copies++;
} }
const vk::ImageMemoryBarrier read_barrier = { const vk::ImageMemoryBarrier read_barrier = {
@ -877,7 +875,7 @@ void Surface::Upload(const VideoCore::BufferTextureCopy& upload,
vk::DependencyFlagBits::eByRegion, {}, {}, read_barrier); vk::DependencyFlagBits::eByRegion, {}, {}, read_barrier);
cmdbuf.copyBufferToImage(buffer, params.src_image, vk::ImageLayout::eTransferDstOptimal, cmdbuf.copyBufferToImage(buffer, params.src_image, vk::ImageLayout::eTransferDstOptimal,
num_copies, buffer_image_copies.data()); buffer_image_copies);
cmdbuf.pipelineBarrier(vk::PipelineStageFlagBits::eTransfer, params.pipeline_flags, cmdbuf.pipelineBarrier(vk::PipelineStageFlagBits::eTransfer, params.pipeline_flags,
vk::DependencyFlagBits::eByRegion, {}, {}, write_barrier); vk::DependencyFlagBits::eByRegion, {}, {}, write_barrier);
@ -1085,7 +1083,7 @@ void Surface::ScaleUp(u32 new_scale) {
runtime->renderpass_cache.EndRendering(); runtime->renderpass_cache.EndRendering();
scheduler->Record( scheduler->Record(
[raw_images = std::array{Image()}, aspect = traits.aspect](vk::CommandBuffer cmdbuf) { [raw_images = std::array{Image()}, aspect = traits.aspect](vk::CommandBuffer cmdbuf) {
const auto barriers = MakeInitBarriers(aspect, raw_images, raw_images.size()); const auto barriers = MakeInitBarriers(aspect, raw_images);
cmdbuf.pipelineBarrier(vk::PipelineStageFlagBits::eTopOfPipe, cmdbuf.pipelineBarrier(vk::PipelineStageFlagBits::eTopOfPipe,
vk::PipelineStageFlagBits::eTopOfPipe, vk::PipelineStageFlagBits::eTopOfPipe,
vk::DependencyFlagBits::eByRegion, {}, {}, barriers); vk::DependencyFlagBits::eByRegion, {}, {}, barriers);
@ -1351,7 +1349,7 @@ vk::Framebuffer Surface::Framebuffer() noexcept {
runtime->renderpass_cache.GetRenderpass(color_format, depth_format, false); runtime->renderpass_cache.GetRenderpass(color_format, depth_format, false);
const auto attachments = std::array{ImageView()}; const auto attachments = std::array{ImageView()};
framebuffers[index] = MakeFramebuffer(instance->GetDevice(), render_pass, GetScaledWidth(), framebuffers[index] = MakeFramebuffer(instance->GetDevice(), render_pass, GetScaledWidth(),
GetScaledHeight(), attachments, 1); GetScaledHeight(), attachments);
return framebuffers[index].get(); return framebuffers[index].get();
} }
@ -1481,17 +1479,16 @@ Framebuffer::Framebuffer(TextureRuntime& runtime, const VideoCore::FramebufferPa
image_views[index] = shadow_rendering ? surface->StorageView() : surface->FramebufferView(); image_views[index] = shadow_rendering ? surface->StorageView() : surface->FramebufferView();
}; };
u32 num_attachments = 0; boost::container::static_vector<vk::ImageView, 2> attachments;
std::array<vk::ImageView, 2> attachments;
if (color) { if (color) {
prepare(0, color); prepare(0, color);
attachments[num_attachments++] = image_views[0]; attachments.emplace_back(image_views[0]);
} }
if (depth) { if (depth) {
prepare(1, depth); prepare(1, depth);
attachments[num_attachments++] = image_views[1]; attachments.emplace_back(image_views[1]);
} }
const vk::Device device = runtime.GetInstance().GetDevice(); const vk::Device device = runtime.GetInstance().GetDevice();
@ -1499,11 +1496,10 @@ Framebuffer::Framebuffer(TextureRuntime& runtime, const VideoCore::FramebufferPa
render_pass = render_pass =
renderpass_cache.GetRenderpass(PixelFormat::Invalid, PixelFormat::Invalid, false); renderpass_cache.GetRenderpass(PixelFormat::Invalid, PixelFormat::Invalid, false);
framebuffer = MakeFramebuffer(device, render_pass, color->GetScaledWidth(), framebuffer = MakeFramebuffer(device, render_pass, color->GetScaledWidth(),
color->GetScaledHeight(), {}, 0); color->GetScaledHeight(), {});
} else { } else {
render_pass = renderpass_cache.GetRenderpass(formats[0], formats[1], false); render_pass = renderpass_cache.GetRenderpass(formats[0], formats[1], false);
framebuffer = framebuffer = MakeFramebuffer(device, render_pass, width, height, attachments);
MakeFramebuffer(device, render_pass, width, height, attachments, num_attachments);
} }
} }

View File

@ -0,0 +1,8 @@
#!/bin/bash -ex
# SPDX-FileCopyrightText: 2024 yuzu Emulator Project
# SPDX-License-Identifier: MIT
git submodule sync
git submodule foreach --recursive git reset --hard
git submodule update --init --recursive