diff options
30 files changed, 237 insertions, 148 deletions
diff --git a/src/core/core.cpp b/src/core/core.cpp index 0ab2e3b76..d7e2efbd7 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp | |||
| @@ -116,11 +116,8 @@ FileSys::VirtualFile GetGameFileFromPath(const FileSys::VirtualFilesystem& vfs, | |||
| 116 | } | 116 | } |
| 117 | } | 117 | } |
| 118 | 118 | ||
| 119 | if (concat.empty()) { | 119 | return FileSys::ConcatenatedVfsFile::MakeConcatenatedFile(dir->GetName(), |
| 120 | return nullptr; | 120 | std::move(concat)); |
| 121 | } | ||
| 122 | |||
| 123 | return FileSys::ConcatenatedVfsFile::MakeConcatenatedFile(concat, dir->GetName()); | ||
| 124 | } | 121 | } |
| 125 | 122 | ||
| 126 | if (Common::FS::IsDir(path)) { | 123 | if (Common::FS::IsDir(path)) { |
diff --git a/src/core/file_sys/fsmitm_romfsbuild.cpp b/src/core/file_sys/fsmitm_romfsbuild.cpp index e39c7b62b..f1d3e4129 100644 --- a/src/core/file_sys/fsmitm_romfsbuild.cpp +++ b/src/core/file_sys/fsmitm_romfsbuild.cpp | |||
| @@ -107,62 +107,56 @@ static u64 romfs_get_hash_table_count(u64 num_entries) { | |||
| 107 | 107 | ||
| 108 | void RomFSBuildContext::VisitDirectory(VirtualDir romfs_dir, VirtualDir ext_dir, | 108 | void RomFSBuildContext::VisitDirectory(VirtualDir romfs_dir, VirtualDir ext_dir, |
| 109 | std::shared_ptr<RomFSBuildDirectoryContext> parent) { | 109 | std::shared_ptr<RomFSBuildDirectoryContext> parent) { |
| 110 | std::vector<std::shared_ptr<RomFSBuildDirectoryContext>> child_dirs; | 110 | for (auto& child_romfs_file : romfs_dir->GetFiles()) { |
| 111 | const auto name = child_romfs_file->GetName(); | ||
| 112 | const auto child = std::make_shared<RomFSBuildFileContext>(); | ||
| 113 | // Set child's path. | ||
| 114 | child->cur_path_ofs = parent->path_len + 1; | ||
| 115 | child->path_len = child->cur_path_ofs + static_cast<u32>(name.size()); | ||
| 116 | child->path = parent->path + "/" + name; | ||
| 117 | |||
| 118 | if (ext_dir != nullptr && ext_dir->GetFile(name + ".stub") != nullptr) { | ||
| 119 | continue; | ||
| 120 | } | ||
| 111 | 121 | ||
| 112 | const auto entries = romfs_dir->GetEntries(); | 122 | // Sanity check on path_len |
| 123 | ASSERT(child->path_len < FS_MAX_PATH); | ||
| 113 | 124 | ||
| 114 | for (const auto& kv : entries) { | 125 | child->source = std::move(child_romfs_file); |
| 115 | if (kv.second == VfsEntryType::Directory) { | ||
| 116 | const auto child = std::make_shared<RomFSBuildDirectoryContext>(); | ||
| 117 | // Set child's path. | ||
| 118 | child->cur_path_ofs = parent->path_len + 1; | ||
| 119 | child->path_len = child->cur_path_ofs + static_cast<u32>(kv.first.size()); | ||
| 120 | child->path = parent->path + "/" + kv.first; | ||
| 121 | 126 | ||
| 122 | if (ext_dir != nullptr && ext_dir->GetFile(kv.first + ".stub") != nullptr) { | 127 | if (ext_dir != nullptr) { |
| 123 | continue; | 128 | if (const auto ips = ext_dir->GetFile(name + ".ips")) { |
| 129 | if (auto patched = PatchIPS(child->source, ips)) { | ||
| 130 | child->source = std::move(patched); | ||
| 131 | } | ||
| 124 | } | 132 | } |
| 133 | } | ||
| 125 | 134 | ||
| 126 | // Sanity check on path_len | 135 | child->size = child->source->GetSize(); |
| 127 | ASSERT(child->path_len < FS_MAX_PATH); | ||
| 128 | |||
| 129 | if (AddDirectory(parent, child)) { | ||
| 130 | child_dirs.push_back(child); | ||
| 131 | } | ||
| 132 | } else { | ||
| 133 | const auto child = std::make_shared<RomFSBuildFileContext>(); | ||
| 134 | // Set child's path. | ||
| 135 | child->cur_path_ofs = parent->path_len + 1; | ||
| 136 | child->path_len = child->cur_path_ofs + static_cast<u32>(kv.first.size()); | ||
| 137 | child->path = parent->path + "/" + kv.first; | ||
| 138 | |||
| 139 | if (ext_dir != nullptr && ext_dir->GetFile(kv.first + ".stub") != nullptr) { | ||
| 140 | continue; | ||
| 141 | } | ||
| 142 | 136 | ||
| 143 | // Sanity check on path_len | 137 | AddFile(parent, child); |
| 144 | ASSERT(child->path_len < FS_MAX_PATH); | 138 | } |
| 145 | 139 | ||
| 146 | child->source = romfs_dir->GetFile(kv.first); | 140 | for (auto& child_romfs_dir : romfs_dir->GetSubdirectories()) { |
| 141 | const auto name = child_romfs_dir->GetName(); | ||
| 142 | const auto child = std::make_shared<RomFSBuildDirectoryContext>(); | ||
| 143 | // Set child's path. | ||
| 144 | child->cur_path_ofs = parent->path_len + 1; | ||
| 145 | child->path_len = child->cur_path_ofs + static_cast<u32>(name.size()); | ||
| 146 | child->path = parent->path + "/" + name; | ||
| 147 | 147 | ||
| 148 | if (ext_dir != nullptr) { | 148 | if (ext_dir != nullptr && ext_dir->GetFile(name + ".stub") != nullptr) { |
| 149 | if (const auto ips = ext_dir->GetFile(kv.first + ".ips")) { | 149 | continue; |
| 150 | if (auto patched = PatchIPS(child->source, ips)) { | 150 | } |
| 151 | child->source = std::move(patched); | ||
| 152 | } | ||
| 153 | } | ||
| 154 | } | ||
| 155 | 151 | ||
| 156 | child->size = child->source->GetSize(); | 152 | // Sanity check on path_len |
| 153 | ASSERT(child->path_len < FS_MAX_PATH); | ||
| 157 | 154 | ||
| 158 | AddFile(parent, child); | 155 | if (!AddDirectory(parent, child)) { |
| 156 | continue; | ||
| 159 | } | 157 | } |
| 160 | } | ||
| 161 | 158 | ||
| 162 | for (auto& child : child_dirs) { | 159 | auto child_ext_dir = ext_dir != nullptr ? ext_dir->GetSubdirectory(name) : nullptr; |
| 163 | auto subdir_name = std::string_view(child->path).substr(child->cur_path_ofs); | ||
| 164 | auto child_romfs_dir = romfs_dir->GetSubdirectory(subdir_name); | ||
| 165 | auto child_ext_dir = ext_dir != nullptr ? ext_dir->GetSubdirectory(subdir_name) : nullptr; | ||
| 166 | this->VisitDirectory(child_romfs_dir, child_ext_dir, child); | 160 | this->VisitDirectory(child_romfs_dir, child_ext_dir, child); |
| 167 | } | 161 | } |
| 168 | } | 162 | } |
| @@ -293,7 +287,7 @@ std::multimap<u64, VirtualFile> RomFSBuildContext::Build() { | |||
| 293 | 287 | ||
| 294 | cur_entry.name_size = name_size; | 288 | cur_entry.name_size = name_size; |
| 295 | 289 | ||
| 296 | out.emplace(cur_file->offset + ROMFS_FILEPARTITION_OFS, cur_file->source); | 290 | out.emplace(cur_file->offset + ROMFS_FILEPARTITION_OFS, std::move(cur_file->source)); |
| 297 | std::memcpy(file_table.data() + cur_file->entry_offset, &cur_entry, sizeof(RomFSFileEntry)); | 291 | std::memcpy(file_table.data() + cur_file->entry_offset, &cur_entry, sizeof(RomFSFileEntry)); |
| 298 | std::memset(file_table.data() + cur_file->entry_offset + sizeof(RomFSFileEntry), 0, | 292 | std::memset(file_table.data() + cur_file->entry_offset + sizeof(RomFSFileEntry), 0, |
| 299 | Common::AlignUp(cur_entry.name_size, 4)); | 293 | Common::AlignUp(cur_entry.name_size, 4)); |
diff --git a/src/core/file_sys/patch_manager.cpp b/src/core/file_sys/patch_manager.cpp index 8e475f25a..0bca05587 100644 --- a/src/core/file_sys/patch_manager.cpp +++ b/src/core/file_sys/patch_manager.cpp | |||
| @@ -377,16 +377,16 @@ static void ApplyLayeredFS(VirtualFile& romfs, u64 title_id, ContentRecordType t | |||
| 377 | 377 | ||
| 378 | auto romfs_dir = FindSubdirectoryCaseless(subdir, "romfs"); | 378 | auto romfs_dir = FindSubdirectoryCaseless(subdir, "romfs"); |
| 379 | if (romfs_dir != nullptr) | 379 | if (romfs_dir != nullptr) |
| 380 | layers.push_back(std::make_shared<CachedVfsDirectory>(romfs_dir)); | 380 | layers.emplace_back(std::make_shared<CachedVfsDirectory>(std::move(romfs_dir))); |
| 381 | 381 | ||
| 382 | auto ext_dir = FindSubdirectoryCaseless(subdir, "romfs_ext"); | 382 | auto ext_dir = FindSubdirectoryCaseless(subdir, "romfs_ext"); |
| 383 | if (ext_dir != nullptr) | 383 | if (ext_dir != nullptr) |
| 384 | layers_ext.push_back(std::make_shared<CachedVfsDirectory>(ext_dir)); | 384 | layers_ext.emplace_back(std::make_shared<CachedVfsDirectory>(std::move(ext_dir))); |
| 385 | 385 | ||
| 386 | if (type == ContentRecordType::HtmlDocument) { | 386 | if (type == ContentRecordType::HtmlDocument) { |
| 387 | auto manual_dir = FindSubdirectoryCaseless(subdir, "manual_html"); | 387 | auto manual_dir = FindSubdirectoryCaseless(subdir, "manual_html"); |
| 388 | if (manual_dir != nullptr) | 388 | if (manual_dir != nullptr) |
| 389 | layers.push_back(std::make_shared<CachedVfsDirectory>(manual_dir)); | 389 | layers.emplace_back(std::make_shared<CachedVfsDirectory>(std::move(manual_dir))); |
| 390 | } | 390 | } |
| 391 | } | 391 | } |
| 392 | 392 | ||
| @@ -400,7 +400,7 @@ static void ApplyLayeredFS(VirtualFile& romfs, u64 title_id, ContentRecordType t | |||
| 400 | return; | 400 | return; |
| 401 | } | 401 | } |
| 402 | 402 | ||
| 403 | layers.push_back(std::move(extracted)); | 403 | layers.emplace_back(std::move(extracted)); |
| 404 | 404 | ||
| 405 | auto layered = LayeredVfsDirectory::MakeLayeredDirectory(std::move(layers)); | 405 | auto layered = LayeredVfsDirectory::MakeLayeredDirectory(std::move(layers)); |
| 406 | if (layered == nullptr) { | 406 | if (layered == nullptr) { |
diff --git a/src/core/file_sys/registered_cache.cpp b/src/core/file_sys/registered_cache.cpp index 04da93d5c..1cc77ad14 100644 --- a/src/core/file_sys/registered_cache.cpp +++ b/src/core/file_sys/registered_cache.cpp | |||
| @@ -322,7 +322,8 @@ VirtualFile RegisteredCache::OpenFileOrDirectoryConcat(const VirtualDir& open_di | |||
| 322 | return nullptr; | 322 | return nullptr; |
| 323 | } | 323 | } |
| 324 | 324 | ||
| 325 | return ConcatenatedVfsFile::MakeConcatenatedFile(concat, concat.front()->GetName()); | 325 | auto name = concat.front()->GetName(); |
| 326 | return ConcatenatedVfsFile::MakeConcatenatedFile(std::move(name), std::move(concat)); | ||
| 326 | } | 327 | } |
| 327 | 328 | ||
| 328 | VirtualFile RegisteredCache::GetFileAtID(NcaID id) const { | 329 | VirtualFile RegisteredCache::GetFileAtID(NcaID id) const { |
diff --git a/src/core/file_sys/romfs.cpp b/src/core/file_sys/romfs.cpp index 614da2130..1c580de57 100644 --- a/src/core/file_sys/romfs.cpp +++ b/src/core/file_sys/romfs.cpp | |||
| @@ -133,7 +133,7 @@ VirtualDir ExtractRomFS(VirtualFile file, RomFSExtractionType type) { | |||
| 133 | out = out->GetSubdirectories().front(); | 133 | out = out->GetSubdirectories().front(); |
| 134 | } | 134 | } |
| 135 | 135 | ||
| 136 | return std::make_shared<CachedVfsDirectory>(out); | 136 | return std::make_shared<CachedVfsDirectory>(std::move(out)); |
| 137 | } | 137 | } |
| 138 | 138 | ||
| 139 | VirtualFile CreateRomFS(VirtualDir dir, VirtualDir ext) { | 139 | VirtualFile CreateRomFS(VirtualDir dir, VirtualDir ext) { |
| @@ -141,8 +141,7 @@ VirtualFile CreateRomFS(VirtualDir dir, VirtualDir ext) { | |||
| 141 | return nullptr; | 141 | return nullptr; |
| 142 | 142 | ||
| 143 | RomFSBuildContext ctx{dir, ext}; | 143 | RomFSBuildContext ctx{dir, ext}; |
| 144 | auto file_map = ctx.Build(); | 144 | return ConcatenatedVfsFile::MakeConcatenatedFile(0, dir->GetName(), ctx.Build()); |
| 145 | return ConcatenatedVfsFile::MakeConcatenatedFile(0, file_map, dir->GetName()); | ||
| 146 | } | 145 | } |
| 147 | 146 | ||
| 148 | } // namespace FileSys | 147 | } // namespace FileSys |
diff --git a/src/core/file_sys/vfs_cached.cpp b/src/core/file_sys/vfs_cached.cpp index c3154ee81..7ee5300e5 100644 --- a/src/core/file_sys/vfs_cached.cpp +++ b/src/core/file_sys/vfs_cached.cpp | |||
| @@ -6,13 +6,13 @@ | |||
| 6 | 6 | ||
| 7 | namespace FileSys { | 7 | namespace FileSys { |
| 8 | 8 | ||
| 9 | CachedVfsDirectory::CachedVfsDirectory(VirtualDir& source_dir) | 9 | CachedVfsDirectory::CachedVfsDirectory(VirtualDir&& source_dir) |
| 10 | : name(source_dir->GetName()), parent(source_dir->GetParentDirectory()) { | 10 | : name(source_dir->GetName()), parent(source_dir->GetParentDirectory()) { |
| 11 | for (auto& dir : source_dir->GetSubdirectories()) { | 11 | for (auto& dir : source_dir->GetSubdirectories()) { |
| 12 | dirs.emplace(dir->GetName(), std::make_shared<CachedVfsDirectory>(dir)); | 12 | dirs.emplace(dir->GetName(), std::make_shared<CachedVfsDirectory>(std::move(dir))); |
| 13 | } | 13 | } |
| 14 | for (auto& file : source_dir->GetFiles()) { | 14 | for (auto& file : source_dir->GetFiles()) { |
| 15 | files.emplace(file->GetName(), file); | 15 | files.emplace(file->GetName(), std::move(file)); |
| 16 | } | 16 | } |
| 17 | } | 17 | } |
| 18 | 18 | ||
diff --git a/src/core/file_sys/vfs_cached.h b/src/core/file_sys/vfs_cached.h index 113acac12..1e5300784 100644 --- a/src/core/file_sys/vfs_cached.h +++ b/src/core/file_sys/vfs_cached.h | |||
| @@ -11,7 +11,7 @@ namespace FileSys { | |||
| 11 | 11 | ||
| 12 | class CachedVfsDirectory : public ReadOnlyVfsDirectory { | 12 | class CachedVfsDirectory : public ReadOnlyVfsDirectory { |
| 13 | public: | 13 | public: |
| 14 | CachedVfsDirectory(VirtualDir& source_directory); | 14 | CachedVfsDirectory(VirtualDir&& source_directory); |
| 15 | 15 | ||
| 16 | ~CachedVfsDirectory() override; | 16 | ~CachedVfsDirectory() override; |
| 17 | VirtualFile GetFile(std::string_view file_name) const override; | 17 | VirtualFile GetFile(std::string_view file_name) const override; |
diff --git a/src/core/file_sys/vfs_concat.cpp b/src/core/file_sys/vfs_concat.cpp index 311a59e5f..168b9cbec 100644 --- a/src/core/file_sys/vfs_concat.cpp +++ b/src/core/file_sys/vfs_concat.cpp | |||
| @@ -10,7 +10,7 @@ | |||
| 10 | 10 | ||
| 11 | namespace FileSys { | 11 | namespace FileSys { |
| 12 | 12 | ||
| 13 | ConcatenatedVfsFile::ConcatenatedVfsFile(ConcatenationMap&& concatenation_map_, std::string&& name_) | 13 | ConcatenatedVfsFile::ConcatenatedVfsFile(std::string&& name_, ConcatenationMap&& concatenation_map_) |
| 14 | : concatenation_map(std::move(concatenation_map_)), name(std::move(name_)) { | 14 | : concatenation_map(std::move(concatenation_map_)), name(std::move(name_)) { |
| 15 | DEBUG_ASSERT(this->VerifyContinuity()); | 15 | DEBUG_ASSERT(this->VerifyContinuity()); |
| 16 | } | 16 | } |
| @@ -30,8 +30,8 @@ bool ConcatenatedVfsFile::VerifyContinuity() const { | |||
| 30 | 30 | ||
| 31 | ConcatenatedVfsFile::~ConcatenatedVfsFile() = default; | 31 | ConcatenatedVfsFile::~ConcatenatedVfsFile() = default; |
| 32 | 32 | ||
| 33 | VirtualFile ConcatenatedVfsFile::MakeConcatenatedFile(const std::vector<VirtualFile>& files, | 33 | VirtualFile ConcatenatedVfsFile::MakeConcatenatedFile(std::string&& name, |
| 34 | std::string&& name) { | 34 | std::vector<VirtualFile>&& files) { |
| 35 | // Fold trivial cases. | 35 | // Fold trivial cases. |
| 36 | if (files.empty()) { | 36 | if (files.empty()) { |
| 37 | return nullptr; | 37 | return nullptr; |
| @@ -46,20 +46,21 @@ VirtualFile ConcatenatedVfsFile::MakeConcatenatedFile(const std::vector<VirtualF | |||
| 46 | u64 last_offset = 0; | 46 | u64 last_offset = 0; |
| 47 | 47 | ||
| 48 | for (auto& file : files) { | 48 | for (auto& file : files) { |
| 49 | const auto size = file->GetSize(); | ||
| 50 | |||
| 49 | concatenation_map.emplace_back(ConcatenationEntry{ | 51 | concatenation_map.emplace_back(ConcatenationEntry{ |
| 50 | .offset = last_offset, | 52 | .offset = last_offset, |
| 51 | .file = file, | 53 | .file = std::move(file), |
| 52 | }); | 54 | }); |
| 53 | 55 | ||
| 54 | last_offset += file->GetSize(); | 56 | last_offset += size; |
| 55 | } | 57 | } |
| 56 | 58 | ||
| 57 | return VirtualFile(new ConcatenatedVfsFile(std::move(concatenation_map), std::move(name))); | 59 | return VirtualFile(new ConcatenatedVfsFile(std::move(name), std::move(concatenation_map))); |
| 58 | } | 60 | } |
| 59 | 61 | ||
| 60 | VirtualFile ConcatenatedVfsFile::MakeConcatenatedFile(u8 filler_byte, | 62 | VirtualFile ConcatenatedVfsFile::MakeConcatenatedFile(u8 filler_byte, std::string&& name, |
| 61 | const std::multimap<u64, VirtualFile>& files, | 63 | std::multimap<u64, VirtualFile>&& files) { |
| 62 | std::string&& name) { | ||
| 63 | // Fold trivial cases. | 64 | // Fold trivial cases. |
| 64 | if (files.empty()) { | 65 | if (files.empty()) { |
| 65 | return nullptr; | 66 | return nullptr; |
| @@ -76,6 +77,8 @@ VirtualFile ConcatenatedVfsFile::MakeConcatenatedFile(u8 filler_byte, | |||
| 76 | 77 | ||
| 77 | // Iteration of a multimap is ordered, so offset will be strictly non-decreasing. | 78 | // Iteration of a multimap is ordered, so offset will be strictly non-decreasing. |
| 78 | for (auto& [offset, file] : files) { | 79 | for (auto& [offset, file] : files) { |
| 80 | const auto size = file->GetSize(); | ||
| 81 | |||
| 79 | if (offset > last_offset) { | 82 | if (offset > last_offset) { |
| 80 | concatenation_map.emplace_back(ConcatenationEntry{ | 83 | concatenation_map.emplace_back(ConcatenationEntry{ |
| 81 | .offset = last_offset, | 84 | .offset = last_offset, |
| @@ -85,13 +88,13 @@ VirtualFile ConcatenatedVfsFile::MakeConcatenatedFile(u8 filler_byte, | |||
| 85 | 88 | ||
| 86 | concatenation_map.emplace_back(ConcatenationEntry{ | 89 | concatenation_map.emplace_back(ConcatenationEntry{ |
| 87 | .offset = offset, | 90 | .offset = offset, |
| 88 | .file = file, | 91 | .file = std::move(file), |
| 89 | }); | 92 | }); |
| 90 | 93 | ||
| 91 | last_offset = offset + file->GetSize(); | 94 | last_offset = offset + size; |
| 92 | } | 95 | } |
| 93 | 96 | ||
| 94 | return VirtualFile(new ConcatenatedVfsFile(std::move(concatenation_map), std::move(name))); | 97 | return VirtualFile(new ConcatenatedVfsFile(std::move(name), std::move(concatenation_map))); |
| 95 | } | 98 | } |
| 96 | 99 | ||
| 97 | std::string ConcatenatedVfsFile::GetName() const { | 100 | std::string ConcatenatedVfsFile::GetName() const { |
diff --git a/src/core/file_sys/vfs_concat.h b/src/core/file_sys/vfs_concat.h index 6b329d545..cbddd12bd 100644 --- a/src/core/file_sys/vfs_concat.h +++ b/src/core/file_sys/vfs_concat.h | |||
| @@ -24,22 +24,20 @@ private: | |||
| 24 | }; | 24 | }; |
| 25 | using ConcatenationMap = std::vector<ConcatenationEntry>; | 25 | using ConcatenationMap = std::vector<ConcatenationEntry>; |
| 26 | 26 | ||
| 27 | explicit ConcatenatedVfsFile(std::vector<ConcatenationEntry>&& concatenation_map, | 27 | explicit ConcatenatedVfsFile(std::string&& name, |
| 28 | std::string&& name); | 28 | std::vector<ConcatenationEntry>&& concatenation_map); |
| 29 | bool VerifyContinuity() const; | 29 | bool VerifyContinuity() const; |
| 30 | 30 | ||
| 31 | public: | 31 | public: |
| 32 | ~ConcatenatedVfsFile() override; | 32 | ~ConcatenatedVfsFile() override; |
| 33 | 33 | ||
| 34 | /// Wrapper function to allow for more efficient handling of files.size() == 0, 1 cases. | 34 | /// Wrapper function to allow for more efficient handling of files.size() == 0, 1 cases. |
| 35 | static VirtualFile MakeConcatenatedFile(const std::vector<VirtualFile>& files, | 35 | static VirtualFile MakeConcatenatedFile(std::string&& name, std::vector<VirtualFile>&& files); |
| 36 | std::string&& name); | ||
| 37 | 36 | ||
| 38 | /// Convenience function that turns a map of offsets to files into a concatenated file, filling | 37 | /// Convenience function that turns a map of offsets to files into a concatenated file, filling |
| 39 | /// gaps with a given filler byte. | 38 | /// gaps with a given filler byte. |
| 40 | static VirtualFile MakeConcatenatedFile(u8 filler_byte, | 39 | static VirtualFile MakeConcatenatedFile(u8 filler_byte, std::string&& name, |
| 41 | const std::multimap<u64, VirtualFile>& files, | 40 | std::multimap<u64, VirtualFile>&& files); |
| 42 | std::string&& name); | ||
| 43 | 41 | ||
| 44 | std::string GetName() const override; | 42 | std::string GetName() const override; |
| 45 | std::size_t GetSize() const override; | 43 | std::size_t GetSize() const override; |
diff --git a/src/core/file_sys/vfs_layered.cpp b/src/core/file_sys/vfs_layered.cpp index 3e6426afc..08daca397 100644 --- a/src/core/file_sys/vfs_layered.cpp +++ b/src/core/file_sys/vfs_layered.cpp | |||
| @@ -38,7 +38,7 @@ VirtualDir LayeredVfsDirectory::GetDirectoryRelative(std::string_view path) cons | |||
| 38 | for (const auto& layer : dirs) { | 38 | for (const auto& layer : dirs) { |
| 39 | auto dir = layer->GetDirectoryRelative(path); | 39 | auto dir = layer->GetDirectoryRelative(path); |
| 40 | if (dir != nullptr) { | 40 | if (dir != nullptr) { |
| 41 | out.push_back(std::move(dir)); | 41 | out.emplace_back(std::move(dir)); |
| 42 | } | 42 | } |
| 43 | } | 43 | } |
| 44 | 44 | ||
| @@ -62,11 +62,11 @@ std::vector<VirtualFile> LayeredVfsDirectory::GetFiles() const { | |||
| 62 | std::set<std::string, std::less<>> out_names; | 62 | std::set<std::string, std::less<>> out_names; |
| 63 | 63 | ||
| 64 | for (const auto& layer : dirs) { | 64 | for (const auto& layer : dirs) { |
| 65 | for (const auto& file : layer->GetFiles()) { | 65 | for (auto& file : layer->GetFiles()) { |
| 66 | auto file_name = file->GetName(); | 66 | auto file_name = file->GetName(); |
| 67 | if (!out_names.contains(file_name)) { | 67 | if (!out_names.contains(file_name)) { |
| 68 | out_names.emplace(std::move(file_name)); | 68 | out_names.emplace(std::move(file_name)); |
| 69 | out.push_back(file); | 69 | out.emplace_back(std::move(file)); |
| 70 | } | 70 | } |
| 71 | } | 71 | } |
| 72 | } | 72 | } |
| @@ -86,7 +86,7 @@ std::vector<VirtualDir> LayeredVfsDirectory::GetSubdirectories() const { | |||
| 86 | std::vector<VirtualDir> out; | 86 | std::vector<VirtualDir> out; |
| 87 | out.reserve(names.size()); | 87 | out.reserve(names.size()); |
| 88 | for (const auto& subdir : names) | 88 | for (const auto& subdir : names) |
| 89 | out.push_back(GetSubdirectory(subdir)); | 89 | out.emplace_back(GetSubdirectory(subdir)); |
| 90 | 90 | ||
| 91 | return out; | 91 | return out; |
| 92 | } | 92 | } |
diff --git a/src/core/hle/service/acc/acc.cpp b/src/core/hle/service/acc/acc.cpp index b7d14060c..1b1c8190e 100644 --- a/src/core/hle/service/acc/acc.cpp +++ b/src/core/hle/service/acc/acc.cpp | |||
| @@ -407,13 +407,13 @@ protected: | |||
| 407 | IPC::RequestParser rp{ctx}; | 407 | IPC::RequestParser rp{ctx}; |
| 408 | const auto base = rp.PopRaw<ProfileBase>(); | 408 | const auto base = rp.PopRaw<ProfileBase>(); |
| 409 | 409 | ||
| 410 | const auto user_data = ctx.ReadBuffer(); | 410 | const auto image_data = ctx.ReadBufferA(0); |
| 411 | const auto image_data = ctx.ReadBuffer(1); | 411 | const auto user_data = ctx.ReadBufferX(0); |
| 412 | 412 | ||
| 413 | LOG_DEBUG(Service_ACC, "called, username='{}', timestamp={:016X}, uuid=0x{}", | 413 | LOG_INFO(Service_ACC, "called, username='{}', timestamp={:016X}, uuid=0x{}", |
| 414 | Common::StringFromFixedZeroTerminatedBuffer( | 414 | Common::StringFromFixedZeroTerminatedBuffer( |
| 415 | reinterpret_cast<const char*>(base.username.data()), base.username.size()), | 415 | reinterpret_cast<const char*>(base.username.data()), base.username.size()), |
| 416 | base.timestamp, base.user_uuid.RawString()); | 416 | base.timestamp, base.user_uuid.RawString()); |
| 417 | 417 | ||
| 418 | if (user_data.size() < sizeof(UserData)) { | 418 | if (user_data.size() < sizeof(UserData)) { |
| 419 | LOG_ERROR(Service_ACC, "UserData buffer too small!"); | 419 | LOG_ERROR(Service_ACC, "UserData buffer too small!"); |
diff --git a/src/core/hle/service/hle_ipc.cpp b/src/core/hle/service/hle_ipc.cpp index f6a1e54f2..6f3ae3cc4 100644 --- a/src/core/hle/service/hle_ipc.cpp +++ b/src/core/hle/service/hle_ipc.cpp | |||
| @@ -23,6 +23,17 @@ | |||
| 23 | #include "core/hle/service/ipc_helpers.h" | 23 | #include "core/hle/service/ipc_helpers.h" |
| 24 | #include "core/memory.h" | 24 | #include "core/memory.h" |
| 25 | 25 | ||
| 26 | namespace { | ||
| 27 | static thread_local std::array read_buffer_data_a{ | ||
| 28 | Common::ScratchBuffer<u8>(), | ||
| 29 | Common::ScratchBuffer<u8>(), | ||
| 30 | }; | ||
| 31 | static thread_local std::array read_buffer_data_x{ | ||
| 32 | Common::ScratchBuffer<u8>(), | ||
| 33 | Common::ScratchBuffer<u8>(), | ||
| 34 | }; | ||
| 35 | } // Anonymous namespace | ||
| 36 | |||
| 26 | namespace Service { | 37 | namespace Service { |
| 27 | 38 | ||
| 28 | SessionRequestHandler::SessionRequestHandler(Kernel::KernelCore& kernel_, const char* service_name_) | 39 | SessionRequestHandler::SessionRequestHandler(Kernel::KernelCore& kernel_, const char* service_name_) |
| @@ -328,26 +339,57 @@ std::vector<u8> HLERequestContext::ReadBufferCopy(std::size_t buffer_index) cons | |||
| 328 | } | 339 | } |
| 329 | } | 340 | } |
| 330 | 341 | ||
| 331 | std::span<const u8> HLERequestContext::ReadBuffer(std::size_t buffer_index) const { | 342 | std::span<const u8> HLERequestContext::ReadBufferA(std::size_t buffer_index) const { |
| 332 | static thread_local std::array read_buffer_a{ | 343 | static thread_local std::array read_buffer_a{ |
| 333 | Core::Memory::CpuGuestMemory<u8, Core::Memory::GuestMemoryFlags::SafeRead>(memory, 0, 0), | 344 | Core::Memory::CpuGuestMemory<u8, Core::Memory::GuestMemoryFlags::SafeRead>(memory, 0, 0), |
| 334 | Core::Memory::CpuGuestMemory<u8, Core::Memory::GuestMemoryFlags::SafeRead>(memory, 0, 0), | 345 | Core::Memory::CpuGuestMemory<u8, Core::Memory::GuestMemoryFlags::SafeRead>(memory, 0, 0), |
| 335 | }; | 346 | }; |
| 336 | static thread_local std::array read_buffer_data_a{ | 347 | |
| 337 | Common::ScratchBuffer<u8>(), | 348 | ASSERT_OR_EXECUTE_MSG( |
| 338 | Common::ScratchBuffer<u8>(), | 349 | BufferDescriptorA().size() > buffer_index, { return {}; }, |
| 339 | }; | 350 | "BufferDescriptorA invalid buffer_index {}", buffer_index); |
| 351 | auto& read_buffer = read_buffer_a[buffer_index]; | ||
| 352 | return read_buffer.Read(BufferDescriptorA()[buffer_index].Address(), | ||
| 353 | BufferDescriptorA()[buffer_index].Size(), | ||
| 354 | &read_buffer_data_a[buffer_index]); | ||
| 355 | } | ||
| 356 | |||
| 357 | std::span<const u8> HLERequestContext::ReadBufferX(std::size_t buffer_index) const { | ||
| 340 | static thread_local std::array read_buffer_x{ | 358 | static thread_local std::array read_buffer_x{ |
| 341 | Core::Memory::CpuGuestMemory<u8, Core::Memory::GuestMemoryFlags::SafeRead>(memory, 0, 0), | 359 | Core::Memory::CpuGuestMemory<u8, Core::Memory::GuestMemoryFlags::SafeRead>(memory, 0, 0), |
| 342 | Core::Memory::CpuGuestMemory<u8, Core::Memory::GuestMemoryFlags::SafeRead>(memory, 0, 0), | 360 | Core::Memory::CpuGuestMemory<u8, Core::Memory::GuestMemoryFlags::SafeRead>(memory, 0, 0), |
| 343 | }; | 361 | }; |
| 344 | static thread_local std::array read_buffer_data_x{ | 362 | |
| 345 | Common::ScratchBuffer<u8>(), | 363 | ASSERT_OR_EXECUTE_MSG( |
| 346 | Common::ScratchBuffer<u8>(), | 364 | BufferDescriptorX().size() > buffer_index, { return {}; }, |
| 365 | "BufferDescriptorX invalid buffer_index {}", buffer_index); | ||
| 366 | auto& read_buffer = read_buffer_x[buffer_index]; | ||
| 367 | return read_buffer.Read(BufferDescriptorX()[buffer_index].Address(), | ||
| 368 | BufferDescriptorX()[buffer_index].Size(), | ||
| 369 | &read_buffer_data_x[buffer_index]); | ||
| 370 | } | ||
| 371 | |||
| 372 | std::span<const u8> HLERequestContext::ReadBuffer(std::size_t buffer_index) const { | ||
| 373 | static thread_local std::array read_buffer_a{ | ||
| 374 | Core::Memory::CpuGuestMemory<u8, Core::Memory::GuestMemoryFlags::SafeRead>(memory, 0, 0), | ||
| 375 | Core::Memory::CpuGuestMemory<u8, Core::Memory::GuestMemoryFlags::SafeRead>(memory, 0, 0), | ||
| 376 | }; | ||
| 377 | static thread_local std::array read_buffer_x{ | ||
| 378 | Core::Memory::CpuGuestMemory<u8, Core::Memory::GuestMemoryFlags::SafeRead>(memory, 0, 0), | ||
| 379 | Core::Memory::CpuGuestMemory<u8, Core::Memory::GuestMemoryFlags::SafeRead>(memory, 0, 0), | ||
| 347 | }; | 380 | }; |
| 348 | 381 | ||
| 349 | const bool is_buffer_a{BufferDescriptorA().size() > buffer_index && | 382 | const bool is_buffer_a{BufferDescriptorA().size() > buffer_index && |
| 350 | BufferDescriptorA()[buffer_index].Size()}; | 383 | BufferDescriptorA()[buffer_index].Size()}; |
| 384 | const bool is_buffer_x{BufferDescriptorX().size() > buffer_index && | ||
| 385 | BufferDescriptorX()[buffer_index].Size()}; | ||
| 386 | |||
| 387 | if (is_buffer_a && is_buffer_x) { | ||
| 388 | LOG_WARNING(Input, "Both buffer descriptors are available a.size={}, x.size={}", | ||
| 389 | BufferDescriptorA()[buffer_index].Size(), | ||
| 390 | BufferDescriptorX()[buffer_index].Size()); | ||
| 391 | } | ||
| 392 | |||
| 351 | if (is_buffer_a) { | 393 | if (is_buffer_a) { |
| 352 | ASSERT_OR_EXECUTE_MSG( | 394 | ASSERT_OR_EXECUTE_MSG( |
| 353 | BufferDescriptorA().size() > buffer_index, { return {}; }, | 395 | BufferDescriptorA().size() > buffer_index, { return {}; }, |
diff --git a/src/core/hle/service/hle_ipc.h b/src/core/hle/service/hle_ipc.h index 4bd24c899..ad5259a5c 100644 --- a/src/core/hle/service/hle_ipc.h +++ b/src/core/hle/service/hle_ipc.h | |||
| @@ -253,6 +253,12 @@ public: | |||
| 253 | return domain_message_header.has_value(); | 253 | return domain_message_header.has_value(); |
| 254 | } | 254 | } |
| 255 | 255 | ||
| 256 | /// Helper function to get a span of a buffer using the buffer descriptor A | ||
| 257 | [[nodiscard]] std::span<const u8> ReadBufferA(std::size_t buffer_index = 0) const; | ||
| 258 | |||
| 259 | /// Helper function to get a span of a buffer using the buffer descriptor X | ||
| 260 | [[nodiscard]] std::span<const u8> ReadBufferX(std::size_t buffer_index = 0) const; | ||
| 261 | |||
| 256 | /// Helper function to get a span of a buffer using the appropriate buffer descriptor | 262 | /// Helper function to get a span of a buffer using the appropriate buffer descriptor |
| 257 | [[nodiscard]] std::span<const u8> ReadBuffer(std::size_t buffer_index = 0) const; | 263 | [[nodiscard]] std::span<const u8> ReadBuffer(std::size_t buffer_index = 0) const; |
| 258 | 264 | ||
diff --git a/src/core/hle/service/mii/types/core_data.cpp b/src/core/hle/service/mii/types/core_data.cpp index 970c748ca..ba1da76ba 100644 --- a/src/core/hle/service/mii/types/core_data.cpp +++ b/src/core/hle/service/mii/types/core_data.cpp | |||
| @@ -41,6 +41,7 @@ void CoreData::BuildRandom(Age age, Gender gender, Race race) { | |||
| 41 | } | 41 | } |
| 42 | } | 42 | } |
| 43 | 43 | ||
| 44 | SetDefault(); | ||
| 44 | SetGender(gender); | 45 | SetGender(gender); |
| 45 | SetFavoriteColor(MiiUtil::GetRandomValue(FavoriteColor::Max)); | 46 | SetFavoriteColor(MiiUtil::GetRandomValue(FavoriteColor::Max)); |
| 46 | SetRegionMove(0); | 47 | SetRegionMove(0); |
diff --git a/src/core/hle/service/prepo/prepo.cpp b/src/core/hle/service/prepo/prepo.cpp index ec4a84989..14e8df63a 100644 --- a/src/core/hle/service/prepo/prepo.cpp +++ b/src/core/hle/service/prepo/prepo.cpp | |||
| @@ -58,14 +58,8 @@ private: | |||
| 58 | IPC::RequestParser rp{ctx}; | 58 | IPC::RequestParser rp{ctx}; |
| 59 | const auto process_id = rp.PopRaw<u64>(); | 59 | const auto process_id = rp.PopRaw<u64>(); |
| 60 | 60 | ||
| 61 | const auto data1 = ctx.ReadBuffer(0); | 61 | const auto data1 = ctx.ReadBufferA(0); |
| 62 | const auto data2 = [&ctx] { | 62 | const auto data2 = ctx.ReadBufferX(0); |
| 63 | if (ctx.CanReadBuffer(1)) { | ||
| 64 | return ctx.ReadBuffer(1); | ||
| 65 | } | ||
| 66 | |||
| 67 | return std::span<const u8>{}; | ||
| 68 | }(); | ||
| 69 | 63 | ||
| 70 | LOG_DEBUG(Service_PREPO, | 64 | LOG_DEBUG(Service_PREPO, |
| 71 | "called, type={:02X}, process_id={:016X}, data1_size={:016X}, data2_size={:016X}", | 65 | "called, type={:02X}, process_id={:016X}, data1_size={:016X}, data2_size={:016X}", |
| @@ -85,14 +79,8 @@ private: | |||
| 85 | const auto user_id = rp.PopRaw<u128>(); | 79 | const auto user_id = rp.PopRaw<u128>(); |
| 86 | const auto process_id = rp.PopRaw<u64>(); | 80 | const auto process_id = rp.PopRaw<u64>(); |
| 87 | 81 | ||
| 88 | const auto data1 = ctx.ReadBuffer(0); | 82 | const auto data1 = ctx.ReadBufferA(0); |
| 89 | const auto data2 = [&ctx] { | 83 | const auto data2 = ctx.ReadBufferX(0); |
| 90 | if (ctx.CanReadBuffer(1)) { | ||
| 91 | return ctx.ReadBuffer(1); | ||
| 92 | } | ||
| 93 | |||
| 94 | return std::span<const u8>{}; | ||
| 95 | }(); | ||
| 96 | 84 | ||
| 97 | LOG_DEBUG(Service_PREPO, | 85 | LOG_DEBUG(Service_PREPO, |
| 98 | "called, type={:02X}, user_id={:016X}{:016X}, process_id={:016X}, " | 86 | "called, type={:02X}, user_id={:016X}{:016X}, process_id={:016X}, " |
| @@ -137,14 +125,8 @@ private: | |||
| 137 | IPC::RequestParser rp{ctx}; | 125 | IPC::RequestParser rp{ctx}; |
| 138 | const auto title_id = rp.PopRaw<u64>(); | 126 | const auto title_id = rp.PopRaw<u64>(); |
| 139 | 127 | ||
| 140 | const auto data1 = ctx.ReadBuffer(0); | 128 | const auto data1 = ctx.ReadBufferA(0); |
| 141 | const auto data2 = [&ctx] { | 129 | const auto data2 = ctx.ReadBufferX(0); |
| 142 | if (ctx.CanReadBuffer(1)) { | ||
| 143 | return ctx.ReadBuffer(1); | ||
| 144 | } | ||
| 145 | |||
| 146 | return std::span<const u8>{}; | ||
| 147 | }(); | ||
| 148 | 130 | ||
| 149 | LOG_DEBUG(Service_PREPO, "called, title_id={:016X}, data1_size={:016X}, data2_size={:016X}", | 131 | LOG_DEBUG(Service_PREPO, "called, title_id={:016X}, data1_size={:016X}, data2_size={:016X}", |
| 150 | title_id, data1.size(), data2.size()); | 132 | title_id, data1.size(), data2.size()); |
| @@ -161,14 +143,8 @@ private: | |||
| 161 | const auto user_id = rp.PopRaw<u128>(); | 143 | const auto user_id = rp.PopRaw<u128>(); |
| 162 | const auto title_id = rp.PopRaw<u64>(); | 144 | const auto title_id = rp.PopRaw<u64>(); |
| 163 | 145 | ||
| 164 | const auto data1 = ctx.ReadBuffer(0); | 146 | const auto data1 = ctx.ReadBufferA(0); |
| 165 | const auto data2 = [&ctx] { | 147 | const auto data2 = ctx.ReadBufferX(0); |
| 166 | if (ctx.CanReadBuffer(1)) { | ||
| 167 | return ctx.ReadBuffer(1); | ||
| 168 | } | ||
| 169 | |||
| 170 | return std::span<const u8>{}; | ||
| 171 | }(); | ||
| 172 | 148 | ||
| 173 | LOG_DEBUG(Service_PREPO, | 149 | LOG_DEBUG(Service_PREPO, |
| 174 | "called, user_id={:016X}{:016X}, title_id={:016X}, data1_size={:016X}, " | 150 | "called, user_id={:016X}{:016X}, title_id={:016X}, data1_size={:016X}, " |
diff --git a/src/tests/common/unique_function.cpp b/src/tests/common/unique_function.cpp index f7a23e876..42e6ade09 100644 --- a/src/tests/common/unique_function.cpp +++ b/src/tests/common/unique_function.cpp | |||
| @@ -46,8 +46,8 @@ TEST_CASE("UniqueFunction", "[common]") { | |||
| 46 | Noisy noisy; | 46 | Noisy noisy; |
| 47 | REQUIRE(noisy.state == "Default constructed"); | 47 | REQUIRE(noisy.state == "Default constructed"); |
| 48 | 48 | ||
| 49 | Common::UniqueFunction<void> func = [noisy = std::move(noisy)] { | 49 | Common::UniqueFunction<void> func = [noisy_inner = std::move(noisy)] { |
| 50 | REQUIRE(noisy.state == "Move constructed"); | 50 | REQUIRE(noisy_inner.state == "Move constructed"); |
| 51 | }; | 51 | }; |
| 52 | REQUIRE(noisy.state == "Moved away"); | 52 | REQUIRE(noisy.state == "Moved away"); |
| 53 | func(); | 53 | func(); |
| @@ -101,7 +101,7 @@ TEST_CASE("UniqueFunction", "[common]") { | |||
| 101 | }; | 101 | }; |
| 102 | Foo object{&num_destroyed}; | 102 | Foo object{&num_destroyed}; |
| 103 | { | 103 | { |
| 104 | Common::UniqueFunction<void> func = [object = std::move(object)] {}; | 104 | Common::UniqueFunction<void> func = [object_inner = std::move(object)] {}; |
| 105 | REQUIRE(num_destroyed == 0); | 105 | REQUIRE(num_destroyed == 0); |
| 106 | } | 106 | } |
| 107 | REQUIRE(num_destroyed == 1); | 107 | REQUIRE(num_destroyed == 1); |
diff --git a/src/video_core/buffer_cache/buffer_cache_base.h b/src/video_core/buffer_cache/buffer_cache_base.h index c4f6e8d12..eed267361 100644 --- a/src/video_core/buffer_cache/buffer_cache_base.h +++ b/src/video_core/buffer_cache/buffer_cache_base.h | |||
| @@ -62,7 +62,11 @@ using BufferId = SlotId; | |||
| 62 | using VideoCore::Surface::PixelFormat; | 62 | using VideoCore::Surface::PixelFormat; |
| 63 | using namespace Common::Literals; | 63 | using namespace Common::Literals; |
| 64 | 64 | ||
| 65 | #ifdef __APPLE__ | ||
| 66 | constexpr u32 NUM_VERTEX_BUFFERS = 16; | ||
| 67 | #else | ||
| 65 | constexpr u32 NUM_VERTEX_BUFFERS = 32; | 68 | constexpr u32 NUM_VERTEX_BUFFERS = 32; |
| 69 | #endif | ||
| 66 | constexpr u32 NUM_TRANSFORM_FEEDBACK_BUFFERS = 4; | 70 | constexpr u32 NUM_TRANSFORM_FEEDBACK_BUFFERS = 4; |
| 67 | constexpr u32 NUM_GRAPHICS_UNIFORM_BUFFERS = 18; | 71 | constexpr u32 NUM_GRAPHICS_UNIFORM_BUFFERS = 18; |
| 68 | constexpr u32 NUM_COMPUTE_UNIFORM_BUFFERS = 8; | 72 | constexpr u32 NUM_COMPUTE_UNIFORM_BUFFERS = 8; |
diff --git a/src/video_core/host_shaders/CMakeLists.txt b/src/video_core/host_shaders/CMakeLists.txt index 8bb429578..cd2549232 100644 --- a/src/video_core/host_shaders/CMakeLists.txt +++ b/src/video_core/host_shaders/CMakeLists.txt | |||
| @@ -19,6 +19,7 @@ set(SHADER_FILES | |||
| 19 | block_linear_unswizzle_2d.comp | 19 | block_linear_unswizzle_2d.comp |
| 20 | block_linear_unswizzle_3d.comp | 20 | block_linear_unswizzle_3d.comp |
| 21 | convert_abgr8_to_d24s8.frag | 21 | convert_abgr8_to_d24s8.frag |
| 22 | convert_abgr8_to_d32f.frag | ||
| 22 | convert_d32f_to_abgr8.frag | 23 | convert_d32f_to_abgr8.frag |
| 23 | convert_d24s8_to_abgr8.frag | 24 | convert_d24s8_to_abgr8.frag |
| 24 | convert_depth_to_float.frag | 25 | convert_depth_to_float.frag |
diff --git a/src/video_core/host_shaders/convert_abgr8_to_d32f.frag b/src/video_core/host_shaders/convert_abgr8_to_d32f.frag new file mode 100644 index 000000000..095b910c2 --- /dev/null +++ b/src/video_core/host_shaders/convert_abgr8_to_d32f.frag | |||
| @@ -0,0 +1,15 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #version 450 | ||
| 5 | |||
| 6 | layout(binding = 0) uniform sampler2D color_texture; | ||
| 7 | |||
| 8 | void main() { | ||
| 9 | ivec2 coord = ivec2(gl_FragCoord.xy); | ||
| 10 | vec4 color = texelFetch(color_texture, coord, 0).abgr; | ||
| 11 | |||
| 12 | float value = color.a * (color.r + color.g + color.b) / 3.0f; | ||
| 13 | |||
| 14 | gl_FragDepth = value; | ||
| 15 | } | ||
diff --git a/src/video_core/host_shaders/convert_d24s8_to_abgr8.frag b/src/video_core/host_shaders/convert_d24s8_to_abgr8.frag index d33131d7c..b81a54056 100644 --- a/src/video_core/host_shaders/convert_d24s8_to_abgr8.frag +++ b/src/video_core/host_shaders/convert_d24s8_to_abgr8.frag | |||
| @@ -3,16 +3,16 @@ | |||
| 3 | 3 | ||
| 4 | #version 450 | 4 | #version 450 |
| 5 | 5 | ||
| 6 | precision mediump int; | ||
| 7 | precision highp float; | ||
| 8 | |||
| 6 | layout(binding = 0) uniform sampler2D depth_tex; | 9 | layout(binding = 0) uniform sampler2D depth_tex; |
| 7 | layout(binding = 1) uniform isampler2D stencil_tex; | 10 | layout(binding = 1) uniform usampler2D stencil_tex; |
| 8 | 11 | ||
| 9 | layout(location = 0) out vec4 color; | 12 | layout(location = 0) out vec4 color; |
| 10 | 13 | ||
| 11 | void main() { | 14 | void main() { |
| 12 | ivec2 coord = ivec2(gl_FragCoord.xy); | 15 | ivec2 coord = ivec2(gl_FragCoord.xy); |
| 13 | uint depth = uint(textureLod(depth_tex, coord, 0).r * (exp2(24.0) - 1.0f)); | ||
| 14 | uint stencil = uint(textureLod(stencil_tex, coord, 0).r); | ||
| 15 | |||
| 16 | highp uint depth_val = | 16 | highp uint depth_val = |
| 17 | uint(textureLod(depth_tex, coord, 0).r * (exp2(32.0) - 1.0)); | 17 | uint(textureLod(depth_tex, coord, 0).r * (exp2(32.0) - 1.0)); |
| 18 | lowp uint stencil_val = textureLod(stencil_tex, coord, 0).r; | 18 | lowp uint stencil_val = textureLod(stencil_tex, coord, 0).r; |
diff --git a/src/video_core/host_shaders/convert_d32f_to_abgr8.frag b/src/video_core/host_shaders/convert_d32f_to_abgr8.frag index 04cfef8b5..4e5a9f955 100644 --- a/src/video_core/host_shaders/convert_d32f_to_abgr8.frag +++ b/src/video_core/host_shaders/convert_d32f_to_abgr8.frag | |||
| @@ -9,6 +9,6 @@ layout(location = 0) out vec4 color; | |||
| 9 | 9 | ||
| 10 | void main() { | 10 | void main() { |
| 11 | ivec2 coord = ivec2(gl_FragCoord.xy); | 11 | ivec2 coord = ivec2(gl_FragCoord.xy); |
| 12 | float depth = textureLod(depth_tex, coord, 0).r; | 12 | float depth = texelFetch(depth_tex, coord, 0).r; |
| 13 | color = vec4(depth, depth, depth, 1.0); | 13 | color = vec4(depth, depth, depth, 1.0); |
| 14 | } | 14 | } |
diff --git a/src/video_core/host_shaders/convert_s8d24_to_abgr8.frag b/src/video_core/host_shaders/convert_s8d24_to_abgr8.frag index 31db7d426..6a457981d 100644 --- a/src/video_core/host_shaders/convert_s8d24_to_abgr8.frag +++ b/src/video_core/host_shaders/convert_s8d24_to_abgr8.frag | |||
| @@ -3,16 +3,16 @@ | |||
| 3 | 3 | ||
| 4 | #version 450 | 4 | #version 450 |
| 5 | 5 | ||
| 6 | precision mediump int; | ||
| 7 | precision highp float; | ||
| 8 | |||
| 6 | layout(binding = 0) uniform sampler2D depth_tex; | 9 | layout(binding = 0) uniform sampler2D depth_tex; |
| 7 | layout(binding = 1) uniform isampler2D stencil_tex; | 10 | layout(binding = 1) uniform usampler2D stencil_tex; |
| 8 | 11 | ||
| 9 | layout(location = 0) out vec4 color; | 12 | layout(location = 0) out vec4 color; |
| 10 | 13 | ||
| 11 | void main() { | 14 | void main() { |
| 12 | ivec2 coord = ivec2(gl_FragCoord.xy); | 15 | ivec2 coord = ivec2(gl_FragCoord.xy); |
| 13 | uint depth = uint(textureLod(depth_tex, coord, 0).r * (exp2(24.0) - 1.0f)); | ||
| 14 | uint stencil = uint(textureLod(stencil_tex, coord, 0).r); | ||
| 15 | |||
| 16 | highp uint depth_val = | 16 | highp uint depth_val = |
| 17 | uint(textureLod(depth_tex, coord, 0).r * (exp2(32.0) - 1.0)); | 17 | uint(textureLod(depth_tex, coord, 0).r * (exp2(32.0) - 1.0)); |
| 18 | lowp uint stencil_val = textureLod(stencil_tex, coord, 0).r; | 18 | lowp uint stencil_val = textureLod(stencil_tex, coord, 0).r; |
diff --git a/src/video_core/renderer_vulkan/blit_image.cpp b/src/video_core/renderer_vulkan/blit_image.cpp index f01d2394e..c3db09424 100644 --- a/src/video_core/renderer_vulkan/blit_image.cpp +++ b/src/video_core/renderer_vulkan/blit_image.cpp | |||
| @@ -8,6 +8,7 @@ | |||
| 8 | #include "common/settings.h" | 8 | #include "common/settings.h" |
| 9 | #include "video_core/host_shaders/blit_color_float_frag_spv.h" | 9 | #include "video_core/host_shaders/blit_color_float_frag_spv.h" |
| 10 | #include "video_core/host_shaders/convert_abgr8_to_d24s8_frag_spv.h" | 10 | #include "video_core/host_shaders/convert_abgr8_to_d24s8_frag_spv.h" |
| 11 | #include "video_core/host_shaders/convert_abgr8_to_d32f_frag_spv.h" | ||
| 11 | #include "video_core/host_shaders/convert_d24s8_to_abgr8_frag_spv.h" | 12 | #include "video_core/host_shaders/convert_d24s8_to_abgr8_frag_spv.h" |
| 12 | #include "video_core/host_shaders/convert_d32f_to_abgr8_frag_spv.h" | 13 | #include "video_core/host_shaders/convert_d32f_to_abgr8_frag_spv.h" |
| 13 | #include "video_core/host_shaders/convert_depth_to_float_frag_spv.h" | 14 | #include "video_core/host_shaders/convert_depth_to_float_frag_spv.h" |
| @@ -434,6 +435,7 @@ BlitImageHelper::BlitImageHelper(const Device& device_, Scheduler& scheduler_, | |||
| 434 | convert_depth_to_float_frag(BuildShader(device, CONVERT_DEPTH_TO_FLOAT_FRAG_SPV)), | 435 | convert_depth_to_float_frag(BuildShader(device, CONVERT_DEPTH_TO_FLOAT_FRAG_SPV)), |
| 435 | convert_float_to_depth_frag(BuildShader(device, CONVERT_FLOAT_TO_DEPTH_FRAG_SPV)), | 436 | convert_float_to_depth_frag(BuildShader(device, CONVERT_FLOAT_TO_DEPTH_FRAG_SPV)), |
| 436 | convert_abgr8_to_d24s8_frag(BuildShader(device, CONVERT_ABGR8_TO_D24S8_FRAG_SPV)), | 437 | convert_abgr8_to_d24s8_frag(BuildShader(device, CONVERT_ABGR8_TO_D24S8_FRAG_SPV)), |
| 438 | convert_abgr8_to_d32f_frag(BuildShader(device, CONVERT_ABGR8_TO_D32F_FRAG_SPV)), | ||
| 437 | convert_d32f_to_abgr8_frag(BuildShader(device, CONVERT_D32F_TO_ABGR8_FRAG_SPV)), | 439 | convert_d32f_to_abgr8_frag(BuildShader(device, CONVERT_D32F_TO_ABGR8_FRAG_SPV)), |
| 438 | convert_d24s8_to_abgr8_frag(BuildShader(device, CONVERT_D24S8_TO_ABGR8_FRAG_SPV)), | 440 | convert_d24s8_to_abgr8_frag(BuildShader(device, CONVERT_D24S8_TO_ABGR8_FRAG_SPV)), |
| 439 | convert_s8d24_to_abgr8_frag(BuildShader(device, CONVERT_S8D24_TO_ABGR8_FRAG_SPV)), | 441 | convert_s8d24_to_abgr8_frag(BuildShader(device, CONVERT_S8D24_TO_ABGR8_FRAG_SPV)), |
| @@ -559,6 +561,13 @@ void BlitImageHelper::ConvertABGR8ToD24S8(const Framebuffer* dst_framebuffer, | |||
| 559 | Convert(*convert_abgr8_to_d24s8_pipeline, dst_framebuffer, src_image_view); | 561 | Convert(*convert_abgr8_to_d24s8_pipeline, dst_framebuffer, src_image_view); |
| 560 | } | 562 | } |
| 561 | 563 | ||
| 564 | void BlitImageHelper::ConvertABGR8ToD32F(const Framebuffer* dst_framebuffer, | ||
| 565 | const ImageView& src_image_view) { | ||
| 566 | ConvertPipelineDepthTargetEx(convert_abgr8_to_d32f_pipeline, dst_framebuffer->RenderPass(), | ||
| 567 | convert_abgr8_to_d32f_frag); | ||
| 568 | Convert(*convert_abgr8_to_d32f_pipeline, dst_framebuffer, src_image_view); | ||
| 569 | } | ||
| 570 | |||
| 562 | void BlitImageHelper::ConvertD32FToABGR8(const Framebuffer* dst_framebuffer, | 571 | void BlitImageHelper::ConvertD32FToABGR8(const Framebuffer* dst_framebuffer, |
| 563 | ImageView& src_image_view) { | 572 | ImageView& src_image_view) { |
| 564 | ConvertPipelineColorTargetEx(convert_d32f_to_abgr8_pipeline, dst_framebuffer->RenderPass(), | 573 | ConvertPipelineColorTargetEx(convert_d32f_to_abgr8_pipeline, dst_framebuffer->RenderPass(), |
diff --git a/src/video_core/renderer_vulkan/blit_image.h b/src/video_core/renderer_vulkan/blit_image.h index a032c71fb..b2104a59e 100644 --- a/src/video_core/renderer_vulkan/blit_image.h +++ b/src/video_core/renderer_vulkan/blit_image.h | |||
| @@ -67,6 +67,8 @@ public: | |||
| 67 | 67 | ||
| 68 | void ConvertABGR8ToD24S8(const Framebuffer* dst_framebuffer, const ImageView& src_image_view); | 68 | void ConvertABGR8ToD24S8(const Framebuffer* dst_framebuffer, const ImageView& src_image_view); |
| 69 | 69 | ||
| 70 | void ConvertABGR8ToD32F(const Framebuffer* dst_framebuffer, const ImageView& src_image_view); | ||
| 71 | |||
| 70 | void ConvertD32FToABGR8(const Framebuffer* dst_framebuffer, ImageView& src_image_view); | 72 | void ConvertD32FToABGR8(const Framebuffer* dst_framebuffer, ImageView& src_image_view); |
| 71 | 73 | ||
| 72 | void ConvertD24S8ToABGR8(const Framebuffer* dst_framebuffer, ImageView& src_image_view); | 74 | void ConvertD24S8ToABGR8(const Framebuffer* dst_framebuffer, ImageView& src_image_view); |
| @@ -130,6 +132,7 @@ private: | |||
| 130 | vk::ShaderModule convert_depth_to_float_frag; | 132 | vk::ShaderModule convert_depth_to_float_frag; |
| 131 | vk::ShaderModule convert_float_to_depth_frag; | 133 | vk::ShaderModule convert_float_to_depth_frag; |
| 132 | vk::ShaderModule convert_abgr8_to_d24s8_frag; | 134 | vk::ShaderModule convert_abgr8_to_d24s8_frag; |
| 135 | vk::ShaderModule convert_abgr8_to_d32f_frag; | ||
| 133 | vk::ShaderModule convert_d32f_to_abgr8_frag; | 136 | vk::ShaderModule convert_d32f_to_abgr8_frag; |
| 134 | vk::ShaderModule convert_d24s8_to_abgr8_frag; | 137 | vk::ShaderModule convert_d24s8_to_abgr8_frag; |
| 135 | vk::ShaderModule convert_s8d24_to_abgr8_frag; | 138 | vk::ShaderModule convert_s8d24_to_abgr8_frag; |
| @@ -149,6 +152,7 @@ private: | |||
| 149 | vk::Pipeline convert_d16_to_r16_pipeline; | 152 | vk::Pipeline convert_d16_to_r16_pipeline; |
| 150 | vk::Pipeline convert_r16_to_d16_pipeline; | 153 | vk::Pipeline convert_r16_to_d16_pipeline; |
| 151 | vk::Pipeline convert_abgr8_to_d24s8_pipeline; | 154 | vk::Pipeline convert_abgr8_to_d24s8_pipeline; |
| 155 | vk::Pipeline convert_abgr8_to_d32f_pipeline; | ||
| 152 | vk::Pipeline convert_d32f_to_abgr8_pipeline; | 156 | vk::Pipeline convert_d32f_to_abgr8_pipeline; |
| 153 | vk::Pipeline convert_d24s8_to_abgr8_pipeline; | 157 | vk::Pipeline convert_d24s8_to_abgr8_pipeline; |
| 154 | vk::Pipeline convert_s8d24_to_abgr8_pipeline; | 158 | vk::Pipeline convert_s8d24_to_abgr8_pipeline; |
diff --git a/src/video_core/renderer_vulkan/vk_query_cache.cpp b/src/video_core/renderer_vulkan/vk_query_cache.cpp index 2edaafa7e..66c03bf17 100644 --- a/src/video_core/renderer_vulkan/vk_query_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_query_cache.cpp | |||
| @@ -1436,6 +1436,7 @@ void QueryCacheRuntime::Barriers(bool is_prebarrier) { | |||
| 1436 | .srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT, | 1436 | .srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT, |
| 1437 | .dstAccessMask = VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT, | 1437 | .dstAccessMask = VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT, |
| 1438 | }; | 1438 | }; |
| 1439 | impl->scheduler.RequestOutsideRenderPassOperationContext(); | ||
| 1439 | if (is_prebarrier) { | 1440 | if (is_prebarrier) { |
| 1440 | impl->scheduler.Record([](vk::CommandBuffer cmdbuf) { | 1441 | impl->scheduler.Record([](vk::CommandBuffer cmdbuf) { |
| 1441 | cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, | 1442 | cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, |
diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp index 23696fac4..465eac37e 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp +++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp | |||
| @@ -977,6 +977,19 @@ void RasterizerVulkan::UpdateScissorsState(Tegra::Engines::Maxwell3D::Regs& regs | |||
| 977 | if (!state_tracker.TouchScissors()) { | 977 | if (!state_tracker.TouchScissors()) { |
| 978 | return; | 978 | return; |
| 979 | } | 979 | } |
| 980 | if (!regs.viewport_scale_offset_enabled) { | ||
| 981 | const auto x = static_cast<float>(regs.surface_clip.x); | ||
| 982 | const auto y = static_cast<float>(regs.surface_clip.y); | ||
| 983 | const auto width = static_cast<float>(regs.surface_clip.width); | ||
| 984 | const auto height = static_cast<float>(regs.surface_clip.height); | ||
| 985 | VkRect2D scissor; | ||
| 986 | scissor.offset.x = static_cast<u32>(x); | ||
| 987 | scissor.offset.y = static_cast<u32>(y); | ||
| 988 | scissor.extent.width = static_cast<u32>(width != 0.0f ? width : 1.0f); | ||
| 989 | scissor.extent.height = static_cast<u32>(height != 0.0f ? height : 1.0f); | ||
| 990 | scheduler.Record([scissor](vk::CommandBuffer cmdbuf) { cmdbuf.SetScissor(0, scissor); }); | ||
| 991 | return; | ||
| 992 | } | ||
| 980 | u32 up_scale = 1; | 993 | u32 up_scale = 1; |
| 981 | u32 down_shift = 0; | 994 | u32 down_shift = 0; |
| 982 | if (texture_cache.IsRescaling()) { | 995 | if (texture_cache.IsRescaling()) { |
diff --git a/src/video_core/renderer_vulkan/vk_render_pass_cache.cpp b/src/video_core/renderer_vulkan/vk_render_pass_cache.cpp index ae9f1de64..7746a88d3 100644 --- a/src/video_core/renderer_vulkan/vk_render_pass_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_render_pass_cache.cpp | |||
| @@ -19,7 +19,7 @@ VkAttachmentDescription AttachmentDescription(const Device& device, PixelFormat | |||
| 19 | VkSampleCountFlagBits samples) { | 19 | VkSampleCountFlagBits samples) { |
| 20 | using MaxwellToVK::SurfaceFormat; | 20 | using MaxwellToVK::SurfaceFormat; |
| 21 | return { | 21 | return { |
| 22 | .flags = VK_ATTACHMENT_DESCRIPTION_MAY_ALIAS_BIT, | 22 | .flags = {}, |
| 23 | .format = SurfaceFormat(device, FormatType::Optimal, true, format).format, | 23 | .format = SurfaceFormat(device, FormatType::Optimal, true, format).format, |
| 24 | .samples = samples, | 24 | .samples = samples, |
| 25 | .loadOp = VK_ATTACHMENT_LOAD_OP_LOAD, | 25 | .loadOp = VK_ATTACHMENT_LOAD_OP_LOAD, |
diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.cpp b/src/video_core/renderer_vulkan/vk_texture_cache.cpp index 93773a69f..de34f6d49 100644 --- a/src/video_core/renderer_vulkan/vk_texture_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_texture_cache.cpp | |||
| @@ -1194,6 +1194,11 @@ void TextureCacheRuntime::ConvertImage(Framebuffer* dst, ImageView& dst_view, Im | |||
| 1194 | return blit_image_helper.ConvertD16ToR16(dst, src_view); | 1194 | return blit_image_helper.ConvertD16ToR16(dst, src_view); |
| 1195 | } | 1195 | } |
| 1196 | break; | 1196 | break; |
| 1197 | case PixelFormat::A8B8G8R8_SRGB: | ||
| 1198 | if (src_view.format == PixelFormat::D32_FLOAT) { | ||
| 1199 | return blit_image_helper.ConvertD32FToABGR8(dst, src_view); | ||
| 1200 | } | ||
| 1201 | break; | ||
| 1197 | case PixelFormat::A8B8G8R8_UNORM: | 1202 | case PixelFormat::A8B8G8R8_UNORM: |
| 1198 | if (src_view.format == PixelFormat::S8_UINT_D24_UNORM) { | 1203 | if (src_view.format == PixelFormat::S8_UINT_D24_UNORM) { |
| 1199 | return blit_image_helper.ConvertD24S8ToABGR8(dst, src_view); | 1204 | return blit_image_helper.ConvertD24S8ToABGR8(dst, src_view); |
| @@ -1205,6 +1210,16 @@ void TextureCacheRuntime::ConvertImage(Framebuffer* dst, ImageView& dst_view, Im | |||
| 1205 | return blit_image_helper.ConvertD32FToABGR8(dst, src_view); | 1210 | return blit_image_helper.ConvertD32FToABGR8(dst, src_view); |
| 1206 | } | 1211 | } |
| 1207 | break; | 1212 | break; |
| 1213 | case PixelFormat::B8G8R8A8_SRGB: | ||
| 1214 | if (src_view.format == PixelFormat::D32_FLOAT) { | ||
| 1215 | return blit_image_helper.ConvertD32FToABGR8(dst, src_view); | ||
| 1216 | } | ||
| 1217 | break; | ||
| 1218 | case PixelFormat::B8G8R8A8_UNORM: | ||
| 1219 | if (src_view.format == PixelFormat::D32_FLOAT) { | ||
| 1220 | return blit_image_helper.ConvertD32FToABGR8(dst, src_view); | ||
| 1221 | } | ||
| 1222 | break; | ||
| 1208 | case PixelFormat::R32_FLOAT: | 1223 | case PixelFormat::R32_FLOAT: |
| 1209 | if (src_view.format == PixelFormat::D32_FLOAT) { | 1224 | if (src_view.format == PixelFormat::D32_FLOAT) { |
| 1210 | return blit_image_helper.ConvertD32ToR32(dst, src_view); | 1225 | return blit_image_helper.ConvertD32ToR32(dst, src_view); |
| @@ -1222,6 +1237,12 @@ void TextureCacheRuntime::ConvertImage(Framebuffer* dst, ImageView& dst_view, Im | |||
| 1222 | } | 1237 | } |
| 1223 | break; | 1238 | break; |
| 1224 | case PixelFormat::D32_FLOAT: | 1239 | case PixelFormat::D32_FLOAT: |
| 1240 | if (src_view.format == PixelFormat::A8B8G8R8_UNORM || | ||
| 1241 | src_view.format == PixelFormat::B8G8R8A8_UNORM || | ||
| 1242 | src_view.format == PixelFormat::A8B8G8R8_SRGB || | ||
| 1243 | src_view.format == PixelFormat::B8G8R8A8_SRGB) { | ||
| 1244 | return blit_image_helper.ConvertABGR8ToD32F(dst, src_view); | ||
| 1245 | } | ||
| 1225 | if (src_view.format == PixelFormat::R32_FLOAT) { | 1246 | if (src_view.format == PixelFormat::R32_FLOAT) { |
| 1226 | return blit_image_helper.ConvertR32ToD32(dst, src_view); | 1247 | return blit_image_helper.ConvertR32ToD32(dst, src_view); |
| 1227 | } | 1248 | } |
| @@ -2034,7 +2055,7 @@ void TextureCacheRuntime::TransitionImageLayout(Image& image) { | |||
| 2034 | }, | 2055 | }, |
| 2035 | }; | 2056 | }; |
| 2036 | scheduler.RequestOutsideRenderPassOperationContext(); | 2057 | scheduler.RequestOutsideRenderPassOperationContext(); |
| 2037 | scheduler.Record([barrier = barrier](vk::CommandBuffer cmdbuf) { | 2058 | scheduler.Record([barrier](vk::CommandBuffer cmdbuf) { |
| 2038 | cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, | 2059 | cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, |
| 2039 | VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, barrier); | 2060 | VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, barrier); |
| 2040 | }); | 2061 | }); |
diff --git a/src/video_core/texture_cache/formatter.cpp b/src/video_core/texture_cache/formatter.cpp index 6279d8e9e..2b7e0df72 100644 --- a/src/video_core/texture_cache/formatter.cpp +++ b/src/video_core/texture_cache/formatter.cpp | |||
| @@ -10,19 +10,23 @@ | |||
| 10 | #include "video_core/texture_cache/image_info.h" | 10 | #include "video_core/texture_cache/image_info.h" |
| 11 | #include "video_core/texture_cache/image_view_base.h" | 11 | #include "video_core/texture_cache/image_view_base.h" |
| 12 | #include "video_core/texture_cache/render_targets.h" | 12 | #include "video_core/texture_cache/render_targets.h" |
| 13 | #include "video_core/texture_cache/samples_helper.h" | ||
| 13 | 14 | ||
| 14 | namespace VideoCommon { | 15 | namespace VideoCommon { |
| 15 | 16 | ||
| 16 | std::string Name(const ImageBase& image) { | 17 | std::string Name(const ImageBase& image) { |
| 17 | const GPUVAddr gpu_addr = image.gpu_addr; | 18 | const GPUVAddr gpu_addr = image.gpu_addr; |
| 18 | const ImageInfo& info = image.info; | 19 | const ImageInfo& info = image.info; |
| 19 | const u32 width = info.size.width; | 20 | u32 width = info.size.width; |
| 20 | const u32 height = info.size.height; | 21 | u32 height = info.size.height; |
| 21 | const u32 depth = info.size.depth; | 22 | const u32 depth = info.size.depth; |
| 22 | const u32 num_layers = image.info.resources.layers; | 23 | const u32 num_layers = image.info.resources.layers; |
| 23 | const u32 num_levels = image.info.resources.levels; | 24 | const u32 num_levels = image.info.resources.levels; |
| 24 | std::string resource; | 25 | std::string resource; |
| 25 | if (image.info.num_samples > 1) { | 26 | if (image.info.num_samples > 1) { |
| 27 | const auto [samples_x, samples_y] = VideoCommon::SamplesLog2(image.info.num_samples); | ||
| 28 | width >>= samples_x; | ||
| 29 | height >>= samples_y; | ||
| 26 | resource += fmt::format(":{}xMSAA", image.info.num_samples); | 30 | resource += fmt::format(":{}xMSAA", image.info.num_samples); |
| 27 | } | 31 | } |
| 28 | if (num_layers > 1) { | 32 | if (num_layers > 1) { |
diff --git a/src/video_core/texture_cache/samples_helper.h b/src/video_core/texture_cache/samples_helper.h index 203ac1b11..2ee2f8312 100644 --- a/src/video_core/texture_cache/samples_helper.h +++ b/src/video_core/texture_cache/samples_helper.h | |||
| @@ -24,7 +24,7 @@ namespace VideoCommon { | |||
| 24 | return {2, 2}; | 24 | return {2, 2}; |
| 25 | } | 25 | } |
| 26 | ASSERT_MSG(false, "Invalid number of samples={}", num_samples); | 26 | ASSERT_MSG(false, "Invalid number of samples={}", num_samples); |
| 27 | return {1, 1}; | 27 | return {0, 0}; |
| 28 | } | 28 | } |
| 29 | 29 | ||
| 30 | [[nodiscard]] inline int NumSamples(Tegra::Texture::MsaaMode msaa_mode) { | 30 | [[nodiscard]] inline int NumSamples(Tegra::Texture::MsaaMode msaa_mode) { |