summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/core/core.cpp2
-rw-r--r--src/core/crypto/key_manager.cpp44
-rw-r--r--src/core/crypto/key_manager.h9
-rw-r--r--src/core/file_sys/content_archive.cpp33
-rw-r--r--src/core/file_sys/content_archive.h7
-rw-r--r--src/core/file_sys/ips_layer.cpp4
-rw-r--r--src/core/file_sys/patch_manager.cpp9
-rw-r--r--src/core/file_sys/registered_cache.cpp62
-rw-r--r--src/core/file_sys/registered_cache.h23
-rw-r--r--src/core/file_sys/vfs.cpp4
-rw-r--r--src/core/file_sys/vfs.h8
-rw-r--r--src/core/file_sys/vfs_offset.cpp4
-rw-r--r--src/core/file_sys/vfs_offset.h2
-rw-r--r--src/core/file_sys/vfs_static.h4
-rw-r--r--src/core/hle/kernel/thread.cpp8
-rw-r--r--src/core/hle/service/acc/profile_manager.cpp2
-rw-r--r--src/core/hle/service/am/am.cpp2
-rw-r--r--src/core/hle/service/nvflinger/buffer_queue.cpp8
-rw-r--r--src/core/hle/service/nvflinger/buffer_queue.h7
-rw-r--r--src/core/hle/service/nvflinger/nvflinger.cpp12
-rw-r--r--src/core/hle/service/vi/vi.cpp9
-rw-r--r--src/core/loader/loader.h5
-rw-r--r--src/core/memory.cpp2
-rw-r--r--src/core/memory_hook.h15
-rw-r--r--src/tests/core/arm/arm_test_common.cpp10
-rw-r--r--src/tests/core/arm/arm_test_common.h10
-rw-r--r--src/video_core/command_processor.cpp2
-rw-r--r--src/video_core/engines/maxwell_3d.cpp10
-rw-r--r--src/video_core/engines/shader_bytecode.h8
-rw-r--r--src/video_core/macro_interpreter.cpp6
-rw-r--r--src/video_core/macro_interpreter.h5
-rw-r--r--src/video_core/memory_manager.cpp8
-rw-r--r--src/video_core/memory_manager.h7
-rw-r--r--src/video_core/renderer_base.h6
-rw-r--r--src/video_core/renderer_opengl/gl_buffer_cache.cpp2
-rw-r--r--src/video_core/renderer_opengl/gl_primitive_assembler.cpp2
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp2
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.h4
-rw-r--r--src/video_core/renderer_opengl/gl_shader_decompiler.cpp112
-rw-r--r--src/video_core/renderer_opengl/gl_shader_decompiler.h8
-rw-r--r--src/video_core/renderer_opengl/gl_shader_gen.cpp8
-rw-r--r--src/video_core/renderer_opengl/renderer_opengl.cpp11
-rw-r--r--src/video_core/renderer_opengl/renderer_opengl.h3
-rw-r--r--src/yuzu/configuration/configure_input.cpp2
-rw-r--r--src/yuzu/configuration/configure_input.h6
-rw-r--r--src/yuzu/configuration/configure_system.cpp8
-rw-r--r--src/yuzu/debugger/graphics/graphics_surface.cpp4
-rw-r--r--src/yuzu/main.cpp6
-rw-r--r--src/yuzu/main.h5
49 files changed, 274 insertions, 266 deletions
diff --git a/src/core/core.cpp b/src/core/core.cpp
index 6c32154db..6d5b5a2d0 100644
--- a/src/core/core.cpp
+++ b/src/core/core.cpp
@@ -185,7 +185,7 @@ struct System::Impl {
185 LOG_CRITICAL(Core, "Failed to obtain loader for {}!", filepath); 185 LOG_CRITICAL(Core, "Failed to obtain loader for {}!", filepath);
186 return ResultStatus::ErrorGetLoader; 186 return ResultStatus::ErrorGetLoader;
187 } 187 }
188 std::pair<boost::optional<u32>, Loader::ResultStatus> system_mode = 188 std::pair<std::optional<u32>, Loader::ResultStatus> system_mode =
189 app_loader->LoadKernelSystemMode(); 189 app_loader->LoadKernelSystemMode();
190 190
191 if (system_mode.second != Loader::ResultStatus::Success) { 191 if (system_mode.second != Loader::ResultStatus::Success) {
diff --git a/src/core/crypto/key_manager.cpp b/src/core/crypto/key_manager.cpp
index 89ae79eb3..904afa039 100644
--- a/src/core/crypto/key_manager.cpp
+++ b/src/core/crypto/key_manager.cpp
@@ -141,28 +141,28 @@ Key128 DeriveKeyblobMACKey(const Key128& keyblob_key, const Key128& mac_source)
141 return mac_key; 141 return mac_key;
142} 142}
143 143
144boost::optional<Key128> DeriveSDSeed() { 144std::optional<Key128> DeriveSDSeed() {
145 const FileUtil::IOFile save_43(FileUtil::GetUserPath(FileUtil::UserPath::NANDDir) + 145 const FileUtil::IOFile save_43(FileUtil::GetUserPath(FileUtil::UserPath::NANDDir) +
146 "/system/save/8000000000000043", 146 "/system/save/8000000000000043",
147 "rb+"); 147 "rb+");
148 if (!save_43.IsOpen()) 148 if (!save_43.IsOpen())
149 return boost::none; 149 return {};
150 150
151 const FileUtil::IOFile sd_private( 151 const FileUtil::IOFile sd_private(
152 FileUtil::GetUserPath(FileUtil::UserPath::SDMCDir) + "/Nintendo/Contents/private", "rb+"); 152 FileUtil::GetUserPath(FileUtil::UserPath::SDMCDir) + "/Nintendo/Contents/private", "rb+");
153 if (!sd_private.IsOpen()) 153 if (!sd_private.IsOpen())
154 return boost::none; 154 return {};
155 155
156 std::array<u8, 0x10> private_seed{}; 156 std::array<u8, 0x10> private_seed{};
157 if (sd_private.ReadBytes(private_seed.data(), private_seed.size()) != private_seed.size()) { 157 if (sd_private.ReadBytes(private_seed.data(), private_seed.size()) != private_seed.size()) {
158 return boost::none; 158 return {};
159 } 159 }
160 160
161 std::array<u8, 0x10> buffer{}; 161 std::array<u8, 0x10> buffer{};
162 std::size_t offset = 0; 162 std::size_t offset = 0;
163 for (; offset + 0x10 < save_43.GetSize(); ++offset) { 163 for (; offset + 0x10 < save_43.GetSize(); ++offset) {
164 if (!save_43.Seek(offset, SEEK_SET)) { 164 if (!save_43.Seek(offset, SEEK_SET)) {
165 return boost::none; 165 return {};
166 } 166 }
167 167
168 save_43.ReadBytes(buffer.data(), buffer.size()); 168 save_43.ReadBytes(buffer.data(), buffer.size());
@@ -172,12 +172,12 @@ boost::optional<Key128> DeriveSDSeed() {
172 } 172 }
173 173
174 if (!save_43.Seek(offset + 0x10, SEEK_SET)) { 174 if (!save_43.Seek(offset + 0x10, SEEK_SET)) {
175 return boost::none; 175 return {};
176 } 176 }
177 177
178 Key128 seed{}; 178 Key128 seed{};
179 if (save_43.ReadBytes(seed.data(), seed.size()) != seed.size()) { 179 if (save_43.ReadBytes(seed.data(), seed.size()) != seed.size()) {
180 return boost::none; 180 return {};
181 } 181 }
182 return seed; 182 return seed;
183} 183}
@@ -291,26 +291,26 @@ static std::array<u8, target_size> MGF1(const std::array<u8, in_size>& seed) {
291} 291}
292 292
293template <size_t size> 293template <size_t size>
294static boost::optional<u64> FindTicketOffset(const std::array<u8, size>& data) { 294static std::optional<u64> FindTicketOffset(const std::array<u8, size>& data) {
295 u64 offset = 0; 295 u64 offset = 0;
296 for (size_t i = 0x20; i < data.size() - 0x10; ++i) { 296 for (size_t i = 0x20; i < data.size() - 0x10; ++i) {
297 if (data[i] == 0x1) { 297 if (data[i] == 0x1) {
298 offset = i + 1; 298 offset = i + 1;
299 break; 299 break;
300 } else if (data[i] != 0x0) { 300 } else if (data[i] != 0x0) {
301 return boost::none; 301 return {};
302 } 302 }
303 } 303 }
304 304
305 return offset; 305 return offset;
306} 306}
307 307
308boost::optional<std::pair<Key128, Key128>> ParseTicket(const TicketRaw& ticket, 308std::optional<std::pair<Key128, Key128>> ParseTicket(const TicketRaw& ticket,
309 const RSAKeyPair<2048>& key) { 309 const RSAKeyPair<2048>& key) {
310 u32 cert_authority; 310 u32 cert_authority;
311 std::memcpy(&cert_authority, ticket.data() + 0x140, sizeof(cert_authority)); 311 std::memcpy(&cert_authority, ticket.data() + 0x140, sizeof(cert_authority));
312 if (cert_authority == 0) 312 if (cert_authority == 0)
313 return boost::none; 313 return {};
314 if (cert_authority != Common::MakeMagic('R', 'o', 'o', 't')) { 314 if (cert_authority != Common::MakeMagic('R', 'o', 'o', 't')) {
315 LOG_INFO(Crypto, 315 LOG_INFO(Crypto,
316 "Attempting to parse ticket with non-standard certificate authority {:08X}.", 316 "Attempting to parse ticket with non-standard certificate authority {:08X}.",
@@ -321,7 +321,7 @@ boost::optional<std::pair<Key128, Key128>> ParseTicket(const TicketRaw& ticket,
321 std::memcpy(rights_id.data(), ticket.data() + 0x2A0, sizeof(Key128)); 321 std::memcpy(rights_id.data(), ticket.data() + 0x2A0, sizeof(Key128));
322 322
323 if (rights_id == Key128{}) 323 if (rights_id == Key128{})
324 return boost::none; 324 return {};
325 325
326 Key128 key_temp{}; 326 Key128 key_temp{};
327 327
@@ -356,17 +356,17 @@ boost::optional<std::pair<Key128, Key128>> ParseTicket(const TicketRaw& ticket,
356 std::memcpy(m_2.data(), rsa_step.data() + 0x21, m_2.size()); 356 std::memcpy(m_2.data(), rsa_step.data() + 0x21, m_2.size());
357 357
358 if (m_0 != 0) 358 if (m_0 != 0)
359 return boost::none; 359 return {};
360 360
361 m_1 = m_1 ^ MGF1<0x20>(m_2); 361 m_1 = m_1 ^ MGF1<0x20>(m_2);
362 m_2 = m_2 ^ MGF1<0xDF>(m_1); 362 m_2 = m_2 ^ MGF1<0xDF>(m_1);
363 363
364 const auto offset = FindTicketOffset(m_2); 364 const auto offset = FindTicketOffset(m_2);
365 if (offset == boost::none) 365 if (!offset)
366 return boost::none; 366 return {};
367 ASSERT(offset.get() > 0); 367 ASSERT(*offset > 0);
368 368
369 std::memcpy(key_temp.data(), m_2.data() + offset.get(), key_temp.size()); 369 std::memcpy(key_temp.data(), m_2.data() + *offset, key_temp.size());
370 370
371 return std::make_pair(rights_id, key_temp); 371 return std::make_pair(rights_id, key_temp);
372} 372}
@@ -661,8 +661,8 @@ void KeyManager::DeriveSDSeedLazy() {
661 return; 661 return;
662 662
663 const auto res = DeriveSDSeed(); 663 const auto res = DeriveSDSeed();
664 if (res != boost::none) 664 if (res)
665 SetKey(S128KeyType::SDSeed, res.get()); 665 SetKey(S128KeyType::SDSeed, *res);
666} 666}
667 667
668static Key128 CalculateCMAC(const u8* source, size_t size, const Key128& key) { 668static Key128 CalculateCMAC(const u8* source, size_t size, const Key128& key) {
@@ -889,9 +889,9 @@ void KeyManager::DeriveETicket(PartitionDataManager& data) {
889 889
890 for (const auto& raw : res) { 890 for (const auto& raw : res) {
891 const auto pair = ParseTicket(raw, rsa_key); 891 const auto pair = ParseTicket(raw, rsa_key);
892 if (pair == boost::none) 892 if (!pair)
893 continue; 893 continue;
894 const auto& [rid, key] = pair.value(); 894 const auto& [rid, key] = *pair;
895 u128 rights_id; 895 u128 rights_id;
896 std::memcpy(rights_id.data(), rid.data(), rid.size()); 896 std::memcpy(rights_id.data(), rid.data(), rid.size());
897 SetKey(S128KeyType::Titlekey, key, rights_id[1], rights_id[0]); 897 SetKey(S128KeyType::Titlekey, key, rights_id[1], rights_id[0]);
diff --git a/src/core/crypto/key_manager.h b/src/core/crypto/key_manager.h
index cccb3c0ae..22f268c65 100644
--- a/src/core/crypto/key_manager.h
+++ b/src/core/crypto/key_manager.h
@@ -6,9 +6,10 @@
6 6
7#include <array> 7#include <array>
8#include <map> 8#include <map>
9#include <optional>
9#include <string> 10#include <string>
11
10#include <boost/container/flat_map.hpp> 12#include <boost/container/flat_map.hpp>
11#include <boost/optional.hpp>
12#include <fmt/format.h> 13#include <fmt/format.h>
13#include "common/common_types.h" 14#include "common/common_types.h"
14#include "core/crypto/partition_data_manager.h" 15#include "core/crypto/partition_data_manager.h"
@@ -191,14 +192,14 @@ Key128 DeriveMasterKey(const std::array<u8, 0x90>& keyblob, const Key128& master
191std::array<u8, 0x90> DecryptKeyblob(const std::array<u8, 0xB0>& encrypted_keyblob, 192std::array<u8, 0x90> DecryptKeyblob(const std::array<u8, 0xB0>& encrypted_keyblob,
192 const Key128& key); 193 const Key128& key);
193 194
194boost::optional<Key128> DeriveSDSeed(); 195std::optional<Key128> DeriveSDSeed();
195Loader::ResultStatus DeriveSDKeys(std::array<Key256, 2>& sd_keys, KeyManager& keys); 196Loader::ResultStatus DeriveSDKeys(std::array<Key256, 2>& sd_keys, KeyManager& keys);
196 197
197std::vector<TicketRaw> GetTicketblob(const FileUtil::IOFile& ticket_save); 198std::vector<TicketRaw> GetTicketblob(const FileUtil::IOFile& ticket_save);
198 199
199// Returns a pair of {rights_id, titlekey}. Fails if the ticket has no certificate authority (offset 200// Returns a pair of {rights_id, titlekey}. Fails if the ticket has no certificate authority (offset
200// 0x140-0x144 is zero) 201// 0x140-0x144 is zero)
201boost::optional<std::pair<Key128, Key128>> ParseTicket( 202std::optional<std::pair<Key128, Key128>> ParseTicket(const TicketRaw& ticket,
202 const TicketRaw& ticket, const RSAKeyPair<2048>& eticket_extended_key); 203 const RSAKeyPair<2048>& eticket_extended_key);
203 204
204} // namespace Core::Crypto 205} // namespace Core::Crypto
diff --git a/src/core/file_sys/content_archive.cpp b/src/core/file_sys/content_archive.cpp
index 77e04704e..b46fe893c 100644
--- a/src/core/file_sys/content_archive.cpp
+++ b/src/core/file_sys/content_archive.cpp
@@ -4,10 +4,9 @@
4 4
5#include <algorithm> 5#include <algorithm>
6#include <cstring> 6#include <cstring>
7#include <optional>
7#include <utility> 8#include <utility>
8 9
9#include <boost/optional.hpp>
10
11#include "common/logging/log.h" 10#include "common/logging/log.h"
12#include "core/crypto/aes_util.h" 11#include "core/crypto/aes_util.h"
13#include "core/crypto/ctr_encryption_layer.h" 12#include "core/crypto/ctr_encryption_layer.h"
@@ -306,18 +305,18 @@ bool NCA::ReadRomFSSection(const NCASectionHeader& section, const NCASectionTabl
306 subsection_buckets.back().entries.push_back({section.bktr.relocation.offset, {0}, ctr_low}); 305 subsection_buckets.back().entries.push_back({section.bktr.relocation.offset, {0}, ctr_low});
307 subsection_buckets.back().entries.push_back({size, {0}, 0}); 306 subsection_buckets.back().entries.push_back({size, {0}, 0});
308 307
309 boost::optional<Core::Crypto::Key128> key = boost::none; 308 std::optional<Core::Crypto::Key128> key = {};
310 if (encrypted) { 309 if (encrypted) {
311 if (has_rights_id) { 310 if (has_rights_id) {
312 status = Loader::ResultStatus::Success; 311 status = Loader::ResultStatus::Success;
313 key = GetTitlekey(); 312 key = GetTitlekey();
314 if (key == boost::none) { 313 if (!key) {
315 status = Loader::ResultStatus::ErrorMissingTitlekey; 314 status = Loader::ResultStatus::ErrorMissingTitlekey;
316 return false; 315 return false;
317 } 316 }
318 } else { 317 } else {
319 key = GetKeyAreaKey(NCASectionCryptoType::BKTR); 318 key = GetKeyAreaKey(NCASectionCryptoType::BKTR);
320 if (key == boost::none) { 319 if (!key) {
321 status = Loader::ResultStatus::ErrorMissingKeyAreaKey; 320 status = Loader::ResultStatus::ErrorMissingKeyAreaKey;
322 return false; 321 return false;
323 } 322 }
@@ -332,7 +331,7 @@ bool NCA::ReadRomFSSection(const NCASectionHeader& section, const NCASectionTabl
332 auto bktr = std::make_shared<BKTR>( 331 auto bktr = std::make_shared<BKTR>(
333 bktr_base_romfs, std::make_shared<OffsetVfsFile>(file, romfs_size, base_offset), 332 bktr_base_romfs, std::make_shared<OffsetVfsFile>(file, romfs_size, base_offset),
334 relocation_block, relocation_buckets, subsection_block, subsection_buckets, encrypted, 333 relocation_block, relocation_buckets, subsection_block, subsection_buckets, encrypted,
335 encrypted ? key.get() : Core::Crypto::Key128{}, base_offset, bktr_base_ivfc_offset, 334 encrypted ? *key : Core::Crypto::Key128{}, base_offset, bktr_base_ivfc_offset,
336 section.raw.section_ctr); 335 section.raw.section_ctr);
337 336
338 // BKTR applies to entire IVFC, so make an offset version to level 6 337 // BKTR applies to entire IVFC, so make an offset version to level 6
@@ -388,11 +387,11 @@ u8 NCA::GetCryptoRevision() const {
388 return master_key_id; 387 return master_key_id;
389} 388}
390 389
391boost::optional<Core::Crypto::Key128> NCA::GetKeyAreaKey(NCASectionCryptoType type) const { 390std::optional<Core::Crypto::Key128> NCA::GetKeyAreaKey(NCASectionCryptoType type) const {
392 const auto master_key_id = GetCryptoRevision(); 391 const auto master_key_id = GetCryptoRevision();
393 392
394 if (!keys.HasKey(Core::Crypto::S128KeyType::KeyArea, master_key_id, header.key_index)) 393 if (!keys.HasKey(Core::Crypto::S128KeyType::KeyArea, master_key_id, header.key_index))
395 return boost::none; 394 return {};
396 395
397 std::vector<u8> key_area(header.key_area.begin(), header.key_area.end()); 396 std::vector<u8> key_area(header.key_area.begin(), header.key_area.end());
398 Core::Crypto::AESCipher<Core::Crypto::Key128> cipher( 397 Core::Crypto::AESCipher<Core::Crypto::Key128> cipher(
@@ -416,25 +415,25 @@ boost::optional<Core::Crypto::Key128> NCA::GetKeyAreaKey(NCASectionCryptoType ty
416 return out; 415 return out;
417} 416}
418 417
419boost::optional<Core::Crypto::Key128> NCA::GetTitlekey() { 418std::optional<Core::Crypto::Key128> NCA::GetTitlekey() {
420 const auto master_key_id = GetCryptoRevision(); 419 const auto master_key_id = GetCryptoRevision();
421 420
422 u128 rights_id{}; 421 u128 rights_id{};
423 memcpy(rights_id.data(), header.rights_id.data(), 16); 422 memcpy(rights_id.data(), header.rights_id.data(), 16);
424 if (rights_id == u128{}) { 423 if (rights_id == u128{}) {
425 status = Loader::ResultStatus::ErrorInvalidRightsID; 424 status = Loader::ResultStatus::ErrorInvalidRightsID;
426 return boost::none; 425 return {};
427 } 426 }
428 427
429 auto titlekey = keys.GetKey(Core::Crypto::S128KeyType::Titlekey, rights_id[1], rights_id[0]); 428 auto titlekey = keys.GetKey(Core::Crypto::S128KeyType::Titlekey, rights_id[1], rights_id[0]);
430 if (titlekey == Core::Crypto::Key128{}) { 429 if (titlekey == Core::Crypto::Key128{}) {
431 status = Loader::ResultStatus::ErrorMissingTitlekey; 430 status = Loader::ResultStatus::ErrorMissingTitlekey;
432 return boost::none; 431 return {};
433 } 432 }
434 433
435 if (!keys.HasKey(Core::Crypto::S128KeyType::Titlekek, master_key_id)) { 434 if (!keys.HasKey(Core::Crypto::S128KeyType::Titlekek, master_key_id)) {
436 status = Loader::ResultStatus::ErrorMissingTitlekek; 435 status = Loader::ResultStatus::ErrorMissingTitlekek;
437 return boost::none; 436 return {};
438 } 437 }
439 438
440 Core::Crypto::AESCipher<Core::Crypto::Key128> cipher( 439 Core::Crypto::AESCipher<Core::Crypto::Key128> cipher(
@@ -458,25 +457,25 @@ VirtualFile NCA::Decrypt(const NCASectionHeader& s_header, VirtualFile in, u64 s
458 case NCASectionCryptoType::BKTR: 457 case NCASectionCryptoType::BKTR:
459 LOG_DEBUG(Crypto, "called with mode=CTR, starting_offset={:016X}", starting_offset); 458 LOG_DEBUG(Crypto, "called with mode=CTR, starting_offset={:016X}", starting_offset);
460 { 459 {
461 boost::optional<Core::Crypto::Key128> key = boost::none; 460 std::optional<Core::Crypto::Key128> key = {};
462 if (has_rights_id) { 461 if (has_rights_id) {
463 status = Loader::ResultStatus::Success; 462 status = Loader::ResultStatus::Success;
464 key = GetTitlekey(); 463 key = GetTitlekey();
465 if (key == boost::none) { 464 if (!key) {
466 if (status == Loader::ResultStatus::Success) 465 if (status == Loader::ResultStatus::Success)
467 status = Loader::ResultStatus::ErrorMissingTitlekey; 466 status = Loader::ResultStatus::ErrorMissingTitlekey;
468 return nullptr; 467 return nullptr;
469 } 468 }
470 } else { 469 } else {
471 key = GetKeyAreaKey(NCASectionCryptoType::CTR); 470 key = GetKeyAreaKey(NCASectionCryptoType::CTR);
472 if (key == boost::none) { 471 if (!key) {
473 status = Loader::ResultStatus::ErrorMissingKeyAreaKey; 472 status = Loader::ResultStatus::ErrorMissingKeyAreaKey;
474 return nullptr; 473 return nullptr;
475 } 474 }
476 } 475 }
477 476
478 auto out = std::make_shared<Core::Crypto::CTREncryptionLayer>( 477 auto out = std::make_shared<Core::Crypto::CTREncryptionLayer>(std::move(in), *key,
479 std::move(in), key.value(), starting_offset); 478 starting_offset);
480 std::vector<u8> iv(16); 479 std::vector<u8> iv(16);
481 for (u8 i = 0; i < 8; ++i) 480 for (u8 i = 0; i < 8; ++i)
482 iv[i] = s_header.raw.section_ctr[0x8 - i - 1]; 481 iv[i] = s_header.raw.section_ctr[0x8 - i - 1];
diff --git a/src/core/file_sys/content_archive.h b/src/core/file_sys/content_archive.h
index 211946686..4bba55607 100644
--- a/src/core/file_sys/content_archive.h
+++ b/src/core/file_sys/content_archive.h
@@ -6,9 +6,10 @@
6 6
7#include <array> 7#include <array>
8#include <memory> 8#include <memory>
9#include <optional>
9#include <string> 10#include <string>
10#include <vector> 11#include <vector>
11#include <boost/optional.hpp> 12
12#include "common/common_funcs.h" 13#include "common/common_funcs.h"
13#include "common/common_types.h" 14#include "common/common_types.h"
14#include "common/swap.h" 15#include "common/swap.h"
@@ -111,8 +112,8 @@ private:
111 bool ReadPFS0Section(const NCASectionHeader& section, const NCASectionTableEntry& entry); 112 bool ReadPFS0Section(const NCASectionHeader& section, const NCASectionTableEntry& entry);
112 113
113 u8 GetCryptoRevision() const; 114 u8 GetCryptoRevision() const;
114 boost::optional<Core::Crypto::Key128> GetKeyAreaKey(NCASectionCryptoType type) const; 115 std::optional<Core::Crypto::Key128> GetKeyAreaKey(NCASectionCryptoType type) const;
115 boost::optional<Core::Crypto::Key128> GetTitlekey(); 116 std::optional<Core::Crypto::Key128> GetTitlekey();
116 VirtualFile Decrypt(const NCASectionHeader& header, VirtualFile in, u64 starting_offset); 117 VirtualFile Decrypt(const NCASectionHeader& header, VirtualFile in, u64 starting_offset);
117 118
118 std::vector<VirtualDir> dirs; 119 std::vector<VirtualDir> dirs;
diff --git a/src/core/file_sys/ips_layer.cpp b/src/core/file_sys/ips_layer.cpp
index 999939d5a..485c4913a 100644
--- a/src/core/file_sys/ips_layer.cpp
+++ b/src/core/file_sys/ips_layer.cpp
@@ -103,12 +103,12 @@ VirtualFile PatchIPS(const VirtualFile& in, const VirtualFile& ips) {
103 offset += sizeof(u16); 103 offset += sizeof(u16);
104 104
105 const auto data = ips->ReadByte(offset++); 105 const auto data = ips->ReadByte(offset++);
106 if (data == boost::none) 106 if (!data)
107 return nullptr; 107 return nullptr;
108 108
109 if (real_offset + rle_size > in_data.size()) 109 if (real_offset + rle_size > in_data.size())
110 rle_size = static_cast<u16>(in_data.size() - real_offset); 110 rle_size = static_cast<u16>(in_data.size() - real_offset);
111 std::memset(in_data.data() + real_offset, data.get(), rle_size); 111 std::memset(in_data.data() + real_offset, *data, rle_size);
112 } else { // Standard Patch 112 } else { // Standard Patch
113 auto read = data_size; 113 auto read = data_size;
114 if (real_offset + read > in_data.size()) 114 if (real_offset + read > in_data.size())
diff --git a/src/core/file_sys/patch_manager.cpp b/src/core/file_sys/patch_manager.cpp
index cb457b987..0c1156989 100644
--- a/src/core/file_sys/patch_manager.cpp
+++ b/src/core/file_sys/patch_manager.cpp
@@ -65,7 +65,7 @@ VirtualDir PatchManager::PatchExeFS(VirtualDir exefs) const {
65 if (update != nullptr && update->GetExeFS() != nullptr && 65 if (update != nullptr && update->GetExeFS() != nullptr &&
66 update->GetStatus() == Loader::ResultStatus::ErrorMissingBKTRBaseRomFS) { 66 update->GetStatus() == Loader::ResultStatus::ErrorMissingBKTRBaseRomFS) {
67 LOG_INFO(Loader, " ExeFS: Update ({}) applied successfully", 67 LOG_INFO(Loader, " ExeFS: Update ({}) applied successfully",
68 FormatTitleVersion(installed->GetEntryVersion(update_tid).get_value_or(0))); 68 FormatTitleVersion(installed->GetEntryVersion(update_tid).value_or(0)));
69 exefs = update->GetExeFS(); 69 exefs = update->GetExeFS();
70 } 70 }
71 71
@@ -236,7 +236,7 @@ VirtualFile PatchManager::PatchRomFS(VirtualFile romfs, u64 ivfc_offset, Content
236 if (new_nca->GetStatus() == Loader::ResultStatus::Success && 236 if (new_nca->GetStatus() == Loader::ResultStatus::Success &&
237 new_nca->GetRomFS() != nullptr) { 237 new_nca->GetRomFS() != nullptr) {
238 LOG_INFO(Loader, " RomFS: Update ({}) applied successfully", 238 LOG_INFO(Loader, " RomFS: Update ({}) applied successfully",
239 FormatTitleVersion(installed->GetEntryVersion(update_tid).get_value_or(0))); 239 FormatTitleVersion(installed->GetEntryVersion(update_tid).value_or(0)));
240 romfs = new_nca->GetRomFS(); 240 romfs = new_nca->GetRomFS();
241 } 241 }
242 } else if (update_raw != nullptr) { 242 } else if (update_raw != nullptr) {
@@ -280,12 +280,11 @@ std::map<std::string, std::string, std::less<>> PatchManager::GetPatchVersionNam
280 } else { 280 } else {
281 if (installed->HasEntry(update_tid, ContentRecordType::Program)) { 281 if (installed->HasEntry(update_tid, ContentRecordType::Program)) {
282 const auto meta_ver = installed->GetEntryVersion(update_tid); 282 const auto meta_ver = installed->GetEntryVersion(update_tid);
283 if (meta_ver == boost::none || meta_ver.get() == 0) { 283 if (meta_ver.value_or(0) == 0) {
284 out.insert_or_assign("Update", ""); 284 out.insert_or_assign("Update", "");
285 } else { 285 } else {
286 out.insert_or_assign( 286 out.insert_or_assign(
287 "Update", 287 "Update", FormatTitleVersion(*meta_ver, TitleVersionFormat::ThreeElements));
288 FormatTitleVersion(meta_ver.get(), TitleVersionFormat::ThreeElements));
289 } 288 }
290 } else if (update_raw != nullptr) { 289 } else if (update_raw != nullptr) {
291 out.insert_or_assign("Update", "PACKED"); 290 out.insert_or_assign("Update", "PACKED");
diff --git a/src/core/file_sys/registered_cache.cpp b/src/core/file_sys/registered_cache.cpp
index 29b100414..96302a241 100644
--- a/src/core/file_sys/registered_cache.cpp
+++ b/src/core/file_sys/registered_cache.cpp
@@ -159,28 +159,28 @@ VirtualFile RegisteredCache::GetFileAtID(NcaID id) const {
159 return file; 159 return file;
160} 160}
161 161
162static boost::optional<NcaID> CheckMapForContentRecord( 162static std::optional<NcaID> CheckMapForContentRecord(
163 const boost::container::flat_map<u64, CNMT>& map, u64 title_id, ContentRecordType type) { 163 const boost::container::flat_map<u64, CNMT>& map, u64 title_id, ContentRecordType type) {
164 if (map.find(title_id) == map.end()) 164 if (map.find(title_id) == map.end())
165 return boost::none; 165 return {};
166 166
167 const auto& cnmt = map.at(title_id); 167 const auto& cnmt = map.at(title_id);
168 168
169 const auto iter = std::find_if(cnmt.GetContentRecords().begin(), cnmt.GetContentRecords().end(), 169 const auto iter = std::find_if(cnmt.GetContentRecords().begin(), cnmt.GetContentRecords().end(),
170 [type](const ContentRecord& rec) { return rec.type == type; }); 170 [type](const ContentRecord& rec) { return rec.type == type; });
171 if (iter == cnmt.GetContentRecords().end()) 171 if (iter == cnmt.GetContentRecords().end())
172 return boost::none; 172 return {};
173 173
174 return boost::make_optional(iter->nca_id); 174 return std::make_optional(iter->nca_id);
175} 175}
176 176
177boost::optional<NcaID> RegisteredCache::GetNcaIDFromMetadata(u64 title_id, 177std::optional<NcaID> RegisteredCache::GetNcaIDFromMetadata(u64 title_id,
178 ContentRecordType type) const { 178 ContentRecordType type) const {
179 if (type == ContentRecordType::Meta && meta_id.find(title_id) != meta_id.end()) 179 if (type == ContentRecordType::Meta && meta_id.find(title_id) != meta_id.end())
180 return meta_id.at(title_id); 180 return meta_id.at(title_id);
181 181
182 const auto res1 = CheckMapForContentRecord(yuzu_meta, title_id, type); 182 const auto res1 = CheckMapForContentRecord(yuzu_meta, title_id, type);
183 if (res1 != boost::none) 183 if (res1)
184 return res1; 184 return res1;
185 return CheckMapForContentRecord(meta, title_id, type); 185 return CheckMapForContentRecord(meta, title_id, type);
186} 186}
@@ -283,17 +283,14 @@ bool RegisteredCache::HasEntry(RegisteredCacheEntry entry) const {
283 283
284VirtualFile RegisteredCache::GetEntryUnparsed(u64 title_id, ContentRecordType type) const { 284VirtualFile RegisteredCache::GetEntryUnparsed(u64 title_id, ContentRecordType type) const {
285 const auto id = GetNcaIDFromMetadata(title_id, type); 285 const auto id = GetNcaIDFromMetadata(title_id, type);
286 if (id == boost::none) 286 return id ? GetFileAtID(*id) : nullptr;
287 return nullptr;
288
289 return GetFileAtID(id.get());
290} 287}
291 288
292VirtualFile RegisteredCache::GetEntryUnparsed(RegisteredCacheEntry entry) const { 289VirtualFile RegisteredCache::GetEntryUnparsed(RegisteredCacheEntry entry) const {
293 return GetEntryUnparsed(entry.title_id, entry.type); 290 return GetEntryUnparsed(entry.title_id, entry.type);
294} 291}
295 292
296boost::optional<u32> RegisteredCache::GetEntryVersion(u64 title_id) const { 293std::optional<u32> RegisteredCache::GetEntryVersion(u64 title_id) const {
297 const auto meta_iter = meta.find(title_id); 294 const auto meta_iter = meta.find(title_id);
298 if (meta_iter != meta.end()) 295 if (meta_iter != meta.end())
299 return meta_iter->second.GetTitleVersion(); 296 return meta_iter->second.GetTitleVersion();
@@ -302,15 +299,12 @@ boost::optional<u32> RegisteredCache::GetEntryVersion(u64 title_id) const {
302 if (yuzu_meta_iter != yuzu_meta.end()) 299 if (yuzu_meta_iter != yuzu_meta.end())
303 return yuzu_meta_iter->second.GetTitleVersion(); 300 return yuzu_meta_iter->second.GetTitleVersion();
304 301
305 return boost::none; 302 return {};
306} 303}
307 304
308VirtualFile RegisteredCache::GetEntryRaw(u64 title_id, ContentRecordType type) const { 305VirtualFile RegisteredCache::GetEntryRaw(u64 title_id, ContentRecordType type) const {
309 const auto id = GetNcaIDFromMetadata(title_id, type); 306 const auto id = GetNcaIDFromMetadata(title_id, type);
310 if (id == boost::none) 307 return id ? parser(GetFileAtID(*id), *id) : nullptr;
311 return nullptr;
312
313 return parser(GetFileAtID(id.get()), id.get());
314} 308}
315 309
316VirtualFile RegisteredCache::GetEntryRaw(RegisteredCacheEntry entry) const { 310VirtualFile RegisteredCache::GetEntryRaw(RegisteredCacheEntry entry) const {
@@ -364,8 +358,8 @@ std::vector<RegisteredCacheEntry> RegisteredCache::ListEntries() const {
364} 358}
365 359
366std::vector<RegisteredCacheEntry> RegisteredCache::ListEntriesFilter( 360std::vector<RegisteredCacheEntry> RegisteredCache::ListEntriesFilter(
367 boost::optional<TitleType> title_type, boost::optional<ContentRecordType> record_type, 361 std::optional<TitleType> title_type, std::optional<ContentRecordType> record_type,
368 boost::optional<u64> title_id) const { 362 std::optional<u64> title_id) const {
369 std::vector<RegisteredCacheEntry> out; 363 std::vector<RegisteredCacheEntry> out;
370 IterateAllMetadata<RegisteredCacheEntry>( 364 IterateAllMetadata<RegisteredCacheEntry>(
371 out, 365 out,
@@ -373,11 +367,11 @@ std::vector<RegisteredCacheEntry> RegisteredCache::ListEntriesFilter(
373 return RegisteredCacheEntry{c.GetTitleID(), r.type}; 367 return RegisteredCacheEntry{c.GetTitleID(), r.type};
374 }, 368 },
375 [&title_type, &record_type, &title_id](const CNMT& c, const ContentRecord& r) { 369 [&title_type, &record_type, &title_id](const CNMT& c, const ContentRecord& r) {
376 if (title_type != boost::none && title_type.get() != c.GetType()) 370 if (title_type && *title_type != c.GetType())
377 return false; 371 return false;
378 if (record_type != boost::none && record_type.get() != r.type) 372 if (record_type && *record_type != r.type)
379 return false; 373 return false;
380 if (title_id != boost::none && title_id.get() != c.GetTitleID()) 374 if (title_id && *title_id != c.GetTitleID())
381 return false; 375 return false;
382 return true; 376 return true;
383 }); 377 });
@@ -459,7 +453,7 @@ InstallResult RegisteredCache::InstallEntry(std::shared_ptr<NCA> nca, TitleType
459 453
460InstallResult RegisteredCache::RawInstallNCA(std::shared_ptr<NCA> nca, const VfsCopyFunction& copy, 454InstallResult RegisteredCache::RawInstallNCA(std::shared_ptr<NCA> nca, const VfsCopyFunction& copy,
461 bool overwrite_if_exists, 455 bool overwrite_if_exists,
462 boost::optional<NcaID> override_id) { 456 std::optional<NcaID> override_id) {
463 const auto in = nca->GetBaseFile(); 457 const auto in = nca->GetBaseFile();
464 Core::Crypto::SHA256Hash hash{}; 458 Core::Crypto::SHA256Hash hash{};
465 459
@@ -468,12 +462,12 @@ InstallResult RegisteredCache::RawInstallNCA(std::shared_ptr<NCA> nca, const Vfs
468 // game is massive), we're going to cheat and only hash the first MB of the NCA. 462 // game is massive), we're going to cheat and only hash the first MB of the NCA.
469 // Also, for XCIs the NcaID matters, so if the override id isn't none, use that. 463 // Also, for XCIs the NcaID matters, so if the override id isn't none, use that.
470 NcaID id{}; 464 NcaID id{};
471 if (override_id == boost::none) { 465 if (override_id) {
466 id = *override_id;
467 } else {
472 const auto& data = in->ReadBytes(0x100000); 468 const auto& data = in->ReadBytes(0x100000);
473 mbedtls_sha256(data.data(), data.size(), hash.data(), 0); 469 mbedtls_sha256(data.data(), data.size(), hash.data(), 0);
474 memcpy(id.data(), hash.data(), 16); 470 memcpy(id.data(), hash.data(), 16);
475 } else {
476 id = override_id.get();
477 } 471 }
478 472
479 std::string path = GetRelativePathFromNcaID(id, false, true); 473 std::string path = GetRelativePathFromNcaID(id, false, true);
@@ -543,14 +537,14 @@ bool RegisteredCacheUnion::HasEntry(RegisteredCacheEntry entry) const {
543 return HasEntry(entry.title_id, entry.type); 537 return HasEntry(entry.title_id, entry.type);
544} 538}
545 539
546boost::optional<u32> RegisteredCacheUnion::GetEntryVersion(u64 title_id) const { 540std::optional<u32> RegisteredCacheUnion::GetEntryVersion(u64 title_id) const {
547 for (const auto& c : caches) { 541 for (const auto& c : caches) {
548 const auto res = c->GetEntryVersion(title_id); 542 const auto res = c->GetEntryVersion(title_id);
549 if (res != boost::none) 543 if (res)
550 return res; 544 return res;
551 } 545 }
552 546
553 return boost::none; 547 return {};
554} 548}
555 549
556VirtualFile RegisteredCacheUnion::GetEntryUnparsed(u64 title_id, ContentRecordType type) const { 550VirtualFile RegisteredCacheUnion::GetEntryUnparsed(u64 title_id, ContentRecordType type) const {
@@ -609,8 +603,8 @@ std::vector<RegisteredCacheEntry> RegisteredCacheUnion::ListEntries() const {
609} 603}
610 604
611std::vector<RegisteredCacheEntry> RegisteredCacheUnion::ListEntriesFilter( 605std::vector<RegisteredCacheEntry> RegisteredCacheUnion::ListEntriesFilter(
612 boost::optional<TitleType> title_type, boost::optional<ContentRecordType> record_type, 606 std::optional<TitleType> title_type, std::optional<ContentRecordType> record_type,
613 boost::optional<u64> title_id) const { 607 std::optional<u64> title_id) const {
614 std::vector<RegisteredCacheEntry> out; 608 std::vector<RegisteredCacheEntry> out;
615 for (const auto& c : caches) { 609 for (const auto& c : caches) {
616 c->IterateAllMetadata<RegisteredCacheEntry>( 610 c->IterateAllMetadata<RegisteredCacheEntry>(
@@ -619,11 +613,11 @@ std::vector<RegisteredCacheEntry> RegisteredCacheUnion::ListEntriesFilter(
619 return RegisteredCacheEntry{c.GetTitleID(), r.type}; 613 return RegisteredCacheEntry{c.GetTitleID(), r.type};
620 }, 614 },
621 [&title_type, &record_type, &title_id](const CNMT& c, const ContentRecord& r) { 615 [&title_type, &record_type, &title_id](const CNMT& c, const ContentRecord& r) {
622 if (title_type != boost::none && title_type.get() != c.GetType()) 616 if (title_type && *title_type != c.GetType())
623 return false; 617 return false;
624 if (record_type != boost::none && record_type.get() != r.type) 618 if (record_type && *record_type != r.type)
625 return false; 619 return false;
626 if (title_id != boost::none && title_id.get() != c.GetTitleID()) 620 if (title_id && *title_id != c.GetTitleID())
627 return false; 621 return false;
628 return true; 622 return true;
629 }); 623 });
diff --git a/src/core/file_sys/registered_cache.h b/src/core/file_sys/registered_cache.h
index 5beceffb3..6cfb16017 100644
--- a/src/core/file_sys/registered_cache.h
+++ b/src/core/file_sys/registered_cache.h
@@ -84,7 +84,7 @@ public:
84 bool HasEntry(u64 title_id, ContentRecordType type) const; 84 bool HasEntry(u64 title_id, ContentRecordType type) const;
85 bool HasEntry(RegisteredCacheEntry entry) const; 85 bool HasEntry(RegisteredCacheEntry entry) const;
86 86
87 boost::optional<u32> GetEntryVersion(u64 title_id) const; 87 std::optional<u32> GetEntryVersion(u64 title_id) const;
88 88
89 VirtualFile GetEntryUnparsed(u64 title_id, ContentRecordType type) const; 89 VirtualFile GetEntryUnparsed(u64 title_id, ContentRecordType type) const;
90 VirtualFile GetEntryUnparsed(RegisteredCacheEntry entry) const; 90 VirtualFile GetEntryUnparsed(RegisteredCacheEntry entry) const;
@@ -96,11 +96,10 @@ public:
96 std::unique_ptr<NCA> GetEntry(RegisteredCacheEntry entry) const; 96 std::unique_ptr<NCA> GetEntry(RegisteredCacheEntry entry) const;
97 97
98 std::vector<RegisteredCacheEntry> ListEntries() const; 98 std::vector<RegisteredCacheEntry> ListEntries() const;
99 // If a parameter is not boost::none, it will be filtered for from all entries. 99 // If a parameter is not std::nullopt, it will be filtered for from all entries.
100 std::vector<RegisteredCacheEntry> ListEntriesFilter( 100 std::vector<RegisteredCacheEntry> ListEntriesFilter(
101 boost::optional<TitleType> title_type = boost::none, 101 std::optional<TitleType> title_type = {}, std::optional<ContentRecordType> record_type = {},
102 boost::optional<ContentRecordType> record_type = boost::none, 102 std::optional<u64> title_id = {}) const;
103 boost::optional<u64> title_id = boost::none) const;
104 103
105 // Raw copies all the ncas from the xci/nsp to the csache. Does some quick checks to make sure 104 // Raw copies all the ncas from the xci/nsp to the csache. Does some quick checks to make sure
106 // there is a meta NCA and all of them are accessible. 105 // there is a meta NCA and all of them are accessible.
@@ -125,12 +124,11 @@ private:
125 std::vector<NcaID> AccumulateFiles() const; 124 std::vector<NcaID> AccumulateFiles() const;
126 void ProcessFiles(const std::vector<NcaID>& ids); 125 void ProcessFiles(const std::vector<NcaID>& ids);
127 void AccumulateYuzuMeta(); 126 void AccumulateYuzuMeta();
128 boost::optional<NcaID> GetNcaIDFromMetadata(u64 title_id, ContentRecordType type) const; 127 std::optional<NcaID> GetNcaIDFromMetadata(u64 title_id, ContentRecordType type) const;
129 VirtualFile GetFileAtID(NcaID id) const; 128 VirtualFile GetFileAtID(NcaID id) const;
130 VirtualFile OpenFileOrDirectoryConcat(const VirtualDir& dir, std::string_view path) const; 129 VirtualFile OpenFileOrDirectoryConcat(const VirtualDir& dir, std::string_view path) const;
131 InstallResult RawInstallNCA(std::shared_ptr<NCA> nca, const VfsCopyFunction& copy, 130 InstallResult RawInstallNCA(std::shared_ptr<NCA> nca, const VfsCopyFunction& copy,
132 bool overwrite_if_exists, 131 bool overwrite_if_exists, std::optional<NcaID> override_id = {});
133 boost::optional<NcaID> override_id = boost::none);
134 bool RawInstallYuzuMeta(const CNMT& cnmt); 132 bool RawInstallYuzuMeta(const CNMT& cnmt);
135 133
136 VirtualDir dir; 134 VirtualDir dir;
@@ -153,7 +151,7 @@ public:
153 bool HasEntry(u64 title_id, ContentRecordType type) const; 151 bool HasEntry(u64 title_id, ContentRecordType type) const;
154 bool HasEntry(RegisteredCacheEntry entry) const; 152 bool HasEntry(RegisteredCacheEntry entry) const;
155 153
156 boost::optional<u32> GetEntryVersion(u64 title_id) const; 154 std::optional<u32> GetEntryVersion(u64 title_id) const;
157 155
158 VirtualFile GetEntryUnparsed(u64 title_id, ContentRecordType type) const; 156 VirtualFile GetEntryUnparsed(u64 title_id, ContentRecordType type) const;
159 VirtualFile GetEntryUnparsed(RegisteredCacheEntry entry) const; 157 VirtualFile GetEntryUnparsed(RegisteredCacheEntry entry) const;
@@ -165,11 +163,10 @@ public:
165 std::unique_ptr<NCA> GetEntry(RegisteredCacheEntry entry) const; 163 std::unique_ptr<NCA> GetEntry(RegisteredCacheEntry entry) const;
166 164
167 std::vector<RegisteredCacheEntry> ListEntries() const; 165 std::vector<RegisteredCacheEntry> ListEntries() const;
168 // If a parameter is not boost::none, it will be filtered for from all entries. 166 // If a parameter is not std::nullopt, it will be filtered for from all entries.
169 std::vector<RegisteredCacheEntry> ListEntriesFilter( 167 std::vector<RegisteredCacheEntry> ListEntriesFilter(
170 boost::optional<TitleType> title_type = boost::none, 168 std::optional<TitleType> title_type = {}, std::optional<ContentRecordType> record_type = {},
171 boost::optional<ContentRecordType> record_type = boost::none, 169 std::optional<u64> title_id = {}) const;
172 boost::optional<u64> title_id = boost::none) const;
173 170
174private: 171private:
175 std::vector<RegisteredCache*> caches; 172 std::vector<RegisteredCache*> caches;
diff --git a/src/core/file_sys/vfs.cpp b/src/core/file_sys/vfs.cpp
index 3824c74e0..7b584de7f 100644
--- a/src/core/file_sys/vfs.cpp
+++ b/src/core/file_sys/vfs.cpp
@@ -167,13 +167,13 @@ std::string VfsFile::GetExtension() const {
167 167
168VfsDirectory::~VfsDirectory() = default; 168VfsDirectory::~VfsDirectory() = default;
169 169
170boost::optional<u8> VfsFile::ReadByte(std::size_t offset) const { 170std::optional<u8> VfsFile::ReadByte(std::size_t offset) const {
171 u8 out{}; 171 u8 out{};
172 std::size_t size = Read(&out, 1, offset); 172 std::size_t size = Read(&out, 1, offset);
173 if (size == 1) 173 if (size == 1)
174 return out; 174 return out;
175 175
176 return boost::none; 176 return {};
177} 177}
178 178
179std::vector<u8> VfsFile::ReadBytes(std::size_t size, std::size_t offset) const { 179std::vector<u8> VfsFile::ReadBytes(std::size_t size, std::size_t offset) const {
diff --git a/src/core/file_sys/vfs.h b/src/core/file_sys/vfs.h
index 09dc9f288..002f99d4e 100644
--- a/src/core/file_sys/vfs.h
+++ b/src/core/file_sys/vfs.h
@@ -4,13 +4,15 @@
4 4
5#pragma once 5#pragma once
6 6
7#include <functional>
7#include <map> 8#include <map>
8#include <memory> 9#include <memory>
10#include <optional>
9#include <string> 11#include <string>
10#include <string_view> 12#include <string_view>
11#include <type_traits> 13#include <type_traits>
12#include <vector> 14#include <vector>
13#include <boost/optional.hpp> 15
14#include "common/common_types.h" 16#include "common/common_types.h"
15#include "core/file_sys/vfs_types.h" 17#include "core/file_sys/vfs_types.h"
16 18
@@ -103,8 +105,8 @@ public:
103 // into file. Returns number of bytes successfully written. 105 // into file. Returns number of bytes successfully written.
104 virtual std::size_t Write(const u8* data, std::size_t length, std::size_t offset = 0) = 0; 106 virtual std::size_t Write(const u8* data, std::size_t length, std::size_t offset = 0) = 0;
105 107
106 // Reads exactly one byte at the offset provided, returning boost::none on error. 108 // Reads exactly one byte at the offset provided, returning std::nullopt on error.
107 virtual boost::optional<u8> ReadByte(std::size_t offset = 0) const; 109 virtual std::optional<u8> ReadByte(std::size_t offset = 0) const;
108 // Reads size bytes starting at offset in file into a vector. 110 // Reads size bytes starting at offset in file into a vector.
109 virtual std::vector<u8> ReadBytes(std::size_t size, std::size_t offset = 0) const; 111 virtual std::vector<u8> ReadBytes(std::size_t size, std::size_t offset = 0) const;
110 // Reads all the bytes from the file into a vector. Equivalent to 'file->Read(file->GetSize(), 112 // Reads all the bytes from the file into a vector. Equivalent to 'file->Read(file->GetSize(),
diff --git a/src/core/file_sys/vfs_offset.cpp b/src/core/file_sys/vfs_offset.cpp
index a4c6719a0..c96f88488 100644
--- a/src/core/file_sys/vfs_offset.cpp
+++ b/src/core/file_sys/vfs_offset.cpp
@@ -57,11 +57,11 @@ std::size_t OffsetVfsFile::Write(const u8* data, std::size_t length, std::size_t
57 return file->Write(data, TrimToFit(length, r_offset), offset + r_offset); 57 return file->Write(data, TrimToFit(length, r_offset), offset + r_offset);
58} 58}
59 59
60boost::optional<u8> OffsetVfsFile::ReadByte(std::size_t r_offset) const { 60std::optional<u8> OffsetVfsFile::ReadByte(std::size_t r_offset) const {
61 if (r_offset < size) 61 if (r_offset < size)
62 return file->ReadByte(offset + r_offset); 62 return file->ReadByte(offset + r_offset);
63 63
64 return boost::none; 64 return {};
65} 65}
66 66
67std::vector<u8> OffsetVfsFile::ReadBytes(std::size_t r_size, std::size_t r_offset) const { 67std::vector<u8> OffsetVfsFile::ReadBytes(std::size_t r_size, std::size_t r_offset) const {
diff --git a/src/core/file_sys/vfs_offset.h b/src/core/file_sys/vfs_offset.h
index 8062702a7..f7b7a3256 100644
--- a/src/core/file_sys/vfs_offset.h
+++ b/src/core/file_sys/vfs_offset.h
@@ -29,7 +29,7 @@ public:
29 bool IsReadable() const override; 29 bool IsReadable() const override;
30 std::size_t Read(u8* data, std::size_t length, std::size_t offset) const override; 30 std::size_t Read(u8* data, std::size_t length, std::size_t offset) const override;
31 std::size_t Write(const u8* data, std::size_t length, std::size_t offset) override; 31 std::size_t Write(const u8* data, std::size_t length, std::size_t offset) override;
32 boost::optional<u8> ReadByte(std::size_t offset) const override; 32 std::optional<u8> ReadByte(std::size_t offset) const override;
33 std::vector<u8> ReadBytes(std::size_t size, std::size_t offset) const override; 33 std::vector<u8> ReadBytes(std::size_t size, std::size_t offset) const override;
34 std::vector<u8> ReadAllBytes() const override; 34 std::vector<u8> ReadAllBytes() const override;
35 bool WriteByte(u8 data, std::size_t offset) override; 35 bool WriteByte(u8 data, std::size_t offset) override;
diff --git a/src/core/file_sys/vfs_static.h b/src/core/file_sys/vfs_static.h
index 44fab51d1..9f5a90b1b 100644
--- a/src/core/file_sys/vfs_static.h
+++ b/src/core/file_sys/vfs_static.h
@@ -53,10 +53,10 @@ public:
53 return 0; 53 return 0;
54 } 54 }
55 55
56 boost::optional<u8> ReadByte(std::size_t offset) const override { 56 std::optional<u8> ReadByte(std::size_t offset) const override {
57 if (offset < size) 57 if (offset < size)
58 return value; 58 return value;
59 return boost::none; 59 return {};
60 } 60 }
61 61
62 std::vector<u8> ReadBytes(std::size_t length, std::size_t offset) const override { 62 std::vector<u8> ReadBytes(std::size_t length, std::size_t offset) const override {
diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp
index 59bc9e0af..dd5cd9ced 100644
--- a/src/core/hle/kernel/thread.cpp
+++ b/src/core/hle/kernel/thread.cpp
@@ -4,9 +4,9 @@
4 4
5#include <algorithm> 5#include <algorithm>
6#include <cinttypes> 6#include <cinttypes>
7#include <optional>
7#include <vector> 8#include <vector>
8 9
9#include <boost/optional.hpp>
10#include <boost/range/algorithm_ext/erase.hpp> 10#include <boost/range/algorithm_ext/erase.hpp>
11 11
12#include "common/assert.h" 12#include "common/assert.h"
@@ -94,7 +94,7 @@ void Thread::CancelWakeupTimer() {
94 CoreTiming::UnscheduleEventThreadsafe(kernel.ThreadWakeupCallbackEventType(), callback_handle); 94 CoreTiming::UnscheduleEventThreadsafe(kernel.ThreadWakeupCallbackEventType(), callback_handle);
95} 95}
96 96
97static boost::optional<s32> GetNextProcessorId(u64 mask) { 97static std::optional<s32> GetNextProcessorId(u64 mask) {
98 for (s32 index = 0; index < Core::NUM_CPU_CORES; ++index) { 98 for (s32 index = 0; index < Core::NUM_CPU_CORES; ++index) {
99 if (mask & (1ULL << index)) { 99 if (mask & (1ULL << index)) {
100 if (!Core::System::GetInstance().Scheduler(index).GetCurrentThread()) { 100 if (!Core::System::GetInstance().Scheduler(index).GetCurrentThread()) {
@@ -142,7 +142,7 @@ void Thread::ResumeFromWait() {
142 142
143 status = ThreadStatus::Ready; 143 status = ThreadStatus::Ready;
144 144
145 boost::optional<s32> new_processor_id = GetNextProcessorId(affinity_mask); 145 std::optional<s32> new_processor_id = GetNextProcessorId(affinity_mask);
146 if (!new_processor_id) { 146 if (!new_processor_id) {
147 new_processor_id = processor_id; 147 new_processor_id = processor_id;
148 } 148 }
@@ -369,7 +369,7 @@ void Thread::ChangeCore(u32 core, u64 mask) {
369 return; 369 return;
370 } 370 }
371 371
372 boost::optional<s32> new_processor_id{GetNextProcessorId(affinity_mask)}; 372 std::optional<s32> new_processor_id{GetNextProcessorId(affinity_mask)};
373 373
374 if (!new_processor_id) { 374 if (!new_processor_id) {
375 new_processor_id = processor_id; 375 new_processor_id = processor_id;
diff --git a/src/core/hle/service/acc/profile_manager.cpp b/src/core/hle/service/acc/profile_manager.cpp
index 3cac1b4ff..c08394e4c 100644
--- a/src/core/hle/service/acc/profile_manager.cpp
+++ b/src/core/hle/service/acc/profile_manager.cpp
@@ -195,7 +195,7 @@ std::size_t ProfileManager::GetOpenUserCount() const {
195 195
196/// Checks if a user id exists in our profile manager 196/// Checks if a user id exists in our profile manager
197bool ProfileManager::UserExists(UUID uuid) const { 197bool ProfileManager::UserExists(UUID uuid) const {
198 return GetUserIndex(uuid) != std::nullopt; 198 return GetUserIndex(uuid).has_value();
199} 199}
200 200
201bool ProfileManager::UserExistsIndex(std::size_t index) const { 201bool ProfileManager::UserExistsIndex(std::size_t index) const {
diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp
index 59aafd616..ac3ff9f20 100644
--- a/src/core/hle/service/am/am.cpp
+++ b/src/core/hle/service/am/am.cpp
@@ -743,7 +743,7 @@ void IApplicationFunctions::PopLaunchParameter(Kernel::HLERequestContext& ctx) {
743 743
744 Account::ProfileManager profile_manager{}; 744 Account::ProfileManager profile_manager{};
745 const auto uuid = profile_manager.GetUser(Settings::values.current_user); 745 const auto uuid = profile_manager.GetUser(Settings::values.current_user);
746 ASSERT(uuid != std::nullopt); 746 ASSERT(uuid);
747 params.current_user = uuid->uuid; 747 params.current_user = uuid->uuid;
748 748
749 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 749 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
diff --git a/src/core/hle/service/nvflinger/buffer_queue.cpp b/src/core/hle/service/nvflinger/buffer_queue.cpp
index fd98d541d..630ebbfc7 100644
--- a/src/core/hle/service/nvflinger/buffer_queue.cpp
+++ b/src/core/hle/service/nvflinger/buffer_queue.cpp
@@ -31,7 +31,7 @@ void BufferQueue::SetPreallocatedBuffer(u32 slot, const IGBPBuffer& igbp_buffer)
31 buffer_wait_event->Signal(); 31 buffer_wait_event->Signal();
32} 32}
33 33
34boost::optional<u32> BufferQueue::DequeueBuffer(u32 width, u32 height) { 34std::optional<u32> BufferQueue::DequeueBuffer(u32 width, u32 height) {
35 auto itr = std::find_if(queue.begin(), queue.end(), [&](const Buffer& buffer) { 35 auto itr = std::find_if(queue.begin(), queue.end(), [&](const Buffer& buffer) {
36 // Only consider free buffers. Buffers become free once again after they've been Acquired 36 // Only consider free buffers. Buffers become free once again after they've been Acquired
37 // and Released by the compositor, see the NVFlinger::Compose method. 37 // and Released by the compositor, see the NVFlinger::Compose method.
@@ -44,7 +44,7 @@ boost::optional<u32> BufferQueue::DequeueBuffer(u32 width, u32 height) {
44 }); 44 });
45 45
46 if (itr == queue.end()) { 46 if (itr == queue.end()) {
47 return boost::none; 47 return {};
48 } 48 }
49 49
50 itr->status = Buffer::Status::Dequeued; 50 itr->status = Buffer::Status::Dequeued;
@@ -70,12 +70,12 @@ void BufferQueue::QueueBuffer(u32 slot, BufferTransformFlags transform,
70 itr->crop_rect = crop_rect; 70 itr->crop_rect = crop_rect;
71} 71}
72 72
73boost::optional<const BufferQueue::Buffer&> BufferQueue::AcquireBuffer() { 73std::optional<std::reference_wrapper<const BufferQueue::Buffer>> BufferQueue::AcquireBuffer() {
74 auto itr = std::find_if(queue.begin(), queue.end(), [](const Buffer& buffer) { 74 auto itr = std::find_if(queue.begin(), queue.end(), [](const Buffer& buffer) {
75 return buffer.status == Buffer::Status::Queued; 75 return buffer.status == Buffer::Status::Queued;
76 }); 76 });
77 if (itr == queue.end()) 77 if (itr == queue.end())
78 return boost::none; 78 return {};
79 itr->status = Buffer::Status::Acquired; 79 itr->status = Buffer::Status::Acquired;
80 return *itr; 80 return *itr;
81} 81}
diff --git a/src/core/hle/service/nvflinger/buffer_queue.h b/src/core/hle/service/nvflinger/buffer_queue.h
index 50b767732..2fe81a560 100644
--- a/src/core/hle/service/nvflinger/buffer_queue.h
+++ b/src/core/hle/service/nvflinger/buffer_queue.h
@@ -4,8 +4,9 @@
4 4
5#pragma once 5#pragma once
6 6
7#include <optional>
7#include <vector> 8#include <vector>
8#include <boost/optional.hpp> 9
9#include "common/common_funcs.h" 10#include "common/common_funcs.h"
10#include "common/math_util.h" 11#include "common/math_util.h"
11#include "common/swap.h" 12#include "common/swap.h"
@@ -73,11 +74,11 @@ public:
73 }; 74 };
74 75
75 void SetPreallocatedBuffer(u32 slot, const IGBPBuffer& igbp_buffer); 76 void SetPreallocatedBuffer(u32 slot, const IGBPBuffer& igbp_buffer);
76 boost::optional<u32> DequeueBuffer(u32 width, u32 height); 77 std::optional<u32> DequeueBuffer(u32 width, u32 height);
77 const IGBPBuffer& RequestBuffer(u32 slot) const; 78 const IGBPBuffer& RequestBuffer(u32 slot) const;
78 void QueueBuffer(u32 slot, BufferTransformFlags transform, 79 void QueueBuffer(u32 slot, BufferTransformFlags transform,
79 const MathUtil::Rectangle<int>& crop_rect); 80 const MathUtil::Rectangle<int>& crop_rect);
80 boost::optional<const Buffer&> AcquireBuffer(); 81 std::optional<std::reference_wrapper<const Buffer>> AcquireBuffer();
81 void ReleaseBuffer(u32 slot); 82 void ReleaseBuffer(u32 slot);
82 u32 Query(QueryType type); 83 u32 Query(QueryType type);
83 84
diff --git a/src/core/hle/service/nvflinger/nvflinger.cpp b/src/core/hle/service/nvflinger/nvflinger.cpp
index d47b6f659..214e6d1b3 100644
--- a/src/core/hle/service/nvflinger/nvflinger.cpp
+++ b/src/core/hle/service/nvflinger/nvflinger.cpp
@@ -3,7 +3,7 @@
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include <algorithm> 5#include <algorithm>
6#include <boost/optional.hpp> 6#include <optional>
7 7
8#include "common/alignment.h" 8#include "common/alignment.h"
9#include "common/assert.h" 9#include "common/assert.h"
@@ -134,7 +134,7 @@ void NVFlinger::Compose() {
134 134
135 MicroProfileFlip(); 135 MicroProfileFlip();
136 136
137 if (buffer == boost::none) { 137 if (!buffer) {
138 auto& system_instance = Core::System::GetInstance(); 138 auto& system_instance = Core::System::GetInstance();
139 139
140 // There was no queued buffer to draw, render previous frame 140 // There was no queued buffer to draw, render previous frame
@@ -143,7 +143,7 @@ void NVFlinger::Compose() {
143 continue; 143 continue;
144 } 144 }
145 145
146 auto& igbp_buffer = buffer->igbp_buffer; 146 auto& igbp_buffer = buffer->get().igbp_buffer;
147 147
148 // Now send the buffer to the GPU for drawing. 148 // Now send the buffer to the GPU for drawing.
149 // TODO(Subv): Support more than just disp0. The display device selection is probably based 149 // TODO(Subv): Support more than just disp0. The display device selection is probably based
@@ -152,10 +152,10 @@ void NVFlinger::Compose() {
152 ASSERT(nvdisp); 152 ASSERT(nvdisp);
153 153
154 nvdisp->flip(igbp_buffer.gpu_buffer_id, igbp_buffer.offset, igbp_buffer.format, 154 nvdisp->flip(igbp_buffer.gpu_buffer_id, igbp_buffer.offset, igbp_buffer.format,
155 igbp_buffer.width, igbp_buffer.height, igbp_buffer.stride, buffer->transform, 155 igbp_buffer.width, igbp_buffer.height, igbp_buffer.stride,
156 buffer->crop_rect); 156 buffer->get().transform, buffer->get().crop_rect);
157 157
158 buffer_queue->ReleaseBuffer(buffer->slot); 158 buffer_queue->ReleaseBuffer(buffer->get().slot);
159 } 159 }
160} 160}
161 161
diff --git a/src/core/hle/service/vi/vi.cpp b/src/core/hle/service/vi/vi.cpp
index 184537daa..d764b2406 100644
--- a/src/core/hle/service/vi/vi.cpp
+++ b/src/core/hle/service/vi/vi.cpp
@@ -6,9 +6,10 @@
6#include <array> 6#include <array>
7#include <cstring> 7#include <cstring>
8#include <memory> 8#include <memory>
9#include <optional>
9#include <type_traits> 10#include <type_traits>
10#include <utility> 11#include <utility>
11#include <boost/optional.hpp> 12
12#include "common/alignment.h" 13#include "common/alignment.h"
13#include "common/assert.h" 14#include "common/assert.h"
14#include "common/common_funcs.h" 15#include "common/common_funcs.h"
@@ -506,9 +507,9 @@ private:
506 IGBPDequeueBufferRequestParcel request{ctx.ReadBuffer()}; 507 IGBPDequeueBufferRequestParcel request{ctx.ReadBuffer()};
507 const u32 width{request.data.width}; 508 const u32 width{request.data.width};
508 const u32 height{request.data.height}; 509 const u32 height{request.data.height};
509 boost::optional<u32> slot = buffer_queue->DequeueBuffer(width, height); 510 std::optional<u32> slot = buffer_queue->DequeueBuffer(width, height);
510 511
511 if (slot != boost::none) { 512 if (slot) {
512 // Buffer is available 513 // Buffer is available
513 IGBPDequeueBufferResponseParcel response{*slot}; 514 IGBPDequeueBufferResponseParcel response{*slot};
514 ctx.WriteBuffer(response.Serialize()); 515 ctx.WriteBuffer(response.Serialize());
@@ -520,7 +521,7 @@ private:
520 Kernel::ThreadWakeupReason reason) { 521 Kernel::ThreadWakeupReason reason) {
521 // Repeat TransactParcel DequeueBuffer when a buffer is available 522 // Repeat TransactParcel DequeueBuffer when a buffer is available
522 auto buffer_queue = nv_flinger->GetBufferQueue(id); 523 auto buffer_queue = nv_flinger->GetBufferQueue(id);
523 boost::optional<u32> slot = buffer_queue->DequeueBuffer(width, height); 524 std::optional<u32> slot = buffer_queue->DequeueBuffer(width, height);
524 IGBPDequeueBufferResponseParcel response{*slot}; 525 IGBPDequeueBufferResponseParcel response{*slot};
525 ctx.WriteBuffer(response.Serialize()); 526 ctx.WriteBuffer(response.Serialize());
526 IPC::ResponseBuilder rb{ctx, 2}; 527 IPC::ResponseBuilder rb{ctx, 2};
diff --git a/src/core/loader/loader.h b/src/core/loader/loader.h
index e562b3a04..7686634bf 100644
--- a/src/core/loader/loader.h
+++ b/src/core/loader/loader.h
@@ -6,10 +6,11 @@
6 6
7#include <iosfwd> 7#include <iosfwd>
8#include <memory> 8#include <memory>
9#include <optional>
9#include <string> 10#include <string>
10#include <utility> 11#include <utility>
11#include <vector> 12#include <vector>
12#include <boost/optional.hpp> 13
13#include "common/common_types.h" 14#include "common/common_types.h"
14#include "core/file_sys/vfs.h" 15#include "core/file_sys/vfs.h"
15 16
@@ -145,7 +146,7 @@ public:
145 * information. 146 * information.
146 * @returns A pair with the optional system mode, and and the status. 147 * @returns A pair with the optional system mode, and and the status.
147 */ 148 */
148 virtual std::pair<boost::optional<u32>, ResultStatus> LoadKernelSystemMode() { 149 virtual std::pair<std::optional<u32>, ResultStatus> LoadKernelSystemMode() {
149 // 96MB allocated to the application. 150 // 96MB allocated to the application.
150 return std::make_pair(2, ResultStatus::Success); 151 return std::make_pair(2, ResultStatus::Success);
151 } 152 }
diff --git a/src/core/memory.cpp b/src/core/memory.cpp
index 014298ed6..70abd856a 100644
--- a/src/core/memory.cpp
+++ b/src/core/memory.cpp
@@ -4,9 +4,9 @@
4 4
5#include <algorithm> 5#include <algorithm>
6#include <cstring> 6#include <cstring>
7#include <optional>
7#include <utility> 8#include <utility>
8 9
9#include <boost/optional.hpp>
10#include "common/assert.h" 10#include "common/assert.h"
11#include "common/common_types.h" 11#include "common/common_types.h"
12#include "common/logging/log.h" 12#include "common/logging/log.h"
diff --git a/src/core/memory_hook.h b/src/core/memory_hook.h
index 0269c7ff1..940777107 100644
--- a/src/core/memory_hook.h
+++ b/src/core/memory_hook.h
@@ -5,7 +5,8 @@
5#pragma once 5#pragma once
6 6
7#include <memory> 7#include <memory>
8#include <boost/optional.hpp> 8#include <optional>
9
9#include "common/common_types.h" 10#include "common/common_types.h"
10 11
11namespace Memory { 12namespace Memory {
@@ -18,19 +19,19 @@ namespace Memory {
18 * 19 *
19 * A hook may be mapped to multiple regions of memory. 20 * A hook may be mapped to multiple regions of memory.
20 * 21 *
21 * If a boost::none or false is returned from a function, the read/write request is passed through 22 * If a std::nullopt or false is returned from a function, the read/write request is passed through
22 * to the underlying memory region. 23 * to the underlying memory region.
23 */ 24 */
24class MemoryHook { 25class MemoryHook {
25public: 26public:
26 virtual ~MemoryHook(); 27 virtual ~MemoryHook();
27 28
28 virtual boost::optional<bool> IsValidAddress(VAddr addr) = 0; 29 virtual std::optional<bool> IsValidAddress(VAddr addr) = 0;
29 30
30 virtual boost::optional<u8> Read8(VAddr addr) = 0; 31 virtual std::optional<u8> Read8(VAddr addr) = 0;
31 virtual boost::optional<u16> Read16(VAddr addr) = 0; 32 virtual std::optional<u16> Read16(VAddr addr) = 0;
32 virtual boost::optional<u32> Read32(VAddr addr) = 0; 33 virtual std::optional<u32> Read32(VAddr addr) = 0;
33 virtual boost::optional<u64> Read64(VAddr addr) = 0; 34 virtual std::optional<u64> Read64(VAddr addr) = 0;
34 35
35 virtual bool ReadBlock(VAddr src_addr, void* dest_buffer, std::size_t size) = 0; 36 virtual bool ReadBlock(VAddr src_addr, void* dest_buffer, std::size_t size) = 0;
36 37
diff --git a/src/tests/core/arm/arm_test_common.cpp b/src/tests/core/arm/arm_test_common.cpp
index 37e15bad0..9b8a44fa1 100644
--- a/src/tests/core/arm/arm_test_common.cpp
+++ b/src/tests/core/arm/arm_test_common.cpp
@@ -64,11 +64,11 @@ void TestEnvironment::ClearWriteRecords() {
64 64
65TestEnvironment::TestMemory::~TestMemory() {} 65TestEnvironment::TestMemory::~TestMemory() {}
66 66
67boost::optional<bool> TestEnvironment::TestMemory::IsValidAddress(VAddr addr) { 67std::optional<bool> TestEnvironment::TestMemory::IsValidAddress(VAddr addr) {
68 return true; 68 return true;
69} 69}
70 70
71boost::optional<u8> TestEnvironment::TestMemory::Read8(VAddr addr) { 71std::optional<u8> TestEnvironment::TestMemory::Read8(VAddr addr) {
72 const auto iter = data.find(addr); 72 const auto iter = data.find(addr);
73 73
74 if (iter == data.end()) { 74 if (iter == data.end()) {
@@ -79,15 +79,15 @@ boost::optional<u8> TestEnvironment::TestMemory::Read8(VAddr addr) {
79 return iter->second; 79 return iter->second;
80} 80}
81 81
82boost::optional<u16> TestEnvironment::TestMemory::Read16(VAddr addr) { 82std::optional<u16> TestEnvironment::TestMemory::Read16(VAddr addr) {
83 return *Read8(addr) | static_cast<u16>(*Read8(addr + 1)) << 8; 83 return *Read8(addr) | static_cast<u16>(*Read8(addr + 1)) << 8;
84} 84}
85 85
86boost::optional<u32> TestEnvironment::TestMemory::Read32(VAddr addr) { 86std::optional<u32> TestEnvironment::TestMemory::Read32(VAddr addr) {
87 return *Read16(addr) | static_cast<u32>(*Read16(addr + 2)) << 16; 87 return *Read16(addr) | static_cast<u32>(*Read16(addr + 2)) << 16;
88} 88}
89 89
90boost::optional<u64> TestEnvironment::TestMemory::Read64(VAddr addr) { 90std::optional<u64> TestEnvironment::TestMemory::Read64(VAddr addr) {
91 return *Read32(addr) | static_cast<u64>(*Read32(addr + 4)) << 32; 91 return *Read32(addr) | static_cast<u64>(*Read32(addr + 4)) << 32;
92} 92}
93 93
diff --git a/src/tests/core/arm/arm_test_common.h b/src/tests/core/arm/arm_test_common.h
index 5de8dab4e..0b7539601 100644
--- a/src/tests/core/arm/arm_test_common.h
+++ b/src/tests/core/arm/arm_test_common.h
@@ -64,12 +64,12 @@ private:
64 64
65 ~TestMemory() override; 65 ~TestMemory() override;
66 66
67 boost::optional<bool> IsValidAddress(VAddr addr) override; 67 std::optional<bool> IsValidAddress(VAddr addr) override;
68 68
69 boost::optional<u8> Read8(VAddr addr) override; 69 std::optional<u8> Read8(VAddr addr) override;
70 boost::optional<u16> Read16(VAddr addr) override; 70 std::optional<u16> Read16(VAddr addr) override;
71 boost::optional<u32> Read32(VAddr addr) override; 71 std::optional<u32> Read32(VAddr addr) override;
72 boost::optional<u64> Read64(VAddr addr) override; 72 std::optional<u64> Read64(VAddr addr) override;
73 73
74 bool ReadBlock(VAddr src_addr, void* dest_buffer, std::size_t size) override; 74 bool ReadBlock(VAddr src_addr, void* dest_buffer, std::size_t size) override;
75 75
diff --git a/src/video_core/command_processor.cpp b/src/video_core/command_processor.cpp
index f1aa6091b..28e8c13aa 100644
--- a/src/video_core/command_processor.cpp
+++ b/src/video_core/command_processor.cpp
@@ -81,7 +81,7 @@ void GPU::ProcessCommandLists(const std::vector<CommandListHeader>& commands) {
81 for (auto entry : commands) { 81 for (auto entry : commands) {
82 Tegra::GPUVAddr address = entry.Address(); 82 Tegra::GPUVAddr address = entry.Address();
83 u32 size = entry.sz; 83 u32 size = entry.sz;
84 const boost::optional<VAddr> head_address = memory_manager->GpuToCpuAddress(address); 84 const std::optional<VAddr> head_address = memory_manager->GpuToCpuAddress(address);
85 VAddr current_addr = *head_address; 85 VAddr current_addr = *head_address;
86 while (current_addr < *head_address + size * sizeof(CommandHeader)) { 86 while (current_addr < *head_address + size * sizeof(CommandHeader)) {
87 const CommandHeader header = {Memory::Read32(current_addr)}; 87 const CommandHeader header = {Memory::Read32(current_addr)};
diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp
index 27ef865a2..7357d20d1 100644
--- a/src/video_core/engines/maxwell_3d.cpp
+++ b/src/video_core/engines/maxwell_3d.cpp
@@ -167,7 +167,7 @@ void Maxwell3D::ProcessQueryGet() {
167 GPUVAddr sequence_address = regs.query.QueryAddress(); 167 GPUVAddr sequence_address = regs.query.QueryAddress();
168 // Since the sequence address is given as a GPU VAddr, we have to convert it to an application 168 // Since the sequence address is given as a GPU VAddr, we have to convert it to an application
169 // VAddr before writing. 169 // VAddr before writing.
170 boost::optional<VAddr> address = memory_manager.GpuToCpuAddress(sequence_address); 170 std::optional<VAddr> address = memory_manager.GpuToCpuAddress(sequence_address);
171 171
172 // TODO(Subv): Support the other query units. 172 // TODO(Subv): Support the other query units.
173 ASSERT_MSG(regs.query.query_get.unit == Regs::QueryUnit::Crop, 173 ASSERT_MSG(regs.query.query_get.unit == Regs::QueryUnit::Crop,
@@ -285,7 +285,7 @@ void Maxwell3D::ProcessCBData(u32 value) {
285 // Don't allow writing past the end of the buffer. 285 // Don't allow writing past the end of the buffer.
286 ASSERT(regs.const_buffer.cb_pos + sizeof(u32) <= regs.const_buffer.cb_size); 286 ASSERT(regs.const_buffer.cb_pos + sizeof(u32) <= regs.const_buffer.cb_size);
287 287
288 boost::optional<VAddr> address = 288 std::optional<VAddr> address =
289 memory_manager.GpuToCpuAddress(buffer_address + regs.const_buffer.cb_pos); 289 memory_manager.GpuToCpuAddress(buffer_address + regs.const_buffer.cb_pos);
290 290
291 Memory::Write32(*address, value); 291 Memory::Write32(*address, value);
@@ -298,7 +298,7 @@ Texture::TICEntry Maxwell3D::GetTICEntry(u32 tic_index) const {
298 GPUVAddr tic_base_address = regs.tic.TICAddress(); 298 GPUVAddr tic_base_address = regs.tic.TICAddress();
299 299
300 GPUVAddr tic_address_gpu = tic_base_address + tic_index * sizeof(Texture::TICEntry); 300 GPUVAddr tic_address_gpu = tic_base_address + tic_index * sizeof(Texture::TICEntry);
301 boost::optional<VAddr> tic_address_cpu = memory_manager.GpuToCpuAddress(tic_address_gpu); 301 std::optional<VAddr> tic_address_cpu = memory_manager.GpuToCpuAddress(tic_address_gpu);
302 302
303 Texture::TICEntry tic_entry; 303 Texture::TICEntry tic_entry;
304 Memory::ReadBlock(*tic_address_cpu, &tic_entry, sizeof(Texture::TICEntry)); 304 Memory::ReadBlock(*tic_address_cpu, &tic_entry, sizeof(Texture::TICEntry));
@@ -322,7 +322,7 @@ Texture::TSCEntry Maxwell3D::GetTSCEntry(u32 tsc_index) const {
322 GPUVAddr tsc_base_address = regs.tsc.TSCAddress(); 322 GPUVAddr tsc_base_address = regs.tsc.TSCAddress();
323 323
324 GPUVAddr tsc_address_gpu = tsc_base_address + tsc_index * sizeof(Texture::TSCEntry); 324 GPUVAddr tsc_address_gpu = tsc_base_address + tsc_index * sizeof(Texture::TSCEntry);
325 boost::optional<VAddr> tsc_address_cpu = memory_manager.GpuToCpuAddress(tsc_address_gpu); 325 std::optional<VAddr> tsc_address_cpu = memory_manager.GpuToCpuAddress(tsc_address_gpu);
326 326
327 Texture::TSCEntry tsc_entry; 327 Texture::TSCEntry tsc_entry;
328 Memory::ReadBlock(*tsc_address_cpu, &tsc_entry, sizeof(Texture::TSCEntry)); 328 Memory::ReadBlock(*tsc_address_cpu, &tsc_entry, sizeof(Texture::TSCEntry));
@@ -386,7 +386,7 @@ Texture::FullTextureInfo Maxwell3D::GetStageTexture(Regs::ShaderStage stage,
386 386
387 ASSERT(tex_info_address < tex_info_buffer.address + tex_info_buffer.size); 387 ASSERT(tex_info_address < tex_info_buffer.address + tex_info_buffer.size);
388 388
389 boost::optional<VAddr> tex_address_cpu = memory_manager.GpuToCpuAddress(tex_info_address); 389 std::optional<VAddr> tex_address_cpu = memory_manager.GpuToCpuAddress(tex_info_address);
390 Texture::TextureHandle tex_handle{Memory::Read32(*tex_address_cpu)}; 390 Texture::TextureHandle tex_handle{Memory::Read32(*tex_address_cpu)};
391 391
392 Texture::FullTextureInfo tex_info{}; 392 Texture::FullTextureInfo tex_info{};
diff --git a/src/video_core/engines/shader_bytecode.h b/src/video_core/engines/shader_bytecode.h
index 141b9159b..b84da512f 100644
--- a/src/video_core/engines/shader_bytecode.h
+++ b/src/video_core/engines/shader_bytecode.h
@@ -5,12 +5,11 @@
5#pragma once 5#pragma once
6 6
7#include <bitset> 7#include <bitset>
8#include <optional>
8#include <string> 9#include <string>
9#include <tuple> 10#include <tuple>
10#include <vector> 11#include <vector>
11 12
12#include <boost/optional.hpp>
13
14#include "common/assert.h" 13#include "common/assert.h"
15#include "common/bit_field.h" 14#include "common/bit_field.h"
16#include "common/common_types.h" 15#include "common/common_types.h"
@@ -1456,7 +1455,7 @@ public:
1456 Type type; 1455 Type type;
1457 }; 1456 };
1458 1457
1459 static boost::optional<const Matcher&> Decode(Instruction instr) { 1458 static std::optional<std::reference_wrapper<const Matcher>> Decode(Instruction instr) {
1460 static const auto table{GetDecodeTable()}; 1459 static const auto table{GetDecodeTable()};
1461 1460
1462 const auto matches_instruction = [instr](const auto& matcher) { 1461 const auto matches_instruction = [instr](const auto& matcher) {
@@ -1464,7 +1463,8 @@ public:
1464 }; 1463 };
1465 1464
1466 auto iter = std::find_if(table.begin(), table.end(), matches_instruction); 1465 auto iter = std::find_if(table.begin(), table.end(), matches_instruction);
1467 return iter != table.end() ? boost::optional<const Matcher&>(*iter) : boost::none; 1466 return iter != table.end() ? std::optional<std::reference_wrapper<const Matcher>>(*iter)
1467 : std::nullopt;
1468 } 1468 }
1469 1469
1470private: 1470private:
diff --git a/src/video_core/macro_interpreter.cpp b/src/video_core/macro_interpreter.cpp
index 377bd66ab..f6af132fb 100644
--- a/src/video_core/macro_interpreter.cpp
+++ b/src/video_core/macro_interpreter.cpp
@@ -29,7 +29,7 @@ void MacroInterpreter::Execute(const std::vector<u32>& code, std::vector<u32> pa
29void MacroInterpreter::Reset() { 29void MacroInterpreter::Reset() {
30 registers = {}; 30 registers = {};
31 pc = 0; 31 pc = 0;
32 delayed_pc = boost::none; 32 delayed_pc = {};
33 method_address.raw = 0; 33 method_address.raw = 0;
34 parameters.clear(); 34 parameters.clear();
35 // The next parameter index starts at 1, because $r1 already has the value of the first 35 // The next parameter index starts at 1, because $r1 already has the value of the first
@@ -44,10 +44,10 @@ bool MacroInterpreter::Step(const std::vector<u32>& code, bool is_delay_slot) {
44 pc += 4; 44 pc += 4;
45 45
46 // Update the program counter if we were delayed 46 // Update the program counter if we were delayed
47 if (delayed_pc != boost::none) { 47 if (delayed_pc) {
48 ASSERT(is_delay_slot); 48 ASSERT(is_delay_slot);
49 pc = *delayed_pc; 49 pc = *delayed_pc;
50 delayed_pc = boost::none; 50 delayed_pc = {};
51 } 51 }
52 52
53 switch (opcode.operation) { 53 switch (opcode.operation) {
diff --git a/src/video_core/macro_interpreter.h b/src/video_core/macro_interpreter.h
index cee0baaf3..773684bde 100644
--- a/src/video_core/macro_interpreter.h
+++ b/src/video_core/macro_interpreter.h
@@ -5,8 +5,9 @@
5#pragma once 5#pragma once
6 6
7#include <array> 7#include <array>
8#include <optional>
8#include <vector> 9#include <vector>
9#include <boost/optional.hpp> 10
10#include "common/bit_field.h" 11#include "common/bit_field.h"
11#include "common/common_types.h" 12#include "common/common_types.h"
12 13
@@ -149,7 +150,7 @@ private:
149 Engines::Maxwell3D& maxwell3d; 150 Engines::Maxwell3D& maxwell3d;
150 151
151 u32 pc; ///< Current program counter 152 u32 pc; ///< Current program counter
152 boost::optional<u32> 153 std::optional<u32>
153 delayed_pc; ///< Program counter to execute at after the delay slot is executed. 154 delayed_pc; ///< Program counter to execute at after the delay slot is executed.
154 155
155 static constexpr std::size_t NumMacroRegisters = 8; 156 static constexpr std::size_t NumMacroRegisters = 8;
diff --git a/src/video_core/memory_manager.cpp b/src/video_core/memory_manager.cpp
index 022d4ab74..90a8e825d 100644
--- a/src/video_core/memory_manager.cpp
+++ b/src/video_core/memory_manager.cpp
@@ -9,7 +9,7 @@
9namespace Tegra { 9namespace Tegra {
10 10
11GPUVAddr MemoryManager::AllocateSpace(u64 size, u64 align) { 11GPUVAddr MemoryManager::AllocateSpace(u64 size, u64 align) {
12 boost::optional<GPUVAddr> gpu_addr = FindFreeBlock(size, align); 12 std::optional<GPUVAddr> gpu_addr = FindFreeBlock(size, align);
13 ASSERT(gpu_addr); 13 ASSERT(gpu_addr);
14 14
15 for (u64 offset = 0; offset < size; offset += PAGE_SIZE) { 15 for (u64 offset = 0; offset < size; offset += PAGE_SIZE) {
@@ -34,7 +34,7 @@ GPUVAddr MemoryManager::AllocateSpace(GPUVAddr gpu_addr, u64 size, u64 align) {
34} 34}
35 35
36GPUVAddr MemoryManager::MapBufferEx(VAddr cpu_addr, u64 size) { 36GPUVAddr MemoryManager::MapBufferEx(VAddr cpu_addr, u64 size) {
37 boost::optional<GPUVAddr> gpu_addr = FindFreeBlock(size, PAGE_SIZE); 37 std::optional<GPUVAddr> gpu_addr = FindFreeBlock(size, PAGE_SIZE);
38 ASSERT(gpu_addr); 38 ASSERT(gpu_addr);
39 39
40 for (u64 offset = 0; offset < size; offset += PAGE_SIZE) { 40 for (u64 offset = 0; offset < size; offset += PAGE_SIZE) {
@@ -97,7 +97,7 @@ GPUVAddr MemoryManager::GetRegionEnd(GPUVAddr region_start) const {
97 return {}; 97 return {};
98} 98}
99 99
100boost::optional<GPUVAddr> MemoryManager::FindFreeBlock(u64 size, u64 align) { 100std::optional<GPUVAddr> MemoryManager::FindFreeBlock(u64 size, u64 align) {
101 GPUVAddr gpu_addr = 0; 101 GPUVAddr gpu_addr = 0;
102 u64 free_space = 0; 102 u64 free_space = 0;
103 align = (align + PAGE_MASK) & ~PAGE_MASK; 103 align = (align + PAGE_MASK) & ~PAGE_MASK;
@@ -118,7 +118,7 @@ boost::optional<GPUVAddr> MemoryManager::FindFreeBlock(u64 size, u64 align) {
118 return {}; 118 return {};
119} 119}
120 120
121boost::optional<VAddr> MemoryManager::GpuToCpuAddress(GPUVAddr gpu_addr) { 121std::optional<VAddr> MemoryManager::GpuToCpuAddress(GPUVAddr gpu_addr) {
122 VAddr base_addr = PageSlot(gpu_addr); 122 VAddr base_addr = PageSlot(gpu_addr);
123 123
124 if (base_addr == static_cast<u64>(PageStatus::Allocated) || 124 if (base_addr == static_cast<u64>(PageStatus::Allocated) ||
diff --git a/src/video_core/memory_manager.h b/src/video_core/memory_manager.h
index caf80093f..b1255fd56 100644
--- a/src/video_core/memory_manager.h
+++ b/src/video_core/memory_manager.h
@@ -6,10 +6,9 @@
6 6
7#include <array> 7#include <array>
8#include <memory> 8#include <memory>
9#include <optional>
9#include <vector> 10#include <vector>
10 11
11#include <boost/optional.hpp>
12
13#include "common/common_types.h" 12#include "common/common_types.h"
14 13
15namespace Tegra { 14namespace Tegra {
@@ -27,7 +26,7 @@ public:
27 GPUVAddr MapBufferEx(VAddr cpu_addr, GPUVAddr gpu_addr, u64 size); 26 GPUVAddr MapBufferEx(VAddr cpu_addr, GPUVAddr gpu_addr, u64 size);
28 GPUVAddr UnmapBuffer(GPUVAddr gpu_addr, u64 size); 27 GPUVAddr UnmapBuffer(GPUVAddr gpu_addr, u64 size);
29 GPUVAddr GetRegionEnd(GPUVAddr region_start) const; 28 GPUVAddr GetRegionEnd(GPUVAddr region_start) const;
30 boost::optional<VAddr> GpuToCpuAddress(GPUVAddr gpu_addr); 29 std::optional<VAddr> GpuToCpuAddress(GPUVAddr gpu_addr);
31 std::vector<GPUVAddr> CpuToGpuAddress(VAddr cpu_addr) const; 30 std::vector<GPUVAddr> CpuToGpuAddress(VAddr cpu_addr) const;
32 31
33 static constexpr u64 PAGE_BITS = 16; 32 static constexpr u64 PAGE_BITS = 16;
@@ -35,7 +34,7 @@ public:
35 static constexpr u64 PAGE_MASK = PAGE_SIZE - 1; 34 static constexpr u64 PAGE_MASK = PAGE_SIZE - 1;
36 35
37private: 36private:
38 boost::optional<GPUVAddr> FindFreeBlock(u64 size, u64 align = 1); 37 std::optional<GPUVAddr> FindFreeBlock(u64 size, u64 align = 1);
39 bool IsPageMapped(GPUVAddr gpu_addr); 38 bool IsPageMapped(GPUVAddr gpu_addr);
40 VAddr& PageSlot(GPUVAddr gpu_addr); 39 VAddr& PageSlot(GPUVAddr gpu_addr);
41 40
diff --git a/src/video_core/renderer_base.h b/src/video_core/renderer_base.h
index 2cd0738ff..669e26e15 100644
--- a/src/video_core/renderer_base.h
+++ b/src/video_core/renderer_base.h
@@ -6,7 +6,8 @@
6 6
7#include <atomic> 7#include <atomic>
8#include <memory> 8#include <memory>
9#include <boost/optional.hpp> 9#include <optional>
10
10#include "common/common_types.h" 11#include "common/common_types.h"
11#include "video_core/gpu.h" 12#include "video_core/gpu.h"
12#include "video_core/rasterizer_interface.h" 13#include "video_core/rasterizer_interface.h"
@@ -28,7 +29,8 @@ public:
28 virtual ~RendererBase(); 29 virtual ~RendererBase();
29 30
30 /// Swap buffers (render frame) 31 /// Swap buffers (render frame)
31 virtual void SwapBuffers(boost::optional<const Tegra::FramebufferConfig&> framebuffer) = 0; 32 virtual void SwapBuffers(
33 std::optional<std::reference_wrapper<const Tegra::FramebufferConfig>> framebuffer) = 0;
32 34
33 /// Initialize the renderer 35 /// Initialize the renderer
34 virtual bool Init() = 0; 36 virtual bool Init() = 0;
diff --git a/src/video_core/renderer_opengl/gl_buffer_cache.cpp b/src/video_core/renderer_opengl/gl_buffer_cache.cpp
index c142095c5..41a54b3e7 100644
--- a/src/video_core/renderer_opengl/gl_buffer_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_buffer_cache.cpp
@@ -17,7 +17,7 @@ OGLBufferCache::OGLBufferCache(std::size_t size) : stream_buffer(GL_ARRAY_BUFFER
17GLintptr OGLBufferCache::UploadMemory(Tegra::GPUVAddr gpu_addr, std::size_t size, 17GLintptr OGLBufferCache::UploadMemory(Tegra::GPUVAddr gpu_addr, std::size_t size,
18 std::size_t alignment, bool cache) { 18 std::size_t alignment, bool cache) {
19 auto& memory_manager = Core::System::GetInstance().GPU().MemoryManager(); 19 auto& memory_manager = Core::System::GetInstance().GPU().MemoryManager();
20 const boost::optional<VAddr> cpu_addr{memory_manager.GpuToCpuAddress(gpu_addr)}; 20 const std::optional<VAddr> cpu_addr{memory_manager.GpuToCpuAddress(gpu_addr)};
21 21
22 // Cache management is a big overhead, so only cache entries with a given size. 22 // Cache management is a big overhead, so only cache entries with a given size.
23 // TODO: Figure out which size is the best for given games. 23 // TODO: Figure out which size is the best for given games.
diff --git a/src/video_core/renderer_opengl/gl_primitive_assembler.cpp b/src/video_core/renderer_opengl/gl_primitive_assembler.cpp
index ee1d9601b..741f14bc3 100644
--- a/src/video_core/renderer_opengl/gl_primitive_assembler.cpp
+++ b/src/video_core/renderer_opengl/gl_primitive_assembler.cpp
@@ -45,7 +45,7 @@ GLintptr PrimitiveAssembler::MakeQuadIndexed(Tegra::GPUVAddr gpu_addr, std::size
45 auto [dst_pointer, index_offset] = buffer_cache.ReserveMemory(map_size); 45 auto [dst_pointer, index_offset] = buffer_cache.ReserveMemory(map_size);
46 46
47 auto& memory_manager = Core::System::GetInstance().GPU().MemoryManager(); 47 auto& memory_manager = Core::System::GetInstance().GPU().MemoryManager();
48 const boost::optional<VAddr> cpu_addr{memory_manager.GpuToCpuAddress(gpu_addr)}; 48 const std::optional<VAddr> cpu_addr{memory_manager.GpuToCpuAddress(gpu_addr)};
49 const u8* source{Memory::GetPointer(*cpu_addr)}; 49 const u8* source{Memory::GetPointer(*cpu_addr)};
50 50
51 for (u32 primitive = 0; primitive < count / 4; ++primitive) { 51 for (u32 primitive = 0; primitive < count / 4; ++primitive) {
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index 7bb5544fc..bf381271e 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -401,7 +401,7 @@ void RasterizerOpenGL::UpdatePagesCachedCount(VAddr addr, u64 size, int delta) {
401 401
402void RasterizerOpenGL::ConfigureFramebuffers(bool using_color_fb, bool using_depth_fb, 402void RasterizerOpenGL::ConfigureFramebuffers(bool using_color_fb, bool using_depth_fb,
403 bool preserve_contents, 403 bool preserve_contents,
404 boost::optional<std::size_t> single_color_target) { 404 std::optional<std::size_t> single_color_target) {
405 MICROPROFILE_SCOPE(OpenGL_Framebuffer); 405 MICROPROFILE_SCOPE(OpenGL_Framebuffer);
406 const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs; 406 const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs;
407 407
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h
index 7b0615125..47097c569 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.h
+++ b/src/video_core/renderer_opengl/gl_rasterizer.h
@@ -8,12 +8,12 @@
8#include <cstddef> 8#include <cstddef>
9#include <map> 9#include <map>
10#include <memory> 10#include <memory>
11#include <optional>
11#include <tuple> 12#include <tuple>
12#include <utility> 13#include <utility>
13#include <vector> 14#include <vector>
14 15
15#include <boost/icl/interval_map.hpp> 16#include <boost/icl/interval_map.hpp>
16#include <boost/optional.hpp>
17#include <boost/range/iterator_range.hpp> 17#include <boost/range/iterator_range.hpp>
18#include <glad/glad.h> 18#include <glad/glad.h>
19 19
@@ -111,7 +111,7 @@ private:
111 */ 111 */
112 void ConfigureFramebuffers(bool use_color_fb = true, bool using_depth_fb = true, 112 void ConfigureFramebuffers(bool use_color_fb = true, bool using_depth_fb = true,
113 bool preserve_contents = true, 113 bool preserve_contents = true,
114 boost::optional<std::size_t> single_color_target = {}); 114 std::optional<std::size_t> single_color_target = {});
115 115
116 /* 116 /*
117 * Configures the current constbuffers to use for the draw command. 117 * Configures the current constbuffers to use for the draw command.
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
index dcf6941b0..d1f6ffe40 100644
--- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
@@ -3,12 +3,12 @@
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include <map> 5#include <map>
6#include <optional>
6#include <set> 7#include <set>
7#include <string> 8#include <string>
8#include <string_view> 9#include <string_view>
9#include <unordered_set> 10#include <unordered_set>
10 11
11#include <boost/optional.hpp>
12#include <fmt/format.h> 12#include <fmt/format.h>
13 13
14#include "common/assert.h" 14#include "common/assert.h"
@@ -144,7 +144,7 @@ private:
144 for (u32 offset = begin; offset != end && offset != PROGRAM_END; ++offset) { 144 for (u32 offset = begin; offset != end && offset != PROGRAM_END; ++offset) {
145 const Instruction instr = {program_code[offset]}; 145 const Instruction instr = {program_code[offset]};
146 if (const auto opcode = OpCode::Decode(instr)) { 146 if (const auto opcode = OpCode::Decode(instr)) {
147 switch (opcode->GetId()) { 147 switch (opcode->get().GetId()) {
148 case OpCode::Id::EXIT: { 148 case OpCode::Id::EXIT: {
149 // The EXIT instruction can be predicated, which means that the shader can 149 // The EXIT instruction can be predicated, which means that the shader can
150 // conditionally end on this instruction. We have to consider the case where the 150 // conditionally end on this instruction. We have to consider the case where the
@@ -430,7 +430,7 @@ public:
430 */ 430 */
431 void SetRegisterToInputAttibute(const Register& reg, u64 elem, Attribute::Index attribute, 431 void SetRegisterToInputAttibute(const Register& reg, u64 elem, Attribute::Index attribute,
432 const Tegra::Shader::IpaMode& input_mode, 432 const Tegra::Shader::IpaMode& input_mode,
433 boost::optional<Register> vertex = {}) { 433 std::optional<Register> vertex = {}) {
434 const std::string dest = GetRegisterAsFloat(reg); 434 const std::string dest = GetRegisterAsFloat(reg);
435 const std::string src = GetInputAttribute(attribute, input_mode, vertex) + GetSwizzle(elem); 435 const std::string src = GetInputAttribute(attribute, input_mode, vertex) + GetSwizzle(elem);
436 shader.AddLine(dest + " = " + src + ';'); 436 shader.AddLine(dest + " = " + src + ';');
@@ -807,10 +807,10 @@ private:
807 /// Generates code representing an input attribute register. 807 /// Generates code representing an input attribute register.
808 std::string GetInputAttribute(Attribute::Index attribute, 808 std::string GetInputAttribute(Attribute::Index attribute,
809 const Tegra::Shader::IpaMode& input_mode, 809 const Tegra::Shader::IpaMode& input_mode,
810 boost::optional<Register> vertex = {}) { 810 std::optional<Register> vertex = {}) {
811 auto GeometryPass = [&](const std::string& name) { 811 auto GeometryPass = [&](const std::string& name) {
812 if (stage == Maxwell3D::Regs::ShaderStage::Geometry && vertex) { 812 if (stage == Maxwell3D::Regs::ShaderStage::Geometry && vertex) {
813 return "gs_" + name + '[' + GetRegisterAsInteger(vertex.value(), 0, false) + ']'; 813 return "gs_" + name + '[' + GetRegisterAsInteger(*vertex, 0, false) + ']';
814 } 814 }
815 return name; 815 return name;
816 }; 816 };
@@ -1465,7 +1465,7 @@ private:
1465 } 1465 }
1466 1466
1467 shader.AddLine( 1467 shader.AddLine(
1468 fmt::format("// {}: {} (0x{:016x})", offset, opcode->GetName(), instr.value)); 1468 fmt::format("// {}: {} (0x{:016x})", offset, opcode->get().GetName(), instr.value));
1469 1469
1470 using Tegra::Shader::Pred; 1470 using Tegra::Shader::Pred;
1471 ASSERT_MSG(instr.pred.full_pred != Pred::NeverExecute, 1471 ASSERT_MSG(instr.pred.full_pred != Pred::NeverExecute,
@@ -1473,7 +1473,7 @@ private:
1473 1473
1474 // Some instructions (like SSY) don't have a predicate field, they are always 1474 // Some instructions (like SSY) don't have a predicate field, they are always
1475 // unconditionally executed. 1475 // unconditionally executed.
1476 bool can_be_predicated = OpCode::IsPredicatedInstruction(opcode->GetId()); 1476 bool can_be_predicated = OpCode::IsPredicatedInstruction(opcode->get().GetId());
1477 1477
1478 if (can_be_predicated && instr.pred.pred_index != static_cast<u64>(Pred::UnusedIndex)) { 1478 if (can_be_predicated && instr.pred.pred_index != static_cast<u64>(Pred::UnusedIndex)) {
1479 shader.AddLine("if (" + 1479 shader.AddLine("if (" +
@@ -1483,7 +1483,7 @@ private:
1483 ++shader.scope; 1483 ++shader.scope;
1484 } 1484 }
1485 1485
1486 switch (opcode->GetType()) { 1486 switch (opcode->get().GetType()) {
1487 case OpCode::Type::Arithmetic: { 1487 case OpCode::Type::Arithmetic: {
1488 std::string op_a = regs.GetRegisterAsFloat(instr.gpr8); 1488 std::string op_a = regs.GetRegisterAsFloat(instr.gpr8);
1489 1489
@@ -1500,7 +1500,7 @@ private:
1500 } 1500 }
1501 } 1501 }
1502 1502
1503 switch (opcode->GetId()) { 1503 switch (opcode->get().GetId()) {
1504 case OpCode::Id::MOV_C: 1504 case OpCode::Id::MOV_C:
1505 case OpCode::Id::MOV_R: { 1505 case OpCode::Id::MOV_R: {
1506 // MOV does not have neither 'abs' nor 'neg' bits. 1506 // MOV does not have neither 'abs' nor 'neg' bits.
@@ -1600,14 +1600,15 @@ private:
1600 break; 1600 break;
1601 } 1601 }
1602 default: { 1602 default: {
1603 LOG_CRITICAL(HW_GPU, "Unhandled arithmetic instruction: {}", opcode->GetName()); 1603 LOG_CRITICAL(HW_GPU, "Unhandled arithmetic instruction: {}",
1604 opcode->get().GetName());
1604 UNREACHABLE(); 1605 UNREACHABLE();
1605 } 1606 }
1606 } 1607 }
1607 break; 1608 break;
1608 } 1609 }
1609 case OpCode::Type::ArithmeticImmediate: { 1610 case OpCode::Type::ArithmeticImmediate: {
1610 switch (opcode->GetId()) { 1611 switch (opcode->get().GetId()) {
1611 case OpCode::Id::MOV32_IMM: { 1612 case OpCode::Id::MOV32_IMM: {
1612 regs.SetRegisterToFloat(instr.gpr0, 0, GetImmediate32(instr), 1, 1); 1613 regs.SetRegisterToFloat(instr.gpr0, 0, GetImmediate32(instr), 1, 1);
1613 break; 1614 break;
@@ -1651,7 +1652,7 @@ private:
1651 std::string op_a = instr.bfe.negate_a ? "-" : ""; 1652 std::string op_a = instr.bfe.negate_a ? "-" : "";
1652 op_a += regs.GetRegisterAsInteger(instr.gpr8); 1653 op_a += regs.GetRegisterAsInteger(instr.gpr8);
1653 1654
1654 switch (opcode->GetId()) { 1655 switch (opcode->get().GetId()) {
1655 case OpCode::Id::BFE_IMM: { 1656 case OpCode::Id::BFE_IMM: {
1656 std::string inner_shift = 1657 std::string inner_shift =
1657 '(' + op_a + " << " + std::to_string(instr.bfe.GetLeftShiftValue()) + ')'; 1658 '(' + op_a + " << " + std::to_string(instr.bfe.GetLeftShiftValue()) + ')';
@@ -1663,7 +1664,7 @@ private:
1663 break; 1664 break;
1664 } 1665 }
1665 default: { 1666 default: {
1666 LOG_CRITICAL(HW_GPU, "Unhandled BFE instruction: {}", opcode->GetName()); 1667 LOG_CRITICAL(HW_GPU, "Unhandled BFE instruction: {}", opcode->get().GetName());
1667 UNREACHABLE(); 1668 UNREACHABLE();
1668 } 1669 }
1669 } 1670 }
@@ -1685,7 +1686,7 @@ private:
1685 } 1686 }
1686 } 1687 }
1687 1688
1688 switch (opcode->GetId()) { 1689 switch (opcode->get().GetId()) {
1689 case OpCode::Id::SHR_C: 1690 case OpCode::Id::SHR_C:
1690 case OpCode::Id::SHR_R: 1691 case OpCode::Id::SHR_R:
1691 case OpCode::Id::SHR_IMM: { 1692 case OpCode::Id::SHR_IMM: {
@@ -1705,7 +1706,7 @@ private:
1705 regs.SetRegisterToInteger(instr.gpr0, true, 0, op_a + " << " + op_b, 1, 1); 1706 regs.SetRegisterToInteger(instr.gpr0, true, 0, op_a + " << " + op_b, 1, 1);
1706 break; 1707 break;
1707 default: { 1708 default: {
1708 LOG_CRITICAL(HW_GPU, "Unhandled shift instruction: {}", opcode->GetName()); 1709 LOG_CRITICAL(HW_GPU, "Unhandled shift instruction: {}", opcode->get().GetName());
1709 UNREACHABLE(); 1710 UNREACHABLE();
1710 } 1711 }
1711 } 1712 }
@@ -1715,7 +1716,7 @@ private:
1715 std::string op_a = regs.GetRegisterAsInteger(instr.gpr8); 1716 std::string op_a = regs.GetRegisterAsInteger(instr.gpr8);
1716 std::string op_b = std::to_string(instr.alu.imm20_32.Value()); 1717 std::string op_b = std::to_string(instr.alu.imm20_32.Value());
1717 1718
1718 switch (opcode->GetId()) { 1719 switch (opcode->get().GetId()) {
1719 case OpCode::Id::IADD32I: 1720 case OpCode::Id::IADD32I:
1720 if (instr.iadd32i.negate_a) 1721 if (instr.iadd32i.negate_a)
1721 op_a = "-(" + op_a + ')'; 1722 op_a = "-(" + op_a + ')';
@@ -1737,7 +1738,7 @@ private:
1737 } 1738 }
1738 default: { 1739 default: {
1739 LOG_CRITICAL(HW_GPU, "Unhandled ArithmeticIntegerImmediate instruction: {}", 1740 LOG_CRITICAL(HW_GPU, "Unhandled ArithmeticIntegerImmediate instruction: {}",
1740 opcode->GetName()); 1741 opcode->get().GetName());
1741 UNREACHABLE(); 1742 UNREACHABLE();
1742 } 1743 }
1743 } 1744 }
@@ -1757,7 +1758,7 @@ private:
1757 } 1758 }
1758 } 1759 }
1759 1760
1760 switch (opcode->GetId()) { 1761 switch (opcode->get().GetId()) {
1761 case OpCode::Id::IADD_C: 1762 case OpCode::Id::IADD_C:
1762 case OpCode::Id::IADD_R: 1763 case OpCode::Id::IADD_R:
1763 case OpCode::Id::IADD_IMM: { 1764 case OpCode::Id::IADD_IMM: {
@@ -1793,7 +1794,7 @@ private:
1793 } 1794 }
1794 }; 1795 };
1795 1796
1796 if (opcode->GetId() == OpCode::Id::IADD3_R) { 1797 if (opcode->get().GetId() == OpCode::Id::IADD3_R) {
1797 apply_height(instr.iadd3.height_a, op_a); 1798 apply_height(instr.iadd3.height_a, op_a);
1798 apply_height(instr.iadd3.height_b, op_b); 1799 apply_height(instr.iadd3.height_b, op_b);
1799 apply_height(instr.iadd3.height_c, op_c); 1800 apply_height(instr.iadd3.height_c, op_c);
@@ -1809,7 +1810,7 @@ private:
1809 op_c = "-(" + op_c + ')'; 1810 op_c = "-(" + op_c + ')';
1810 1811
1811 std::string result; 1812 std::string result;
1812 if (opcode->GetId() == OpCode::Id::IADD3_R) { 1813 if (opcode->get().GetId() == OpCode::Id::IADD3_R) {
1813 switch (instr.iadd3.mode) { 1814 switch (instr.iadd3.mode) {
1814 case Tegra::Shader::IAdd3Mode::RightShift: 1815 case Tegra::Shader::IAdd3Mode::RightShift:
1815 // TODO(tech4me): According to 1816 // TODO(tech4me): According to
@@ -1884,7 +1885,7 @@ private:
1884 const std::string op_c = regs.GetRegisterAsInteger(instr.gpr39); 1885 const std::string op_c = regs.GetRegisterAsInteger(instr.gpr39);
1885 std::string lut; 1886 std::string lut;
1886 1887
1887 if (opcode->GetId() == OpCode::Id::LOP3_R) { 1888 if (opcode->get().GetId() == OpCode::Id::LOP3_R) {
1888 lut = '(' + std::to_string(instr.alu.lop3.GetImmLut28()) + ')'; 1889 lut = '(' + std::to_string(instr.alu.lop3.GetImmLut28()) + ')';
1889 } else { 1890 } else {
1890 lut = '(' + std::to_string(instr.alu.lop3.GetImmLut48()) + ')'; 1891 lut = '(' + std::to_string(instr.alu.lop3.GetImmLut48()) + ')';
@@ -1914,7 +1915,7 @@ private:
1914 case OpCode::Id::LEA_HI: { 1915 case OpCode::Id::LEA_HI: {
1915 std::string op_c; 1916 std::string op_c;
1916 1917
1917 switch (opcode->GetId()) { 1918 switch (opcode->get().GetId()) {
1918 case OpCode::Id::LEA_R2: { 1919 case OpCode::Id::LEA_R2: {
1919 op_a = regs.GetRegisterAsInteger(instr.gpr20); 1920 op_a = regs.GetRegisterAsInteger(instr.gpr20);
1920 op_b = regs.GetRegisterAsInteger(instr.gpr39); 1921 op_b = regs.GetRegisterAsInteger(instr.gpr39);
@@ -1959,7 +1960,8 @@ private:
1959 op_b = regs.GetRegisterAsInteger(instr.gpr8); 1960 op_b = regs.GetRegisterAsInteger(instr.gpr8);
1960 op_a = std::to_string(instr.lea.imm.entry_a); 1961 op_a = std::to_string(instr.lea.imm.entry_a);
1961 op_c = std::to_string(instr.lea.imm.entry_b); 1962 op_c = std::to_string(instr.lea.imm.entry_b);
1962 LOG_CRITICAL(HW_GPU, "Unhandled LEA subinstruction: {}", opcode->GetName()); 1963 LOG_CRITICAL(HW_GPU, "Unhandled LEA subinstruction: {}",
1964 opcode->get().GetName());
1963 UNREACHABLE(); 1965 UNREACHABLE();
1964 } 1966 }
1965 } 1967 }
@@ -1974,7 +1976,7 @@ private:
1974 } 1976 }
1975 default: { 1977 default: {
1976 LOG_CRITICAL(HW_GPU, "Unhandled ArithmeticInteger instruction: {}", 1978 LOG_CRITICAL(HW_GPU, "Unhandled ArithmeticInteger instruction: {}",
1977 opcode->GetName()); 1979 opcode->get().GetName());
1978 UNREACHABLE(); 1980 UNREACHABLE();
1979 } 1981 }
1980 } 1982 }
@@ -1982,20 +1984,21 @@ private:
1982 break; 1984 break;
1983 } 1985 }
1984 case OpCode::Type::ArithmeticHalf: { 1986 case OpCode::Type::ArithmeticHalf: {
1985 if (opcode->GetId() == OpCode::Id::HADD2_C || opcode->GetId() == OpCode::Id::HADD2_R) { 1987 if (opcode->get().GetId() == OpCode::Id::HADD2_C ||
1988 opcode->get().GetId() == OpCode::Id::HADD2_R) {
1986 ASSERT_MSG(instr.alu_half.ftz == 0, "Unimplemented"); 1989 ASSERT_MSG(instr.alu_half.ftz == 0, "Unimplemented");
1987 } 1990 }
1988 const bool negate_a = 1991 const bool negate_a =
1989 opcode->GetId() != OpCode::Id::HMUL2_R && instr.alu_half.negate_a != 0; 1992 opcode->get().GetId() != OpCode::Id::HMUL2_R && instr.alu_half.negate_a != 0;
1990 const bool negate_b = 1993 const bool negate_b =
1991 opcode->GetId() != OpCode::Id::HMUL2_C && instr.alu_half.negate_b != 0; 1994 opcode->get().GetId() != OpCode::Id::HMUL2_C && instr.alu_half.negate_b != 0;
1992 1995
1993 const std::string op_a = 1996 const std::string op_a =
1994 GetHalfFloat(regs.GetRegisterAsInteger(instr.gpr8, 0, false), instr.alu_half.type_a, 1997 GetHalfFloat(regs.GetRegisterAsInteger(instr.gpr8, 0, false), instr.alu_half.type_a,
1995 instr.alu_half.abs_a != 0, negate_a); 1998 instr.alu_half.abs_a != 0, negate_a);
1996 1999
1997 std::string op_b; 2000 std::string op_b;
1998 switch (opcode->GetId()) { 2001 switch (opcode->get().GetId()) {
1999 case OpCode::Id::HADD2_C: 2002 case OpCode::Id::HADD2_C:
2000 case OpCode::Id::HMUL2_C: 2003 case OpCode::Id::HMUL2_C:
2001 op_b = regs.GetUniform(instr.cbuf34.index, instr.cbuf34.offset, 2004 op_b = regs.GetUniform(instr.cbuf34.index, instr.cbuf34.offset,
@@ -2013,7 +2016,7 @@ private:
2013 op_b = GetHalfFloat(op_b, instr.alu_half.type_b, instr.alu_half.abs_b != 0, negate_b); 2016 op_b = GetHalfFloat(op_b, instr.alu_half.type_b, instr.alu_half.abs_b != 0, negate_b);
2014 2017
2015 const std::string result = [&]() { 2018 const std::string result = [&]() {
2016 switch (opcode->GetId()) { 2019 switch (opcode->get().GetId()) {
2017 case OpCode::Id::HADD2_C: 2020 case OpCode::Id::HADD2_C:
2018 case OpCode::Id::HADD2_R: 2021 case OpCode::Id::HADD2_R:
2019 return '(' + op_a + " + " + op_b + ')'; 2022 return '(' + op_a + " + " + op_b + ')';
@@ -2021,7 +2024,8 @@ private:
2021 case OpCode::Id::HMUL2_R: 2024 case OpCode::Id::HMUL2_R:
2022 return '(' + op_a + " * " + op_b + ')'; 2025 return '(' + op_a + " * " + op_b + ')';
2023 default: 2026 default:
2024 LOG_CRITICAL(HW_GPU, "Unhandled half float instruction: {}", opcode->GetName()); 2027 LOG_CRITICAL(HW_GPU, "Unhandled half float instruction: {}",
2028 opcode->get().GetName());
2025 UNREACHABLE(); 2029 UNREACHABLE();
2026 return std::string("0"); 2030 return std::string("0");
2027 } 2031 }
@@ -2032,7 +2036,7 @@ private:
2032 break; 2036 break;
2033 } 2037 }
2034 case OpCode::Type::ArithmeticHalfImmediate: { 2038 case OpCode::Type::ArithmeticHalfImmediate: {
2035 if (opcode->GetId() == OpCode::Id::HADD2_IMM) { 2039 if (opcode->get().GetId() == OpCode::Id::HADD2_IMM) {
2036 ASSERT_MSG(instr.alu_half_imm.ftz == 0, "Unimplemented"); 2040 ASSERT_MSG(instr.alu_half_imm.ftz == 0, "Unimplemented");
2037 } else { 2041 } else {
2038 ASSERT_MSG(instr.alu_half_imm.precision == Tegra::Shader::HalfPrecision::None, 2042 ASSERT_MSG(instr.alu_half_imm.precision == Tegra::Shader::HalfPrecision::None,
@@ -2046,7 +2050,7 @@ private:
2046 const std::string op_b = UnpackHalfImmediate(instr, true); 2050 const std::string op_b = UnpackHalfImmediate(instr, true);
2047 2051
2048 const std::string result = [&]() { 2052 const std::string result = [&]() {
2049 switch (opcode->GetId()) { 2053 switch (opcode->get().GetId()) {
2050 case OpCode::Id::HADD2_IMM: 2054 case OpCode::Id::HADD2_IMM:
2051 return op_a + " + " + op_b; 2055 return op_a + " + " + op_b;
2052 case OpCode::Id::HMUL2_IMM: 2056 case OpCode::Id::HMUL2_IMM:
@@ -2072,7 +2076,7 @@ private:
2072 ASSERT_MSG(instr.ffma.tab5980_1 == 0, "FFMA tab5980_1({}) not implemented", 2076 ASSERT_MSG(instr.ffma.tab5980_1 == 0, "FFMA tab5980_1({}) not implemented",
2073 instr.ffma.tab5980_1.Value()); 2077 instr.ffma.tab5980_1.Value());
2074 2078
2075 switch (opcode->GetId()) { 2079 switch (opcode->get().GetId()) {
2076 case OpCode::Id::FFMA_CR: { 2080 case OpCode::Id::FFMA_CR: {
2077 op_b += regs.GetUniform(instr.cbuf34.index, instr.cbuf34.offset, 2081 op_b += regs.GetUniform(instr.cbuf34.index, instr.cbuf34.offset,
2078 GLSLRegister::Type::Float); 2082 GLSLRegister::Type::Float);
@@ -2096,7 +2100,7 @@ private:
2096 break; 2100 break;
2097 } 2101 }
2098 default: { 2102 default: {
2099 LOG_CRITICAL(HW_GPU, "Unhandled FFMA instruction: {}", opcode->GetName()); 2103 LOG_CRITICAL(HW_GPU, "Unhandled FFMA instruction: {}", opcode->get().GetName());
2100 UNREACHABLE(); 2104 UNREACHABLE();
2101 } 2105 }
2102 } 2106 }
@@ -2107,14 +2111,14 @@ private:
2107 break; 2111 break;
2108 } 2112 }
2109 case OpCode::Type::Hfma2: { 2113 case OpCode::Type::Hfma2: {
2110 if (opcode->GetId() == OpCode::Id::HFMA2_RR) { 2114 if (opcode->get().GetId() == OpCode::Id::HFMA2_RR) {
2111 ASSERT_MSG(instr.hfma2.rr.precision == Tegra::Shader::HalfPrecision::None, 2115 ASSERT_MSG(instr.hfma2.rr.precision == Tegra::Shader::HalfPrecision::None,
2112 "Unimplemented"); 2116 "Unimplemented");
2113 } else { 2117 } else {
2114 ASSERT_MSG(instr.hfma2.precision == Tegra::Shader::HalfPrecision::None, 2118 ASSERT_MSG(instr.hfma2.precision == Tegra::Shader::HalfPrecision::None,
2115 "Unimplemented"); 2119 "Unimplemented");
2116 } 2120 }
2117 const bool saturate = opcode->GetId() == OpCode::Id::HFMA2_RR 2121 const bool saturate = opcode->get().GetId() == OpCode::Id::HFMA2_RR
2118 ? instr.hfma2.rr.saturate != 0 2122 ? instr.hfma2.rr.saturate != 0
2119 : instr.hfma2.saturate != 0; 2123 : instr.hfma2.saturate != 0;
2120 2124
@@ -2122,7 +2126,7 @@ private:
2122 GetHalfFloat(regs.GetRegisterAsInteger(instr.gpr8, 0, false), instr.hfma2.type_a); 2126 GetHalfFloat(regs.GetRegisterAsInteger(instr.gpr8, 0, false), instr.hfma2.type_a);
2123 std::string op_b, op_c; 2127 std::string op_b, op_c;
2124 2128
2125 switch (opcode->GetId()) { 2129 switch (opcode->get().GetId()) {
2126 case OpCode::Id::HFMA2_CR: 2130 case OpCode::Id::HFMA2_CR:
2127 op_b = GetHalfFloat(regs.GetUniform(instr.cbuf34.index, instr.cbuf34.offset, 2131 op_b = GetHalfFloat(regs.GetUniform(instr.cbuf34.index, instr.cbuf34.offset,
2128 GLSLRegister::Type::UnsignedInteger), 2132 GLSLRegister::Type::UnsignedInteger),
@@ -2160,7 +2164,7 @@ private:
2160 break; 2164 break;
2161 } 2165 }
2162 case OpCode::Type::Conversion: { 2166 case OpCode::Type::Conversion: {
2163 switch (opcode->GetId()) { 2167 switch (opcode->get().GetId()) {
2164 case OpCode::Id::I2I_R: { 2168 case OpCode::Id::I2I_R: {
2165 ASSERT_MSG(!instr.conversion.selector, "Unimplemented"); 2169 ASSERT_MSG(!instr.conversion.selector, "Unimplemented");
2166 2170
@@ -2298,14 +2302,15 @@ private:
2298 break; 2302 break;
2299 } 2303 }
2300 default: { 2304 default: {
2301 LOG_CRITICAL(HW_GPU, "Unhandled conversion instruction: {}", opcode->GetName()); 2305 LOG_CRITICAL(HW_GPU, "Unhandled conversion instruction: {}",
2306 opcode->get().GetName());
2302 UNREACHABLE(); 2307 UNREACHABLE();
2303 } 2308 }
2304 } 2309 }
2305 break; 2310 break;
2306 } 2311 }
2307 case OpCode::Type::Memory: { 2312 case OpCode::Type::Memory: {
2308 switch (opcode->GetId()) { 2313 switch (opcode->get().GetId()) {
2309 case OpCode::Id::LD_A: { 2314 case OpCode::Id::LD_A: {
2310 // Note: Shouldn't this be interp mode flat? As in no interpolation made. 2315 // Note: Shouldn't this be interp mode flat? As in no interpolation made.
2311 ASSERT_MSG(instr.gpr8.Value() == Register::ZeroIndex, 2316 ASSERT_MSG(instr.gpr8.Value() == Register::ZeroIndex,
@@ -2949,7 +2954,7 @@ private:
2949 break; 2954 break;
2950 } 2955 }
2951 default: { 2956 default: {
2952 LOG_CRITICAL(HW_GPU, "Unhandled memory instruction: {}", opcode->GetName()); 2957 LOG_CRITICAL(HW_GPU, "Unhandled memory instruction: {}", opcode->get().GetName());
2953 UNREACHABLE(); 2958 UNREACHABLE();
2954 } 2959 }
2955 } 2960 }
@@ -3043,7 +3048,7 @@ private:
3043 instr.hsetp2.abs_a, instr.hsetp2.negate_a); 3048 instr.hsetp2.abs_a, instr.hsetp2.negate_a);
3044 3049
3045 const std::string op_b = [&]() { 3050 const std::string op_b = [&]() {
3046 switch (opcode->GetId()) { 3051 switch (opcode->get().GetId()) {
3047 case OpCode::Id::HSETP2_R: 3052 case OpCode::Id::HSETP2_R:
3048 return GetHalfFloat(regs.GetRegisterAsInteger(instr.gpr20, 0, false), 3053 return GetHalfFloat(regs.GetRegisterAsInteger(instr.gpr20, 0, false),
3049 instr.hsetp2.type_b, instr.hsetp2.abs_a, 3054 instr.hsetp2.type_b, instr.hsetp2.abs_a,
@@ -3105,7 +3110,7 @@ private:
3105 break; 3110 break;
3106 } 3111 }
3107 case OpCode::Type::PredicateSetPredicate: { 3112 case OpCode::Type::PredicateSetPredicate: {
3108 switch (opcode->GetId()) { 3113 switch (opcode->get().GetId()) {
3109 case OpCode::Id::PSETP: { 3114 case OpCode::Id::PSETP: {
3110 const std::string op_a = 3115 const std::string op_a =
3111 GetPredicateCondition(instr.psetp.pred12, instr.psetp.neg_pred12 != 0); 3116 GetPredicateCondition(instr.psetp.pred12, instr.psetp.neg_pred12 != 0);
@@ -3151,7 +3156,8 @@ private:
3151 break; 3156 break;
3152 } 3157 }
3153 default: { 3158 default: {
3154 LOG_CRITICAL(HW_GPU, "Unhandled predicate instruction: {}", opcode->GetName()); 3159 LOG_CRITICAL(HW_GPU, "Unhandled predicate instruction: {}",
3160 opcode->get().GetName());
3155 UNREACHABLE(); 3161 UNREACHABLE();
3156 } 3162 }
3157 } 3163 }
@@ -3239,7 +3245,7 @@ private:
3239 instr.hset2.abs_a != 0, instr.hset2.negate_a != 0); 3245 instr.hset2.abs_a != 0, instr.hset2.negate_a != 0);
3240 3246
3241 const std::string op_b = [&]() { 3247 const std::string op_b = [&]() {
3242 switch (opcode->GetId()) { 3248 switch (opcode->get().GetId()) {
3243 case OpCode::Id::HSET2_R: 3249 case OpCode::Id::HSET2_R:
3244 return GetHalfFloat(regs.GetRegisterAsInteger(instr.gpr20, 0, false), 3250 return GetHalfFloat(regs.GetRegisterAsInteger(instr.gpr20, 0, false),
3245 instr.hset2.type_b, instr.hset2.abs_b != 0, 3251 instr.hset2.type_b, instr.hset2.abs_b != 0,
@@ -3288,7 +3294,7 @@ private:
3288 const bool is_signed{instr.xmad.sign_a == 1}; 3294 const bool is_signed{instr.xmad.sign_a == 1};
3289 3295
3290 bool is_merge{}; 3296 bool is_merge{};
3291 switch (opcode->GetId()) { 3297 switch (opcode->get().GetId()) {
3292 case OpCode::Id::XMAD_CR: { 3298 case OpCode::Id::XMAD_CR: {
3293 is_merge = instr.xmad.merge_56; 3299 is_merge = instr.xmad.merge_56;
3294 op_b += regs.GetUniform(instr.cbuf34.index, instr.cbuf34.offset, 3300 op_b += regs.GetUniform(instr.cbuf34.index, instr.cbuf34.offset,
@@ -3317,7 +3323,7 @@ private:
3317 break; 3323 break;
3318 } 3324 }
3319 default: { 3325 default: {
3320 LOG_CRITICAL(HW_GPU, "Unhandled XMAD instruction: {}", opcode->GetName()); 3326 LOG_CRITICAL(HW_GPU, "Unhandled XMAD instruction: {}", opcode->get().GetName());
3321 UNREACHABLE(); 3327 UNREACHABLE();
3322 } 3328 }
3323 } 3329 }
@@ -3369,7 +3375,7 @@ private:
3369 break; 3375 break;
3370 } 3376 }
3371 default: { 3377 default: {
3372 switch (opcode->GetId()) { 3378 switch (opcode->get().GetId()) {
3373 case OpCode::Id::EXIT: { 3379 case OpCode::Id::EXIT: {
3374 if (stage == Maxwell3D::Regs::ShaderStage::Fragment) { 3380 if (stage == Maxwell3D::Regs::ShaderStage::Fragment) {
3375 EmitFragmentOutputsWrite(); 3381 EmitFragmentOutputsWrite();
@@ -3564,7 +3570,7 @@ private:
3564 break; 3570 break;
3565 } 3571 }
3566 default: { 3572 default: {
3567 LOG_CRITICAL(HW_GPU, "Unhandled instruction: {}", opcode->GetName()); 3573 LOG_CRITICAL(HW_GPU, "Unhandled instruction: {}", opcode->get().GetName());
3568 UNREACHABLE(); 3574 UNREACHABLE();
3569 } 3575 }
3570 } 3576 }
@@ -3705,9 +3711,9 @@ std::string GetCommonDeclarations() {
3705 RasterizerOpenGL::MaxConstbufferSize / sizeof(GLvec4)); 3711 RasterizerOpenGL::MaxConstbufferSize / sizeof(GLvec4));
3706} 3712}
3707 3713
3708boost::optional<ProgramResult> DecompileProgram(const ProgramCode& program_code, u32 main_offset, 3714std::optional<ProgramResult> DecompileProgram(const ProgramCode& program_code, u32 main_offset,
3709 Maxwell3D::Regs::ShaderStage stage, 3715 Maxwell3D::Regs::ShaderStage stage,
3710 const std::string& suffix) { 3716 const std::string& suffix) {
3711 try { 3717 try {
3712 const auto subroutines = 3718 const auto subroutines =
3713 ControlFlowAnalyzer(program_code, main_offset, suffix).GetSubroutines(); 3719 ControlFlowAnalyzer(program_code, main_offset, suffix).GetSubroutines();
@@ -3716,7 +3722,7 @@ boost::optional<ProgramResult> DecompileProgram(const ProgramCode& program_code,
3716 } catch (const DecompileFail& exception) { 3722 } catch (const DecompileFail& exception) {
3717 LOG_ERROR(HW_GPU, "Shader decompilation failed: {}", exception.what()); 3723 LOG_ERROR(HW_GPU, "Shader decompilation failed: {}", exception.what());
3718 } 3724 }
3719 return boost::none; 3725 return {};
3720} 3726}
3721 3727
3722} // namespace OpenGL::GLShader::Decompiler 3728} // namespace OpenGL::GLShader::Decompiler
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.h b/src/video_core/renderer_opengl/gl_shader_decompiler.h
index b20cc4bfa..d01a4a7ee 100644
--- a/src/video_core/renderer_opengl/gl_shader_decompiler.h
+++ b/src/video_core/renderer_opengl/gl_shader_decompiler.h
@@ -6,8 +6,8 @@
6 6
7#include <array> 7#include <array>
8#include <functional> 8#include <functional>
9#include <optional>
9#include <string> 10#include <string>
10#include <boost/optional.hpp>
11#include "common/common_types.h" 11#include "common/common_types.h"
12#include "video_core/engines/maxwell_3d.h" 12#include "video_core/engines/maxwell_3d.h"
13#include "video_core/renderer_opengl/gl_shader_gen.h" 13#include "video_core/renderer_opengl/gl_shader_gen.h"
@@ -18,8 +18,8 @@ using Tegra::Engines::Maxwell3D;
18 18
19std::string GetCommonDeclarations(); 19std::string GetCommonDeclarations();
20 20
21boost::optional<ProgramResult> DecompileProgram(const ProgramCode& program_code, u32 main_offset, 21std::optional<ProgramResult> DecompileProgram(const ProgramCode& program_code, u32 main_offset,
22 Maxwell3D::Regs::ShaderStage stage, 22 Maxwell3D::Regs::ShaderStage stage,
23 const std::string& suffix); 23 const std::string& suffix);
24 24
25} // namespace OpenGL::GLShader::Decompiler 25} // namespace OpenGL::GLShader::Decompiler
diff --git a/src/video_core/renderer_opengl/gl_shader_gen.cpp b/src/video_core/renderer_opengl/gl_shader_gen.cpp
index dfb562706..9d17edd63 100644
--- a/src/video_core/renderer_opengl/gl_shader_gen.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_gen.cpp
@@ -37,7 +37,7 @@ layout(std140) uniform vs_config {
37 ProgramResult program = 37 ProgramResult program =
38 Decompiler::DecompileProgram(setup.program.code, PROGRAM_OFFSET, 38 Decompiler::DecompileProgram(setup.program.code, PROGRAM_OFFSET,
39 Maxwell3D::Regs::ShaderStage::Vertex, "vertex") 39 Maxwell3D::Regs::ShaderStage::Vertex, "vertex")
40 .get_value_or({}); 40 .value_or(ProgramResult());
41 41
42 out += program.first; 42 out += program.first;
43 43
@@ -45,7 +45,7 @@ layout(std140) uniform vs_config {
45 ProgramResult program_b = 45 ProgramResult program_b =
46 Decompiler::DecompileProgram(setup.program.code_b, PROGRAM_OFFSET, 46 Decompiler::DecompileProgram(setup.program.code_b, PROGRAM_OFFSET,
47 Maxwell3D::Regs::ShaderStage::Vertex, "vertex_b") 47 Maxwell3D::Regs::ShaderStage::Vertex, "vertex_b")
48 .get_value_or({}); 48 .value_or(ProgramResult());
49 out += program_b.first; 49 out += program_b.first;
50 } 50 }
51 51
@@ -90,7 +90,7 @@ ProgramResult GenerateGeometryShader(const ShaderSetup& setup) {
90 ProgramResult program = 90 ProgramResult program =
91 Decompiler::DecompileProgram(setup.program.code, PROGRAM_OFFSET, 91 Decompiler::DecompileProgram(setup.program.code, PROGRAM_OFFSET,
92 Maxwell3D::Regs::ShaderStage::Geometry, "geometry") 92 Maxwell3D::Regs::ShaderStage::Geometry, "geometry")
93 .get_value_or({}); 93 .value_or(ProgramResult());
94 out += R"( 94 out += R"(
95out gl_PerVertex { 95out gl_PerVertex {
96 vec4 gl_Position; 96 vec4 gl_Position;
@@ -124,7 +124,7 @@ ProgramResult GenerateFragmentShader(const ShaderSetup& setup) {
124 ProgramResult program = 124 ProgramResult program =
125 Decompiler::DecompileProgram(setup.program.code, PROGRAM_OFFSET, 125 Decompiler::DecompileProgram(setup.program.code, PROGRAM_OFFSET,
126 Maxwell3D::Regs::ShaderStage::Fragment, "fragment") 126 Maxwell3D::Regs::ShaderStage::Fragment, "fragment")
127 .get_value_or({}); 127 .value_or(ProgramResult());
128 out += R"( 128 out += R"(
129layout(location = 0) out vec4 FragColor0; 129layout(location = 0) out vec4 FragColor0;
130layout(location = 1) out vec4 FragColor1; 130layout(location = 1) out vec4 FragColor1;
diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp
index 90b68943d..ea38da932 100644
--- a/src/video_core/renderer_opengl/renderer_opengl.cpp
+++ b/src/video_core/renderer_opengl/renderer_opengl.cpp
@@ -115,7 +115,8 @@ RendererOpenGL::RendererOpenGL(Core::Frontend::EmuWindow& window)
115RendererOpenGL::~RendererOpenGL() = default; 115RendererOpenGL::~RendererOpenGL() = default;
116 116
117/// Swap buffers (render frame) 117/// Swap buffers (render frame)
118void RendererOpenGL::SwapBuffers(boost::optional<const Tegra::FramebufferConfig&> framebuffer) { 118void RendererOpenGL::SwapBuffers(
119 std::optional<std::reference_wrapper<const Tegra::FramebufferConfig>> framebuffer) {
119 ScopeAcquireGLContext acquire_context{render_window}; 120 ScopeAcquireGLContext acquire_context{render_window};
120 121
121 Core::System::GetInstance().GetPerfStats().EndSystemFrame(); 122 Core::System::GetInstance().GetPerfStats().EndSystemFrame();
@@ -124,11 +125,11 @@ void RendererOpenGL::SwapBuffers(boost::optional<const Tegra::FramebufferConfig&
124 OpenGLState prev_state = OpenGLState::GetCurState(); 125 OpenGLState prev_state = OpenGLState::GetCurState();
125 state.Apply(); 126 state.Apply();
126 127
127 if (framebuffer != boost::none) { 128 if (framebuffer) {
128 // If framebuffer is provided, reload it from memory to a texture 129 // If framebuffer is provided, reload it from memory to a texture
129 if (screen_info.texture.width != (GLsizei)framebuffer->width || 130 if (screen_info.texture.width != (GLsizei)framebuffer->get().width ||
130 screen_info.texture.height != (GLsizei)framebuffer->height || 131 screen_info.texture.height != (GLsizei)framebuffer->get().height ||
131 screen_info.texture.pixel_format != framebuffer->pixel_format) { 132 screen_info.texture.pixel_format != framebuffer->get().pixel_format) {
132 // Reallocate texture if the framebuffer size has changed. 133 // Reallocate texture if the framebuffer size has changed.
133 // This is expected to not happen very often and hence should not be a 134 // This is expected to not happen very often and hence should not be a
134 // performance problem. 135 // performance problem.
diff --git a/src/video_core/renderer_opengl/renderer_opengl.h b/src/video_core/renderer_opengl/renderer_opengl.h
index 961467a62..c0868c0e4 100644
--- a/src/video_core/renderer_opengl/renderer_opengl.h
+++ b/src/video_core/renderer_opengl/renderer_opengl.h
@@ -51,7 +51,8 @@ public:
51 ~RendererOpenGL() override; 51 ~RendererOpenGL() override;
52 52
53 /// Swap buffers (render frame) 53 /// Swap buffers (render frame)
54 void SwapBuffers(boost::optional<const Tegra::FramebufferConfig&> framebuffer) override; 54 void SwapBuffers(
55 std::optional<std::reference_wrapper<const Tegra::FramebufferConfig>> framebuffer) override;
55 56
56 /// Initialize the renderer 57 /// Initialize the renderer
57 bool Init() override; 58 bool Init() override;
diff --git a/src/yuzu/configuration/configure_input.cpp b/src/yuzu/configuration/configure_input.cpp
index 94789c064..42a7beac6 100644
--- a/src/yuzu/configuration/configure_input.cpp
+++ b/src/yuzu/configuration/configure_input.cpp
@@ -322,7 +322,7 @@ void ConfigureInput::setPollingResult(const Common::ParamPackage& params, bool a
322 } 322 }
323 323
324 updateButtonLabels(); 324 updateButtonLabels();
325 input_setter = boost::none; 325 input_setter = {};
326} 326}
327 327
328void ConfigureInput::keyPressEvent(QKeyEvent* event) { 328void ConfigureInput::keyPressEvent(QKeyEvent* event) {
diff --git a/src/yuzu/configuration/configure_input.h b/src/yuzu/configuration/configure_input.h
index d1198db81..32c7183f9 100644
--- a/src/yuzu/configuration/configure_input.h
+++ b/src/yuzu/configuration/configure_input.h
@@ -7,11 +7,13 @@
7#include <array> 7#include <array>
8#include <functional> 8#include <functional>
9#include <memory> 9#include <memory>
10#include <optional>
10#include <string> 11#include <string>
11#include <unordered_map> 12#include <unordered_map>
13
12#include <QKeyEvent> 14#include <QKeyEvent>
13#include <QWidget> 15#include <QWidget>
14#include <boost/optional.hpp> 16
15#include "common/param_package.h" 17#include "common/param_package.h"
16#include "core/settings.h" 18#include "core/settings.h"
17#include "input_common/main.h" 19#include "input_common/main.h"
@@ -41,7 +43,7 @@ private:
41 std::unique_ptr<QTimer> poll_timer; 43 std::unique_ptr<QTimer> poll_timer;
42 44
43 /// This will be the the setting function when an input is awaiting configuration. 45 /// This will be the the setting function when an input is awaiting configuration.
44 boost::optional<std::function<void(const Common::ParamPackage&)>> input_setter; 46 std::optional<std::function<void(const Common::ParamPackage&)>> input_setter;
45 47
46 std::array<Common::ParamPackage, Settings::NativeButton::NumButtons> buttons_param; 48 std::array<Common::ParamPackage, Settings::NativeButton::NumButtons> buttons_param;
47 std::array<Common::ParamPackage, Settings::NativeAnalog::NumAnalogs> analogs_param; 49 std::array<Common::ParamPackage, Settings::NativeAnalog::NumAnalogs> analogs_param;
diff --git a/src/yuzu/configuration/configure_system.cpp b/src/yuzu/configuration/configure_system.cpp
index 4b34c1e28..bb7ae3da4 100644
--- a/src/yuzu/configuration/configure_system.cpp
+++ b/src/yuzu/configuration/configure_system.cpp
@@ -173,7 +173,7 @@ void ConfigureSystem::UpdateCurrentUser() {
173 ui->pm_add->setEnabled(profile_manager->GetUserCount() < Service::Account::MAX_USERS); 173 ui->pm_add->setEnabled(profile_manager->GetUserCount() < Service::Account::MAX_USERS);
174 174
175 const auto& current_user = profile_manager->GetUser(Settings::values.current_user); 175 const auto& current_user = profile_manager->GetUser(Settings::values.current_user);
176 ASSERT(current_user != std::nullopt); 176 ASSERT(current_user);
177 const auto username = GetAccountUsername(*profile_manager, *current_user); 177 const auto username = GetAccountUsername(*profile_manager, *current_user);
178 178
179 scene->clear(); 179 scene->clear();
@@ -261,7 +261,7 @@ void ConfigureSystem::AddUser() {
261void ConfigureSystem::RenameUser() { 261void ConfigureSystem::RenameUser() {
262 const auto user = tree_view->currentIndex().row(); 262 const auto user = tree_view->currentIndex().row();
263 const auto uuid = profile_manager->GetUser(user); 263 const auto uuid = profile_manager->GetUser(user);
264 ASSERT(uuid != std::nullopt); 264 ASSERT(uuid);
265 265
266 Service::Account::ProfileBase profile; 266 Service::Account::ProfileBase profile;
267 if (!profile_manager->GetProfileBase(*uuid, profile)) 267 if (!profile_manager->GetProfileBase(*uuid, profile))
@@ -297,7 +297,7 @@ void ConfigureSystem::RenameUser() {
297void ConfigureSystem::DeleteUser() { 297void ConfigureSystem::DeleteUser() {
298 const auto index = tree_view->currentIndex().row(); 298 const auto index = tree_view->currentIndex().row();
299 const auto uuid = profile_manager->GetUser(index); 299 const auto uuid = profile_manager->GetUser(index);
300 ASSERT(uuid != std::nullopt); 300 ASSERT(uuid);
301 const auto username = GetAccountUsername(*profile_manager, *uuid); 301 const auto username = GetAccountUsername(*profile_manager, *uuid);
302 302
303 const auto confirm = QMessageBox::question( 303 const auto confirm = QMessageBox::question(
@@ -324,7 +324,7 @@ void ConfigureSystem::DeleteUser() {
324void ConfigureSystem::SetUserImage() { 324void ConfigureSystem::SetUserImage() {
325 const auto index = tree_view->currentIndex().row(); 325 const auto index = tree_view->currentIndex().row();
326 const auto uuid = profile_manager->GetUser(index); 326 const auto uuid = profile_manager->GetUser(index);
327 ASSERT(uuid != std::nullopt); 327 ASSERT(uuid);
328 328
329 const auto file = QFileDialog::getOpenFileName(this, tr("Select User Image"), QString(), 329 const auto file = QFileDialog::getOpenFileName(this, tr("Select User Image"), QString(),
330 tr("JPEG Images (*.jpg *.jpeg)")); 330 tr("JPEG Images (*.jpg *.jpeg)"));
diff --git a/src/yuzu/debugger/graphics/graphics_surface.cpp b/src/yuzu/debugger/graphics/graphics_surface.cpp
index 44d423da2..0adbab27d 100644
--- a/src/yuzu/debugger/graphics/graphics_surface.cpp
+++ b/src/yuzu/debugger/graphics/graphics_surface.cpp
@@ -382,7 +382,7 @@ void GraphicsSurfaceWidget::OnUpdate() {
382 // TODO: Implement a good way to visualize alpha components! 382 // TODO: Implement a good way to visualize alpha components!
383 383
384 QImage decoded_image(surface_width, surface_height, QImage::Format_ARGB32); 384 QImage decoded_image(surface_width, surface_height, QImage::Format_ARGB32);
385 boost::optional<VAddr> address = gpu.MemoryManager().GpuToCpuAddress(surface_address); 385 std::optional<VAddr> address = gpu.MemoryManager().GpuToCpuAddress(surface_address);
386 386
387 // TODO(bunnei): Will not work with BCn formats that swizzle 4x4 tiles. 387 // TODO(bunnei): Will not work with BCn formats that swizzle 4x4 tiles.
388 // Needs to be fixed if we plan to use this feature more, otherwise we may remove it. 388 // Needs to be fixed if we plan to use this feature more, otherwise we may remove it.
@@ -444,7 +444,7 @@ void GraphicsSurfaceWidget::SaveSurface() {
444 pixmap->save(&file, "PNG"); 444 pixmap->save(&file, "PNG");
445 } else if (selectedFilter == bin_filter) { 445 } else if (selectedFilter == bin_filter) {
446 auto& gpu = Core::System::GetInstance().GPU(); 446 auto& gpu = Core::System::GetInstance().GPU();
447 boost::optional<VAddr> address = gpu.MemoryManager().GpuToCpuAddress(surface_address); 447 std::optional<VAddr> address = gpu.MemoryManager().GpuToCpuAddress(surface_address);
448 448
449 const u8* buffer = Memory::GetPointer(*address); 449 const u8* buffer = Memory::GetPointer(*address);
450 ASSERT_MSG(buffer != nullptr, "Memory not accessible"); 450 ASSERT_MSG(buffer != nullptr, "Memory not accessible");
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp
index b5bfa6741..c5a56cbfd 100644
--- a/src/yuzu/main.cpp
+++ b/src/yuzu/main.cpp
@@ -786,7 +786,7 @@ void GMainWindow::OnGameListOpenFolder(u64 program_id, GameListOpenTarget target
786 ASSERT(index != -1 && index < 8); 786 ASSERT(index != -1 && index < 8);
787 787
788 const auto user_id = manager.GetUser(index); 788 const auto user_id = manager.GetUser(index);
789 ASSERT(user_id != std::nullopt); 789 ASSERT(user_id);
790 path = nand_dir + FileSys::SaveDataFactory::GetFullPath(FileSys::SaveDataSpaceId::NandUser, 790 path = nand_dir + FileSys::SaveDataFactory::GetFullPath(FileSys::SaveDataSpaceId::NandUser,
791 FileSys::SaveDataType::SaveData, 791 FileSys::SaveDataType::SaveData,
792 program_id, user_id->uuid, 0); 792 program_id, user_id->uuid, 0);
@@ -1560,7 +1560,7 @@ void GMainWindow::OnReinitializeKeys(ReinitializeKeyBehavior behavior) {
1560 } 1560 }
1561} 1561}
1562 1562
1563boost::optional<u64> GMainWindow::SelectRomFSDumpTarget( 1563std::optional<u64> GMainWindow::SelectRomFSDumpTarget(
1564 const FileSys::RegisteredCacheUnion& installed, u64 program_id) { 1564 const FileSys::RegisteredCacheUnion& installed, u64 program_id) {
1565 const auto dlc_entries = 1565 const auto dlc_entries =
1566 installed.ListEntriesFilter(FileSys::TitleType::AOC, FileSys::ContentRecordType::Data); 1566 installed.ListEntriesFilter(FileSys::TitleType::AOC, FileSys::ContentRecordType::Data);
@@ -1587,7 +1587,7 @@ boost::optional<u64> GMainWindow::SelectRomFSDumpTarget(
1587 this, tr("Select RomFS Dump Target"), 1587 this, tr("Select RomFS Dump Target"),
1588 tr("Please select which RomFS you would like to dump."), list, 0, false, &ok); 1588 tr("Please select which RomFS you would like to dump."), list, 0, false, &ok);
1589 if (!ok) { 1589 if (!ok) {
1590 return boost::none; 1590 return {};
1591 } 1591 }
1592 1592
1593 return romfs_tids[list.indexOf(res)]; 1593 return romfs_tids[list.indexOf(res)];
diff --git a/src/yuzu/main.h b/src/yuzu/main.h
index 7c7c223e1..af637d89e 100644
--- a/src/yuzu/main.h
+++ b/src/yuzu/main.h
@@ -5,12 +5,12 @@
5#pragma once 5#pragma once
6 6
7#include <memory> 7#include <memory>
8#include <optional>
8#include <unordered_map> 9#include <unordered_map>
9 10
10#include <QMainWindow> 11#include <QMainWindow>
11#include <QTimer> 12#include <QTimer>
12 13
13#include <boost/optional.hpp>
14#include "common/common_types.h" 14#include "common/common_types.h"
15#include "core/core.h" 15#include "core/core.h"
16#include "ui_main.h" 16#include "ui_main.h"
@@ -178,8 +178,7 @@ private slots:
178 void OnReinitializeKeys(ReinitializeKeyBehavior behavior); 178 void OnReinitializeKeys(ReinitializeKeyBehavior behavior);
179 179
180private: 180private:
181 boost::optional<u64> SelectRomFSDumpTarget(const FileSys::RegisteredCacheUnion&, 181 std::optional<u64> SelectRomFSDumpTarget(const FileSys::RegisteredCacheUnion&, u64 program_id);
182 u64 program_id);
183 void UpdateStatusBar(); 182 void UpdateStatusBar();
184 183
185 Ui::MainWindow ui; 184 Ui::MainWindow ui;