diff options
66 files changed, 1005 insertions, 933 deletions
diff --git a/src/audio_core/audio_renderer.cpp b/src/audio_core/audio_renderer.cpp index 23e5d3f10..2e59894ab 100644 --- a/src/audio_core/audio_renderer.cpp +++ b/src/audio_core/audio_renderer.cpp | |||
| @@ -8,7 +8,7 @@ | |||
| 8 | #include "audio_core/codec.h" | 8 | #include "audio_core/codec.h" |
| 9 | #include "common/assert.h" | 9 | #include "common/assert.h" |
| 10 | #include "common/logging/log.h" | 10 | #include "common/logging/log.h" |
| 11 | #include "core/hle/kernel/event.h" | 11 | #include "core/hle/kernel/writable_event.h" |
| 12 | #include "core/memory.h" | 12 | #include "core/memory.h" |
| 13 | 13 | ||
| 14 | namespace AudioCore { | 14 | namespace AudioCore { |
| @@ -72,7 +72,7 @@ private: | |||
| 72 | EffectInStatus info{}; | 72 | EffectInStatus info{}; |
| 73 | }; | 73 | }; |
| 74 | AudioRenderer::AudioRenderer(AudioRendererParameter params, | 74 | AudioRenderer::AudioRenderer(AudioRendererParameter params, |
| 75 | Kernel::SharedPtr<Kernel::Event> buffer_event) | 75 | Kernel::SharedPtr<Kernel::WritableEvent> buffer_event) |
| 76 | : worker_params{params}, buffer_event{buffer_event}, voices(params.voice_count), | 76 | : worker_params{params}, buffer_event{buffer_event}, voices(params.voice_count), |
| 77 | effects(params.effect_count) { | 77 | effects(params.effect_count) { |
| 78 | 78 | ||
diff --git a/src/audio_core/audio_renderer.h b/src/audio_core/audio_renderer.h index 71ba4be40..7826881bf 100644 --- a/src/audio_core/audio_renderer.h +++ b/src/audio_core/audio_renderer.h | |||
| @@ -15,7 +15,7 @@ | |||
| 15 | #include "core/hle/kernel/object.h" | 15 | #include "core/hle/kernel/object.h" |
| 16 | 16 | ||
| 17 | namespace Kernel { | 17 | namespace Kernel { |
| 18 | class Event; | 18 | class WritableEvent; |
| 19 | } | 19 | } |
| 20 | 20 | ||
| 21 | namespace AudioCore { | 21 | namespace AudioCore { |
| @@ -208,7 +208,8 @@ static_assert(sizeof(UpdateDataHeader) == 0x40, "UpdateDataHeader has wrong size | |||
| 208 | 208 | ||
| 209 | class AudioRenderer { | 209 | class AudioRenderer { |
| 210 | public: | 210 | public: |
| 211 | AudioRenderer(AudioRendererParameter params, Kernel::SharedPtr<Kernel::Event> buffer_event); | 211 | AudioRenderer(AudioRendererParameter params, |
| 212 | Kernel::SharedPtr<Kernel::WritableEvent> buffer_event); | ||
| 212 | ~AudioRenderer(); | 213 | ~AudioRenderer(); |
| 213 | 214 | ||
| 214 | std::vector<u8> UpdateAudioRenderer(const std::vector<u8>& input_params); | 215 | std::vector<u8> UpdateAudioRenderer(const std::vector<u8>& input_params); |
| @@ -224,7 +225,7 @@ private: | |||
| 224 | class VoiceState; | 225 | class VoiceState; |
| 225 | 226 | ||
| 226 | AudioRendererParameter worker_params; | 227 | AudioRendererParameter worker_params; |
| 227 | Kernel::SharedPtr<Kernel::Event> buffer_event; | 228 | Kernel::SharedPtr<Kernel::WritableEvent> buffer_event; |
| 228 | std::vector<VoiceState> voices; | 229 | std::vector<VoiceState> voices; |
| 229 | std::vector<EffectState> effects; | 230 | std::vector<EffectState> effects; |
| 230 | std::unique_ptr<AudioOut> audio_out; | 231 | std::unique_ptr<AudioOut> audio_out; |
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index e1f21a764..73aec8ab0 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt | |||
| @@ -97,8 +97,6 @@ add_library(core STATIC | |||
| 97 | hle/kernel/client_session.cpp | 97 | hle/kernel/client_session.cpp |
| 98 | hle/kernel/client_session.h | 98 | hle/kernel/client_session.h |
| 99 | hle/kernel/errors.h | 99 | hle/kernel/errors.h |
| 100 | hle/kernel/event.cpp | ||
| 101 | hle/kernel/event.h | ||
| 102 | hle/kernel/handle_table.cpp | 100 | hle/kernel/handle_table.cpp |
| 103 | hle/kernel/handle_table.h | 101 | hle/kernel/handle_table.h |
| 104 | hle/kernel/hle_ipc.cpp | 102 | hle/kernel/hle_ipc.cpp |
| @@ -111,6 +109,8 @@ add_library(core STATIC | |||
| 111 | hle/kernel/object.h | 109 | hle/kernel/object.h |
| 112 | hle/kernel/process.cpp | 110 | hle/kernel/process.cpp |
| 113 | hle/kernel/process.h | 111 | hle/kernel/process.h |
| 112 | hle/kernel/readable_event.cpp | ||
| 113 | hle/kernel/readable_event.h | ||
| 114 | hle/kernel/resource_limit.cpp | 114 | hle/kernel/resource_limit.cpp |
| 115 | hle/kernel/resource_limit.h | 115 | hle/kernel/resource_limit.h |
| 116 | hle/kernel/scheduler.cpp | 116 | hle/kernel/scheduler.cpp |
| @@ -133,6 +133,8 @@ add_library(core STATIC | |||
| 133 | hle/kernel/vm_manager.h | 133 | hle/kernel/vm_manager.h |
| 134 | hle/kernel/wait_object.cpp | 134 | hle/kernel/wait_object.cpp |
| 135 | hle/kernel/wait_object.h | 135 | hle/kernel/wait_object.h |
| 136 | hle/kernel/writable_event.cpp | ||
| 137 | hle/kernel/writable_event.h | ||
| 136 | hle/lock.cpp | 138 | hle/lock.cpp |
| 137 | hle/lock.h | 139 | hle/lock.h |
| 138 | hle/result.h | 140 | hle/result.h |
diff --git a/src/core/crypto/key_manager.cpp b/src/core/crypto/key_manager.cpp index 904afa039..ed231927b 100644 --- a/src/core/crypto/key_manager.cpp +++ b/src/core/crypto/key_manager.cpp | |||
| @@ -794,7 +794,7 @@ void KeyManager::DeriveBase() { | |||
| 794 | 794 | ||
| 795 | void KeyManager::DeriveETicket(PartitionDataManager& data) { | 795 | void KeyManager::DeriveETicket(PartitionDataManager& data) { |
| 796 | // ETicket keys | 796 | // ETicket keys |
| 797 | const auto es = Service::FileSystem::GetUnionContents()->GetEntry( | 797 | const auto es = Service::FileSystem::GetUnionContents().GetEntry( |
| 798 | 0x0100000000000033, FileSys::ContentRecordType::Program); | 798 | 0x0100000000000033, FileSys::ContentRecordType::Program); |
| 799 | 799 | ||
| 800 | if (es == nullptr) | 800 | if (es == nullptr) |
diff --git a/src/core/file_sys/patch_manager.cpp b/src/core/file_sys/patch_manager.cpp index e8df08724..6b14e08be 100644 --- a/src/core/file_sys/patch_manager.cpp +++ b/src/core/file_sys/patch_manager.cpp | |||
| @@ -75,12 +75,12 @@ VirtualDir PatchManager::PatchExeFS(VirtualDir exefs) const { | |||
| 75 | 75 | ||
| 76 | // Game Updates | 76 | // Game Updates |
| 77 | const auto update_tid = GetUpdateTitleID(title_id); | 77 | const auto update_tid = GetUpdateTitleID(title_id); |
| 78 | const auto update = installed->GetEntry(update_tid, ContentRecordType::Program); | 78 | const auto update = installed.GetEntry(update_tid, ContentRecordType::Program); |
| 79 | 79 | ||
| 80 | if (update != nullptr && update->GetExeFS() != nullptr && | 80 | if (update != nullptr && update->GetExeFS() != nullptr && |
| 81 | update->GetStatus() == Loader::ResultStatus::ErrorMissingBKTRBaseRomFS) { | 81 | update->GetStatus() == Loader::ResultStatus::ErrorMissingBKTRBaseRomFS) { |
| 82 | LOG_INFO(Loader, " ExeFS: Update ({}) applied successfully", | 82 | LOG_INFO(Loader, " ExeFS: Update ({}) applied successfully", |
| 83 | FormatTitleVersion(installed->GetEntryVersion(update_tid).value_or(0))); | 83 | FormatTitleVersion(installed.GetEntryVersion(update_tid).value_or(0))); |
| 84 | exefs = update->GetExeFS(); | 84 | exefs = update->GetExeFS(); |
| 85 | } | 85 | } |
| 86 | 86 | ||
| @@ -281,13 +281,13 @@ VirtualFile PatchManager::PatchRomFS(VirtualFile romfs, u64 ivfc_offset, Content | |||
| 281 | 281 | ||
| 282 | // Game Updates | 282 | // Game Updates |
| 283 | const auto update_tid = GetUpdateTitleID(title_id); | 283 | const auto update_tid = GetUpdateTitleID(title_id); |
| 284 | const auto update = installed->GetEntryRaw(update_tid, type); | 284 | const auto update = installed.GetEntryRaw(update_tid, type); |
| 285 | if (update != nullptr) { | 285 | if (update != nullptr) { |
| 286 | const auto new_nca = std::make_shared<NCA>(update, romfs, ivfc_offset); | 286 | const auto new_nca = std::make_shared<NCA>(update, romfs, ivfc_offset); |
| 287 | if (new_nca->GetStatus() == Loader::ResultStatus::Success && | 287 | if (new_nca->GetStatus() == Loader::ResultStatus::Success && |
| 288 | new_nca->GetRomFS() != nullptr) { | 288 | new_nca->GetRomFS() != nullptr) { |
| 289 | LOG_INFO(Loader, " RomFS: Update ({}) applied successfully", | 289 | LOG_INFO(Loader, " RomFS: Update ({}) applied successfully", |
| 290 | FormatTitleVersion(installed->GetEntryVersion(update_tid).value_or(0))); | 290 | FormatTitleVersion(installed.GetEntryVersion(update_tid).value_or(0))); |
| 291 | romfs = new_nca->GetRomFS(); | 291 | romfs = new_nca->GetRomFS(); |
| 292 | } | 292 | } |
| 293 | } else if (update_raw != nullptr) { | 293 | } else if (update_raw != nullptr) { |
| @@ -329,8 +329,8 @@ std::map<std::string, std::string, std::less<>> PatchManager::GetPatchVersionNam | |||
| 329 | if (nacp != nullptr) { | 329 | if (nacp != nullptr) { |
| 330 | out.insert_or_assign("Update", nacp->GetVersionString()); | 330 | out.insert_or_assign("Update", nacp->GetVersionString()); |
| 331 | } else { | 331 | } else { |
| 332 | if (installed->HasEntry(update_tid, ContentRecordType::Program)) { | 332 | if (installed.HasEntry(update_tid, ContentRecordType::Program)) { |
| 333 | const auto meta_ver = installed->GetEntryVersion(update_tid); | 333 | const auto meta_ver = installed.GetEntryVersion(update_tid); |
| 334 | if (meta_ver.value_or(0) == 0) { | 334 | if (meta_ver.value_or(0) == 0) { |
| 335 | out.insert_or_assign("Update", ""); | 335 | out.insert_or_assign("Update", ""); |
| 336 | } else { | 336 | } else { |
| @@ -383,14 +383,13 @@ std::map<std::string, std::string, std::less<>> PatchManager::GetPatchVersionNam | |||
| 383 | } | 383 | } |
| 384 | 384 | ||
| 385 | // DLC | 385 | // DLC |
| 386 | const auto dlc_entries = installed->ListEntriesFilter(TitleType::AOC, ContentRecordType::Data); | 386 | const auto dlc_entries = installed.ListEntriesFilter(TitleType::AOC, ContentRecordType::Data); |
| 387 | std::vector<RegisteredCacheEntry> dlc_match; | 387 | std::vector<RegisteredCacheEntry> dlc_match; |
| 388 | dlc_match.reserve(dlc_entries.size()); | 388 | dlc_match.reserve(dlc_entries.size()); |
| 389 | std::copy_if(dlc_entries.begin(), dlc_entries.end(), std::back_inserter(dlc_match), | 389 | std::copy_if(dlc_entries.begin(), dlc_entries.end(), std::back_inserter(dlc_match), |
| 390 | [this, &installed](const RegisteredCacheEntry& entry) { | 390 | [this, &installed](const RegisteredCacheEntry& entry) { |
| 391 | return (entry.title_id & DLC_BASE_TITLE_ID_MASK) == title_id && | 391 | return (entry.title_id & DLC_BASE_TITLE_ID_MASK) == title_id && |
| 392 | installed->GetEntry(entry)->GetStatus() == | 392 | installed.GetEntry(entry)->GetStatus() == Loader::ResultStatus::Success; |
| 393 | Loader::ResultStatus::Success; | ||
| 394 | }); | 393 | }); |
| 395 | if (!dlc_match.empty()) { | 394 | if (!dlc_match.empty()) { |
| 396 | // Ensure sorted so DLC IDs show in order. | 395 | // Ensure sorted so DLC IDs show in order. |
| @@ -411,7 +410,7 @@ std::map<std::string, std::string, std::less<>> PatchManager::GetPatchVersionNam | |||
| 411 | std::pair<std::unique_ptr<NACP>, VirtualFile> PatchManager::GetControlMetadata() const { | 410 | std::pair<std::unique_ptr<NACP>, VirtualFile> PatchManager::GetControlMetadata() const { |
| 412 | const auto installed{Service::FileSystem::GetUnionContents()}; | 411 | const auto installed{Service::FileSystem::GetUnionContents()}; |
| 413 | 412 | ||
| 414 | const auto base_control_nca = installed->GetEntry(title_id, ContentRecordType::Control); | 413 | const auto base_control_nca = installed.GetEntry(title_id, ContentRecordType::Control); |
| 415 | if (base_control_nca == nullptr) | 414 | if (base_control_nca == nullptr) |
| 416 | return {}; | 415 | return {}; |
| 417 | 416 | ||
diff --git a/src/core/file_sys/romfs_factory.cpp b/src/core/file_sys/romfs_factory.cpp index 0b645b106..6ad1e4f86 100644 --- a/src/core/file_sys/romfs_factory.cpp +++ b/src/core/file_sys/romfs_factory.cpp | |||
| @@ -48,7 +48,7 @@ ResultVal<VirtualFile> RomFSFactory::Open(u64 title_id, StorageId storage, Conte | |||
| 48 | 48 | ||
| 49 | switch (storage) { | 49 | switch (storage) { |
| 50 | case StorageId::None: | 50 | case StorageId::None: |
| 51 | res = Service::FileSystem::GetUnionContents()->GetEntry(title_id, type); | 51 | res = Service::FileSystem::GetUnionContents().GetEntry(title_id, type); |
| 52 | break; | 52 | break; |
| 53 | case StorageId::NandSystem: | 53 | case StorageId::NandSystem: |
| 54 | res = Service::FileSystem::GetSystemNANDContents()->GetEntry(title_id, type); | 54 | res = Service::FileSystem::GetSystemNANDContents()->GetEntry(title_id, type); |
diff --git a/src/core/file_sys/vfs.cpp b/src/core/file_sys/vfs.cpp index 7b584de7f..e33327ef0 100644 --- a/src/core/file_sys/vfs.cpp +++ b/src/core/file_sys/vfs.cpp | |||
| @@ -384,6 +384,28 @@ bool VfsDirectory::DeleteSubdirectoryRecursive(std::string_view name) { | |||
| 384 | return success; | 384 | return success; |
| 385 | } | 385 | } |
| 386 | 386 | ||
| 387 | bool VfsDirectory::CleanSubdirectoryRecursive(std::string_view name) { | ||
| 388 | auto dir = GetSubdirectory(name); | ||
| 389 | if (dir == nullptr) { | ||
| 390 | return false; | ||
| 391 | } | ||
| 392 | |||
| 393 | bool success = true; | ||
| 394 | for (const auto& file : dir->GetFiles()) { | ||
| 395 | if (!dir->DeleteFile(file->GetName())) { | ||
| 396 | success = false; | ||
| 397 | } | ||
| 398 | } | ||
| 399 | |||
| 400 | for (const auto& sdir : dir->GetSubdirectories()) { | ||
| 401 | if (!dir->DeleteSubdirectoryRecursive(sdir->GetName())) { | ||
| 402 | success = false; | ||
| 403 | } | ||
| 404 | } | ||
| 405 | |||
| 406 | return success; | ||
| 407 | } | ||
| 408 | |||
| 387 | bool VfsDirectory::Copy(std::string_view src, std::string_view dest) { | 409 | bool VfsDirectory::Copy(std::string_view src, std::string_view dest) { |
| 388 | const auto f1 = GetFile(src); | 410 | const auto f1 = GetFile(src); |
| 389 | auto f2 = CreateFile(dest); | 411 | auto f2 = CreateFile(dest); |
| @@ -431,10 +453,34 @@ std::shared_ptr<VfsFile> ReadOnlyVfsDirectory::CreateFile(std::string_view name) | |||
| 431 | return nullptr; | 453 | return nullptr; |
| 432 | } | 454 | } |
| 433 | 455 | ||
| 456 | std::shared_ptr<VfsFile> ReadOnlyVfsDirectory::CreateFileAbsolute(std::string_view path) { | ||
| 457 | return nullptr; | ||
| 458 | } | ||
| 459 | |||
| 460 | std::shared_ptr<VfsFile> ReadOnlyVfsDirectory::CreateFileRelative(std::string_view path) { | ||
| 461 | return nullptr; | ||
| 462 | } | ||
| 463 | |||
| 464 | std::shared_ptr<VfsDirectory> ReadOnlyVfsDirectory::CreateDirectoryAbsolute(std::string_view path) { | ||
| 465 | return nullptr; | ||
| 466 | } | ||
| 467 | |||
| 468 | std::shared_ptr<VfsDirectory> ReadOnlyVfsDirectory::CreateDirectoryRelative(std::string_view path) { | ||
| 469 | return nullptr; | ||
| 470 | } | ||
| 471 | |||
| 434 | bool ReadOnlyVfsDirectory::DeleteSubdirectory(std::string_view name) { | 472 | bool ReadOnlyVfsDirectory::DeleteSubdirectory(std::string_view name) { |
| 435 | return false; | 473 | return false; |
| 436 | } | 474 | } |
| 437 | 475 | ||
| 476 | bool ReadOnlyVfsDirectory::DeleteSubdirectoryRecursive(std::string_view name) { | ||
| 477 | return false; | ||
| 478 | } | ||
| 479 | |||
| 480 | bool ReadOnlyVfsDirectory::CleanSubdirectoryRecursive(std::string_view name) { | ||
| 481 | return false; | ||
| 482 | } | ||
| 483 | |||
| 438 | bool ReadOnlyVfsDirectory::DeleteFile(std::string_view name) { | 484 | bool ReadOnlyVfsDirectory::DeleteFile(std::string_view name) { |
| 439 | return false; | 485 | return false; |
| 440 | } | 486 | } |
diff --git a/src/core/file_sys/vfs.h b/src/core/file_sys/vfs.h index 002f99d4e..e5641b255 100644 --- a/src/core/file_sys/vfs.h +++ b/src/core/file_sys/vfs.h | |||
| @@ -245,12 +245,18 @@ public: | |||
| 245 | // any failure. | 245 | // any failure. |
| 246 | virtual std::shared_ptr<VfsDirectory> CreateDirectoryAbsolute(std::string_view path); | 246 | virtual std::shared_ptr<VfsDirectory> CreateDirectoryAbsolute(std::string_view path); |
| 247 | 247 | ||
| 248 | // Deletes the subdirectory with name and returns true on success. | 248 | // Deletes the subdirectory with the given name and returns true on success. |
| 249 | virtual bool DeleteSubdirectory(std::string_view name) = 0; | 249 | virtual bool DeleteSubdirectory(std::string_view name) = 0; |
| 250 | // Deletes all subdirectories and files of subdirectory with name recirsively and then deletes | 250 | |
| 251 | // the subdirectory. Returns true on success. | 251 | // Deletes all subdirectories and files within the provided directory and then deletes |
| 252 | // the directory itself. Returns true on success. | ||
| 252 | virtual bool DeleteSubdirectoryRecursive(std::string_view name); | 253 | virtual bool DeleteSubdirectoryRecursive(std::string_view name); |
| 253 | // Returnes whether or not the file with name name was deleted successfully. | 254 | |
| 255 | // Deletes all subdirectories and files within the provided directory. | ||
| 256 | // Unlike DeleteSubdirectoryRecursive, this does not delete the provided directory. | ||
| 257 | virtual bool CleanSubdirectoryRecursive(std::string_view name); | ||
| 258 | |||
| 259 | // Returns whether or not the file with name name was deleted successfully. | ||
| 254 | virtual bool DeleteFile(std::string_view name) = 0; | 260 | virtual bool DeleteFile(std::string_view name) = 0; |
| 255 | 261 | ||
| 256 | // Returns whether or not this directory was renamed to name. | 262 | // Returns whether or not this directory was renamed to name. |
| @@ -276,7 +282,13 @@ public: | |||
| 276 | bool IsReadable() const override; | 282 | bool IsReadable() const override; |
| 277 | std::shared_ptr<VfsDirectory> CreateSubdirectory(std::string_view name) override; | 283 | std::shared_ptr<VfsDirectory> CreateSubdirectory(std::string_view name) override; |
| 278 | std::shared_ptr<VfsFile> CreateFile(std::string_view name) override; | 284 | std::shared_ptr<VfsFile> CreateFile(std::string_view name) override; |
| 285 | std::shared_ptr<VfsFile> CreateFileAbsolute(std::string_view path) override; | ||
| 286 | std::shared_ptr<VfsFile> CreateFileRelative(std::string_view path) override; | ||
| 287 | std::shared_ptr<VfsDirectory> CreateDirectoryAbsolute(std::string_view path) override; | ||
| 288 | std::shared_ptr<VfsDirectory> CreateDirectoryRelative(std::string_view path) override; | ||
| 279 | bool DeleteSubdirectory(std::string_view name) override; | 289 | bool DeleteSubdirectory(std::string_view name) override; |
| 290 | bool DeleteSubdirectoryRecursive(std::string_view name) override; | ||
| 291 | bool CleanSubdirectoryRecursive(std::string_view name) override; | ||
| 280 | bool DeleteFile(std::string_view name) override; | 292 | bool DeleteFile(std::string_view name) override; |
| 281 | bool Rename(std::string_view name) override; | 293 | bool Rename(std::string_view name) override; |
| 282 | }; | 294 | }; |
diff --git a/src/core/hle/kernel/handle_table.cpp b/src/core/hle/kernel/handle_table.cpp index 1bf79b692..c8acde5b1 100644 --- a/src/core/hle/kernel/handle_table.cpp +++ b/src/core/hle/kernel/handle_table.cpp | |||
| @@ -42,9 +42,10 @@ ResultVal<Handle> HandleTable::Create(SharedPtr<Object> obj) { | |||
| 42 | u16 generation = next_generation++; | 42 | u16 generation = next_generation++; |
| 43 | 43 | ||
| 44 | // Overflow count so it fits in the 15 bits dedicated to the generation in the handle. | 44 | // Overflow count so it fits in the 15 bits dedicated to the generation in the handle. |
| 45 | // CTR-OS doesn't use generation 0, so skip straight to 1. | 45 | // Horizon OS uses zero to represent an invalid handle, so skip to 1. |
| 46 | if (next_generation >= (1 << 15)) | 46 | if (next_generation >= (1 << 15)) { |
| 47 | next_generation = 1; | 47 | next_generation = 1; |
| 48 | } | ||
| 48 | 49 | ||
| 49 | generations[slot] = generation; | 50 | generations[slot] = generation; |
| 50 | objects[slot] = std::move(obj); | 51 | objects[slot] = std::move(obj); |
diff --git a/src/core/hle/kernel/handle_table.h b/src/core/hle/kernel/handle_table.h index e3f3e3fb8..6b7927fd8 100644 --- a/src/core/hle/kernel/handle_table.h +++ b/src/core/hle/kernel/handle_table.h | |||
| @@ -13,6 +13,7 @@ | |||
| 13 | namespace Kernel { | 13 | namespace Kernel { |
| 14 | 14 | ||
| 15 | enum KernelHandle : Handle { | 15 | enum KernelHandle : Handle { |
| 16 | InvalidHandle = 0, | ||
| 16 | CurrentThread = 0xFFFF8000, | 17 | CurrentThread = 0xFFFF8000, |
| 17 | CurrentProcess = 0xFFFF8001, | 18 | CurrentProcess = 0xFFFF8001, |
| 18 | }; | 19 | }; |
diff --git a/src/core/hle/kernel/hle_ipc.cpp b/src/core/hle/kernel/hle_ipc.cpp index 68d5376cb..61ce7d7e4 100644 --- a/src/core/hle/kernel/hle_ipc.cpp +++ b/src/core/hle/kernel/hle_ipc.cpp | |||
| @@ -15,13 +15,14 @@ | |||
| 15 | #include "common/logging/log.h" | 15 | #include "common/logging/log.h" |
| 16 | #include "core/core.h" | 16 | #include "core/core.h" |
| 17 | #include "core/hle/ipc_helpers.h" | 17 | #include "core/hle/ipc_helpers.h" |
| 18 | #include "core/hle/kernel/event.h" | ||
| 19 | #include "core/hle/kernel/handle_table.h" | 18 | #include "core/hle/kernel/handle_table.h" |
| 20 | #include "core/hle/kernel/hle_ipc.h" | 19 | #include "core/hle/kernel/hle_ipc.h" |
| 21 | #include "core/hle/kernel/kernel.h" | 20 | #include "core/hle/kernel/kernel.h" |
| 22 | #include "core/hle/kernel/object.h" | 21 | #include "core/hle/kernel/object.h" |
| 23 | #include "core/hle/kernel/process.h" | 22 | #include "core/hle/kernel/process.h" |
| 23 | #include "core/hle/kernel/readable_event.h" | ||
| 24 | #include "core/hle/kernel/server_session.h" | 24 | #include "core/hle/kernel/server_session.h" |
| 25 | #include "core/hle/kernel/writable_event.h" | ||
| 25 | #include "core/memory.h" | 26 | #include "core/memory.h" |
| 26 | 27 | ||
| 27 | namespace Kernel { | 28 | namespace Kernel { |
| @@ -36,11 +37,9 @@ void SessionRequestHandler::ClientDisconnected(const SharedPtr<ServerSession>& s | |||
| 36 | boost::range::remove_erase(connected_sessions, server_session); | 37 | boost::range::remove_erase(connected_sessions, server_session); |
| 37 | } | 38 | } |
| 38 | 39 | ||
| 39 | SharedPtr<Event> HLERequestContext::SleepClientThread(SharedPtr<Thread> thread, | 40 | SharedPtr<WritableEvent> HLERequestContext::SleepClientThread( |
| 40 | const std::string& reason, u64 timeout, | 41 | SharedPtr<Thread> thread, const std::string& reason, u64 timeout, WakeupCallback&& callback, |
| 41 | WakeupCallback&& callback, | 42 | SharedPtr<WritableEvent> writable_event) { |
| 42 | Kernel::SharedPtr<Kernel::Event> event) { | ||
| 43 | |||
| 44 | // Put the client thread to sleep until the wait event is signaled or the timeout expires. | 43 | // Put the client thread to sleep until the wait event is signaled or the timeout expires. |
| 45 | thread->SetWakeupCallback([context = *this, callback]( | 44 | thread->SetWakeupCallback([context = *this, callback]( |
| 46 | ThreadWakeupReason reason, SharedPtr<Thread> thread, | 45 | ThreadWakeupReason reason, SharedPtr<Thread> thread, |
| @@ -51,23 +50,25 @@ SharedPtr<Event> HLERequestContext::SleepClientThread(SharedPtr<Thread> thread, | |||
| 51 | return true; | 50 | return true; |
| 52 | }); | 51 | }); |
| 53 | 52 | ||
| 54 | if (!event) { | 53 | auto& kernel = Core::System::GetInstance().Kernel(); |
| 54 | if (!writable_event) { | ||
| 55 | // Create event if not provided | 55 | // Create event if not provided |
| 56 | auto& kernel = Core::System::GetInstance().Kernel(); | 56 | const auto pair = WritableEvent::CreateEventPair(kernel, Kernel::ResetType::OneShot, |
| 57 | event = | 57 | "HLE Pause Event: " + reason); |
| 58 | Kernel::Event::Create(kernel, Kernel::ResetType::OneShot, "HLE Pause Event: " + reason); | 58 | writable_event = pair.writable; |
| 59 | } | 59 | } |
| 60 | 60 | ||
| 61 | event->Clear(); | 61 | const auto readable_event{writable_event->GetReadableEvent()}; |
| 62 | writable_event->Clear(); | ||
| 62 | thread->SetStatus(ThreadStatus::WaitHLEEvent); | 63 | thread->SetStatus(ThreadStatus::WaitHLEEvent); |
| 63 | thread->SetWaitObjects({event}); | 64 | thread->SetWaitObjects({readable_event}); |
| 64 | event->AddWaitingThread(thread); | 65 | readable_event->AddWaitingThread(thread); |
| 65 | 66 | ||
| 66 | if (timeout > 0) { | 67 | if (timeout > 0) { |
| 67 | thread->WakeAfterDelay(timeout); | 68 | thread->WakeAfterDelay(timeout); |
| 68 | } | 69 | } |
| 69 | 70 | ||
| 70 | return event; | 71 | return writable_event; |
| 71 | } | 72 | } |
| 72 | 73 | ||
| 73 | HLERequestContext::HLERequestContext(SharedPtr<Kernel::ServerSession> server_session) | 74 | HLERequestContext::HLERequestContext(SharedPtr<Kernel::ServerSession> server_session) |
diff --git a/src/core/hle/kernel/hle_ipc.h b/src/core/hle/kernel/hle_ipc.h index a38e34b74..e5c0610cd 100644 --- a/src/core/hle/kernel/hle_ipc.h +++ b/src/core/hle/kernel/hle_ipc.h | |||
| @@ -24,10 +24,11 @@ class ServiceFrameworkBase; | |||
| 24 | namespace Kernel { | 24 | namespace Kernel { |
| 25 | 25 | ||
| 26 | class Domain; | 26 | class Domain; |
| 27 | class Event; | ||
| 28 | class HandleTable; | 27 | class HandleTable; |
| 29 | class HLERequestContext; | 28 | class HLERequestContext; |
| 30 | class Process; | 29 | class Process; |
| 30 | class ReadableEvent; | ||
| 31 | class WritableEvent; | ||
| 31 | 32 | ||
| 32 | /** | 33 | /** |
| 33 | * Interface implemented by HLE Session handlers. | 34 | * Interface implemented by HLE Session handlers. |
| @@ -119,12 +120,13 @@ public: | |||
| 119 | * @param callback Callback to be invoked when the thread is resumed. This callback must write | 120 | * @param callback Callback to be invoked when the thread is resumed. This callback must write |
| 120 | * the entire command response once again, regardless of the state of it before this function | 121 | * the entire command response once again, regardless of the state of it before this function |
| 121 | * was called. | 122 | * was called. |
| 122 | * @param event Event to use to wake up the thread. If unspecified, an event will be created. | 123 | * @param writable_event Event to use to wake up the thread. If unspecified, an event will be |
| 124 | * created. | ||
| 123 | * @returns Event that when signaled will resume the thread and call the callback function. | 125 | * @returns Event that when signaled will resume the thread and call the callback function. |
| 124 | */ | 126 | */ |
| 125 | SharedPtr<Event> SleepClientThread(SharedPtr<Thread> thread, const std::string& reason, | 127 | SharedPtr<WritableEvent> SleepClientThread(SharedPtr<Thread> thread, const std::string& reason, |
| 126 | u64 timeout, WakeupCallback&& callback, | 128 | u64 timeout, WakeupCallback&& callback, |
| 127 | Kernel::SharedPtr<Kernel::Event> event = nullptr); | 129 | SharedPtr<WritableEvent> writable_event = nullptr); |
| 128 | 130 | ||
| 129 | /// Populates this context with data from the requesting process/thread. | 131 | /// Populates this context with data from the requesting process/thread. |
| 130 | ResultCode PopulateFromIncomingCommandBuffer(const HandleTable& handle_table, | 132 | ResultCode PopulateFromIncomingCommandBuffer(const HandleTable& handle_table, |
diff --git a/src/core/hle/kernel/object.cpp b/src/core/hle/kernel/object.cpp index d87a62bb9..bb1b68778 100644 --- a/src/core/hle/kernel/object.cpp +++ b/src/core/hle/kernel/object.cpp | |||
| @@ -13,7 +13,7 @@ Object::~Object() = default; | |||
| 13 | 13 | ||
| 14 | bool Object::IsWaitable() const { | 14 | bool Object::IsWaitable() const { |
| 15 | switch (GetHandleType()) { | 15 | switch (GetHandleType()) { |
| 16 | case HandleType::Event: | 16 | case HandleType::ReadableEvent: |
| 17 | case HandleType::Thread: | 17 | case HandleType::Thread: |
| 18 | case HandleType::Timer: | 18 | case HandleType::Timer: |
| 19 | case HandleType::ServerPort: | 19 | case HandleType::ServerPort: |
| @@ -21,6 +21,7 @@ bool Object::IsWaitable() const { | |||
| 21 | return true; | 21 | return true; |
| 22 | 22 | ||
| 23 | case HandleType::Unknown: | 23 | case HandleType::Unknown: |
| 24 | case HandleType::WritableEvent: | ||
| 24 | case HandleType::SharedMemory: | 25 | case HandleType::SharedMemory: |
| 25 | case HandleType::Process: | 26 | case HandleType::Process: |
| 26 | case HandleType::AddressArbiter: | 27 | case HandleType::AddressArbiter: |
diff --git a/src/core/hle/kernel/object.h b/src/core/hle/kernel/object.h index c9f4d0bb3..f1606a204 100644 --- a/src/core/hle/kernel/object.h +++ b/src/core/hle/kernel/object.h | |||
| @@ -19,7 +19,8 @@ using Handle = u32; | |||
| 19 | 19 | ||
| 20 | enum class HandleType : u32 { | 20 | enum class HandleType : u32 { |
| 21 | Unknown, | 21 | Unknown, |
| 22 | Event, | 22 | WritableEvent, |
| 23 | ReadableEvent, | ||
| 23 | SharedMemory, | 24 | SharedMemory, |
| 24 | Thread, | 25 | Thread, |
| 25 | Process, | 26 | Process, |
| @@ -33,9 +34,9 @@ enum class HandleType : u32 { | |||
| 33 | }; | 34 | }; |
| 34 | 35 | ||
| 35 | enum class ResetType { | 36 | enum class ResetType { |
| 36 | OneShot, | 37 | OneShot, ///< Reset automatically on object acquisition |
| 37 | Sticky, | 38 | Sticky, ///< Never reset automatically |
| 38 | Pulse, | 39 | Pulse, ///< Reset automatically on wakeup |
| 39 | }; | 40 | }; |
| 40 | 41 | ||
| 41 | class Object : NonCopyable { | 42 | class Object : NonCopyable { |
diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp index 7ca538401..4ecb8c926 100644 --- a/src/core/hle/kernel/process.cpp +++ b/src/core/hle/kernel/process.cpp | |||
| @@ -44,6 +44,10 @@ SharedPtr<Process> Process::Create(KernelCore& kernel, std::string&& name) { | |||
| 44 | return process; | 44 | return process; |
| 45 | } | 45 | } |
| 46 | 46 | ||
| 47 | SharedPtr<ResourceLimit> Process::GetResourceLimit() const { | ||
| 48 | return resource_limit; | ||
| 49 | } | ||
| 50 | |||
| 47 | void Process::LoadFromMetadata(const FileSys::ProgramMetadata& metadata) { | 51 | void Process::LoadFromMetadata(const FileSys::ProgramMetadata& metadata) { |
| 48 | program_id = metadata.GetTitleID(); | 52 | program_id = metadata.GetTitleID(); |
| 49 | is_64bit_process = metadata.Is64BitProgram(); | 53 | is_64bit_process = metadata.Is64BitProgram(); |
diff --git a/src/core/hle/kernel/process.h b/src/core/hle/kernel/process.h index ada845c7f..49345aa66 100644 --- a/src/core/hle/kernel/process.h +++ b/src/core/hle/kernel/process.h | |||
| @@ -171,14 +171,7 @@ public: | |||
| 171 | } | 171 | } |
| 172 | 172 | ||
| 173 | /// Gets the resource limit descriptor for this process | 173 | /// Gets the resource limit descriptor for this process |
| 174 | ResourceLimit& GetResourceLimit() { | 174 | SharedPtr<ResourceLimit> GetResourceLimit() const; |
| 175 | return *resource_limit; | ||
| 176 | } | ||
| 177 | |||
| 178 | /// Gets the resource limit descriptor for this process | ||
| 179 | const ResourceLimit& GetResourceLimit() const { | ||
| 180 | return *resource_limit; | ||
| 181 | } | ||
| 182 | 175 | ||
| 183 | /// Gets the default CPU ID for this process | 176 | /// Gets the default CPU ID for this process |
| 184 | u8 GetDefaultProcessorID() const { | 177 | u8 GetDefaultProcessorID() const { |
diff --git a/src/core/hle/kernel/event.cpp b/src/core/hle/kernel/readable_event.cpp index 8967e602e..92e16b4e6 100644 --- a/src/core/hle/kernel/event.cpp +++ b/src/core/hle/kernel/readable_event.cpp | |||
| @@ -4,46 +4,37 @@ | |||
| 4 | 4 | ||
| 5 | #include <algorithm> | 5 | #include <algorithm> |
| 6 | #include "common/assert.h" | 6 | #include "common/assert.h" |
| 7 | #include "core/hle/kernel/event.h" | ||
| 8 | #include "core/hle/kernel/object.h" | 7 | #include "core/hle/kernel/object.h" |
| 8 | #include "core/hle/kernel/readable_event.h" | ||
| 9 | #include "core/hle/kernel/thread.h" | 9 | #include "core/hle/kernel/thread.h" |
| 10 | #include "core/hle/kernel/writable_event.h" | ||
| 10 | 11 | ||
| 11 | namespace Kernel { | 12 | namespace Kernel { |
| 12 | 13 | ||
| 13 | Event::Event(KernelCore& kernel) : WaitObject{kernel} {} | 14 | ReadableEvent::ReadableEvent(KernelCore& kernel) : WaitObject{kernel} {} |
| 14 | Event::~Event() = default; | 15 | ReadableEvent::~ReadableEvent() = default; |
| 15 | 16 | ||
| 16 | SharedPtr<Event> Event::Create(KernelCore& kernel, ResetType reset_type, std::string name) { | 17 | bool ReadableEvent::ShouldWait(Thread* thread) const { |
| 17 | SharedPtr<Event> evt(new Event(kernel)); | ||
| 18 | |||
| 19 | evt->signaled = false; | ||
| 20 | evt->reset_type = reset_type; | ||
| 21 | evt->name = std::move(name); | ||
| 22 | |||
| 23 | return evt; | ||
| 24 | } | ||
| 25 | |||
| 26 | bool Event::ShouldWait(Thread* thread) const { | ||
| 27 | return !signaled; | 18 | return !signaled; |
| 28 | } | 19 | } |
| 29 | 20 | ||
| 30 | void Event::Acquire(Thread* thread) { | 21 | void ReadableEvent::Acquire(Thread* thread) { |
| 31 | ASSERT_MSG(!ShouldWait(thread), "object unavailable!"); | 22 | ASSERT_MSG(!ShouldWait(thread), "object unavailable!"); |
| 32 | 23 | ||
| 33 | if (reset_type == ResetType::OneShot) | 24 | if (reset_type == ResetType::OneShot) |
| 34 | signaled = false; | 25 | signaled = false; |
| 35 | } | 26 | } |
| 36 | 27 | ||
| 37 | void Event::Signal() { | 28 | void ReadableEvent::Signal() { |
| 38 | signaled = true; | 29 | signaled = true; |
| 39 | WakeupAllWaitingThreads(); | 30 | WakeupAllWaitingThreads(); |
| 40 | } | 31 | } |
| 41 | 32 | ||
| 42 | void Event::Clear() { | 33 | void ReadableEvent::Clear() { |
| 43 | signaled = false; | 34 | signaled = false; |
| 44 | } | 35 | } |
| 45 | 36 | ||
| 46 | void Event::WakeupAllWaitingThreads() { | 37 | void ReadableEvent::WakeupAllWaitingThreads() { |
| 47 | WaitObject::WakeupAllWaitingThreads(); | 38 | WaitObject::WakeupAllWaitingThreads(); |
| 48 | 39 | ||
| 49 | if (reset_type == ResetType::Pulse) | 40 | if (reset_type == ResetType::Pulse) |
diff --git a/src/core/hle/kernel/readable_event.h b/src/core/hle/kernel/readable_event.h new file mode 100644 index 000000000..867ff3051 --- /dev/null +++ b/src/core/hle/kernel/readable_event.h | |||
| @@ -0,0 +1,55 @@ | |||
| 1 | // Copyright 2014 Citra Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include "core/hle/kernel/object.h" | ||
| 8 | #include "core/hle/kernel/wait_object.h" | ||
| 9 | |||
| 10 | namespace Kernel { | ||
| 11 | |||
| 12 | class KernelCore; | ||
| 13 | class WritableEvent; | ||
| 14 | |||
| 15 | class ReadableEvent final : public WaitObject { | ||
| 16 | friend class WritableEvent; | ||
| 17 | |||
| 18 | public: | ||
| 19 | ~ReadableEvent() override; | ||
| 20 | |||
| 21 | std::string GetTypeName() const override { | ||
| 22 | return "ReadableEvent"; | ||
| 23 | } | ||
| 24 | std::string GetName() const override { | ||
| 25 | return name; | ||
| 26 | } | ||
| 27 | |||
| 28 | ResetType GetResetType() const { | ||
| 29 | return reset_type; | ||
| 30 | } | ||
| 31 | |||
| 32 | static const HandleType HANDLE_TYPE = HandleType::ReadableEvent; | ||
| 33 | HandleType GetHandleType() const override { | ||
| 34 | return HANDLE_TYPE; | ||
| 35 | } | ||
| 36 | |||
| 37 | bool ShouldWait(Thread* thread) const override; | ||
| 38 | void Acquire(Thread* thread) override; | ||
| 39 | |||
| 40 | void WakeupAllWaitingThreads() override; | ||
| 41 | |||
| 42 | void Clear(); | ||
| 43 | |||
| 44 | private: | ||
| 45 | explicit ReadableEvent(KernelCore& kernel); | ||
| 46 | |||
| 47 | void Signal(); | ||
| 48 | |||
| 49 | ResetType reset_type; | ||
| 50 | bool signaled; | ||
| 51 | |||
| 52 | std::string name; ///< Name of event (optional) | ||
| 53 | }; | ||
| 54 | |||
| 55 | } // namespace Kernel | ||
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index 3339777c1..812b32005 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp | |||
| @@ -20,17 +20,18 @@ | |||
| 20 | #include "core/hle/kernel/address_arbiter.h" | 20 | #include "core/hle/kernel/address_arbiter.h" |
| 21 | #include "core/hle/kernel/client_port.h" | 21 | #include "core/hle/kernel/client_port.h" |
| 22 | #include "core/hle/kernel/client_session.h" | 22 | #include "core/hle/kernel/client_session.h" |
| 23 | #include "core/hle/kernel/event.h" | ||
| 24 | #include "core/hle/kernel/handle_table.h" | 23 | #include "core/hle/kernel/handle_table.h" |
| 25 | #include "core/hle/kernel/kernel.h" | 24 | #include "core/hle/kernel/kernel.h" |
| 26 | #include "core/hle/kernel/mutex.h" | 25 | #include "core/hle/kernel/mutex.h" |
| 27 | #include "core/hle/kernel/process.h" | 26 | #include "core/hle/kernel/process.h" |
| 27 | #include "core/hle/kernel/readable_event.h" | ||
| 28 | #include "core/hle/kernel/resource_limit.h" | 28 | #include "core/hle/kernel/resource_limit.h" |
| 29 | #include "core/hle/kernel/scheduler.h" | 29 | #include "core/hle/kernel/scheduler.h" |
| 30 | #include "core/hle/kernel/shared_memory.h" | 30 | #include "core/hle/kernel/shared_memory.h" |
| 31 | #include "core/hle/kernel/svc.h" | 31 | #include "core/hle/kernel/svc.h" |
| 32 | #include "core/hle/kernel/svc_wrap.h" | 32 | #include "core/hle/kernel/svc_wrap.h" |
| 33 | #include "core/hle/kernel/thread.h" | 33 | #include "core/hle/kernel/thread.h" |
| 34 | #include "core/hle/kernel/writable_event.h" | ||
| 34 | #include "core/hle/lock.h" | 35 | #include "core/hle/lock.h" |
| 35 | #include "core/hle/result.h" | 36 | #include "core/hle/result.h" |
| 36 | #include "core/hle/service/service.h" | 37 | #include "core/hle/service/service.h" |
| @@ -662,7 +663,7 @@ static ResultCode GetInfo(u64* result, u64 info_id, u64 handle, u64 info_sub_id) | |||
| 662 | TotalMemoryUsage = 6, | 663 | TotalMemoryUsage = 6, |
| 663 | TotalHeapUsage = 7, | 664 | TotalHeapUsage = 7, |
| 664 | IsCurrentProcessBeingDebugged = 8, | 665 | IsCurrentProcessBeingDebugged = 8, |
| 665 | ResourceHandleLimit = 9, | 666 | RegisterResourceLimit = 9, |
| 666 | IdleTickCount = 10, | 667 | IdleTickCount = 10, |
| 667 | RandomEntropy = 11, | 668 | RandomEntropy = 11, |
| 668 | PerformanceCounter = 0xF0000002, | 669 | PerformanceCounter = 0xF0000002, |
| @@ -682,37 +683,137 @@ static ResultCode GetInfo(u64* result, u64 info_id, u64 handle, u64 info_sub_id) | |||
| 682 | ThreadTickCount = 0xF0000002, | 683 | ThreadTickCount = 0xF0000002, |
| 683 | }; | 684 | }; |
| 684 | 685 | ||
| 685 | const auto* current_process = Core::CurrentProcess(); | 686 | const auto info_id_type = static_cast<GetInfoType>(info_id); |
| 686 | const auto& vm_manager = current_process->VMManager(); | ||
| 687 | 687 | ||
| 688 | switch (static_cast<GetInfoType>(info_id)) { | 688 | switch (info_id_type) { |
| 689 | case GetInfoType::AllowedCpuIdBitmask: | 689 | case GetInfoType::AllowedCpuIdBitmask: |
| 690 | *result = current_process->GetAllowedProcessorMask(); | ||
| 691 | break; | ||
| 692 | case GetInfoType::AllowedThreadPrioBitmask: | 690 | case GetInfoType::AllowedThreadPrioBitmask: |
| 693 | *result = current_process->GetAllowedThreadPriorityMask(); | ||
| 694 | break; | ||
| 695 | case GetInfoType::MapRegionBaseAddr: | 691 | case GetInfoType::MapRegionBaseAddr: |
| 696 | *result = vm_manager.GetMapRegionBaseAddress(); | ||
| 697 | break; | ||
| 698 | case GetInfoType::MapRegionSize: | 692 | case GetInfoType::MapRegionSize: |
| 699 | *result = vm_manager.GetMapRegionSize(); | ||
| 700 | break; | ||
| 701 | case GetInfoType::HeapRegionBaseAddr: | 693 | case GetInfoType::HeapRegionBaseAddr: |
| 702 | *result = vm_manager.GetHeapRegionBaseAddress(); | ||
| 703 | break; | ||
| 704 | case GetInfoType::HeapRegionSize: | 694 | case GetInfoType::HeapRegionSize: |
| 705 | *result = vm_manager.GetHeapRegionSize(); | 695 | case GetInfoType::ASLRRegionBaseAddr: |
| 706 | break; | 696 | case GetInfoType::ASLRRegionSize: |
| 697 | case GetInfoType::NewMapRegionBaseAddr: | ||
| 698 | case GetInfoType::NewMapRegionSize: | ||
| 707 | case GetInfoType::TotalMemoryUsage: | 699 | case GetInfoType::TotalMemoryUsage: |
| 708 | *result = vm_manager.GetTotalMemoryUsage(); | ||
| 709 | break; | ||
| 710 | case GetInfoType::TotalHeapUsage: | 700 | case GetInfoType::TotalHeapUsage: |
| 711 | *result = vm_manager.GetTotalHeapUsage(); | 701 | case GetInfoType::IsVirtualAddressMemoryEnabled: |
| 712 | break; | 702 | case GetInfoType::PersonalMmHeapUsage: |
| 703 | case GetInfoType::TitleId: | ||
| 704 | case GetInfoType::UserExceptionContextAddr: { | ||
| 705 | if (info_sub_id != 0) { | ||
| 706 | return ERR_INVALID_ENUM_VALUE; | ||
| 707 | } | ||
| 708 | |||
| 709 | const auto& current_process_handle_table = Core::CurrentProcess()->GetHandleTable(); | ||
| 710 | const auto process = current_process_handle_table.Get<Process>(static_cast<Handle>(handle)); | ||
| 711 | if (!process) { | ||
| 712 | return ERR_INVALID_HANDLE; | ||
| 713 | } | ||
| 714 | |||
| 715 | switch (info_id_type) { | ||
| 716 | case GetInfoType::AllowedCpuIdBitmask: | ||
| 717 | *result = process->GetAllowedProcessorMask(); | ||
| 718 | return RESULT_SUCCESS; | ||
| 719 | |||
| 720 | case GetInfoType::AllowedThreadPrioBitmask: | ||
| 721 | *result = process->GetAllowedThreadPriorityMask(); | ||
| 722 | return RESULT_SUCCESS; | ||
| 723 | |||
| 724 | case GetInfoType::MapRegionBaseAddr: | ||
| 725 | *result = process->VMManager().GetMapRegionBaseAddress(); | ||
| 726 | return RESULT_SUCCESS; | ||
| 727 | |||
| 728 | case GetInfoType::MapRegionSize: | ||
| 729 | *result = process->VMManager().GetMapRegionSize(); | ||
| 730 | return RESULT_SUCCESS; | ||
| 731 | |||
| 732 | case GetInfoType::HeapRegionBaseAddr: | ||
| 733 | *result = process->VMManager().GetHeapRegionBaseAddress(); | ||
| 734 | return RESULT_SUCCESS; | ||
| 735 | |||
| 736 | case GetInfoType::HeapRegionSize: | ||
| 737 | *result = process->VMManager().GetHeapRegionSize(); | ||
| 738 | return RESULT_SUCCESS; | ||
| 739 | |||
| 740 | case GetInfoType::ASLRRegionBaseAddr: | ||
| 741 | *result = process->VMManager().GetASLRRegionBaseAddress(); | ||
| 742 | return RESULT_SUCCESS; | ||
| 743 | |||
| 744 | case GetInfoType::ASLRRegionSize: | ||
| 745 | *result = process->VMManager().GetASLRRegionSize(); | ||
| 746 | return RESULT_SUCCESS; | ||
| 747 | |||
| 748 | case GetInfoType::NewMapRegionBaseAddr: | ||
| 749 | *result = process->VMManager().GetNewMapRegionBaseAddress(); | ||
| 750 | return RESULT_SUCCESS; | ||
| 751 | |||
| 752 | case GetInfoType::NewMapRegionSize: | ||
| 753 | *result = process->VMManager().GetNewMapRegionSize(); | ||
| 754 | return RESULT_SUCCESS; | ||
| 755 | |||
| 756 | case GetInfoType::TotalMemoryUsage: | ||
| 757 | *result = process->VMManager().GetTotalMemoryUsage(); | ||
| 758 | return RESULT_SUCCESS; | ||
| 759 | |||
| 760 | case GetInfoType::TotalHeapUsage: | ||
| 761 | *result = process->VMManager().GetTotalHeapUsage(); | ||
| 762 | return RESULT_SUCCESS; | ||
| 763 | |||
| 764 | case GetInfoType::IsVirtualAddressMemoryEnabled: | ||
| 765 | *result = process->IsVirtualMemoryEnabled(); | ||
| 766 | return RESULT_SUCCESS; | ||
| 767 | |||
| 768 | case GetInfoType::TitleId: | ||
| 769 | *result = process->GetTitleID(); | ||
| 770 | return RESULT_SUCCESS; | ||
| 771 | |||
| 772 | case GetInfoType::UserExceptionContextAddr: | ||
| 773 | LOG_WARNING(Kernel_SVC, | ||
| 774 | "(STUBBED) Attempted to query user exception context address, returned 0"); | ||
| 775 | *result = 0; | ||
| 776 | return RESULT_SUCCESS; | ||
| 777 | |||
| 778 | default: | ||
| 779 | break; | ||
| 780 | } | ||
| 781 | |||
| 782 | LOG_WARNING(Kernel_SVC, "(STUBBED) Unimplemented svcGetInfo id=0x{:016X}", info_id); | ||
| 783 | return ERR_INVALID_ENUM_VALUE; | ||
| 784 | } | ||
| 785 | |||
| 713 | case GetInfoType::IsCurrentProcessBeingDebugged: | 786 | case GetInfoType::IsCurrentProcessBeingDebugged: |
| 714 | *result = 0; | 787 | *result = 0; |
| 715 | break; | 788 | return RESULT_SUCCESS; |
| 789 | |||
| 790 | case GetInfoType::RegisterResourceLimit: { | ||
| 791 | if (handle != 0) { | ||
| 792 | return ERR_INVALID_HANDLE; | ||
| 793 | } | ||
| 794 | |||
| 795 | if (info_sub_id != 0) { | ||
| 796 | return ERR_INVALID_COMBINATION; | ||
| 797 | } | ||
| 798 | |||
| 799 | Process* const current_process = Core::CurrentProcess(); | ||
| 800 | HandleTable& handle_table = current_process->GetHandleTable(); | ||
| 801 | const auto resource_limit = current_process->GetResourceLimit(); | ||
| 802 | if (!resource_limit) { | ||
| 803 | *result = KernelHandle::InvalidHandle; | ||
| 804 | // Yes, the kernel considers this a successful operation. | ||
| 805 | return RESULT_SUCCESS; | ||
| 806 | } | ||
| 807 | |||
| 808 | const auto table_result = handle_table.Create(resource_limit); | ||
| 809 | if (table_result.Failed()) { | ||
| 810 | return table_result.Code(); | ||
| 811 | } | ||
| 812 | |||
| 813 | *result = *table_result; | ||
| 814 | return RESULT_SUCCESS; | ||
| 815 | } | ||
| 816 | |||
| 716 | case GetInfoType::RandomEntropy: | 817 | case GetInfoType::RandomEntropy: |
| 717 | if (handle != 0) { | 818 | if (handle != 0) { |
| 718 | LOG_ERROR(Kernel_SVC, "Process Handle is non zero, expected 0 result but got {:016X}", | 819 | LOG_ERROR(Kernel_SVC, "Process Handle is non zero, expected 0 result but got {:016X}", |
| @@ -726,37 +827,15 @@ static ResultCode GetInfo(u64* result, u64 info_id, u64 handle, u64 info_sub_id) | |||
| 726 | return ERR_INVALID_COMBINATION; | 827 | return ERR_INVALID_COMBINATION; |
| 727 | } | 828 | } |
| 728 | 829 | ||
| 729 | *result = current_process->GetRandomEntropy(info_sub_id); | 830 | *result = Core::CurrentProcess()->GetRandomEntropy(info_sub_id); |
| 730 | return RESULT_SUCCESS; | 831 | return RESULT_SUCCESS; |
| 731 | break; | 832 | |
| 732 | case GetInfoType::ASLRRegionBaseAddr: | ||
| 733 | *result = vm_manager.GetASLRRegionBaseAddress(); | ||
| 734 | break; | ||
| 735 | case GetInfoType::ASLRRegionSize: | ||
| 736 | *result = vm_manager.GetASLRRegionSize(); | ||
| 737 | break; | ||
| 738 | case GetInfoType::NewMapRegionBaseAddr: | ||
| 739 | *result = vm_manager.GetNewMapRegionBaseAddress(); | ||
| 740 | break; | ||
| 741 | case GetInfoType::NewMapRegionSize: | ||
| 742 | *result = vm_manager.GetNewMapRegionSize(); | ||
| 743 | break; | ||
| 744 | case GetInfoType::IsVirtualAddressMemoryEnabled: | ||
| 745 | *result = current_process->IsVirtualMemoryEnabled(); | ||
| 746 | break; | ||
| 747 | case GetInfoType::TitleId: | ||
| 748 | *result = current_process->GetTitleID(); | ||
| 749 | break; | ||
| 750 | case GetInfoType::PrivilegedProcessId: | 833 | case GetInfoType::PrivilegedProcessId: |
| 751 | LOG_WARNING(Kernel_SVC, | 834 | LOG_WARNING(Kernel_SVC, |
| 752 | "(STUBBED) Attempted to query privileged process id bounds, returned 0"); | 835 | "(STUBBED) Attempted to query privileged process id bounds, returned 0"); |
| 753 | *result = 0; | 836 | *result = 0; |
| 754 | break; | 837 | return RESULT_SUCCESS; |
| 755 | case GetInfoType::UserExceptionContextAddr: | 838 | |
| 756 | LOG_WARNING(Kernel_SVC, | ||
| 757 | "(STUBBED) Attempted to query user exception context address, returned 0"); | ||
| 758 | *result = 0; | ||
| 759 | break; | ||
| 760 | case GetInfoType::ThreadTickCount: { | 839 | case GetInfoType::ThreadTickCount: { |
| 761 | constexpr u64 num_cpus = 4; | 840 | constexpr u64 num_cpus = 4; |
| 762 | if (info_sub_id != 0xFFFFFFFFFFFFFFFF && info_sub_id >= num_cpus) { | 841 | if (info_sub_id != 0xFFFFFFFFFFFFFFFF && info_sub_id >= num_cpus) { |
| @@ -766,7 +845,7 @@ static ResultCode GetInfo(u64* result, u64 info_id, u64 handle, u64 info_sub_id) | |||
| 766 | } | 845 | } |
| 767 | 846 | ||
| 768 | const auto thread = | 847 | const auto thread = |
| 769 | current_process->GetHandleTable().Get<Thread>(static_cast<Handle>(handle)); | 848 | Core::CurrentProcess()->GetHandleTable().Get<Thread>(static_cast<Handle>(handle)); |
| 770 | if (!thread) { | 849 | if (!thread) { |
| 771 | LOG_ERROR(Kernel_SVC, "Thread handle does not exist, handle=0x{:08X}", | 850 | LOG_ERROR(Kernel_SVC, "Thread handle does not exist, handle=0x{:08X}", |
| 772 | static_cast<Handle>(handle)); | 851 | static_cast<Handle>(handle)); |
| @@ -789,14 +868,13 @@ static ResultCode GetInfo(u64* result, u64 info_id, u64 handle, u64 info_sub_id) | |||
| 789 | } | 868 | } |
| 790 | 869 | ||
| 791 | *result = out_ticks; | 870 | *result = out_ticks; |
| 792 | break; | 871 | return RESULT_SUCCESS; |
| 793 | } | 872 | } |
| 873 | |||
| 794 | default: | 874 | default: |
| 795 | LOG_WARNING(Kernel_SVC, "(STUBBED) Unimplemented svcGetInfo id=0x{:016X}", info_id); | 875 | LOG_WARNING(Kernel_SVC, "(STUBBED) Unimplemented svcGetInfo id=0x{:016X}", info_id); |
| 796 | return ERR_INVALID_ENUM_VALUE; | 876 | return ERR_INVALID_ENUM_VALUE; |
| 797 | } | 877 | } |
| 798 | |||
| 799 | return RESULT_SUCCESS; | ||
| 800 | } | 878 | } |
| 801 | 879 | ||
| 802 | /// Sets the thread activity | 880 | /// Sets the thread activity |
| @@ -1042,7 +1120,7 @@ static void ExitProcess() { | |||
| 1042 | static ResultCode CreateThread(Handle* out_handle, VAddr entry_point, u64 arg, VAddr stack_top, | 1120 | static ResultCode CreateThread(Handle* out_handle, VAddr entry_point, u64 arg, VAddr stack_top, |
| 1043 | u32 priority, s32 processor_id) { | 1121 | u32 priority, s32 processor_id) { |
| 1044 | LOG_TRACE(Kernel_SVC, | 1122 | LOG_TRACE(Kernel_SVC, |
| 1045 | "called entrypoint=0x{:08X} ({}), arg=0x{:08X}, stacktop=0x{:08X}, " | 1123 | "called entrypoint=0x{:08X}, arg=0x{:08X}, stacktop=0x{:08X}, " |
| 1046 | "threadpriority=0x{:08X}, processorid=0x{:08X} : created handle=0x{:08X}", | 1124 | "threadpriority=0x{:08X}, processorid=0x{:08X} : created handle=0x{:08X}", |
| 1047 | entry_point, arg, stack_top, priority, processor_id, *out_handle); | 1125 | entry_point, arg, stack_top, priority, processor_id, *out_handle); |
| 1048 | 1126 | ||
| @@ -1361,7 +1439,7 @@ static ResultCode ResetSignal(Handle handle) { | |||
| 1361 | LOG_DEBUG(Kernel_SVC, "called handle 0x{:08X}", handle); | 1439 | LOG_DEBUG(Kernel_SVC, "called handle 0x{:08X}", handle); |
| 1362 | 1440 | ||
| 1363 | const auto& handle_table = Core::CurrentProcess()->GetHandleTable(); | 1441 | const auto& handle_table = Core::CurrentProcess()->GetHandleTable(); |
| 1364 | auto event = handle_table.Get<Event>(handle); | 1442 | auto event = handle_table.Get<ReadableEvent>(handle); |
| 1365 | 1443 | ||
| 1366 | ASSERT(event != nullptr); | 1444 | ASSERT(event != nullptr); |
| 1367 | 1445 | ||
| @@ -1524,14 +1602,21 @@ static ResultCode ClearEvent(Handle handle) { | |||
| 1524 | LOG_TRACE(Kernel_SVC, "called, event=0x{:08X}", handle); | 1602 | LOG_TRACE(Kernel_SVC, "called, event=0x{:08X}", handle); |
| 1525 | 1603 | ||
| 1526 | const auto& handle_table = Core::CurrentProcess()->GetHandleTable(); | 1604 | const auto& handle_table = Core::CurrentProcess()->GetHandleTable(); |
| 1527 | SharedPtr<Event> evt = handle_table.Get<Event>(handle); | 1605 | |
| 1528 | if (evt == nullptr) { | 1606 | auto writable_event = handle_table.Get<WritableEvent>(handle); |
| 1529 | LOG_ERROR(Kernel_SVC, "Event handle does not exist, handle=0x{:08X}", handle); | 1607 | if (writable_event) { |
| 1530 | return ERR_INVALID_HANDLE; | 1608 | writable_event->Clear(); |
| 1609 | return RESULT_SUCCESS; | ||
| 1531 | } | 1610 | } |
| 1532 | 1611 | ||
| 1533 | evt->Clear(); | 1612 | auto readable_event = handle_table.Get<ReadableEvent>(handle); |
| 1534 | return RESULT_SUCCESS; | 1613 | if (readable_event) { |
| 1614 | readable_event->Clear(); | ||
| 1615 | return RESULT_SUCCESS; | ||
| 1616 | } | ||
| 1617 | |||
| 1618 | LOG_ERROR(Kernel_SVC, "Event handle does not exist, handle=0x{:08X}", handle); | ||
| 1619 | return ERR_INVALID_HANDLE; | ||
| 1535 | } | 1620 | } |
| 1536 | 1621 | ||
| 1537 | static ResultCode GetProcessInfo(u64* out, Handle process_handle, u32 type) { | 1622 | static ResultCode GetProcessInfo(u64* out, Handle process_handle, u32 type) { |
diff --git a/src/core/hle/kernel/writable_event.cpp b/src/core/hle/kernel/writable_event.cpp new file mode 100644 index 000000000..a58ea6ec8 --- /dev/null +++ b/src/core/hle/kernel/writable_event.cpp | |||
| @@ -0,0 +1,52 @@ | |||
| 1 | // Copyright 2014 Citra Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include <algorithm> | ||
| 6 | #include "common/assert.h" | ||
| 7 | #include "core/hle/kernel/kernel.h" | ||
| 8 | #include "core/hle/kernel/object.h" | ||
| 9 | #include "core/hle/kernel/readable_event.h" | ||
| 10 | #include "core/hle/kernel/thread.h" | ||
| 11 | #include "core/hle/kernel/writable_event.h" | ||
| 12 | |||
| 13 | namespace Kernel { | ||
| 14 | |||
| 15 | WritableEvent::WritableEvent(KernelCore& kernel) : Object{kernel} {} | ||
| 16 | WritableEvent::~WritableEvent() = default; | ||
| 17 | |||
| 18 | EventPair WritableEvent::CreateEventPair(KernelCore& kernel, ResetType reset_type, | ||
| 19 | std::string name) { | ||
| 20 | SharedPtr<WritableEvent> writable_event(new WritableEvent(kernel)); | ||
| 21 | SharedPtr<ReadableEvent> readable_event(new ReadableEvent(kernel)); | ||
| 22 | |||
| 23 | writable_event->name = name + ":Writable"; | ||
| 24 | writable_event->readable = readable_event; | ||
| 25 | readable_event->name = name + ":Readable"; | ||
| 26 | readable_event->signaled = false; | ||
| 27 | readable_event->reset_type = reset_type; | ||
| 28 | |||
| 29 | return {std::move(readable_event), std::move(writable_event)}; | ||
| 30 | } | ||
| 31 | |||
| 32 | SharedPtr<ReadableEvent> WritableEvent::GetReadableEvent() const { | ||
| 33 | return readable; | ||
| 34 | } | ||
| 35 | |||
| 36 | ResetType WritableEvent::GetResetType() const { | ||
| 37 | return readable->reset_type; | ||
| 38 | } | ||
| 39 | |||
| 40 | void WritableEvent::Signal() { | ||
| 41 | readable->Signal(); | ||
| 42 | } | ||
| 43 | |||
| 44 | void WritableEvent::Clear() { | ||
| 45 | readable->Clear(); | ||
| 46 | } | ||
| 47 | |||
| 48 | bool WritableEvent::IsSignaled() const { | ||
| 49 | return readable->signaled; | ||
| 50 | } | ||
| 51 | |||
| 52 | } // namespace Kernel | ||
diff --git a/src/core/hle/kernel/event.h b/src/core/hle/kernel/writable_event.h index 27d6126b0..8fa8d68ee 100644 --- a/src/core/hle/kernel/event.h +++ b/src/core/hle/kernel/writable_event.h | |||
| @@ -11,49 +11,52 @@ | |||
| 11 | namespace Kernel { | 11 | namespace Kernel { |
| 12 | 12 | ||
| 13 | class KernelCore; | 13 | class KernelCore; |
| 14 | class ReadableEvent; | ||
| 15 | class WritableEvent; | ||
| 14 | 16 | ||
| 15 | class Event final : public WaitObject { | 17 | struct EventPair { |
| 18 | SharedPtr<ReadableEvent> readable; | ||
| 19 | SharedPtr<WritableEvent> writable; | ||
| 20 | }; | ||
| 21 | |||
| 22 | class WritableEvent final : public Object { | ||
| 16 | public: | 23 | public: |
| 24 | ~WritableEvent() override; | ||
| 25 | |||
| 17 | /** | 26 | /** |
| 18 | * Creates an event | 27 | * Creates an event |
| 19 | * @param kernel The kernel instance to create this event under. | 28 | * @param kernel The kernel instance to create this event under. |
| 20 | * @param reset_type ResetType describing how to create event | 29 | * @param reset_type ResetType describing how to create event |
| 21 | * @param name Optional name of event | 30 | * @param name Optional name of event |
| 22 | */ | 31 | */ |
| 23 | static SharedPtr<Event> Create(KernelCore& kernel, ResetType reset_type, | 32 | static EventPair CreateEventPair(KernelCore& kernel, ResetType reset_type, |
| 24 | std::string name = "Unknown"); | 33 | std::string name = "Unknown"); |
| 25 | 34 | ||
| 26 | std::string GetTypeName() const override { | 35 | std::string GetTypeName() const override { |
| 27 | return "Event"; | 36 | return "WritableEvent"; |
| 28 | } | 37 | } |
| 29 | std::string GetName() const override { | 38 | std::string GetName() const override { |
| 30 | return name; | 39 | return name; |
| 31 | } | 40 | } |
| 32 | 41 | ||
| 33 | static const HandleType HANDLE_TYPE = HandleType::Event; | 42 | static const HandleType HANDLE_TYPE = HandleType::WritableEvent; |
| 34 | HandleType GetHandleType() const override { | 43 | HandleType GetHandleType() const override { |
| 35 | return HANDLE_TYPE; | 44 | return HANDLE_TYPE; |
| 36 | } | 45 | } |
| 37 | 46 | ||
| 38 | ResetType GetResetType() const { | 47 | SharedPtr<ReadableEvent> GetReadableEvent() const; |
| 39 | return reset_type; | ||
| 40 | } | ||
| 41 | |||
| 42 | bool ShouldWait(Thread* thread) const override; | ||
| 43 | void Acquire(Thread* thread) override; | ||
| 44 | 48 | ||
| 45 | void WakeupAllWaitingThreads() override; | 49 | ResetType GetResetType() const; |
| 46 | 50 | ||
| 47 | void Signal(); | 51 | void Signal(); |
| 48 | void Clear(); | 52 | void Clear(); |
| 53 | bool IsSignaled() const; | ||
| 49 | 54 | ||
| 50 | private: | 55 | private: |
| 51 | explicit Event(KernelCore& kernel); | 56 | explicit WritableEvent(KernelCore& kernel); |
| 52 | ~Event() override; | ||
| 53 | 57 | ||
| 54 | ResetType reset_type; ///< Current ResetType | 58 | SharedPtr<ReadableEvent> readable; |
| 55 | 59 | ||
| 56 | bool signaled; ///< Whether the event has already been signaled | ||
| 57 | std::string name; ///< Name of event (optional) | 60 | std::string name; ///< Name of event (optional) |
| 58 | }; | 61 | }; |
| 59 | 62 | ||
diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp index d595c37b0..3a7b6da84 100644 --- a/src/core/hle/service/am/am.cpp +++ b/src/core/hle/service/am/am.cpp | |||
| @@ -9,9 +9,11 @@ | |||
| 9 | #include "audio_core/audio_renderer.h" | 9 | #include "audio_core/audio_renderer.h" |
| 10 | #include "core/core.h" | 10 | #include "core/core.h" |
| 11 | #include "core/hle/ipc_helpers.h" | 11 | #include "core/hle/ipc_helpers.h" |
| 12 | #include "core/hle/kernel/event.h" | 12 | #include "core/hle/kernel/kernel.h" |
| 13 | #include "core/hle/kernel/process.h" | 13 | #include "core/hle/kernel/process.h" |
| 14 | #include "core/hle/kernel/readable_event.h" | ||
| 14 | #include "core/hle/kernel/shared_memory.h" | 15 | #include "core/hle/kernel/shared_memory.h" |
| 16 | #include "core/hle/kernel/writable_event.h" | ||
| 15 | #include "core/hle/service/acc/profile_manager.h" | 17 | #include "core/hle/service/acc/profile_manager.h" |
| 16 | #include "core/hle/service/am/am.h" | 18 | #include "core/hle/service/am/am.h" |
| 17 | #include "core/hle/service/am/applet_ae.h" | 19 | #include "core/hle/service/am/applet_ae.h" |
| @@ -208,8 +210,8 @@ ISelfController::ISelfController(std::shared_ptr<NVFlinger::NVFlinger> nvflinger | |||
| 208 | RegisterHandlers(functions); | 210 | RegisterHandlers(functions); |
| 209 | 211 | ||
| 210 | auto& kernel = Core::System::GetInstance().Kernel(); | 212 | auto& kernel = Core::System::GetInstance().Kernel(); |
| 211 | launchable_event = | 213 | launchable_event = Kernel::WritableEvent::CreateEventPair(kernel, Kernel::ResetType::Sticky, |
| 212 | Kernel::Event::Create(kernel, Kernel::ResetType::Sticky, "ISelfController:LaunchableEvent"); | 214 | "ISelfController:LaunchableEvent"); |
| 213 | } | 215 | } |
| 214 | 216 | ||
| 215 | ISelfController::~ISelfController() = default; | 217 | ISelfController::~ISelfController() = default; |
| @@ -295,11 +297,11 @@ void ISelfController::UnlockExit(Kernel::HLERequestContext& ctx) { | |||
| 295 | void ISelfController::GetLibraryAppletLaunchableEvent(Kernel::HLERequestContext& ctx) { | 297 | void ISelfController::GetLibraryAppletLaunchableEvent(Kernel::HLERequestContext& ctx) { |
| 296 | LOG_WARNING(Service_AM, "(STUBBED) called"); | 298 | LOG_WARNING(Service_AM, "(STUBBED) called"); |
| 297 | 299 | ||
| 298 | launchable_event->Signal(); | 300 | launchable_event.writable->Signal(); |
| 299 | 301 | ||
| 300 | IPC::ResponseBuilder rb{ctx, 2, 1}; | 302 | IPC::ResponseBuilder rb{ctx, 2, 1}; |
| 301 | rb.Push(RESULT_SUCCESS); | 303 | rb.Push(RESULT_SUCCESS); |
| 302 | rb.PushCopyObjects(launchable_event); | 304 | rb.PushCopyObjects(launchable_event.readable); |
| 303 | } | 305 | } |
| 304 | 306 | ||
| 305 | void ISelfController::SetScreenShotImageOrientation(Kernel::HLERequestContext& ctx) { | 307 | void ISelfController::SetScreenShotImageOrientation(Kernel::HLERequestContext& ctx) { |
| @@ -348,36 +350,38 @@ void ISelfController::GetIdleTimeDetectionExtension(Kernel::HLERequestContext& c | |||
| 348 | 350 | ||
| 349 | AppletMessageQueue::AppletMessageQueue() { | 351 | AppletMessageQueue::AppletMessageQueue() { |
| 350 | auto& kernel = Core::System::GetInstance().Kernel(); | 352 | auto& kernel = Core::System::GetInstance().Kernel(); |
| 351 | on_new_message = Kernel::Event::Create(kernel, Kernel::ResetType::Sticky, | 353 | on_new_message = Kernel::WritableEvent::CreateEventPair(kernel, Kernel::ResetType::Sticky, |
| 352 | "AMMessageQueue:OnMessageRecieved"); | 354 | "AMMessageQueue:OnMessageRecieved"); |
| 353 | on_operation_mode_changed = Kernel::Event::Create(kernel, Kernel::ResetType::OneShot, | 355 | on_operation_mode_changed = Kernel::WritableEvent::CreateEventPair( |
| 354 | "AMMessageQueue:OperationModeChanged"); | 356 | kernel, Kernel::ResetType::OneShot, "AMMessageQueue:OperationModeChanged"); |
| 355 | } | 357 | } |
| 356 | 358 | ||
| 357 | AppletMessageQueue::~AppletMessageQueue() = default; | 359 | AppletMessageQueue::~AppletMessageQueue() = default; |
| 358 | 360 | ||
| 359 | const Kernel::SharedPtr<Kernel::Event>& AppletMessageQueue::GetMesssageRecieveEvent() const { | 361 | const Kernel::SharedPtr<Kernel::ReadableEvent>& AppletMessageQueue::GetMesssageRecieveEvent() |
| 360 | return on_new_message; | 362 | const { |
| 363 | return on_new_message.readable; | ||
| 361 | } | 364 | } |
| 362 | 365 | ||
| 363 | const Kernel::SharedPtr<Kernel::Event>& AppletMessageQueue::GetOperationModeChangedEvent() const { | 366 | const Kernel::SharedPtr<Kernel::ReadableEvent>& AppletMessageQueue::GetOperationModeChangedEvent() |
| 364 | return on_operation_mode_changed; | 367 | const { |
| 368 | return on_operation_mode_changed.readable; | ||
| 365 | } | 369 | } |
| 366 | 370 | ||
| 367 | void AppletMessageQueue::PushMessage(AppletMessage msg) { | 371 | void AppletMessageQueue::PushMessage(AppletMessage msg) { |
| 368 | messages.push(msg); | 372 | messages.push(msg); |
| 369 | on_new_message->Signal(); | 373 | on_new_message.writable->Signal(); |
| 370 | } | 374 | } |
| 371 | 375 | ||
| 372 | AppletMessageQueue::AppletMessage AppletMessageQueue::PopMessage() { | 376 | AppletMessageQueue::AppletMessage AppletMessageQueue::PopMessage() { |
| 373 | if (messages.empty()) { | 377 | if (messages.empty()) { |
| 374 | on_new_message->Clear(); | 378 | on_new_message.writable->Clear(); |
| 375 | return AppletMessage::NoMessage; | 379 | return AppletMessage::NoMessage; |
| 376 | } | 380 | } |
| 377 | auto msg = messages.front(); | 381 | auto msg = messages.front(); |
| 378 | messages.pop(); | 382 | messages.pop(); |
| 379 | if (messages.empty()) { | 383 | if (messages.empty()) { |
| 380 | on_new_message->Clear(); | 384 | on_new_message.writable->Clear(); |
| 381 | } | 385 | } |
| 382 | return msg; | 386 | return msg; |
| 383 | } | 387 | } |
| @@ -389,7 +393,7 @@ std::size_t AppletMessageQueue::GetMessageCount() const { | |||
| 389 | void AppletMessageQueue::OperationModeChanged() { | 393 | void AppletMessageQueue::OperationModeChanged() { |
| 390 | PushMessage(AppletMessage::OperationModeChanged); | 394 | PushMessage(AppletMessage::OperationModeChanged); |
| 391 | PushMessage(AppletMessage::PerformanceModeChanged); | 395 | PushMessage(AppletMessage::PerformanceModeChanged); |
| 392 | on_operation_mode_changed->Signal(); | 396 | on_operation_mode_changed.writable->Signal(); |
| 393 | } | 397 | } |
| 394 | 398 | ||
| 395 | ICommonStateGetter::ICommonStateGetter(std::shared_ptr<AppletMessageQueue> msg_queue) | 399 | ICommonStateGetter::ICommonStateGetter(std::shared_ptr<AppletMessageQueue> msg_queue) |
| @@ -426,9 +430,6 @@ ICommonStateGetter::ICommonStateGetter(std::shared_ptr<AppletMessageQueue> msg_q | |||
| 426 | // clang-format on | 430 | // clang-format on |
| 427 | 431 | ||
| 428 | RegisterHandlers(functions); | 432 | RegisterHandlers(functions); |
| 429 | |||
| 430 | auto& kernel = Core::System::GetInstance().Kernel(); | ||
| 431 | event = Kernel::Event::Create(kernel, Kernel::ResetType::OneShot, "ICommonStateGetter:Event"); | ||
| 432 | } | 433 | } |
| 433 | 434 | ||
| 434 | ICommonStateGetter::~ICommonStateGetter() = default; | 435 | ICommonStateGetter::~ICommonStateGetter() = default; |
| @@ -564,8 +565,8 @@ private: | |||
| 564 | void GetAppletStateChangedEvent(Kernel::HLERequestContext& ctx) { | 565 | void GetAppletStateChangedEvent(Kernel::HLERequestContext& ctx) { |
| 565 | LOG_DEBUG(Service_AM, "called"); | 566 | LOG_DEBUG(Service_AM, "called"); |
| 566 | 567 | ||
| 568 | applet->GetBroker().SignalStateChanged(); | ||
| 567 | const auto event = applet->GetBroker().GetStateChangedEvent(); | 569 | const auto event = applet->GetBroker().GetStateChangedEvent(); |
| 568 | event->Signal(); | ||
| 569 | 570 | ||
| 570 | IPC::ResponseBuilder rb{ctx, 2, 1}; | 571 | IPC::ResponseBuilder rb{ctx, 2, 1}; |
| 571 | rb.Push(RESULT_SUCCESS); | 572 | rb.Push(RESULT_SUCCESS); |
diff --git a/src/core/hle/service/am/am.h b/src/core/hle/service/am/am.h index 44c1bcde5..34c45fadf 100644 --- a/src/core/hle/service/am/am.h +++ b/src/core/hle/service/am/am.h | |||
| @@ -6,12 +6,9 @@ | |||
| 6 | 6 | ||
| 7 | #include <memory> | 7 | #include <memory> |
| 8 | #include <queue> | 8 | #include <queue> |
| 9 | #include "core/hle/kernel/writable_event.h" | ||
| 9 | #include "core/hle/service/service.h" | 10 | #include "core/hle/service/service.h" |
| 10 | 11 | ||
| 11 | namespace Kernel { | ||
| 12 | class Event; | ||
| 13 | } | ||
| 14 | |||
| 15 | namespace Service { | 12 | namespace Service { |
| 16 | namespace NVFlinger { | 13 | namespace NVFlinger { |
| 17 | class NVFlinger; | 14 | class NVFlinger; |
| @@ -52,8 +49,8 @@ public: | |||
| 52 | AppletMessageQueue(); | 49 | AppletMessageQueue(); |
| 53 | ~AppletMessageQueue(); | 50 | ~AppletMessageQueue(); |
| 54 | 51 | ||
| 55 | const Kernel::SharedPtr<Kernel::Event>& GetMesssageRecieveEvent() const; | 52 | const Kernel::SharedPtr<Kernel::ReadableEvent>& GetMesssageRecieveEvent() const; |
| 56 | const Kernel::SharedPtr<Kernel::Event>& GetOperationModeChangedEvent() const; | 53 | const Kernel::SharedPtr<Kernel::ReadableEvent>& GetOperationModeChangedEvent() const; |
| 57 | void PushMessage(AppletMessage msg); | 54 | void PushMessage(AppletMessage msg); |
| 58 | AppletMessage PopMessage(); | 55 | AppletMessage PopMessage(); |
| 59 | std::size_t GetMessageCount() const; | 56 | std::size_t GetMessageCount() const; |
| @@ -61,8 +58,8 @@ public: | |||
| 61 | 58 | ||
| 62 | private: | 59 | private: |
| 63 | std::queue<AppletMessage> messages; | 60 | std::queue<AppletMessage> messages; |
| 64 | Kernel::SharedPtr<Kernel::Event> on_new_message; | 61 | Kernel::EventPair on_new_message; |
| 65 | Kernel::SharedPtr<Kernel::Event> on_operation_mode_changed; | 62 | Kernel::EventPair on_operation_mode_changed; |
| 66 | }; | 63 | }; |
| 67 | 64 | ||
| 68 | class IWindowController final : public ServiceFramework<IWindowController> { | 65 | class IWindowController final : public ServiceFramework<IWindowController> { |
| @@ -122,7 +119,7 @@ private: | |||
| 122 | void GetIdleTimeDetectionExtension(Kernel::HLERequestContext& ctx); | 119 | void GetIdleTimeDetectionExtension(Kernel::HLERequestContext& ctx); |
| 123 | 120 | ||
| 124 | std::shared_ptr<NVFlinger::NVFlinger> nvflinger; | 121 | std::shared_ptr<NVFlinger::NVFlinger> nvflinger; |
| 125 | Kernel::SharedPtr<Kernel::Event> launchable_event; | 122 | Kernel::EventPair launchable_event; |
| 126 | u32 idle_time_detection_extension = 0; | 123 | u32 idle_time_detection_extension = 0; |
| 127 | }; | 124 | }; |
| 128 | 125 | ||
| @@ -151,7 +148,6 @@ private: | |||
| 151 | void GetBootMode(Kernel::HLERequestContext& ctx); | 148 | void GetBootMode(Kernel::HLERequestContext& ctx); |
| 152 | void GetDefaultDisplayResolution(Kernel::HLERequestContext& ctx); | 149 | void GetDefaultDisplayResolution(Kernel::HLERequestContext& ctx); |
| 153 | 150 | ||
| 154 | Kernel::SharedPtr<Kernel::Event> event; | ||
| 155 | std::shared_ptr<AppletMessageQueue> msg_queue; | 151 | std::shared_ptr<AppletMessageQueue> msg_queue; |
| 156 | }; | 152 | }; |
| 157 | 153 | ||
diff --git a/src/core/hle/service/am/applets/applets.cpp b/src/core/hle/service/am/applets/applets.cpp index becbadd06..47da35537 100644 --- a/src/core/hle/service/am/applets/applets.cpp +++ b/src/core/hle/service/am/applets/applets.cpp | |||
| @@ -5,8 +5,9 @@ | |||
| 5 | #include <cstring> | 5 | #include <cstring> |
| 6 | #include "common/assert.h" | 6 | #include "common/assert.h" |
| 7 | #include "core/core.h" | 7 | #include "core/core.h" |
| 8 | #include "core/hle/kernel/event.h" | 8 | #include "core/hle/kernel/readable_event.h" |
| 9 | #include "core/hle/kernel/server_port.h" | 9 | #include "core/hle/kernel/server_port.h" |
| 10 | #include "core/hle/kernel/writable_event.h" | ||
| 10 | #include "core/hle/service/am/am.h" | 11 | #include "core/hle/service/am/am.h" |
| 11 | #include "core/hle/service/am/applets/applets.h" | 12 | #include "core/hle/service/am/applets/applets.h" |
| 12 | 13 | ||
| @@ -14,11 +15,11 @@ namespace Service::AM::Applets { | |||
| 14 | 15 | ||
| 15 | AppletDataBroker::AppletDataBroker() { | 16 | AppletDataBroker::AppletDataBroker() { |
| 16 | auto& kernel = Core::System::GetInstance().Kernel(); | 17 | auto& kernel = Core::System::GetInstance().Kernel(); |
| 17 | state_changed_event = Kernel::Event::Create(kernel, Kernel::ResetType::OneShot, | 18 | state_changed_event = Kernel::WritableEvent::CreateEventPair( |
| 18 | "ILibraryAppletAccessor:StateChangedEvent"); | 19 | kernel, Kernel::ResetType::OneShot, "ILibraryAppletAccessor:StateChangedEvent"); |
| 19 | pop_out_data_event = Kernel::Event::Create(kernel, Kernel::ResetType::OneShot, | 20 | pop_out_data_event = Kernel::WritableEvent::CreateEventPair( |
| 20 | "ILibraryAppletAccessor:PopDataOutEvent"); | 21 | kernel, Kernel::ResetType::OneShot, "ILibraryAppletAccessor:PopDataOutEvent"); |
| 21 | pop_interactive_out_data_event = Kernel::Event::Create( | 22 | pop_interactive_out_data_event = Kernel::WritableEvent::CreateEventPair( |
| 22 | kernel, Kernel::ResetType::OneShot, "ILibraryAppletAccessor:PopInteractiveDataOutEvent"); | 23 | kernel, Kernel::ResetType::OneShot, "ILibraryAppletAccessor:PopInteractiveDataOutEvent"); |
| 23 | } | 24 | } |
| 24 | 25 | ||
| @@ -66,7 +67,7 @@ void AppletDataBroker::PushNormalDataFromGame(IStorage storage) { | |||
| 66 | 67 | ||
| 67 | void AppletDataBroker::PushNormalDataFromApplet(IStorage storage) { | 68 | void AppletDataBroker::PushNormalDataFromApplet(IStorage storage) { |
| 68 | out_channel.push(std::make_unique<IStorage>(storage)); | 69 | out_channel.push(std::make_unique<IStorage>(storage)); |
| 69 | pop_out_data_event->Signal(); | 70 | pop_out_data_event.writable->Signal(); |
| 70 | } | 71 | } |
| 71 | 72 | ||
| 72 | void AppletDataBroker::PushInteractiveDataFromGame(IStorage storage) { | 73 | void AppletDataBroker::PushInteractiveDataFromGame(IStorage storage) { |
| @@ -75,23 +76,23 @@ void AppletDataBroker::PushInteractiveDataFromGame(IStorage storage) { | |||
| 75 | 76 | ||
| 76 | void AppletDataBroker::PushInteractiveDataFromApplet(IStorage storage) { | 77 | void AppletDataBroker::PushInteractiveDataFromApplet(IStorage storage) { |
| 77 | out_interactive_channel.push(std::make_unique<IStorage>(storage)); | 78 | out_interactive_channel.push(std::make_unique<IStorage>(storage)); |
| 78 | pop_interactive_out_data_event->Signal(); | 79 | pop_interactive_out_data_event.writable->Signal(); |
| 79 | } | 80 | } |
| 80 | 81 | ||
| 81 | void AppletDataBroker::SignalStateChanged() const { | 82 | void AppletDataBroker::SignalStateChanged() const { |
| 82 | state_changed_event->Signal(); | 83 | state_changed_event.writable->Signal(); |
| 83 | } | 84 | } |
| 84 | 85 | ||
| 85 | Kernel::SharedPtr<Kernel::Event> AppletDataBroker::GetNormalDataEvent() const { | 86 | Kernel::SharedPtr<Kernel::ReadableEvent> AppletDataBroker::GetNormalDataEvent() const { |
| 86 | return pop_out_data_event; | 87 | return pop_out_data_event.readable; |
| 87 | } | 88 | } |
| 88 | 89 | ||
| 89 | Kernel::SharedPtr<Kernel::Event> AppletDataBroker::GetInteractiveDataEvent() const { | 90 | Kernel::SharedPtr<Kernel::ReadableEvent> AppletDataBroker::GetInteractiveDataEvent() const { |
| 90 | return pop_interactive_out_data_event; | 91 | return pop_interactive_out_data_event.readable; |
| 91 | } | 92 | } |
| 92 | 93 | ||
| 93 | Kernel::SharedPtr<Kernel::Event> AppletDataBroker::GetStateChangedEvent() const { | 94 | Kernel::SharedPtr<Kernel::ReadableEvent> AppletDataBroker::GetStateChangedEvent() const { |
| 94 | return state_changed_event; | 95 | return state_changed_event.readable; |
| 95 | } | 96 | } |
| 96 | 97 | ||
| 97 | Applet::Applet() = default; | 98 | Applet::Applet() = default; |
diff --git a/src/core/hle/service/am/applets/applets.h b/src/core/hle/service/am/applets/applets.h index f65ea119c..b0a8913c3 100644 --- a/src/core/hle/service/am/applets/applets.h +++ b/src/core/hle/service/am/applets/applets.h | |||
| @@ -8,13 +8,10 @@ | |||
| 8 | #include <queue> | 8 | #include <queue> |
| 9 | #include "common/swap.h" | 9 | #include "common/swap.h" |
| 10 | #include "core/hle/kernel/kernel.h" | 10 | #include "core/hle/kernel/kernel.h" |
| 11 | #include "core/hle/kernel/writable_event.h" | ||
| 11 | 12 | ||
| 12 | union ResultCode; | 13 | union ResultCode; |
| 13 | 14 | ||
| 14 | namespace Kernel { | ||
| 15 | class Event; | ||
| 16 | } | ||
| 17 | |||
| 18 | namespace Service::AM { | 15 | namespace Service::AM { |
| 19 | 16 | ||
| 20 | class IStorage; | 17 | class IStorage; |
| @@ -40,9 +37,9 @@ public: | |||
| 40 | 37 | ||
| 41 | void SignalStateChanged() const; | 38 | void SignalStateChanged() const; |
| 42 | 39 | ||
| 43 | Kernel::SharedPtr<Kernel::Event> GetNormalDataEvent() const; | 40 | Kernel::SharedPtr<Kernel::ReadableEvent> GetNormalDataEvent() const; |
| 44 | Kernel::SharedPtr<Kernel::Event> GetInteractiveDataEvent() const; | 41 | Kernel::SharedPtr<Kernel::ReadableEvent> GetInteractiveDataEvent() const; |
| 45 | Kernel::SharedPtr<Kernel::Event> GetStateChangedEvent() const; | 42 | Kernel::SharedPtr<Kernel::ReadableEvent> GetStateChangedEvent() const; |
| 46 | 43 | ||
| 47 | private: | 44 | private: |
| 48 | // Queues are named from applet's perspective | 45 | // Queues are named from applet's perspective |
| @@ -59,13 +56,13 @@ private: | |||
| 59 | // PopInteractiveDataToGame and PushInteractiveDataFromApplet | 56 | // PopInteractiveDataToGame and PushInteractiveDataFromApplet |
| 60 | std::queue<std::unique_ptr<IStorage>> out_interactive_channel; | 57 | std::queue<std::unique_ptr<IStorage>> out_interactive_channel; |
| 61 | 58 | ||
| 62 | Kernel::SharedPtr<Kernel::Event> state_changed_event; | 59 | Kernel::EventPair state_changed_event; |
| 63 | 60 | ||
| 64 | // Signaled on PushNormalDataFromApplet | 61 | // Signaled on PushNormalDataFromApplet |
| 65 | Kernel::SharedPtr<Kernel::Event> pop_out_data_event; | 62 | Kernel::EventPair pop_out_data_event; |
| 66 | 63 | ||
| 67 | // Signaled on PushInteractiveDataFromApplet | 64 | // Signaled on PushInteractiveDataFromApplet |
| 68 | Kernel::SharedPtr<Kernel::Event> pop_interactive_out_data_event; | 65 | Kernel::EventPair pop_interactive_out_data_event; |
| 69 | }; | 66 | }; |
| 70 | 67 | ||
| 71 | class Applet { | 68 | class Applet { |
diff --git a/src/core/hle/service/aoc/aoc_u.cpp b/src/core/hle/service/aoc/aoc_u.cpp index bacf19de2..0417fdb92 100644 --- a/src/core/hle/service/aoc/aoc_u.cpp +++ b/src/core/hle/service/aoc/aoc_u.cpp | |||
| @@ -13,8 +13,10 @@ | |||
| 13 | #include "core/file_sys/patch_manager.h" | 13 | #include "core/file_sys/patch_manager.h" |
| 14 | #include "core/file_sys/registered_cache.h" | 14 | #include "core/file_sys/registered_cache.h" |
| 15 | #include "core/hle/ipc_helpers.h" | 15 | #include "core/hle/ipc_helpers.h" |
| 16 | #include "core/hle/kernel/event.h" | 16 | #include "core/hle/kernel/kernel.h" |
| 17 | #include "core/hle/kernel/process.h" | 17 | #include "core/hle/kernel/process.h" |
| 18 | #include "core/hle/kernel/readable_event.h" | ||
| 19 | #include "core/hle/kernel/writable_event.h" | ||
| 18 | #include "core/hle/service/aoc/aoc_u.h" | 20 | #include "core/hle/service/aoc/aoc_u.h" |
| 19 | #include "core/hle/service/filesystem/filesystem.h" | 21 | #include "core/hle/service/filesystem/filesystem.h" |
| 20 | #include "core/loader/loader.h" | 22 | #include "core/loader/loader.h" |
| @@ -32,14 +34,14 @@ static std::vector<u64> AccumulateAOCTitleIDs() { | |||
| 32 | std::vector<u64> add_on_content; | 34 | std::vector<u64> add_on_content; |
| 33 | const auto rcu = FileSystem::GetUnionContents(); | 35 | const auto rcu = FileSystem::GetUnionContents(); |
| 34 | const auto list = | 36 | const auto list = |
| 35 | rcu->ListEntriesFilter(FileSys::TitleType::AOC, FileSys::ContentRecordType::Data); | 37 | rcu.ListEntriesFilter(FileSys::TitleType::AOC, FileSys::ContentRecordType::Data); |
| 36 | std::transform(list.begin(), list.end(), std::back_inserter(add_on_content), | 38 | std::transform(list.begin(), list.end(), std::back_inserter(add_on_content), |
| 37 | [](const FileSys::RegisteredCacheEntry& rce) { return rce.title_id; }); | 39 | [](const FileSys::RegisteredCacheEntry& rce) { return rce.title_id; }); |
| 38 | add_on_content.erase( | 40 | add_on_content.erase( |
| 39 | std::remove_if( | 41 | std::remove_if( |
| 40 | add_on_content.begin(), add_on_content.end(), | 42 | add_on_content.begin(), add_on_content.end(), |
| 41 | [&rcu](u64 tid) { | 43 | [&rcu](u64 tid) { |
| 42 | return rcu->GetEntry(tid, FileSys::ContentRecordType::Data)->GetStatus() != | 44 | return rcu.GetEntry(tid, FileSys::ContentRecordType::Data)->GetStatus() != |
| 43 | Loader::ResultStatus::Success; | 45 | Loader::ResultStatus::Success; |
| 44 | }), | 46 | }), |
| 45 | add_on_content.end()); | 47 | add_on_content.end()); |
| @@ -61,8 +63,8 @@ AOC_U::AOC_U() : ServiceFramework("aoc:u"), add_on_content(AccumulateAOCTitleIDs | |||
| 61 | RegisterHandlers(functions); | 63 | RegisterHandlers(functions); |
| 62 | 64 | ||
| 63 | auto& kernel = Core::System::GetInstance().Kernel(); | 65 | auto& kernel = Core::System::GetInstance().Kernel(); |
| 64 | aoc_change_event = Kernel::Event::Create(kernel, Kernel::ResetType::Sticky, | 66 | aoc_change_event = Kernel::WritableEvent::CreateEventPair(kernel, Kernel::ResetType::Sticky, |
| 65 | "GetAddOnContentListChanged:Event"); | 67 | "GetAddOnContentListChanged:Event"); |
| 66 | } | 68 | } |
| 67 | 69 | ||
| 68 | AOC_U::~AOC_U() = default; | 70 | AOC_U::~AOC_U() = default; |
| @@ -144,7 +146,7 @@ void AOC_U::GetAddOnContentListChangedEvent(Kernel::HLERequestContext& ctx) { | |||
| 144 | 146 | ||
| 145 | IPC::ResponseBuilder rb{ctx, 2, 1}; | 147 | IPC::ResponseBuilder rb{ctx, 2, 1}; |
| 146 | rb.Push(RESULT_SUCCESS); | 148 | rb.Push(RESULT_SUCCESS); |
| 147 | rb.PushCopyObjects(aoc_change_event); | 149 | rb.PushCopyObjects(aoc_change_event.readable); |
| 148 | } | 150 | } |
| 149 | 151 | ||
| 150 | void InstallInterfaces(SM::ServiceManager& service_manager) { | 152 | void InstallInterfaces(SM::ServiceManager& service_manager) { |
diff --git a/src/core/hle/service/aoc/aoc_u.h b/src/core/hle/service/aoc/aoc_u.h index 68d94fdaa..5effea730 100644 --- a/src/core/hle/service/aoc/aoc_u.h +++ b/src/core/hle/service/aoc/aoc_u.h | |||
| @@ -6,6 +6,10 @@ | |||
| 6 | 6 | ||
| 7 | #include "core/hle/service/service.h" | 7 | #include "core/hle/service/service.h" |
| 8 | 8 | ||
| 9 | namespace Kernel { | ||
| 10 | class WritableEvent; | ||
| 11 | } | ||
| 12 | |||
| 9 | namespace Service::AOC { | 13 | namespace Service::AOC { |
| 10 | 14 | ||
| 11 | class AOC_U final : public ServiceFramework<AOC_U> { | 15 | class AOC_U final : public ServiceFramework<AOC_U> { |
| @@ -21,7 +25,7 @@ private: | |||
| 21 | void GetAddOnContentListChangedEvent(Kernel::HLERequestContext& ctx); | 25 | void GetAddOnContentListChangedEvent(Kernel::HLERequestContext& ctx); |
| 22 | 26 | ||
| 23 | std::vector<u64> add_on_content; | 27 | std::vector<u64> add_on_content; |
| 24 | Kernel::SharedPtr<Kernel::Event> aoc_change_event; | 28 | Kernel::EventPair aoc_change_event; |
| 25 | }; | 29 | }; |
| 26 | 30 | ||
| 27 | /// Registers all AOC services with the specified service manager. | 31 | /// Registers all AOC services with the specified service manager. |
diff --git a/src/core/hle/service/audio/audout_u.cpp b/src/core/hle/service/audio/audout_u.cpp index 2ee9bc273..dc6a6b188 100644 --- a/src/core/hle/service/audio/audout_u.cpp +++ b/src/core/hle/service/audio/audout_u.cpp | |||
| @@ -13,8 +13,10 @@ | |||
| 13 | #include "common/swap.h" | 13 | #include "common/swap.h" |
| 14 | #include "core/core.h" | 14 | #include "core/core.h" |
| 15 | #include "core/hle/ipc_helpers.h" | 15 | #include "core/hle/ipc_helpers.h" |
| 16 | #include "core/hle/kernel/event.h" | ||
| 17 | #include "core/hle/kernel/hle_ipc.h" | 16 | #include "core/hle/kernel/hle_ipc.h" |
| 17 | #include "core/hle/kernel/kernel.h" | ||
| 18 | #include "core/hle/kernel/readable_event.h" | ||
| 19 | #include "core/hle/kernel/writable_event.h" | ||
| 18 | #include "core/hle/service/audio/audout_u.h" | 20 | #include "core/hle/service/audio/audout_u.h" |
| 19 | #include "core/memory.h" | 21 | #include "core/memory.h" |
| 20 | 22 | ||
| @@ -46,8 +48,8 @@ class IAudioOut final : public ServiceFramework<IAudioOut> { | |||
| 46 | public: | 48 | public: |
| 47 | IAudioOut(AudoutParams audio_params, AudioCore::AudioOut& audio_core, std::string&& device_name, | 49 | IAudioOut(AudoutParams audio_params, AudioCore::AudioOut& audio_core, std::string&& device_name, |
| 48 | std::string&& unique_name) | 50 | std::string&& unique_name) |
| 49 | : ServiceFramework("IAudioOut"), audio_core(audio_core), audio_params(audio_params), | 51 | : ServiceFramework("IAudioOut"), audio_core(audio_core), |
| 50 | device_name(std::move(device_name)) { | 52 | device_name(std::move(device_name)), audio_params(audio_params) { |
| 51 | 53 | ||
| 52 | static const FunctionInfo functions[] = { | 54 | static const FunctionInfo functions[] = { |
| 53 | {0, &IAudioOut::GetAudioOutState, "GetAudioOutState"}, | 55 | {0, &IAudioOut::GetAudioOutState, "GetAudioOutState"}, |
| @@ -67,11 +69,12 @@ public: | |||
| 67 | 69 | ||
| 68 | // This is the event handle used to check if the audio buffer was released | 70 | // This is the event handle used to check if the audio buffer was released |
| 69 | auto& kernel = Core::System::GetInstance().Kernel(); | 71 | auto& kernel = Core::System::GetInstance().Kernel(); |
| 70 | buffer_event = | 72 | buffer_event = Kernel::WritableEvent::CreateEventPair(kernel, Kernel::ResetType::Sticky, |
| 71 | Kernel::Event::Create(kernel, Kernel::ResetType::Sticky, "IAudioOutBufferReleased"); | 73 | "IAudioOutBufferReleased"); |
| 72 | 74 | ||
| 73 | stream = audio_core.OpenStream(audio_params.sample_rate, audio_params.channel_count, | 75 | stream = audio_core.OpenStream(audio_params.sample_rate, audio_params.channel_count, |
| 74 | std::move(unique_name), [=]() { buffer_event->Signal(); }); | 76 | std::move(unique_name), |
| 77 | [=]() { buffer_event.writable->Signal(); }); | ||
| 75 | } | 78 | } |
| 76 | 79 | ||
| 77 | private: | 80 | private: |
| @@ -121,7 +124,7 @@ private: | |||
| 121 | 124 | ||
| 122 | IPC::ResponseBuilder rb{ctx, 2, 1}; | 125 | IPC::ResponseBuilder rb{ctx, 2, 1}; |
| 123 | rb.Push(RESULT_SUCCESS); | 126 | rb.Push(RESULT_SUCCESS); |
| 124 | rb.PushCopyObjects(buffer_event); | 127 | rb.PushCopyObjects(buffer_event.readable); |
| 125 | } | 128 | } |
| 126 | 129 | ||
| 127 | void AppendAudioOutBufferImpl(Kernel::HLERequestContext& ctx) { | 130 | void AppendAudioOutBufferImpl(Kernel::HLERequestContext& ctx) { |
| @@ -187,8 +190,8 @@ private: | |||
| 187 | 190 | ||
| 188 | AudoutParams audio_params{}; | 191 | AudoutParams audio_params{}; |
| 189 | 192 | ||
| 190 | /// This is the evend handle used to check if the audio buffer was released | 193 | /// This is the event handle used to check if the audio buffer was released |
| 191 | Kernel::SharedPtr<Kernel::Event> buffer_event; | 194 | Kernel::EventPair buffer_event; |
| 192 | }; | 195 | }; |
| 193 | 196 | ||
| 194 | void AudOutU::ListAudioOutsImpl(Kernel::HLERequestContext& ctx) { | 197 | void AudOutU::ListAudioOutsImpl(Kernel::HLERequestContext& ctx) { |
diff --git a/src/core/hle/service/audio/audren_u.cpp b/src/core/hle/service/audio/audren_u.cpp index 1c418a9bb..945259c7d 100644 --- a/src/core/hle/service/audio/audren_u.cpp +++ b/src/core/hle/service/audio/audren_u.cpp | |||
| @@ -12,8 +12,10 @@ | |||
| 12 | #include "common/logging/log.h" | 12 | #include "common/logging/log.h" |
| 13 | #include "core/core.h" | 13 | #include "core/core.h" |
| 14 | #include "core/hle/ipc_helpers.h" | 14 | #include "core/hle/ipc_helpers.h" |
| 15 | #include "core/hle/kernel/event.h" | ||
| 16 | #include "core/hle/kernel/hle_ipc.h" | 15 | #include "core/hle/kernel/hle_ipc.h" |
| 16 | #include "core/hle/kernel/kernel.h" | ||
| 17 | #include "core/hle/kernel/readable_event.h" | ||
| 18 | #include "core/hle/kernel/writable_event.h" | ||
| 17 | #include "core/hle/service/audio/audren_u.h" | 19 | #include "core/hle/service/audio/audren_u.h" |
| 18 | 20 | ||
| 19 | namespace Service::Audio { | 21 | namespace Service::Audio { |
| @@ -41,14 +43,14 @@ public: | |||
| 41 | RegisterHandlers(functions); | 43 | RegisterHandlers(functions); |
| 42 | 44 | ||
| 43 | auto& kernel = Core::System::GetInstance().Kernel(); | 45 | auto& kernel = Core::System::GetInstance().Kernel(); |
| 44 | system_event = | 46 | system_event = Kernel::WritableEvent::CreateEventPair(kernel, Kernel::ResetType::Sticky, |
| 45 | Kernel::Event::Create(kernel, Kernel::ResetType::Sticky, "IAudioRenderer:SystemEvent"); | 47 | "IAudioRenderer:SystemEvent"); |
| 46 | renderer = std::make_unique<AudioCore::AudioRenderer>(audren_params, system_event); | 48 | renderer = std::make_unique<AudioCore::AudioRenderer>(audren_params, system_event.writable); |
| 47 | } | 49 | } |
| 48 | 50 | ||
| 49 | private: | 51 | private: |
| 50 | void UpdateAudioCallback() { | 52 | void UpdateAudioCallback() { |
| 51 | system_event->Signal(); | 53 | system_event.writable->Signal(); |
| 52 | } | 54 | } |
| 53 | 55 | ||
| 54 | void GetSampleRate(Kernel::HLERequestContext& ctx) { | 56 | void GetSampleRate(Kernel::HLERequestContext& ctx) { |
| @@ -112,7 +114,7 @@ private: | |||
| 112 | 114 | ||
| 113 | IPC::ResponseBuilder rb{ctx, 2, 1}; | 115 | IPC::ResponseBuilder rb{ctx, 2, 1}; |
| 114 | rb.Push(RESULT_SUCCESS); | 116 | rb.Push(RESULT_SUCCESS); |
| 115 | rb.PushCopyObjects(system_event); | 117 | rb.PushCopyObjects(system_event.readable); |
| 116 | } | 118 | } |
| 117 | 119 | ||
| 118 | void SetRenderingTimeLimit(Kernel::HLERequestContext& ctx) { | 120 | void SetRenderingTimeLimit(Kernel::HLERequestContext& ctx) { |
| @@ -135,7 +137,7 @@ private: | |||
| 135 | rb.Push(rendering_time_limit_percent); | 137 | rb.Push(rendering_time_limit_percent); |
| 136 | } | 138 | } |
| 137 | 139 | ||
| 138 | Kernel::SharedPtr<Kernel::Event> system_event; | 140 | Kernel::EventPair system_event; |
| 139 | std::unique_ptr<AudioCore::AudioRenderer> renderer; | 141 | std::unique_ptr<AudioCore::AudioRenderer> renderer; |
| 140 | u32 rendering_time_limit_percent = 100; | 142 | u32 rendering_time_limit_percent = 100; |
| 141 | }; | 143 | }; |
| @@ -162,8 +164,8 @@ public: | |||
| 162 | RegisterHandlers(functions); | 164 | RegisterHandlers(functions); |
| 163 | 165 | ||
| 164 | auto& kernel = Core::System::GetInstance().Kernel(); | 166 | auto& kernel = Core::System::GetInstance().Kernel(); |
| 165 | buffer_event = Kernel::Event::Create(kernel, Kernel::ResetType::OneShot, | 167 | buffer_event = Kernel::WritableEvent::CreateEventPair(kernel, Kernel::ResetType::OneShot, |
| 166 | "IAudioOutBufferReleasedEvent"); | 168 | "IAudioOutBufferReleasedEvent"); |
| 167 | } | 169 | } |
| 168 | 170 | ||
| 169 | private: | 171 | private: |
| @@ -207,11 +209,11 @@ private: | |||
| 207 | void QueryAudioDeviceSystemEvent(Kernel::HLERequestContext& ctx) { | 209 | void QueryAudioDeviceSystemEvent(Kernel::HLERequestContext& ctx) { |
| 208 | LOG_WARNING(Service_Audio, "(STUBBED) called"); | 210 | LOG_WARNING(Service_Audio, "(STUBBED) called"); |
| 209 | 211 | ||
| 210 | buffer_event->Signal(); | 212 | buffer_event.writable->Signal(); |
| 211 | 213 | ||
| 212 | IPC::ResponseBuilder rb{ctx, 2, 1}; | 214 | IPC::ResponseBuilder rb{ctx, 2, 1}; |
| 213 | rb.Push(RESULT_SUCCESS); | 215 | rb.Push(RESULT_SUCCESS); |
| 214 | rb.PushCopyObjects(buffer_event); | 216 | rb.PushCopyObjects(buffer_event.readable); |
| 215 | } | 217 | } |
| 216 | 218 | ||
| 217 | void GetActiveChannelCount(Kernel::HLERequestContext& ctx) { | 219 | void GetActiveChannelCount(Kernel::HLERequestContext& ctx) { |
| @@ -222,7 +224,7 @@ private: | |||
| 222 | rb.Push<u32>(1); | 224 | rb.Push<u32>(1); |
| 223 | } | 225 | } |
| 224 | 226 | ||
| 225 | Kernel::SharedPtr<Kernel::Event> buffer_event; | 227 | Kernel::EventPair buffer_event; |
| 226 | 228 | ||
| 227 | }; // namespace Audio | 229 | }; // namespace Audio |
| 228 | 230 | ||
diff --git a/src/core/hle/service/btdrv/btdrv.cpp b/src/core/hle/service/btdrv/btdrv.cpp index 2eadcdd05..5704ca0ab 100644 --- a/src/core/hle/service/btdrv/btdrv.cpp +++ b/src/core/hle/service/btdrv/btdrv.cpp | |||
| @@ -4,8 +4,10 @@ | |||
| 4 | 4 | ||
| 5 | #include "common/logging/log.h" | 5 | #include "common/logging/log.h" |
| 6 | #include "core/hle/ipc_helpers.h" | 6 | #include "core/hle/ipc_helpers.h" |
| 7 | #include "core/hle/kernel/event.h" | ||
| 8 | #include "core/hle/kernel/hle_ipc.h" | 7 | #include "core/hle/kernel/hle_ipc.h" |
| 8 | #include "core/hle/kernel/kernel.h" | ||
| 9 | #include "core/hle/kernel/readable_event.h" | ||
| 10 | #include "core/hle/kernel/writable_event.h" | ||
| 9 | #include "core/hle/service/btdrv/btdrv.h" | 11 | #include "core/hle/service/btdrv/btdrv.h" |
| 10 | #include "core/hle/service/service.h" | 12 | #include "core/hle/service/service.h" |
| 11 | #include "core/hle/service/sm/sm.h" | 13 | #include "core/hle/service/sm/sm.h" |
| @@ -30,20 +32,22 @@ public: | |||
| 30 | }; | 32 | }; |
| 31 | // clang-format on | 33 | // clang-format on |
| 32 | RegisterHandlers(functions); | 34 | RegisterHandlers(functions); |
| 35 | |||
| 36 | auto& kernel = Core::System::GetInstance().Kernel(); | ||
| 37 | register_event = Kernel::WritableEvent::CreateEventPair(kernel, Kernel::ResetType::OneShot, | ||
| 38 | "BT:RegisterEvent"); | ||
| 33 | } | 39 | } |
| 34 | 40 | ||
| 35 | private: | 41 | private: |
| 36 | void RegisterEvent(Kernel::HLERequestContext& ctx) { | 42 | void RegisterEvent(Kernel::HLERequestContext& ctx) { |
| 37 | LOG_WARNING(Service_BTM, "(STUBBED) called"); | 43 | LOG_WARNING(Service_BTM, "(STUBBED) called"); |
| 38 | 44 | ||
| 39 | auto& kernel = Core::System::GetInstance().Kernel(); | ||
| 40 | register_event = | ||
| 41 | Kernel::Event::Create(kernel, Kernel::ResetType::OneShot, "BT:RegisterEvent"); | ||
| 42 | IPC::ResponseBuilder rb{ctx, 2, 1}; | 45 | IPC::ResponseBuilder rb{ctx, 2, 1}; |
| 43 | rb.Push(RESULT_SUCCESS); | 46 | rb.Push(RESULT_SUCCESS); |
| 44 | rb.PushCopyObjects(register_event); | 47 | rb.PushCopyObjects(register_event.readable); |
| 45 | } | 48 | } |
| 46 | Kernel::SharedPtr<Kernel::Event> register_event; | 49 | |
| 50 | Kernel::EventPair register_event; | ||
| 47 | }; | 51 | }; |
| 48 | 52 | ||
| 49 | class BtDrv final : public ServiceFramework<BtDrv> { | 53 | class BtDrv final : public ServiceFramework<BtDrv> { |
diff --git a/src/core/hle/service/btm/btm.cpp b/src/core/hle/service/btm/btm.cpp index 463a79351..ef7398a23 100644 --- a/src/core/hle/service/btm/btm.cpp +++ b/src/core/hle/service/btm/btm.cpp | |||
| @@ -6,8 +6,10 @@ | |||
| 6 | 6 | ||
| 7 | #include "common/logging/log.h" | 7 | #include "common/logging/log.h" |
| 8 | #include "core/hle/ipc_helpers.h" | 8 | #include "core/hle/ipc_helpers.h" |
| 9 | #include "core/hle/kernel/event.h" | ||
| 10 | #include "core/hle/kernel/hle_ipc.h" | 9 | #include "core/hle/kernel/hle_ipc.h" |
| 10 | #include "core/hle/kernel/kernel.h" | ||
| 11 | #include "core/hle/kernel/readable_event.h" | ||
| 12 | #include "core/hle/kernel/writable_event.h" | ||
| 11 | #include "core/hle/service/btm/btm.h" | 13 | #include "core/hle/service/btm/btm.h" |
| 12 | #include "core/hle/service/service.h" | 14 | #include "core/hle/service/service.h" |
| 13 | 15 | ||
| @@ -53,53 +55,55 @@ public: | |||
| 53 | }; | 55 | }; |
| 54 | // clang-format on | 56 | // clang-format on |
| 55 | RegisterHandlers(functions); | 57 | RegisterHandlers(functions); |
| 58 | |||
| 59 | auto& kernel = Core::System::GetInstance().Kernel(); | ||
| 60 | scan_event = Kernel::WritableEvent::CreateEventPair(kernel, Kernel::ResetType::OneShot, | ||
| 61 | "IBtmUserCore:ScanEvent"); | ||
| 62 | connection_event = Kernel::WritableEvent::CreateEventPair( | ||
| 63 | kernel, Kernel::ResetType::OneShot, "IBtmUserCore:ConnectionEvent"); | ||
| 64 | service_discovery = Kernel::WritableEvent::CreateEventPair( | ||
| 65 | kernel, Kernel::ResetType::OneShot, "IBtmUserCore:Discovery"); | ||
| 66 | config_event = Kernel::WritableEvent::CreateEventPair(kernel, Kernel::ResetType::OneShot, | ||
| 67 | "IBtmUserCore:ConfigEvent"); | ||
| 56 | } | 68 | } |
| 57 | 69 | ||
| 58 | private: | 70 | private: |
| 59 | void GetScanEvent(Kernel::HLERequestContext& ctx) { | 71 | void GetScanEvent(Kernel::HLERequestContext& ctx) { |
| 60 | LOG_WARNING(Service_BTM, "(STUBBED) called"); | 72 | LOG_WARNING(Service_BTM, "(STUBBED) called"); |
| 61 | 73 | ||
| 62 | auto& kernel = Core::System::GetInstance().Kernel(); | ||
| 63 | scan_event = | ||
| 64 | Kernel::Event::Create(kernel, Kernel::ResetType::OneShot, "IBtmUserCore:ScanEvent"); | ||
| 65 | IPC::ResponseBuilder rb{ctx, 2, 1}; | 74 | IPC::ResponseBuilder rb{ctx, 2, 1}; |
| 66 | rb.Push(RESULT_SUCCESS); | 75 | rb.Push(RESULT_SUCCESS); |
| 67 | rb.PushCopyObjects(scan_event); | 76 | rb.PushCopyObjects(scan_event.readable); |
| 68 | } | 77 | } |
| 78 | |||
| 69 | void GetConnectionEvent(Kernel::HLERequestContext& ctx) { | 79 | void GetConnectionEvent(Kernel::HLERequestContext& ctx) { |
| 70 | LOG_WARNING(Service_BTM, "(STUBBED) called"); | 80 | LOG_WARNING(Service_BTM, "(STUBBED) called"); |
| 71 | 81 | ||
| 72 | auto& kernel = Core::System::GetInstance().Kernel(); | ||
| 73 | connection_event = Kernel::Event::Create(kernel, Kernel::ResetType::OneShot, | ||
| 74 | "IBtmUserCore:ConnectionEvent"); | ||
| 75 | IPC::ResponseBuilder rb{ctx, 2, 1}; | 82 | IPC::ResponseBuilder rb{ctx, 2, 1}; |
| 76 | rb.Push(RESULT_SUCCESS); | 83 | rb.Push(RESULT_SUCCESS); |
| 77 | rb.PushCopyObjects(connection_event); | 84 | rb.PushCopyObjects(connection_event.readable); |
| 78 | } | 85 | } |
| 86 | |||
| 79 | void GetDiscoveryEvent(Kernel::HLERequestContext& ctx) { | 87 | void GetDiscoveryEvent(Kernel::HLERequestContext& ctx) { |
| 80 | LOG_WARNING(Service_BTM, "(STUBBED) called"); | 88 | LOG_WARNING(Service_BTM, "(STUBBED) called"); |
| 81 | 89 | ||
| 82 | auto& kernel = Core::System::GetInstance().Kernel(); | ||
| 83 | service_discovery = | ||
| 84 | Kernel::Event::Create(kernel, Kernel::ResetType::OneShot, "IBtmUserCore:Discovery"); | ||
| 85 | IPC::ResponseBuilder rb{ctx, 2, 1}; | 90 | IPC::ResponseBuilder rb{ctx, 2, 1}; |
| 86 | rb.Push(RESULT_SUCCESS); | 91 | rb.Push(RESULT_SUCCESS); |
| 87 | rb.PushCopyObjects(service_discovery); | 92 | rb.PushCopyObjects(service_discovery.readable); |
| 88 | } | 93 | } |
| 94 | |||
| 89 | void GetConfigEvent(Kernel::HLERequestContext& ctx) { | 95 | void GetConfigEvent(Kernel::HLERequestContext& ctx) { |
| 90 | LOG_WARNING(Service_BTM, "(STUBBED) called"); | 96 | LOG_WARNING(Service_BTM, "(STUBBED) called"); |
| 91 | 97 | ||
| 92 | auto& kernel = Core::System::GetInstance().Kernel(); | ||
| 93 | config_event = | ||
| 94 | Kernel::Event::Create(kernel, Kernel::ResetType::OneShot, "IBtmUserCore:ConfigEvent"); | ||
| 95 | IPC::ResponseBuilder rb{ctx, 2, 1}; | 98 | IPC::ResponseBuilder rb{ctx, 2, 1}; |
| 96 | rb.Push(RESULT_SUCCESS); | 99 | rb.Push(RESULT_SUCCESS); |
| 97 | rb.PushCopyObjects(config_event); | 100 | rb.PushCopyObjects(config_event.readable); |
| 98 | } | 101 | } |
| 99 | Kernel::SharedPtr<Kernel::Event> scan_event; | 102 | |
| 100 | Kernel::SharedPtr<Kernel::Event> connection_event; | 103 | Kernel::EventPair scan_event; |
| 101 | Kernel::SharedPtr<Kernel::Event> service_discovery; | 104 | Kernel::EventPair connection_event; |
| 102 | Kernel::SharedPtr<Kernel::Event> config_event; | 105 | Kernel::EventPair service_discovery; |
| 106 | Kernel::EventPair config_event; | ||
| 103 | }; | 107 | }; |
| 104 | 108 | ||
| 105 | class BTM_USR final : public ServiceFramework<BTM_USR> { | 109 | class BTM_USR final : public ServiceFramework<BTM_USR> { |
diff --git a/src/core/hle/service/erpt/erpt.cpp b/src/core/hle/service/erpt/erpt.cpp index ee11cd78e..d9b32954e 100644 --- a/src/core/hle/service/erpt/erpt.cpp +++ b/src/core/hle/service/erpt/erpt.cpp | |||
| @@ -17,11 +17,13 @@ public: | |||
| 17 | static const FunctionInfo functions[] = { | 17 | static const FunctionInfo functions[] = { |
| 18 | {0, nullptr, "SubmitContext"}, | 18 | {0, nullptr, "SubmitContext"}, |
| 19 | {1, nullptr, "CreateReport"}, | 19 | {1, nullptr, "CreateReport"}, |
| 20 | {2, nullptr, "Unknown1"}, | 20 | {2, nullptr, "SetInitialLaunchSettingsCompletionTime"}, |
| 21 | {3, nullptr, "Unknown2"}, | 21 | {3, nullptr, "ClearInitialLaunchSettingsCompletionTime"}, |
| 22 | {4, nullptr, "Unknown3"}, | 22 | {4, nullptr, "UpdatePowerOnTime"}, |
| 23 | {5, nullptr, "Unknown4"}, | 23 | {5, nullptr, "UpdateAwakeTime"}, |
| 24 | {6, nullptr, "Unknown5"}, | 24 | {6, nullptr, "SubmitMultipleCategoryContext"}, |
| 25 | {7, nullptr, "UpdateApplicationLaunchTime"}, | ||
| 26 | {8, nullptr, "ClearApplicationLaunchTime"}, | ||
| 25 | }; | 27 | }; |
| 26 | // clang-format on | 28 | // clang-format on |
| 27 | 29 | ||
diff --git a/src/core/hle/service/filesystem/filesystem.cpp b/src/core/hle/service/filesystem/filesystem.cpp index 2aa77f68d..b1490e6fa 100644 --- a/src/core/hle/service/filesystem/filesystem.cpp +++ b/src/core/hle/service/filesystem/filesystem.cpp | |||
| @@ -113,6 +113,18 @@ ResultCode VfsDirectoryServiceWrapper::DeleteDirectoryRecursively(const std::str | |||
| 113 | return RESULT_SUCCESS; | 113 | return RESULT_SUCCESS; |
| 114 | } | 114 | } |
| 115 | 115 | ||
| 116 | ResultCode VfsDirectoryServiceWrapper::CleanDirectoryRecursively(const std::string& path) const { | ||
| 117 | const std::string sanitized_path(FileUtil::SanitizePath(path)); | ||
| 118 | auto dir = GetDirectoryRelativeWrapped(backing, FileUtil::GetParentPath(sanitized_path)); | ||
| 119 | |||
| 120 | if (!dir->CleanSubdirectoryRecursive(FileUtil::GetFilename(sanitized_path))) { | ||
| 121 | // TODO(DarkLordZach): Find a better error code for this | ||
| 122 | return ResultCode(-1); | ||
| 123 | } | ||
| 124 | |||
| 125 | return RESULT_SUCCESS; | ||
| 126 | } | ||
| 127 | |||
| 116 | ResultCode VfsDirectoryServiceWrapper::RenameFile(const std::string& src_path_, | 128 | ResultCode VfsDirectoryServiceWrapper::RenameFile(const std::string& src_path_, |
| 117 | const std::string& dest_path_) const { | 129 | const std::string& dest_path_) const { |
| 118 | std::string src_path(FileUtil::SanitizePath(src_path_)); | 130 | std::string src_path(FileUtil::SanitizePath(src_path_)); |
| @@ -329,20 +341,9 @@ ResultVal<FileSys::VirtualDir> OpenSDMC() { | |||
| 329 | return sdmc_factory->Open(); | 341 | return sdmc_factory->Open(); |
| 330 | } | 342 | } |
| 331 | 343 | ||
| 332 | std::shared_ptr<FileSys::RegisteredCacheUnion> registered_cache_union; | 344 | FileSys::RegisteredCacheUnion GetUnionContents() { |
| 333 | 345 | return FileSys::RegisteredCacheUnion{ | |
| 334 | std::shared_ptr<FileSys::RegisteredCacheUnion> GetUnionContents() { | 346 | {GetSystemNANDContents(), GetUserNANDContents(), GetSDMCContents()}}; |
| 335 | if (registered_cache_union == nullptr) { | ||
| 336 | registered_cache_union = | ||
| 337 | std::make_shared<FileSys::RegisteredCacheUnion>(std::vector<FileSys::RegisteredCache*>{ | ||
| 338 | GetSystemNANDContents(), GetUserNANDContents(), GetSDMCContents()}); | ||
| 339 | } | ||
| 340 | |||
| 341 | return registered_cache_union; | ||
| 342 | } | ||
| 343 | |||
| 344 | void ClearUnionContents() { | ||
| 345 | registered_cache_union = nullptr; | ||
| 346 | } | 347 | } |
| 347 | 348 | ||
| 348 | FileSys::RegisteredCache* GetSystemNANDContents() { | 349 | FileSys::RegisteredCache* GetSystemNANDContents() { |
| @@ -395,7 +396,6 @@ void CreateFactories(FileSys::VfsFilesystem& vfs, bool overwrite) { | |||
| 395 | bis_factory = nullptr; | 396 | bis_factory = nullptr; |
| 396 | save_data_factory = nullptr; | 397 | save_data_factory = nullptr; |
| 397 | sdmc_factory = nullptr; | 398 | sdmc_factory = nullptr; |
| 398 | ClearUnionContents(); | ||
| 399 | } | 399 | } |
| 400 | 400 | ||
| 401 | auto nand_directory = vfs.OpenDirectory(FileUtil::GetUserPath(FileUtil::UserPath::NANDDir), | 401 | auto nand_directory = vfs.OpenDirectory(FileUtil::GetUserPath(FileUtil::UserPath::NANDDir), |
diff --git a/src/core/hle/service/filesystem/filesystem.h b/src/core/hle/service/filesystem/filesystem.h index 0a6cb6635..965414be0 100644 --- a/src/core/hle/service/filesystem/filesystem.h +++ b/src/core/hle/service/filesystem/filesystem.h | |||
| @@ -48,8 +48,7 @@ ResultVal<FileSys::VirtualDir> OpenSaveData(FileSys::SaveDataSpaceId space, | |||
| 48 | ResultVal<FileSys::VirtualDir> OpenSaveDataSpace(FileSys::SaveDataSpaceId space); | 48 | ResultVal<FileSys::VirtualDir> OpenSaveDataSpace(FileSys::SaveDataSpaceId space); |
| 49 | ResultVal<FileSys::VirtualDir> OpenSDMC(); | 49 | ResultVal<FileSys::VirtualDir> OpenSDMC(); |
| 50 | 50 | ||
| 51 | std::shared_ptr<FileSys::RegisteredCacheUnion> GetUnionContents(); | 51 | FileSys::RegisteredCacheUnion GetUnionContents(); |
| 52 | void ClearUnionContents(); | ||
| 53 | 52 | ||
| 54 | FileSys::RegisteredCache* GetSystemNANDContents(); | 53 | FileSys::RegisteredCache* GetSystemNANDContents(); |
| 55 | FileSys::RegisteredCache* GetUserNANDContents(); | 54 | FileSys::RegisteredCache* GetUserNANDContents(); |
| @@ -114,6 +113,18 @@ public: | |||
| 114 | ResultCode DeleteDirectoryRecursively(const std::string& path) const; | 113 | ResultCode DeleteDirectoryRecursively(const std::string& path) const; |
| 115 | 114 | ||
| 116 | /** | 115 | /** |
| 116 | * Cleans the specified directory. This is similar to DeleteDirectoryRecursively, | ||
| 117 | * in that it deletes all the contents of the specified directory, however, this | ||
| 118 | * function does *not* delete the directory itself. It only deletes everything | ||
| 119 | * within it. | ||
| 120 | * | ||
| 121 | * @param path Path relative to the archive. | ||
| 122 | * | ||
| 123 | * @return Result of the operation. | ||
| 124 | */ | ||
| 125 | ResultCode CleanDirectoryRecursively(const std::string& path) const; | ||
| 126 | |||
| 127 | /** | ||
| 117 | * Rename a File specified by its path | 128 | * Rename a File specified by its path |
| 118 | * @param src_path Source path relative to the archive | 129 | * @param src_path Source path relative to the archive |
| 119 | * @param dest_path Destination path relative to the archive | 130 | * @param dest_path Destination path relative to the archive |
diff --git a/src/core/hle/service/filesystem/fsp_srv.cpp b/src/core/hle/service/filesystem/fsp_srv.cpp index 99d9ebc39..694ec40ec 100644 --- a/src/core/hle/service/filesystem/fsp_srv.cpp +++ b/src/core/hle/service/filesystem/fsp_srv.cpp | |||
| @@ -291,7 +291,7 @@ public: | |||
| 291 | {10, &IFileSystem::Commit, "Commit"}, | 291 | {10, &IFileSystem::Commit, "Commit"}, |
| 292 | {11, nullptr, "GetFreeSpaceSize"}, | 292 | {11, nullptr, "GetFreeSpaceSize"}, |
| 293 | {12, nullptr, "GetTotalSpaceSize"}, | 293 | {12, nullptr, "GetTotalSpaceSize"}, |
| 294 | {13, nullptr, "CleanDirectoryRecursively"}, | 294 | {13, &IFileSystem::CleanDirectoryRecursively, "CleanDirectoryRecursively"}, |
| 295 | {14, nullptr, "GetFileTimeStampRaw"}, | 295 | {14, nullptr, "GetFileTimeStampRaw"}, |
| 296 | {15, nullptr, "QueryEntry"}, | 296 | {15, nullptr, "QueryEntry"}, |
| 297 | }; | 297 | }; |
| @@ -361,6 +361,16 @@ public: | |||
| 361 | rb.Push(backend.DeleteDirectoryRecursively(name)); | 361 | rb.Push(backend.DeleteDirectoryRecursively(name)); |
| 362 | } | 362 | } |
| 363 | 363 | ||
| 364 | void CleanDirectoryRecursively(Kernel::HLERequestContext& ctx) { | ||
| 365 | const auto file_buffer = ctx.ReadBuffer(); | ||
| 366 | const std::string name = Common::StringFromBuffer(file_buffer); | ||
| 367 | |||
| 368 | LOG_DEBUG(Service_FS, "called. Directory: {}", name); | ||
| 369 | |||
| 370 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 371 | rb.Push(backend.CleanDirectoryRecursively(name)); | ||
| 372 | } | ||
| 373 | |||
| 364 | void RenameFile(Kernel::HLERequestContext& ctx) { | 374 | void RenameFile(Kernel::HLERequestContext& ctx) { |
| 365 | IPC::RequestParser rp{ctx}; | 375 | IPC::RequestParser rp{ctx}; |
| 366 | 376 | ||
diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp index 22e87a50a..d6829d0b8 100644 --- a/src/core/hle/service/hid/controllers/npad.cpp +++ b/src/core/hle/service/hid/controllers/npad.cpp | |||
| @@ -12,7 +12,9 @@ | |||
| 12 | #include "core/core.h" | 12 | #include "core/core.h" |
| 13 | #include "core/core_timing.h" | 13 | #include "core/core_timing.h" |
| 14 | #include "core/frontend/input.h" | 14 | #include "core/frontend/input.h" |
| 15 | #include "core/hle/kernel/event.h" | 15 | #include "core/hle/kernel/kernel.h" |
| 16 | #include "core/hle/kernel/readable_event.h" | ||
| 17 | #include "core/hle/kernel/writable_event.h" | ||
| 16 | #include "core/hle/service/hid/controllers/npad.h" | 18 | #include "core/hle/service/hid/controllers/npad.h" |
| 17 | #include "core/settings.h" | 19 | #include "core/settings.h" |
| 18 | 20 | ||
| @@ -167,8 +169,8 @@ void Controller_NPad::InitNewlyAddedControler(std::size_t controller_idx) { | |||
| 167 | 169 | ||
| 168 | void Controller_NPad::OnInit() { | 170 | void Controller_NPad::OnInit() { |
| 169 | auto& kernel = Core::System::GetInstance().Kernel(); | 171 | auto& kernel = Core::System::GetInstance().Kernel(); |
| 170 | styleset_changed_event = | 172 | styleset_changed_event = Kernel::WritableEvent::CreateEventPair( |
| 171 | Kernel::Event::Create(kernel, Kernel::ResetType::OneShot, "npad:NpadStyleSetChanged"); | 173 | kernel, Kernel::ResetType::OneShot, "npad:NpadStyleSetChanged"); |
| 172 | 174 | ||
| 173 | if (!IsControllerActivated()) { | 175 | if (!IsControllerActivated()) { |
| 174 | return; | 176 | return; |
| @@ -494,7 +496,7 @@ void Controller_NPad::SetSupportedNPadIdTypes(u8* data, std::size_t length) { | |||
| 494 | had_controller_update = true; | 496 | had_controller_update = true; |
| 495 | } | 497 | } |
| 496 | if (had_controller_update) { | 498 | if (had_controller_update) { |
| 497 | styleset_changed_event->Signal(); | 499 | styleset_changed_event.writable->Signal(); |
| 498 | } | 500 | } |
| 499 | } | 501 | } |
| 500 | } | 502 | } |
| @@ -509,7 +511,7 @@ std::size_t Controller_NPad::GetSupportedNPadIdTypesSize() const { | |||
| 509 | } | 511 | } |
| 510 | 512 | ||
| 511 | void Controller_NPad::SetHoldType(NpadHoldType joy_hold_type) { | 513 | void Controller_NPad::SetHoldType(NpadHoldType joy_hold_type) { |
| 512 | styleset_changed_event->Signal(); | 514 | styleset_changed_event.writable->Signal(); |
| 513 | hold_type = joy_hold_type; | 515 | hold_type = joy_hold_type; |
| 514 | } | 516 | } |
| 515 | 517 | ||
| @@ -518,8 +520,9 @@ Controller_NPad::NpadHoldType Controller_NPad::GetHoldType() const { | |||
| 518 | } | 520 | } |
| 519 | 521 | ||
| 520 | void Controller_NPad::SetNpadMode(u32 npad_id, NPadAssignments assignment_mode) { | 522 | void Controller_NPad::SetNpadMode(u32 npad_id, NPadAssignments assignment_mode) { |
| 521 | ASSERT(npad_id < shared_memory_entries.size()); | 523 | const std::size_t npad_index = NPadIdToIndex(npad_id); |
| 522 | shared_memory_entries[npad_id].pad_assignment = assignment_mode; | 524 | ASSERT(npad_index < shared_memory_entries.size()); |
| 525 | shared_memory_entries[npad_index].pad_assignment = assignment_mode; | ||
| 523 | } | 526 | } |
| 524 | 527 | ||
| 525 | void Controller_NPad::VibrateController(const std::vector<u32>& controller_ids, | 528 | void Controller_NPad::VibrateController(const std::vector<u32>& controller_ids, |
| @@ -538,11 +541,11 @@ void Controller_NPad::VibrateController(const std::vector<u32>& controller_ids, | |||
| 538 | last_processed_vibration = vibrations.back(); | 541 | last_processed_vibration = vibrations.back(); |
| 539 | } | 542 | } |
| 540 | 543 | ||
| 541 | Kernel::SharedPtr<Kernel::Event> Controller_NPad::GetStyleSetChangedEvent() const { | 544 | Kernel::SharedPtr<Kernel::ReadableEvent> Controller_NPad::GetStyleSetChangedEvent() const { |
| 542 | // TODO(ogniK): Figure out the best time to signal this event. This event seems that it should | 545 | // TODO(ogniK): Figure out the best time to signal this event. This event seems that it should |
| 543 | // be signalled at least once, and signaled after a new controller is connected? | 546 | // be signalled at least once, and signaled after a new controller is connected? |
| 544 | styleset_changed_event->Signal(); | 547 | styleset_changed_event.writable->Signal(); |
| 545 | return styleset_changed_event; | 548 | return styleset_changed_event.readable; |
| 546 | } | 549 | } |
| 547 | 550 | ||
| 548 | Controller_NPad::Vibration Controller_NPad::GetLastVibration() const { | 551 | Controller_NPad::Vibration Controller_NPad::GetLastVibration() const { |
diff --git a/src/core/hle/service/hid/controllers/npad.h b/src/core/hle/service/hid/controllers/npad.h index abff6544d..29851f16a 100644 --- a/src/core/hle/service/hid/controllers/npad.h +++ b/src/core/hle/service/hid/controllers/npad.h | |||
| @@ -8,7 +8,8 @@ | |||
| 8 | #include "common/bit_field.h" | 8 | #include "common/bit_field.h" |
| 9 | #include "common/common_types.h" | 9 | #include "common/common_types.h" |
| 10 | #include "core/frontend/input.h" | 10 | #include "core/frontend/input.h" |
| 11 | #include "core/hle/kernel/event.h" | 11 | #include "core/hle/kernel/object.h" |
| 12 | #include "core/hle/kernel/writable_event.h" | ||
| 12 | #include "core/hle/service/hid/controllers/controller_base.h" | 13 | #include "core/hle/service/hid/controllers/controller_base.h" |
| 13 | #include "core/settings.h" | 14 | #include "core/settings.h" |
| 14 | 15 | ||
| @@ -108,7 +109,7 @@ public: | |||
| 108 | void VibrateController(const std::vector<u32>& controller_ids, | 109 | void VibrateController(const std::vector<u32>& controller_ids, |
| 109 | const std::vector<Vibration>& vibrations); | 110 | const std::vector<Vibration>& vibrations); |
| 110 | 111 | ||
| 111 | Kernel::SharedPtr<Kernel::Event> GetStyleSetChangedEvent() const; | 112 | Kernel::SharedPtr<Kernel::ReadableEvent> GetStyleSetChangedEvent() const; |
| 112 | Vibration GetLastVibration() const; | 113 | Vibration GetLastVibration() const; |
| 113 | 114 | ||
| 114 | void AddNewController(NPadControllerType controller); | 115 | void AddNewController(NPadControllerType controller); |
| @@ -303,7 +304,7 @@ private: | |||
| 303 | sticks; | 304 | sticks; |
| 304 | std::vector<u32> supported_npad_id_types{}; | 305 | std::vector<u32> supported_npad_id_types{}; |
| 305 | NpadHoldType hold_type{NpadHoldType::Vertical}; | 306 | NpadHoldType hold_type{NpadHoldType::Vertical}; |
| 306 | Kernel::SharedPtr<Kernel::Event> styleset_changed_event; | 307 | Kernel::EventPair styleset_changed_event; |
| 307 | Vibration last_processed_vibration{}; | 308 | Vibration last_processed_vibration{}; |
| 308 | std::array<ControllerHolder, 10> connected_controllers{}; | 309 | std::array<ControllerHolder, 10> connected_controllers{}; |
| 309 | bool can_controllers_vibrate{true}; | 310 | bool can_controllers_vibrate{true}; |
diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp index 46496e9bb..2ec38c726 100644 --- a/src/core/hle/service/hid/hid.cpp +++ b/src/core/hle/service/hid/hid.cpp | |||
| @@ -13,8 +13,9 @@ | |||
| 13 | #include "core/hle/ipc_helpers.h" | 13 | #include "core/hle/ipc_helpers.h" |
| 14 | #include "core/hle/kernel/client_port.h" | 14 | #include "core/hle/kernel/client_port.h" |
| 15 | #include "core/hle/kernel/client_session.h" | 15 | #include "core/hle/kernel/client_session.h" |
| 16 | #include "core/hle/kernel/event.h" | 16 | #include "core/hle/kernel/readable_event.h" |
| 17 | #include "core/hle/kernel/shared_memory.h" | 17 | #include "core/hle/kernel/shared_memory.h" |
| 18 | #include "core/hle/kernel/writable_event.h" | ||
| 18 | #include "core/hle/service/hid/hid.h" | 19 | #include "core/hle/service/hid/hid.h" |
| 19 | #include "core/hle/service/hid/irs.h" | 20 | #include "core/hle/service/hid/irs.h" |
| 20 | #include "core/hle/service/hid/xcd.h" | 21 | #include "core/hle/service/hid/xcd.h" |
diff --git a/src/core/hle/service/nfp/nfp.cpp b/src/core/hle/service/nfp/nfp.cpp index ff9170c24..d5df112a0 100644 --- a/src/core/hle/service/nfp/nfp.cpp +++ b/src/core/hle/service/nfp/nfp.cpp | |||
| @@ -7,7 +7,9 @@ | |||
| 7 | #include "common/logging/log.h" | 7 | #include "common/logging/log.h" |
| 8 | #include "core/core.h" | 8 | #include "core/core.h" |
| 9 | #include "core/hle/ipc_helpers.h" | 9 | #include "core/hle/ipc_helpers.h" |
| 10 | #include "core/hle/kernel/event.h" | 10 | #include "core/hle/kernel/kernel.h" |
| 11 | #include "core/hle/kernel/readable_event.h" | ||
| 12 | #include "core/hle/kernel/writable_event.h" | ||
| 11 | #include "core/hle/lock.h" | 13 | #include "core/hle/lock.h" |
| 12 | #include "core/hle/service/hid/hid.h" | 14 | #include "core/hle/service/hid/hid.h" |
| 13 | #include "core/hle/service/nfp/nfp.h" | 15 | #include "core/hle/service/nfp/nfp.h" |
| @@ -23,8 +25,8 @@ constexpr ResultCode ERR_TAG_FAILED(ErrorModule::NFP, | |||
| 23 | Module::Interface::Interface(std::shared_ptr<Module> module, const char* name) | 25 | Module::Interface::Interface(std::shared_ptr<Module> module, const char* name) |
| 24 | : ServiceFramework(name), module(std::move(module)) { | 26 | : ServiceFramework(name), module(std::move(module)) { |
| 25 | auto& kernel = Core::System::GetInstance().Kernel(); | 27 | auto& kernel = Core::System::GetInstance().Kernel(); |
| 26 | nfc_tag_load = | 28 | nfc_tag_load = Kernel::WritableEvent::CreateEventPair(kernel, Kernel::ResetType::OneShot, |
| 27 | Kernel::Event::Create(kernel, Kernel::ResetType::OneShot, "IUser:NFCTagDetected"); | 29 | "IUser:NFCTagDetected"); |
| 28 | } | 30 | } |
| 29 | 31 | ||
| 30 | Module::Interface::~Interface() = default; | 32 | Module::Interface::~Interface() = default; |
| @@ -63,10 +65,10 @@ public: | |||
| 63 | RegisterHandlers(functions); | 65 | RegisterHandlers(functions); |
| 64 | 66 | ||
| 65 | auto& kernel = Core::System::GetInstance().Kernel(); | 67 | auto& kernel = Core::System::GetInstance().Kernel(); |
| 66 | deactivate_event = | 68 | deactivate_event = Kernel::WritableEvent::CreateEventPair( |
| 67 | Kernel::Event::Create(kernel, Kernel::ResetType::OneShot, "IUser:DeactivateEvent"); | 69 | kernel, Kernel::ResetType::OneShot, "IUser:DeactivateEvent"); |
| 68 | availability_change_event = Kernel::Event::Create(kernel, Kernel::ResetType::OneShot, | 70 | availability_change_event = Kernel::WritableEvent::CreateEventPair( |
| 69 | "IUser:AvailabilityChangeEvent"); | 71 | kernel, Kernel::ResetType::OneShot, "IUser:AvailabilityChangeEvent"); |
| 70 | } | 72 | } |
| 71 | 73 | ||
| 72 | private: | 74 | private: |
| @@ -164,7 +166,7 @@ private: | |||
| 164 | 166 | ||
| 165 | IPC::ResponseBuilder rb{ctx, 2, 1}; | 167 | IPC::ResponseBuilder rb{ctx, 2, 1}; |
| 166 | rb.Push(RESULT_SUCCESS); | 168 | rb.Push(RESULT_SUCCESS); |
| 167 | rb.PushCopyObjects(deactivate_event); | 169 | rb.PushCopyObjects(deactivate_event.readable); |
| 168 | } | 170 | } |
| 169 | 171 | ||
| 170 | void StopDetection(Kernel::HLERequestContext& ctx) { | 172 | void StopDetection(Kernel::HLERequestContext& ctx) { |
| @@ -173,7 +175,7 @@ private: | |||
| 173 | switch (device_state) { | 175 | switch (device_state) { |
| 174 | case DeviceState::TagFound: | 176 | case DeviceState::TagFound: |
| 175 | case DeviceState::TagNearby: | 177 | case DeviceState::TagNearby: |
| 176 | deactivate_event->Signal(); | 178 | deactivate_event.writable->Signal(); |
| 177 | device_state = DeviceState::Initialized; | 179 | device_state = DeviceState::Initialized; |
| 178 | break; | 180 | break; |
| 179 | case DeviceState::SearchingForTag: | 181 | case DeviceState::SearchingForTag: |
| @@ -264,7 +266,7 @@ private: | |||
| 264 | 266 | ||
| 265 | IPC::ResponseBuilder rb{ctx, 2, 1}; | 267 | IPC::ResponseBuilder rb{ctx, 2, 1}; |
| 266 | rb.Push(RESULT_SUCCESS); | 268 | rb.Push(RESULT_SUCCESS); |
| 267 | rb.PushCopyObjects(availability_change_event); | 269 | rb.PushCopyObjects(availability_change_event.readable); |
| 268 | } | 270 | } |
| 269 | 271 | ||
| 270 | void GetRegisterInfo(Kernel::HLERequestContext& ctx) { | 272 | void GetRegisterInfo(Kernel::HLERequestContext& ctx) { |
| @@ -319,8 +321,8 @@ private: | |||
| 319 | const u32 npad_id{0}; // Player 1 controller | 321 | const u32 npad_id{0}; // Player 1 controller |
| 320 | State state{State::NonInitialized}; | 322 | State state{State::NonInitialized}; |
| 321 | DeviceState device_state{DeviceState::Initialized}; | 323 | DeviceState device_state{DeviceState::Initialized}; |
| 322 | Kernel::SharedPtr<Kernel::Event> deactivate_event; | 324 | Kernel::EventPair deactivate_event; |
| 323 | Kernel::SharedPtr<Kernel::Event> availability_change_event; | 325 | Kernel::EventPair availability_change_event; |
| 324 | const Module::Interface& nfp_interface; | 326 | const Module::Interface& nfp_interface; |
| 325 | }; | 327 | }; |
| 326 | 328 | ||
| @@ -339,12 +341,14 @@ bool Module::Interface::LoadAmiibo(const std::vector<u8>& buffer) { | |||
| 339 | } | 341 | } |
| 340 | 342 | ||
| 341 | std::memcpy(&amiibo, buffer.data(), sizeof(amiibo)); | 343 | std::memcpy(&amiibo, buffer.data(), sizeof(amiibo)); |
| 342 | nfc_tag_load->Signal(); | 344 | nfc_tag_load.writable->Signal(); |
| 343 | return true; | 345 | return true; |
| 344 | } | 346 | } |
| 345 | const Kernel::SharedPtr<Kernel::Event>& Module::Interface::GetNFCEvent() const { | 347 | |
| 346 | return nfc_tag_load; | 348 | const Kernel::SharedPtr<Kernel::ReadableEvent>& Module::Interface::GetNFCEvent() const { |
| 349 | return nfc_tag_load.readable; | ||
| 347 | } | 350 | } |
| 351 | |||
| 348 | const Module::Interface::AmiiboFile& Module::Interface::GetAmiiboBuffer() const { | 352 | const Module::Interface::AmiiboFile& Module::Interface::GetAmiiboBuffer() const { |
| 349 | return amiibo; | 353 | return amiibo; |
| 350 | } | 354 | } |
diff --git a/src/core/hle/service/nfp/nfp.h b/src/core/hle/service/nfp/nfp.h index 5c0ae8a54..a1817e991 100644 --- a/src/core/hle/service/nfp/nfp.h +++ b/src/core/hle/service/nfp/nfp.h | |||
| @@ -6,7 +6,8 @@ | |||
| 6 | 6 | ||
| 7 | #include <array> | 7 | #include <array> |
| 8 | #include <vector> | 8 | #include <vector> |
| 9 | #include "core/hle/kernel/event.h" | 9 | #include "core/hle/kernel/readable_event.h" |
| 10 | #include "core/hle/kernel/writable_event.h" | ||
| 10 | #include "core/hle/service/service.h" | 11 | #include "core/hle/service/service.h" |
| 11 | 12 | ||
| 12 | namespace Service::NFP { | 13 | namespace Service::NFP { |
| @@ -33,11 +34,11 @@ public: | |||
| 33 | 34 | ||
| 34 | void CreateUserInterface(Kernel::HLERequestContext& ctx); | 35 | void CreateUserInterface(Kernel::HLERequestContext& ctx); |
| 35 | bool LoadAmiibo(const std::vector<u8>& buffer); | 36 | bool LoadAmiibo(const std::vector<u8>& buffer); |
| 36 | const Kernel::SharedPtr<Kernel::Event>& GetNFCEvent() const; | 37 | const Kernel::SharedPtr<Kernel::ReadableEvent>& GetNFCEvent() const; |
| 37 | const AmiiboFile& GetAmiiboBuffer() const; | 38 | const AmiiboFile& GetAmiiboBuffer() const; |
| 38 | 39 | ||
| 39 | private: | 40 | private: |
| 40 | Kernel::SharedPtr<Kernel::Event> nfc_tag_load{}; | 41 | Kernel::EventPair nfc_tag_load{}; |
| 41 | AmiiboFile amiibo{}; | 42 | AmiiboFile amiibo{}; |
| 42 | 43 | ||
| 43 | protected: | 44 | protected: |
diff --git a/src/core/hle/service/nifm/nifm.cpp b/src/core/hle/service/nifm/nifm.cpp index dee391201..60479bb45 100644 --- a/src/core/hle/service/nifm/nifm.cpp +++ b/src/core/hle/service/nifm/nifm.cpp | |||
| @@ -4,7 +4,9 @@ | |||
| 4 | 4 | ||
| 5 | #include "core/core.h" | 5 | #include "core/core.h" |
| 6 | #include "core/hle/ipc_helpers.h" | 6 | #include "core/hle/ipc_helpers.h" |
| 7 | #include "core/hle/kernel/event.h" | 7 | #include "core/hle/kernel/kernel.h" |
| 8 | #include "core/hle/kernel/readable_event.h" | ||
| 9 | #include "core/hle/kernel/writable_event.h" | ||
| 8 | #include "core/hle/service/nifm/nifm.h" | 10 | #include "core/hle/service/nifm/nifm.h" |
| 9 | #include "core/hle/service/service.h" | 11 | #include "core/hle/service/service.h" |
| 10 | 12 | ||
| @@ -56,8 +58,10 @@ public: | |||
| 56 | RegisterHandlers(functions); | 58 | RegisterHandlers(functions); |
| 57 | 59 | ||
| 58 | auto& kernel = Core::System::GetInstance().Kernel(); | 60 | auto& kernel = Core::System::GetInstance().Kernel(); |
| 59 | event1 = Kernel::Event::Create(kernel, Kernel::ResetType::OneShot, "IRequest:Event1"); | 61 | event1 = Kernel::WritableEvent::CreateEventPair(kernel, Kernel::ResetType::OneShot, |
| 60 | event2 = Kernel::Event::Create(kernel, Kernel::ResetType::OneShot, "IRequest:Event2"); | 62 | "IRequest:Event1"); |
| 63 | event2 = Kernel::WritableEvent::CreateEventPair(kernel, Kernel::ResetType::OneShot, | ||
| 64 | "IRequest:Event2"); | ||
| 61 | } | 65 | } |
| 62 | 66 | ||
| 63 | private: | 67 | private: |
| @@ -88,7 +92,7 @@ private: | |||
| 88 | 92 | ||
| 89 | IPC::ResponseBuilder rb{ctx, 2, 2}; | 93 | IPC::ResponseBuilder rb{ctx, 2, 2}; |
| 90 | rb.Push(RESULT_SUCCESS); | 94 | rb.Push(RESULT_SUCCESS); |
| 91 | rb.PushCopyObjects(event1, event2); | 95 | rb.PushCopyObjects(event1.readable, event2.readable); |
| 92 | } | 96 | } |
| 93 | 97 | ||
| 94 | void Cancel(Kernel::HLERequestContext& ctx) { | 98 | void Cancel(Kernel::HLERequestContext& ctx) { |
| @@ -105,7 +109,7 @@ private: | |||
| 105 | rb.Push(RESULT_SUCCESS); | 109 | rb.Push(RESULT_SUCCESS); |
| 106 | } | 110 | } |
| 107 | 111 | ||
| 108 | Kernel::SharedPtr<Kernel::Event> event1, event2; | 112 | Kernel::EventPair event1, event2; |
| 109 | }; | 113 | }; |
| 110 | 114 | ||
| 111 | class INetworkProfile final : public ServiceFramework<INetworkProfile> { | 115 | class INetworkProfile final : public ServiceFramework<INetworkProfile> { |
diff --git a/src/core/hle/service/nim/nim.cpp b/src/core/hle/service/nim/nim.cpp index 1bbccd444..0dabcd23b 100644 --- a/src/core/hle/service/nim/nim.cpp +++ b/src/core/hle/service/nim/nim.cpp | |||
| @@ -6,7 +6,9 @@ | |||
| 6 | #include <ctime> | 6 | #include <ctime> |
| 7 | #include "core/core.h" | 7 | #include "core/core.h" |
| 8 | #include "core/hle/ipc_helpers.h" | 8 | #include "core/hle/ipc_helpers.h" |
| 9 | #include "core/hle/kernel/event.h" | 9 | #include "core/hle/kernel/kernel.h" |
| 10 | #include "core/hle/kernel/readable_event.h" | ||
| 11 | #include "core/hle/kernel/writable_event.h" | ||
| 10 | #include "core/hle/service/nim/nim.h" | 12 | #include "core/hle/service/nim/nim.h" |
| 11 | #include "core/hle/service/service.h" | 13 | #include "core/hle/service/service.h" |
| 12 | #include "core/hle/service/sm/sm.h" | 14 | #include "core/hle/service/sm/sm.h" |
| @@ -138,19 +140,18 @@ public: | |||
| 138 | RegisterHandlers(functions); | 140 | RegisterHandlers(functions); |
| 139 | 141 | ||
| 140 | auto& kernel = Core::System::GetInstance().Kernel(); | 142 | auto& kernel = Core::System::GetInstance().Kernel(); |
| 141 | finished_event = | 143 | finished_event = Kernel::WritableEvent::CreateEventPair( |
| 142 | Kernel::Event::Create(kernel, Kernel::ResetType::OneShot, | 144 | kernel, Kernel::ResetType::OneShot, |
| 143 | "IEnsureNetworkClockAvailabilityService:FinishEvent"); | 145 | "IEnsureNetworkClockAvailabilityService:FinishEvent"); |
| 144 | } | 146 | } |
| 145 | 147 | ||
| 146 | private: | 148 | private: |
| 147 | Kernel::SharedPtr<Kernel::Event> finished_event; | 149 | Kernel::EventPair finished_event; |
| 148 | 150 | ||
| 149 | void StartTask(Kernel::HLERequestContext& ctx) { | 151 | void StartTask(Kernel::HLERequestContext& ctx) { |
| 150 | // No need to connect to the internet, just finish the task straight away. | 152 | // No need to connect to the internet, just finish the task straight away. |
| 151 | LOG_DEBUG(Service_NIM, "called"); | 153 | LOG_DEBUG(Service_NIM, "called"); |
| 152 | 154 | finished_event.writable->Signal(); | |
| 153 | finished_event->Signal(); | ||
| 154 | IPC::ResponseBuilder rb{ctx, 2}; | 155 | IPC::ResponseBuilder rb{ctx, 2}; |
| 155 | rb.Push(RESULT_SUCCESS); | 156 | rb.Push(RESULT_SUCCESS); |
| 156 | } | 157 | } |
| @@ -160,7 +161,7 @@ private: | |||
| 160 | 161 | ||
| 161 | IPC::ResponseBuilder rb{ctx, 2, 1}; | 162 | IPC::ResponseBuilder rb{ctx, 2, 1}; |
| 162 | rb.Push(RESULT_SUCCESS); | 163 | rb.Push(RESULT_SUCCESS); |
| 163 | rb.PushCopyObjects(finished_event); | 164 | rb.PushCopyObjects(finished_event.readable); |
| 164 | } | 165 | } |
| 165 | 166 | ||
| 166 | void GetResult(Kernel::HLERequestContext& ctx) { | 167 | void GetResult(Kernel::HLERequestContext& ctx) { |
| @@ -172,8 +173,7 @@ private: | |||
| 172 | 173 | ||
| 173 | void Cancel(Kernel::HLERequestContext& ctx) { | 174 | void Cancel(Kernel::HLERequestContext& ctx) { |
| 174 | LOG_DEBUG(Service_NIM, "called"); | 175 | LOG_DEBUG(Service_NIM, "called"); |
| 175 | 176 | finished_event.writable->Clear(); | |
| 176 | finished_event->Clear(); | ||
| 177 | IPC::ResponseBuilder rb{ctx, 2}; | 177 | IPC::ResponseBuilder rb{ctx, 2}; |
| 178 | rb.Push(RESULT_SUCCESS); | 178 | rb.Push(RESULT_SUCCESS); |
| 179 | } | 179 | } |
diff --git a/src/core/hle/service/nvdrv/interface.cpp b/src/core/hle/service/nvdrv/interface.cpp index ff76e0524..3b9ab4b14 100644 --- a/src/core/hle/service/nvdrv/interface.cpp +++ b/src/core/hle/service/nvdrv/interface.cpp | |||
| @@ -6,7 +6,9 @@ | |||
| 6 | #include "common/logging/log.h" | 6 | #include "common/logging/log.h" |
| 7 | #include "core/core.h" | 7 | #include "core/core.h" |
| 8 | #include "core/hle/ipc_helpers.h" | 8 | #include "core/hle/ipc_helpers.h" |
| 9 | #include "core/hle/kernel/event.h" | 9 | #include "core/hle/kernel/kernel.h" |
| 10 | #include "core/hle/kernel/readable_event.h" | ||
| 11 | #include "core/hle/kernel/writable_event.h" | ||
| 10 | #include "core/hle/service/nvdrv/interface.h" | 12 | #include "core/hle/service/nvdrv/interface.h" |
| 11 | #include "core/hle/service/nvdrv/nvdrv.h" | 13 | #include "core/hle/service/nvdrv/nvdrv.h" |
| 12 | 14 | ||
| @@ -69,7 +71,7 @@ void NVDRV::QueryEvent(Kernel::HLERequestContext& ctx) { | |||
| 69 | 71 | ||
| 70 | IPC::ResponseBuilder rb{ctx, 3, 1}; | 72 | IPC::ResponseBuilder rb{ctx, 3, 1}; |
| 71 | rb.Push(RESULT_SUCCESS); | 73 | rb.Push(RESULT_SUCCESS); |
| 72 | rb.PushCopyObjects(query_event); | 74 | rb.PushCopyObjects(query_event.readable); |
| 73 | rb.Push<u32>(0); | 75 | rb.Push<u32>(0); |
| 74 | } | 76 | } |
| 75 | 77 | ||
| @@ -127,7 +129,8 @@ NVDRV::NVDRV(std::shared_ptr<Module> nvdrv, const char* name) | |||
| 127 | RegisterHandlers(functions); | 129 | RegisterHandlers(functions); |
| 128 | 130 | ||
| 129 | auto& kernel = Core::System::GetInstance().Kernel(); | 131 | auto& kernel = Core::System::GetInstance().Kernel(); |
| 130 | query_event = Kernel::Event::Create(kernel, Kernel::ResetType::OneShot, "NVDRV::query_event"); | 132 | query_event = Kernel::WritableEvent::CreateEventPair(kernel, Kernel::ResetType::OneShot, |
| 133 | "NVDRV::query_event"); | ||
| 131 | } | 134 | } |
| 132 | 135 | ||
| 133 | NVDRV::~NVDRV() = default; | 136 | NVDRV::~NVDRV() = default; |
diff --git a/src/core/hle/service/nvdrv/interface.h b/src/core/hle/service/nvdrv/interface.h index 5a1e4baa7..fe311b069 100644 --- a/src/core/hle/service/nvdrv/interface.h +++ b/src/core/hle/service/nvdrv/interface.h | |||
| @@ -5,10 +5,13 @@ | |||
| 5 | #pragma once | 5 | #pragma once |
| 6 | 6 | ||
| 7 | #include <memory> | 7 | #include <memory> |
| 8 | #include "core/hle/kernel/event.h" | ||
| 9 | #include "core/hle/service/nvdrv/nvdrv.h" | 8 | #include "core/hle/service/nvdrv/nvdrv.h" |
| 10 | #include "core/hle/service/service.h" | 9 | #include "core/hle/service/service.h" |
| 11 | 10 | ||
| 11 | namespace Kernel { | ||
| 12 | class WritableEvent; | ||
| 13 | } | ||
| 14 | |||
| 12 | namespace Service::Nvidia { | 15 | namespace Service::Nvidia { |
| 13 | 16 | ||
| 14 | class NVDRV final : public ServiceFramework<NVDRV> { | 17 | class NVDRV final : public ServiceFramework<NVDRV> { |
| @@ -31,7 +34,7 @@ private: | |||
| 31 | 34 | ||
| 32 | u64 pid{}; | 35 | u64 pid{}; |
| 33 | 36 | ||
| 34 | Kernel::SharedPtr<Kernel::Event> query_event; | 37 | Kernel::EventPair query_event; |
| 35 | }; | 38 | }; |
| 36 | 39 | ||
| 37 | } // namespace Service::Nvidia | 40 | } // namespace Service::Nvidia |
diff --git a/src/core/hle/service/nvflinger/buffer_queue.cpp b/src/core/hle/service/nvflinger/buffer_queue.cpp index 172a1a441..fc07d9bb8 100644 --- a/src/core/hle/service/nvflinger/buffer_queue.cpp +++ b/src/core/hle/service/nvflinger/buffer_queue.cpp | |||
| @@ -7,14 +7,17 @@ | |||
| 7 | #include "common/assert.h" | 7 | #include "common/assert.h" |
| 8 | #include "common/logging/log.h" | 8 | #include "common/logging/log.h" |
| 9 | #include "core/core.h" | 9 | #include "core/core.h" |
| 10 | #include "core/hle/kernel/kernel.h" | ||
| 11 | #include "core/hle/kernel/readable_event.h" | ||
| 12 | #include "core/hle/kernel/writable_event.h" | ||
| 10 | #include "core/hle/service/nvflinger/buffer_queue.h" | 13 | #include "core/hle/service/nvflinger/buffer_queue.h" |
| 11 | 14 | ||
| 12 | namespace Service::NVFlinger { | 15 | namespace Service::NVFlinger { |
| 13 | 16 | ||
| 14 | BufferQueue::BufferQueue(u32 id, u64 layer_id) : id(id), layer_id(layer_id) { | 17 | BufferQueue::BufferQueue(u32 id, u64 layer_id) : id(id), layer_id(layer_id) { |
| 15 | auto& kernel = Core::System::GetInstance().Kernel(); | 18 | auto& kernel = Core::System::GetInstance().Kernel(); |
| 16 | buffer_wait_event = | 19 | buffer_wait_event = Kernel::WritableEvent::CreateEventPair(kernel, Kernel::ResetType::Sticky, |
| 17 | Kernel::Event::Create(kernel, Kernel::ResetType::Sticky, "BufferQueue NativeHandle"); | 20 | "BufferQueue NativeHandle"); |
| 18 | } | 21 | } |
| 19 | 22 | ||
| 20 | BufferQueue::~BufferQueue() = default; | 23 | BufferQueue::~BufferQueue() = default; |
| @@ -28,7 +31,7 @@ void BufferQueue::SetPreallocatedBuffer(u32 slot, const IGBPBuffer& igbp_buffer) | |||
| 28 | buffer.status = Buffer::Status::Free; | 31 | buffer.status = Buffer::Status::Free; |
| 29 | 32 | ||
| 30 | queue.emplace_back(buffer); | 33 | queue.emplace_back(buffer); |
| 31 | buffer_wait_event->Signal(); | 34 | buffer_wait_event.writable->Signal(); |
| 32 | } | 35 | } |
| 33 | 36 | ||
| 34 | std::optional<u32> BufferQueue::DequeueBuffer(u32 width, u32 height) { | 37 | std::optional<u32> BufferQueue::DequeueBuffer(u32 width, u32 height) { |
| @@ -87,7 +90,7 @@ void BufferQueue::ReleaseBuffer(u32 slot) { | |||
| 87 | ASSERT(itr->status == Buffer::Status::Acquired); | 90 | ASSERT(itr->status == Buffer::Status::Acquired); |
| 88 | itr->status = Buffer::Status::Free; | 91 | itr->status = Buffer::Status::Free; |
| 89 | 92 | ||
| 90 | buffer_wait_event->Signal(); | 93 | buffer_wait_event.writable->Signal(); |
| 91 | } | 94 | } |
| 92 | 95 | ||
| 93 | u32 BufferQueue::Query(QueryType type) { | 96 | u32 BufferQueue::Query(QueryType type) { |
| @@ -104,4 +107,12 @@ u32 BufferQueue::Query(QueryType type) { | |||
| 104 | return 0; | 107 | return 0; |
| 105 | } | 108 | } |
| 106 | 109 | ||
| 110 | Kernel::SharedPtr<Kernel::WritableEvent> BufferQueue::GetWritableBufferWaitEvent() const { | ||
| 111 | return buffer_wait_event.writable; | ||
| 112 | } | ||
| 113 | |||
| 114 | Kernel::SharedPtr<Kernel::ReadableEvent> BufferQueue::GetBufferWaitEvent() const { | ||
| 115 | return buffer_wait_event.readable; | ||
| 116 | } | ||
| 117 | |||
| 107 | } // namespace Service::NVFlinger | 118 | } // namespace Service::NVFlinger |
diff --git a/src/core/hle/service/nvflinger/buffer_queue.h b/src/core/hle/service/nvflinger/buffer_queue.h index 8cff5eb71..b171f256c 100644 --- a/src/core/hle/service/nvflinger/buffer_queue.h +++ b/src/core/hle/service/nvflinger/buffer_queue.h | |||
| @@ -10,7 +10,8 @@ | |||
| 10 | #include "common/common_funcs.h" | 10 | #include "common/common_funcs.h" |
| 11 | #include "common/math_util.h" | 11 | #include "common/math_util.h" |
| 12 | #include "common/swap.h" | 12 | #include "common/swap.h" |
| 13 | #include "core/hle/kernel/event.h" | 13 | #include "core/hle/kernel/object.h" |
| 14 | #include "core/hle/kernel/writable_event.h" | ||
| 14 | 15 | ||
| 15 | namespace CoreTiming { | 16 | namespace CoreTiming { |
| 16 | struct EventType; | 17 | struct EventType; |
| @@ -86,16 +87,16 @@ public: | |||
| 86 | return id; | 87 | return id; |
| 87 | } | 88 | } |
| 88 | 89 | ||
| 89 | Kernel::SharedPtr<Kernel::Event> GetBufferWaitEvent() const { | 90 | Kernel::SharedPtr<Kernel::WritableEvent> GetWritableBufferWaitEvent() const; |
| 90 | return buffer_wait_event; | 91 | |
| 91 | } | 92 | Kernel::SharedPtr<Kernel::ReadableEvent> GetBufferWaitEvent() const; |
| 92 | 93 | ||
| 93 | private: | 94 | private: |
| 94 | u32 id; | 95 | u32 id; |
| 95 | u64 layer_id; | 96 | u64 layer_id; |
| 96 | 97 | ||
| 97 | std::vector<Buffer> queue; | 98 | std::vector<Buffer> queue; |
| 98 | Kernel::SharedPtr<Kernel::Event> buffer_wait_event; | 99 | Kernel::EventPair buffer_wait_event; |
| 99 | }; | 100 | }; |
| 100 | 101 | ||
| 101 | } // namespace Service::NVFlinger | 102 | } // namespace Service::NVFlinger |
diff --git a/src/core/hle/service/nvflinger/nvflinger.cpp b/src/core/hle/service/nvflinger/nvflinger.cpp index 214e6d1b3..05af2d593 100644 --- a/src/core/hle/service/nvflinger/nvflinger.cpp +++ b/src/core/hle/service/nvflinger/nvflinger.cpp | |||
| @@ -13,6 +13,9 @@ | |||
| 13 | #include "core/core.h" | 13 | #include "core/core.h" |
| 14 | #include "core/core_timing.h" | 14 | #include "core/core_timing.h" |
| 15 | #include "core/core_timing_util.h" | 15 | #include "core/core_timing_util.h" |
| 16 | #include "core/hle/kernel/kernel.h" | ||
| 17 | #include "core/hle/kernel/readable_event.h" | ||
| 18 | #include "core/hle/kernel/writable_event.h" | ||
| 16 | #include "core/hle/service/nvdrv/devices/nvdisp_disp0.h" | 19 | #include "core/hle/service/nvdrv/devices/nvdisp_disp0.h" |
| 17 | #include "core/hle/service/nvdrv/nvdrv.h" | 20 | #include "core/hle/service/nvdrv/nvdrv.h" |
| 18 | #include "core/hle/service/nvflinger/buffer_queue.h" | 21 | #include "core/hle/service/nvflinger/buffer_queue.h" |
| @@ -83,9 +86,8 @@ u32 NVFlinger::GetBufferQueueId(u64 display_id, u64 layer_id) { | |||
| 83 | return layer.buffer_queue->GetId(); | 86 | return layer.buffer_queue->GetId(); |
| 84 | } | 87 | } |
| 85 | 88 | ||
| 86 | Kernel::SharedPtr<Kernel::Event> NVFlinger::GetVsyncEvent(u64 display_id) { | 89 | Kernel::SharedPtr<Kernel::ReadableEvent> NVFlinger::GetVsyncEvent(u64 display_id) { |
| 87 | const auto& display = GetDisplay(display_id); | 90 | return GetDisplay(display_id).vsync_event.readable; |
| 88 | return display.vsync_event; | ||
| 89 | } | 91 | } |
| 90 | 92 | ||
| 91 | std::shared_ptr<BufferQueue> NVFlinger::GetBufferQueue(u32 id) const { | 93 | std::shared_ptr<BufferQueue> NVFlinger::GetBufferQueue(u32 id) const { |
| @@ -117,7 +119,7 @@ Layer& NVFlinger::GetLayer(u64 display_id, u64 layer_id) { | |||
| 117 | void NVFlinger::Compose() { | 119 | void NVFlinger::Compose() { |
| 118 | for (auto& display : displays) { | 120 | for (auto& display : displays) { |
| 119 | // Trigger vsync for this display at the end of drawing | 121 | // Trigger vsync for this display at the end of drawing |
| 120 | SCOPE_EXIT({ display.vsync_event->Signal(); }); | 122 | SCOPE_EXIT({ display.vsync_event.writable->Signal(); }); |
| 121 | 123 | ||
| 122 | // Don't do anything for displays without layers. | 124 | // Don't do anything for displays without layers. |
| 123 | if (display.layers.empty()) | 125 | if (display.layers.empty()) |
| @@ -164,7 +166,8 @@ Layer::~Layer() = default; | |||
| 164 | 166 | ||
| 165 | Display::Display(u64 id, std::string name) : id(id), name(std::move(name)) { | 167 | Display::Display(u64 id, std::string name) : id(id), name(std::move(name)) { |
| 166 | auto& kernel = Core::System::GetInstance().Kernel(); | 168 | auto& kernel = Core::System::GetInstance().Kernel(); |
| 167 | vsync_event = Kernel::Event::Create(kernel, Kernel::ResetType::Pulse, "Display VSync Event"); | 169 | vsync_event = Kernel::WritableEvent::CreateEventPair(kernel, Kernel::ResetType::Pulse, |
| 170 | fmt::format("Display VSync Event {}", id)); | ||
| 168 | } | 171 | } |
| 169 | 172 | ||
| 170 | Display::~Display() = default; | 173 | Display::~Display() = default; |
diff --git a/src/core/hle/service/nvflinger/nvflinger.h b/src/core/hle/service/nvflinger/nvflinger.h index 3dc69e69b..9abba555b 100644 --- a/src/core/hle/service/nvflinger/nvflinger.h +++ b/src/core/hle/service/nvflinger/nvflinger.h | |||
| @@ -10,12 +10,17 @@ | |||
| 10 | #include <vector> | 10 | #include <vector> |
| 11 | 11 | ||
| 12 | #include "common/common_types.h" | 12 | #include "common/common_types.h" |
| 13 | #include "core/hle/kernel/event.h" | 13 | #include "core/hle/kernel/object.h" |
| 14 | 14 | ||
| 15 | namespace CoreTiming { | 15 | namespace CoreTiming { |
| 16 | struct EventType; | 16 | struct EventType; |
| 17 | } | 17 | } |
| 18 | 18 | ||
| 19 | namespace Kernel { | ||
| 20 | class ReadableEvent; | ||
| 21 | class WritableEvent; | ||
| 22 | } // namespace Kernel | ||
| 23 | |||
| 19 | namespace Service::Nvidia { | 24 | namespace Service::Nvidia { |
| 20 | class Module; | 25 | class Module; |
| 21 | } | 26 | } |
| @@ -40,7 +45,7 @@ struct Display { | |||
| 40 | std::string name; | 45 | std::string name; |
| 41 | 46 | ||
| 42 | std::vector<Layer> layers; | 47 | std::vector<Layer> layers; |
| 43 | Kernel::SharedPtr<Kernel::Event> vsync_event; | 48 | Kernel::EventPair vsync_event; |
| 44 | }; | 49 | }; |
| 45 | 50 | ||
| 46 | class NVFlinger final { | 51 | class NVFlinger final { |
| @@ -61,7 +66,7 @@ public: | |||
| 61 | u32 GetBufferQueueId(u64 display_id, u64 layer_id); | 66 | u32 GetBufferQueueId(u64 display_id, u64 layer_id); |
| 62 | 67 | ||
| 63 | /// Gets the vsync event for the specified display. | 68 | /// Gets the vsync event for the specified display. |
| 64 | Kernel::SharedPtr<Kernel::Event> GetVsyncEvent(u64 display_id); | 69 | Kernel::SharedPtr<Kernel::ReadableEvent> GetVsyncEvent(u64 display_id); |
| 65 | 70 | ||
| 66 | /// Obtains a buffer queue identified by the id. | 71 | /// Obtains a buffer queue identified by the id. |
| 67 | std::shared_ptr<BufferQueue> GetBufferQueue(u32 id) const; | 72 | std::shared_ptr<BufferQueue> GetBufferQueue(u32 id) const; |
diff --git a/src/core/hle/service/usb/usb.cpp b/src/core/hle/service/usb/usb.cpp index f082a63bc..58a9845fc 100644 --- a/src/core/hle/service/usb/usb.cpp +++ b/src/core/hle/service/usb/usb.cpp | |||
| @@ -73,7 +73,7 @@ public: | |||
| 73 | {3, nullptr, "Populate"}, | 73 | {3, nullptr, "Populate"}, |
| 74 | {4, nullptr, "PostBufferAsync"}, | 74 | {4, nullptr, "PostBufferAsync"}, |
| 75 | {5, nullptr, "GetXferReport"}, | 75 | {5, nullptr, "GetXferReport"}, |
| 76 | {6, nullptr, "Unknown2"}, | 76 | {6, nullptr, "PostBufferMultiAsync"}, |
| 77 | {7, nullptr, "Unknown3"}, | 77 | {7, nullptr, "Unknown3"}, |
| 78 | {8, nullptr, "Unknown4"}, | 78 | {8, nullptr, "Unknown4"}, |
| 79 | }; | 79 | }; |
diff --git a/src/core/hle/service/vi/vi.cpp b/src/core/hle/service/vi/vi.cpp index 412d5b0c9..311b0c765 100644 --- a/src/core/hle/service/vi/vi.cpp +++ b/src/core/hle/service/vi/vi.cpp | |||
| @@ -18,7 +18,8 @@ | |||
| 18 | #include "common/swap.h" | 18 | #include "common/swap.h" |
| 19 | #include "core/core_timing.h" | 19 | #include "core/core_timing.h" |
| 20 | #include "core/hle/ipc_helpers.h" | 20 | #include "core/hle/ipc_helpers.h" |
| 21 | #include "core/hle/kernel/event.h" | 21 | #include "core/hle/kernel/readable_event.h" |
| 22 | #include "core/hle/kernel/writable_event.h" | ||
| 22 | #include "core/hle/service/nvdrv/nvdrv.h" | 23 | #include "core/hle/service/nvdrv/nvdrv.h" |
| 23 | #include "core/hle/service/nvflinger/buffer_queue.h" | 24 | #include "core/hle/service/nvflinger/buffer_queue.h" |
| 24 | #include "core/hle/service/nvflinger/nvflinger.h" | 25 | #include "core/hle/service/nvflinger/nvflinger.h" |
| @@ -549,7 +550,7 @@ private: | |||
| 549 | IPC::ResponseBuilder rb{ctx, 2}; | 550 | IPC::ResponseBuilder rb{ctx, 2}; |
| 550 | rb.Push(RESULT_SUCCESS); | 551 | rb.Push(RESULT_SUCCESS); |
| 551 | }, | 552 | }, |
| 552 | buffer_queue->GetBufferWaitEvent()); | 553 | buffer_queue->GetWritableBufferWaitEvent()); |
| 553 | } | 554 | } |
| 554 | } else if (transaction == TransactionId::RequestBuffer) { | 555 | } else if (transaction == TransactionId::RequestBuffer) { |
| 555 | IGBPRequestBufferRequestParcel request{ctx.ReadBuffer()}; | 556 | IGBPRequestBufferRequestParcel request{ctx.ReadBuffer()}; |
diff --git a/src/video_core/command_processor.cpp b/src/video_core/command_processor.cpp deleted file mode 100644 index 8b9c548cc..000000000 --- a/src/video_core/command_processor.cpp +++ /dev/null | |||
| @@ -1,142 +0,0 @@ | |||
| 1 | // Copyright 2018 yuzu Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include <array> | ||
| 6 | #include <cstddef> | ||
| 7 | #include <memory> | ||
| 8 | #include <utility> | ||
| 9 | #include "common/assert.h" | ||
| 10 | #include "common/logging/log.h" | ||
| 11 | #include "common/microprofile.h" | ||
| 12 | #include "common/vector_math.h" | ||
| 13 | #include "core/memory.h" | ||
| 14 | #include "core/tracer/recorder.h" | ||
| 15 | #include "video_core/command_processor.h" | ||
| 16 | #include "video_core/engines/fermi_2d.h" | ||
| 17 | #include "video_core/engines/kepler_memory.h" | ||
| 18 | #include "video_core/engines/maxwell_3d.h" | ||
| 19 | #include "video_core/engines/maxwell_compute.h" | ||
| 20 | #include "video_core/engines/maxwell_dma.h" | ||
| 21 | #include "video_core/gpu.h" | ||
| 22 | #include "video_core/renderer_base.h" | ||
| 23 | #include "video_core/video_core.h" | ||
| 24 | |||
| 25 | namespace Tegra { | ||
| 26 | |||
| 27 | enum class BufferMethods { | ||
| 28 | BindObject = 0, | ||
| 29 | CountBufferMethods = 0x40, | ||
| 30 | }; | ||
| 31 | |||
| 32 | MICROPROFILE_DEFINE(ProcessCommandLists, "GPU", "Execute command buffer", MP_RGB(128, 128, 192)); | ||
| 33 | |||
| 34 | void GPU::ProcessCommandLists(const std::vector<CommandListHeader>& commands) { | ||
| 35 | MICROPROFILE_SCOPE(ProcessCommandLists); | ||
| 36 | |||
| 37 | // On entering GPU code, assume all memory may be touched by the ARM core. | ||
| 38 | maxwell_3d->dirty_flags.OnMemoryWrite(); | ||
| 39 | |||
| 40 | auto WriteReg = [this](u32 method, u32 subchannel, u32 value, u32 remaining_params) { | ||
| 41 | LOG_TRACE(HW_GPU, | ||
| 42 | "Processing method {:08X} on subchannel {} value " | ||
| 43 | "{:08X} remaining params {}", | ||
| 44 | method, subchannel, value, remaining_params); | ||
| 45 | |||
| 46 | ASSERT(subchannel < bound_engines.size()); | ||
| 47 | |||
| 48 | if (method == static_cast<u32>(BufferMethods::BindObject)) { | ||
| 49 | // Bind the current subchannel to the desired engine id. | ||
| 50 | LOG_DEBUG(HW_GPU, "Binding subchannel {} to engine {}", subchannel, value); | ||
| 51 | bound_engines[subchannel] = static_cast<EngineID>(value); | ||
| 52 | return; | ||
| 53 | } | ||
| 54 | |||
| 55 | if (method < static_cast<u32>(BufferMethods::CountBufferMethods)) { | ||
| 56 | // TODO(Subv): Research and implement these methods. | ||
| 57 | LOG_ERROR(HW_GPU, "Special buffer methods other than Bind are not implemented"); | ||
| 58 | return; | ||
| 59 | } | ||
| 60 | |||
| 61 | const EngineID engine = bound_engines[subchannel]; | ||
| 62 | |||
| 63 | switch (engine) { | ||
| 64 | case EngineID::FERMI_TWOD_A: | ||
| 65 | fermi_2d->WriteReg(method, value); | ||
| 66 | break; | ||
| 67 | case EngineID::MAXWELL_B: | ||
| 68 | maxwell_3d->WriteReg(method, value, remaining_params); | ||
| 69 | break; | ||
| 70 | case EngineID::MAXWELL_COMPUTE_B: | ||
| 71 | maxwell_compute->WriteReg(method, value); | ||
| 72 | break; | ||
| 73 | case EngineID::MAXWELL_DMA_COPY_A: | ||
| 74 | maxwell_dma->WriteReg(method, value); | ||
| 75 | break; | ||
| 76 | case EngineID::KEPLER_INLINE_TO_MEMORY_B: | ||
| 77 | kepler_memory->WriteReg(method, value); | ||
| 78 | break; | ||
| 79 | default: | ||
| 80 | UNIMPLEMENTED_MSG("Unimplemented engine"); | ||
| 81 | } | ||
| 82 | }; | ||
| 83 | |||
| 84 | for (auto entry : commands) { | ||
| 85 | Tegra::GPUVAddr address = entry.Address(); | ||
| 86 | u32 size = entry.sz; | ||
| 87 | const std::optional<VAddr> head_address = memory_manager->GpuToCpuAddress(address); | ||
| 88 | VAddr current_addr = *head_address; | ||
| 89 | while (current_addr < *head_address + size * sizeof(CommandHeader)) { | ||
| 90 | const CommandHeader header = {Memory::Read32(current_addr)}; | ||
| 91 | current_addr += sizeof(u32); | ||
| 92 | |||
| 93 | switch (header.mode.Value()) { | ||
| 94 | case SubmissionMode::IncreasingOld: | ||
| 95 | case SubmissionMode::Increasing: { | ||
| 96 | // Increase the method value with each argument. | ||
| 97 | for (unsigned i = 0; i < header.arg_count; ++i) { | ||
| 98 | WriteReg(header.method + i, header.subchannel, Memory::Read32(current_addr), | ||
| 99 | header.arg_count - i - 1); | ||
| 100 | current_addr += sizeof(u32); | ||
| 101 | } | ||
| 102 | break; | ||
| 103 | } | ||
| 104 | case SubmissionMode::NonIncreasingOld: | ||
| 105 | case SubmissionMode::NonIncreasing: { | ||
| 106 | // Use the same method value for all arguments. | ||
| 107 | for (unsigned i = 0; i < header.arg_count; ++i) { | ||
| 108 | WriteReg(header.method, header.subchannel, Memory::Read32(current_addr), | ||
| 109 | header.arg_count - i - 1); | ||
| 110 | current_addr += sizeof(u32); | ||
| 111 | } | ||
| 112 | break; | ||
| 113 | } | ||
| 114 | case SubmissionMode::IncreaseOnce: { | ||
| 115 | ASSERT(header.arg_count.Value() >= 1); | ||
| 116 | |||
| 117 | // Use the original method for the first argument and then the next method for all | ||
| 118 | // other arguments. | ||
| 119 | WriteReg(header.method, header.subchannel, Memory::Read32(current_addr), | ||
| 120 | header.arg_count - 1); | ||
| 121 | current_addr += sizeof(u32); | ||
| 122 | |||
| 123 | for (unsigned i = 1; i < header.arg_count; ++i) { | ||
| 124 | WriteReg(header.method + 1, header.subchannel, Memory::Read32(current_addr), | ||
| 125 | header.arg_count - i - 1); | ||
| 126 | current_addr += sizeof(u32); | ||
| 127 | } | ||
| 128 | break; | ||
| 129 | } | ||
| 130 | case SubmissionMode::Inline: { | ||
| 131 | // The register value is stored in the bits 16-28 as an immediate | ||
| 132 | WriteReg(header.method, header.subchannel, header.inline_data, 0); | ||
| 133 | break; | ||
| 134 | } | ||
| 135 | default: | ||
| 136 | UNIMPLEMENTED(); | ||
| 137 | } | ||
| 138 | } | ||
| 139 | } | ||
| 140 | } | ||
| 141 | |||
| 142 | } // namespace Tegra | ||
diff --git a/src/video_core/gpu.cpp b/src/video_core/gpu.cpp index fd1242333..88c45a423 100644 --- a/src/video_core/gpu.cpp +++ b/src/video_core/gpu.cpp | |||
| @@ -141,6 +141,12 @@ void GPU::CallMethod(const MethodCall& method_call) { | |||
| 141 | return; | 141 | return; |
| 142 | } | 142 | } |
| 143 | 143 | ||
| 144 | if (method_call.method < static_cast<u32>(BufferMethods::CountBufferMethods)) { | ||
| 145 | // TODO(Subv): Research and implement these methods. | ||
| 146 | LOG_ERROR(HW_GPU, "Special buffer methods other than Bind are not implemented"); | ||
| 147 | return; | ||
| 148 | } | ||
| 149 | |||
| 144 | const EngineID engine = bound_engines[method_call.subchannel]; | 150 | const EngineID engine = bound_engines[method_call.subchannel]; |
| 145 | 151 | ||
| 146 | switch (engine) { | 152 | switch (engine) { |
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp index 0c1632bd1..8d68156bf 100644 --- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp +++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp | |||
| @@ -201,14 +201,53 @@ private: | |||
| 201 | } | 201 | } |
| 202 | }; | 202 | }; |
| 203 | 203 | ||
| 204 | template <typename T> | ||
| 205 | class ShaderScopedScope { | ||
| 206 | public: | ||
| 207 | explicit ShaderScopedScope(T& writer, std::string_view begin_expr, std::string end_expr) | ||
| 208 | : writer(writer), end_expr(std::move(end_expr)) { | ||
| 209 | |||
| 210 | if (begin_expr.empty()) { | ||
| 211 | writer.AddLine('{'); | ||
| 212 | } else { | ||
| 213 | writer.AddExpression(begin_expr); | ||
| 214 | writer.AddLine(" {"); | ||
| 215 | } | ||
| 216 | ++writer.scope; | ||
| 217 | } | ||
| 218 | |||
| 219 | ShaderScopedScope(const ShaderScopedScope&) = delete; | ||
| 220 | |||
| 221 | ~ShaderScopedScope() { | ||
| 222 | --writer.scope; | ||
| 223 | if (end_expr.empty()) { | ||
| 224 | writer.AddLine('}'); | ||
| 225 | } else { | ||
| 226 | writer.AddExpression("} "); | ||
| 227 | writer.AddExpression(end_expr); | ||
| 228 | writer.AddLine(';'); | ||
| 229 | } | ||
| 230 | } | ||
| 231 | |||
| 232 | ShaderScopedScope& operator=(const ShaderScopedScope&) = delete; | ||
| 233 | |||
| 234 | private: | ||
| 235 | T& writer; | ||
| 236 | std::string end_expr; | ||
| 237 | }; | ||
| 238 | |||
| 204 | class ShaderWriter { | 239 | class ShaderWriter { |
| 205 | public: | 240 | public: |
| 206 | void AddLine(std::string_view text) { | 241 | void AddExpression(std::string_view text) { |
| 207 | DEBUG_ASSERT(scope >= 0); | 242 | DEBUG_ASSERT(scope >= 0); |
| 208 | if (!text.empty()) { | 243 | if (!text.empty()) { |
| 209 | AppendIndentation(); | 244 | AppendIndentation(); |
| 210 | } | 245 | } |
| 211 | shader_source += text; | 246 | shader_source += text; |
| 247 | } | ||
| 248 | |||
| 249 | void AddLine(std::string_view text) { | ||
| 250 | AddExpression(text); | ||
| 212 | AddNewLine(); | 251 | AddNewLine(); |
| 213 | } | 252 | } |
| 214 | 253 | ||
| @@ -228,6 +267,11 @@ public: | |||
| 228 | return std::move(shader_source); | 267 | return std::move(shader_source); |
| 229 | } | 268 | } |
| 230 | 269 | ||
| 270 | ShaderScopedScope<ShaderWriter> Scope(std::string_view begin_expr = {}, | ||
| 271 | std::string end_expr = {}) { | ||
| 272 | return ShaderScopedScope(*this, begin_expr, end_expr); | ||
| 273 | } | ||
| 274 | |||
| 231 | int scope = 0; | 275 | int scope = 0; |
| 232 | 276 | ||
| 233 | private: | 277 | private: |
| @@ -311,7 +355,7 @@ public: | |||
| 311 | // Default - do nothing | 355 | // Default - do nothing |
| 312 | return value; | 356 | return value; |
| 313 | default: | 357 | default: |
| 314 | UNIMPLEMENTED_MSG("Unimplemented conversion size: {}", static_cast<u32>(size)); | 358 | UNREACHABLE_MSG("Unimplemented conversion size: {}", static_cast<u32>(size)); |
| 315 | } | 359 | } |
| 316 | } | 360 | } |
| 317 | 361 | ||
| @@ -816,14 +860,12 @@ private: | |||
| 816 | } | 860 | } |
| 817 | 861 | ||
| 818 | if (precise && stage != Maxwell3D::Regs::ShaderStage::Fragment) { | 862 | if (precise && stage != Maxwell3D::Regs::ShaderStage::Fragment) { |
| 819 | shader.AddLine('{'); | 863 | const auto scope = shader.Scope(); |
| 820 | ++shader.scope; | 864 | |
| 821 | // This avoids optimizations of constant propagation and keeps the code as the original | 865 | // This avoids optimizations of constant propagation and keeps the code as the original |
| 822 | // Sadly using the precise keyword causes "linking" errors on fragment shaders. | 866 | // Sadly using the precise keyword causes "linking" errors on fragment shaders. |
| 823 | shader.AddLine("precise float tmp = " + src + ';'); | 867 | shader.AddLine("precise float tmp = " + src + ';'); |
| 824 | shader.AddLine(dest + " = tmp;"); | 868 | shader.AddLine(dest + " = tmp;"); |
| 825 | --shader.scope; | ||
| 826 | shader.AddLine('}'); | ||
| 827 | } else { | 869 | } else { |
| 828 | shader.AddLine(dest + " = " + src + ';'); | 870 | shader.AddLine(dest + " = " + src + ';'); |
| 829 | } | 871 | } |
| @@ -1301,15 +1343,7 @@ private: | |||
| 1301 | regs.SetRegisterToInteger(dest, true, 0, result, 1, 1); | 1343 | regs.SetRegisterToInteger(dest, true, 0, result, 1, 1); |
| 1302 | } | 1344 | } |
| 1303 | 1345 | ||
| 1304 | void WriteTexsInstruction(const Instruction& instr, const std::string& coord, | 1346 | void WriteTexsInstruction(const Instruction& instr, const std::string& texture) { |
| 1305 | const std::string& texture) { | ||
| 1306 | // Add an extra scope and declare the texture coords inside to prevent | ||
| 1307 | // overwriting them in case they are used as outputs of the texs instruction. | ||
| 1308 | shader.AddLine('{'); | ||
| 1309 | ++shader.scope; | ||
| 1310 | shader.AddLine(coord); | ||
| 1311 | shader.AddLine("vec4 texture_tmp = " + texture + ';'); | ||
| 1312 | |||
| 1313 | // TEXS has two destination registers and a swizzle. The first two elements in the swizzle | 1347 | // TEXS has two destination registers and a swizzle. The first two elements in the swizzle |
| 1314 | // go into gpr0+0 and gpr0+1, and the rest goes into gpr28+0 and gpr28+1 | 1348 | // go into gpr0+0 and gpr0+1, and the rest goes into gpr28+0 and gpr28+1 |
| 1315 | 1349 | ||
| @@ -1321,19 +1355,17 @@ private: | |||
| 1321 | 1355 | ||
| 1322 | if (written_components < 2) { | 1356 | if (written_components < 2) { |
| 1323 | // Write the first two swizzle components to gpr0 and gpr0+1 | 1357 | // Write the first two swizzle components to gpr0 and gpr0+1 |
| 1324 | regs.SetRegisterToFloat(instr.gpr0, component, "texture_tmp", 1, 4, false, | 1358 | regs.SetRegisterToFloat(instr.gpr0, component, texture, 1, 4, false, |
| 1325 | written_components % 2); | 1359 | written_components % 2); |
| 1326 | } else { | 1360 | } else { |
| 1327 | ASSERT(instr.texs.HasTwoDestinations()); | 1361 | ASSERT(instr.texs.HasTwoDestinations()); |
| 1328 | // Write the rest of the swizzle components to gpr28 and gpr28+1 | 1362 | // Write the rest of the swizzle components to gpr28 and gpr28+1 |
| 1329 | regs.SetRegisterToFloat(instr.gpr28, component, "texture_tmp", 1, 4, false, | 1363 | regs.SetRegisterToFloat(instr.gpr28, component, texture, 1, 4, false, |
| 1330 | written_components % 2); | 1364 | written_components % 2); |
| 1331 | } | 1365 | } |
| 1332 | 1366 | ||
| 1333 | ++written_components; | 1367 | ++written_components; |
| 1334 | } | 1368 | } |
| 1335 | --shader.scope; | ||
| 1336 | shader.AddLine('}'); | ||
| 1337 | } | 1369 | } |
| 1338 | 1370 | ||
| 1339 | static u32 TextureCoordinates(Tegra::Shader::TextureType texture_type) { | 1371 | static u32 TextureCoordinates(Tegra::Shader::TextureType texture_type) { |
| @@ -1356,12 +1388,10 @@ private: | |||
| 1356 | * top. | 1388 | * top. |
| 1357 | */ | 1389 | */ |
| 1358 | void EmitPushToFlowStack(u32 target) { | 1390 | void EmitPushToFlowStack(u32 target) { |
| 1359 | shader.AddLine('{'); | 1391 | const auto scope = shader.Scope(); |
| 1360 | ++shader.scope; | 1392 | |
| 1361 | shader.AddLine("flow_stack[flow_stack_top] = " + std::to_string(target) + "u;"); | 1393 | shader.AddLine("flow_stack[flow_stack_top] = " + std::to_string(target) + "u;"); |
| 1362 | shader.AddLine("flow_stack_top++;"); | 1394 | shader.AddLine("flow_stack_top++;"); |
| 1363 | --shader.scope; | ||
| 1364 | shader.AddLine('}'); | ||
| 1365 | } | 1395 | } |
| 1366 | 1396 | ||
| 1367 | /* | 1397 | /* |
| @@ -1369,13 +1399,11 @@ private: | |||
| 1369 | * popped address and decrementing the stack top. | 1399 | * popped address and decrementing the stack top. |
| 1370 | */ | 1400 | */ |
| 1371 | void EmitPopFromFlowStack() { | 1401 | void EmitPopFromFlowStack() { |
| 1372 | shader.AddLine('{'); | 1402 | const auto scope = shader.Scope(); |
| 1373 | ++shader.scope; | 1403 | |
| 1374 | shader.AddLine("flow_stack_top--;"); | 1404 | shader.AddLine("flow_stack_top--;"); |
| 1375 | shader.AddLine("jmp_to = flow_stack[flow_stack_top];"); | 1405 | shader.AddLine("jmp_to = flow_stack[flow_stack_top];"); |
| 1376 | shader.AddLine("break;"); | 1406 | shader.AddLine("break;"); |
| 1377 | --shader.scope; | ||
| 1378 | shader.AddLine('}'); | ||
| 1379 | } | 1407 | } |
| 1380 | 1408 | ||
| 1381 | /// Writes the output values from a fragment shader to the corresponding GLSL output variables. | 1409 | /// Writes the output values from a fragment shader to the corresponding GLSL output variables. |
| @@ -1487,6 +1515,161 @@ private: | |||
| 1487 | } | 1515 | } |
| 1488 | } | 1516 | } |
| 1489 | 1517 | ||
| 1518 | std::pair<size_t, std::string> ValidateAndGetCoordinateElement( | ||
| 1519 | const Tegra::Shader::TextureType texture_type, const bool depth_compare, | ||
| 1520 | const bool is_array, const bool lod_bias_enabled, size_t max_coords, size_t max_inputs) { | ||
| 1521 | const size_t coord_count = TextureCoordinates(texture_type); | ||
| 1522 | |||
| 1523 | size_t total_coord_count = coord_count + (is_array ? 1 : 0) + (depth_compare ? 1 : 0); | ||
| 1524 | const size_t total_reg_count = total_coord_count + (lod_bias_enabled ? 1 : 0); | ||
| 1525 | if (total_coord_count > max_coords || total_reg_count > max_inputs) { | ||
| 1526 | UNIMPLEMENTED_MSG("Unsupported Texture operation"); | ||
| 1527 | total_coord_count = std::min(total_coord_count, max_coords); | ||
| 1528 | } | ||
| 1529 | // 1D.DC opengl is using a vec3 but 2nd component is ignored later. | ||
| 1530 | total_coord_count += | ||
| 1531 | (depth_compare && !is_array && texture_type == Tegra::Shader::TextureType::Texture1D) | ||
| 1532 | ? 1 | ||
| 1533 | : 0; | ||
| 1534 | |||
| 1535 | constexpr std::array<const char*, 5> coord_container{ | ||
| 1536 | {"", "float coord = (", "vec2 coord = vec2(", "vec3 coord = vec3(", | ||
| 1537 | "vec4 coord = vec4("}}; | ||
| 1538 | |||
| 1539 | return std::pair<size_t, std::string>(coord_count, coord_container[total_coord_count]); | ||
| 1540 | } | ||
| 1541 | |||
| 1542 | std::string GetTextureCode(const Tegra::Shader::Instruction& instr, | ||
| 1543 | const Tegra::Shader::TextureType texture_type, | ||
| 1544 | const Tegra::Shader::TextureProcessMode process_mode, | ||
| 1545 | const bool depth_compare, const bool is_array, | ||
| 1546 | const size_t bias_offset) { | ||
| 1547 | |||
| 1548 | if ((texture_type == Tegra::Shader::TextureType::Texture3D && | ||
| 1549 | (is_array || depth_compare)) || | ||
| 1550 | (texture_type == Tegra::Shader::TextureType::TextureCube && is_array && | ||
| 1551 | depth_compare)) { | ||
| 1552 | UNIMPLEMENTED_MSG("This method is not supported."); | ||
| 1553 | } | ||
| 1554 | |||
| 1555 | const std::string sampler = | ||
| 1556 | GetSampler(instr.sampler, texture_type, is_array, depth_compare); | ||
| 1557 | |||
| 1558 | const bool lod_needed = process_mode == Tegra::Shader::TextureProcessMode::LZ || | ||
| 1559 | process_mode == Tegra::Shader::TextureProcessMode::LL || | ||
| 1560 | process_mode == Tegra::Shader::TextureProcessMode::LLA; | ||
| 1561 | |||
| 1562 | const bool gl_lod_supported = !( | ||
| 1563 | (texture_type == Tegra::Shader::TextureType::Texture2D && is_array && depth_compare) || | ||
| 1564 | (texture_type == Tegra::Shader::TextureType::TextureCube && !is_array && | ||
| 1565 | depth_compare)); | ||
| 1566 | |||
| 1567 | const std::string read_method = lod_needed && gl_lod_supported ? "textureLod(" : "texture("; | ||
| 1568 | std::string texture = read_method + sampler + ", coord"; | ||
| 1569 | |||
| 1570 | if (process_mode != Tegra::Shader::TextureProcessMode::None) { | ||
| 1571 | if (process_mode == Tegra::Shader::TextureProcessMode::LZ) { | ||
| 1572 | if (gl_lod_supported) { | ||
| 1573 | texture += ", 0"; | ||
| 1574 | } else { | ||
| 1575 | // Lod 0 is emulated by a big negative bias | ||
| 1576 | // in scenarios that are not supported by glsl | ||
| 1577 | texture += ", -1000"; | ||
| 1578 | } | ||
| 1579 | } else { | ||
| 1580 | // If present, lod or bias are always stored in the register indexed by the | ||
| 1581 | // gpr20 | ||
| 1582 | // field with an offset depending on the usage of the other registers | ||
| 1583 | texture += ',' + regs.GetRegisterAsFloat(instr.gpr20.Value() + bias_offset); | ||
| 1584 | } | ||
| 1585 | } | ||
| 1586 | texture += ")"; | ||
| 1587 | return texture; | ||
| 1588 | } | ||
| 1589 | |||
| 1590 | std::pair<std::string, std::string> GetTEXCode( | ||
| 1591 | const Instruction& instr, const Tegra::Shader::TextureType texture_type, | ||
| 1592 | const Tegra::Shader::TextureProcessMode process_mode, const bool depth_compare, | ||
| 1593 | const bool is_array) { | ||
| 1594 | const bool lod_bias_enabled = (process_mode != Tegra::Shader::TextureProcessMode::None && | ||
| 1595 | process_mode != Tegra::Shader::TextureProcessMode::LZ); | ||
| 1596 | |||
| 1597 | const auto [coord_count, coord_dcl] = ValidateAndGetCoordinateElement( | ||
| 1598 | texture_type, depth_compare, is_array, lod_bias_enabled, 4, 5); | ||
| 1599 | // If enabled arrays index is always stored in the gpr8 field | ||
| 1600 | const u64 array_register = instr.gpr8.Value(); | ||
| 1601 | // First coordinate index is the gpr8 or gpr8 + 1 when arrays are used | ||
| 1602 | const u64 coord_register = array_register + (is_array ? 1 : 0); | ||
| 1603 | |||
| 1604 | std::string coord = coord_dcl; | ||
| 1605 | for (size_t i = 0; i < coord_count;) { | ||
| 1606 | coord += regs.GetRegisterAsFloat(coord_register + i); | ||
| 1607 | ++i; | ||
| 1608 | if (i != coord_count) { | ||
| 1609 | coord += ','; | ||
| 1610 | } | ||
| 1611 | } | ||
| 1612 | // 1D.DC in opengl the 2nd component is ignored. | ||
| 1613 | if (depth_compare && !is_array && texture_type == Tegra::Shader::TextureType::Texture1D) { | ||
| 1614 | coord += ",0.0"; | ||
| 1615 | } | ||
| 1616 | if (depth_compare) { | ||
| 1617 | // Depth is always stored in the register signaled by gpr20 | ||
| 1618 | // or in the next register if lod or bias are used | ||
| 1619 | const u64 depth_register = instr.gpr20.Value() + (lod_bias_enabled ? 1 : 0); | ||
| 1620 | coord += ',' + regs.GetRegisterAsFloat(depth_register); | ||
| 1621 | } | ||
| 1622 | if (is_array) { | ||
| 1623 | coord += ',' + regs.GetRegisterAsInteger(array_register); | ||
| 1624 | } | ||
| 1625 | coord += ");"; | ||
| 1626 | return std::make_pair( | ||
| 1627 | coord, GetTextureCode(instr, texture_type, process_mode, depth_compare, is_array, 0)); | ||
| 1628 | } | ||
| 1629 | |||
| 1630 | std::pair<std::string, std::string> GetTEXSCode( | ||
| 1631 | const Instruction& instr, const Tegra::Shader::TextureType texture_type, | ||
| 1632 | const Tegra::Shader::TextureProcessMode process_mode, const bool depth_compare, | ||
| 1633 | const bool is_array) { | ||
| 1634 | const bool lod_bias_enabled = (process_mode != Tegra::Shader::TextureProcessMode::None && | ||
| 1635 | process_mode != Tegra::Shader::TextureProcessMode::LZ); | ||
| 1636 | |||
| 1637 | const auto [coord_count, coord_dcl] = ValidateAndGetCoordinateElement( | ||
| 1638 | texture_type, depth_compare, is_array, lod_bias_enabled, 4, 4); | ||
| 1639 | // If enabled arrays index is always stored in the gpr8 field | ||
| 1640 | const u64 array_register = instr.gpr8.Value(); | ||
| 1641 | // First coordinate index is stored in gpr8 field or (gpr8 + 1) when arrays are used | ||
| 1642 | const u64 coord_register = array_register + (is_array ? 1 : 0); | ||
| 1643 | const u64 last_coord_register = | ||
| 1644 | (is_array || !(lod_bias_enabled || depth_compare) || (coord_count > 2)) | ||
| 1645 | ? static_cast<u64>(instr.gpr20.Value()) | ||
| 1646 | : coord_register + 1; | ||
| 1647 | |||
| 1648 | std::string coord = coord_dcl; | ||
| 1649 | for (size_t i = 0; i < coord_count; ++i) { | ||
| 1650 | const bool last = (i == (coord_count - 1)) && (coord_count > 1); | ||
| 1651 | coord += regs.GetRegisterAsFloat(last ? last_coord_register : coord_register + i); | ||
| 1652 | if (!last) { | ||
| 1653 | coord += ','; | ||
| 1654 | } | ||
| 1655 | } | ||
| 1656 | |||
| 1657 | if (depth_compare) { | ||
| 1658 | // Depth is always stored in the register signaled by gpr20 | ||
| 1659 | // or in the next register if lod or bias are used | ||
| 1660 | const u64 depth_register = instr.gpr20.Value() + (lod_bias_enabled ? 1 : 0); | ||
| 1661 | coord += ',' + regs.GetRegisterAsFloat(depth_register); | ||
| 1662 | } | ||
| 1663 | if (is_array) { | ||
| 1664 | coord += ',' + regs.GetRegisterAsInteger(array_register); | ||
| 1665 | } | ||
| 1666 | coord += ");"; | ||
| 1667 | |||
| 1668 | return std::make_pair(coord, | ||
| 1669 | GetTextureCode(instr, texture_type, process_mode, depth_compare, | ||
| 1670 | is_array, (coord_count > 2 ? 1 : 0))); | ||
| 1671 | } | ||
| 1672 | |||
| 1490 | /** | 1673 | /** |
| 1491 | * Compiles a single instruction from Tegra to GLSL. | 1674 | * Compiles a single instruction from Tegra to GLSL. |
| 1492 | * @param offset the offset of the Tegra shader instruction. | 1675 | * @param offset the offset of the Tegra shader instruction. |
| @@ -2287,8 +2470,7 @@ private: | |||
| 2287 | UNIMPLEMENTED_IF(instr.conversion.selector); | 2470 | UNIMPLEMENTED_IF(instr.conversion.selector); |
| 2288 | UNIMPLEMENTED_IF_MSG(instr.generates_cc, | 2471 | UNIMPLEMENTED_IF_MSG(instr.generates_cc, |
| 2289 | "Condition codes generation in I2F is not implemented"); | 2472 | "Condition codes generation in I2F is not implemented"); |
| 2290 | 2473 | std::string op_a; | |
| 2291 | std::string op_a{}; | ||
| 2292 | 2474 | ||
| 2293 | if (instr.is_b_gpr) { | 2475 | if (instr.is_b_gpr) { |
| 2294 | op_a = | 2476 | op_a = |
| @@ -2444,10 +2626,7 @@ private: | |||
| 2444 | case OpCode::Id::LD_C: { | 2626 | case OpCode::Id::LD_C: { |
| 2445 | UNIMPLEMENTED_IF(instr.ld_c.unknown != 0); | 2627 | UNIMPLEMENTED_IF(instr.ld_c.unknown != 0); |
| 2446 | 2628 | ||
| 2447 | // Add an extra scope and declare the index register inside to prevent | 2629 | const auto scope = shader.Scope(); |
| 2448 | // overwriting it in case it is used as an output of the LD instruction. | ||
| 2449 | shader.AddLine("{"); | ||
| 2450 | ++shader.scope; | ||
| 2451 | 2630 | ||
| 2452 | shader.AddLine("uint index = (" + regs.GetRegisterAsInteger(instr.gpr8, 0, false) + | 2631 | shader.AddLine("uint index = (" + regs.GetRegisterAsInteger(instr.gpr8, 0, false) + |
| 2453 | " / 4) & (MAX_CONSTBUFFER_ELEMENTS - 1);"); | 2632 | " / 4) & (MAX_CONSTBUFFER_ELEMENTS - 1);"); |
| @@ -2473,19 +2652,13 @@ private: | |||
| 2473 | UNIMPLEMENTED_MSG("Unhandled type: {}", | 2652 | UNIMPLEMENTED_MSG("Unhandled type: {}", |
| 2474 | static_cast<unsigned>(instr.ld_c.type.Value())); | 2653 | static_cast<unsigned>(instr.ld_c.type.Value())); |
| 2475 | } | 2654 | } |
| 2476 | |||
| 2477 | --shader.scope; | ||
| 2478 | shader.AddLine("}"); | ||
| 2479 | break; | 2655 | break; |
| 2480 | } | 2656 | } |
| 2481 | case OpCode::Id::LD_L: { | 2657 | case OpCode::Id::LD_L: { |
| 2482 | UNIMPLEMENTED_IF_MSG(instr.ld_l.unknown == 1, "LD_L Unhandled mode: {}", | 2658 | UNIMPLEMENTED_IF_MSG(instr.ld_l.unknown == 1, "LD_L Unhandled mode: {}", |
| 2483 | static_cast<unsigned>(instr.ld_l.unknown.Value())); | 2659 | static_cast<unsigned>(instr.ld_l.unknown.Value())); |
| 2484 | 2660 | ||
| 2485 | // Add an extra scope and declare the index register inside to prevent | 2661 | const auto scope = shader.Scope(); |
| 2486 | // overwriting it in case it is used as an output of the LD instruction. | ||
| 2487 | shader.AddLine('{'); | ||
| 2488 | ++shader.scope; | ||
| 2489 | 2662 | ||
| 2490 | std::string op = '(' + regs.GetRegisterAsInteger(instr.gpr8, 0, false) + " + " + | 2663 | std::string op = '(' + regs.GetRegisterAsInteger(instr.gpr8, 0, false) + " + " + |
| 2491 | std::to_string(instr.smem_imm.Value()) + ')'; | 2664 | std::to_string(instr.smem_imm.Value()) + ')'; |
| @@ -2502,9 +2675,6 @@ private: | |||
| 2502 | UNIMPLEMENTED_MSG("LD_L Unhandled type: {}", | 2675 | UNIMPLEMENTED_MSG("LD_L Unhandled type: {}", |
| 2503 | static_cast<unsigned>(instr.ldst_sl.type.Value())); | 2676 | static_cast<unsigned>(instr.ldst_sl.type.Value())); |
| 2504 | } | 2677 | } |
| 2505 | |||
| 2506 | --shader.scope; | ||
| 2507 | shader.AddLine('}'); | ||
| 2508 | break; | 2678 | break; |
| 2509 | } | 2679 | } |
| 2510 | case OpCode::Id::ST_A: { | 2680 | case OpCode::Id::ST_A: { |
| @@ -2539,10 +2709,7 @@ private: | |||
| 2539 | UNIMPLEMENTED_IF_MSG(instr.st_l.unknown == 0, "ST_L Unhandled mode: {}", | 2709 | UNIMPLEMENTED_IF_MSG(instr.st_l.unknown == 0, "ST_L Unhandled mode: {}", |
| 2540 | static_cast<unsigned>(instr.st_l.unknown.Value())); | 2710 | static_cast<unsigned>(instr.st_l.unknown.Value())); |
| 2541 | 2711 | ||
| 2542 | // Add an extra scope and declare the index register inside to prevent | 2712 | const auto scope = shader.Scope(); |
| 2543 | // overwriting it in case it is used as an output of the LD instruction. | ||
| 2544 | shader.AddLine('{'); | ||
| 2545 | ++shader.scope; | ||
| 2546 | 2713 | ||
| 2547 | std::string op = '(' + regs.GetRegisterAsInteger(instr.gpr8, 0, false) + " + " + | 2714 | std::string op = '(' + regs.GetRegisterAsInteger(instr.gpr8, 0, false) + " + " + |
| 2548 | std::to_string(instr.smem_imm.Value()) + ')'; | 2715 | std::to_string(instr.smem_imm.Value()) + ')'; |
| @@ -2557,179 +2724,28 @@ private: | |||
| 2557 | UNIMPLEMENTED_MSG("ST_L Unhandled type: {}", | 2724 | UNIMPLEMENTED_MSG("ST_L Unhandled type: {}", |
| 2558 | static_cast<unsigned>(instr.ldst_sl.type.Value())); | 2725 | static_cast<unsigned>(instr.ldst_sl.type.Value())); |
| 2559 | } | 2726 | } |
| 2560 | |||
| 2561 | --shader.scope; | ||
| 2562 | shader.AddLine('}'); | ||
| 2563 | break; | 2727 | break; |
| 2564 | } | 2728 | } |
| 2565 | case OpCode::Id::TEX: { | 2729 | case OpCode::Id::TEX: { |
| 2566 | Tegra::Shader::TextureType texture_type{instr.tex.texture_type}; | 2730 | Tegra::Shader::TextureType texture_type{instr.tex.texture_type}; |
| 2567 | std::string coord; | ||
| 2568 | const bool is_array = instr.tex.array != 0; | 2731 | const bool is_array = instr.tex.array != 0; |
| 2569 | 2732 | const bool depth_compare = | |
| 2733 | instr.tex.UsesMiscMode(Tegra::Shader::TextureMiscMode::DC); | ||
| 2734 | const auto process_mode = instr.tex.GetTextureProcessMode(); | ||
| 2570 | UNIMPLEMENTED_IF_MSG(instr.tex.UsesMiscMode(Tegra::Shader::TextureMiscMode::NODEP), | 2735 | UNIMPLEMENTED_IF_MSG(instr.tex.UsesMiscMode(Tegra::Shader::TextureMiscMode::NODEP), |
| 2571 | "NODEP is not implemented"); | 2736 | "NODEP is not implemented"); |
| 2572 | UNIMPLEMENTED_IF_MSG(instr.tex.UsesMiscMode(Tegra::Shader::TextureMiscMode::AOFFI), | 2737 | UNIMPLEMENTED_IF_MSG(instr.tex.UsesMiscMode(Tegra::Shader::TextureMiscMode::AOFFI), |
| 2573 | "AOFFI is not implemented"); | 2738 | "AOFFI is not implemented"); |
| 2574 | 2739 | ||
| 2575 | const bool depth_compare = | 2740 | const auto [coord, texture] = |
| 2576 | instr.tex.UsesMiscMode(Tegra::Shader::TextureMiscMode::DC); | 2741 | GetTEXCode(instr, texture_type, process_mode, depth_compare, is_array); |
| 2577 | u32 num_coordinates = TextureCoordinates(texture_type); | ||
| 2578 | u32 start_index = 0; | ||
| 2579 | std::string array_elem; | ||
| 2580 | if (is_array) { | ||
| 2581 | array_elem = regs.GetRegisterAsInteger(instr.gpr8); | ||
| 2582 | start_index = 1; | ||
| 2583 | } | ||
| 2584 | const auto process_mode = instr.tex.GetTextureProcessMode(); | ||
| 2585 | u32 start_index_b = 0; | ||
| 2586 | std::string lod_value; | ||
| 2587 | if (process_mode != Tegra::Shader::TextureProcessMode::LZ && | ||
| 2588 | process_mode != Tegra::Shader::TextureProcessMode::None) { | ||
| 2589 | start_index_b = 1; | ||
| 2590 | lod_value = regs.GetRegisterAsFloat(instr.gpr20); | ||
| 2591 | } | ||
| 2592 | |||
| 2593 | std::string depth_value; | ||
| 2594 | if (depth_compare) { | ||
| 2595 | depth_value = regs.GetRegisterAsFloat(instr.gpr20.Value() + start_index_b); | ||
| 2596 | } | ||
| 2597 | |||
| 2598 | bool depth_compare_extra = false; | ||
| 2599 | |||
| 2600 | switch (num_coordinates) { | ||
| 2601 | case 1: { | ||
| 2602 | const std::string x = regs.GetRegisterAsFloat(instr.gpr8.Value() + start_index); | ||
| 2603 | if (is_array) { | ||
| 2604 | if (depth_compare) { | ||
| 2605 | coord = "vec3 coords = vec3(" + x + ", " + depth_value + ", " + | ||
| 2606 | array_elem + ");"; | ||
| 2607 | } else { | ||
| 2608 | coord = "vec2 coords = vec2(" + x + ", " + array_elem + ");"; | ||
| 2609 | } | ||
| 2610 | } else { | ||
| 2611 | if (depth_compare) { | ||
| 2612 | coord = "vec2 coords = vec2(" + x + ", " + depth_value + ");"; | ||
| 2613 | } else { | ||
| 2614 | coord = "float coords = " + x + ';'; | ||
| 2615 | } | ||
| 2616 | } | ||
| 2617 | break; | ||
| 2618 | } | ||
| 2619 | case 2: { | ||
| 2620 | const std::string x = regs.GetRegisterAsFloat(instr.gpr8.Value() + start_index); | ||
| 2621 | const std::string y = | ||
| 2622 | regs.GetRegisterAsFloat(instr.gpr8.Value() + start_index + 1); | ||
| 2623 | if (is_array) { | ||
| 2624 | if (depth_compare) { | ||
| 2625 | coord = "vec4 coords = vec4(" + x + ", " + y + ", " + depth_value + | ||
| 2626 | ", " + array_elem + ");"; | ||
| 2627 | } else { | ||
| 2628 | coord = "vec3 coords = vec3(" + x + ", " + y + ", " + array_elem + ");"; | ||
| 2629 | } | ||
| 2630 | } else { | ||
| 2631 | if (depth_compare) { | ||
| 2632 | coord = | ||
| 2633 | "vec3 coords = vec3(" + x + ", " + y + ", " + depth_value + ");"; | ||
| 2634 | } else { | ||
| 2635 | coord = "vec2 coords = vec2(" + x + ", " + y + ");"; | ||
| 2636 | } | ||
| 2637 | } | ||
| 2638 | break; | ||
| 2639 | } | ||
| 2640 | case 3: { | ||
| 2641 | const std::string x = regs.GetRegisterAsFloat(instr.gpr8.Value() + start_index); | ||
| 2642 | const std::string y = | ||
| 2643 | regs.GetRegisterAsFloat(instr.gpr8.Value() + start_index + 1); | ||
| 2644 | const std::string z = | ||
| 2645 | regs.GetRegisterAsFloat(instr.gpr8.Value() + start_index + 2); | ||
| 2646 | if (is_array) { | ||
| 2647 | depth_compare_extra = depth_compare; | ||
| 2648 | coord = "vec4 coords = vec4(" + x + ", " + y + ", " + z + ", " + | ||
| 2649 | array_elem + ");"; | ||
| 2650 | } else { | ||
| 2651 | if (depth_compare) { | ||
| 2652 | coord = "vec4 coords = vec4(" + x + ", " + y + ", " + z + ", " + | ||
| 2653 | depth_value + ");"; | ||
| 2654 | } else { | ||
| 2655 | coord = "vec3 coords = vec3(" + x + ", " + y + ", " + z + ");"; | ||
| 2656 | } | ||
| 2657 | } | ||
| 2658 | break; | ||
| 2659 | } | ||
| 2660 | default: | ||
| 2661 | UNIMPLEMENTED_MSG("Unhandled coordinates number {}", | ||
| 2662 | static_cast<u32>(num_coordinates)); | ||
| 2663 | |||
| 2664 | // Fallback to interpreting as a 2D texture for now | ||
| 2665 | const std::string x = regs.GetRegisterAsFloat(instr.gpr8); | ||
| 2666 | const std::string y = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); | ||
| 2667 | coord = "vec2 coords = vec2(" + x + ", " + y + ");"; | ||
| 2668 | texture_type = Tegra::Shader::TextureType::Texture2D; | ||
| 2669 | } | ||
| 2670 | |||
| 2671 | const std::string sampler = | ||
| 2672 | GetSampler(instr.sampler, texture_type, is_array, depth_compare); | ||
| 2673 | // Add an extra scope and declare the texture coords inside to prevent | ||
| 2674 | // overwriting them in case they are used as outputs of the texs instruction. | ||
| 2675 | 2742 | ||
| 2676 | shader.AddLine('{'); | 2743 | const auto scope = shader.Scope(); |
| 2677 | ++shader.scope; | ||
| 2678 | shader.AddLine(coord); | 2744 | shader.AddLine(coord); |
| 2679 | std::string texture; | ||
| 2680 | 2745 | ||
| 2681 | switch (instr.tex.GetTextureProcessMode()) { | 2746 | if (depth_compare) { |
| 2682 | case Tegra::Shader::TextureProcessMode::None: { | 2747 | regs.SetRegisterToFloat(instr.gpr0, 0, texture, 1, 1, false); |
| 2683 | if (!depth_compare_extra) { | 2748 | } else { |
| 2684 | texture = "texture(" + sampler + ", coords)"; | ||
| 2685 | } else { | ||
| 2686 | texture = "texture(" + sampler + ", coords, " + depth_value + ')'; | ||
| 2687 | } | ||
| 2688 | break; | ||
| 2689 | } | ||
| 2690 | case Tegra::Shader::TextureProcessMode::LZ: { | ||
| 2691 | if (!depth_compare_extra) { | ||
| 2692 | texture = "textureLod(" + sampler + ", coords, 0.0)"; | ||
| 2693 | } else { | ||
| 2694 | texture = "texture(" + sampler + ", coords, " + depth_value + ')'; | ||
| 2695 | } | ||
| 2696 | break; | ||
| 2697 | } | ||
| 2698 | case Tegra::Shader::TextureProcessMode::LB: | ||
| 2699 | case Tegra::Shader::TextureProcessMode::LBA: { | ||
| 2700 | // TODO: Figure if A suffix changes the equation at all. | ||
| 2701 | if (!depth_compare_extra) { | ||
| 2702 | texture = "texture(" + sampler + ", coords, " + lod_value + ')'; | ||
| 2703 | } else { | ||
| 2704 | texture = "texture(" + sampler + ", coords, " + depth_value + ')'; | ||
| 2705 | LOG_WARNING(HW_GPU, | ||
| 2706 | "OpenGL Limitation: can't set bias value along depth compare"); | ||
| 2707 | } | ||
| 2708 | break; | ||
| 2709 | } | ||
| 2710 | case Tegra::Shader::TextureProcessMode::LL: | ||
| 2711 | case Tegra::Shader::TextureProcessMode::LLA: { | ||
| 2712 | // TODO: Figure if A suffix changes the equation at all. | ||
| 2713 | if (!depth_compare_extra) { | ||
| 2714 | texture = "textureLod(" + sampler + ", coords, " + lod_value + ')'; | ||
| 2715 | } else { | ||
| 2716 | texture = "texture(" + sampler + ", coords, " + depth_value + ')'; | ||
| 2717 | LOG_WARNING(HW_GPU, | ||
| 2718 | "OpenGL Limitation: can't set lod value along depth compare"); | ||
| 2719 | } | ||
| 2720 | break; | ||
| 2721 | } | ||
| 2722 | default: { | ||
| 2723 | if (!depth_compare_extra) { | ||
| 2724 | texture = "texture(" + sampler + ", coords)"; | ||
| 2725 | } else { | ||
| 2726 | texture = "texture(" + sampler + ", coords, " + depth_value + ')'; | ||
| 2727 | } | ||
| 2728 | UNIMPLEMENTED_MSG("Unhandled texture process mode {}", | ||
| 2729 | static_cast<u32>(instr.tex.GetTextureProcessMode())); | ||
| 2730 | } | ||
| 2731 | } | ||
| 2732 | if (!depth_compare) { | ||
| 2733 | shader.AddLine("vec4 texture_tmp = " + texture + ';'); | 2749 | shader.AddLine("vec4 texture_tmp = " + texture + ';'); |
| 2734 | std::size_t dest_elem{}; | 2750 | std::size_t dest_elem{}; |
| 2735 | for (std::size_t elem = 0; elem < 4; ++elem) { | 2751 | for (std::size_t elem = 0; elem < 4; ++elem) { |
| @@ -2741,138 +2757,33 @@ private: | |||
| 2741 | dest_elem); | 2757 | dest_elem); |
| 2742 | ++dest_elem; | 2758 | ++dest_elem; |
| 2743 | } | 2759 | } |
| 2744 | } else { | ||
| 2745 | regs.SetRegisterToFloat(instr.gpr0, 0, texture, 1, 1, false); | ||
| 2746 | } | 2760 | } |
| 2747 | --shader.scope; | ||
| 2748 | shader.AddLine('}'); | ||
| 2749 | break; | 2761 | break; |
| 2750 | } | 2762 | } |
| 2751 | case OpCode::Id::TEXS: { | 2763 | case OpCode::Id::TEXS: { |
| 2752 | Tegra::Shader::TextureType texture_type{instr.texs.GetTextureType()}; | 2764 | Tegra::Shader::TextureType texture_type{instr.texs.GetTextureType()}; |
| 2753 | bool is_array{instr.texs.IsArrayTexture()}; | 2765 | const bool is_array{instr.texs.IsArrayTexture()}; |
| 2754 | |||
| 2755 | UNIMPLEMENTED_IF_MSG(instr.texs.UsesMiscMode(Tegra::Shader::TextureMiscMode::NODEP), | ||
| 2756 | "NODEP is not implemented"); | ||
| 2757 | |||
| 2758 | const bool depth_compare = | 2766 | const bool depth_compare = |
| 2759 | instr.texs.UsesMiscMode(Tegra::Shader::TextureMiscMode::DC); | 2767 | instr.texs.UsesMiscMode(Tegra::Shader::TextureMiscMode::DC); |
| 2760 | u32 num_coordinates = TextureCoordinates(texture_type); | ||
| 2761 | const auto process_mode = instr.texs.GetTextureProcessMode(); | 2768 | const auto process_mode = instr.texs.GetTextureProcessMode(); |
| 2762 | std::string lod_value; | 2769 | UNIMPLEMENTED_IF_MSG(instr.texs.UsesMiscMode(Tegra::Shader::TextureMiscMode::NODEP), |
| 2763 | std::string coord; | 2770 | "NODEP is not implemented"); |
| 2764 | u32 lod_offset = 0; | ||
| 2765 | if (process_mode == Tegra::Shader::TextureProcessMode::LL) { | ||
| 2766 | if (num_coordinates > 2) { | ||
| 2767 | lod_value = regs.GetRegisterAsFloat(instr.gpr20.Value() + 1); | ||
| 2768 | lod_offset = 2; | ||
| 2769 | } else { | ||
| 2770 | lod_value = regs.GetRegisterAsFloat(instr.gpr20); | ||
| 2771 | lod_offset = 1; | ||
| 2772 | } | ||
| 2773 | } | ||
| 2774 | 2771 | ||
| 2775 | switch (num_coordinates) { | 2772 | const auto scope = shader.Scope(); |
| 2776 | case 1: { | 2773 | |
| 2777 | coord = "float coords = " + regs.GetRegisterAsFloat(instr.gpr8) + ';'; | 2774 | const auto [coord, texture] = |
| 2778 | break; | 2775 | GetTEXSCode(instr, texture_type, process_mode, depth_compare, is_array); |
| 2779 | } | 2776 | |
| 2780 | case 2: { | 2777 | shader.AddLine(coord); |
| 2781 | if (is_array) { | ||
| 2782 | if (depth_compare) { | ||
| 2783 | const std::string index = regs.GetRegisterAsInteger(instr.gpr8); | ||
| 2784 | const std::string x = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); | ||
| 2785 | const std::string y = regs.GetRegisterAsFloat(instr.gpr20); | ||
| 2786 | const std::string z = regs.GetRegisterAsFloat(instr.gpr20.Value() + 1); | ||
| 2787 | coord = "vec4 coords = vec4(" + x + ", " + y + ", " + z + ", " + index + | ||
| 2788 | ");"; | ||
| 2789 | } else { | ||
| 2790 | const std::string index = regs.GetRegisterAsInteger(instr.gpr8); | ||
| 2791 | const std::string x = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); | ||
| 2792 | const std::string y = regs.GetRegisterAsFloat(instr.gpr20); | ||
| 2793 | coord = "vec3 coords = vec3(" + x + ", " + y + ", " + index + ");"; | ||
| 2794 | } | ||
| 2795 | } else { | ||
| 2796 | if (lod_offset != 0) { | ||
| 2797 | if (depth_compare) { | ||
| 2798 | const std::string x = regs.GetRegisterAsFloat(instr.gpr8); | ||
| 2799 | const std::string y = | ||
| 2800 | regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); | ||
| 2801 | const std::string z = | ||
| 2802 | regs.GetRegisterAsFloat(instr.gpr20.Value() + lod_offset); | ||
| 2803 | coord = "vec3 coords = vec3(" + x + ", " + y + ", " + z + ");"; | ||
| 2804 | } else { | ||
| 2805 | const std::string x = regs.GetRegisterAsFloat(instr.gpr8); | ||
| 2806 | const std::string y = | ||
| 2807 | regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); | ||
| 2808 | coord = "vec2 coords = vec2(" + x + ", " + y + ");"; | ||
| 2809 | } | ||
| 2810 | } else { | ||
| 2811 | if (depth_compare) { | ||
| 2812 | const std::string x = regs.GetRegisterAsFloat(instr.gpr8); | ||
| 2813 | const std::string y = | ||
| 2814 | regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); | ||
| 2815 | const std::string z = regs.GetRegisterAsFloat(instr.gpr20); | ||
| 2816 | coord = "vec3 coords = vec3(" + x + ", " + y + ", " + z + ");"; | ||
| 2817 | } else { | ||
| 2818 | const std::string x = regs.GetRegisterAsFloat(instr.gpr8); | ||
| 2819 | const std::string y = regs.GetRegisterAsFloat(instr.gpr20); | ||
| 2820 | coord = "vec2 coords = vec2(" + x + ", " + y + ");"; | ||
| 2821 | } | ||
| 2822 | } | ||
| 2823 | } | ||
| 2824 | break; | ||
| 2825 | } | ||
| 2826 | case 3: { | ||
| 2827 | const std::string x = regs.GetRegisterAsFloat(instr.gpr8); | ||
| 2828 | const std::string y = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); | ||
| 2829 | const std::string z = regs.GetRegisterAsFloat(instr.gpr20); | ||
| 2830 | coord = "vec3 coords = vec3(" + x + ", " + y + ", " + z + ");"; | ||
| 2831 | break; | ||
| 2832 | } | ||
| 2833 | default: | ||
| 2834 | UNIMPLEMENTED_MSG("Unhandled coordinates number {}", | ||
| 2835 | static_cast<u32>(num_coordinates)); | ||
| 2836 | 2778 | ||
| 2837 | // Fallback to interpreting as a 2D texture for now | ||
| 2838 | const std::string x = regs.GetRegisterAsFloat(instr.gpr8); | ||
| 2839 | const std::string y = regs.GetRegisterAsFloat(instr.gpr20); | ||
| 2840 | coord = "vec2 coords = vec2(" + x + ", " + y + ");"; | ||
| 2841 | texture_type = Tegra::Shader::TextureType::Texture2D; | ||
| 2842 | is_array = false; | ||
| 2843 | } | ||
| 2844 | const std::string sampler = | ||
| 2845 | GetSampler(instr.sampler, texture_type, is_array, depth_compare); | ||
| 2846 | std::string texture; | ||
| 2847 | switch (process_mode) { | ||
| 2848 | case Tegra::Shader::TextureProcessMode::None: { | ||
| 2849 | texture = "texture(" + sampler + ", coords)"; | ||
| 2850 | break; | ||
| 2851 | } | ||
| 2852 | case Tegra::Shader::TextureProcessMode::LZ: { | ||
| 2853 | if (depth_compare && is_array) { | ||
| 2854 | texture = "texture(" + sampler + ", coords)"; | ||
| 2855 | } else { | ||
| 2856 | texture = "textureLod(" + sampler + ", coords, 0.0)"; | ||
| 2857 | } | ||
| 2858 | break; | ||
| 2859 | } | ||
| 2860 | case Tegra::Shader::TextureProcessMode::LL: { | ||
| 2861 | texture = "textureLod(" + sampler + ", coords, " + lod_value + ')'; | ||
| 2862 | break; | ||
| 2863 | } | ||
| 2864 | default: { | ||
| 2865 | texture = "texture(" + sampler + ", coords)"; | ||
| 2866 | UNIMPLEMENTED_MSG("Unhandled texture process mode {}", | ||
| 2867 | static_cast<u32>(instr.texs.GetTextureProcessMode())); | ||
| 2868 | } | ||
| 2869 | } | ||
| 2870 | if (!depth_compare) { | 2779 | if (!depth_compare) { |
| 2871 | WriteTexsInstruction(instr, coord, texture); | 2780 | shader.AddLine("vec4 texture_tmp = " + texture + ';'); |
| 2781 | |||
| 2872 | } else { | 2782 | } else { |
| 2873 | WriteTexsInstruction(instr, coord, "vec4(" + texture + ')'); | 2783 | shader.AddLine("vec4 texture_tmp = vec4(" + texture + ");"); |
| 2874 | } | 2784 | } |
| 2875 | 2785 | ||
| 2786 | WriteTexsInstruction(instr, "texture_tmp"); | ||
| 2876 | break; | 2787 | break; |
| 2877 | } | 2788 | } |
| 2878 | case OpCode::Id::TLDS: { | 2789 | case OpCode::Id::TLDS: { |
| @@ -2891,15 +2802,12 @@ private: | |||
| 2891 | 2802 | ||
| 2892 | u32 extra_op_offset = 0; | 2803 | u32 extra_op_offset = 0; |
| 2893 | 2804 | ||
| 2894 | // Scope to avoid variable name overlaps. | 2805 | ShaderScopedScope scope = shader.Scope(); |
| 2895 | shader.AddLine('{'); | ||
| 2896 | ++shader.scope; | ||
| 2897 | std::string coords; | ||
| 2898 | 2806 | ||
| 2899 | switch (texture_type) { | 2807 | switch (texture_type) { |
| 2900 | case Tegra::Shader::TextureType::Texture1D: { | 2808 | case Tegra::Shader::TextureType::Texture1D: { |
| 2901 | const std::string x = regs.GetRegisterAsInteger(instr.gpr8); | 2809 | const std::string x = regs.GetRegisterAsInteger(instr.gpr8); |
| 2902 | coords = "float coords = " + x + ';'; | 2810 | shader.AddLine("float coords = " + x + ';'); |
| 2903 | break; | 2811 | break; |
| 2904 | } | 2812 | } |
| 2905 | case Tegra::Shader::TextureType::Texture2D: { | 2813 | case Tegra::Shader::TextureType::Texture2D: { |
| @@ -2908,7 +2816,7 @@ private: | |||
| 2908 | const std::string x = regs.GetRegisterAsInteger(instr.gpr8); | 2816 | const std::string x = regs.GetRegisterAsInteger(instr.gpr8); |
| 2909 | const std::string y = regs.GetRegisterAsInteger(instr.gpr20); | 2817 | const std::string y = regs.GetRegisterAsInteger(instr.gpr20); |
| 2910 | // shader.AddLine("ivec2 coords = ivec2(" + x + ", " + y + ");"); | 2818 | // shader.AddLine("ivec2 coords = ivec2(" + x + ", " + y + ");"); |
| 2911 | coords = "ivec2 coords = ivec2(" + x + ", " + y + ");"; | 2819 | shader.AddLine("ivec2 coords = ivec2(" + x + ", " + y + ");"); |
| 2912 | extra_op_offset = 1; | 2820 | extra_op_offset = 1; |
| 2913 | break; | 2821 | break; |
| 2914 | } | 2822 | } |
| @@ -2917,35 +2825,29 @@ private: | |||
| 2917 | } | 2825 | } |
| 2918 | const std::string sampler = | 2826 | const std::string sampler = |
| 2919 | GetSampler(instr.sampler, texture_type, is_array, false); | 2827 | GetSampler(instr.sampler, texture_type, is_array, false); |
| 2920 | std::string texture = "texelFetch(" + sampler + ", coords, 0)"; | ||
| 2921 | switch (instr.tlds.GetTextureProcessMode()) { | ||
| 2922 | case Tegra::Shader::TextureProcessMode::LZ: { | ||
| 2923 | texture = "texelFetch(" + sampler + ", coords, 0)"; | ||
| 2924 | break; | ||
| 2925 | } | ||
| 2926 | case Tegra::Shader::TextureProcessMode::LL: { | ||
| 2927 | shader.AddLine( | ||
| 2928 | "float lod = " + | ||
| 2929 | regs.GetRegisterAsInteger(instr.gpr20.Value() + extra_op_offset) + ';'); | ||
| 2930 | texture = "texelFetch(" + sampler + ", coords, lod)"; | ||
| 2931 | break; | ||
| 2932 | } | ||
| 2933 | default: { | ||
| 2934 | texture = "texelFetch(" + sampler + ", coords, 0)"; | ||
| 2935 | UNIMPLEMENTED_MSG("Unhandled texture process mode {}", | ||
| 2936 | static_cast<u32>(instr.tlds.GetTextureProcessMode())); | ||
| 2937 | } | ||
| 2938 | } | ||
| 2939 | WriteTexsInstruction(instr, coords, texture); | ||
| 2940 | 2828 | ||
| 2941 | --shader.scope; | 2829 | const std::string texture = [&]() { |
| 2942 | shader.AddLine('}'); | 2830 | switch (instr.tlds.GetTextureProcessMode()) { |
| 2831 | case Tegra::Shader::TextureProcessMode::LZ: | ||
| 2832 | return "texelFetch(" + sampler + ", coords, 0)"; | ||
| 2833 | case Tegra::Shader::TextureProcessMode::LL: | ||
| 2834 | shader.AddLine( | ||
| 2835 | "float lod = " + | ||
| 2836 | regs.GetRegisterAsInteger(instr.gpr20.Value() + extra_op_offset) + ';'); | ||
| 2837 | return "texelFetch(" + sampler + ", coords, lod)"; | ||
| 2838 | default: | ||
| 2839 | UNIMPLEMENTED_MSG("Unhandled texture process mode {}", | ||
| 2840 | static_cast<u32>(instr.tlds.GetTextureProcessMode())); | ||
| 2841 | return "texelFetch(" + sampler + ", coords, 0)"; | ||
| 2842 | } | ||
| 2843 | }(); | ||
| 2844 | |||
| 2845 | WriteTexsInstruction(instr, texture); | ||
| 2943 | break; | 2846 | break; |
| 2944 | } | 2847 | } |
| 2945 | case OpCode::Id::TLD4: { | 2848 | case OpCode::Id::TLD4: { |
| 2946 | ASSERT(instr.tld4.texture_type == Tegra::Shader::TextureType::Texture2D); | 2849 | ASSERT(instr.tld4.texture_type == Tegra::Shader::TextureType::Texture2D); |
| 2947 | ASSERT(instr.tld4.array == 0); | 2850 | ASSERT(instr.tld4.array == 0); |
| 2948 | std::string coord; | ||
| 2949 | 2851 | ||
| 2950 | UNIMPLEMENTED_IF_MSG(instr.tld4.UsesMiscMode(Tegra::Shader::TextureMiscMode::NODEP), | 2852 | UNIMPLEMENTED_IF_MSG(instr.tld4.UsesMiscMode(Tegra::Shader::TextureMiscMode::NODEP), |
| 2951 | "NODEP is not implemented"); | 2853 | "NODEP is not implemented"); |
| @@ -2962,10 +2864,7 @@ private: | |||
| 2962 | if (depth_compare) | 2864 | if (depth_compare) |
| 2963 | num_coordinates += 1; | 2865 | num_coordinates += 1; |
| 2964 | 2866 | ||
| 2965 | // Add an extra scope and declare the texture coords inside to prevent | 2867 | const auto scope = shader.Scope(); |
| 2966 | // overwriting them in case they are used as outputs of the texs instruction. | ||
| 2967 | shader.AddLine('{'); | ||
| 2968 | ++shader.scope; | ||
| 2969 | 2868 | ||
| 2970 | switch (num_coordinates) { | 2869 | switch (num_coordinates) { |
| 2971 | case 2: { | 2870 | case 2: { |
| @@ -2996,23 +2895,19 @@ private: | |||
| 2996 | const std::string texture = "textureGather(" + sampler + ", coords, " + | 2895 | const std::string texture = "textureGather(" + sampler + ", coords, " + |
| 2997 | std::to_string(instr.tld4.component) + ')'; | 2896 | std::to_string(instr.tld4.component) + ')'; |
| 2998 | 2897 | ||
| 2999 | if (!depth_compare) { | 2898 | if (depth_compare) { |
| 3000 | shader.AddLine("vec4 texture_tmp = " + texture + ';'); | 2899 | regs.SetRegisterToFloat(instr.gpr0, 0, texture, 1, 1, false); |
| 2900 | } else { | ||
| 3001 | std::size_t dest_elem{}; | 2901 | std::size_t dest_elem{}; |
| 3002 | for (std::size_t elem = 0; elem < 4; ++elem) { | 2902 | for (std::size_t elem = 0; elem < 4; ++elem) { |
| 3003 | if (!instr.tex.IsComponentEnabled(elem)) { | 2903 | if (!instr.tex.IsComponentEnabled(elem)) { |
| 3004 | // Skip disabled components | 2904 | // Skip disabled components |
| 3005 | continue; | 2905 | continue; |
| 3006 | } | 2906 | } |
| 3007 | regs.SetRegisterToFloat(instr.gpr0, elem, "texture_tmp", 1, 4, false, | 2907 | regs.SetRegisterToFloat(instr.gpr0, elem, texture, 1, 4, false, dest_elem); |
| 3008 | dest_elem); | ||
| 3009 | ++dest_elem; | 2908 | ++dest_elem; |
| 3010 | } | 2909 | } |
| 3011 | } else { | ||
| 3012 | regs.SetRegisterToFloat(instr.gpr0, 0, texture, 1, 1, false); | ||
| 3013 | } | 2910 | } |
| 3014 | --shader.scope; | ||
| 3015 | shader.AddLine('}'); | ||
| 3016 | break; | 2911 | break; |
| 3017 | } | 2912 | } |
| 3018 | case OpCode::Id::TLD4S: { | 2913 | case OpCode::Id::TLD4S: { |
| @@ -3023,10 +2918,7 @@ private: | |||
| 3023 | instr.tld4s.UsesMiscMode(Tegra::Shader::TextureMiscMode::AOFFI), | 2918 | instr.tld4s.UsesMiscMode(Tegra::Shader::TextureMiscMode::AOFFI), |
| 3024 | "AOFFI is not implemented"); | 2919 | "AOFFI is not implemented"); |
| 3025 | 2920 | ||
| 3026 | // Scope to avoid variable name overlaps. | 2921 | const auto scope = shader.Scope(); |
| 3027 | shader.AddLine('{'); | ||
| 3028 | ++shader.scope; | ||
| 3029 | std::string coords; | ||
| 3030 | 2922 | ||
| 3031 | const bool depth_compare = | 2923 | const bool depth_compare = |
| 3032 | instr.tld4s.UsesMiscMode(Tegra::Shader::TextureMiscMode::DC); | 2924 | instr.tld4s.UsesMiscMode(Tegra::Shader::TextureMiscMode::DC); |
| @@ -3035,33 +2927,29 @@ private: | |||
| 3035 | // TODO(Subv): Figure out how the sampler type is encoded in the TLD4S instruction. | 2927 | // TODO(Subv): Figure out how the sampler type is encoded in the TLD4S instruction. |
| 3036 | const std::string sampler = GetSampler( | 2928 | const std::string sampler = GetSampler( |
| 3037 | instr.sampler, Tegra::Shader::TextureType::Texture2D, false, depth_compare); | 2929 | instr.sampler, Tegra::Shader::TextureType::Texture2D, false, depth_compare); |
| 3038 | if (!depth_compare) { | 2930 | if (depth_compare) { |
| 3039 | coords = "vec2 coords = vec2(" + op_a + ", " + op_b + ");"; | ||
| 3040 | } else { | ||
| 3041 | // Note: TLD4S coordinate encoding works just like TEXS's | 2931 | // Note: TLD4S coordinate encoding works just like TEXS's |
| 3042 | const std::string op_y = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); | 2932 | const std::string op_y = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); |
| 3043 | coords = "vec3 coords = vec3(" + op_a + ", " + op_y + ", " + op_b + ");"; | 2933 | shader.AddLine("vec3 coords = vec3(" + op_a + ", " + op_y + ", " + op_b + ");"); |
| 3044 | } | ||
| 3045 | const std::string texture = "textureGather(" + sampler + ", coords, " + | ||
| 3046 | std::to_string(instr.tld4s.component) + ')'; | ||
| 3047 | |||
| 3048 | if (!depth_compare) { | ||
| 3049 | WriteTexsInstruction(instr, coords, texture); | ||
| 3050 | } else { | 2934 | } else { |
| 3051 | WriteTexsInstruction(instr, coords, "vec4(" + texture + ')'); | 2935 | shader.AddLine("vec2 coords = vec2(" + op_a + ", " + op_b + ");"); |
| 3052 | } | 2936 | } |
| 3053 | 2937 | ||
| 3054 | --shader.scope; | 2938 | std::string texture = "textureGather(" + sampler + ", coords, " + |
| 3055 | shader.AddLine('}'); | 2939 | std::to_string(instr.tld4s.component) + ')'; |
| 2940 | if (depth_compare) { | ||
| 2941 | texture = "vec4(" + texture + ')'; | ||
| 2942 | } | ||
| 2943 | WriteTexsInstruction(instr, texture); | ||
| 3056 | break; | 2944 | break; |
| 3057 | } | 2945 | } |
| 3058 | case OpCode::Id::TXQ: { | 2946 | case OpCode::Id::TXQ: { |
| 3059 | UNIMPLEMENTED_IF_MSG(instr.txq.UsesMiscMode(Tegra::Shader::TextureMiscMode::NODEP), | 2947 | UNIMPLEMENTED_IF_MSG(instr.txq.UsesMiscMode(Tegra::Shader::TextureMiscMode::NODEP), |
| 3060 | "NODEP is not implemented"); | 2948 | "NODEP is not implemented"); |
| 3061 | 2949 | ||
| 3062 | ++shader.scope; | 2950 | const auto scope = shader.Scope(); |
| 3063 | shader.AddLine('{'); | 2951 | |
| 3064 | // TODO: the new commits on the texture refactor, change the way samplers work. | 2952 | // TODO: The new commits on the texture refactor, change the way samplers work. |
| 3065 | // Sadly, not all texture instructions specify the type of texture their sampler | 2953 | // Sadly, not all texture instructions specify the type of texture their sampler |
| 3066 | // uses. This must be fixed at a later instance. | 2954 | // uses. This must be fixed at a later instance. |
| 3067 | const std::string sampler = | 2955 | const std::string sampler = |
| @@ -3072,7 +2960,8 @@ private: | |||
| 3072 | regs.GetRegisterAsInteger(instr.gpr8) + ')'; | 2960 | regs.GetRegisterAsInteger(instr.gpr8) + ')'; |
| 3073 | const std::string mip_level = "textureQueryLevels(" + sampler + ')'; | 2961 | const std::string mip_level = "textureQueryLevels(" + sampler + ')'; |
| 3074 | shader.AddLine("ivec2 sizes = " + texture + ';'); | 2962 | shader.AddLine("ivec2 sizes = " + texture + ';'); |
| 3075 | regs.SetRegisterToInteger(instr.gpr0, true, 0, "sizes.x", 1, 1); | 2963 | |
| 2964 | regs.SetRegisterToInteger(instr.gpr0.Value() + 0, true, 0, "sizes.x", 1, 1); | ||
| 3076 | regs.SetRegisterToInteger(instr.gpr0.Value() + 1, true, 0, "sizes.y", 1, 1); | 2965 | regs.SetRegisterToInteger(instr.gpr0.Value() + 1, true, 0, "sizes.y", 1, 1); |
| 3077 | regs.SetRegisterToInteger(instr.gpr0.Value() + 2, true, 0, "0", 1, 1); | 2966 | regs.SetRegisterToInteger(instr.gpr0.Value() + 2, true, 0, "0", 1, 1); |
| 3078 | regs.SetRegisterToInteger(instr.gpr0.Value() + 3, true, 0, mip_level, 1, 1); | 2967 | regs.SetRegisterToInteger(instr.gpr0.Value() + 3, true, 0, mip_level, 1, 1); |
| @@ -3083,8 +2972,6 @@ private: | |||
| 3083 | static_cast<u32>(instr.txq.query_type.Value())); | 2972 | static_cast<u32>(instr.txq.query_type.Value())); |
| 3084 | } | 2973 | } |
| 3085 | } | 2974 | } |
| 3086 | --shader.scope; | ||
| 3087 | shader.AddLine('}'); | ||
| 3088 | break; | 2975 | break; |
| 3089 | } | 2976 | } |
| 3090 | case OpCode::Id::TMML: { | 2977 | case OpCode::Id::TMML: { |
| @@ -3099,17 +2986,18 @@ private: | |||
| 3099 | const std::string sampler = | 2986 | const std::string sampler = |
| 3100 | GetSampler(instr.sampler, texture_type, is_array, false); | 2987 | GetSampler(instr.sampler, texture_type, is_array, false); |
| 3101 | 2988 | ||
| 3102 | // TODO: add coordinates for different samplers once other texture types are | 2989 | const auto scope = shader.Scope(); |
| 2990 | |||
| 2991 | // TODO: Add coordinates for different samplers once other texture types are | ||
| 3103 | // implemented. | 2992 | // implemented. |
| 3104 | std::string coord; | ||
| 3105 | switch (texture_type) { | 2993 | switch (texture_type) { |
| 3106 | case Tegra::Shader::TextureType::Texture1D: { | 2994 | case Tegra::Shader::TextureType::Texture1D: { |
| 3107 | coord = "float coords = " + x + ';'; | 2995 | shader.AddLine("float coords = " + x + ';'); |
| 3108 | break; | 2996 | break; |
| 3109 | } | 2997 | } |
| 3110 | case Tegra::Shader::TextureType::Texture2D: { | 2998 | case Tegra::Shader::TextureType::Texture2D: { |
| 3111 | const std::string y = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); | 2999 | const std::string y = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); |
| 3112 | coord = "vec2 coords = vec2(" + x + ", " + y + ");"; | 3000 | shader.AddLine("vec2 coords = vec2(" + x + ", " + y + ");"); |
| 3113 | break; | 3001 | break; |
| 3114 | } | 3002 | } |
| 3115 | default: | 3003 | default: |
| @@ -3117,22 +3005,15 @@ private: | |||
| 3117 | 3005 | ||
| 3118 | // Fallback to interpreting as a 2D texture for now | 3006 | // Fallback to interpreting as a 2D texture for now |
| 3119 | const std::string y = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); | 3007 | const std::string y = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); |
| 3120 | coord = "vec2 coords = vec2(" + x + ", " + y + ");"; | 3008 | shader.AddLine("vec2 coords = vec2(" + x + ", " + y + ");"); |
| 3121 | texture_type = Tegra::Shader::TextureType::Texture2D; | 3009 | texture_type = Tegra::Shader::TextureType::Texture2D; |
| 3122 | } | 3010 | } |
| 3123 | // Add an extra scope and declare the texture coords inside to prevent | 3011 | |
| 3124 | // overwriting them in case they are used as outputs of the texs instruction. | ||
| 3125 | shader.AddLine('{'); | ||
| 3126 | ++shader.scope; | ||
| 3127 | shader.AddLine(coord); | ||
| 3128 | const std::string texture = "textureQueryLod(" + sampler + ", coords)"; | 3012 | const std::string texture = "textureQueryLod(" + sampler + ", coords)"; |
| 3129 | const std::string tmp = "vec2 tmp = " + texture + "*vec2(256.0, 256.0);"; | 3013 | shader.AddLine("vec2 tmp = " + texture + " * vec2(256.0, 256.0);"); |
| 3130 | shader.AddLine(tmp); | ||
| 3131 | 3014 | ||
| 3132 | regs.SetRegisterToInteger(instr.gpr0, true, 0, "int(tmp.y)", 1, 1); | 3015 | regs.SetRegisterToInteger(instr.gpr0, true, 0, "int(tmp.y)", 1, 1); |
| 3133 | regs.SetRegisterToInteger(instr.gpr0.Value() + 1, false, 0, "uint(tmp.x)", 1, 1); | 3016 | regs.SetRegisterToInteger(instr.gpr0.Value() + 1, false, 0, "uint(tmp.x)", 1, 1); |
| 3134 | --shader.scope; | ||
| 3135 | shader.AddLine('}'); | ||
| 3136 | break; | 3017 | break; |
| 3137 | } | 3018 | } |
| 3138 | default: { | 3019 | default: { |
| @@ -3971,4 +3852,4 @@ std::optional<ProgramResult> DecompileProgram(const ProgramCode& program_code, u | |||
| 3971 | return {}; | 3852 | return {}; |
| 3972 | } | 3853 | } |
| 3973 | 3854 | ||
| 3974 | } // namespace OpenGL::GLShader::Decompiler | 3855 | } // namespace OpenGL::GLShader::Decompiler \ No newline at end of file |
diff --git a/src/yuzu/configuration/configure_audio.h b/src/yuzu/configuration/configure_audio.h index 207f9dfb3..8771421c0 100644 --- a/src/yuzu/configuration/configure_audio.h +++ b/src/yuzu/configuration/configure_audio.h | |||
| @@ -16,15 +16,14 @@ class ConfigureAudio : public QWidget { | |||
| 16 | 16 | ||
| 17 | public: | 17 | public: |
| 18 | explicit ConfigureAudio(QWidget* parent = nullptr); | 18 | explicit ConfigureAudio(QWidget* parent = nullptr); |
| 19 | ~ConfigureAudio(); | 19 | ~ConfigureAudio() override; |
| 20 | 20 | ||
| 21 | void applyConfiguration(); | 21 | void applyConfiguration(); |
| 22 | void retranslateUi(); | 22 | void retranslateUi(); |
| 23 | 23 | ||
| 24 | public slots: | 24 | private: |
| 25 | void updateAudioDevices(int sink_index); | 25 | void updateAudioDevices(int sink_index); |
| 26 | 26 | ||
| 27 | private: | ||
| 28 | void setConfiguration(); | 27 | void setConfiguration(); |
| 29 | void setOutputSinkFromSinkID(); | 28 | void setOutputSinkFromSinkID(); |
| 30 | void setAudioDeviceFromDeviceID(); | 29 | void setAudioDeviceFromDeviceID(); |
diff --git a/src/yuzu/configuration/configure_debug.h b/src/yuzu/configuration/configure_debug.h index d167eb996..c6420b18c 100644 --- a/src/yuzu/configuration/configure_debug.h +++ b/src/yuzu/configuration/configure_debug.h | |||
| @@ -16,13 +16,12 @@ class ConfigureDebug : public QWidget { | |||
| 16 | 16 | ||
| 17 | public: | 17 | public: |
| 18 | explicit ConfigureDebug(QWidget* parent = nullptr); | 18 | explicit ConfigureDebug(QWidget* parent = nullptr); |
| 19 | ~ConfigureDebug(); | 19 | ~ConfigureDebug() override; |
| 20 | 20 | ||
| 21 | void applyConfiguration(); | 21 | void applyConfiguration(); |
| 22 | 22 | ||
| 23 | private: | 23 | private: |
| 24 | void setConfiguration(); | 24 | void setConfiguration(); |
| 25 | 25 | ||
| 26 | private: | ||
| 27 | std::unique_ptr<Ui::ConfigureDebug> ui; | 26 | std::unique_ptr<Ui::ConfigureDebug> ui; |
| 28 | }; | 27 | }; |
diff --git a/src/yuzu/configuration/configure_dialog.h b/src/yuzu/configuration/configure_dialog.h index bbbdacc29..f6df7b827 100644 --- a/src/yuzu/configuration/configure_dialog.h +++ b/src/yuzu/configuration/configure_dialog.h | |||
| @@ -18,13 +18,12 @@ class ConfigureDialog : public QDialog { | |||
| 18 | 18 | ||
| 19 | public: | 19 | public: |
| 20 | explicit ConfigureDialog(QWidget* parent, const HotkeyRegistry& registry); | 20 | explicit ConfigureDialog(QWidget* parent, const HotkeyRegistry& registry); |
| 21 | ~ConfigureDialog(); | 21 | ~ConfigureDialog() override; |
| 22 | 22 | ||
| 23 | void applyConfiguration(); | 23 | void applyConfiguration(); |
| 24 | 24 | ||
| 25 | private: | 25 | private: |
| 26 | void setConfiguration(); | 26 | void setConfiguration(); |
| 27 | 27 | ||
| 28 | private: | ||
| 29 | std::unique_ptr<Ui::ConfigureDialog> ui; | 28 | std::unique_ptr<Ui::ConfigureDialog> ui; |
| 30 | }; | 29 | }; |
diff --git a/src/yuzu/configuration/configure_gamelist.h b/src/yuzu/configuration/configure_gamelist.h index bbf7e25f1..bf3f1cdfa 100644 --- a/src/yuzu/configuration/configure_gamelist.h +++ b/src/yuzu/configuration/configure_gamelist.h | |||
| @@ -16,7 +16,7 @@ class ConfigureGameList : public QWidget { | |||
| 16 | 16 | ||
| 17 | public: | 17 | public: |
| 18 | explicit ConfigureGameList(QWidget* parent = nullptr); | 18 | explicit ConfigureGameList(QWidget* parent = nullptr); |
| 19 | ~ConfigureGameList(); | 19 | ~ConfigureGameList() override; |
| 20 | 20 | ||
| 21 | void applyConfiguration(); | 21 | void applyConfiguration(); |
| 22 | 22 | ||
diff --git a/src/yuzu/configuration/configure_general.h b/src/yuzu/configuration/configure_general.h index 4770034cc..59738af40 100644 --- a/src/yuzu/configuration/configure_general.h +++ b/src/yuzu/configuration/configure_general.h | |||
| @@ -18,7 +18,7 @@ class ConfigureGeneral : public QWidget { | |||
| 18 | 18 | ||
| 19 | public: | 19 | public: |
| 20 | explicit ConfigureGeneral(QWidget* parent = nullptr); | 20 | explicit ConfigureGeneral(QWidget* parent = nullptr); |
| 21 | ~ConfigureGeneral(); | 21 | ~ConfigureGeneral() override; |
| 22 | 22 | ||
| 23 | void PopulateHotkeyList(const HotkeyRegistry& registry); | 23 | void PopulateHotkeyList(const HotkeyRegistry& registry); |
| 24 | void applyConfiguration(); | 24 | void applyConfiguration(); |
diff --git a/src/yuzu/configuration/configure_graphics.h b/src/yuzu/configuration/configure_graphics.h index 9bda26fd6..d6ffc6fde 100644 --- a/src/yuzu/configuration/configure_graphics.h +++ b/src/yuzu/configuration/configure_graphics.h | |||
| @@ -16,14 +16,13 @@ class ConfigureGraphics : public QWidget { | |||
| 16 | 16 | ||
| 17 | public: | 17 | public: |
| 18 | explicit ConfigureGraphics(QWidget* parent = nullptr); | 18 | explicit ConfigureGraphics(QWidget* parent = nullptr); |
| 19 | ~ConfigureGraphics(); | 19 | ~ConfigureGraphics() override; |
| 20 | 20 | ||
| 21 | void applyConfiguration(); | 21 | void applyConfiguration(); |
| 22 | 22 | ||
| 23 | private: | 23 | private: |
| 24 | void setConfiguration(); | 24 | void setConfiguration(); |
| 25 | 25 | ||
| 26 | private: | ||
| 27 | std::unique_ptr<Ui::ConfigureGraphics> ui; | 26 | std::unique_ptr<Ui::ConfigureGraphics> ui; |
| 28 | QColor bg_color; | 27 | QColor bg_color; |
| 29 | }; | 28 | }; |
diff --git a/src/yuzu/configuration/configure_input.cpp b/src/yuzu/configuration/configure_input.cpp index 0527d098c..830d26115 100644 --- a/src/yuzu/configuration/configure_input.cpp +++ b/src/yuzu/configuration/configure_input.cpp | |||
| @@ -88,6 +88,8 @@ ConfigureInput::ConfigureInput(QWidget* parent) | |||
| 88 | [this] { CallConfigureDialog<ConfigureTouchscreenAdvanced>(*this); }); | 88 | [this] { CallConfigureDialog<ConfigureTouchscreenAdvanced>(*this); }); |
| 89 | } | 89 | } |
| 90 | 90 | ||
| 91 | ConfigureInput::~ConfigureInput() = default; | ||
| 92 | |||
| 91 | void ConfigureInput::OnDockedModeChanged(bool last_state, bool new_state) { | 93 | void ConfigureInput::OnDockedModeChanged(bool last_state, bool new_state) { |
| 92 | if (ui->use_docked_mode->isChecked() && ui->handheld_connected->isChecked()) { | 94 | if (ui->use_docked_mode->isChecked() && ui->handheld_connected->isChecked()) { |
| 93 | ui->handheld_connected->setChecked(false); | 95 | ui->handheld_connected->setChecked(false); |
diff --git a/src/yuzu/configuration/configure_input.h b/src/yuzu/configuration/configure_input.h index e8723dfcb..1649e4c0b 100644 --- a/src/yuzu/configuration/configure_input.h +++ b/src/yuzu/configuration/configure_input.h | |||
| @@ -25,6 +25,7 @@ class ConfigureInput : public QWidget { | |||
| 25 | 25 | ||
| 26 | public: | 26 | public: |
| 27 | explicit ConfigureInput(QWidget* parent = nullptr); | 27 | explicit ConfigureInput(QWidget* parent = nullptr); |
| 28 | ~ConfigureInput() override; | ||
| 28 | 29 | ||
| 29 | /// Save all button configurations to settings file | 30 | /// Save all button configurations to settings file |
| 30 | void applyConfiguration(); | 31 | void applyConfiguration(); |
diff --git a/src/yuzu/configuration/configure_web.h b/src/yuzu/configuration/configure_web.h index 7741ab95d..7752ae4a1 100644 --- a/src/yuzu/configuration/configure_web.h +++ b/src/yuzu/configuration/configure_web.h | |||
| @@ -17,18 +17,17 @@ class ConfigureWeb : public QWidget { | |||
| 17 | 17 | ||
| 18 | public: | 18 | public: |
| 19 | explicit ConfigureWeb(QWidget* parent = nullptr); | 19 | explicit ConfigureWeb(QWidget* parent = nullptr); |
| 20 | ~ConfigureWeb(); | 20 | ~ConfigureWeb() override; |
| 21 | 21 | ||
| 22 | void applyConfiguration(); | 22 | void applyConfiguration(); |
| 23 | void retranslateUi(); | 23 | void retranslateUi(); |
| 24 | 24 | ||
| 25 | public slots: | 25 | private: |
| 26 | void RefreshTelemetryID(); | 26 | void RefreshTelemetryID(); |
| 27 | void OnLoginChanged(); | 27 | void OnLoginChanged(); |
| 28 | void VerifyLogin(); | 28 | void VerifyLogin(); |
| 29 | void OnLoginVerified(); | 29 | void OnLoginVerified(); |
| 30 | 30 | ||
| 31 | private: | ||
| 32 | void setConfiguration(); | 31 | void setConfiguration(); |
| 33 | 32 | ||
| 34 | bool user_verified = true; | 33 | bool user_verified = true; |
diff --git a/src/yuzu/debugger/wait_tree.cpp b/src/yuzu/debugger/wait_tree.cpp index 0c831c9f4..f9c18ede4 100644 --- a/src/yuzu/debugger/wait_tree.cpp +++ b/src/yuzu/debugger/wait_tree.cpp | |||
| @@ -7,10 +7,10 @@ | |||
| 7 | 7 | ||
| 8 | #include "common/assert.h" | 8 | #include "common/assert.h" |
| 9 | #include "core/core.h" | 9 | #include "core/core.h" |
| 10 | #include "core/hle/kernel/event.h" | ||
| 11 | #include "core/hle/kernel/handle_table.h" | 10 | #include "core/hle/kernel/handle_table.h" |
| 12 | #include "core/hle/kernel/mutex.h" | 11 | #include "core/hle/kernel/mutex.h" |
| 13 | #include "core/hle/kernel/process.h" | 12 | #include "core/hle/kernel/process.h" |
| 13 | #include "core/hle/kernel/readable_event.h" | ||
| 14 | #include "core/hle/kernel/scheduler.h" | 14 | #include "core/hle/kernel/scheduler.h" |
| 15 | #include "core/hle/kernel/thread.h" | 15 | #include "core/hle/kernel/thread.h" |
| 16 | #include "core/hle/kernel/timer.h" | 16 | #include "core/hle/kernel/timer.h" |
| @@ -153,8 +153,8 @@ QString WaitTreeWaitObject::GetText() const { | |||
| 153 | 153 | ||
| 154 | std::unique_ptr<WaitTreeWaitObject> WaitTreeWaitObject::make(const Kernel::WaitObject& object) { | 154 | std::unique_ptr<WaitTreeWaitObject> WaitTreeWaitObject::make(const Kernel::WaitObject& object) { |
| 155 | switch (object.GetHandleType()) { | 155 | switch (object.GetHandleType()) { |
| 156 | case Kernel::HandleType::Event: | 156 | case Kernel::HandleType::ReadableEvent: |
| 157 | return std::make_unique<WaitTreeEvent>(static_cast<const Kernel::Event&>(object)); | 157 | return std::make_unique<WaitTreeEvent>(static_cast<const Kernel::ReadableEvent&>(object)); |
| 158 | case Kernel::HandleType::Timer: | 158 | case Kernel::HandleType::Timer: |
| 159 | return std::make_unique<WaitTreeTimer>(static_cast<const Kernel::Timer&>(object)); | 159 | return std::make_unique<WaitTreeTimer>(static_cast<const Kernel::Timer&>(object)); |
| 160 | case Kernel::HandleType::Thread: | 160 | case Kernel::HandleType::Thread: |
| @@ -332,7 +332,7 @@ std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeThread::GetChildren() const { | |||
| 332 | return list; | 332 | return list; |
| 333 | } | 333 | } |
| 334 | 334 | ||
| 335 | WaitTreeEvent::WaitTreeEvent(const Kernel::Event& object) : WaitTreeWaitObject(object) {} | 335 | WaitTreeEvent::WaitTreeEvent(const Kernel::ReadableEvent& object) : WaitTreeWaitObject(object) {} |
| 336 | WaitTreeEvent::~WaitTreeEvent() = default; | 336 | WaitTreeEvent::~WaitTreeEvent() = default; |
| 337 | 337 | ||
| 338 | std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeEvent::GetChildren() const { | 338 | std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeEvent::GetChildren() const { |
| @@ -340,7 +340,8 @@ std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeEvent::GetChildren() const { | |||
| 340 | 340 | ||
| 341 | list.push_back(std::make_unique<WaitTreeText>( | 341 | list.push_back(std::make_unique<WaitTreeText>( |
| 342 | tr("reset type = %1") | 342 | tr("reset type = %1") |
| 343 | .arg(GetResetTypeQString(static_cast<const Kernel::Event&>(object).GetResetType())))); | 343 | .arg(GetResetTypeQString( |
| 344 | static_cast<const Kernel::ReadableEvent&>(object).GetResetType())))); | ||
| 344 | return list; | 345 | return list; |
| 345 | } | 346 | } |
| 346 | 347 | ||
diff --git a/src/yuzu/debugger/wait_tree.h b/src/yuzu/debugger/wait_tree.h index 331f89885..492fb6ac9 100644 --- a/src/yuzu/debugger/wait_tree.h +++ b/src/yuzu/debugger/wait_tree.h | |||
| @@ -17,8 +17,8 @@ | |||
| 17 | class EmuThread; | 17 | class EmuThread; |
| 18 | 18 | ||
| 19 | namespace Kernel { | 19 | namespace Kernel { |
| 20 | class ReadableEvent; | ||
| 20 | class WaitObject; | 21 | class WaitObject; |
| 21 | class Event; | ||
| 22 | class Thread; | 22 | class Thread; |
| 23 | class Timer; | 23 | class Timer; |
| 24 | } // namespace Kernel | 24 | } // namespace Kernel |
| @@ -144,7 +144,7 @@ public: | |||
| 144 | class WaitTreeEvent : public WaitTreeWaitObject { | 144 | class WaitTreeEvent : public WaitTreeWaitObject { |
| 145 | Q_OBJECT | 145 | Q_OBJECT |
| 146 | public: | 146 | public: |
| 147 | explicit WaitTreeEvent(const Kernel::Event& object); | 147 | explicit WaitTreeEvent(const Kernel::ReadableEvent& object); |
| 148 | ~WaitTreeEvent() override; | 148 | ~WaitTreeEvent() override; |
| 149 | 149 | ||
| 150 | std::vector<std::unique_ptr<WaitTreeItem>> GetChildren() const override; | 150 | std::vector<std::unique_ptr<WaitTreeItem>> GetChildren() const override; |
diff --git a/src/yuzu/game_list_worker.cpp b/src/yuzu/game_list_worker.cpp index 362902e46..1edc60df7 100644 --- a/src/yuzu/game_list_worker.cpp +++ b/src/yuzu/game_list_worker.cpp | |||
| @@ -97,11 +97,11 @@ GameListWorker::~GameListWorker() = default; | |||
| 97 | 97 | ||
| 98 | void GameListWorker::AddInstalledTitlesToGameList() { | 98 | void GameListWorker::AddInstalledTitlesToGameList() { |
| 99 | const auto cache = Service::FileSystem::GetUnionContents(); | 99 | const auto cache = Service::FileSystem::GetUnionContents(); |
| 100 | const auto installed_games = cache->ListEntriesFilter(FileSys::TitleType::Application, | 100 | const auto installed_games = cache.ListEntriesFilter(FileSys::TitleType::Application, |
| 101 | FileSys::ContentRecordType::Program); | 101 | FileSys::ContentRecordType::Program); |
| 102 | 102 | ||
| 103 | for (const auto& game : installed_games) { | 103 | for (const auto& game : installed_games) { |
| 104 | const auto file = cache->GetEntryUnparsed(game); | 104 | const auto file = cache.GetEntryUnparsed(game); |
| 105 | std::unique_ptr<Loader::AppLoader> loader = Loader::GetLoader(file); | 105 | std::unique_ptr<Loader::AppLoader> loader = Loader::GetLoader(file); |
| 106 | if (!loader) | 106 | if (!loader) |
| 107 | continue; | 107 | continue; |
| @@ -112,7 +112,7 @@ void GameListWorker::AddInstalledTitlesToGameList() { | |||
| 112 | loader->ReadProgramId(program_id); | 112 | loader->ReadProgramId(program_id); |
| 113 | 113 | ||
| 114 | const FileSys::PatchManager patch{program_id}; | 114 | const FileSys::PatchManager patch{program_id}; |
| 115 | const auto control = cache->GetEntry(game.title_id, FileSys::ContentRecordType::Control); | 115 | const auto control = cache.GetEntry(game.title_id, FileSys::ContentRecordType::Control); |
| 116 | if (control != nullptr) | 116 | if (control != nullptr) |
| 117 | GetMetadataFromControlNCA(patch, *control, icon, name); | 117 | GetMetadataFromControlNCA(patch, *control, icon, name); |
| 118 | 118 | ||
| @@ -141,11 +141,11 @@ void GameListWorker::AddInstalledTitlesToGameList() { | |||
| 141 | emit EntryReady(list); | 141 | emit EntryReady(list); |
| 142 | } | 142 | } |
| 143 | 143 | ||
| 144 | const auto control_data = cache->ListEntriesFilter(FileSys::TitleType::Application, | 144 | const auto control_data = cache.ListEntriesFilter(FileSys::TitleType::Application, |
| 145 | FileSys::ContentRecordType::Control); | 145 | FileSys::ContentRecordType::Control); |
| 146 | 146 | ||
| 147 | for (const auto& entry : control_data) { | 147 | for (const auto& entry : control_data) { |
| 148 | auto nca = cache->GetEntry(entry); | 148 | auto nca = cache.GetEntry(entry); |
| 149 | if (nca != nullptr) { | 149 | if (nca != nullptr) { |
| 150 | nca_control_map.insert_or_assign(entry.title_id, std::move(nca)); | 150 | nca_control_map.insert_or_assign(entry.title_id, std::move(nca)); |
| 151 | } | 151 | } |
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index d4010001d..22c207a3a 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp | |||
| @@ -907,7 +907,7 @@ void GMainWindow::OnGameListDumpRomFS(u64 program_id, const std::string& game_pa | |||
| 907 | } | 907 | } |
| 908 | 908 | ||
| 909 | const auto installed = Service::FileSystem::GetUnionContents(); | 909 | const auto installed = Service::FileSystem::GetUnionContents(); |
| 910 | auto romfs_title_id = SelectRomFSDumpTarget(*installed, program_id); | 910 | const auto romfs_title_id = SelectRomFSDumpTarget(installed, program_id); |
| 911 | 911 | ||
| 912 | if (!romfs_title_id) { | 912 | if (!romfs_title_id) { |
| 913 | failed(); | 913 | failed(); |
| @@ -922,7 +922,7 @@ void GMainWindow::OnGameListDumpRomFS(u64 program_id, const std::string& game_pa | |||
| 922 | if (*romfs_title_id == program_id) { | 922 | if (*romfs_title_id == program_id) { |
| 923 | romfs = file; | 923 | romfs = file; |
| 924 | } else { | 924 | } else { |
| 925 | romfs = installed->GetEntry(*romfs_title_id, FileSys::ContentRecordType::Data)->GetRomFS(); | 925 | romfs = installed.GetEntry(*romfs_title_id, FileSys::ContentRecordType::Data)->GetRomFS(); |
| 926 | } | 926 | } |
| 927 | 927 | ||
| 928 | const auto extracted = FileSys::ExtractRomFS(romfs, FileSys::RomFSExtractionType::Full); | 928 | const auto extracted = FileSys::ExtractRomFS(romfs, FileSys::RomFSExtractionType::Full); |