diff options
Diffstat (limited to 'src')
24 files changed, 240 insertions, 56 deletions
diff --git a/src/core/file_sys/patch_manager.cpp b/src/core/file_sys/patch_manager.cpp index 53b8b7ca0..7c0950bb0 100644 --- a/src/core/file_sys/patch_manager.cpp +++ b/src/core/file_sys/patch_manager.cpp | |||
| @@ -345,8 +345,10 @@ std::vector<Core::Memory::CheatEntry> PatchManager::CreateCheatList( | |||
| 345 | static void ApplyLayeredFS(VirtualFile& romfs, u64 title_id, ContentRecordType type, | 345 | static void ApplyLayeredFS(VirtualFile& romfs, u64 title_id, ContentRecordType type, |
| 346 | const Service::FileSystem::FileSystemController& fs_controller) { | 346 | const Service::FileSystem::FileSystemController& fs_controller) { |
| 347 | const auto load_dir = fs_controller.GetModificationLoadRoot(title_id); | 347 | const auto load_dir = fs_controller.GetModificationLoadRoot(title_id); |
| 348 | const auto sdmc_load_dir = fs_controller.GetSDMCModificationLoadRoot(title_id); | ||
| 348 | if ((type != ContentRecordType::Program && type != ContentRecordType::Data) || | 349 | if ((type != ContentRecordType::Program && type != ContentRecordType::Data) || |
| 349 | load_dir == nullptr || load_dir->GetSize() <= 0) { | 350 | ((load_dir == nullptr || load_dir->GetSize() <= 0) && |
| 351 | (sdmc_load_dir == nullptr || sdmc_load_dir->GetSize() <= 0))) { | ||
| 350 | return; | 352 | return; |
| 351 | } | 353 | } |
| 352 | 354 | ||
| @@ -356,7 +358,10 @@ static void ApplyLayeredFS(VirtualFile& romfs, u64 title_id, ContentRecordType t | |||
| 356 | } | 358 | } |
| 357 | 359 | ||
| 358 | const auto& disabled = Settings::values.disabled_addons[title_id]; | 360 | const auto& disabled = Settings::values.disabled_addons[title_id]; |
| 359 | auto patch_dirs = load_dir->GetSubdirectories(); | 361 | std::vector<VirtualDir> patch_dirs = load_dir->GetSubdirectories(); |
| 362 | if (std::find(disabled.cbegin(), disabled.cend(), "SDMC") == disabled.cend()) { | ||
| 363 | patch_dirs.push_back(sdmc_load_dir); | ||
| 364 | } | ||
| 360 | std::sort(patch_dirs.begin(), patch_dirs.end(), | 365 | std::sort(patch_dirs.begin(), patch_dirs.end(), |
| 361 | [](const VirtualDir& l, const VirtualDir& r) { return l->GetName() < r->GetName(); }); | 366 | [](const VirtualDir& l, const VirtualDir& r) { return l->GetName() < r->GetName(); }); |
| 362 | 367 | ||
| @@ -402,7 +407,7 @@ static void ApplyLayeredFS(VirtualFile& romfs, u64 title_id, ContentRecordType t | |||
| 402 | } | 407 | } |
| 403 | 408 | ||
| 404 | VirtualFile PatchManager::PatchRomFS(VirtualFile romfs, u64 ivfc_offset, ContentRecordType type, | 409 | VirtualFile PatchManager::PatchRomFS(VirtualFile romfs, u64 ivfc_offset, ContentRecordType type, |
| 405 | VirtualFile update_raw) const { | 410 | VirtualFile update_raw, bool apply_layeredfs) const { |
| 406 | const auto log_string = fmt::format("Patching RomFS for title_id={:016X}, type={:02X}", | 411 | const auto log_string = fmt::format("Patching RomFS for title_id={:016X}, type={:02X}", |
| 407 | title_id, static_cast<u8>(type)); | 412 | title_id, static_cast<u8>(type)); |
| 408 | 413 | ||
| @@ -442,7 +447,9 @@ VirtualFile PatchManager::PatchRomFS(VirtualFile romfs, u64 ivfc_offset, Content | |||
| 442 | } | 447 | } |
| 443 | 448 | ||
| 444 | // LayeredFS | 449 | // LayeredFS |
| 445 | ApplyLayeredFS(romfs, title_id, type, fs_controller); | 450 | if (apply_layeredfs) { |
| 451 | ApplyLayeredFS(romfs, title_id, type, fs_controller); | ||
| 452 | } | ||
| 446 | 453 | ||
| 447 | return romfs; | 454 | return romfs; |
| 448 | } | 455 | } |
| @@ -524,6 +531,15 @@ PatchManager::PatchVersionNames PatchManager::GetPatchVersionNames(VirtualFile u | |||
| 524 | } | 531 | } |
| 525 | } | 532 | } |
| 526 | 533 | ||
| 534 | // SDMC mod directory (RomFS LayeredFS) | ||
| 535 | const auto sdmc_mod_dir = fs_controller.GetSDMCModificationLoadRoot(title_id); | ||
| 536 | if (sdmc_mod_dir != nullptr && sdmc_mod_dir->GetSize() > 0 && | ||
| 537 | IsDirValidAndNonEmpty(FindSubdirectoryCaseless(sdmc_mod_dir, "romfs"))) { | ||
| 538 | const auto mod_disabled = | ||
| 539 | std::find(disabled.begin(), disabled.end(), "SDMC") != disabled.end(); | ||
| 540 | out.insert_or_assign(mod_disabled ? "[D] SDMC" : "SDMC", "LayeredFS"); | ||
| 541 | } | ||
| 542 | |||
| 527 | // DLC | 543 | // DLC |
| 528 | const auto dlc_entries = | 544 | const auto dlc_entries = |
| 529 | content_provider.ListEntriesFilter(TitleType::AOC, ContentRecordType::Data); | 545 | content_provider.ListEntriesFilter(TitleType::AOC, ContentRecordType::Data); |
diff --git a/src/core/file_sys/patch_manager.h b/src/core/file_sys/patch_manager.h index fb1853035..3be871f35 100644 --- a/src/core/file_sys/patch_manager.h +++ b/src/core/file_sys/patch_manager.h | |||
| @@ -64,7 +64,8 @@ public: | |||
| 64 | // - LayeredFS | 64 | // - LayeredFS |
| 65 | [[nodiscard]] VirtualFile PatchRomFS(VirtualFile base, u64 ivfc_offset, | 65 | [[nodiscard]] VirtualFile PatchRomFS(VirtualFile base, u64 ivfc_offset, |
| 66 | ContentRecordType type = ContentRecordType::Program, | 66 | ContentRecordType type = ContentRecordType::Program, |
| 67 | VirtualFile update_raw = nullptr) const; | 67 | VirtualFile update_raw = nullptr, |
| 68 | bool apply_layeredfs = true) const; | ||
| 68 | 69 | ||
| 69 | // Returns a vector of pairs between patch names and patch versions. | 70 | // Returns a vector of pairs between patch names and patch versions. |
| 70 | // i.e. Update 3.2.2 will return {"Update", "3.2.2"} | 71 | // i.e. Update 3.2.2 will return {"Update", "3.2.2"} |
diff --git a/src/core/file_sys/sdmc_factory.cpp b/src/core/file_sys/sdmc_factory.cpp index cb56d8f2d..e5c72cd4d 100644 --- a/src/core/file_sys/sdmc_factory.cpp +++ b/src/core/file_sys/sdmc_factory.cpp | |||
| @@ -12,23 +12,32 @@ namespace FileSys { | |||
| 12 | 12 | ||
| 13 | constexpr u64 SDMC_TOTAL_SIZE = 0x10000000000; // 1 TiB | 13 | constexpr u64 SDMC_TOTAL_SIZE = 0x10000000000; // 1 TiB |
| 14 | 14 | ||
| 15 | SDMCFactory::SDMCFactory(VirtualDir dir_) | 15 | SDMCFactory::SDMCFactory(VirtualDir sd_dir_, VirtualDir sd_mod_dir_) |
| 16 | : dir(std::move(dir_)), contents(std::make_unique<RegisteredCache>( | 16 | : sd_dir(std::move(sd_dir_)), sd_mod_dir(std::move(sd_mod_dir_)), |
| 17 | GetOrCreateDirectoryRelative(dir, "/Nintendo/Contents/registered"), | 17 | contents(std::make_unique<RegisteredCache>( |
| 18 | [](const VirtualFile& file, const NcaID& id) { | 18 | GetOrCreateDirectoryRelative(sd_dir, "/Nintendo/Contents/registered"), |
| 19 | return NAX{file, id}.GetDecrypted(); | 19 | [](const VirtualFile& file, const NcaID& id) { |
| 20 | })), | 20 | return NAX{file, id}.GetDecrypted(); |
| 21 | })), | ||
| 21 | placeholder(std::make_unique<PlaceholderCache>( | 22 | placeholder(std::make_unique<PlaceholderCache>( |
| 22 | GetOrCreateDirectoryRelative(dir, "/Nintendo/Contents/placehld"))) {} | 23 | GetOrCreateDirectoryRelative(sd_dir, "/Nintendo/Contents/placehld"))) {} |
| 23 | 24 | ||
| 24 | SDMCFactory::~SDMCFactory() = default; | 25 | SDMCFactory::~SDMCFactory() = default; |
| 25 | 26 | ||
| 26 | ResultVal<VirtualDir> SDMCFactory::Open() const { | 27 | ResultVal<VirtualDir> SDMCFactory::Open() const { |
| 27 | return MakeResult<VirtualDir>(dir); | 28 | return MakeResult<VirtualDir>(sd_dir); |
| 29 | } | ||
| 30 | |||
| 31 | VirtualDir SDMCFactory::GetSDMCModificationLoadRoot(u64 title_id) const { | ||
| 32 | // LayeredFS doesn't work on updates and title id-less homebrew | ||
| 33 | if (title_id == 0 || (title_id & 0xFFF) == 0x800) { | ||
| 34 | return nullptr; | ||
| 35 | } | ||
| 36 | return GetOrCreateDirectoryRelative(sd_mod_dir, fmt::format("/{:016X}", title_id)); | ||
| 28 | } | 37 | } |
| 29 | 38 | ||
| 30 | VirtualDir SDMCFactory::GetSDMCContentDirectory() const { | 39 | VirtualDir SDMCFactory::GetSDMCContentDirectory() const { |
| 31 | return GetOrCreateDirectoryRelative(dir, "/Nintendo/Contents"); | 40 | return GetOrCreateDirectoryRelative(sd_dir, "/Nintendo/Contents"); |
| 32 | } | 41 | } |
| 33 | 42 | ||
| 34 | RegisteredCache* SDMCFactory::GetSDMCContents() const { | 43 | RegisteredCache* SDMCFactory::GetSDMCContents() const { |
| @@ -40,11 +49,11 @@ PlaceholderCache* SDMCFactory::GetSDMCPlaceholder() const { | |||
| 40 | } | 49 | } |
| 41 | 50 | ||
| 42 | VirtualDir SDMCFactory::GetImageDirectory() const { | 51 | VirtualDir SDMCFactory::GetImageDirectory() const { |
| 43 | return GetOrCreateDirectoryRelative(dir, "/Nintendo/Album"); | 52 | return GetOrCreateDirectoryRelative(sd_dir, "/Nintendo/Album"); |
| 44 | } | 53 | } |
| 45 | 54 | ||
| 46 | u64 SDMCFactory::GetSDMCFreeSpace() const { | 55 | u64 SDMCFactory::GetSDMCFreeSpace() const { |
| 47 | return GetSDMCTotalSpace() - dir->GetSize(); | 56 | return GetSDMCTotalSpace() - sd_dir->GetSize(); |
| 48 | } | 57 | } |
| 49 | 58 | ||
| 50 | u64 SDMCFactory::GetSDMCTotalSpace() const { | 59 | u64 SDMCFactory::GetSDMCTotalSpace() const { |
diff --git a/src/core/file_sys/sdmc_factory.h b/src/core/file_sys/sdmc_factory.h index 2bb92ba93..3a3d11f3a 100644 --- a/src/core/file_sys/sdmc_factory.h +++ b/src/core/file_sys/sdmc_factory.h | |||
| @@ -16,11 +16,12 @@ class PlaceholderCache; | |||
| 16 | /// File system interface to the SDCard archive | 16 | /// File system interface to the SDCard archive |
| 17 | class SDMCFactory { | 17 | class SDMCFactory { |
| 18 | public: | 18 | public: |
| 19 | explicit SDMCFactory(VirtualDir dir); | 19 | explicit SDMCFactory(VirtualDir sd_dir_, VirtualDir sd_mod_dir_); |
| 20 | ~SDMCFactory(); | 20 | ~SDMCFactory(); |
| 21 | 21 | ||
| 22 | ResultVal<VirtualDir> Open() const; | 22 | ResultVal<VirtualDir> Open() const; |
| 23 | 23 | ||
| 24 | VirtualDir GetSDMCModificationLoadRoot(u64 title_id) const; | ||
| 24 | VirtualDir GetSDMCContentDirectory() const; | 25 | VirtualDir GetSDMCContentDirectory() const; |
| 25 | 26 | ||
| 26 | RegisteredCache* GetSDMCContents() const; | 27 | RegisteredCache* GetSDMCContents() const; |
| @@ -32,7 +33,8 @@ public: | |||
| 32 | u64 GetSDMCTotalSpace() const; | 33 | u64 GetSDMCTotalSpace() const; |
| 33 | 34 | ||
| 34 | private: | 35 | private: |
| 35 | VirtualDir dir; | 36 | VirtualDir sd_dir; |
| 37 | VirtualDir sd_mod_dir; | ||
| 36 | 38 | ||
| 37 | std::unique_ptr<RegisteredCache> contents; | 39 | std::unique_ptr<RegisteredCache> contents; |
| 38 | std::unique_ptr<PlaceholderCache> placeholder; | 40 | std::unique_ptr<PlaceholderCache> placeholder; |
diff --git a/src/core/hle/service/filesystem/filesystem.cpp b/src/core/hle/service/filesystem/filesystem.cpp index 3c16fe6c7..4a9b13e45 100644 --- a/src/core/hle/service/filesystem/filesystem.cpp +++ b/src/core/hle/service/filesystem/filesystem.cpp | |||
| @@ -703,6 +703,16 @@ FileSys::VirtualDir FileSystemController::GetModificationLoadRoot(u64 title_id) | |||
| 703 | return bis_factory->GetModificationLoadRoot(title_id); | 703 | return bis_factory->GetModificationLoadRoot(title_id); |
| 704 | } | 704 | } |
| 705 | 705 | ||
| 706 | FileSys::VirtualDir FileSystemController::GetSDMCModificationLoadRoot(u64 title_id) const { | ||
| 707 | LOG_TRACE(Service_FS, "Opening SDMC mod load root for tid={:016X}", title_id); | ||
| 708 | |||
| 709 | if (sdmc_factory == nullptr) { | ||
| 710 | return nullptr; | ||
| 711 | } | ||
| 712 | |||
| 713 | return sdmc_factory->GetSDMCModificationLoadRoot(title_id); | ||
| 714 | } | ||
| 715 | |||
| 706 | FileSys::VirtualDir FileSystemController::GetModificationDumpRoot(u64 title_id) const { | 716 | FileSys::VirtualDir FileSystemController::GetModificationDumpRoot(u64 title_id) const { |
| 707 | LOG_TRACE(Service_FS, "Opening mod dump root for tid={:016X}", title_id); | 717 | LOG_TRACE(Service_FS, "Opening mod dump root for tid={:016X}", title_id); |
| 708 | 718 | ||
| @@ -733,20 +743,23 @@ void FileSystemController::CreateFactories(FileSys::VfsFilesystem& vfs, bool ove | |||
| 733 | } | 743 | } |
| 734 | 744 | ||
| 735 | using YuzuPath = Common::FS::YuzuPath; | 745 | using YuzuPath = Common::FS::YuzuPath; |
| 746 | const auto sdmc_dir_path = Common::FS::GetYuzuPath(YuzuPath::SDMCDir); | ||
| 747 | const auto sdmc_load_dir_path = sdmc_dir_path / "atmosphere/contents"; | ||
| 736 | const auto rw_mode = FileSys::Mode::ReadWrite; | 748 | const auto rw_mode = FileSys::Mode::ReadWrite; |
| 737 | 749 | ||
| 738 | auto nand_directory = | 750 | auto nand_directory = |
| 739 | vfs.OpenDirectory(Common::FS::GetYuzuPathString(YuzuPath::NANDDir), rw_mode); | 751 | vfs.OpenDirectory(Common::FS::GetYuzuPathString(YuzuPath::NANDDir), rw_mode); |
| 740 | auto sd_directory = | 752 | auto sd_directory = vfs.OpenDirectory(Common::FS::PathToUTF8String(sdmc_dir_path), rw_mode); |
| 741 | vfs.OpenDirectory(Common::FS::GetYuzuPathString(YuzuPath::SDMCDir), rw_mode); | ||
| 742 | auto load_directory = | 753 | auto load_directory = |
| 743 | vfs.OpenDirectory(Common::FS::GetYuzuPathString(YuzuPath::LoadDir), FileSys::Mode::Read); | 754 | vfs.OpenDirectory(Common::FS::GetYuzuPathString(YuzuPath::LoadDir), FileSys::Mode::Read); |
| 755 | auto sd_load_directory = | ||
| 756 | vfs.OpenDirectory(Common::FS::PathToUTF8String(sdmc_load_dir_path), FileSys::Mode::Read); | ||
| 744 | auto dump_directory = | 757 | auto dump_directory = |
| 745 | vfs.OpenDirectory(Common::FS::GetYuzuPathString(YuzuPath::DumpDir), rw_mode); | 758 | vfs.OpenDirectory(Common::FS::GetYuzuPathString(YuzuPath::DumpDir), rw_mode); |
| 746 | 759 | ||
| 747 | if (bis_factory == nullptr) { | 760 | if (bis_factory == nullptr) { |
| 748 | bis_factory = | 761 | bis_factory = std::make_unique<FileSys::BISFactory>( |
| 749 | std::make_unique<FileSys::BISFactory>(nand_directory, load_directory, dump_directory); | 762 | nand_directory, std::move(load_directory), std::move(dump_directory)); |
| 750 | system.RegisterContentProvider(FileSys::ContentProviderUnionSlot::SysNAND, | 763 | system.RegisterContentProvider(FileSys::ContentProviderUnionSlot::SysNAND, |
| 751 | bis_factory->GetSystemNANDContents()); | 764 | bis_factory->GetSystemNANDContents()); |
| 752 | system.RegisterContentProvider(FileSys::ContentProviderUnionSlot::UserNAND, | 765 | system.RegisterContentProvider(FileSys::ContentProviderUnionSlot::UserNAND, |
| @@ -759,7 +772,8 @@ void FileSystemController::CreateFactories(FileSys::VfsFilesystem& vfs, bool ove | |||
| 759 | } | 772 | } |
| 760 | 773 | ||
| 761 | if (sdmc_factory == nullptr) { | 774 | if (sdmc_factory == nullptr) { |
| 762 | sdmc_factory = std::make_unique<FileSys::SDMCFactory>(std::move(sd_directory)); | 775 | sdmc_factory = std::make_unique<FileSys::SDMCFactory>(std::move(sd_directory), |
| 776 | std::move(sd_load_directory)); | ||
| 763 | system.RegisterContentProvider(FileSys::ContentProviderUnionSlot::SDMC, | 777 | system.RegisterContentProvider(FileSys::ContentProviderUnionSlot::SDMC, |
| 764 | sdmc_factory->GetSDMCContents()); | 778 | sdmc_factory->GetSDMCContents()); |
| 765 | } | 779 | } |
diff --git a/src/core/hle/service/filesystem/filesystem.h b/src/core/hle/service/filesystem/filesystem.h index b6b1b9220..d387af3cb 100644 --- a/src/core/hle/service/filesystem/filesystem.h +++ b/src/core/hle/service/filesystem/filesystem.h | |||
| @@ -115,6 +115,7 @@ public: | |||
| 115 | FileSys::VirtualDir GetContentDirectory(ContentStorageId id) const; | 115 | FileSys::VirtualDir GetContentDirectory(ContentStorageId id) const; |
| 116 | FileSys::VirtualDir GetImageDirectory(ImageDirectoryId id) const; | 116 | FileSys::VirtualDir GetImageDirectory(ImageDirectoryId id) const; |
| 117 | 117 | ||
| 118 | FileSys::VirtualDir GetSDMCModificationLoadRoot(u64 title_id) const; | ||
| 118 | FileSys::VirtualDir GetModificationLoadRoot(u64 title_id) const; | 119 | FileSys::VirtualDir GetModificationLoadRoot(u64 title_id) const; |
| 119 | FileSys::VirtualDir GetModificationDumpRoot(u64 title_id) const; | 120 | FileSys::VirtualDir GetModificationDumpRoot(u64 title_id) const; |
| 120 | 121 | ||
diff --git a/src/video_core/CMakeLists.txt b/src/video_core/CMakeLists.txt index f9454bbaa..e31eb30c0 100644 --- a/src/video_core/CMakeLists.txt +++ b/src/video_core/CMakeLists.txt | |||
| @@ -293,6 +293,7 @@ endif() | |||
| 293 | if (MSVC) | 293 | if (MSVC) |
| 294 | target_compile_options(video_core PRIVATE | 294 | target_compile_options(video_core PRIVATE |
| 295 | /we4267 # 'var' : conversion from 'size_t' to 'type', possible loss of data | 295 | /we4267 # 'var' : conversion from 'size_t' to 'type', possible loss of data |
| 296 | /we4244 # 'var' : conversion from integer to 'type', possible loss of data | ||
| 296 | /we4456 # Declaration of 'identifier' hides previous local declaration | 297 | /we4456 # Declaration of 'identifier' hides previous local declaration |
| 297 | /we4457 # Declaration of 'identifier' hides function parameter | 298 | /we4457 # Declaration of 'identifier' hides function parameter |
| 298 | /we4458 # Declaration of 'identifier' hides class member | 299 | /we4458 # Declaration of 'identifier' hides class member |
diff --git a/src/video_core/buffer_cache/buffer_cache.h b/src/video_core/buffer_cache/buffer_cache.h index 9d726a6fb..cad7f902d 100644 --- a/src/video_core/buffer_cache/buffer_cache.h +++ b/src/video_core/buffer_cache/buffer_cache.h | |||
| @@ -99,7 +99,7 @@ class BufferCache { | |||
| 99 | }; | 99 | }; |
| 100 | 100 | ||
| 101 | public: | 101 | public: |
| 102 | static constexpr u32 DEFAULT_SKIP_CACHE_SIZE = 4_KiB; | 102 | static constexpr u32 DEFAULT_SKIP_CACHE_SIZE = static_cast<u32>(4_KiB); |
| 103 | 103 | ||
| 104 | explicit BufferCache(VideoCore::RasterizerInterface& rasterizer_, | 104 | explicit BufferCache(VideoCore::RasterizerInterface& rasterizer_, |
| 105 | Tegra::Engines::Maxwell3D& maxwell3d_, | 105 | Tegra::Engines::Maxwell3D& maxwell3d_, |
| @@ -109,8 +109,6 @@ public: | |||
| 109 | 109 | ||
| 110 | void TickFrame(); | 110 | void TickFrame(); |
| 111 | 111 | ||
| 112 | void RunGarbageCollector(); | ||
| 113 | |||
| 114 | void WriteMemory(VAddr cpu_addr, u64 size); | 112 | void WriteMemory(VAddr cpu_addr, u64 size); |
| 115 | 113 | ||
| 116 | void CachedWriteMemory(VAddr cpu_addr, u64 size); | 114 | void CachedWriteMemory(VAddr cpu_addr, u64 size); |
| @@ -197,6 +195,8 @@ private: | |||
| 197 | ((cpu_addr + size) & ~Core::Memory::PAGE_MASK); | 195 | ((cpu_addr + size) & ~Core::Memory::PAGE_MASK); |
| 198 | } | 196 | } |
| 199 | 197 | ||
| 198 | void RunGarbageCollector(); | ||
| 199 | |||
| 200 | void BindHostIndexBuffer(); | 200 | void BindHostIndexBuffer(); |
| 201 | 201 | ||
| 202 | void BindHostVertexBuffers(); | 202 | void BindHostVertexBuffers(); |
| @@ -416,8 +416,9 @@ void BufferCache<P>::CachedWriteMemory(VAddr cpu_addr, u64 size) { | |||
| 416 | 416 | ||
| 417 | template <class P> | 417 | template <class P> |
| 418 | void BufferCache<P>::DownloadMemory(VAddr cpu_addr, u64 size) { | 418 | void BufferCache<P>::DownloadMemory(VAddr cpu_addr, u64 size) { |
| 419 | ForEachBufferInRange(cpu_addr, size, | 419 | ForEachBufferInRange(cpu_addr, size, [&](BufferId, Buffer& buffer) { |
| 420 | [&](BufferId, Buffer& buffer) { DownloadBufferMemory(buffer); }); | 420 | DownloadBufferMemory(buffer, cpu_addr, size); |
| 421 | }); | ||
| 421 | } | 422 | } |
| 422 | 423 | ||
| 423 | template <class P> | 424 | template <class P> |
diff --git a/src/video_core/command_classes/codecs/codec.h b/src/video_core/command_classes/codecs/codec.h index 8a2a6c360..3e135a2a6 100644 --- a/src/video_core/command_classes/codecs/codec.h +++ b/src/video_core/command_classes/codecs/codec.h | |||
| @@ -14,10 +14,18 @@ extern "C" { | |||
| 14 | #pragma GCC diagnostic push | 14 | #pragma GCC diagnostic push |
| 15 | #pragma GCC diagnostic ignored "-Wconversion" | 15 | #pragma GCC diagnostic ignored "-Wconversion" |
| 16 | #endif | 16 | #endif |
| 17 | #ifdef _MSC_VER | ||
| 18 | #pragma warning(push) | ||
| 19 | #pragma warning(disable : 4242) // conversion from 'type' to 'type', possible loss of data | ||
| 20 | #pragma warning(disable : 4244) // conversion from 'type' to 'type', possible loss of data | ||
| 21 | #endif | ||
| 17 | #include <libavcodec/avcodec.h> | 22 | #include <libavcodec/avcodec.h> |
| 18 | #if defined(__GNUC__) || defined(__clang__) | 23 | #if defined(__GNUC__) || defined(__clang__) |
| 19 | #pragma GCC diagnostic pop | 24 | #pragma GCC diagnostic pop |
| 20 | #endif | 25 | #endif |
| 26 | #ifdef _MSC_VER | ||
| 27 | #pragma warning(pop) | ||
| 28 | #endif | ||
| 21 | } | 29 | } |
| 22 | 30 | ||
| 23 | namespace Tegra { | 31 | namespace Tegra { |
diff --git a/src/video_core/command_classes/vic.cpp b/src/video_core/command_classes/vic.cpp index 0a8b82f2b..5faf8c0f1 100644 --- a/src/video_core/command_classes/vic.cpp +++ b/src/video_core/command_classes/vic.cpp | |||
| @@ -3,7 +3,28 @@ | |||
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include <array> | 5 | #include <array> |
| 6 | |||
| 7 | extern "C" { | ||
| 8 | #if defined(__GNUC__) || defined(__clang__) | ||
| 9 | #pragma GCC diagnostic push | ||
| 10 | #pragma GCC diagnostic ignored "-Wconversion" | ||
| 11 | #endif | ||
| 12 | #ifdef _MSC_VER | ||
| 13 | #pragma warning(disable : 4244) // conversion from 'type' to 'type', possible loss of data | ||
| 14 | #pragma warning(push) | ||
| 15 | #endif | ||
| 16 | #include <libswscale/swscale.h> | ||
| 17 | #if defined(__GNUC__) || defined(__clang__) | ||
| 18 | #pragma GCC diagnostic pop | ||
| 19 | #endif | ||
| 20 | #ifdef _MSC_VER | ||
| 21 | #pragma warning(pop) | ||
| 22 | #endif | ||
| 23 | } | ||
| 24 | |||
| 6 | #include "common/assert.h" | 25 | #include "common/assert.h" |
| 26 | #include "common/logging/log.h" | ||
| 27 | |||
| 7 | #include "video_core/command_classes/nvdec.h" | 28 | #include "video_core/command_classes/nvdec.h" |
| 8 | #include "video_core/command_classes/vic.h" | 29 | #include "video_core/command_classes/vic.h" |
| 9 | #include "video_core/engines/maxwell_3d.h" | 30 | #include "video_core/engines/maxwell_3d.h" |
| @@ -11,10 +32,6 @@ | |||
| 11 | #include "video_core/memory_manager.h" | 32 | #include "video_core/memory_manager.h" |
| 12 | #include "video_core/textures/decoders.h" | 33 | #include "video_core/textures/decoders.h" |
| 13 | 34 | ||
| 14 | extern "C" { | ||
| 15 | #include <libswscale/swscale.h> | ||
| 16 | } | ||
| 17 | |||
| 18 | namespace Tegra { | 35 | namespace Tegra { |
| 19 | 36 | ||
| 20 | Vic::Vic(GPU& gpu_, std::shared_ptr<Nvdec> nvdec_processor_) | 37 | Vic::Vic(GPU& gpu_, std::shared_ptr<Nvdec> nvdec_processor_) |
diff --git a/src/video_core/host_shaders/CMakeLists.txt b/src/video_core/host_shaders/CMakeLists.txt index 2208e1922..c9cff7450 100644 --- a/src/video_core/host_shaders/CMakeLists.txt +++ b/src/video_core/host_shaders/CMakeLists.txt | |||
| @@ -18,7 +18,10 @@ set(SHADER_FILES | |||
| 18 | vulkan_uint8.comp | 18 | vulkan_uint8.comp |
| 19 | ) | 19 | ) |
| 20 | 20 | ||
| 21 | find_program(GLSLANGVALIDATOR "glslangValidator" REQUIRED) | 21 | find_program(GLSLANGVALIDATOR "glslangValidator") |
| 22 | if ("${GLSLANGVALIDATOR}" STREQUAL "GLSLANGVALIDATOR-NOTFOUND") | ||
| 23 | message(FATAL_ERROR "Required program `glslangValidator` not found.") | ||
| 24 | endif() | ||
| 22 | 25 | ||
| 23 | set(GLSL_FLAGS "") | 26 | set(GLSL_FLAGS "") |
| 24 | set(QUIET_FLAG "--quiet") | 27 | set(QUIET_FLAG "--quiet") |
diff --git a/src/video_core/renderer_base.h b/src/video_core/renderer_base.h index 320ee8d30..63d8ad42a 100644 --- a/src/video_core/renderer_base.h +++ b/src/video_core/renderer_base.h | |||
| @@ -42,6 +42,8 @@ public: | |||
| 42 | 42 | ||
| 43 | [[nodiscard]] virtual RasterizerInterface* ReadRasterizer() = 0; | 43 | [[nodiscard]] virtual RasterizerInterface* ReadRasterizer() = 0; |
| 44 | 44 | ||
| 45 | [[nodiscard]] virtual std::string GetDeviceVendor() const = 0; | ||
| 46 | |||
| 45 | // Getter/setter functions: | 47 | // Getter/setter functions: |
| 46 | // ------------------------ | 48 | // ------------------------ |
| 47 | 49 | ||
diff --git a/src/video_core/renderer_opengl/gl_device.cpp b/src/video_core/renderer_opengl/gl_device.cpp index 3f4532ca7..3b00614e7 100644 --- a/src/video_core/renderer_opengl/gl_device.cpp +++ b/src/video_core/renderer_opengl/gl_device.cpp | |||
| @@ -202,13 +202,13 @@ Device::Device() { | |||
| 202 | LOG_ERROR(Render_OpenGL, "OpenGL 4.6 is not available"); | 202 | LOG_ERROR(Render_OpenGL, "OpenGL 4.6 is not available"); |
| 203 | throw std::runtime_error{"Insufficient version"}; | 203 | throw std::runtime_error{"Insufficient version"}; |
| 204 | } | 204 | } |
| 205 | const std::string_view vendor = reinterpret_cast<const char*>(glGetString(GL_VENDOR)); | 205 | vendor_name = reinterpret_cast<const char*>(glGetString(GL_VENDOR)); |
| 206 | const std::string_view version = reinterpret_cast<const char*>(glGetString(GL_VERSION)); | 206 | const std::string_view version = reinterpret_cast<const char*>(glGetString(GL_VERSION)); |
| 207 | const std::vector extensions = GetExtensions(); | 207 | const std::vector extensions = GetExtensions(); |
| 208 | 208 | ||
| 209 | const bool is_nvidia = vendor == "NVIDIA Corporation"; | 209 | const bool is_nvidia = vendor_name == "NVIDIA Corporation"; |
| 210 | const bool is_amd = vendor == "ATI Technologies Inc."; | 210 | const bool is_amd = vendor_name == "ATI Technologies Inc."; |
| 211 | const bool is_intel = vendor == "Intel"; | 211 | const bool is_intel = vendor_name == "Intel"; |
| 212 | 212 | ||
| 213 | #ifdef __unix__ | 213 | #ifdef __unix__ |
| 214 | const bool is_linux = true; | 214 | const bool is_linux = true; |
| @@ -275,6 +275,56 @@ Device::Device() { | |||
| 275 | } | 275 | } |
| 276 | } | 276 | } |
| 277 | 277 | ||
| 278 | std::string Device::GetVendorName() const { | ||
| 279 | if (vendor_name == "NVIDIA Corporation") { | ||
| 280 | return "NVIDIA"; | ||
| 281 | } | ||
| 282 | if (vendor_name == "ATI Technologies Inc.") { | ||
| 283 | return "AMD"; | ||
| 284 | } | ||
| 285 | if (vendor_name == "Intel") { | ||
| 286 | // For Mesa, `Intel` is an overloaded vendor string that could mean crocus or iris. | ||
| 287 | // Simply return `INTEL` for those as well as the Windows driver. | ||
| 288 | return "INTEL"; | ||
| 289 | } | ||
| 290 | if (vendor_name == "Intel Open Source Technology Center") { | ||
| 291 | return "I965"; | ||
| 292 | } | ||
| 293 | if (vendor_name == "Mesa Project") { | ||
| 294 | return "I915"; | ||
| 295 | } | ||
| 296 | if (vendor_name == "Mesa/X.org") { | ||
| 297 | // This vendor string is overloaded between llvmpipe, softpipe, and virgl, so just return | ||
| 298 | // MESA instead of one of those driver names. | ||
| 299 | return "MESA"; | ||
| 300 | } | ||
| 301 | if (vendor_name == "AMD") { | ||
| 302 | return "RADEONSI"; | ||
| 303 | } | ||
| 304 | if (vendor_name == "nouveau") { | ||
| 305 | return "NOUVEAU"; | ||
| 306 | } | ||
| 307 | if (vendor_name == "X.Org") { | ||
| 308 | return "R600"; | ||
| 309 | } | ||
| 310 | if (vendor_name == "Collabora Ltd") { | ||
| 311 | return "ZINK"; | ||
| 312 | } | ||
| 313 | if (vendor_name == "Intel Corporation") { | ||
| 314 | return "OPENSWR"; | ||
| 315 | } | ||
| 316 | if (vendor_name == "Microsoft Corporation") { | ||
| 317 | return "D3D12"; | ||
| 318 | } | ||
| 319 | if (vendor_name == "NVIDIA") { | ||
| 320 | // Mesa's tegra driver reports `NVIDIA`. Only present in this list because the default | ||
| 321 | // strategy would have returned `NVIDIA` here for this driver, the same result as the | ||
| 322 | // proprietary driver. | ||
| 323 | return "TEGRA"; | ||
| 324 | } | ||
| 325 | return vendor_name; | ||
| 326 | } | ||
| 327 | |||
| 278 | Device::Device(std::nullptr_t) { | 328 | Device::Device(std::nullptr_t) { |
| 279 | max_uniform_buffers.fill(std::numeric_limits<u32>::max()); | 329 | max_uniform_buffers.fill(std::numeric_limits<u32>::max()); |
| 280 | uniform_buffer_alignment = 4; | 330 | uniform_buffer_alignment = 4; |
diff --git a/src/video_core/renderer_opengl/gl_device.h b/src/video_core/renderer_opengl/gl_device.h index f24bd0c7b..2c2b13767 100644 --- a/src/video_core/renderer_opengl/gl_device.h +++ b/src/video_core/renderer_opengl/gl_device.h | |||
| @@ -22,6 +22,8 @@ public: | |||
| 22 | explicit Device(); | 22 | explicit Device(); |
| 23 | explicit Device(std::nullptr_t); | 23 | explicit Device(std::nullptr_t); |
| 24 | 24 | ||
| 25 | [[nodiscard]] std::string GetVendorName() const; | ||
| 26 | |||
| 25 | u32 GetMaxUniformBuffers(Tegra::Engines::ShaderType shader_type) const noexcept { | 27 | u32 GetMaxUniformBuffers(Tegra::Engines::ShaderType shader_type) const noexcept { |
| 26 | return max_uniform_buffers[static_cast<std::size_t>(shader_type)]; | 28 | return max_uniform_buffers[static_cast<std::size_t>(shader_type)]; |
| 27 | } | 29 | } |
| @@ -130,6 +132,7 @@ private: | |||
| 130 | static bool TestVariableAoffi(); | 132 | static bool TestVariableAoffi(); |
| 131 | static bool TestPreciseBug(); | 133 | static bool TestPreciseBug(); |
| 132 | 134 | ||
| 135 | std::string vendor_name; | ||
| 133 | std::array<u32, Tegra::Engines::MaxShaderTypes> max_uniform_buffers{}; | 136 | std::array<u32, Tegra::Engines::MaxShaderTypes> max_uniform_buffers{}; |
| 134 | std::array<BaseBindings, Tegra::Engines::MaxShaderTypes> base_bindings{}; | 137 | std::array<BaseBindings, Tegra::Engines::MaxShaderTypes> base_bindings{}; |
| 135 | size_t uniform_buffer_alignment{}; | 138 | size_t uniform_buffer_alignment{}; |
diff --git a/src/video_core/renderer_opengl/renderer_opengl.h b/src/video_core/renderer_opengl/renderer_opengl.h index cc19a110f..0b66f8332 100644 --- a/src/video_core/renderer_opengl/renderer_opengl.h +++ b/src/video_core/renderer_opengl/renderer_opengl.h | |||
| @@ -70,6 +70,10 @@ public: | |||
| 70 | return &rasterizer; | 70 | return &rasterizer; |
| 71 | } | 71 | } |
| 72 | 72 | ||
| 73 | [[nodiscard]] std::string GetDeviceVendor() const override { | ||
| 74 | return device.GetVendorName(); | ||
| 75 | } | ||
| 76 | |||
| 73 | private: | 77 | private: |
| 74 | /// Initializes the OpenGL state and creates persistent objects. | 78 | /// Initializes the OpenGL state and creates persistent objects. |
| 75 | void InitOpenGLObjects(); | 79 | void InitOpenGLObjects(); |
diff --git a/src/video_core/renderer_vulkan/renderer_vulkan.h b/src/video_core/renderer_vulkan/renderer_vulkan.h index 72071316c..d7d17e110 100644 --- a/src/video_core/renderer_vulkan/renderer_vulkan.h +++ b/src/video_core/renderer_vulkan/renderer_vulkan.h | |||
| @@ -47,6 +47,10 @@ public: | |||
| 47 | return &rasterizer; | 47 | return &rasterizer; |
| 48 | } | 48 | } |
| 49 | 49 | ||
| 50 | [[nodiscard]] std::string GetDeviceVendor() const override { | ||
| 51 | return device.GetDriverName(); | ||
| 52 | } | ||
| 53 | |||
| 50 | private: | 54 | private: |
| 51 | void Report() const; | 55 | void Report() const; |
| 52 | 56 | ||
diff --git a/src/video_core/renderer_vulkan/vk_buffer_cache.cpp b/src/video_core/renderer_vulkan/vk_buffer_cache.cpp index 8cb65e588..0df4e1a1c 100644 --- a/src/video_core/renderer_vulkan/vk_buffer_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_buffer_cache.cpp | |||
| @@ -55,8 +55,9 @@ size_t BytesPerIndex(VkIndexType index_type) { | |||
| 55 | template <typename T> | 55 | template <typename T> |
| 56 | std::array<T, 6> MakeQuadIndices(u32 quad, u32 first) { | 56 | std::array<T, 6> MakeQuadIndices(u32 quad, u32 first) { |
| 57 | std::array<T, 6> indices{0, 1, 2, 0, 2, 3}; | 57 | std::array<T, 6> indices{0, 1, 2, 0, 2, 3}; |
| 58 | std::ranges::transform(indices, indices.begin(), | 58 | for (T& index : indices) { |
| 59 | [quad, first](u32 index) { return first + index + quad * 4; }); | 59 | index = static_cast<T>(first + index + quad * 4); |
| 60 | } | ||
| 60 | return indices; | 61 | return indices; |
| 61 | } | 62 | } |
| 62 | } // Anonymous namespace | 63 | } // Anonymous namespace |
diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h index 84530a179..c7cfd02b6 100644 --- a/src/video_core/texture_cache/texture_cache.h +++ b/src/video_core/texture_cache/texture_cache.h | |||
| @@ -110,9 +110,6 @@ public: | |||
| 110 | /// Notify the cache that a new frame has been queued | 110 | /// Notify the cache that a new frame has been queued |
| 111 | void TickFrame(); | 111 | void TickFrame(); |
| 112 | 112 | ||
| 113 | /// Runs the Garbage Collector. | ||
| 114 | void RunGarbageCollector(); | ||
| 115 | |||
| 116 | /// Return a constant reference to the given image view id | 113 | /// Return a constant reference to the given image view id |
| 117 | [[nodiscard]] const ImageView& GetImageView(ImageViewId id) const noexcept; | 114 | [[nodiscard]] const ImageView& GetImageView(ImageViewId id) const noexcept; |
| 118 | 115 | ||
| @@ -207,6 +204,9 @@ private: | |||
| 207 | } | 204 | } |
| 208 | } | 205 | } |
| 209 | 206 | ||
| 207 | /// Runs the Garbage Collector. | ||
| 208 | void RunGarbageCollector(); | ||
| 209 | |||
| 210 | /// Fills image_view_ids in the image views in indices | 210 | /// Fills image_view_ids in the image views in indices |
| 211 | void FillImageViews(DescriptorTable<TICEntry>& table, | 211 | void FillImageViews(DescriptorTable<TICEntry>& table, |
| 212 | std::span<ImageViewId> cached_image_view_ids, std::span<const u32> indices, | 212 | std::span<ImageViewId> cached_image_view_ids, std::span<const u32> indices, |
diff --git a/src/video_core/vulkan_common/vulkan_device.cpp b/src/video_core/vulkan_common/vulkan_device.cpp index 23814afd2..f214510da 100644 --- a/src/video_core/vulkan_common/vulkan_device.cpp +++ b/src/video_core/vulkan_common/vulkan_device.cpp | |||
| @@ -532,6 +532,27 @@ bool Device::IsFormatSupported(VkFormat wanted_format, VkFormatFeatureFlags want | |||
| 532 | return (supported_usage & wanted_usage) == wanted_usage; | 532 | return (supported_usage & wanted_usage) == wanted_usage; |
| 533 | } | 533 | } |
| 534 | 534 | ||
| 535 | std::string Device::GetDriverName() const { | ||
| 536 | switch (driver_id) { | ||
| 537 | case VK_DRIVER_ID_AMD_PROPRIETARY: | ||
| 538 | return "AMD"; | ||
| 539 | case VK_DRIVER_ID_AMD_OPEN_SOURCE: | ||
| 540 | return "AMDVLK"; | ||
| 541 | case VK_DRIVER_ID_MESA_RADV: | ||
| 542 | return "RADV"; | ||
| 543 | case VK_DRIVER_ID_NVIDIA_PROPRIETARY: | ||
| 544 | return "NVIDIA"; | ||
| 545 | case VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS: | ||
| 546 | return "INTEL"; | ||
| 547 | case VK_DRIVER_ID_INTEL_OPEN_SOURCE_MESA: | ||
| 548 | return "ANV"; | ||
| 549 | case VK_DRIVER_ID_MESA_LLVMPIPE: | ||
| 550 | return "LAVAPIPE"; | ||
| 551 | default: | ||
| 552 | return vendor_name; | ||
| 553 | } | ||
| 554 | } | ||
| 555 | |||
| 535 | void Device::CheckSuitability(bool requires_swapchain) const { | 556 | void Device::CheckSuitability(bool requires_swapchain) const { |
| 536 | std::bitset<REQUIRED_EXTENSIONS.size()> available_extensions; | 557 | std::bitset<REQUIRED_EXTENSIONS.size()> available_extensions; |
| 537 | bool has_swapchain = false; | 558 | bool has_swapchain = false; |
diff --git a/src/video_core/vulkan_common/vulkan_device.h b/src/video_core/vulkan_common/vulkan_device.h index 88b298196..96c0f8c60 100644 --- a/src/video_core/vulkan_common/vulkan_device.h +++ b/src/video_core/vulkan_common/vulkan_device.h | |||
| @@ -45,6 +45,9 @@ public: | |||
| 45 | /// Reports a shader to Nsight Aftermath. | 45 | /// Reports a shader to Nsight Aftermath. |
| 46 | void SaveShader(const std::vector<u32>& spirv) const; | 46 | void SaveShader(const std::vector<u32>& spirv) const; |
| 47 | 47 | ||
| 48 | /// Returns the name of the VkDriverId reported from Vulkan. | ||
| 49 | std::string GetDriverName() const; | ||
| 50 | |||
| 48 | /// Returns the dispatch loader with direct function pointers of the device. | 51 | /// Returns the dispatch loader with direct function pointers of the device. |
| 49 | const vk::DeviceDispatch& GetDispatchLoader() const { | 52 | const vk::DeviceDispatch& GetDispatchLoader() const { |
| 50 | return dld; | 53 | return dld; |
diff --git a/src/yuzu/game_list.cpp b/src/yuzu/game_list.cpp index da956c99b..e44907be8 100644 --- a/src/yuzu/game_list.cpp +++ b/src/yuzu/game_list.cpp | |||
| @@ -521,7 +521,9 @@ void GameList::AddGamePopup(QMenu& context_menu, u64 program_id, const std::stri | |||
| 521 | QAction* remove_custom_config = remove_menu->addAction(tr("Remove Custom Configuration")); | 521 | QAction* remove_custom_config = remove_menu->addAction(tr("Remove Custom Configuration")); |
| 522 | remove_menu->addSeparator(); | 522 | remove_menu->addSeparator(); |
| 523 | QAction* remove_all_content = remove_menu->addAction(tr("Remove All Installed Contents")); | 523 | QAction* remove_all_content = remove_menu->addAction(tr("Remove All Installed Contents")); |
| 524 | QAction* dump_romfs = context_menu.addAction(tr("Dump RomFS")); | 524 | QMenu* dump_romfs_menu = context_menu.addMenu(tr("Dump RomFS")); |
| 525 | QAction* dump_romfs = dump_romfs_menu->addAction(tr("Dump RomFS")); | ||
| 526 | QAction* dump_romfs_sdmc = dump_romfs_menu->addAction(tr("Dump RomFS to SDMC")); | ||
| 525 | QAction* copy_tid = context_menu.addAction(tr("Copy Title ID to Clipboard")); | 527 | QAction* copy_tid = context_menu.addAction(tr("Copy Title ID to Clipboard")); |
| 526 | QAction* navigate_to_gamedb_entry = context_menu.addAction(tr("Navigate to GameDB entry")); | 528 | QAction* navigate_to_gamedb_entry = context_menu.addAction(tr("Navigate to GameDB entry")); |
| 527 | context_menu.addSeparator(); | 529 | context_menu.addSeparator(); |
| @@ -570,8 +572,12 @@ void GameList::AddGamePopup(QMenu& context_menu, u64 program_id, const std::stri | |||
| 570 | connect(remove_custom_config, &QAction::triggered, [this, program_id, path]() { | 572 | connect(remove_custom_config, &QAction::triggered, [this, program_id, path]() { |
| 571 | emit RemoveFileRequested(program_id, GameListRemoveTarget::CustomConfiguration, path); | 573 | emit RemoveFileRequested(program_id, GameListRemoveTarget::CustomConfiguration, path); |
| 572 | }); | 574 | }); |
| 573 | connect(dump_romfs, &QAction::triggered, | 575 | connect(dump_romfs, &QAction::triggered, [this, program_id, path]() { |
| 574 | [this, program_id, path]() { emit DumpRomFSRequested(program_id, path); }); | 576 | emit DumpRomFSRequested(program_id, path, DumpRomFSTarget::Normal); |
| 577 | }); | ||
| 578 | connect(dump_romfs_sdmc, &QAction::triggered, [this, program_id, path]() { | ||
| 579 | emit DumpRomFSRequested(program_id, path, DumpRomFSTarget::SDMC); | ||
| 580 | }); | ||
| 575 | connect(copy_tid, &QAction::triggered, | 581 | connect(copy_tid, &QAction::triggered, |
| 576 | [this, program_id]() { emit CopyTIDRequested(program_id); }); | 582 | [this, program_id]() { emit CopyTIDRequested(program_id); }); |
| 577 | connect(navigate_to_gamedb_entry, &QAction::triggered, [this, program_id]() { | 583 | connect(navigate_to_gamedb_entry, &QAction::triggered, [this, program_id]() { |
diff --git a/src/yuzu/game_list.h b/src/yuzu/game_list.h index b630e34ff..50402da51 100644 --- a/src/yuzu/game_list.h +++ b/src/yuzu/game_list.h | |||
| @@ -45,6 +45,11 @@ enum class GameListRemoveTarget { | |||
| 45 | CustomConfiguration, | 45 | CustomConfiguration, |
| 46 | }; | 46 | }; |
| 47 | 47 | ||
| 48 | enum class DumpRomFSTarget { | ||
| 49 | Normal, | ||
| 50 | SDMC, | ||
| 51 | }; | ||
| 52 | |||
| 48 | enum class InstalledEntryType { | 53 | enum class InstalledEntryType { |
| 49 | Game, | 54 | Game, |
| 50 | Update, | 55 | Update, |
| @@ -92,7 +97,7 @@ signals: | |||
| 92 | void RemoveInstalledEntryRequested(u64 program_id, InstalledEntryType type); | 97 | void RemoveInstalledEntryRequested(u64 program_id, InstalledEntryType type); |
| 93 | void RemoveFileRequested(u64 program_id, GameListRemoveTarget target, | 98 | void RemoveFileRequested(u64 program_id, GameListRemoveTarget target, |
| 94 | const std::string& game_path); | 99 | const std::string& game_path); |
| 95 | void DumpRomFSRequested(u64 program_id, const std::string& game_path); | 100 | void DumpRomFSRequested(u64 program_id, const std::string& game_path, DumpRomFSTarget target); |
| 96 | void CopyTIDRequested(u64 program_id); | 101 | void CopyTIDRequested(u64 program_id); |
| 97 | void NavigateToGamedbEntryRequested(u64 program_id, | 102 | void NavigateToGamedbEntryRequested(u64 program_id, |
| 98 | const CompatibilityList& compatibility_list); | 103 | const CompatibilityList& compatibility_list); |
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index 6f5b2f6d6..f462cd072 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp | |||
| @@ -104,6 +104,7 @@ static FileSys::VirtualFile VfsDirectoryCreateFileWrapper(const FileSys::Virtual | |||
| 104 | #include "input_common/main.h" | 104 | #include "input_common/main.h" |
| 105 | #include "util/overlay_dialog.h" | 105 | #include "util/overlay_dialog.h" |
| 106 | #include "video_core/gpu.h" | 106 | #include "video_core/gpu.h" |
| 107 | #include "video_core/renderer_base.h" | ||
| 107 | #include "video_core/shader_notify.h" | 108 | #include "video_core/shader_notify.h" |
| 108 | #include "yuzu/about_dialog.h" | 109 | #include "yuzu/about_dialog.h" |
| 109 | #include "yuzu/bootmanager.h" | 110 | #include "yuzu/bootmanager.h" |
| @@ -1422,8 +1423,12 @@ void GMainWindow::BootGame(const QString& filename, std::size_t program_index, S | |||
| 1422 | title_name = Common::FS::PathToUTF8String( | 1423 | title_name = Common::FS::PathToUTF8String( |
| 1423 | std::filesystem::path{filename.toStdU16String()}.filename()); | 1424 | std::filesystem::path{filename.toStdU16String()}.filename()); |
| 1424 | } | 1425 | } |
| 1426 | const bool is_64bit = system.Kernel().CurrentProcess()->Is64BitProcess(); | ||
| 1427 | const auto instruction_set_suffix = is_64bit ? " (64-bit)" : " (32-bit)"; | ||
| 1428 | title_name += instruction_set_suffix; | ||
| 1425 | LOG_INFO(Frontend, "Booting game: {:016X} | {} | {}", title_id, title_name, title_version); | 1429 | LOG_INFO(Frontend, "Booting game: {:016X} | {} | {}", title_id, title_name, title_version); |
| 1426 | UpdateWindowTitle(title_name, title_version); | 1430 | const auto gpu_vendor = system.GPU().Renderer().GetDeviceVendor(); |
| 1431 | UpdateWindowTitle(title_name, title_version, gpu_vendor); | ||
| 1427 | 1432 | ||
| 1428 | loading_screen->Prepare(system.GetAppLoader()); | 1433 | loading_screen->Prepare(system.GetAppLoader()); |
| 1429 | loading_screen->show(); | 1434 | loading_screen->show(); |
| @@ -1877,7 +1882,8 @@ void GMainWindow::RemoveCustomConfiguration(u64 program_id, const std::string& g | |||
| 1877 | } | 1882 | } |
| 1878 | } | 1883 | } |
| 1879 | 1884 | ||
| 1880 | void GMainWindow::OnGameListDumpRomFS(u64 program_id, const std::string& game_path) { | 1885 | void GMainWindow::OnGameListDumpRomFS(u64 program_id, const std::string& game_path, |
| 1886 | DumpRomFSTarget target) { | ||
| 1881 | const auto failed = [this] { | 1887 | const auto failed = [this] { |
| 1882 | QMessageBox::warning(this, tr("RomFS Extraction Failed!"), | 1888 | QMessageBox::warning(this, tr("RomFS Extraction Failed!"), |
| 1883 | tr("There was an error copying the RomFS files or the user " | 1889 | tr("There was an error copying the RomFS files or the user " |
| @@ -1905,7 +1911,10 @@ void GMainWindow::OnGameListDumpRomFS(u64 program_id, const std::string& game_pa | |||
| 1905 | return; | 1911 | return; |
| 1906 | } | 1912 | } |
| 1907 | 1913 | ||
| 1908 | const auto dump_dir = Common::FS::GetYuzuPath(Common::FS::YuzuPath::DumpDir); | 1914 | const auto dump_dir = |
| 1915 | target == DumpRomFSTarget::Normal | ||
| 1916 | ? Common::FS::GetYuzuPath(Common::FS::YuzuPath::DumpDir) | ||
| 1917 | : Common::FS::GetYuzuPath(Common::FS::YuzuPath::SDMCDir) / "atmosphere" / "contents"; | ||
| 1909 | const auto romfs_dir = fmt::format("{:016X}/romfs", *romfs_title_id); | 1918 | const auto romfs_dir = fmt::format("{:016X}/romfs", *romfs_title_id); |
| 1910 | 1919 | ||
| 1911 | const auto path = Common::FS::PathToUTF8String(dump_dir / romfs_dir); | 1920 | const auto path = Common::FS::PathToUTF8String(dump_dir / romfs_dir); |
| @@ -1915,7 +1924,8 @@ void GMainWindow::OnGameListDumpRomFS(u64 program_id, const std::string& game_pa | |||
| 1915 | if (*romfs_title_id == program_id) { | 1924 | if (*romfs_title_id == program_id) { |
| 1916 | const u64 ivfc_offset = loader->ReadRomFSIVFCOffset(); | 1925 | const u64 ivfc_offset = loader->ReadRomFSIVFCOffset(); |
| 1917 | const FileSys::PatchManager pm{program_id, system.GetFileSystemController(), installed}; | 1926 | const FileSys::PatchManager pm{program_id, system.GetFileSystemController(), installed}; |
| 1918 | romfs = pm.PatchRomFS(file, ivfc_offset, FileSys::ContentRecordType::Program); | 1927 | romfs = |
| 1928 | pm.PatchRomFS(file, ivfc_offset, FileSys::ContentRecordType::Program, nullptr, false); | ||
| 1919 | } else { | 1929 | } else { |
| 1920 | romfs = installed.GetEntry(*romfs_title_id, FileSys::ContentRecordType::Data)->GetRomFS(); | 1930 | romfs = installed.GetEntry(*romfs_title_id, FileSys::ContentRecordType::Data)->GetRomFS(); |
| 1921 | } | 1931 | } |
| @@ -2852,8 +2862,8 @@ void GMainWindow::MigrateConfigFiles() { | |||
| 2852 | } | 2862 | } |
| 2853 | } | 2863 | } |
| 2854 | 2864 | ||
| 2855 | void GMainWindow::UpdateWindowTitle(const std::string& title_name, | 2865 | void GMainWindow::UpdateWindowTitle(std::string_view title_name, std::string_view title_version, |
| 2856 | const std::string& title_version) { | 2866 | std::string_view gpu_vendor) { |
| 2857 | const auto branch_name = std::string(Common::g_scm_branch); | 2867 | const auto branch_name = std::string(Common::g_scm_branch); |
| 2858 | const auto description = std::string(Common::g_scm_desc); | 2868 | const auto description = std::string(Common::g_scm_desc); |
| 2859 | const auto build_id = std::string(Common::g_build_id); | 2869 | const auto build_id = std::string(Common::g_build_id); |
| @@ -2866,7 +2876,8 @@ void GMainWindow::UpdateWindowTitle(const std::string& title_name, | |||
| 2866 | if (title_name.empty()) { | 2876 | if (title_name.empty()) { |
| 2867 | setWindowTitle(QString::fromStdString(window_title)); | 2877 | setWindowTitle(QString::fromStdString(window_title)); |
| 2868 | } else { | 2878 | } else { |
| 2869 | const auto run_title = fmt::format("{} | {} | {}", window_title, title_name, title_version); | 2879 | const auto run_title = |
| 2880 | fmt::format("{} | {} | {} | {}", window_title, title_name, title_version, gpu_vendor); | ||
| 2870 | setWindowTitle(QString::fromStdString(run_title)); | 2881 | setWindowTitle(QString::fromStdString(run_title)); |
| 2871 | } | 2882 | } |
| 2872 | } | 2883 | } |
diff --git a/src/yuzu/main.h b/src/yuzu/main.h index 11f152cbe..45c8310e1 100644 --- a/src/yuzu/main.h +++ b/src/yuzu/main.h | |||
| @@ -34,6 +34,7 @@ class QProgressDialog; | |||
| 34 | class WaitTreeWidget; | 34 | class WaitTreeWidget; |
| 35 | enum class GameListOpenTarget; | 35 | enum class GameListOpenTarget; |
| 36 | enum class GameListRemoveTarget; | 36 | enum class GameListRemoveTarget; |
| 37 | enum class DumpRomFSTarget; | ||
| 37 | enum class InstalledEntryType; | 38 | enum class InstalledEntryType; |
| 38 | class GameListPlaceholder; | 39 | class GameListPlaceholder; |
| 39 | 40 | ||
| @@ -244,7 +245,7 @@ private slots: | |||
| 244 | void OnGameListRemoveInstalledEntry(u64 program_id, InstalledEntryType type); | 245 | void OnGameListRemoveInstalledEntry(u64 program_id, InstalledEntryType type); |
| 245 | void OnGameListRemoveFile(u64 program_id, GameListRemoveTarget target, | 246 | void OnGameListRemoveFile(u64 program_id, GameListRemoveTarget target, |
| 246 | const std::string& game_path); | 247 | const std::string& game_path); |
| 247 | void OnGameListDumpRomFS(u64 program_id, const std::string& game_path); | 248 | void OnGameListDumpRomFS(u64 program_id, const std::string& game_path, DumpRomFSTarget target); |
| 248 | void OnGameListCopyTID(u64 program_id); | 249 | void OnGameListCopyTID(u64 program_id); |
| 249 | void OnGameListNavigateToGamedbEntry(u64 program_id, | 250 | void OnGameListNavigateToGamedbEntry(u64 program_id, |
| 250 | const CompatibilityList& compatibility_list); | 251 | const CompatibilityList& compatibility_list); |
| @@ -287,8 +288,8 @@ private: | |||
| 287 | InstallResult InstallNSPXCI(const QString& filename); | 288 | InstallResult InstallNSPXCI(const QString& filename); |
| 288 | InstallResult InstallNCA(const QString& filename); | 289 | InstallResult InstallNCA(const QString& filename); |
| 289 | void MigrateConfigFiles(); | 290 | void MigrateConfigFiles(); |
| 290 | void UpdateWindowTitle(const std::string& title_name = {}, | 291 | void UpdateWindowTitle(std::string_view title_name = {}, std::string_view title_version = {}, |
| 291 | const std::string& title_version = {}); | 292 | std::string_view gpu_vendor = {}); |
| 292 | void UpdateStatusBar(); | 293 | void UpdateStatusBar(); |
| 293 | void UpdateStatusButtons(); | 294 | void UpdateStatusButtons(); |
| 294 | void UpdateUISettings(); | 295 | void UpdateUISettings(); |