summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/core.cpp7
-rw-r--r--src/core/file_sys/fsmitm_romfsbuild.cpp84
-rw-r--r--src/core/file_sys/patch_manager.cpp8
-rw-r--r--src/core/file_sys/registered_cache.cpp3
-rw-r--r--src/core/file_sys/romfs.cpp5
-rw-r--r--src/core/file_sys/vfs_cached.cpp6
-rw-r--r--src/core/file_sys/vfs_cached.h2
-rw-r--r--src/core/file_sys/vfs_concat.cpp27
-rw-r--r--src/core/file_sys/vfs_concat.h12
-rw-r--r--src/core/file_sys/vfs_layered.cpp8
-rw-r--r--src/core/hle/service/acc/acc.cpp12
-rw-r--r--src/core/hle/service/hle_ipc.cpp58
-rw-r--r--src/core/hle/service/hle_ipc.h6
-rw-r--r--src/core/hle/service/mii/types/core_data.cpp1
-rw-r--r--src/core/hle/service/prepo/prepo.cpp40
-rw-r--r--src/tests/common/unique_function.cpp6
-rw-r--r--src/video_core/buffer_cache/buffer_cache_base.h4
-rw-r--r--src/video_core/host_shaders/CMakeLists.txt1
-rw-r--r--src/video_core/host_shaders/convert_abgr8_to_d32f.frag15
-rw-r--r--src/video_core/host_shaders/convert_d24s8_to_abgr8.frag8
-rw-r--r--src/video_core/host_shaders/convert_d32f_to_abgr8.frag2
-rw-r--r--src/video_core/host_shaders/convert_s8d24_to_abgr8.frag8
-rw-r--r--src/video_core/renderer_vulkan/blit_image.cpp9
-rw-r--r--src/video_core/renderer_vulkan/blit_image.h4
-rw-r--r--src/video_core/renderer_vulkan/vk_query_cache.cpp1
-rw-r--r--src/video_core/renderer_vulkan/vk_rasterizer.cpp13
-rw-r--r--src/video_core/renderer_vulkan/vk_render_pass_cache.cpp2
-rw-r--r--src/video_core/renderer_vulkan/vk_texture_cache.cpp23
-rw-r--r--src/video_core/texture_cache/formatter.cpp8
-rw-r--r--src/video_core/texture_cache/samples_helper.h2
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
108void RomFSBuildContext::VisitDirectory(VirtualDir romfs_dir, VirtualDir ext_dir, 108void 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
328VirtualFile RegisteredCache::GetFileAtID(NcaID id) const { 329VirtualFile 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
139VirtualFile CreateRomFS(VirtualDir dir, VirtualDir ext) { 139VirtualFile 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
7namespace FileSys { 7namespace FileSys {
8 8
9CachedVfsDirectory::CachedVfsDirectory(VirtualDir& source_dir) 9CachedVfsDirectory::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
12class CachedVfsDirectory : public ReadOnlyVfsDirectory { 12class CachedVfsDirectory : public ReadOnlyVfsDirectory {
13public: 13public:
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
11namespace FileSys { 11namespace FileSys {
12 12
13ConcatenatedVfsFile::ConcatenatedVfsFile(ConcatenationMap&& concatenation_map_, std::string&& name_) 13ConcatenatedVfsFile::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
31ConcatenatedVfsFile::~ConcatenatedVfsFile() = default; 31ConcatenatedVfsFile::~ConcatenatedVfsFile() = default;
32 32
33VirtualFile ConcatenatedVfsFile::MakeConcatenatedFile(const std::vector<VirtualFile>& files, 33VirtualFile 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
60VirtualFile ConcatenatedVfsFile::MakeConcatenatedFile(u8 filler_byte, 62VirtualFile 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
97std::string ConcatenatedVfsFile::GetName() const { 100std::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
31public: 31public:
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
26namespace {
27static thread_local std::array read_buffer_data_a{
28 Common::ScratchBuffer<u8>(),
29 Common::ScratchBuffer<u8>(),
30};
31static thread_local std::array read_buffer_data_x{
32 Common::ScratchBuffer<u8>(),
33 Common::ScratchBuffer<u8>(),
34};
35} // Anonymous namespace
36
26namespace Service { 37namespace Service {
27 38
28SessionRequestHandler::SessionRequestHandler(Kernel::KernelCore& kernel_, const char* service_name_) 39SessionRequestHandler::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
331std::span<const u8> HLERequestContext::ReadBuffer(std::size_t buffer_index) const { 342std::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
357std::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
372std::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;
62using VideoCore::Surface::PixelFormat; 62using VideoCore::Surface::PixelFormat;
63using namespace Common::Literals; 63using namespace Common::Literals;
64 64
65#ifdef __APPLE__
66constexpr u32 NUM_VERTEX_BUFFERS = 16;
67#else
65constexpr u32 NUM_VERTEX_BUFFERS = 32; 68constexpr u32 NUM_VERTEX_BUFFERS = 32;
69#endif
66constexpr u32 NUM_TRANSFORM_FEEDBACK_BUFFERS = 4; 70constexpr u32 NUM_TRANSFORM_FEEDBACK_BUFFERS = 4;
67constexpr u32 NUM_GRAPHICS_UNIFORM_BUFFERS = 18; 71constexpr u32 NUM_GRAPHICS_UNIFORM_BUFFERS = 18;
68constexpr u32 NUM_COMPUTE_UNIFORM_BUFFERS = 8; 72constexpr 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
6layout(binding = 0) uniform sampler2D color_texture;
7
8void 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
6precision mediump int;
7precision highp float;
8
6layout(binding = 0) uniform sampler2D depth_tex; 9layout(binding = 0) uniform sampler2D depth_tex;
7layout(binding = 1) uniform isampler2D stencil_tex; 10layout(binding = 1) uniform usampler2D stencil_tex;
8 11
9layout(location = 0) out vec4 color; 12layout(location = 0) out vec4 color;
10 13
11void main() { 14void 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
10void main() { 10void 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
6precision mediump int;
7precision highp float;
8
6layout(binding = 0) uniform sampler2D depth_tex; 9layout(binding = 0) uniform sampler2D depth_tex;
7layout(binding = 1) uniform isampler2D stencil_tex; 10layout(binding = 1) uniform usampler2D stencil_tex;
8 11
9layout(location = 0) out vec4 color; 12layout(location = 0) out vec4 color;
10 13
11void main() { 14void 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
564void 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
562void BlitImageHelper::ConvertD32FToABGR8(const Framebuffer* dst_framebuffer, 571void 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
14namespace VideoCommon { 15namespace VideoCommon {
15 16
16std::string Name(const ImageBase& image) { 17std::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) {