diff options
Diffstat (limited to 'src')
66 files changed, 749 insertions, 697 deletions
diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index 9c6f1c07c..9b0c3db68 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt | |||
| @@ -3,17 +3,8 @@ | |||
| 3 | # could affect the result, but much more unlikely than the following files. Keeping a list of files | 3 | # could affect the result, but much more unlikely than the following files. Keeping a list of files |
| 4 | # like this allows for much better caching since it doesn't force the user to recompile binary shaders every update | 4 | # like this allows for much better caching since it doesn't force the user to recompile binary shaders every update |
| 5 | set(VIDEO_CORE "${CMAKE_SOURCE_DIR}/src/video_core") | 5 | set(VIDEO_CORE "${CMAKE_SOURCE_DIR}/src/video_core") |
| 6 | if (DEFINED ENV{CI}) | 6 | if (DEFINED ENV{AZURECIREPO}) |
| 7 | if (DEFINED ENV{TRAVIS}) | 7 | set(BUILD_REPOSITORY $ENV{AZURECIREPO}) |
| 8 | set(BUILD_REPOSITORY $ENV{TRAVIS_REPO_SLUG}) | ||
| 9 | set(BUILD_TAG $ENV{TRAVIS_TAG}) | ||
| 10 | elseif(DEFINED ENV{APPVEYOR}) | ||
| 11 | set(BUILD_REPOSITORY $ENV{APPVEYOR_REPO_NAME}) | ||
| 12 | set(BUILD_TAG $ENV{APPVEYOR_REPO_TAG_NAME}) | ||
| 13 | elseif(DEFINED ENV{AZURE}) | ||
| 14 | set(BUILD_REPOSITORY $ENV{AZURE_REPO_NAME}) | ||
| 15 | set(BUILD_TAG $ENV{AZURE_REPO_TAG}) | ||
| 16 | endif() | ||
| 17 | endif() | 8 | endif() |
| 18 | if (DEFINED ENV{TITLEBARFORMATIDLE}) | 9 | if (DEFINED ENV{TITLEBARFORMATIDLE}) |
| 19 | set(TITLE_BAR_FORMAT_IDLE $ENV{TITLEBARFORMATIDLE}) | 10 | set(TITLE_BAR_FORMAT_IDLE $ENV{TITLEBARFORMATIDLE}) |
diff --git a/src/common/bit_field.h b/src/common/bit_field.h index 902e668e3..fd2bbbd99 100644 --- a/src/common/bit_field.h +++ b/src/common/bit_field.h | |||
| @@ -36,6 +36,13 @@ | |||
| 36 | #include "common/common_funcs.h" | 36 | #include "common/common_funcs.h" |
| 37 | #include "common/swap.h" | 37 | #include "common/swap.h" |
| 38 | 38 | ||
| 39 | // Inlining | ||
| 40 | #ifdef _WIN32 | ||
| 41 | #define FORCE_INLINE __forceinline | ||
| 42 | #else | ||
| 43 | #define FORCE_INLINE inline __attribute__((always_inline)) | ||
| 44 | #endif | ||
| 45 | |||
| 39 | /* | 46 | /* |
| 40 | * Abstract bitfield class | 47 | * Abstract bitfield class |
| 41 | * | 48 | * |
| @@ -168,11 +175,11 @@ public: | |||
| 168 | constexpr BitField(BitField&&) noexcept = default; | 175 | constexpr BitField(BitField&&) noexcept = default; |
| 169 | constexpr BitField& operator=(BitField&&) noexcept = default; | 176 | constexpr BitField& operator=(BitField&&) noexcept = default; |
| 170 | 177 | ||
| 171 | constexpr FORCE_INLINE operator T() const { | 178 | constexpr operator T() const { |
| 172 | return Value(); | 179 | return Value(); |
| 173 | } | 180 | } |
| 174 | 181 | ||
| 175 | constexpr FORCE_INLINE void Assign(const T& value) { | 182 | constexpr void Assign(const T& value) { |
| 176 | storage = (static_cast<StorageType>(storage) & ~mask) | FormatValue(value); | 183 | storage = (static_cast<StorageType>(storage) & ~mask) | FormatValue(value); |
| 177 | } | 184 | } |
| 178 | 185 | ||
diff --git a/src/common/common_funcs.h b/src/common/common_funcs.h index 04ecac959..c029dc7b3 100644 --- a/src/common/common_funcs.h +++ b/src/common/common_funcs.h | |||
| @@ -1,10 +1,11 @@ | |||
| 1 | // Copyright 2013 Dolphin Emulator Project / 2014 Citra Emulator Project | 1 | // Copyright 2019 yuzu emulator team |
| 2 | // Licensed under GPLv2 or any later version | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #pragma once | 5 | #pragma once |
| 6 | 6 | ||
| 7 | #include <algorithm> | 7 | #include <algorithm> |
| 8 | #include <array> | ||
| 8 | #include <string> | 9 | #include <string> |
| 9 | 10 | ||
| 10 | #if !defined(ARCHITECTURE_x86_64) | 11 | #if !defined(ARCHITECTURE_x86_64) |
| @@ -16,18 +17,15 @@ | |||
| 16 | #define CONCAT2(x, y) DO_CONCAT2(x, y) | 17 | #define CONCAT2(x, y) DO_CONCAT2(x, y) |
| 17 | #define DO_CONCAT2(x, y) x##y | 18 | #define DO_CONCAT2(x, y) x##y |
| 18 | 19 | ||
| 19 | // helper macro to properly align structure members. | 20 | /// Helper macros to insert unused bytes or words to properly align structs. These values will be |
| 20 | // Calling INSERT_PADDING_BYTES will add a new member variable with a name like "pad121", | 21 | /// zero-initialized. |
| 21 | // depending on the current source line to make sure variable names are unique. | 22 | #define INSERT_PADDING_BYTES(num_bytes) std::array<u8, num_bytes> CONCAT2(pad, __LINE__){}; |
| 22 | #define INSERT_PADDING_BYTES(num_bytes) u8 CONCAT2(pad, __LINE__)[(num_bytes)] | 23 | #define INSERT_PADDING_WORDS(num_words) std::array<u32, num_words> CONCAT2(pad, __LINE__){}; |
| 23 | #define INSERT_PADDING_WORDS(num_words) u32 CONCAT2(pad, __LINE__)[(num_words)] | ||
| 24 | 24 | ||
| 25 | // Inlining | 25 | /// These are similar to the INSERT_PADDING_* macros, but are needed for padding unions. This is |
| 26 | #ifdef _WIN32 | 26 | /// because unions can only be initialized by one member. |
| 27 | #define FORCE_INLINE __forceinline | 27 | #define INSERT_UNION_PADDING_BYTES(num_bytes) std::array<u8, num_bytes> CONCAT2(pad, __LINE__); |
| 28 | #else | 28 | #define INSERT_UNION_PADDING_WORDS(num_words) std::array<u32, num_words> CONCAT2(pad, __LINE__); |
| 29 | #define FORCE_INLINE inline __attribute__((always_inline)) | ||
| 30 | #endif | ||
| 31 | 29 | ||
| 32 | #ifndef _MSC_VER | 30 | #ifndef _MSC_VER |
| 33 | 31 | ||
diff --git a/src/core/file_sys/content_archive.cpp b/src/core/file_sys/content_archive.cpp index ea5c92f61..b8bbdd1ef 100644 --- a/src/core/file_sys/content_archive.cpp +++ b/src/core/file_sys/content_archive.cpp | |||
| @@ -32,11 +32,28 @@ enum class NCASectionFilesystemType : u8 { | |||
| 32 | ROMFS = 0x3, | 32 | ROMFS = 0x3, |
| 33 | }; | 33 | }; |
| 34 | 34 | ||
| 35 | struct IVFCLevel { | ||
| 36 | u64_le offset; | ||
| 37 | u64_le size; | ||
| 38 | u32_le block_size; | ||
| 39 | u32_le reserved; | ||
| 40 | }; | ||
| 41 | static_assert(sizeof(IVFCLevel) == 0x18, "IVFCLevel has incorrect size."); | ||
| 42 | |||
| 43 | struct IVFCHeader { | ||
| 44 | u32_le magic; | ||
| 45 | u32_le magic_number; | ||
| 46 | INSERT_UNION_PADDING_BYTES(8); | ||
| 47 | std::array<IVFCLevel, 6> levels; | ||
| 48 | INSERT_UNION_PADDING_BYTES(64); | ||
| 49 | }; | ||
| 50 | static_assert(sizeof(IVFCHeader) == 0xE0, "IVFCHeader has incorrect size."); | ||
| 51 | |||
| 35 | struct NCASectionHeaderBlock { | 52 | struct NCASectionHeaderBlock { |
| 36 | INSERT_PADDING_BYTES(3); | 53 | INSERT_UNION_PADDING_BYTES(3); |
| 37 | NCASectionFilesystemType filesystem_type; | 54 | NCASectionFilesystemType filesystem_type; |
| 38 | NCASectionCryptoType crypto_type; | 55 | NCASectionCryptoType crypto_type; |
| 39 | INSERT_PADDING_BYTES(3); | 56 | INSERT_UNION_PADDING_BYTES(3); |
| 40 | }; | 57 | }; |
| 41 | static_assert(sizeof(NCASectionHeaderBlock) == 0x8, "NCASectionHeaderBlock has incorrect size."); | 58 | static_assert(sizeof(NCASectionHeaderBlock) == 0x8, "NCASectionHeaderBlock has incorrect size."); |
| 42 | 59 | ||
| @@ -44,7 +61,7 @@ struct NCASectionRaw { | |||
| 44 | NCASectionHeaderBlock header; | 61 | NCASectionHeaderBlock header; |
| 45 | std::array<u8, 0x138> block_data; | 62 | std::array<u8, 0x138> block_data; |
| 46 | std::array<u8, 0x8> section_ctr; | 63 | std::array<u8, 0x8> section_ctr; |
| 47 | INSERT_PADDING_BYTES(0xB8); | 64 | INSERT_UNION_PADDING_BYTES(0xB8); |
| 48 | }; | 65 | }; |
| 49 | static_assert(sizeof(NCASectionRaw) == 0x200, "NCASectionRaw has incorrect size."); | 66 | static_assert(sizeof(NCASectionRaw) == 0x200, "NCASectionRaw has incorrect size."); |
| 50 | 67 | ||
| @@ -52,19 +69,19 @@ struct PFS0Superblock { | |||
| 52 | NCASectionHeaderBlock header_block; | 69 | NCASectionHeaderBlock header_block; |
| 53 | std::array<u8, 0x20> hash; | 70 | std::array<u8, 0x20> hash; |
| 54 | u32_le size; | 71 | u32_le size; |
| 55 | INSERT_PADDING_BYTES(4); | 72 | INSERT_UNION_PADDING_BYTES(4); |
| 56 | u64_le hash_table_offset; | 73 | u64_le hash_table_offset; |
| 57 | u64_le hash_table_size; | 74 | u64_le hash_table_size; |
| 58 | u64_le pfs0_header_offset; | 75 | u64_le pfs0_header_offset; |
| 59 | u64_le pfs0_size; | 76 | u64_le pfs0_size; |
| 60 | INSERT_PADDING_BYTES(0x1B0); | 77 | INSERT_UNION_PADDING_BYTES(0x1B0); |
| 61 | }; | 78 | }; |
| 62 | static_assert(sizeof(PFS0Superblock) == 0x200, "PFS0Superblock has incorrect size."); | 79 | static_assert(sizeof(PFS0Superblock) == 0x200, "PFS0Superblock has incorrect size."); |
| 63 | 80 | ||
| 64 | struct RomFSSuperblock { | 81 | struct RomFSSuperblock { |
| 65 | NCASectionHeaderBlock header_block; | 82 | NCASectionHeaderBlock header_block; |
| 66 | IVFCHeader ivfc; | 83 | IVFCHeader ivfc; |
| 67 | INSERT_PADDING_BYTES(0x118); | 84 | INSERT_UNION_PADDING_BYTES(0x118); |
| 68 | }; | 85 | }; |
| 69 | static_assert(sizeof(RomFSSuperblock) == 0x200, "RomFSSuperblock has incorrect size."); | 86 | static_assert(sizeof(RomFSSuperblock) == 0x200, "RomFSSuperblock has incorrect size."); |
| 70 | 87 | ||
| @@ -72,24 +89,24 @@ struct BKTRHeader { | |||
| 72 | u64_le offset; | 89 | u64_le offset; |
| 73 | u64_le size; | 90 | u64_le size; |
| 74 | u32_le magic; | 91 | u32_le magic; |
| 75 | INSERT_PADDING_BYTES(0x4); | 92 | INSERT_UNION_PADDING_BYTES(0x4); |
| 76 | u32_le number_entries; | 93 | u32_le number_entries; |
| 77 | INSERT_PADDING_BYTES(0x4); | 94 | INSERT_UNION_PADDING_BYTES(0x4); |
| 78 | }; | 95 | }; |
| 79 | static_assert(sizeof(BKTRHeader) == 0x20, "BKTRHeader has incorrect size."); | 96 | static_assert(sizeof(BKTRHeader) == 0x20, "BKTRHeader has incorrect size."); |
| 80 | 97 | ||
| 81 | struct BKTRSuperblock { | 98 | struct BKTRSuperblock { |
| 82 | NCASectionHeaderBlock header_block; | 99 | NCASectionHeaderBlock header_block; |
| 83 | IVFCHeader ivfc; | 100 | IVFCHeader ivfc; |
| 84 | INSERT_PADDING_BYTES(0x18); | 101 | INSERT_UNION_PADDING_BYTES(0x18); |
| 85 | BKTRHeader relocation; | 102 | BKTRHeader relocation; |
| 86 | BKTRHeader subsection; | 103 | BKTRHeader subsection; |
| 87 | INSERT_PADDING_BYTES(0xC0); | 104 | INSERT_UNION_PADDING_BYTES(0xC0); |
| 88 | }; | 105 | }; |
| 89 | static_assert(sizeof(BKTRSuperblock) == 0x200, "BKTRSuperblock has incorrect size."); | 106 | static_assert(sizeof(BKTRSuperblock) == 0x200, "BKTRSuperblock has incorrect size."); |
| 90 | 107 | ||
| 91 | union NCASectionHeader { | 108 | union NCASectionHeader { |
| 92 | NCASectionRaw raw; | 109 | NCASectionRaw raw{}; |
| 93 | PFS0Superblock pfs0; | 110 | PFS0Superblock pfs0; |
| 94 | RomFSSuperblock romfs; | 111 | RomFSSuperblock romfs; |
| 95 | BKTRSuperblock bktr; | 112 | BKTRSuperblock bktr; |
diff --git a/src/core/file_sys/romfs.h b/src/core/file_sys/romfs.h index 0f35639bc..1c89be8a4 100644 --- a/src/core/file_sys/romfs.h +++ b/src/core/file_sys/romfs.h | |||
| @@ -13,25 +13,6 @@ | |||
| 13 | 13 | ||
| 14 | namespace FileSys { | 14 | namespace FileSys { |
| 15 | 15 | ||
| 16 | struct RomFSHeader; | ||
| 17 | |||
| 18 | struct IVFCLevel { | ||
| 19 | u64_le offset; | ||
| 20 | u64_le size; | ||
| 21 | u32_le block_size; | ||
| 22 | u32_le reserved; | ||
| 23 | }; | ||
| 24 | static_assert(sizeof(IVFCLevel) == 0x18, "IVFCLevel has incorrect size."); | ||
| 25 | |||
| 26 | struct IVFCHeader { | ||
| 27 | u32_le magic; | ||
| 28 | u32_le magic_number; | ||
| 29 | INSERT_PADDING_BYTES(8); | ||
| 30 | std::array<IVFCLevel, 6> levels; | ||
| 31 | INSERT_PADDING_BYTES(64); | ||
| 32 | }; | ||
| 33 | static_assert(sizeof(IVFCHeader) == 0xE0, "IVFCHeader has incorrect size."); | ||
| 34 | |||
| 35 | enum class RomFSExtractionType { | 16 | enum class RomFSExtractionType { |
| 36 | Full, // Includes data directory | 17 | Full, // Includes data directory |
| 37 | Truncated, // Traverses into data directory | 18 | Truncated, // Traverses into data directory |
diff --git a/src/core/hle/ipc.h b/src/core/hle/ipc.h index fae54bcc7..7ce313190 100644 --- a/src/core/hle/ipc.h +++ b/src/core/hle/ipc.h | |||
| @@ -160,7 +160,7 @@ struct DomainMessageHeader { | |||
| 160 | // Used when responding to an IPC request, Server -> Client. | 160 | // Used when responding to an IPC request, Server -> Client. |
| 161 | struct { | 161 | struct { |
| 162 | u32_le num_objects; | 162 | u32_le num_objects; |
| 163 | INSERT_PADDING_WORDS(3); | 163 | INSERT_UNION_PADDING_WORDS(3); |
| 164 | }; | 164 | }; |
| 165 | 165 | ||
| 166 | // Used when performing an IPC request, Client -> Server. | 166 | // Used when performing an IPC request, Client -> Server. |
| @@ -171,8 +171,10 @@ struct DomainMessageHeader { | |||
| 171 | BitField<16, 16, u32> size; | 171 | BitField<16, 16, u32> size; |
| 172 | }; | 172 | }; |
| 173 | u32_le object_id; | 173 | u32_le object_id; |
| 174 | INSERT_PADDING_WORDS(2); | 174 | INSERT_UNION_PADDING_WORDS(2); |
| 175 | }; | 175 | }; |
| 176 | |||
| 177 | std::array<u32, 4> raw{}; | ||
| 176 | }; | 178 | }; |
| 177 | }; | 179 | }; |
| 178 | static_assert(sizeof(DomainMessageHeader) == 16, "DomainMessageHeader size is incorrect"); | 180 | static_assert(sizeof(DomainMessageHeader) == 16, "DomainMessageHeader size is incorrect"); |
diff --git a/src/core/hle/kernel/hle_ipc.cpp b/src/core/hle/kernel/hle_ipc.cpp index f3da525d6..a7b5849b0 100644 --- a/src/core/hle/kernel/hle_ipc.cpp +++ b/src/core/hle/kernel/hle_ipc.cpp | |||
| @@ -58,8 +58,7 @@ SharedPtr<WritableEvent> HLERequestContext::SleepClientThread( | |||
| 58 | auto& kernel = Core::System::GetInstance().Kernel(); | 58 | auto& kernel = Core::System::GetInstance().Kernel(); |
| 59 | if (!writable_event) { | 59 | if (!writable_event) { |
| 60 | // Create event if not provided | 60 | // Create event if not provided |
| 61 | const auto pair = WritableEvent::CreateEventPair(kernel, ResetType::Automatic, | 61 | const auto pair = WritableEvent::CreateEventPair(kernel, "HLE Pause Event: " + reason); |
| 62 | "HLE Pause Event: " + reason); | ||
| 63 | writable_event = pair.writable; | 62 | writable_event = pair.writable; |
| 64 | } | 63 | } |
| 65 | 64 | ||
diff --git a/src/core/hle/kernel/object.h b/src/core/hle/kernel/object.h index 2821176a7..a6faeb83b 100644 --- a/src/core/hle/kernel/object.h +++ b/src/core/hle/kernel/object.h | |||
| @@ -32,11 +32,6 @@ enum class HandleType : u32 { | |||
| 32 | ServerSession, | 32 | ServerSession, |
| 33 | }; | 33 | }; |
| 34 | 34 | ||
| 35 | enum class ResetType { | ||
| 36 | Automatic, ///< Reset automatically on object acquisition | ||
| 37 | Manual, ///< Never reset automatically | ||
| 38 | }; | ||
| 39 | |||
| 40 | class Object : NonCopyable { | 35 | class Object : NonCopyable { |
| 41 | public: | 36 | public: |
| 42 | explicit Object(KernelCore& kernel); | 37 | explicit Object(KernelCore& kernel); |
diff --git a/src/core/hle/kernel/readable_event.cpp b/src/core/hle/kernel/readable_event.cpp index 06463cd26..d8ac97aa1 100644 --- a/src/core/hle/kernel/readable_event.cpp +++ b/src/core/hle/kernel/readable_event.cpp | |||
| @@ -20,15 +20,13 @@ bool ReadableEvent::ShouldWait(const Thread* thread) const { | |||
| 20 | 20 | ||
| 21 | void ReadableEvent::Acquire(Thread* thread) { | 21 | void ReadableEvent::Acquire(Thread* thread) { |
| 22 | ASSERT_MSG(!ShouldWait(thread), "object unavailable!"); | 22 | ASSERT_MSG(!ShouldWait(thread), "object unavailable!"); |
| 23 | |||
| 24 | if (reset_type == ResetType::Automatic) { | ||
| 25 | signaled = false; | ||
| 26 | } | ||
| 27 | } | 23 | } |
| 28 | 24 | ||
| 29 | void ReadableEvent::Signal() { | 25 | void ReadableEvent::Signal() { |
| 30 | signaled = true; | 26 | if (!signaled) { |
| 31 | WakeupAllWaitingThreads(); | 27 | signaled = true; |
| 28 | WakeupAllWaitingThreads(); | ||
| 29 | }; | ||
| 32 | } | 30 | } |
| 33 | 31 | ||
| 34 | void ReadableEvent::Clear() { | 32 | void ReadableEvent::Clear() { |
diff --git a/src/core/hle/kernel/readable_event.h b/src/core/hle/kernel/readable_event.h index 84215f572..11ff71c3a 100644 --- a/src/core/hle/kernel/readable_event.h +++ b/src/core/hle/kernel/readable_event.h | |||
| @@ -27,10 +27,6 @@ public: | |||
| 27 | return name; | 27 | return name; |
| 28 | } | 28 | } |
| 29 | 29 | ||
| 30 | ResetType GetResetType() const { | ||
| 31 | return reset_type; | ||
| 32 | } | ||
| 33 | |||
| 34 | static constexpr HandleType HANDLE_TYPE = HandleType::ReadableEvent; | 30 | static constexpr HandleType HANDLE_TYPE = HandleType::ReadableEvent; |
| 35 | HandleType GetHandleType() const override { | 31 | HandleType GetHandleType() const override { |
| 36 | return HANDLE_TYPE; | 32 | return HANDLE_TYPE; |
| @@ -55,8 +51,7 @@ private: | |||
| 55 | 51 | ||
| 56 | void Signal(); | 52 | void Signal(); |
| 57 | 53 | ||
| 58 | ResetType reset_type; | 54 | bool signaled{}; |
| 59 | bool signaled; | ||
| 60 | 55 | ||
| 61 | std::string name; ///< Name of event (optional) | 56 | std::string name; ///< Name of event (optional) |
| 62 | }; | 57 | }; |
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index f64236be1..c63a9ba8b 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp | |||
| @@ -2099,7 +2099,7 @@ static ResultCode CreateEvent(Core::System& system, Handle* write_handle, Handle | |||
| 2099 | 2099 | ||
| 2100 | auto& kernel = system.Kernel(); | 2100 | auto& kernel = system.Kernel(); |
| 2101 | const auto [readable_event, writable_event] = | 2101 | const auto [readable_event, writable_event] = |
| 2102 | WritableEvent::CreateEventPair(kernel, ResetType::Manual, "CreateEvent"); | 2102 | WritableEvent::CreateEventPair(kernel, "CreateEvent"); |
| 2103 | 2103 | ||
| 2104 | HandleTable& handle_table = kernel.CurrentProcess()->GetHandleTable(); | 2104 | HandleTable& handle_table = kernel.CurrentProcess()->GetHandleTable(); |
| 2105 | 2105 | ||
diff --git a/src/core/hle/kernel/writable_event.cpp b/src/core/hle/kernel/writable_event.cpp index a58ea6ec8..c783a34ee 100644 --- a/src/core/hle/kernel/writable_event.cpp +++ b/src/core/hle/kernel/writable_event.cpp | |||
| @@ -15,8 +15,7 @@ namespace Kernel { | |||
| 15 | WritableEvent::WritableEvent(KernelCore& kernel) : Object{kernel} {} | 15 | WritableEvent::WritableEvent(KernelCore& kernel) : Object{kernel} {} |
| 16 | WritableEvent::~WritableEvent() = default; | 16 | WritableEvent::~WritableEvent() = default; |
| 17 | 17 | ||
| 18 | EventPair WritableEvent::CreateEventPair(KernelCore& kernel, ResetType reset_type, | 18 | EventPair WritableEvent::CreateEventPair(KernelCore& kernel, std::string name) { |
| 19 | std::string name) { | ||
| 20 | SharedPtr<WritableEvent> writable_event(new WritableEvent(kernel)); | 19 | SharedPtr<WritableEvent> writable_event(new WritableEvent(kernel)); |
| 21 | SharedPtr<ReadableEvent> readable_event(new ReadableEvent(kernel)); | 20 | SharedPtr<ReadableEvent> readable_event(new ReadableEvent(kernel)); |
| 22 | 21 | ||
| @@ -24,7 +23,6 @@ EventPair WritableEvent::CreateEventPair(KernelCore& kernel, ResetType reset_typ | |||
| 24 | writable_event->readable = readable_event; | 23 | writable_event->readable = readable_event; |
| 25 | readable_event->name = name + ":Readable"; | 24 | readable_event->name = name + ":Readable"; |
| 26 | readable_event->signaled = false; | 25 | readable_event->signaled = false; |
| 27 | readable_event->reset_type = reset_type; | ||
| 28 | 26 | ||
| 29 | return {std::move(readable_event), std::move(writable_event)}; | 27 | return {std::move(readable_event), std::move(writable_event)}; |
| 30 | } | 28 | } |
| @@ -33,10 +31,6 @@ SharedPtr<ReadableEvent> WritableEvent::GetReadableEvent() const { | |||
| 33 | return readable; | 31 | return readable; |
| 34 | } | 32 | } |
| 35 | 33 | ||
| 36 | ResetType WritableEvent::GetResetType() const { | ||
| 37 | return readable->reset_type; | ||
| 38 | } | ||
| 39 | |||
| 40 | void WritableEvent::Signal() { | 34 | void WritableEvent::Signal() { |
| 41 | readable->Signal(); | 35 | readable->Signal(); |
| 42 | } | 36 | } |
diff --git a/src/core/hle/kernel/writable_event.h b/src/core/hle/kernel/writable_event.h index d00c92a6b..f46cf1dd8 100644 --- a/src/core/hle/kernel/writable_event.h +++ b/src/core/hle/kernel/writable_event.h | |||
| @@ -24,11 +24,9 @@ public: | |||
| 24 | /** | 24 | /** |
| 25 | * Creates an event | 25 | * Creates an event |
| 26 | * @param kernel The kernel instance to create this event under. | 26 | * @param kernel The kernel instance to create this event under. |
| 27 | * @param reset_type ResetType describing how to create event | ||
| 28 | * @param name Optional name of event | 27 | * @param name Optional name of event |
| 29 | */ | 28 | */ |
| 30 | static EventPair CreateEventPair(KernelCore& kernel, ResetType reset_type, | 29 | static EventPair CreateEventPair(KernelCore& kernel, std::string name = "Unknown"); |
| 31 | std::string name = "Unknown"); | ||
| 32 | 30 | ||
| 33 | std::string GetTypeName() const override { | 31 | std::string GetTypeName() const override { |
| 34 | return "WritableEvent"; | 32 | return "WritableEvent"; |
| @@ -44,8 +42,6 @@ public: | |||
| 44 | 42 | ||
| 45 | SharedPtr<ReadableEvent> GetReadableEvent() const; | 43 | SharedPtr<ReadableEvent> GetReadableEvent() const; |
| 46 | 44 | ||
| 47 | ResetType GetResetType() const; | ||
| 48 | |||
| 49 | void Signal(); | 45 | void Signal(); |
| 50 | void Clear(); | 46 | void Clear(); |
| 51 | bool IsSignaled() const; | 47 | bool IsSignaled() const; |
diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp index 3a32d5b41..ba54b3040 100644 --- a/src/core/hle/service/am/am.cpp +++ b/src/core/hle/service/am/am.cpp | |||
| @@ -289,8 +289,8 @@ ISelfController::ISelfController(Core::System& system, | |||
| 289 | RegisterHandlers(functions); | 289 | RegisterHandlers(functions); |
| 290 | 290 | ||
| 291 | auto& kernel = system.Kernel(); | 291 | auto& kernel = system.Kernel(); |
| 292 | launchable_event = Kernel::WritableEvent::CreateEventPair(kernel, Kernel::ResetType::Manual, | 292 | launchable_event = |
| 293 | "ISelfController:LaunchableEvent"); | 293 | Kernel::WritableEvent::CreateEventPair(kernel, "ISelfController:LaunchableEvent"); |
| 294 | 294 | ||
| 295 | // This event is created by AM on the first time GetAccumulatedSuspendedTickChangedEvent() is | 295 | // This event is created by AM on the first time GetAccumulatedSuspendedTickChangedEvent() is |
| 296 | // called. Yuzu can just create it unconditionally, since it doesn't need to support multiple | 296 | // called. Yuzu can just create it unconditionally, since it doesn't need to support multiple |
| @@ -298,7 +298,7 @@ ISelfController::ISelfController(Core::System& system, | |||
| 298 | // suspended if the event has previously been created by a call to | 298 | // suspended if the event has previously been created by a call to |
| 299 | // GetAccumulatedSuspendedTickChangedEvent. | 299 | // GetAccumulatedSuspendedTickChangedEvent. |
| 300 | accumulated_suspended_tick_changed_event = Kernel::WritableEvent::CreateEventPair( | 300 | accumulated_suspended_tick_changed_event = Kernel::WritableEvent::CreateEventPair( |
| 301 | kernel, Kernel::ResetType::Manual, "ISelfController:AccumulatedSuspendedTickChangedEvent"); | 301 | kernel, "ISelfController:AccumulatedSuspendedTickChangedEvent"); |
| 302 | accumulated_suspended_tick_changed_event.writable->Signal(); | 302 | accumulated_suspended_tick_changed_event.writable->Signal(); |
| 303 | } | 303 | } |
| 304 | 304 | ||
| @@ -523,10 +523,10 @@ void ISelfController::GetAccumulatedSuspendedTickChangedEvent(Kernel::HLERequest | |||
| 523 | } | 523 | } |
| 524 | 524 | ||
| 525 | AppletMessageQueue::AppletMessageQueue(Kernel::KernelCore& kernel) { | 525 | AppletMessageQueue::AppletMessageQueue(Kernel::KernelCore& kernel) { |
| 526 | on_new_message = Kernel::WritableEvent::CreateEventPair(kernel, Kernel::ResetType::Manual, | 526 | on_new_message = |
| 527 | "AMMessageQueue:OnMessageRecieved"); | 527 | Kernel::WritableEvent::CreateEventPair(kernel, "AMMessageQueue:OnMessageRecieved"); |
| 528 | on_operation_mode_changed = Kernel::WritableEvent::CreateEventPair( | 528 | on_operation_mode_changed = |
| 529 | kernel, Kernel::ResetType::Automatic, "AMMessageQueue:OperationModeChanged"); | 529 | Kernel::WritableEvent::CreateEventPair(kernel, "AMMessageQueue:OperationModeChanged"); |
| 530 | } | 530 | } |
| 531 | 531 | ||
| 532 | AppletMessageQueue::~AppletMessageQueue() = default; | 532 | AppletMessageQueue::~AppletMessageQueue() = default; |
| @@ -1073,9 +1073,9 @@ IApplicationFunctions::IApplicationFunctions(Core::System& system_) | |||
| 1073 | {71, nullptr, "RequestToReboot"}, | 1073 | {71, nullptr, "RequestToReboot"}, |
| 1074 | {80, nullptr, "ExitAndRequestToShowThanksMessage"}, | 1074 | {80, nullptr, "ExitAndRequestToShowThanksMessage"}, |
| 1075 | {90, &IApplicationFunctions::EnableApplicationCrashReport, "EnableApplicationCrashReport"}, | 1075 | {90, &IApplicationFunctions::EnableApplicationCrashReport, "EnableApplicationCrashReport"}, |
| 1076 | {100, nullptr, "InitializeApplicationCopyrightFrameBuffer"}, | 1076 | {100, &IApplicationFunctions::InitializeApplicationCopyrightFrameBuffer, "InitializeApplicationCopyrightFrameBuffer"}, |
| 1077 | {101, nullptr, "SetApplicationCopyrightImage"}, | 1077 | {101, &IApplicationFunctions::SetApplicationCopyrightImage, "SetApplicationCopyrightImage"}, |
| 1078 | {102, nullptr, "SetApplicationCopyrightVisibility"}, | 1078 | {102, &IApplicationFunctions::SetApplicationCopyrightVisibility, "SetApplicationCopyrightVisibility"}, |
| 1079 | {110, nullptr, "QueryApplicationPlayStatistics"}, | 1079 | {110, nullptr, "QueryApplicationPlayStatistics"}, |
| 1080 | {120, nullptr, "ExecuteProgram"}, | 1080 | {120, nullptr, "ExecuteProgram"}, |
| 1081 | {121, nullptr, "ClearUserChannel"}, | 1081 | {121, nullptr, "ClearUserChannel"}, |
| @@ -1091,7 +1091,7 @@ IApplicationFunctions::IApplicationFunctions(Core::System& system_) | |||
| 1091 | 1091 | ||
| 1092 | auto& kernel = system.Kernel(); | 1092 | auto& kernel = system.Kernel(); |
| 1093 | gpu_error_detected_event = Kernel::WritableEvent::CreateEventPair( | 1093 | gpu_error_detected_event = Kernel::WritableEvent::CreateEventPair( |
| 1094 | kernel, Kernel::ResetType::Manual, "IApplicationFunctions:GpuErrorDetectedSystemEvent"); | 1094 | kernel, "IApplicationFunctions:GpuErrorDetectedSystemEvent"); |
| 1095 | } | 1095 | } |
| 1096 | 1096 | ||
| 1097 | IApplicationFunctions::~IApplicationFunctions() = default; | 1097 | IApplicationFunctions::~IApplicationFunctions() = default; |
| @@ -1103,6 +1103,31 @@ void IApplicationFunctions::EnableApplicationCrashReport(Kernel::HLERequestConte | |||
| 1103 | rb.Push(RESULT_SUCCESS); | 1103 | rb.Push(RESULT_SUCCESS); |
| 1104 | } | 1104 | } |
| 1105 | 1105 | ||
| 1106 | void IApplicationFunctions::InitializeApplicationCopyrightFrameBuffer( | ||
| 1107 | Kernel::HLERequestContext& ctx) { | ||
| 1108 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 1109 | |||
| 1110 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 1111 | rb.Push(RESULT_SUCCESS); | ||
| 1112 | } | ||
| 1113 | |||
| 1114 | void IApplicationFunctions::SetApplicationCopyrightImage(Kernel::HLERequestContext& ctx) { | ||
| 1115 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 1116 | |||
| 1117 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 1118 | rb.Push(RESULT_SUCCESS); | ||
| 1119 | } | ||
| 1120 | |||
| 1121 | void IApplicationFunctions::SetApplicationCopyrightVisibility(Kernel::HLERequestContext& ctx) { | ||
| 1122 | IPC::RequestParser rp{ctx}; | ||
| 1123 | const auto is_visible = rp.Pop<bool>(); | ||
| 1124 | |||
| 1125 | LOG_WARNING(Service_AM, "(STUBBED) called, is_visible={}", is_visible); | ||
| 1126 | |||
| 1127 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 1128 | rb.Push(RESULT_SUCCESS); | ||
| 1129 | } | ||
| 1130 | |||
| 1106 | void IApplicationFunctions::BeginBlockingHomeButtonShortAndLongPressed( | 1131 | void IApplicationFunctions::BeginBlockingHomeButtonShortAndLongPressed( |
| 1107 | Kernel::HLERequestContext& ctx) { | 1132 | Kernel::HLERequestContext& ctx) { |
| 1108 | LOG_WARNING(Service_AM, "(STUBBED) called"); | 1133 | LOG_WARNING(Service_AM, "(STUBBED) called"); |
diff --git a/src/core/hle/service/am/am.h b/src/core/hle/service/am/am.h index ccd053c13..2ae9402a8 100644 --- a/src/core/hle/service/am/am.h +++ b/src/core/hle/service/am/am.h | |||
| @@ -252,6 +252,9 @@ private: | |||
| 252 | void BeginBlockingHomeButton(Kernel::HLERequestContext& ctx); | 252 | void BeginBlockingHomeButton(Kernel::HLERequestContext& ctx); |
| 253 | void EndBlockingHomeButton(Kernel::HLERequestContext& ctx); | 253 | void EndBlockingHomeButton(Kernel::HLERequestContext& ctx); |
| 254 | void EnableApplicationCrashReport(Kernel::HLERequestContext& ctx); | 254 | void EnableApplicationCrashReport(Kernel::HLERequestContext& ctx); |
| 255 | void InitializeApplicationCopyrightFrameBuffer(Kernel::HLERequestContext& ctx); | ||
| 256 | void SetApplicationCopyrightImage(Kernel::HLERequestContext& ctx); | ||
| 257 | void SetApplicationCopyrightVisibility(Kernel::HLERequestContext& ctx); | ||
| 255 | void GetGpuErrorDetectedSystemEvent(Kernel::HLERequestContext& ctx); | 258 | void GetGpuErrorDetectedSystemEvent(Kernel::HLERequestContext& ctx); |
| 256 | 259 | ||
| 257 | bool launch_popped_application_specific = false; | 260 | bool launch_popped_application_specific = false; |
diff --git a/src/core/hle/service/am/applets/applets.cpp b/src/core/hle/service/am/applets/applets.cpp index 720fe766f..673ad1f7f 100644 --- a/src/core/hle/service/am/applets/applets.cpp +++ b/src/core/hle/service/am/applets/applets.cpp | |||
| @@ -24,12 +24,12 @@ | |||
| 24 | namespace Service::AM::Applets { | 24 | namespace Service::AM::Applets { |
| 25 | 25 | ||
| 26 | AppletDataBroker::AppletDataBroker(Kernel::KernelCore& kernel) { | 26 | AppletDataBroker::AppletDataBroker(Kernel::KernelCore& kernel) { |
| 27 | state_changed_event = Kernel::WritableEvent::CreateEventPair( | 27 | state_changed_event = |
| 28 | kernel, Kernel::ResetType::Manual, "ILibraryAppletAccessor:StateChangedEvent"); | 28 | Kernel::WritableEvent::CreateEventPair(kernel, "ILibraryAppletAccessor:StateChangedEvent"); |
| 29 | pop_out_data_event = Kernel::WritableEvent::CreateEventPair( | 29 | pop_out_data_event = |
| 30 | kernel, Kernel::ResetType::Manual, "ILibraryAppletAccessor:PopDataOutEvent"); | 30 | Kernel::WritableEvent::CreateEventPair(kernel, "ILibraryAppletAccessor:PopDataOutEvent"); |
| 31 | pop_interactive_out_data_event = Kernel::WritableEvent::CreateEventPair( | 31 | pop_interactive_out_data_event = Kernel::WritableEvent::CreateEventPair( |
| 32 | kernel, Kernel::ResetType::Manual, "ILibraryAppletAccessor:PopInteractiveDataOutEvent"); | 32 | kernel, "ILibraryAppletAccessor:PopInteractiveDataOutEvent"); |
| 33 | } | 33 | } |
| 34 | 34 | ||
| 35 | AppletDataBroker::~AppletDataBroker() = default; | 35 | AppletDataBroker::~AppletDataBroker() = default; |
diff --git a/src/core/hle/service/am/applets/error.cpp b/src/core/hle/service/am/applets/error.cpp index a7db26725..eab0d42c9 100644 --- a/src/core/hle/service/am/applets/error.cpp +++ b/src/core/hle/service/am/applets/error.cpp | |||
| @@ -20,9 +20,9 @@ namespace Service::AM::Applets { | |||
| 20 | struct ShowError { | 20 | struct ShowError { |
| 21 | u8 mode; | 21 | u8 mode; |
| 22 | bool jump; | 22 | bool jump; |
| 23 | INSERT_PADDING_BYTES(4); | 23 | INSERT_UNION_PADDING_BYTES(4); |
| 24 | bool use_64bit_error_code; | 24 | bool use_64bit_error_code; |
| 25 | INSERT_PADDING_BYTES(1); | 25 | INSERT_UNION_PADDING_BYTES(1); |
| 26 | u64 error_code_64; | 26 | u64 error_code_64; |
| 27 | u32 error_code_32; | 27 | u32 error_code_32; |
| 28 | }; | 28 | }; |
| @@ -32,7 +32,7 @@ static_assert(sizeof(ShowError) == 0x14, "ShowError has incorrect size."); | |||
| 32 | struct ShowErrorRecord { | 32 | struct ShowErrorRecord { |
| 33 | u8 mode; | 33 | u8 mode; |
| 34 | bool jump; | 34 | bool jump; |
| 35 | INSERT_PADDING_BYTES(6); | 35 | INSERT_UNION_PADDING_BYTES(6); |
| 36 | u64 error_code_64; | 36 | u64 error_code_64; |
| 37 | u64 posix_time; | 37 | u64 posix_time; |
| 38 | }; | 38 | }; |
| @@ -41,7 +41,7 @@ static_assert(sizeof(ShowErrorRecord) == 0x18, "ShowErrorRecord has incorrect si | |||
| 41 | struct SystemErrorArg { | 41 | struct SystemErrorArg { |
| 42 | u8 mode; | 42 | u8 mode; |
| 43 | bool jump; | 43 | bool jump; |
| 44 | INSERT_PADDING_BYTES(6); | 44 | INSERT_UNION_PADDING_BYTES(6); |
| 45 | u64 error_code_64; | 45 | u64 error_code_64; |
| 46 | std::array<char, 8> language_code; | 46 | std::array<char, 8> language_code; |
| 47 | std::array<char, 0x800> main_text; | 47 | std::array<char, 0x800> main_text; |
| @@ -52,7 +52,7 @@ static_assert(sizeof(SystemErrorArg) == 0x1018, "SystemErrorArg has incorrect si | |||
| 52 | struct ApplicationErrorArg { | 52 | struct ApplicationErrorArg { |
| 53 | u8 mode; | 53 | u8 mode; |
| 54 | bool jump; | 54 | bool jump; |
| 55 | INSERT_PADDING_BYTES(6); | 55 | INSERT_UNION_PADDING_BYTES(6); |
| 56 | u32 error_code; | 56 | u32 error_code; |
| 57 | std::array<char, 8> language_code; | 57 | std::array<char, 8> language_code; |
| 58 | std::array<char, 0x800> main_text; | 58 | std::array<char, 0x800> main_text; |
| @@ -65,6 +65,7 @@ union Error::ErrorArguments { | |||
| 65 | ShowErrorRecord error_record; | 65 | ShowErrorRecord error_record; |
| 66 | SystemErrorArg system_error; | 66 | SystemErrorArg system_error; |
| 67 | ApplicationErrorArg application_error; | 67 | ApplicationErrorArg application_error; |
| 68 | std::array<u8, 0x1018> raw{}; | ||
| 68 | }; | 69 | }; |
| 69 | 70 | ||
| 70 | namespace { | 71 | namespace { |
diff --git a/src/core/hle/service/aoc/aoc_u.cpp b/src/core/hle/service/aoc/aoc_u.cpp index e9cf1e840..f36ccbc49 100644 --- a/src/core/hle/service/aoc/aoc_u.cpp +++ b/src/core/hle/service/aoc/aoc_u.cpp | |||
| @@ -67,8 +67,8 @@ AOC_U::AOC_U(Core::System& system) | |||
| 67 | RegisterHandlers(functions); | 67 | RegisterHandlers(functions); |
| 68 | 68 | ||
| 69 | auto& kernel = system.Kernel(); | 69 | auto& kernel = system.Kernel(); |
| 70 | aoc_change_event = Kernel::WritableEvent::CreateEventPair(kernel, Kernel::ResetType::Manual, | 70 | aoc_change_event = |
| 71 | "GetAddOnContentListChanged:Event"); | 71 | Kernel::WritableEvent::CreateEventPair(kernel, "GetAddOnContentListChanged:Event"); |
| 72 | } | 72 | } |
| 73 | 73 | ||
| 74 | AOC_U::~AOC_U() = default; | 74 | AOC_U::~AOC_U() = default; |
diff --git a/src/core/hle/service/audio/audout_u.cpp b/src/core/hle/service/audio/audout_u.cpp index 9afefb5c6..6a29377e3 100644 --- a/src/core/hle/service/audio/audout_u.cpp +++ b/src/core/hle/service/audio/audout_u.cpp | |||
| @@ -65,8 +65,8 @@ public: | |||
| 65 | RegisterHandlers(functions); | 65 | RegisterHandlers(functions); |
| 66 | 66 | ||
| 67 | // This is the event handle used to check if the audio buffer was released | 67 | // This is the event handle used to check if the audio buffer was released |
| 68 | buffer_event = Kernel::WritableEvent::CreateEventPair( | 68 | buffer_event = |
| 69 | system.Kernel(), Kernel::ResetType::Manual, "IAudioOutBufferReleased"); | 69 | Kernel::WritableEvent::CreateEventPair(system.Kernel(), "IAudioOutBufferReleased"); |
| 70 | 70 | ||
| 71 | stream = audio_core.OpenStream(system.CoreTiming(), audio_params.sample_rate, | 71 | stream = audio_core.OpenStream(system.CoreTiming(), audio_params.sample_rate, |
| 72 | audio_params.channel_count, std::move(unique_name), | 72 | audio_params.channel_count, std::move(unique_name), |
diff --git a/src/core/hle/service/audio/audren_u.cpp b/src/core/hle/service/audio/audren_u.cpp index f162249ed..4ea7ade6e 100644 --- a/src/core/hle/service/audio/audren_u.cpp +++ b/src/core/hle/service/audio/audren_u.cpp | |||
| @@ -47,8 +47,8 @@ public: | |||
| 47 | // clang-format on | 47 | // clang-format on |
| 48 | RegisterHandlers(functions); | 48 | RegisterHandlers(functions); |
| 49 | 49 | ||
| 50 | system_event = Kernel::WritableEvent::CreateEventPair( | 50 | system_event = |
| 51 | system.Kernel(), Kernel::ResetType::Manual, "IAudioRenderer:SystemEvent"); | 51 | Kernel::WritableEvent::CreateEventPair(system.Kernel(), "IAudioRenderer:SystemEvent"); |
| 52 | renderer = std::make_unique<AudioCore::AudioRenderer>( | 52 | renderer = std::make_unique<AudioCore::AudioRenderer>( |
| 53 | system.CoreTiming(), audren_params, system_event.writable, instance_number); | 53 | system.CoreTiming(), audren_params, system_event.writable, instance_number); |
| 54 | } | 54 | } |
| @@ -180,17 +180,17 @@ public: | |||
| 180 | RegisterHandlers(functions); | 180 | RegisterHandlers(functions); |
| 181 | 181 | ||
| 182 | auto& kernel = system.Kernel(); | 182 | auto& kernel = system.Kernel(); |
| 183 | buffer_event = Kernel::WritableEvent::CreateEventPair(kernel, Kernel::ResetType::Automatic, | 183 | buffer_event = |
| 184 | "IAudioOutBufferReleasedEvent"); | 184 | Kernel::WritableEvent::CreateEventPair(kernel, "IAudioOutBufferReleasedEvent"); |
| 185 | 185 | ||
| 186 | // Should be similar to audio_output_device_switch_event | 186 | // Should be similar to audio_output_device_switch_event |
| 187 | audio_input_device_switch_event = Kernel::WritableEvent::CreateEventPair( | 187 | audio_input_device_switch_event = Kernel::WritableEvent::CreateEventPair( |
| 188 | kernel, Kernel::ResetType::Automatic, "IAudioDevice:AudioInputDeviceSwitchedEvent"); | 188 | kernel, "IAudioDevice:AudioInputDeviceSwitchedEvent"); |
| 189 | 189 | ||
| 190 | // Should only be signalled when an audio output device has been changed, example: speaker | 190 | // Should only be signalled when an audio output device has been changed, example: speaker |
| 191 | // to headset | 191 | // to headset |
| 192 | audio_output_device_switch_event = Kernel::WritableEvent::CreateEventPair( | 192 | audio_output_device_switch_event = Kernel::WritableEvent::CreateEventPair( |
| 193 | kernel, Kernel::ResetType::Automatic, "IAudioDevice:AudioOutputDeviceSwitchedEvent"); | 193 | kernel, "IAudioDevice:AudioOutputDeviceSwitchedEvent"); |
| 194 | } | 194 | } |
| 195 | 195 | ||
| 196 | private: | 196 | private: |
diff --git a/src/core/hle/service/bcat/backend/backend.cpp b/src/core/hle/service/bcat/backend/backend.cpp index b86fda29a..dec0849b8 100644 --- a/src/core/hle/service/bcat/backend/backend.cpp +++ b/src/core/hle/service/bcat/backend/backend.cpp | |||
| @@ -13,8 +13,7 @@ namespace Service::BCAT { | |||
| 13 | ProgressServiceBackend::ProgressServiceBackend(Kernel::KernelCore& kernel, | 13 | ProgressServiceBackend::ProgressServiceBackend(Kernel::KernelCore& kernel, |
| 14 | std::string_view event_name) { | 14 | std::string_view event_name) { |
| 15 | event = Kernel::WritableEvent::CreateEventPair( | 15 | event = Kernel::WritableEvent::CreateEventPair( |
| 16 | kernel, Kernel::ResetType::Automatic, | 16 | kernel, std::string("ProgressServiceBackend:UpdateEvent:").append(event_name)); |
| 17 | std::string("ProgressServiceBackend:UpdateEvent:").append(event_name)); | ||
| 18 | } | 17 | } |
| 19 | 18 | ||
| 20 | Kernel::SharedPtr<Kernel::ReadableEvent> ProgressServiceBackend::GetEvent() const { | 19 | Kernel::SharedPtr<Kernel::ReadableEvent> ProgressServiceBackend::GetEvent() const { |
diff --git a/src/core/hle/service/btdrv/btdrv.cpp b/src/core/hle/service/btdrv/btdrv.cpp index afce581e5..4574d9572 100644 --- a/src/core/hle/service/btdrv/btdrv.cpp +++ b/src/core/hle/service/btdrv/btdrv.cpp | |||
| @@ -34,8 +34,7 @@ public: | |||
| 34 | RegisterHandlers(functions); | 34 | RegisterHandlers(functions); |
| 35 | 35 | ||
| 36 | auto& kernel = system.Kernel(); | 36 | auto& kernel = system.Kernel(); |
| 37 | register_event = Kernel::WritableEvent::CreateEventPair( | 37 | register_event = Kernel::WritableEvent::CreateEventPair(kernel, "BT:RegisterEvent"); |
| 38 | kernel, Kernel::ResetType::Automatic, "BT:RegisterEvent"); | ||
| 39 | } | 38 | } |
| 40 | 39 | ||
| 41 | private: | 40 | private: |
diff --git a/src/core/hle/service/btm/btm.cpp b/src/core/hle/service/btm/btm.cpp index 920fc6ff7..251b3c9df 100644 --- a/src/core/hle/service/btm/btm.cpp +++ b/src/core/hle/service/btm/btm.cpp | |||
| @@ -57,14 +57,12 @@ public: | |||
| 57 | RegisterHandlers(functions); | 57 | RegisterHandlers(functions); |
| 58 | 58 | ||
| 59 | auto& kernel = system.Kernel(); | 59 | auto& kernel = system.Kernel(); |
| 60 | scan_event = Kernel::WritableEvent::CreateEventPair(kernel, Kernel::ResetType::Automatic, | 60 | scan_event = Kernel::WritableEvent::CreateEventPair(kernel, "IBtmUserCore:ScanEvent"); |
| 61 | "IBtmUserCore:ScanEvent"); | 61 | connection_event = |
| 62 | connection_event = Kernel::WritableEvent::CreateEventPair( | 62 | Kernel::WritableEvent::CreateEventPair(kernel, "IBtmUserCore:ConnectionEvent"); |
| 63 | kernel, Kernel::ResetType::Automatic, "IBtmUserCore:ConnectionEvent"); | 63 | service_discovery = |
| 64 | service_discovery = Kernel::WritableEvent::CreateEventPair( | 64 | Kernel::WritableEvent::CreateEventPair(kernel, "IBtmUserCore:Discovery"); |
| 65 | kernel, Kernel::ResetType::Automatic, "IBtmUserCore:Discovery"); | 65 | config_event = Kernel::WritableEvent::CreateEventPair(kernel, "IBtmUserCore:ConfigEvent"); |
| 66 | config_event = Kernel::WritableEvent::CreateEventPair(kernel, Kernel::ResetType::Automatic, | ||
| 67 | "IBtmUserCore:ConfigEvent"); | ||
| 68 | } | 66 | } |
| 69 | 67 | ||
| 70 | private: | 68 | private: |
diff --git a/src/core/hle/service/friend/friend.cpp b/src/core/hle/service/friend/friend.cpp index 75dd9043b..1a0214f08 100644 --- a/src/core/hle/service/friend/friend.cpp +++ b/src/core/hle/service/friend/friend.cpp | |||
| @@ -162,7 +162,7 @@ public: | |||
| 162 | RegisterHandlers(functions); | 162 | RegisterHandlers(functions); |
| 163 | 163 | ||
| 164 | notification_event = Kernel::WritableEvent::CreateEventPair( | 164 | notification_event = Kernel::WritableEvent::CreateEventPair( |
| 165 | system.Kernel(), Kernel::ResetType::Manual, "INotificationService:NotifyEvent"); | 165 | system.Kernel(), "INotificationService:NotifyEvent"); |
| 166 | } | 166 | } |
| 167 | 167 | ||
| 168 | private: | 168 | private: |
diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp index 81bd2f3cb..79fff517e 100644 --- a/src/core/hle/service/hid/controllers/npad.cpp +++ b/src/core/hle/service/hid/controllers/npad.cpp | |||
| @@ -174,7 +174,7 @@ void Controller_NPad::OnInit() { | |||
| 174 | auto& kernel = system.Kernel(); | 174 | auto& kernel = system.Kernel(); |
| 175 | for (std::size_t i = 0; i < styleset_changed_events.size(); i++) { | 175 | for (std::size_t i = 0; i < styleset_changed_events.size(); i++) { |
| 176 | styleset_changed_events[i] = Kernel::WritableEvent::CreateEventPair( | 176 | styleset_changed_events[i] = Kernel::WritableEvent::CreateEventPair( |
| 177 | kernel, Kernel::ResetType::Manual, fmt::format("npad:NpadStyleSetChanged_{}", i)); | 177 | kernel, fmt::format("npad:NpadStyleSetChanged_{}", i)); |
| 178 | } | 178 | } |
| 179 | 179 | ||
| 180 | if (!IsControllerActivated()) { | 180 | if (!IsControllerActivated()) { |
diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp index ba1da4181..ecc130f6c 100644 --- a/src/core/hle/service/hid/hid.cpp +++ b/src/core/hle/service/hid/hid.cpp | |||
| @@ -203,13 +203,13 @@ Hid::Hid(Core::System& system) : ServiceFramework("hid"), system(system) { | |||
| 203 | {120, &Hid::SetNpadJoyHoldType, "SetNpadJoyHoldType"}, | 203 | {120, &Hid::SetNpadJoyHoldType, "SetNpadJoyHoldType"}, |
| 204 | {121, &Hid::GetNpadJoyHoldType, "GetNpadJoyHoldType"}, | 204 | {121, &Hid::GetNpadJoyHoldType, "GetNpadJoyHoldType"}, |
| 205 | {122, &Hid::SetNpadJoyAssignmentModeSingleByDefault, "SetNpadJoyAssignmentModeSingleByDefault"}, | 205 | {122, &Hid::SetNpadJoyAssignmentModeSingleByDefault, "SetNpadJoyAssignmentModeSingleByDefault"}, |
| 206 | {123, nullptr, "SetNpadJoyAssignmentModeSingleByDefault"}, | 206 | {123, &Hid::SetNpadJoyAssignmentModeSingle, "SetNpadJoyAssignmentModeSingle"}, |
| 207 | {124, &Hid::SetNpadJoyAssignmentModeDual, "SetNpadJoyAssignmentModeDual"}, | 207 | {124, &Hid::SetNpadJoyAssignmentModeDual, "SetNpadJoyAssignmentModeDual"}, |
| 208 | {125, &Hid::MergeSingleJoyAsDualJoy, "MergeSingleJoyAsDualJoy"}, | 208 | {125, &Hid::MergeSingleJoyAsDualJoy, "MergeSingleJoyAsDualJoy"}, |
| 209 | {126, &Hid::StartLrAssignmentMode, "StartLrAssignmentMode"}, | 209 | {126, &Hid::StartLrAssignmentMode, "StartLrAssignmentMode"}, |
| 210 | {127, &Hid::StopLrAssignmentMode, "StopLrAssignmentMode"}, | 210 | {127, &Hid::StopLrAssignmentMode, "StopLrAssignmentMode"}, |
| 211 | {128, &Hid::SetNpadHandheldActivationMode, "SetNpadHandheldActivationMode"}, | 211 | {128, &Hid::SetNpadHandheldActivationMode, "SetNpadHandheldActivationMode"}, |
| 212 | {129, nullptr, "GetNpadHandheldActivationMode"}, | 212 | {129, &Hid::GetNpadHandheldActivationMode, "GetNpadHandheldActivationMode"}, |
| 213 | {130, &Hid::SwapNpadAssignment, "SwapNpadAssignment"}, | 213 | {130, &Hid::SwapNpadAssignment, "SwapNpadAssignment"}, |
| 214 | {131, nullptr, "IsUnintendedHomeButtonInputProtectionEnabled"}, | 214 | {131, nullptr, "IsUnintendedHomeButtonInputProtectionEnabled"}, |
| 215 | {132, nullptr, "EnableUnintendedHomeButtonInputProtection"}, | 215 | {132, nullptr, "EnableUnintendedHomeButtonInputProtection"}, |
| @@ -557,10 +557,126 @@ void Hid::SetNpadJoyAssignmentModeSingleByDefault(Kernel::HLERequestContext& ctx | |||
| 557 | LOG_WARNING(Service_HID, "(STUBBED) called, npad_id={}, applet_resource_user_id={}", npad_id, | 557 | LOG_WARNING(Service_HID, "(STUBBED) called, npad_id={}, applet_resource_user_id={}", npad_id, |
| 558 | applet_resource_user_id); | 558 | applet_resource_user_id); |
| 559 | 559 | ||
| 560 | auto& controller = applet_resource->GetController<Controller_NPad>(HidController::NPad); | ||
| 561 | controller.SetNpadMode(npad_id, Controller_NPad::NPadAssignments::Single); | ||
| 562 | |||
| 563 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 564 | rb.Push(RESULT_SUCCESS); | ||
| 565 | } | ||
| 566 | |||
| 567 | void Hid::SetNpadJoyAssignmentModeSingle(Kernel::HLERequestContext& ctx) { | ||
| 568 | // TODO: Check the differences between this and SetNpadJoyAssignmentModeSingleByDefault | ||
| 569 | IPC::RequestParser rp{ctx}; | ||
| 570 | const auto npad_id{rp.Pop<u32>()}; | ||
| 571 | const auto applet_resource_user_id{rp.Pop<u64>()}; | ||
| 572 | const auto npad_joy_device_type{rp.Pop<u64>()}; | ||
| 573 | |||
| 574 | LOG_WARNING(Service_HID, | ||
| 575 | "(STUBBED) called, npad_id={}, applet_resource_user_id={}, npad_joy_device_type={}", | ||
| 576 | npad_id, applet_resource_user_id, npad_joy_device_type); | ||
| 577 | |||
| 578 | auto& controller = applet_resource->GetController<Controller_NPad>(HidController::NPad); | ||
| 579 | controller.SetNpadMode(npad_id, Controller_NPad::NPadAssignments::Single); | ||
| 580 | |||
| 581 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 582 | rb.Push(RESULT_SUCCESS); | ||
| 583 | } | ||
| 584 | |||
| 585 | void Hid::SetNpadJoyAssignmentModeDual(Kernel::HLERequestContext& ctx) { | ||
| 586 | IPC::RequestParser rp{ctx}; | ||
| 587 | const auto npad_id{rp.Pop<u32>()}; | ||
| 588 | const auto applet_resource_user_id{rp.Pop<u64>()}; | ||
| 589 | |||
| 590 | LOG_DEBUG(Service_HID, "called, npad_id={}, applet_resource_user_id={}", npad_id, | ||
| 591 | applet_resource_user_id); | ||
| 592 | |||
| 593 | auto& controller = applet_resource->GetController<Controller_NPad>(HidController::NPad); | ||
| 594 | controller.SetNpadMode(npad_id, Controller_NPad::NPadAssignments::Dual); | ||
| 595 | |||
| 596 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 597 | rb.Push(RESULT_SUCCESS); | ||
| 598 | } | ||
| 599 | |||
| 600 | void Hid::MergeSingleJoyAsDualJoy(Kernel::HLERequestContext& ctx) { | ||
| 601 | IPC::RequestParser rp{ctx}; | ||
| 602 | const auto unknown_1{rp.Pop<u32>()}; | ||
| 603 | const auto unknown_2{rp.Pop<u32>()}; | ||
| 604 | const auto applet_resource_user_id{rp.Pop<u64>()}; | ||
| 605 | |||
| 606 | LOG_WARNING(Service_HID, | ||
| 607 | "(STUBBED) called, unknown_1={}, unknown_2={}, applet_resource_user_id={}", | ||
| 608 | unknown_1, unknown_2, applet_resource_user_id); | ||
| 609 | |||
| 610 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 611 | rb.Push(RESULT_SUCCESS); | ||
| 612 | } | ||
| 613 | |||
| 614 | void Hid::StartLrAssignmentMode(Kernel::HLERequestContext& ctx) { | ||
| 615 | IPC::RequestParser rp{ctx}; | ||
| 616 | const auto applet_resource_user_id{rp.Pop<u64>()}; | ||
| 617 | |||
| 618 | LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id); | ||
| 619 | auto& controller = applet_resource->GetController<Controller_NPad>(HidController::NPad); | ||
| 620 | controller.StartLRAssignmentMode(); | ||
| 621 | |||
| 622 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 623 | rb.Push(RESULT_SUCCESS); | ||
| 624 | } | ||
| 625 | |||
| 626 | void Hid::StopLrAssignmentMode(Kernel::HLERequestContext& ctx) { | ||
| 627 | IPC::RequestParser rp{ctx}; | ||
| 628 | const auto applet_resource_user_id{rp.Pop<u64>()}; | ||
| 629 | |||
| 630 | LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id); | ||
| 631 | auto& controller = applet_resource->GetController<Controller_NPad>(HidController::NPad); | ||
| 632 | controller.StopLRAssignmentMode(); | ||
| 633 | |||
| 634 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 635 | rb.Push(RESULT_SUCCESS); | ||
| 636 | } | ||
| 637 | |||
| 638 | void Hid::SetNpadHandheldActivationMode(Kernel::HLERequestContext& ctx) { | ||
| 639 | IPC::RequestParser rp{ctx}; | ||
| 640 | const auto applet_resource_user_id{rp.Pop<u64>()}; | ||
| 641 | const auto mode{rp.Pop<u64>()}; | ||
| 642 | |||
| 643 | LOG_WARNING(Service_HID, "(STUBBED) called, applet_resource_user_id={}, mode={}", | ||
| 644 | applet_resource_user_id, mode); | ||
| 645 | |||
| 646 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 647 | rb.Push(RESULT_SUCCESS); | ||
| 648 | } | ||
| 649 | |||
| 650 | void Hid::GetNpadHandheldActivationMode(Kernel::HLERequestContext& ctx) { | ||
| 651 | IPC::RequestParser rp{ctx}; | ||
| 652 | const auto applet_resource_user_id{rp.Pop<u64>()}; | ||
| 653 | |||
| 654 | LOG_WARNING(Service_HID, "(STUBBED) called, applet_resource_user_id={}", | ||
| 655 | applet_resource_user_id); | ||
| 656 | |||
| 560 | IPC::ResponseBuilder rb{ctx, 2}; | 657 | IPC::ResponseBuilder rb{ctx, 2}; |
| 561 | rb.Push(RESULT_SUCCESS); | 658 | rb.Push(RESULT_SUCCESS); |
| 562 | } | 659 | } |
| 563 | 660 | ||
| 661 | void Hid::SwapNpadAssignment(Kernel::HLERequestContext& ctx) { | ||
| 662 | IPC::RequestParser rp{ctx}; | ||
| 663 | const auto npad_1{rp.Pop<u32>()}; | ||
| 664 | const auto npad_2{rp.Pop<u32>()}; | ||
| 665 | const auto applet_resource_user_id{rp.Pop<u64>()}; | ||
| 666 | |||
| 667 | LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}, npad_1={}, npad_2={}", | ||
| 668 | applet_resource_user_id, npad_1, npad_2); | ||
| 669 | |||
| 670 | auto& controller = applet_resource->GetController<Controller_NPad>(HidController::NPad); | ||
| 671 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 672 | if (controller.SwapNpadAssignment(npad_1, npad_2)) { | ||
| 673 | rb.Push(RESULT_SUCCESS); | ||
| 674 | } else { | ||
| 675 | LOG_ERROR(Service_HID, "Npads are not connected!"); | ||
| 676 | rb.Push(ERR_NPAD_NOT_CONNECTED); | ||
| 677 | } | ||
| 678 | } | ||
| 679 | |||
| 564 | void Hid::BeginPermitVibrationSession(Kernel::HLERequestContext& ctx) { | 680 | void Hid::BeginPermitVibrationSession(Kernel::HLERequestContext& ctx) { |
| 565 | IPC::RequestParser rp{ctx}; | 681 | IPC::RequestParser rp{ctx}; |
| 566 | const auto applet_resource_user_id{rp.Pop<u64>()}; | 682 | const auto applet_resource_user_id{rp.Pop<u64>()}; |
| @@ -635,47 +751,6 @@ void Hid::GetActualVibrationValue(Kernel::HLERequestContext& ctx) { | |||
| 635 | applet_resource->GetController<Controller_NPad>(HidController::NPad).GetLastVibration()); | 751 | applet_resource->GetController<Controller_NPad>(HidController::NPad).GetLastVibration()); |
| 636 | } | 752 | } |
| 637 | 753 | ||
| 638 | void Hid::SetNpadJoyAssignmentModeDual(Kernel::HLERequestContext& ctx) { | ||
| 639 | IPC::RequestParser rp{ctx}; | ||
| 640 | const auto npad_id{rp.Pop<u32>()}; | ||
| 641 | const auto applet_resource_user_id{rp.Pop<u64>()}; | ||
| 642 | |||
| 643 | LOG_DEBUG(Service_HID, "called, npad_id={}, applet_resource_user_id={}", npad_id, | ||
| 644 | applet_resource_user_id); | ||
| 645 | |||
| 646 | auto& controller = applet_resource->GetController<Controller_NPad>(HidController::NPad); | ||
| 647 | controller.SetNpadMode(npad_id, Controller_NPad::NPadAssignments::Dual); | ||
| 648 | |||
| 649 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 650 | rb.Push(RESULT_SUCCESS); | ||
| 651 | } | ||
| 652 | |||
| 653 | void Hid::MergeSingleJoyAsDualJoy(Kernel::HLERequestContext& ctx) { | ||
| 654 | IPC::RequestParser rp{ctx}; | ||
| 655 | const auto unknown_1{rp.Pop<u32>()}; | ||
| 656 | const auto unknown_2{rp.Pop<u32>()}; | ||
| 657 | const auto applet_resource_user_id{rp.Pop<u64>()}; | ||
| 658 | |||
| 659 | LOG_WARNING(Service_HID, | ||
| 660 | "(STUBBED) called, unknown_1={}, unknown_2={}, applet_resource_user_id={}", | ||
| 661 | unknown_1, unknown_2, applet_resource_user_id); | ||
| 662 | |||
| 663 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 664 | rb.Push(RESULT_SUCCESS); | ||
| 665 | } | ||
| 666 | |||
| 667 | void Hid::SetNpadHandheldActivationMode(Kernel::HLERequestContext& ctx) { | ||
| 668 | IPC::RequestParser rp{ctx}; | ||
| 669 | const auto applet_resource_user_id{rp.Pop<u64>()}; | ||
| 670 | const auto mode{rp.Pop<u64>()}; | ||
| 671 | |||
| 672 | LOG_WARNING(Service_HID, "(STUBBED) called, applet_resource_user_id={}, mode={}", | ||
| 673 | applet_resource_user_id, mode); | ||
| 674 | |||
| 675 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 676 | rb.Push(RESULT_SUCCESS); | ||
| 677 | } | ||
| 678 | |||
| 679 | void Hid::GetVibrationDeviceInfo(Kernel::HLERequestContext& ctx) { | 754 | void Hid::GetVibrationDeviceInfo(Kernel::HLERequestContext& ctx) { |
| 680 | LOG_DEBUG(Service_HID, "called"); | 755 | LOG_DEBUG(Service_HID, "called"); |
| 681 | 756 | ||
| @@ -769,49 +844,6 @@ void Hid::SetPalmaBoostMode(Kernel::HLERequestContext& ctx) { | |||
| 769 | rb.Push(RESULT_SUCCESS); | 844 | rb.Push(RESULT_SUCCESS); |
| 770 | } | 845 | } |
| 771 | 846 | ||
| 772 | void Hid::StartLrAssignmentMode(Kernel::HLERequestContext& ctx) { | ||
| 773 | IPC::RequestParser rp{ctx}; | ||
| 774 | const auto applet_resource_user_id{rp.Pop<u64>()}; | ||
| 775 | |||
| 776 | LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id); | ||
| 777 | auto& controller = applet_resource->GetController<Controller_NPad>(HidController::NPad); | ||
| 778 | controller.StartLRAssignmentMode(); | ||
| 779 | |||
| 780 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 781 | rb.Push(RESULT_SUCCESS); | ||
| 782 | } | ||
| 783 | |||
| 784 | void Hid::StopLrAssignmentMode(Kernel::HLERequestContext& ctx) { | ||
| 785 | IPC::RequestParser rp{ctx}; | ||
| 786 | const auto applet_resource_user_id{rp.Pop<u64>()}; | ||
| 787 | |||
| 788 | LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id); | ||
| 789 | auto& controller = applet_resource->GetController<Controller_NPad>(HidController::NPad); | ||
| 790 | controller.StopLRAssignmentMode(); | ||
| 791 | |||
| 792 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 793 | rb.Push(RESULT_SUCCESS); | ||
| 794 | } | ||
| 795 | |||
| 796 | void Hid::SwapNpadAssignment(Kernel::HLERequestContext& ctx) { | ||
| 797 | IPC::RequestParser rp{ctx}; | ||
| 798 | const auto npad_1{rp.Pop<u32>()}; | ||
| 799 | const auto npad_2{rp.Pop<u32>()}; | ||
| 800 | const auto applet_resource_user_id{rp.Pop<u64>()}; | ||
| 801 | |||
| 802 | LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}, npad_1={}, npad_2={}", | ||
| 803 | applet_resource_user_id, npad_1, npad_2); | ||
| 804 | |||
| 805 | auto& controller = applet_resource->GetController<Controller_NPad>(HidController::NPad); | ||
| 806 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 807 | if (controller.SwapNpadAssignment(npad_1, npad_2)) { | ||
| 808 | rb.Push(RESULT_SUCCESS); | ||
| 809 | } else { | ||
| 810 | LOG_ERROR(Service_HID, "Npads are not connected!"); | ||
| 811 | rb.Push(ERR_NPAD_NOT_CONNECTED); | ||
| 812 | } | ||
| 813 | } | ||
| 814 | |||
| 815 | class HidDbg final : public ServiceFramework<HidDbg> { | 847 | class HidDbg final : public ServiceFramework<HidDbg> { |
| 816 | public: | 848 | public: |
| 817 | explicit HidDbg() : ServiceFramework{"hid:dbg"} { | 849 | explicit HidDbg() : ServiceFramework{"hid:dbg"} { |
diff --git a/src/core/hle/service/hid/hid.h b/src/core/hle/service/hid/hid.h index 01852e019..f08e036a3 100644 --- a/src/core/hle/service/hid/hid.h +++ b/src/core/hle/service/hid/hid.h | |||
| @@ -106,14 +106,19 @@ private: | |||
| 106 | void SetNpadJoyHoldType(Kernel::HLERequestContext& ctx); | 106 | void SetNpadJoyHoldType(Kernel::HLERequestContext& ctx); |
| 107 | void GetNpadJoyHoldType(Kernel::HLERequestContext& ctx); | 107 | void GetNpadJoyHoldType(Kernel::HLERequestContext& ctx); |
| 108 | void SetNpadJoyAssignmentModeSingleByDefault(Kernel::HLERequestContext& ctx); | 108 | void SetNpadJoyAssignmentModeSingleByDefault(Kernel::HLERequestContext& ctx); |
| 109 | void SetNpadJoyAssignmentModeSingle(Kernel::HLERequestContext& ctx); | ||
| 110 | void SetNpadJoyAssignmentModeDual(Kernel::HLERequestContext& ctx); | ||
| 111 | void MergeSingleJoyAsDualJoy(Kernel::HLERequestContext& ctx); | ||
| 112 | void StartLrAssignmentMode(Kernel::HLERequestContext& ctx); | ||
| 113 | void StopLrAssignmentMode(Kernel::HLERequestContext& ctx); | ||
| 114 | void SetNpadHandheldActivationMode(Kernel::HLERequestContext& ctx); | ||
| 115 | void GetNpadHandheldActivationMode(Kernel::HLERequestContext& ctx); | ||
| 116 | void SwapNpadAssignment(Kernel::HLERequestContext& ctx); | ||
| 109 | void BeginPermitVibrationSession(Kernel::HLERequestContext& ctx); | 117 | void BeginPermitVibrationSession(Kernel::HLERequestContext& ctx); |
| 110 | void EndPermitVibrationSession(Kernel::HLERequestContext& ctx); | 118 | void EndPermitVibrationSession(Kernel::HLERequestContext& ctx); |
| 111 | void SendVibrationValue(Kernel::HLERequestContext& ctx); | 119 | void SendVibrationValue(Kernel::HLERequestContext& ctx); |
| 112 | void SendVibrationValues(Kernel::HLERequestContext& ctx); | 120 | void SendVibrationValues(Kernel::HLERequestContext& ctx); |
| 113 | void GetActualVibrationValue(Kernel::HLERequestContext& ctx); | 121 | void GetActualVibrationValue(Kernel::HLERequestContext& ctx); |
| 114 | void SetNpadJoyAssignmentModeDual(Kernel::HLERequestContext& ctx); | ||
| 115 | void MergeSingleJoyAsDualJoy(Kernel::HLERequestContext& ctx); | ||
| 116 | void SetNpadHandheldActivationMode(Kernel::HLERequestContext& ctx); | ||
| 117 | void GetVibrationDeviceInfo(Kernel::HLERequestContext& ctx); | 122 | void GetVibrationDeviceInfo(Kernel::HLERequestContext& ctx); |
| 118 | void CreateActiveVibrationDeviceList(Kernel::HLERequestContext& ctx); | 123 | void CreateActiveVibrationDeviceList(Kernel::HLERequestContext& ctx); |
| 119 | void PermitVibration(Kernel::HLERequestContext& ctx); | 124 | void PermitVibration(Kernel::HLERequestContext& ctx); |
| @@ -123,9 +128,6 @@ private: | |||
| 123 | void StopSixAxisSensor(Kernel::HLERequestContext& ctx); | 128 | void StopSixAxisSensor(Kernel::HLERequestContext& ctx); |
| 124 | void SetIsPalmaAllConnectable(Kernel::HLERequestContext& ctx); | 129 | void SetIsPalmaAllConnectable(Kernel::HLERequestContext& ctx); |
| 125 | void SetPalmaBoostMode(Kernel::HLERequestContext& ctx); | 130 | void SetPalmaBoostMode(Kernel::HLERequestContext& ctx); |
| 126 | void StartLrAssignmentMode(Kernel::HLERequestContext& ctx); | ||
| 127 | void StopLrAssignmentMode(Kernel::HLERequestContext& ctx); | ||
| 128 | void SwapNpadAssignment(Kernel::HLERequestContext& ctx); | ||
| 129 | 131 | ||
| 130 | std::shared_ptr<IAppletResource> applet_resource; | 132 | std::shared_ptr<IAppletResource> applet_resource; |
| 131 | Core::System& system; | 133 | Core::System& system; |
diff --git a/src/core/hle/service/nfp/nfp.cpp b/src/core/hle/service/nfp/nfp.cpp index aa886cd3e..795d7b716 100644 --- a/src/core/hle/service/nfp/nfp.cpp +++ b/src/core/hle/service/nfp/nfp.cpp | |||
| @@ -26,8 +26,7 @@ constexpr ResultCode ERR_NO_APPLICATION_AREA(ErrorModule::NFP, 152); | |||
| 26 | Module::Interface::Interface(std::shared_ptr<Module> module, Core::System& system, const char* name) | 26 | Module::Interface::Interface(std::shared_ptr<Module> module, Core::System& system, const char* name) |
| 27 | : ServiceFramework(name), module(std::move(module)), system(system) { | 27 | : ServiceFramework(name), module(std::move(module)), system(system) { |
| 28 | auto& kernel = system.Kernel(); | 28 | auto& kernel = system.Kernel(); |
| 29 | nfc_tag_load = Kernel::WritableEvent::CreateEventPair(kernel, Kernel::ResetType::Automatic, | 29 | nfc_tag_load = Kernel::WritableEvent::CreateEventPair(kernel, "IUser:NFCTagDetected"); |
| 30 | "IUser:NFCTagDetected"); | ||
| 31 | } | 30 | } |
| 32 | 31 | ||
| 33 | Module::Interface::~Interface() = default; | 32 | Module::Interface::~Interface() = default; |
| @@ -66,10 +65,9 @@ public: | |||
| 66 | RegisterHandlers(functions); | 65 | RegisterHandlers(functions); |
| 67 | 66 | ||
| 68 | auto& kernel = system.Kernel(); | 67 | auto& kernel = system.Kernel(); |
| 69 | deactivate_event = Kernel::WritableEvent::CreateEventPair( | 68 | deactivate_event = Kernel::WritableEvent::CreateEventPair(kernel, "IUser:DeactivateEvent"); |
| 70 | kernel, Kernel::ResetType::Automatic, "IUser:DeactivateEvent"); | 69 | availability_change_event = |
| 71 | availability_change_event = Kernel::WritableEvent::CreateEventPair( | 70 | Kernel::WritableEvent::CreateEventPair(kernel, "IUser:AvailabilityChangeEvent"); |
| 72 | kernel, Kernel::ResetType::Automatic, "IUser:AvailabilityChangeEvent"); | ||
| 73 | } | 71 | } |
| 74 | 72 | ||
| 75 | private: | 73 | private: |
diff --git a/src/core/hle/service/nifm/nifm.cpp b/src/core/hle/service/nifm/nifm.cpp index 756a2af57..01d557c7a 100644 --- a/src/core/hle/service/nifm/nifm.cpp +++ b/src/core/hle/service/nifm/nifm.cpp | |||
| @@ -69,10 +69,8 @@ public: | |||
| 69 | RegisterHandlers(functions); | 69 | RegisterHandlers(functions); |
| 70 | 70 | ||
| 71 | auto& kernel = system.Kernel(); | 71 | auto& kernel = system.Kernel(); |
| 72 | event1 = Kernel::WritableEvent::CreateEventPair(kernel, Kernel::ResetType::Automatic, | 72 | event1 = Kernel::WritableEvent::CreateEventPair(kernel, "IRequest:Event1"); |
| 73 | "IRequest:Event1"); | 73 | event2 = Kernel::WritableEvent::CreateEventPair(kernel, "IRequest:Event2"); |
| 74 | event2 = Kernel::WritableEvent::CreateEventPair(kernel, Kernel::ResetType::Automatic, | ||
| 75 | "IRequest:Event2"); | ||
| 76 | } | 74 | } |
| 77 | 75 | ||
| 78 | private: | 76 | private: |
diff --git a/src/core/hle/service/nim/nim.cpp b/src/core/hle/service/nim/nim.cpp index 75d414952..7d6cf2070 100644 --- a/src/core/hle/service/nim/nim.cpp +++ b/src/core/hle/service/nim/nim.cpp | |||
| @@ -141,8 +141,7 @@ public: | |||
| 141 | 141 | ||
| 142 | auto& kernel = system.Kernel(); | 142 | auto& kernel = system.Kernel(); |
| 143 | finished_event = Kernel::WritableEvent::CreateEventPair( | 143 | finished_event = Kernel::WritableEvent::CreateEventPair( |
| 144 | kernel, Kernel::ResetType::Automatic, | 144 | kernel, "IEnsureNetworkClockAvailabilityService:FinishEvent"); |
| 145 | "IEnsureNetworkClockAvailabilityService:FinishEvent"); | ||
| 146 | } | 145 | } |
| 147 | 146 | ||
| 148 | private: | 147 | private: |
diff --git a/src/core/hle/service/nvdrv/nvdrv.cpp b/src/core/hle/service/nvdrv/nvdrv.cpp index 7bfb99e34..cc9cd3fd1 100644 --- a/src/core/hle/service/nvdrv/nvdrv.cpp +++ b/src/core/hle/service/nvdrv/nvdrv.cpp | |||
| @@ -40,8 +40,7 @@ Module::Module(Core::System& system) { | |||
| 40 | auto& kernel = system.Kernel(); | 40 | auto& kernel = system.Kernel(); |
| 41 | for (u32 i = 0; i < MaxNvEvents; i++) { | 41 | for (u32 i = 0; i < MaxNvEvents; i++) { |
| 42 | std::string event_label = fmt::format("NVDRV::NvEvent_{}", i); | 42 | std::string event_label = fmt::format("NVDRV::NvEvent_{}", i); |
| 43 | events_interface.events[i] = | 43 | events_interface.events[i] = Kernel::WritableEvent::CreateEventPair(kernel, event_label); |
| 44 | Kernel::WritableEvent::CreateEventPair(kernel, Kernel::ResetType::Manual, event_label); | ||
| 45 | events_interface.status[i] = EventState::Free; | 44 | events_interface.status[i] = EventState::Free; |
| 46 | events_interface.registered[i] = false; | 45 | events_interface.registered[i] = false; |
| 47 | } | 46 | } |
diff --git a/src/core/hle/service/nvflinger/buffer_queue.cpp b/src/core/hle/service/nvflinger/buffer_queue.cpp index 55b68eb0c..1af11e80c 100644 --- a/src/core/hle/service/nvflinger/buffer_queue.cpp +++ b/src/core/hle/service/nvflinger/buffer_queue.cpp | |||
| @@ -16,8 +16,7 @@ namespace Service::NVFlinger { | |||
| 16 | 16 | ||
| 17 | BufferQueue::BufferQueue(Kernel::KernelCore& kernel, u32 id, u64 layer_id) | 17 | BufferQueue::BufferQueue(Kernel::KernelCore& kernel, u32 id, u64 layer_id) |
| 18 | : id(id), layer_id(layer_id) { | 18 | : id(id), layer_id(layer_id) { |
| 19 | buffer_wait_event = Kernel::WritableEvent::CreateEventPair(kernel, Kernel::ResetType::Manual, | 19 | buffer_wait_event = Kernel::WritableEvent::CreateEventPair(kernel, "BufferQueue NativeHandle"); |
| 20 | "BufferQueue NativeHandle"); | ||
| 21 | } | 20 | } |
| 22 | 21 | ||
| 23 | BufferQueue::~BufferQueue() = default; | 22 | BufferQueue::~BufferQueue() = default; |
diff --git a/src/core/hle/service/vi/display/vi_display.cpp b/src/core/hle/service/vi/display/vi_display.cpp index 006a6d9ff..07033fb98 100644 --- a/src/core/hle/service/vi/display/vi_display.cpp +++ b/src/core/hle/service/vi/display/vi_display.cpp | |||
| @@ -17,8 +17,8 @@ namespace Service::VI { | |||
| 17 | 17 | ||
| 18 | Display::Display(u64 id, std::string name, Core::System& system) : id{id}, name{std::move(name)} { | 18 | Display::Display(u64 id, std::string name, Core::System& system) : id{id}, name{std::move(name)} { |
| 19 | auto& kernel = system.Kernel(); | 19 | auto& kernel = system.Kernel(); |
| 20 | vsync_event = Kernel::WritableEvent::CreateEventPair(kernel, Kernel::ResetType::Manual, | 20 | vsync_event = |
| 21 | fmt::format("Display VSync Event {}", id)); | 21 | Kernel::WritableEvent::CreateEventPair(kernel, fmt::format("Display VSync Event {}", id)); |
| 22 | } | 22 | } |
| 23 | 23 | ||
| 24 | Display::~Display() = default; | 24 | Display::~Display() = default; |
diff --git a/src/core/hle/service/vi/vi.cpp b/src/core/hle/service/vi/vi.cpp index 199b30635..611cecc20 100644 --- a/src/core/hle/service/vi/vi.cpp +++ b/src/core/hle/service/vi/vi.cpp | |||
| @@ -45,7 +45,7 @@ struct DisplayInfo { | |||
| 45 | 45 | ||
| 46 | /// Whether or not the display has a limited number of layers. | 46 | /// Whether or not the display has a limited number of layers. |
| 47 | u8 has_limited_layers{1}; | 47 | u8 has_limited_layers{1}; |
| 48 | INSERT_PADDING_BYTES(7){}; | 48 | INSERT_PADDING_BYTES(7); |
| 49 | 49 | ||
| 50 | /// Indicates the total amount of layers supported by the display. | 50 | /// Indicates the total amount of layers supported by the display. |
| 51 | /// @note This is only valid if has_limited_layers is set. | 51 | /// @note This is only valid if has_limited_layers is set. |
diff --git a/src/video_core/buffer_cache/buffer_cache.h b/src/video_core/buffer_cache/buffer_cache.h index 2442ddfd6..4408b5001 100644 --- a/src/video_core/buffer_cache/buffer_cache.h +++ b/src/video_core/buffer_cache/buffer_cache.h | |||
| @@ -12,6 +12,10 @@ | |||
| 12 | #include <utility> | 12 | #include <utility> |
| 13 | #include <vector> | 13 | #include <vector> |
| 14 | 14 | ||
| 15 | #include <boost/icl/interval_map.hpp> | ||
| 16 | #include <boost/icl/interval_set.hpp> | ||
| 17 | #include <boost/range/iterator_range.hpp> | ||
| 18 | |||
| 15 | #include "common/alignment.h" | 19 | #include "common/alignment.h" |
| 16 | #include "common/common_types.h" | 20 | #include "common/common_types.h" |
| 17 | #include "core/core.h" | 21 | #include "core/core.h" |
| @@ -30,7 +34,7 @@ public: | |||
| 30 | using BufferInfo = std::pair<const TBufferType*, u64>; | 34 | using BufferInfo = std::pair<const TBufferType*, u64>; |
| 31 | 35 | ||
| 32 | BufferInfo UploadMemory(GPUVAddr gpu_addr, std::size_t size, std::size_t alignment = 4, | 36 | BufferInfo UploadMemory(GPUVAddr gpu_addr, std::size_t size, std::size_t alignment = 4, |
| 33 | bool is_written = false) { | 37 | bool is_written = false, bool use_fast_cbuf = false) { |
| 34 | std::lock_guard lock{mutex}; | 38 | std::lock_guard lock{mutex}; |
| 35 | 39 | ||
| 36 | auto& memory_manager = system.GPU().MemoryManager(); | 40 | auto& memory_manager = system.GPU().MemoryManager(); |
| @@ -43,9 +47,13 @@ public: | |||
| 43 | // Cache management is a big overhead, so only cache entries with a given size. | 47 | // Cache management is a big overhead, so only cache entries with a given size. |
| 44 | // TODO: Figure out which size is the best for given games. | 48 | // TODO: Figure out which size is the best for given games. |
| 45 | constexpr std::size_t max_stream_size = 0x800; | 49 | constexpr std::size_t max_stream_size = 0x800; |
| 46 | if (size < max_stream_size) { | 50 | if (use_fast_cbuf || size < max_stream_size) { |
| 47 | if (!is_written && !IsRegionWritten(cache_addr, cache_addr + size - 1)) { | 51 | if (!is_written && !IsRegionWritten(cache_addr, cache_addr + size - 1)) { |
| 48 | return StreamBufferUpload(host_ptr, size, alignment); | 52 | if (use_fast_cbuf) { |
| 53 | return ConstBufferUpload(host_ptr, size); | ||
| 54 | } else { | ||
| 55 | return StreamBufferUpload(host_ptr, size, alignment); | ||
| 56 | } | ||
| 49 | } | 57 | } |
| 50 | } | 58 | } |
| 51 | 59 | ||
| @@ -152,6 +160,10 @@ protected: | |||
| 152 | virtual void CopyBlock(const TBuffer& src, const TBuffer& dst, std::size_t src_offset, | 160 | virtual void CopyBlock(const TBuffer& src, const TBuffer& dst, std::size_t src_offset, |
| 153 | std::size_t dst_offset, std::size_t size) = 0; | 161 | std::size_t dst_offset, std::size_t size) = 0; |
| 154 | 162 | ||
| 163 | virtual BufferInfo ConstBufferUpload(const void* raw_pointer, std::size_t size) { | ||
| 164 | return {}; | ||
| 165 | } | ||
| 166 | |||
| 155 | /// Register an object into the cache | 167 | /// Register an object into the cache |
| 156 | void Register(const MapInterval& new_map, bool inherit_written = false) { | 168 | void Register(const MapInterval& new_map, bool inherit_written = false) { |
| 157 | const CacheAddr cache_ptr = new_map->GetStart(); | 169 | const CacheAddr cache_ptr = new_map->GetStart(); |
diff --git a/src/video_core/engines/fermi_2d.cpp b/src/video_core/engines/fermi_2d.cpp index 7ff44f06d..85d308e26 100644 --- a/src/video_core/engines/fermi_2d.cpp +++ b/src/video_core/engines/fermi_2d.cpp | |||
| @@ -28,6 +28,13 @@ void Fermi2D::CallMethod(const GPU::MethodCall& method_call) { | |||
| 28 | } | 28 | } |
| 29 | } | 29 | } |
| 30 | 30 | ||
| 31 | std::pair<u32, u32> DelimitLine(u32 src_1, u32 src_2, u32 dst_1, u32 dst_2, u32 src_line) { | ||
| 32 | const u32 line_a = src_2 - src_1; | ||
| 33 | const u32 line_b = dst_2 - dst_1; | ||
| 34 | const u32 excess = std::max<s32>(0, line_a - src_line + src_1); | ||
| 35 | return {line_b - (excess * line_b) / line_a, excess}; | ||
| 36 | } | ||
| 37 | |||
| 31 | void Fermi2D::HandleSurfaceCopy() { | 38 | void Fermi2D::HandleSurfaceCopy() { |
| 32 | LOG_DEBUG(HW_GPU, "Requested a surface copy with operation {}", | 39 | LOG_DEBUG(HW_GPU, "Requested a surface copy with operation {}", |
| 33 | static_cast<u32>(regs.operation)); | 40 | static_cast<u32>(regs.operation)); |
| @@ -47,10 +54,27 @@ void Fermi2D::HandleSurfaceCopy() { | |||
| 47 | src_blit_x2 = static_cast<u32>((regs.blit_src_x >> 32) + regs.blit_dst_width); | 54 | src_blit_x2 = static_cast<u32>((regs.blit_src_x >> 32) + regs.blit_dst_width); |
| 48 | src_blit_y2 = static_cast<u32>((regs.blit_src_y >> 32) + regs.blit_dst_height); | 55 | src_blit_y2 = static_cast<u32>((regs.blit_src_y >> 32) + regs.blit_dst_height); |
| 49 | } | 56 | } |
| 57 | u32 dst_blit_x2 = regs.blit_dst_x + regs.blit_dst_width; | ||
| 58 | u32 dst_blit_y2 = regs.blit_dst_y + regs.blit_dst_height; | ||
| 59 | const auto [new_dst_w, src_excess_x] = | ||
| 60 | DelimitLine(src_blit_x1, src_blit_x2, regs.blit_dst_x, dst_blit_x2, regs.src.width); | ||
| 61 | const auto [new_dst_h, src_excess_y] = | ||
| 62 | DelimitLine(src_blit_y1, src_blit_y2, regs.blit_dst_y, dst_blit_y2, regs.src.height); | ||
| 63 | dst_blit_x2 = new_dst_w + regs.blit_dst_x; | ||
| 64 | src_blit_x2 = src_blit_x2 - src_excess_x; | ||
| 65 | dst_blit_y2 = new_dst_h + regs.blit_dst_y; | ||
| 66 | src_blit_y2 = src_blit_y2 - src_excess_y; | ||
| 67 | const auto [new_src_w, dst_excess_x] = | ||
| 68 | DelimitLine(regs.blit_dst_x, dst_blit_x2, src_blit_x1, src_blit_x2, regs.dst.width); | ||
| 69 | const auto [new_src_h, dst_excess_y] = | ||
| 70 | DelimitLine(regs.blit_dst_y, dst_blit_y2, src_blit_y1, src_blit_y2, regs.dst.height); | ||
| 71 | src_blit_x2 = new_src_w + src_blit_x1; | ||
| 72 | dst_blit_x2 = dst_blit_x2 - dst_excess_x; | ||
| 73 | src_blit_y2 = new_src_h + src_blit_y1; | ||
| 74 | dst_blit_y2 = dst_blit_y2 - dst_excess_y; | ||
| 50 | const Common::Rectangle<u32> src_rect{src_blit_x1, src_blit_y1, src_blit_x2, src_blit_y2}; | 75 | const Common::Rectangle<u32> src_rect{src_blit_x1, src_blit_y1, src_blit_x2, src_blit_y2}; |
| 51 | const Common::Rectangle<u32> dst_rect{regs.blit_dst_x, regs.blit_dst_y, | 76 | const Common::Rectangle<u32> dst_rect{regs.blit_dst_x, regs.blit_dst_y, dst_blit_x2, |
| 52 | regs.blit_dst_x + regs.blit_dst_width, | 77 | dst_blit_y2}; |
| 53 | regs.blit_dst_y + regs.blit_dst_height}; | ||
| 54 | Config copy_config; | 78 | Config copy_config; |
| 55 | copy_config.operation = regs.operation; | 79 | copy_config.operation = regs.operation; |
| 56 | copy_config.filter = regs.blit_control.filter; | 80 | copy_config.filter = regs.blit_control.filter; |
diff --git a/src/video_core/engines/fermi_2d.h b/src/video_core/engines/fermi_2d.h index 0901cf2fa..dba342c70 100644 --- a/src/video_core/engines/fermi_2d.h +++ b/src/video_core/engines/fermi_2d.h | |||
| @@ -99,19 +99,19 @@ public: | |||
| 99 | 99 | ||
| 100 | union { | 100 | union { |
| 101 | struct { | 101 | struct { |
| 102 | INSERT_PADDING_WORDS(0x80); | 102 | INSERT_UNION_PADDING_WORDS(0x80); |
| 103 | 103 | ||
| 104 | Surface dst; | 104 | Surface dst; |
| 105 | 105 | ||
| 106 | INSERT_PADDING_WORDS(2); | 106 | INSERT_UNION_PADDING_WORDS(2); |
| 107 | 107 | ||
| 108 | Surface src; | 108 | Surface src; |
| 109 | 109 | ||
| 110 | INSERT_PADDING_WORDS(0x15); | 110 | INSERT_UNION_PADDING_WORDS(0x15); |
| 111 | 111 | ||
| 112 | Operation operation; | 112 | Operation operation; |
| 113 | 113 | ||
| 114 | INSERT_PADDING_WORDS(0x177); | 114 | INSERT_UNION_PADDING_WORDS(0x177); |
| 115 | 115 | ||
| 116 | union { | 116 | union { |
| 117 | u32 raw; | 117 | u32 raw; |
| @@ -119,7 +119,7 @@ public: | |||
| 119 | BitField<4, 1, Filter> filter; | 119 | BitField<4, 1, Filter> filter; |
| 120 | } blit_control; | 120 | } blit_control; |
| 121 | 121 | ||
| 122 | INSERT_PADDING_WORDS(0x8); | 122 | INSERT_UNION_PADDING_WORDS(0x8); |
| 123 | 123 | ||
| 124 | u32 blit_dst_x; | 124 | u32 blit_dst_x; |
| 125 | u32 blit_dst_y; | 125 | u32 blit_dst_y; |
| @@ -130,7 +130,7 @@ public: | |||
| 130 | u64 blit_src_x; | 130 | u64 blit_src_x; |
| 131 | u64 blit_src_y; | 131 | u64 blit_src_y; |
| 132 | 132 | ||
| 133 | INSERT_PADDING_WORDS(0x21); | 133 | INSERT_UNION_PADDING_WORDS(0x21); |
| 134 | }; | 134 | }; |
| 135 | std::array<u32, NUM_REGS> reg_array; | 135 | std::array<u32, NUM_REGS> reg_array; |
| 136 | }; | 136 | }; |
diff --git a/src/video_core/engines/kepler_compute.h b/src/video_core/engines/kepler_compute.h index b185c98c7..5259d92bd 100644 --- a/src/video_core/engines/kepler_compute.h +++ b/src/video_core/engines/kepler_compute.h | |||
| @@ -51,7 +51,7 @@ public: | |||
| 51 | 51 | ||
| 52 | union { | 52 | union { |
| 53 | struct { | 53 | struct { |
| 54 | INSERT_PADDING_WORDS(0x60); | 54 | INSERT_UNION_PADDING_WORDS(0x60); |
| 55 | 55 | ||
| 56 | Upload::Registers upload; | 56 | Upload::Registers upload; |
| 57 | 57 | ||
| @@ -63,7 +63,7 @@ public: | |||
| 63 | 63 | ||
| 64 | u32 data_upload; | 64 | u32 data_upload; |
| 65 | 65 | ||
| 66 | INSERT_PADDING_WORDS(0x3F); | 66 | INSERT_UNION_PADDING_WORDS(0x3F); |
| 67 | 67 | ||
| 68 | struct { | 68 | struct { |
| 69 | u32 address; | 69 | u32 address; |
| @@ -72,11 +72,11 @@ public: | |||
| 72 | } | 72 | } |
| 73 | } launch_desc_loc; | 73 | } launch_desc_loc; |
| 74 | 74 | ||
| 75 | INSERT_PADDING_WORDS(0x1); | 75 | INSERT_UNION_PADDING_WORDS(0x1); |
| 76 | 76 | ||
| 77 | u32 launch; | 77 | u32 launch; |
| 78 | 78 | ||
| 79 | INSERT_PADDING_WORDS(0x4A7); | 79 | INSERT_UNION_PADDING_WORDS(0x4A7); |
| 80 | 80 | ||
| 81 | struct { | 81 | struct { |
| 82 | u32 address_high; | 82 | u32 address_high; |
| @@ -88,7 +88,7 @@ public: | |||
| 88 | } | 88 | } |
| 89 | } tsc; | 89 | } tsc; |
| 90 | 90 | ||
| 91 | INSERT_PADDING_WORDS(0x3); | 91 | INSERT_UNION_PADDING_WORDS(0x3); |
| 92 | 92 | ||
| 93 | struct { | 93 | struct { |
| 94 | u32 address_high; | 94 | u32 address_high; |
| @@ -100,7 +100,7 @@ public: | |||
| 100 | } | 100 | } |
| 101 | } tic; | 101 | } tic; |
| 102 | 102 | ||
| 103 | INSERT_PADDING_WORDS(0x22); | 103 | INSERT_UNION_PADDING_WORDS(0x22); |
| 104 | 104 | ||
| 105 | struct { | 105 | struct { |
| 106 | u32 address_high; | 106 | u32 address_high; |
| @@ -111,11 +111,11 @@ public: | |||
| 111 | } | 111 | } |
| 112 | } code_loc; | 112 | } code_loc; |
| 113 | 113 | ||
| 114 | INSERT_PADDING_WORDS(0x3FE); | 114 | INSERT_UNION_PADDING_WORDS(0x3FE); |
| 115 | 115 | ||
| 116 | u32 tex_cb_index; | 116 | u32 tex_cb_index; |
| 117 | 117 | ||
| 118 | INSERT_PADDING_WORDS(0x374); | 118 | INSERT_UNION_PADDING_WORDS(0x374); |
| 119 | }; | 119 | }; |
| 120 | std::array<u32, NUM_REGS> reg_array; | 120 | std::array<u32, NUM_REGS> reg_array; |
| 121 | }; | 121 | }; |
| @@ -179,7 +179,7 @@ public: | |||
| 179 | }; | 179 | }; |
| 180 | 180 | ||
| 181 | INSERT_PADDING_WORDS(0x11); | 181 | INSERT_PADDING_WORDS(0x11); |
| 182 | } launch_description; | 182 | } launch_description{}; |
| 183 | 183 | ||
| 184 | struct { | 184 | struct { |
| 185 | u32 write_offset = 0; | 185 | u32 write_offset = 0; |
diff --git a/src/video_core/engines/kepler_memory.h b/src/video_core/engines/kepler_memory.h index e0e25c321..396fb6e86 100644 --- a/src/video_core/engines/kepler_memory.h +++ b/src/video_core/engines/kepler_memory.h | |||
| @@ -45,7 +45,7 @@ public: | |||
| 45 | 45 | ||
| 46 | union { | 46 | union { |
| 47 | struct { | 47 | struct { |
| 48 | INSERT_PADDING_WORDS(0x60); | 48 | INSERT_UNION_PADDING_WORDS(0x60); |
| 49 | 49 | ||
| 50 | Upload::Registers upload; | 50 | Upload::Registers upload; |
| 51 | 51 | ||
| @@ -57,7 +57,7 @@ public: | |||
| 57 | 57 | ||
| 58 | u32 data; | 58 | u32 data; |
| 59 | 59 | ||
| 60 | INSERT_PADDING_WORDS(0x11); | 60 | INSERT_UNION_PADDING_WORDS(0x11); |
| 61 | }; | 61 | }; |
| 62 | std::array<u32, NUM_REGS> reg_array; | 62 | std::array<u32, NUM_REGS> reg_array; |
| 63 | }; | 63 | }; |
diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h index 8cc842684..1aa7c274f 100644 --- a/src/video_core/engines/maxwell_3d.h +++ b/src/video_core/engines/maxwell_3d.h | |||
| @@ -496,7 +496,7 @@ public: | |||
| 496 | Equation equation_a; | 496 | Equation equation_a; |
| 497 | Factor factor_source_a; | 497 | Factor factor_source_a; |
| 498 | Factor factor_dest_a; | 498 | Factor factor_dest_a; |
| 499 | INSERT_PADDING_WORDS(1); | 499 | INSERT_UNION_PADDING_WORDS(1); |
| 500 | }; | 500 | }; |
| 501 | 501 | ||
| 502 | struct RenderTargetConfig { | 502 | struct RenderTargetConfig { |
| @@ -517,7 +517,7 @@ public: | |||
| 517 | }; | 517 | }; |
| 518 | u32 layer_stride; | 518 | u32 layer_stride; |
| 519 | u32 base_layer; | 519 | u32 base_layer; |
| 520 | INSERT_PADDING_WORDS(7); | 520 | INSERT_UNION_PADDING_WORDS(7); |
| 521 | 521 | ||
| 522 | GPUVAddr Address() const { | 522 | GPUVAddr Address() const { |
| 523 | return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) | | 523 | return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) | |
| @@ -542,7 +542,7 @@ public: | |||
| 542 | f32 translate_x; | 542 | f32 translate_x; |
| 543 | f32 translate_y; | 543 | f32 translate_y; |
| 544 | f32 translate_z; | 544 | f32 translate_z; |
| 545 | INSERT_PADDING_WORDS(2); | 545 | INSERT_UNION_PADDING_WORDS(2); |
| 546 | 546 | ||
| 547 | Common::Rectangle<s32> GetRect() const { | 547 | Common::Rectangle<s32> GetRect() const { |
| 548 | return { | 548 | return { |
| @@ -606,7 +606,7 @@ public: | |||
| 606 | 606 | ||
| 607 | union { | 607 | union { |
| 608 | struct { | 608 | struct { |
| 609 | INSERT_PADDING_WORDS(0x45); | 609 | INSERT_UNION_PADDING_WORDS(0x45); |
| 610 | 610 | ||
| 611 | struct { | 611 | struct { |
| 612 | u32 upload_address; | 612 | u32 upload_address; |
| @@ -615,7 +615,7 @@ public: | |||
| 615 | u32 bind; | 615 | u32 bind; |
| 616 | } macros; | 616 | } macros; |
| 617 | 617 | ||
| 618 | INSERT_PADDING_WORDS(0x17); | 618 | INSERT_UNION_PADDING_WORDS(0x17); |
| 619 | 619 | ||
| 620 | Upload::Registers upload; | 620 | Upload::Registers upload; |
| 621 | struct { | 621 | struct { |
| @@ -626,7 +626,7 @@ public: | |||
| 626 | 626 | ||
| 627 | u32 data_upload; | 627 | u32 data_upload; |
| 628 | 628 | ||
| 629 | INSERT_PADDING_WORDS(0x44); | 629 | INSERT_UNION_PADDING_WORDS(0x44); |
| 630 | 630 | ||
| 631 | struct { | 631 | struct { |
| 632 | union { | 632 | union { |
| @@ -636,11 +636,11 @@ public: | |||
| 636 | }; | 636 | }; |
| 637 | } sync_info; | 637 | } sync_info; |
| 638 | 638 | ||
| 639 | INSERT_PADDING_WORDS(0x11E); | 639 | INSERT_UNION_PADDING_WORDS(0x11E); |
| 640 | 640 | ||
| 641 | u32 tfb_enabled; | 641 | u32 tfb_enabled; |
| 642 | 642 | ||
| 643 | INSERT_PADDING_WORDS(0x2E); | 643 | INSERT_UNION_PADDING_WORDS(0x2E); |
| 644 | 644 | ||
| 645 | std::array<RenderTargetConfig, NumRenderTargets> rt; | 645 | std::array<RenderTargetConfig, NumRenderTargets> rt; |
| 646 | 646 | ||
| @@ -648,49 +648,49 @@ public: | |||
| 648 | 648 | ||
| 649 | std::array<ViewPort, NumViewports> viewports; | 649 | std::array<ViewPort, NumViewports> viewports; |
| 650 | 650 | ||
| 651 | INSERT_PADDING_WORDS(0x1D); | 651 | INSERT_UNION_PADDING_WORDS(0x1D); |
| 652 | 652 | ||
| 653 | struct { | 653 | struct { |
| 654 | u32 first; | 654 | u32 first; |
| 655 | u32 count; | 655 | u32 count; |
| 656 | } vertex_buffer; | 656 | } vertex_buffer; |
| 657 | 657 | ||
| 658 | INSERT_PADDING_WORDS(1); | 658 | INSERT_UNION_PADDING_WORDS(1); |
| 659 | 659 | ||
| 660 | float clear_color[4]; | 660 | float clear_color[4]; |
| 661 | float clear_depth; | 661 | float clear_depth; |
| 662 | 662 | ||
| 663 | INSERT_PADDING_WORDS(0x3); | 663 | INSERT_UNION_PADDING_WORDS(0x3); |
| 664 | 664 | ||
| 665 | s32 clear_stencil; | 665 | s32 clear_stencil; |
| 666 | 666 | ||
| 667 | INSERT_PADDING_WORDS(0x7); | 667 | INSERT_UNION_PADDING_WORDS(0x7); |
| 668 | 668 | ||
| 669 | u32 polygon_offset_point_enable; | 669 | u32 polygon_offset_point_enable; |
| 670 | u32 polygon_offset_line_enable; | 670 | u32 polygon_offset_line_enable; |
| 671 | u32 polygon_offset_fill_enable; | 671 | u32 polygon_offset_fill_enable; |
| 672 | 672 | ||
| 673 | INSERT_PADDING_WORDS(0xD); | 673 | INSERT_UNION_PADDING_WORDS(0xD); |
| 674 | 674 | ||
| 675 | std::array<ScissorTest, NumViewports> scissor_test; | 675 | std::array<ScissorTest, NumViewports> scissor_test; |
| 676 | 676 | ||
| 677 | INSERT_PADDING_WORDS(0x15); | 677 | INSERT_UNION_PADDING_WORDS(0x15); |
| 678 | 678 | ||
| 679 | s32 stencil_back_func_ref; | 679 | s32 stencil_back_func_ref; |
| 680 | u32 stencil_back_mask; | 680 | u32 stencil_back_mask; |
| 681 | u32 stencil_back_func_mask; | 681 | u32 stencil_back_func_mask; |
| 682 | 682 | ||
| 683 | INSERT_PADDING_WORDS(0xC); | 683 | INSERT_UNION_PADDING_WORDS(0xC); |
| 684 | 684 | ||
| 685 | u32 color_mask_common; | 685 | u32 color_mask_common; |
| 686 | 686 | ||
| 687 | INSERT_PADDING_WORDS(0x6); | 687 | INSERT_UNION_PADDING_WORDS(0x6); |
| 688 | 688 | ||
| 689 | u32 rt_separate_frag_data; | 689 | u32 rt_separate_frag_data; |
| 690 | 690 | ||
| 691 | f32 depth_bounds[2]; | 691 | f32 depth_bounds[2]; |
| 692 | 692 | ||
| 693 | INSERT_PADDING_WORDS(0xA); | 693 | INSERT_UNION_PADDING_WORDS(0xA); |
| 694 | 694 | ||
| 695 | struct { | 695 | struct { |
| 696 | u32 address_high; | 696 | u32 address_high; |
| @@ -710,7 +710,7 @@ public: | |||
| 710 | } | 710 | } |
| 711 | } zeta; | 711 | } zeta; |
| 712 | 712 | ||
| 713 | INSERT_PADDING_WORDS(0x41); | 713 | INSERT_UNION_PADDING_WORDS(0x41); |
| 714 | 714 | ||
| 715 | union { | 715 | union { |
| 716 | BitField<0, 4, u32> stencil; | 716 | BitField<0, 4, u32> stencil; |
| @@ -719,11 +719,11 @@ public: | |||
| 719 | BitField<12, 4, u32> viewport; | 719 | BitField<12, 4, u32> viewport; |
| 720 | } clear_flags; | 720 | } clear_flags; |
| 721 | 721 | ||
| 722 | INSERT_PADDING_WORDS(0x19); | 722 | INSERT_UNION_PADDING_WORDS(0x19); |
| 723 | 723 | ||
| 724 | std::array<VertexAttribute, NumVertexAttributes> vertex_attrib_format; | 724 | std::array<VertexAttribute, NumVertexAttributes> vertex_attrib_format; |
| 725 | 725 | ||
| 726 | INSERT_PADDING_WORDS(0xF); | 726 | INSERT_UNION_PADDING_WORDS(0xF); |
| 727 | 727 | ||
| 728 | struct { | 728 | struct { |
| 729 | union { | 729 | union { |
| @@ -746,16 +746,16 @@ public: | |||
| 746 | } | 746 | } |
| 747 | } rt_control; | 747 | } rt_control; |
| 748 | 748 | ||
| 749 | INSERT_PADDING_WORDS(0x2); | 749 | INSERT_UNION_PADDING_WORDS(0x2); |
| 750 | 750 | ||
| 751 | u32 zeta_width; | 751 | u32 zeta_width; |
| 752 | u32 zeta_height; | 752 | u32 zeta_height; |
| 753 | 753 | ||
| 754 | INSERT_PADDING_WORDS(0x27); | 754 | INSERT_UNION_PADDING_WORDS(0x27); |
| 755 | 755 | ||
| 756 | u32 depth_test_enable; | 756 | u32 depth_test_enable; |
| 757 | 757 | ||
| 758 | INSERT_PADDING_WORDS(0x5); | 758 | INSERT_UNION_PADDING_WORDS(0x5); |
| 759 | 759 | ||
| 760 | u32 independent_blend_enable; | 760 | u32 independent_blend_enable; |
| 761 | 761 | ||
| @@ -763,7 +763,7 @@ public: | |||
| 763 | 763 | ||
| 764 | u32 alpha_test_enabled; | 764 | u32 alpha_test_enabled; |
| 765 | 765 | ||
| 766 | INSERT_PADDING_WORDS(0x6); | 766 | INSERT_UNION_PADDING_WORDS(0x6); |
| 767 | 767 | ||
| 768 | u32 d3d_cull_mode; | 768 | u32 d3d_cull_mode; |
| 769 | 769 | ||
| @@ -777,7 +777,7 @@ public: | |||
| 777 | float b; | 777 | float b; |
| 778 | float a; | 778 | float a; |
| 779 | } blend_color; | 779 | } blend_color; |
| 780 | INSERT_PADDING_WORDS(0x4); | 780 | INSERT_UNION_PADDING_WORDS(0x4); |
| 781 | 781 | ||
| 782 | struct { | 782 | struct { |
| 783 | u32 separate_alpha; | 783 | u32 separate_alpha; |
| @@ -786,7 +786,7 @@ public: | |||
| 786 | Blend::Factor factor_dest_rgb; | 786 | Blend::Factor factor_dest_rgb; |
| 787 | Blend::Equation equation_a; | 787 | Blend::Equation equation_a; |
| 788 | Blend::Factor factor_source_a; | 788 | Blend::Factor factor_source_a; |
| 789 | INSERT_PADDING_WORDS(1); | 789 | INSERT_UNION_PADDING_WORDS(1); |
| 790 | Blend::Factor factor_dest_a; | 790 | Blend::Factor factor_dest_a; |
| 791 | 791 | ||
| 792 | u32 enable_common; | 792 | u32 enable_common; |
| @@ -802,7 +802,7 @@ public: | |||
| 802 | u32 stencil_front_func_mask; | 802 | u32 stencil_front_func_mask; |
| 803 | u32 stencil_front_mask; | 803 | u32 stencil_front_mask; |
| 804 | 804 | ||
| 805 | INSERT_PADDING_WORDS(0x2); | 805 | INSERT_UNION_PADDING_WORDS(0x2); |
| 806 | 806 | ||
| 807 | u32 frag_color_clamp; | 807 | u32 frag_color_clamp; |
| 808 | 808 | ||
| @@ -811,12 +811,12 @@ public: | |||
| 811 | BitField<4, 1, u32> triangle_rast_flip; | 811 | BitField<4, 1, u32> triangle_rast_flip; |
| 812 | } screen_y_control; | 812 | } screen_y_control; |
| 813 | 813 | ||
| 814 | INSERT_PADDING_WORDS(0x21); | 814 | INSERT_UNION_PADDING_WORDS(0x21); |
| 815 | 815 | ||
| 816 | u32 vb_element_base; | 816 | u32 vb_element_base; |
| 817 | u32 vb_base_instance; | 817 | u32 vb_base_instance; |
| 818 | 818 | ||
| 819 | INSERT_PADDING_WORDS(0x35); | 819 | INSERT_UNION_PADDING_WORDS(0x35); |
| 820 | 820 | ||
| 821 | union { | 821 | union { |
| 822 | BitField<0, 1, u32> c0; | 822 | BitField<0, 1, u32> c0; |
| @@ -829,11 +829,11 @@ public: | |||
| 829 | BitField<7, 1, u32> c7; | 829 | BitField<7, 1, u32> c7; |
| 830 | } clip_distance_enabled; | 830 | } clip_distance_enabled; |
| 831 | 831 | ||
| 832 | INSERT_PADDING_WORDS(0x1); | 832 | INSERT_UNION_PADDING_WORDS(0x1); |
| 833 | 833 | ||
| 834 | float point_size; | 834 | float point_size; |
| 835 | 835 | ||
| 836 | INSERT_PADDING_WORDS(0x7); | 836 | INSERT_UNION_PADDING_WORDS(0x7); |
| 837 | 837 | ||
| 838 | u32 zeta_enable; | 838 | u32 zeta_enable; |
| 839 | 839 | ||
| @@ -842,7 +842,7 @@ public: | |||
| 842 | BitField<4, 1, u32> alpha_to_one; | 842 | BitField<4, 1, u32> alpha_to_one; |
| 843 | } multisample_control; | 843 | } multisample_control; |
| 844 | 844 | ||
| 845 | INSERT_PADDING_WORDS(0x4); | 845 | INSERT_UNION_PADDING_WORDS(0x4); |
| 846 | 846 | ||
| 847 | struct { | 847 | struct { |
| 848 | u32 address_high; | 848 | u32 address_high; |
| @@ -866,11 +866,11 @@ public: | |||
| 866 | } | 866 | } |
| 867 | } tsc; | 867 | } tsc; |
| 868 | 868 | ||
| 869 | INSERT_PADDING_WORDS(0x1); | 869 | INSERT_UNION_PADDING_WORDS(0x1); |
| 870 | 870 | ||
| 871 | float polygon_offset_factor; | 871 | float polygon_offset_factor; |
| 872 | 872 | ||
| 873 | INSERT_PADDING_WORDS(0x1); | 873 | INSERT_UNION_PADDING_WORDS(0x1); |
| 874 | 874 | ||
| 875 | struct { | 875 | struct { |
| 876 | u32 tic_address_high; | 876 | u32 tic_address_high; |
| @@ -883,7 +883,7 @@ public: | |||
| 883 | } | 883 | } |
| 884 | } tic; | 884 | } tic; |
| 885 | 885 | ||
| 886 | INSERT_PADDING_WORDS(0x5); | 886 | INSERT_UNION_PADDING_WORDS(0x5); |
| 887 | 887 | ||
| 888 | u32 stencil_two_side_enable; | 888 | u32 stencil_two_side_enable; |
| 889 | StencilOp stencil_back_op_fail; | 889 | StencilOp stencil_back_op_fail; |
| @@ -891,13 +891,13 @@ public: | |||
| 891 | StencilOp stencil_back_op_zpass; | 891 | StencilOp stencil_back_op_zpass; |
| 892 | ComparisonOp stencil_back_func_func; | 892 | ComparisonOp stencil_back_func_func; |
| 893 | 893 | ||
| 894 | INSERT_PADDING_WORDS(0x4); | 894 | INSERT_UNION_PADDING_WORDS(0x4); |
| 895 | 895 | ||
| 896 | u32 framebuffer_srgb; | 896 | u32 framebuffer_srgb; |
| 897 | 897 | ||
| 898 | float polygon_offset_units; | 898 | float polygon_offset_units; |
| 899 | 899 | ||
| 900 | INSERT_PADDING_WORDS(0x11); | 900 | INSERT_UNION_PADDING_WORDS(0x11); |
| 901 | 901 | ||
| 902 | union { | 902 | union { |
| 903 | BitField<2, 1, u32> coord_origin; | 903 | BitField<2, 1, u32> coord_origin; |
| @@ -913,7 +913,7 @@ public: | |||
| 913 | (static_cast<GPUVAddr>(code_address_high) << 32) | code_address_low); | 913 | (static_cast<GPUVAddr>(code_address_high) << 32) | code_address_low); |
| 914 | } | 914 | } |
| 915 | } code_address; | 915 | } code_address; |
| 916 | INSERT_PADDING_WORDS(1); | 916 | INSERT_UNION_PADDING_WORDS(1); |
| 917 | 917 | ||
| 918 | struct { | 918 | struct { |
| 919 | u32 vertex_end_gl; | 919 | u32 vertex_end_gl; |
| @@ -925,14 +925,14 @@ public: | |||
| 925 | }; | 925 | }; |
| 926 | } draw; | 926 | } draw; |
| 927 | 927 | ||
| 928 | INSERT_PADDING_WORDS(0xA); | 928 | INSERT_UNION_PADDING_WORDS(0xA); |
| 929 | 929 | ||
| 930 | struct { | 930 | struct { |
| 931 | u32 enabled; | 931 | u32 enabled; |
| 932 | u32 index; | 932 | u32 index; |
| 933 | } primitive_restart; | 933 | } primitive_restart; |
| 934 | 934 | ||
| 935 | INSERT_PADDING_WORDS(0x5F); | 935 | INSERT_UNION_PADDING_WORDS(0x5F); |
| 936 | 936 | ||
| 937 | struct { | 937 | struct { |
| 938 | u32 start_addr_high; | 938 | u32 start_addr_high; |
| @@ -973,9 +973,9 @@ public: | |||
| 973 | } | 973 | } |
| 974 | } index_array; | 974 | } index_array; |
| 975 | 975 | ||
| 976 | INSERT_PADDING_WORDS(0x7); | 976 | INSERT_UNION_PADDING_WORDS(0x7); |
| 977 | 977 | ||
| 978 | INSERT_PADDING_WORDS(0x1F); | 978 | INSERT_UNION_PADDING_WORDS(0x1F); |
| 979 | 979 | ||
| 980 | float polygon_offset_clamp; | 980 | float polygon_offset_clamp; |
| 981 | 981 | ||
| @@ -989,17 +989,17 @@ public: | |||
| 989 | } | 989 | } |
| 990 | } instanced_arrays; | 990 | } instanced_arrays; |
| 991 | 991 | ||
| 992 | INSERT_PADDING_WORDS(0x6); | 992 | INSERT_UNION_PADDING_WORDS(0x6); |
| 993 | 993 | ||
| 994 | Cull cull; | 994 | Cull cull; |
| 995 | 995 | ||
| 996 | u32 pixel_center_integer; | 996 | u32 pixel_center_integer; |
| 997 | 997 | ||
| 998 | INSERT_PADDING_WORDS(0x1); | 998 | INSERT_UNION_PADDING_WORDS(0x1); |
| 999 | 999 | ||
| 1000 | u32 viewport_transform_enabled; | 1000 | u32 viewport_transform_enabled; |
| 1001 | 1001 | ||
| 1002 | INSERT_PADDING_WORDS(0x3); | 1002 | INSERT_UNION_PADDING_WORDS(0x3); |
| 1003 | 1003 | ||
| 1004 | union { | 1004 | union { |
| 1005 | BitField<0, 1, u32> depth_range_0_1; | 1005 | BitField<0, 1, u32> depth_range_0_1; |
| @@ -1007,13 +1007,13 @@ public: | |||
| 1007 | BitField<4, 1, u32> depth_clamp_far; | 1007 | BitField<4, 1, u32> depth_clamp_far; |
| 1008 | } view_volume_clip_control; | 1008 | } view_volume_clip_control; |
| 1009 | 1009 | ||
| 1010 | INSERT_PADDING_WORDS(0x21); | 1010 | INSERT_UNION_PADDING_WORDS(0x21); |
| 1011 | struct { | 1011 | struct { |
| 1012 | u32 enable; | 1012 | u32 enable; |
| 1013 | LogicOperation operation; | 1013 | LogicOperation operation; |
| 1014 | } logic_op; | 1014 | } logic_op; |
| 1015 | 1015 | ||
| 1016 | INSERT_PADDING_WORDS(0x1); | 1016 | INSERT_UNION_PADDING_WORDS(0x1); |
| 1017 | 1017 | ||
| 1018 | union { | 1018 | union { |
| 1019 | u32 raw; | 1019 | u32 raw; |
| @@ -1026,9 +1026,9 @@ public: | |||
| 1026 | BitField<6, 4, u32> RT; | 1026 | BitField<6, 4, u32> RT; |
| 1027 | BitField<10, 11, u32> layer; | 1027 | BitField<10, 11, u32> layer; |
| 1028 | } clear_buffers; | 1028 | } clear_buffers; |
| 1029 | INSERT_PADDING_WORDS(0xB); | 1029 | INSERT_UNION_PADDING_WORDS(0xB); |
| 1030 | std::array<ColorMask, NumRenderTargets> color_mask; | 1030 | std::array<ColorMask, NumRenderTargets> color_mask; |
| 1031 | INSERT_PADDING_WORDS(0x38); | 1031 | INSERT_UNION_PADDING_WORDS(0x38); |
| 1032 | 1032 | ||
| 1033 | struct { | 1033 | struct { |
| 1034 | u32 query_address_high; | 1034 | u32 query_address_high; |
| @@ -1050,7 +1050,7 @@ public: | |||
| 1050 | } | 1050 | } |
| 1051 | } query; | 1051 | } query; |
| 1052 | 1052 | ||
| 1053 | INSERT_PADDING_WORDS(0x3C); | 1053 | INSERT_UNION_PADDING_WORDS(0x3C); |
| 1054 | 1054 | ||
| 1055 | struct { | 1055 | struct { |
| 1056 | union { | 1056 | union { |
| @@ -1090,10 +1090,10 @@ public: | |||
| 1090 | BitField<4, 4, ShaderProgram> program; | 1090 | BitField<4, 4, ShaderProgram> program; |
| 1091 | }; | 1091 | }; |
| 1092 | u32 offset; | 1092 | u32 offset; |
| 1093 | INSERT_PADDING_WORDS(14); | 1093 | INSERT_UNION_PADDING_WORDS(14); |
| 1094 | } shader_config[MaxShaderProgram]; | 1094 | } shader_config[MaxShaderProgram]; |
| 1095 | 1095 | ||
| 1096 | INSERT_PADDING_WORDS(0x60); | 1096 | INSERT_UNION_PADDING_WORDS(0x60); |
| 1097 | 1097 | ||
| 1098 | u32 firmware[0x20]; | 1098 | u32 firmware[0x20]; |
| 1099 | 1099 | ||
| @@ -1110,7 +1110,7 @@ public: | |||
| 1110 | } | 1110 | } |
| 1111 | } const_buffer; | 1111 | } const_buffer; |
| 1112 | 1112 | ||
| 1113 | INSERT_PADDING_WORDS(0x10); | 1113 | INSERT_UNION_PADDING_WORDS(0x10); |
| 1114 | 1114 | ||
| 1115 | struct { | 1115 | struct { |
| 1116 | union { | 1116 | union { |
| @@ -1118,14 +1118,14 @@ public: | |||
| 1118 | BitField<0, 1, u32> valid; | 1118 | BitField<0, 1, u32> valid; |
| 1119 | BitField<4, 5, u32> index; | 1119 | BitField<4, 5, u32> index; |
| 1120 | }; | 1120 | }; |
| 1121 | INSERT_PADDING_WORDS(7); | 1121 | INSERT_UNION_PADDING_WORDS(7); |
| 1122 | } cb_bind[MaxShaderStage]; | 1122 | } cb_bind[MaxShaderStage]; |
| 1123 | 1123 | ||
| 1124 | INSERT_PADDING_WORDS(0x56); | 1124 | INSERT_UNION_PADDING_WORDS(0x56); |
| 1125 | 1125 | ||
| 1126 | u32 tex_cb_index; | 1126 | u32 tex_cb_index; |
| 1127 | 1127 | ||
| 1128 | INSERT_PADDING_WORDS(0x395); | 1128 | INSERT_UNION_PADDING_WORDS(0x395); |
| 1129 | 1129 | ||
| 1130 | struct { | 1130 | struct { |
| 1131 | /// Compressed address of a buffer that holds information about bound SSBOs. | 1131 | /// Compressed address of a buffer that holds information about bound SSBOs. |
| @@ -1137,14 +1137,14 @@ public: | |||
| 1137 | } | 1137 | } |
| 1138 | } ssbo_info; | 1138 | } ssbo_info; |
| 1139 | 1139 | ||
| 1140 | INSERT_PADDING_WORDS(0x11); | 1140 | INSERT_UNION_PADDING_WORDS(0x11); |
| 1141 | 1141 | ||
| 1142 | struct { | 1142 | struct { |
| 1143 | u32 address[MaxShaderStage]; | 1143 | u32 address[MaxShaderStage]; |
| 1144 | u32 size[MaxShaderStage]; | 1144 | u32 size[MaxShaderStage]; |
| 1145 | } tex_info_buffers; | 1145 | } tex_info_buffers; |
| 1146 | 1146 | ||
| 1147 | INSERT_PADDING_WORDS(0xCC); | 1147 | INSERT_UNION_PADDING_WORDS(0xCC); |
| 1148 | }; | 1148 | }; |
| 1149 | std::array<u32, NUM_REGS> reg_array; | 1149 | std::array<u32, NUM_REGS> reg_array; |
| 1150 | }; | 1150 | }; |
diff --git a/src/video_core/engines/maxwell_dma.h b/src/video_core/engines/maxwell_dma.h index 93808a9bb..4f40d1d1f 100644 --- a/src/video_core/engines/maxwell_dma.h +++ b/src/video_core/engines/maxwell_dma.h | |||
| @@ -94,7 +94,7 @@ public: | |||
| 94 | 94 | ||
| 95 | union { | 95 | union { |
| 96 | struct { | 96 | struct { |
| 97 | INSERT_PADDING_WORDS(0xC0); | 97 | INSERT_UNION_PADDING_WORDS(0xC0); |
| 98 | 98 | ||
| 99 | struct { | 99 | struct { |
| 100 | union { | 100 | union { |
| @@ -112,7 +112,7 @@ public: | |||
| 112 | }; | 112 | }; |
| 113 | } exec; | 113 | } exec; |
| 114 | 114 | ||
| 115 | INSERT_PADDING_WORDS(0x3F); | 115 | INSERT_UNION_PADDING_WORDS(0x3F); |
| 116 | 116 | ||
| 117 | struct { | 117 | struct { |
| 118 | u32 address_high; | 118 | u32 address_high; |
| @@ -139,7 +139,7 @@ public: | |||
| 139 | u32 x_count; | 139 | u32 x_count; |
| 140 | u32 y_count; | 140 | u32 y_count; |
| 141 | 141 | ||
| 142 | INSERT_PADDING_WORDS(0xB8); | 142 | INSERT_UNION_PADDING_WORDS(0xB8); |
| 143 | 143 | ||
| 144 | u32 const0; | 144 | u32 const0; |
| 145 | u32 const1; | 145 | u32 const1; |
| @@ -162,11 +162,11 @@ public: | |||
| 162 | 162 | ||
| 163 | Parameters dst_params; | 163 | Parameters dst_params; |
| 164 | 164 | ||
| 165 | INSERT_PADDING_WORDS(1); | 165 | INSERT_UNION_PADDING_WORDS(1); |
| 166 | 166 | ||
| 167 | Parameters src_params; | 167 | Parameters src_params; |
| 168 | 168 | ||
| 169 | INSERT_PADDING_WORDS(0x13); | 169 | INSERT_UNION_PADDING_WORDS(0x13); |
| 170 | }; | 170 | }; |
| 171 | std::array<u32, NUM_REGS> reg_array; | 171 | std::array<u32, NUM_REGS> reg_array; |
| 172 | }; | 172 | }; |
diff --git a/src/video_core/engines/shader_header.h b/src/video_core/engines/shader_header.h index e86a7f04a..bc80661d8 100644 --- a/src/video_core/engines/shader_header.h +++ b/src/video_core/engines/shader_header.h | |||
| @@ -38,37 +38,37 @@ struct Header { | |||
| 38 | BitField<26, 1, u32> does_load_or_store; | 38 | BitField<26, 1, u32> does_load_or_store; |
| 39 | BitField<27, 1, u32> does_fp64; | 39 | BitField<27, 1, u32> does_fp64; |
| 40 | BitField<28, 4, u32> stream_out_mask; | 40 | BitField<28, 4, u32> stream_out_mask; |
| 41 | } common0; | 41 | } common0{}; |
| 42 | 42 | ||
| 43 | union { | 43 | union { |
| 44 | BitField<0, 24, u32> shader_local_memory_low_size; | 44 | BitField<0, 24, u32> shader_local_memory_low_size; |
| 45 | BitField<24, 8, u32> per_patch_attribute_count; | 45 | BitField<24, 8, u32> per_patch_attribute_count; |
| 46 | } common1; | 46 | } common1{}; |
| 47 | 47 | ||
| 48 | union { | 48 | union { |
| 49 | BitField<0, 24, u32> shader_local_memory_high_size; | 49 | BitField<0, 24, u32> shader_local_memory_high_size; |
| 50 | BitField<24, 8, u32> threads_per_input_primitive; | 50 | BitField<24, 8, u32> threads_per_input_primitive; |
| 51 | } common2; | 51 | } common2{}; |
| 52 | 52 | ||
| 53 | union { | 53 | union { |
| 54 | BitField<0, 24, u32> shader_local_memory_crs_size; | 54 | BitField<0, 24, u32> shader_local_memory_crs_size; |
| 55 | BitField<24, 4, OutputTopology> output_topology; | 55 | BitField<24, 4, OutputTopology> output_topology; |
| 56 | BitField<28, 4, u32> reserved; | 56 | BitField<28, 4, u32> reserved; |
| 57 | } common3; | 57 | } common3{}; |
| 58 | 58 | ||
| 59 | union { | 59 | union { |
| 60 | BitField<0, 12, u32> max_output_vertices; | 60 | BitField<0, 12, u32> max_output_vertices; |
| 61 | BitField<12, 8, u32> store_req_start; // NOTE: not used by geometry shaders. | 61 | BitField<12, 8, u32> store_req_start; // NOTE: not used by geometry shaders. |
| 62 | BitField<24, 4, u32> reserved; | 62 | BitField<24, 4, u32> reserved; |
| 63 | BitField<12, 8, u32> store_req_end; // NOTE: not used by geometry shaders. | 63 | BitField<12, 8, u32> store_req_end; // NOTE: not used by geometry shaders. |
| 64 | } common4; | 64 | } common4{}; |
| 65 | 65 | ||
| 66 | union { | 66 | union { |
| 67 | struct { | 67 | struct { |
| 68 | INSERT_PADDING_BYTES(3); // ImapSystemValuesA | 68 | INSERT_UNION_PADDING_BYTES(3); // ImapSystemValuesA |
| 69 | INSERT_PADDING_BYTES(1); // ImapSystemValuesB | 69 | INSERT_UNION_PADDING_BYTES(1); // ImapSystemValuesB |
| 70 | INSERT_PADDING_BYTES(16); // ImapGenericVector[32] | 70 | INSERT_UNION_PADDING_BYTES(16); // ImapGenericVector[32] |
| 71 | INSERT_PADDING_BYTES(2); // ImapColor | 71 | INSERT_UNION_PADDING_BYTES(2); // ImapColor |
| 72 | union { | 72 | union { |
| 73 | BitField<0, 8, u16> clip_distances; | 73 | BitField<0, 8, u16> clip_distances; |
| 74 | BitField<8, 1, u16> point_sprite_s; | 74 | BitField<8, 1, u16> point_sprite_s; |
| @@ -79,20 +79,20 @@ struct Header { | |||
| 79 | BitField<14, 1, u16> instance_id; | 79 | BitField<14, 1, u16> instance_id; |
| 80 | BitField<15, 1, u16> vertex_id; | 80 | BitField<15, 1, u16> vertex_id; |
| 81 | }; | 81 | }; |
| 82 | INSERT_PADDING_BYTES(5); // ImapFixedFncTexture[10] | 82 | INSERT_UNION_PADDING_BYTES(5); // ImapFixedFncTexture[10] |
| 83 | INSERT_PADDING_BYTES(1); // ImapReserved | 83 | INSERT_UNION_PADDING_BYTES(1); // ImapReserved |
| 84 | INSERT_PADDING_BYTES(3); // OmapSystemValuesA | 84 | INSERT_UNION_PADDING_BYTES(3); // OmapSystemValuesA |
| 85 | INSERT_PADDING_BYTES(1); // OmapSystemValuesB | 85 | INSERT_UNION_PADDING_BYTES(1); // OmapSystemValuesB |
| 86 | INSERT_PADDING_BYTES(16); // OmapGenericVector[32] | 86 | INSERT_UNION_PADDING_BYTES(16); // OmapGenericVector[32] |
| 87 | INSERT_PADDING_BYTES(2); // OmapColor | 87 | INSERT_UNION_PADDING_BYTES(2); // OmapColor |
| 88 | INSERT_PADDING_BYTES(2); // OmapSystemValuesC | 88 | INSERT_UNION_PADDING_BYTES(2); // OmapSystemValuesC |
| 89 | INSERT_PADDING_BYTES(5); // OmapFixedFncTexture[10] | 89 | INSERT_UNION_PADDING_BYTES(5); // OmapFixedFncTexture[10] |
| 90 | INSERT_PADDING_BYTES(1); // OmapReserved | 90 | INSERT_UNION_PADDING_BYTES(1); // OmapReserved |
| 91 | } vtg; | 91 | } vtg; |
| 92 | 92 | ||
| 93 | struct { | 93 | struct { |
| 94 | INSERT_PADDING_BYTES(3); // ImapSystemValuesA | 94 | INSERT_UNION_PADDING_BYTES(3); // ImapSystemValuesA |
| 95 | INSERT_PADDING_BYTES(1); // ImapSystemValuesB | 95 | INSERT_UNION_PADDING_BYTES(1); // ImapSystemValuesB |
| 96 | union { | 96 | union { |
| 97 | BitField<0, 2, AttributeUse> x; | 97 | BitField<0, 2, AttributeUse> x; |
| 98 | BitField<2, 2, AttributeUse> y; | 98 | BitField<2, 2, AttributeUse> y; |
| @@ -100,10 +100,10 @@ struct Header { | |||
| 100 | BitField<6, 2, AttributeUse> z; | 100 | BitField<6, 2, AttributeUse> z; |
| 101 | u8 raw; | 101 | u8 raw; |
| 102 | } imap_generic_vector[32]; | 102 | } imap_generic_vector[32]; |
| 103 | INSERT_PADDING_BYTES(2); // ImapColor | 103 | INSERT_UNION_PADDING_BYTES(2); // ImapColor |
| 104 | INSERT_PADDING_BYTES(2); // ImapSystemValuesC | 104 | INSERT_UNION_PADDING_BYTES(2); // ImapSystemValuesC |
| 105 | INSERT_PADDING_BYTES(10); // ImapFixedFncTexture[10] | 105 | INSERT_UNION_PADDING_BYTES(10); // ImapFixedFncTexture[10] |
| 106 | INSERT_PADDING_BYTES(2); // ImapReserved | 106 | INSERT_UNION_PADDING_BYTES(2); // ImapReserved |
| 107 | struct { | 107 | struct { |
| 108 | u32 target; | 108 | u32 target; |
| 109 | union { | 109 | union { |
| @@ -139,6 +139,8 @@ struct Header { | |||
| 139 | return result; | 139 | return result; |
| 140 | } | 140 | } |
| 141 | } ps; | 141 | } ps; |
| 142 | |||
| 143 | std::array<u32, 0xF> raw{}; | ||
| 142 | }; | 144 | }; |
| 143 | 145 | ||
| 144 | u64 GetLocalMemorySize() const { | 146 | u64 GetLocalMemorySize() const { |
diff --git a/src/video_core/gpu.h b/src/video_core/gpu.h index dbca19f35..ecc338ae9 100644 --- a/src/video_core/gpu.h +++ b/src/video_core/gpu.h | |||
| @@ -207,7 +207,7 @@ public: | |||
| 207 | 207 | ||
| 208 | union { | 208 | union { |
| 209 | struct { | 209 | struct { |
| 210 | INSERT_PADDING_WORDS(0x4); | 210 | INSERT_UNION_PADDING_WORDS(0x4); |
| 211 | struct { | 211 | struct { |
| 212 | u32 address_high; | 212 | u32 address_high; |
| 213 | u32 address_low; | 213 | u32 address_low; |
| @@ -220,12 +220,12 @@ public: | |||
| 220 | 220 | ||
| 221 | u32 semaphore_sequence; | 221 | u32 semaphore_sequence; |
| 222 | u32 semaphore_trigger; | 222 | u32 semaphore_trigger; |
| 223 | INSERT_PADDING_WORDS(0xC); | 223 | INSERT_UNION_PADDING_WORDS(0xC); |
| 224 | 224 | ||
| 225 | // The puser and the puller share the reference counter, the pusher only has read | 225 | // The puser and the puller share the reference counter, the pusher only has read |
| 226 | // access | 226 | // access |
| 227 | u32 reference_count; | 227 | u32 reference_count; |
| 228 | INSERT_PADDING_WORDS(0x5); | 228 | INSERT_UNION_PADDING_WORDS(0x5); |
| 229 | 229 | ||
| 230 | u32 semaphore_acquire; | 230 | u32 semaphore_acquire; |
| 231 | u32 semaphore_release; | 231 | u32 semaphore_release; |
| @@ -234,7 +234,7 @@ public: | |||
| 234 | BitField<4, 4, u32> operation; | 234 | BitField<4, 4, u32> operation; |
| 235 | BitField<8, 8, u32> id; | 235 | BitField<8, 8, u32> id; |
| 236 | } fence_action; | 236 | } fence_action; |
| 237 | INSERT_PADDING_WORDS(0xE2); | 237 | INSERT_UNION_PADDING_WORDS(0xE2); |
| 238 | 238 | ||
| 239 | // Puller state | 239 | // Puller state |
| 240 | u32 acquire_mode; | 240 | u32 acquire_mode; |
diff --git a/src/video_core/renderer_opengl/gl_buffer_cache.cpp b/src/video_core/renderer_opengl/gl_buffer_cache.cpp index f8a807c84..0375fca17 100644 --- a/src/video_core/renderer_opengl/gl_buffer_cache.cpp +++ b/src/video_core/renderer_opengl/gl_buffer_cache.cpp | |||
| @@ -8,13 +8,17 @@ | |||
| 8 | 8 | ||
| 9 | #include "common/assert.h" | 9 | #include "common/assert.h" |
| 10 | #include "common/microprofile.h" | 10 | #include "common/microprofile.h" |
| 11 | #include "video_core/engines/maxwell_3d.h" | ||
| 11 | #include "video_core/rasterizer_interface.h" | 12 | #include "video_core/rasterizer_interface.h" |
| 12 | #include "video_core/renderer_opengl/gl_buffer_cache.h" | 13 | #include "video_core/renderer_opengl/gl_buffer_cache.h" |
| 14 | #include "video_core/renderer_opengl/gl_device.h" | ||
| 13 | #include "video_core/renderer_opengl/gl_rasterizer.h" | 15 | #include "video_core/renderer_opengl/gl_rasterizer.h" |
| 14 | #include "video_core/renderer_opengl/gl_resource_manager.h" | 16 | #include "video_core/renderer_opengl/gl_resource_manager.h" |
| 15 | 17 | ||
| 16 | namespace OpenGL { | 18 | namespace OpenGL { |
| 17 | 19 | ||
| 20 | using Maxwell = Tegra::Engines::Maxwell3D::Regs; | ||
| 21 | |||
| 18 | MICROPROFILE_DEFINE(OpenGL_Buffer_Download, "OpenGL", "Buffer Download", MP_RGB(192, 192, 128)); | 22 | MICROPROFILE_DEFINE(OpenGL_Buffer_Download, "OpenGL", "Buffer Download", MP_RGB(192, 192, 128)); |
| 19 | 23 | ||
| 20 | CachedBufferBlock::CachedBufferBlock(CacheAddr cache_addr, const std::size_t size) | 24 | CachedBufferBlock::CachedBufferBlock(CacheAddr cache_addr, const std::size_t size) |
| @@ -26,11 +30,22 @@ CachedBufferBlock::CachedBufferBlock(CacheAddr cache_addr, const std::size_t siz | |||
| 26 | CachedBufferBlock::~CachedBufferBlock() = default; | 30 | CachedBufferBlock::~CachedBufferBlock() = default; |
| 27 | 31 | ||
| 28 | OGLBufferCache::OGLBufferCache(RasterizerOpenGL& rasterizer, Core::System& system, | 32 | OGLBufferCache::OGLBufferCache(RasterizerOpenGL& rasterizer, Core::System& system, |
| 29 | std::size_t stream_size) | 33 | const Device& device, std::size_t stream_size) |
| 30 | : VideoCommon::BufferCache<Buffer, GLuint, OGLStreamBuffer>{ | 34 | : GenericBufferCache{rasterizer, system, std::make_unique<OGLStreamBuffer>(stream_size, true)} { |
| 31 | rasterizer, system, std::make_unique<OGLStreamBuffer>(stream_size, true)} {} | 35 | if (!device.HasFastBufferSubData()) { |
| 36 | return; | ||
| 37 | } | ||
| 38 | |||
| 39 | static constexpr auto size = static_cast<GLsizeiptr>(Maxwell::MaxConstBufferSize); | ||
| 40 | glCreateBuffers(static_cast<GLsizei>(std::size(cbufs)), std::data(cbufs)); | ||
| 41 | for (const GLuint cbuf : cbufs) { | ||
| 42 | glNamedBufferData(cbuf, size, nullptr, GL_STREAM_DRAW); | ||
| 43 | } | ||
| 44 | } | ||
| 32 | 45 | ||
| 33 | OGLBufferCache::~OGLBufferCache() = default; | 46 | OGLBufferCache::~OGLBufferCache() { |
| 47 | glDeleteBuffers(static_cast<GLsizei>(std::size(cbufs)), std::data(cbufs)); | ||
| 48 | } | ||
| 34 | 49 | ||
| 35 | Buffer OGLBufferCache::CreateBlock(CacheAddr cache_addr, std::size_t size) { | 50 | Buffer OGLBufferCache::CreateBlock(CacheAddr cache_addr, std::size_t size) { |
| 36 | return std::make_shared<CachedBufferBlock>(cache_addr, size); | 51 | return std::make_shared<CachedBufferBlock>(cache_addr, size); |
| @@ -69,4 +84,12 @@ void OGLBufferCache::CopyBlock(const Buffer& src, const Buffer& dst, std::size_t | |||
| 69 | static_cast<GLsizeiptr>(size)); | 84 | static_cast<GLsizeiptr>(size)); |
| 70 | } | 85 | } |
| 71 | 86 | ||
| 87 | OGLBufferCache::BufferInfo OGLBufferCache::ConstBufferUpload(const void* raw_pointer, | ||
| 88 | std::size_t size) { | ||
| 89 | DEBUG_ASSERT(cbuf_cursor < std::size(cbufs)); | ||
| 90 | const GLuint& cbuf = cbufs[cbuf_cursor++]; | ||
| 91 | glNamedBufferSubData(cbuf, 0, static_cast<GLsizeiptr>(size), raw_pointer); | ||
| 92 | return {&cbuf, 0}; | ||
| 93 | } | ||
| 94 | |||
| 72 | } // namespace OpenGL | 95 | } // namespace OpenGL |
diff --git a/src/video_core/renderer_opengl/gl_buffer_cache.h b/src/video_core/renderer_opengl/gl_buffer_cache.h index 022e7bfa9..8c7145443 100644 --- a/src/video_core/renderer_opengl/gl_buffer_cache.h +++ b/src/video_core/renderer_opengl/gl_buffer_cache.h | |||
| @@ -4,10 +4,12 @@ | |||
| 4 | 4 | ||
| 5 | #pragma once | 5 | #pragma once |
| 6 | 6 | ||
| 7 | #include <array> | ||
| 7 | #include <memory> | 8 | #include <memory> |
| 8 | 9 | ||
| 9 | #include "common/common_types.h" | 10 | #include "common/common_types.h" |
| 10 | #include "video_core/buffer_cache/buffer_cache.h" | 11 | #include "video_core/buffer_cache/buffer_cache.h" |
| 12 | #include "video_core/engines/maxwell_3d.h" | ||
| 11 | #include "video_core/rasterizer_cache.h" | 13 | #include "video_core/rasterizer_cache.h" |
| 12 | #include "video_core/renderer_opengl/gl_resource_manager.h" | 14 | #include "video_core/renderer_opengl/gl_resource_manager.h" |
| 13 | #include "video_core/renderer_opengl/gl_stream_buffer.h" | 15 | #include "video_core/renderer_opengl/gl_stream_buffer.h" |
| @@ -18,12 +20,14 @@ class System; | |||
| 18 | 20 | ||
| 19 | namespace OpenGL { | 21 | namespace OpenGL { |
| 20 | 22 | ||
| 23 | class Device; | ||
| 21 | class OGLStreamBuffer; | 24 | class OGLStreamBuffer; |
| 22 | class RasterizerOpenGL; | 25 | class RasterizerOpenGL; |
| 23 | 26 | ||
| 24 | class CachedBufferBlock; | 27 | class CachedBufferBlock; |
| 25 | 28 | ||
| 26 | using Buffer = std::shared_ptr<CachedBufferBlock>; | 29 | using Buffer = std::shared_ptr<CachedBufferBlock>; |
| 30 | using GenericBufferCache = VideoCommon::BufferCache<Buffer, GLuint, OGLStreamBuffer>; | ||
| 27 | 31 | ||
| 28 | class CachedBufferBlock : public VideoCommon::BufferBlock { | 32 | class CachedBufferBlock : public VideoCommon::BufferBlock { |
| 29 | public: | 33 | public: |
| @@ -38,14 +42,18 @@ private: | |||
| 38 | OGLBuffer gl_buffer{}; | 42 | OGLBuffer gl_buffer{}; |
| 39 | }; | 43 | }; |
| 40 | 44 | ||
| 41 | class OGLBufferCache final : public VideoCommon::BufferCache<Buffer, GLuint, OGLStreamBuffer> { | 45 | class OGLBufferCache final : public GenericBufferCache { |
| 42 | public: | 46 | public: |
| 43 | explicit OGLBufferCache(RasterizerOpenGL& rasterizer, Core::System& system, | 47 | explicit OGLBufferCache(RasterizerOpenGL& rasterizer, Core::System& system, |
| 44 | std::size_t stream_size); | 48 | const Device& device, std::size_t stream_size); |
| 45 | ~OGLBufferCache(); | 49 | ~OGLBufferCache(); |
| 46 | 50 | ||
| 47 | const GLuint* GetEmptyBuffer(std::size_t) override; | 51 | const GLuint* GetEmptyBuffer(std::size_t) override; |
| 48 | 52 | ||
| 53 | void Acquire() noexcept { | ||
| 54 | cbuf_cursor = 0; | ||
| 55 | } | ||
| 56 | |||
| 49 | protected: | 57 | protected: |
| 50 | Buffer CreateBlock(CacheAddr cache_addr, std::size_t size) override; | 58 | Buffer CreateBlock(CacheAddr cache_addr, std::size_t size) override; |
| 51 | 59 | ||
| @@ -61,6 +69,14 @@ protected: | |||
| 61 | 69 | ||
| 62 | void CopyBlock(const Buffer& src, const Buffer& dst, std::size_t src_offset, | 70 | void CopyBlock(const Buffer& src, const Buffer& dst, std::size_t src_offset, |
| 63 | std::size_t dst_offset, std::size_t size) override; | 71 | std::size_t dst_offset, std::size_t size) override; |
| 72 | |||
| 73 | BufferInfo ConstBufferUpload(const void* raw_pointer, std::size_t size) override; | ||
| 74 | |||
| 75 | private: | ||
| 76 | std::size_t cbuf_cursor = 0; | ||
| 77 | std::array<GLuint, Tegra::Engines::Maxwell3D::Regs::MaxConstBuffers * | ||
| 78 | Tegra::Engines::Maxwell3D::Regs::MaxShaderProgram> | ||
| 79 | cbufs; | ||
| 64 | }; | 80 | }; |
| 65 | 81 | ||
| 66 | } // namespace OpenGL | 82 | } // namespace OpenGL |
diff --git a/src/video_core/renderer_opengl/gl_device.cpp b/src/video_core/renderer_opengl/gl_device.cpp index 64de7e425..c65b24c69 100644 --- a/src/video_core/renderer_opengl/gl_device.cpp +++ b/src/video_core/renderer_opengl/gl_device.cpp | |||
| @@ -51,8 +51,11 @@ bool HasExtension(const std::vector<std::string_view>& images, std::string_view | |||
| 51 | } // Anonymous namespace | 51 | } // Anonymous namespace |
| 52 | 52 | ||
| 53 | Device::Device() { | 53 | Device::Device() { |
| 54 | const std::string_view vendor = reinterpret_cast<const char*>(glGetString(GL_VENDOR)); | ||
| 54 | const std::vector extensions = GetExtensions(); | 55 | const std::vector extensions = GetExtensions(); |
| 55 | 56 | ||
| 57 | const bool is_nvidia = vendor == "NVIDIA Corporation"; | ||
| 58 | |||
| 56 | uniform_buffer_alignment = GetInteger<std::size_t>(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT); | 59 | uniform_buffer_alignment = GetInteger<std::size_t>(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT); |
| 57 | shader_storage_alignment = GetInteger<std::size_t>(GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT); | 60 | shader_storage_alignment = GetInteger<std::size_t>(GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT); |
| 58 | max_vertex_attributes = GetInteger<u32>(GL_MAX_VERTEX_ATTRIBS); | 61 | max_vertex_attributes = GetInteger<u32>(GL_MAX_VERTEX_ATTRIBS); |
| @@ -64,6 +67,7 @@ Device::Device() { | |||
| 64 | has_variable_aoffi = TestVariableAoffi(); | 67 | has_variable_aoffi = TestVariableAoffi(); |
| 65 | has_component_indexing_bug = TestComponentIndexingBug(); | 68 | has_component_indexing_bug = TestComponentIndexingBug(); |
| 66 | has_precise_bug = TestPreciseBug(); | 69 | has_precise_bug = TestPreciseBug(); |
| 70 | has_fast_buffer_sub_data = is_nvidia; | ||
| 67 | 71 | ||
| 68 | LOG_INFO(Render_OpenGL, "Renderer_VariableAOFFI: {}", has_variable_aoffi); | 72 | LOG_INFO(Render_OpenGL, "Renderer_VariableAOFFI: {}", has_variable_aoffi); |
| 69 | LOG_INFO(Render_OpenGL, "Renderer_ComponentIndexingBug: {}", has_component_indexing_bug); | 73 | LOG_INFO(Render_OpenGL, "Renderer_ComponentIndexingBug: {}", has_component_indexing_bug); |
diff --git a/src/video_core/renderer_opengl/gl_device.h b/src/video_core/renderer_opengl/gl_device.h index bb273c3d6..bf35bd0b6 100644 --- a/src/video_core/renderer_opengl/gl_device.h +++ b/src/video_core/renderer_opengl/gl_device.h | |||
| @@ -54,6 +54,10 @@ public: | |||
| 54 | return has_precise_bug; | 54 | return has_precise_bug; |
| 55 | } | 55 | } |
| 56 | 56 | ||
| 57 | bool HasFastBufferSubData() const { | ||
| 58 | return has_fast_buffer_sub_data; | ||
| 59 | } | ||
| 60 | |||
| 57 | private: | 61 | private: |
| 58 | static bool TestVariableAoffi(); | 62 | static bool TestVariableAoffi(); |
| 59 | static bool TestComponentIndexingBug(); | 63 | static bool TestComponentIndexingBug(); |
| @@ -69,6 +73,7 @@ private: | |||
| 69 | bool has_variable_aoffi{}; | 73 | bool has_variable_aoffi{}; |
| 70 | bool has_component_indexing_bug{}; | 74 | bool has_component_indexing_bug{}; |
| 71 | bool has_precise_bug{}; | 75 | bool has_precise_bug{}; |
| 76 | bool has_fast_buffer_sub_data{}; | ||
| 72 | }; | 77 | }; |
| 73 | 78 | ||
| 74 | } // namespace OpenGL | 79 | } // namespace OpenGL |
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 6a4d2c83a..e560d70d5 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp | |||
| @@ -67,7 +67,7 @@ static std::size_t GetConstBufferSize(const Tegra::Engines::ConstBufferInfo& buf | |||
| 67 | RasterizerOpenGL::RasterizerOpenGL(Core::System& system, Core::Frontend::EmuWindow& emu_window, | 67 | RasterizerOpenGL::RasterizerOpenGL(Core::System& system, Core::Frontend::EmuWindow& emu_window, |
| 68 | ScreenInfo& info) | 68 | ScreenInfo& info) |
| 69 | : texture_cache{system, *this, device}, shader_cache{*this, system, emu_window, device}, | 69 | : texture_cache{system, *this, device}, shader_cache{*this, system, emu_window, device}, |
| 70 | system{system}, screen_info{info}, buffer_cache{*this, system, STREAM_BUFFER_SIZE} { | 70 | system{system}, screen_info{info}, buffer_cache{*this, system, device, STREAM_BUFFER_SIZE} { |
| 71 | shader_program_manager = std::make_unique<GLShader::ProgramManager>(); | 71 | shader_program_manager = std::make_unique<GLShader::ProgramManager>(); |
| 72 | state.draw.shader_program = 0; | 72 | state.draw.shader_program = 0; |
| 73 | state.Apply(); | 73 | state.Apply(); |
| @@ -558,6 +558,8 @@ void RasterizerOpenGL::DrawPrelude() { | |||
| 558 | SyncPolygonOffset(); | 558 | SyncPolygonOffset(); |
| 559 | SyncAlphaTest(); | 559 | SyncAlphaTest(); |
| 560 | 560 | ||
| 561 | buffer_cache.Acquire(); | ||
| 562 | |||
| 561 | // Draw the vertex batch | 563 | // Draw the vertex batch |
| 562 | const bool is_indexed = accelerate_draw == AccelDraw::Indexed; | 564 | const bool is_indexed = accelerate_draw == AccelDraw::Indexed; |
| 563 | 565 | ||
| @@ -879,7 +881,8 @@ void RasterizerOpenGL::SetupConstBuffer(const Tegra::Engines::ConstBufferInfo& b | |||
| 879 | const std::size_t size = Common::AlignUp(GetConstBufferSize(buffer, entry), sizeof(GLvec4)); | 881 | const std::size_t size = Common::AlignUp(GetConstBufferSize(buffer, entry), sizeof(GLvec4)); |
| 880 | 882 | ||
| 881 | const auto alignment = device.GetUniformBufferAlignment(); | 883 | const auto alignment = device.GetUniformBufferAlignment(); |
| 882 | const auto [cbuf, offset] = buffer_cache.UploadMemory(buffer.address, size, alignment); | 884 | const auto [cbuf, offset] = buffer_cache.UploadMemory(buffer.address, size, alignment, false, |
| 885 | device.HasFastBufferSubData()); | ||
| 883 | bind_ubo_pushbuffer.Push(cbuf, offset, size); | 886 | bind_ubo_pushbuffer.Push(cbuf, offset, size); |
| 884 | } | 887 | } |
| 885 | 888 | ||
| @@ -935,10 +938,9 @@ TextureBufferUsage RasterizerOpenGL::SetupDrawTextures(Maxwell::ShaderStage stag | |||
| 935 | if (!entry.IsBindless()) { | 938 | if (!entry.IsBindless()) { |
| 936 | return maxwell3d.GetStageTexture(stage, entry.GetOffset()); | 939 | return maxwell3d.GetStageTexture(stage, entry.GetOffset()); |
| 937 | } | 940 | } |
| 938 | const auto cbuf = entry.GetBindlessCBuf(); | 941 | const auto shader_type = static_cast<Tegra::Engines::ShaderType>(stage); |
| 939 | Tegra::Texture::TextureHandle tex_handle; | 942 | const Tegra::Texture::TextureHandle tex_handle = |
| 940 | Tegra::Engines::ShaderType shader_type = static_cast<Tegra::Engines::ShaderType>(stage); | 943 | maxwell3d.AccessConstBuffer32(shader_type, entry.GetBuffer(), entry.GetOffset()); |
| 941 | tex_handle.raw = maxwell3d.AccessConstBuffer32(shader_type, cbuf.first, cbuf.second); | ||
| 942 | return maxwell3d.GetTextureInfo(tex_handle); | 944 | return maxwell3d.GetTextureInfo(tex_handle); |
| 943 | }(); | 945 | }(); |
| 944 | 946 | ||
| @@ -966,10 +968,8 @@ TextureBufferUsage RasterizerOpenGL::SetupComputeTextures(const Shader& kernel) | |||
| 966 | if (!entry.IsBindless()) { | 968 | if (!entry.IsBindless()) { |
| 967 | return compute.GetTexture(entry.GetOffset()); | 969 | return compute.GetTexture(entry.GetOffset()); |
| 968 | } | 970 | } |
| 969 | const auto cbuf = entry.GetBindlessCBuf(); | 971 | const Tegra::Texture::TextureHandle tex_handle = compute.AccessConstBuffer32( |
| 970 | Tegra::Texture::TextureHandle tex_handle; | 972 | Tegra::Engines::ShaderType::Compute, entry.GetBuffer(), entry.GetOffset()); |
| 971 | tex_handle.raw = compute.AccessConstBuffer32(Tegra::Engines::ShaderType::Compute, | ||
| 972 | cbuf.first, cbuf.second); | ||
| 973 | return compute.GetTextureInfo(tex_handle); | 973 | return compute.GetTextureInfo(tex_handle); |
| 974 | }(); | 974 | }(); |
| 975 | 975 | ||
| @@ -1012,10 +1012,8 @@ void RasterizerOpenGL::SetupComputeImages(const Shader& shader) { | |||
| 1012 | if (!entry.IsBindless()) { | 1012 | if (!entry.IsBindless()) { |
| 1013 | return compute.GetTexture(entry.GetOffset()).tic; | 1013 | return compute.GetTexture(entry.GetOffset()).tic; |
| 1014 | } | 1014 | } |
| 1015 | const auto cbuf = entry.GetBindlessCBuf(); | 1015 | const Tegra::Texture::TextureHandle tex_handle = compute.AccessConstBuffer32( |
| 1016 | Tegra::Texture::TextureHandle tex_handle; | 1016 | Tegra::Engines::ShaderType::Compute, entry.GetBuffer(), entry.GetOffset()); |
| 1017 | tex_handle.raw = compute.AccessConstBuffer32(Tegra::Engines::ShaderType::Compute, | ||
| 1018 | cbuf.first, cbuf.second); | ||
| 1019 | return compute.GetTextureInfo(tex_handle).tic; | 1017 | return compute.GetTextureInfo(tex_handle).tic; |
| 1020 | }(); | 1018 | }(); |
| 1021 | SetupImage(bindpoint, tic, entry); | 1019 | SetupImage(bindpoint, tic, entry); |
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp index 8a514cb8a..0ce59a852 100644 --- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp +++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp | |||
| @@ -735,7 +735,7 @@ private: | |||
| 735 | 735 | ||
| 736 | void DeclareImages() { | 736 | void DeclareImages() { |
| 737 | const auto& images{ir.GetImages()}; | 737 | const auto& images{ir.GetImages()}; |
| 738 | for (const auto& [offset, image] : images) { | 738 | for (const auto& image : images) { |
| 739 | std::string qualifier = "coherent volatile"; | 739 | std::string qualifier = "coherent volatile"; |
| 740 | if (image.IsRead() && !image.IsWritten()) { | 740 | if (image.IsRead() && !image.IsWritten()) { |
| 741 | qualifier += " readonly"; | 741 | qualifier += " readonly"; |
| @@ -2466,16 +2466,16 @@ ShaderEntries GetEntries(const VideoCommon::Shader::ShaderIR& ir) { | |||
| 2466 | entries.const_buffers.emplace_back(cbuf.second.GetMaxOffset(), cbuf.second.IsIndirect(), | 2466 | entries.const_buffers.emplace_back(cbuf.second.GetMaxOffset(), cbuf.second.IsIndirect(), |
| 2467 | cbuf.first); | 2467 | cbuf.first); |
| 2468 | } | 2468 | } |
| 2469 | for (const auto& [base, usage] : ir.GetGlobalMemory()) { | ||
| 2470 | entries.global_memory_entries.emplace_back(base.cbuf_index, base.cbuf_offset, usage.is_read, | ||
| 2471 | usage.is_written); | ||
| 2472 | } | ||
| 2469 | for (const auto& sampler : ir.GetSamplers()) { | 2473 | for (const auto& sampler : ir.GetSamplers()) { |
| 2470 | entries.samplers.emplace_back(sampler); | 2474 | entries.samplers.emplace_back(sampler); |
| 2471 | } | 2475 | } |
| 2472 | for (const auto& [offset, image] : ir.GetImages()) { | 2476 | for (const auto& image : ir.GetImages()) { |
| 2473 | entries.images.emplace_back(image); | 2477 | entries.images.emplace_back(image); |
| 2474 | } | 2478 | } |
| 2475 | for (const auto& [base, usage] : ir.GetGlobalMemory()) { | ||
| 2476 | entries.global_memory_entries.emplace_back(base.cbuf_index, base.cbuf_offset, usage.is_read, | ||
| 2477 | usage.is_written); | ||
| 2478 | } | ||
| 2479 | entries.clip_distances = ir.GetClipDistances(); | 2479 | entries.clip_distances = ir.GetClipDistances(); |
| 2480 | entries.shader_length = ir.GetLength(); | 2480 | entries.shader_length = ir.GetLength(); |
| 2481 | return entries; | 2481 | return entries; |
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.h b/src/video_core/renderer_opengl/gl_shader_decompiler.h index fead2a51e..b1e75e6cc 100644 --- a/src/video_core/renderer_opengl/gl_shader_decompiler.h +++ b/src/video_core/renderer_opengl/gl_shader_decompiler.h | |||
| @@ -82,10 +82,9 @@ private: | |||
| 82 | 82 | ||
| 83 | struct ShaderEntries { | 83 | struct ShaderEntries { |
| 84 | std::vector<ConstBufferEntry> const_buffers; | 84 | std::vector<ConstBufferEntry> const_buffers; |
| 85 | std::vector<GlobalMemoryEntry> global_memory_entries; | ||
| 85 | std::vector<SamplerEntry> samplers; | 86 | std::vector<SamplerEntry> samplers; |
| 86 | std::vector<SamplerEntry> bindless_samplers; | ||
| 87 | std::vector<ImageEntry> images; | 87 | std::vector<ImageEntry> images; |
| 88 | std::vector<GlobalMemoryEntry> global_memory_entries; | ||
| 89 | std::array<bool, Maxwell::NumClipDistances> clip_distances{}; | 88 | std::array<bool, Maxwell::NumClipDistances> clip_distances{}; |
| 90 | std::size_t shader_length{}; | 89 | std::size_t shader_length{}; |
| 91 | }; | 90 | }; |
diff --git a/src/video_core/shader/control_flow.cpp b/src/video_core/shader/control_flow.cpp index d47c63d9f..b427ac873 100644 --- a/src/video_core/shader/control_flow.cpp +++ b/src/video_core/shader/control_flow.cpp | |||
| @@ -16,7 +16,9 @@ | |||
| 16 | #include "video_core/shader/shader_ir.h" | 16 | #include "video_core/shader/shader_ir.h" |
| 17 | 17 | ||
| 18 | namespace VideoCommon::Shader { | 18 | namespace VideoCommon::Shader { |
| 19 | |||
| 19 | namespace { | 20 | namespace { |
| 21 | |||
| 20 | using Tegra::Shader::Instruction; | 22 | using Tegra::Shader::Instruction; |
| 21 | using Tegra::Shader::OpCode; | 23 | using Tegra::Shader::OpCode; |
| 22 | 24 | ||
| @@ -68,15 +70,15 @@ struct CFGRebuildState { | |||
| 68 | const ProgramCode& program_code; | 70 | const ProgramCode& program_code; |
| 69 | ConstBufferLocker& locker; | 71 | ConstBufferLocker& locker; |
| 70 | u32 start{}; | 72 | u32 start{}; |
| 71 | std::vector<BlockInfo> block_info{}; | 73 | std::vector<BlockInfo> block_info; |
| 72 | std::list<u32> inspect_queries{}; | 74 | std::list<u32> inspect_queries; |
| 73 | std::list<Query> queries{}; | 75 | std::list<Query> queries; |
| 74 | std::unordered_map<u32, u32> registered{}; | 76 | std::unordered_map<u32, u32> registered; |
| 75 | std::set<u32> labels{}; | 77 | std::set<u32> labels; |
| 76 | std::map<u32, u32> ssy_labels{}; | 78 | std::map<u32, u32> ssy_labels; |
| 77 | std::map<u32, u32> pbk_labels{}; | 79 | std::map<u32, u32> pbk_labels; |
| 78 | std::unordered_map<u32, BlockStack> stacks{}; | 80 | std::unordered_map<u32, BlockStack> stacks; |
| 79 | ASTManager* manager; | 81 | ASTManager* manager{}; |
| 80 | }; | 82 | }; |
| 81 | 83 | ||
| 82 | enum class BlockCollision : u32 { None, Found, Inside }; | 84 | enum class BlockCollision : u32 { None, Found, Inside }; |
| @@ -109,7 +111,7 @@ BlockInfo& CreateBlockInfo(CFGRebuildState& state, u32 start, u32 end) { | |||
| 109 | } | 111 | } |
| 110 | 112 | ||
| 111 | Pred GetPredicate(u32 index, bool negated) { | 113 | Pred GetPredicate(u32 index, bool negated) { |
| 112 | return static_cast<Pred>(index + (negated ? 8 : 0)); | 114 | return static_cast<Pred>(static_cast<u64>(index) + (negated ? 8ULL : 0ULL)); |
| 113 | } | 115 | } |
| 114 | 116 | ||
| 115 | /** | 117 | /** |
| @@ -136,15 +138,13 @@ struct BranchIndirectInfo { | |||
| 136 | s32 relative_position{}; | 138 | s32 relative_position{}; |
| 137 | }; | 139 | }; |
| 138 | 140 | ||
| 139 | std::optional<BranchIndirectInfo> TrackBranchIndirectInfo(const CFGRebuildState& state, | 141 | struct BufferInfo { |
| 140 | u32 start_address, u32 current_position) { | 142 | u32 index; |
| 141 | const u32 shader_start = state.start; | 143 | u32 offset; |
| 142 | u32 pos = current_position; | 144 | }; |
| 143 | BranchIndirectInfo result{}; | ||
| 144 | u64 track_register = 0; | ||
| 145 | 145 | ||
| 146 | // Step 0 Get BRX Info | 146 | std::optional<std::pair<s32, u64>> GetBRXInfo(const CFGRebuildState& state, u32& pos) { |
| 147 | const Instruction instr = {state.program_code[pos]}; | 147 | const Instruction instr = state.program_code[pos]; |
| 148 | const auto opcode = OpCode::Decode(instr); | 148 | const auto opcode = OpCode::Decode(instr); |
| 149 | if (opcode->get().GetId() != OpCode::Id::BRX) { | 149 | if (opcode->get().GetId() != OpCode::Id::BRX) { |
| 150 | return std::nullopt; | 150 | return std::nullopt; |
| @@ -152,86 +152,94 @@ std::optional<BranchIndirectInfo> TrackBranchIndirectInfo(const CFGRebuildState& | |||
| 152 | if (instr.brx.constant_buffer != 0) { | 152 | if (instr.brx.constant_buffer != 0) { |
| 153 | return std::nullopt; | 153 | return std::nullopt; |
| 154 | } | 154 | } |
| 155 | track_register = instr.gpr8.Value(); | 155 | --pos; |
| 156 | result.relative_position = instr.brx.GetBranchExtend(); | 156 | return std::make_pair(instr.brx.GetBranchExtend(), instr.gpr8.Value()); |
| 157 | pos--; | 157 | } |
| 158 | bool found_track = false; | ||
| 159 | 158 | ||
| 160 | // Step 1 Track LDC | 159 | template <typename Result, typename TestCallable, typename PackCallable> |
| 161 | while (pos >= shader_start) { | 160 | // requires std::predicate<TestCallable, Instruction, const OpCode::Matcher&> |
| 162 | if (IsSchedInstruction(pos, shader_start)) { | 161 | // requires std::invocable<PackCallable, Instruction, const OpCode::Matcher&> |
| 163 | pos--; | 162 | std::optional<Result> TrackInstruction(const CFGRebuildState& state, u32& pos, TestCallable test, |
| 163 | PackCallable pack) { | ||
| 164 | for (; pos >= state.start; --pos) { | ||
| 165 | if (IsSchedInstruction(pos, state.start)) { | ||
| 164 | continue; | 166 | continue; |
| 165 | } | 167 | } |
| 166 | const Instruction instr = {state.program_code[pos]}; | 168 | const Instruction instr = state.program_code[pos]; |
| 167 | const auto opcode = OpCode::Decode(instr); | 169 | const auto opcode = OpCode::Decode(instr); |
| 168 | if (opcode->get().GetId() == OpCode::Id::LD_C) { | 170 | if (!opcode) { |
| 169 | if (instr.gpr0.Value() == track_register && | 171 | continue; |
| 170 | instr.ld_c.type.Value() == Tegra::Shader::UniformType::Single) { | 172 | } |
| 171 | result.buffer = instr.cbuf36.index.Value(); | 173 | if (test(instr, opcode->get())) { |
| 172 | result.offset = static_cast<u32>(instr.cbuf36.GetOffset()); | 174 | --pos; |
| 173 | track_register = instr.gpr8.Value(); | 175 | return std::make_optional(pack(instr, opcode->get())); |
| 174 | pos--; | ||
| 175 | found_track = true; | ||
| 176 | break; | ||
| 177 | } | ||
| 178 | } | 176 | } |
| 179 | pos--; | ||
| 180 | } | 177 | } |
| 178 | return std::nullopt; | ||
| 179 | } | ||
| 181 | 180 | ||
| 182 | if (!found_track) { | 181 | std::optional<std::pair<BufferInfo, u64>> TrackLDC(const CFGRebuildState& state, u32& pos, |
| 183 | return std::nullopt; | 182 | u64 brx_tracked_register) { |
| 184 | } | 183 | return TrackInstruction<std::pair<BufferInfo, u64>>( |
| 185 | found_track = false; | 184 | state, pos, |
| 185 | [brx_tracked_register](auto instr, const auto& opcode) { | ||
| 186 | return opcode.GetId() == OpCode::Id::LD_C && | ||
| 187 | instr.gpr0.Value() == brx_tracked_register && | ||
| 188 | instr.ld_c.type.Value() == Tegra::Shader::UniformType::Single; | ||
| 189 | }, | ||
| 190 | [](auto instr, const auto& opcode) { | ||
| 191 | const BufferInfo info = {static_cast<u32>(instr.cbuf36.index.Value()), | ||
| 192 | static_cast<u32>(instr.cbuf36.GetOffset())}; | ||
| 193 | return std::make_pair(info, instr.gpr8.Value()); | ||
| 194 | }); | ||
| 195 | } | ||
| 186 | 196 | ||
| 187 | // Step 2 Track SHL | 197 | std::optional<u64> TrackSHLRegister(const CFGRebuildState& state, u32& pos, |
| 188 | while (pos >= shader_start) { | 198 | u64 ldc_tracked_register) { |
| 189 | if (IsSchedInstruction(pos, shader_start)) { | 199 | return TrackInstruction<u64>(state, pos, |
| 190 | pos--; | 200 | [ldc_tracked_register](auto instr, const auto& opcode) { |
| 191 | continue; | 201 | return opcode.GetId() == OpCode::Id::SHL_IMM && |
| 192 | } | 202 | instr.gpr0.Value() == ldc_tracked_register; |
| 193 | const Instruction instr = state.program_code[pos]; | 203 | }, |
| 194 | const auto opcode = OpCode::Decode(instr); | 204 | [](auto instr, const auto&) { return instr.gpr8.Value(); }); |
| 195 | if (opcode->get().GetId() == OpCode::Id::SHL_IMM) { | 205 | } |
| 196 | if (instr.gpr0.Value() == track_register) { | 206 | |
| 197 | track_register = instr.gpr8.Value(); | 207 | std::optional<u32> TrackIMNMXValue(const CFGRebuildState& state, u32& pos, |
| 198 | pos--; | 208 | u64 shl_tracked_register) { |
| 199 | found_track = true; | 209 | return TrackInstruction<u32>(state, pos, |
| 200 | break; | 210 | [shl_tracked_register](auto instr, const auto& opcode) { |
| 201 | } | 211 | return opcode.GetId() == OpCode::Id::IMNMX_IMM && |
| 202 | } | 212 | instr.gpr0.Value() == shl_tracked_register; |
| 203 | pos--; | 213 | }, |
| 214 | [](auto instr, const auto&) { | ||
| 215 | return static_cast<u32>(instr.alu.GetSignedImm20_20() + 1); | ||
| 216 | }); | ||
| 217 | } | ||
| 218 | |||
| 219 | std::optional<BranchIndirectInfo> TrackBranchIndirectInfo(const CFGRebuildState& state, u32 pos) { | ||
| 220 | const auto brx_info = GetBRXInfo(state, pos); | ||
| 221 | if (!brx_info) { | ||
| 222 | return std::nullopt; | ||
| 204 | } | 223 | } |
| 224 | const auto [relative_position, brx_tracked_register] = *brx_info; | ||
| 205 | 225 | ||
| 206 | if (!found_track) { | 226 | const auto ldc_info = TrackLDC(state, pos, brx_tracked_register); |
| 227 | if (!ldc_info) { | ||
| 207 | return std::nullopt; | 228 | return std::nullopt; |
| 208 | } | 229 | } |
| 209 | found_track = false; | 230 | const auto [buffer_info, ldc_tracked_register] = *ldc_info; |
| 210 | 231 | ||
| 211 | // Step 3 Track IMNMX | 232 | const auto shl_tracked_register = TrackSHLRegister(state, pos, ldc_tracked_register); |
| 212 | while (pos >= shader_start) { | 233 | if (!shl_tracked_register) { |
| 213 | if (IsSchedInstruction(pos, shader_start)) { | 234 | return std::nullopt; |
| 214 | pos--; | ||
| 215 | continue; | ||
| 216 | } | ||
| 217 | const Instruction instr = state.program_code[pos]; | ||
| 218 | const auto opcode = OpCode::Decode(instr); | ||
| 219 | if (opcode->get().GetId() == OpCode::Id::IMNMX_IMM) { | ||
| 220 | if (instr.gpr0.Value() == track_register) { | ||
| 221 | track_register = instr.gpr8.Value(); | ||
| 222 | result.entries = instr.alu.GetSignedImm20_20() + 1; | ||
| 223 | pos--; | ||
| 224 | found_track = true; | ||
| 225 | break; | ||
| 226 | } | ||
| 227 | } | ||
| 228 | pos--; | ||
| 229 | } | 235 | } |
| 230 | 236 | ||
| 231 | if (!found_track) { | 237 | const auto entries = TrackIMNMXValue(state, pos, *shl_tracked_register); |
| 238 | if (!entries) { | ||
| 232 | return std::nullopt; | 239 | return std::nullopt; |
| 233 | } | 240 | } |
| 234 | return result; | 241 | |
| 242 | return BranchIndirectInfo{buffer_info.index, buffer_info.offset, *entries, relative_position}; | ||
| 235 | } | 243 | } |
| 236 | 244 | ||
| 237 | std::pair<ParseResult, ParseInfo> ParseCode(CFGRebuildState& state, u32 address) { | 245 | std::pair<ParseResult, ParseInfo> ParseCode(CFGRebuildState& state, u32 address) { |
| @@ -420,30 +428,30 @@ std::pair<ParseResult, ParseInfo> ParseCode(CFGRebuildState& state, u32 address) | |||
| 420 | break; | 428 | break; |
| 421 | } | 429 | } |
| 422 | case OpCode::Id::BRX: { | 430 | case OpCode::Id::BRX: { |
| 423 | auto tmp = TrackBranchIndirectInfo(state, address, offset); | 431 | const auto tmp = TrackBranchIndirectInfo(state, offset); |
| 424 | if (tmp) { | 432 | if (!tmp) { |
| 425 | auto result = *tmp; | ||
| 426 | std::vector<CaseBranch> branches{}; | ||
| 427 | s32 pc_target = offset + result.relative_position; | ||
| 428 | for (u32 i = 0; i < result.entries; i++) { | ||
| 429 | auto k = state.locker.ObtainKey(result.buffer, result.offset + i * 4); | ||
| 430 | if (!k) { | ||
| 431 | return {ParseResult::AbnormalFlow, parse_info}; | ||
| 432 | } | ||
| 433 | u32 value = *k; | ||
| 434 | u32 target = static_cast<u32>((value >> 3) + pc_target); | ||
| 435 | insert_label(state, target); | ||
| 436 | branches.emplace_back(value, target); | ||
| 437 | } | ||
| 438 | parse_info.end_address = offset; | ||
| 439 | parse_info.branch_info = MakeBranchInfo<MultiBranch>( | ||
| 440 | static_cast<u32>(instr.gpr8.Value()), std::move(branches)); | ||
| 441 | |||
| 442 | return {ParseResult::ControlCaught, parse_info}; | ||
| 443 | } else { | ||
| 444 | LOG_WARNING(HW_GPU, "BRX Track Unsuccesful"); | 433 | LOG_WARNING(HW_GPU, "BRX Track Unsuccesful"); |
| 434 | return {ParseResult::AbnormalFlow, parse_info}; | ||
| 445 | } | 435 | } |
| 446 | return {ParseResult::AbnormalFlow, parse_info}; | 436 | |
| 437 | const auto result = *tmp; | ||
| 438 | const s32 pc_target = offset + result.relative_position; | ||
| 439 | std::vector<CaseBranch> branches; | ||
| 440 | for (u32 i = 0; i < result.entries; i++) { | ||
| 441 | auto key = state.locker.ObtainKey(result.buffer, result.offset + i * 4); | ||
| 442 | if (!key) { | ||
| 443 | return {ParseResult::AbnormalFlow, parse_info}; | ||
| 444 | } | ||
| 445 | u32 value = *key; | ||
| 446 | u32 target = static_cast<u32>((value >> 3) + pc_target); | ||
| 447 | insert_label(state, target); | ||
| 448 | branches.emplace_back(value, target); | ||
| 449 | } | ||
| 450 | parse_info.end_address = offset; | ||
| 451 | parse_info.branch_info = MakeBranchInfo<MultiBranch>( | ||
| 452 | static_cast<u32>(instr.gpr8.Value()), std::move(branches)); | ||
| 453 | |||
| 454 | return {ParseResult::ControlCaught, parse_info}; | ||
| 447 | } | 455 | } |
| 448 | default: | 456 | default: |
| 449 | break; | 457 | break; |
diff --git a/src/video_core/shader/decode/arithmetic.cpp b/src/video_core/shader/decode/arithmetic.cpp index 1473c282a..fcedd2af6 100644 --- a/src/video_core/shader/decode/arithmetic.cpp +++ b/src/video_core/shader/decode/arithmetic.cpp | |||
| @@ -43,12 +43,12 @@ u32 ShaderIR::DecodeArithmetic(NodeBlock& bb, u32 pc) { | |||
| 43 | case OpCode::Id::FMUL_IMM: { | 43 | case OpCode::Id::FMUL_IMM: { |
| 44 | // FMUL does not have 'abs' bits and only the second operand has a 'neg' bit. | 44 | // FMUL does not have 'abs' bits and only the second operand has a 'neg' bit. |
| 45 | if (instr.fmul.tab5cb8_2 != 0) { | 45 | if (instr.fmul.tab5cb8_2 != 0) { |
| 46 | LOG_WARNING(HW_GPU, "FMUL tab5cb8_2({}) is not implemented", | 46 | LOG_DEBUG(HW_GPU, "FMUL tab5cb8_2({}) is not implemented", |
| 47 | instr.fmul.tab5cb8_2.Value()); | 47 | instr.fmul.tab5cb8_2.Value()); |
| 48 | } | 48 | } |
| 49 | if (instr.fmul.tab5c68_0 != 1) { | 49 | if (instr.fmul.tab5c68_0 != 1) { |
| 50 | LOG_WARNING(HW_GPU, "FMUL tab5cb8_0({}) is not implemented", | 50 | LOG_DEBUG(HW_GPU, "FMUL tab5cb8_0({}) is not implemented", |
| 51 | instr.fmul.tab5c68_0.Value()); | 51 | instr.fmul.tab5c68_0.Value()); |
| 52 | } | 52 | } |
| 53 | 53 | ||
| 54 | op_b = GetOperandAbsNegFloat(op_b, false, instr.fmul.negate_b); | 54 | op_b = GetOperandAbsNegFloat(op_b, false, instr.fmul.negate_b); |
| @@ -144,10 +144,11 @@ u32 ShaderIR::DecodeArithmetic(NodeBlock& bb, u32 pc) { | |||
| 144 | case OpCode::Id::RRO_C: | 144 | case OpCode::Id::RRO_C: |
| 145 | case OpCode::Id::RRO_R: | 145 | case OpCode::Id::RRO_R: |
| 146 | case OpCode::Id::RRO_IMM: { | 146 | case OpCode::Id::RRO_IMM: { |
| 147 | LOG_DEBUG(HW_GPU, "(STUBBED) RRO used"); | ||
| 148 | |||
| 147 | // Currently RRO is only implemented as a register move. | 149 | // Currently RRO is only implemented as a register move. |
| 148 | op_b = GetOperandAbsNegFloat(op_b, instr.alu.abs_b, instr.alu.negate_b); | 150 | op_b = GetOperandAbsNegFloat(op_b, instr.alu.abs_b, instr.alu.negate_b); |
| 149 | SetRegister(bb, instr.gpr0, op_b); | 151 | SetRegister(bb, instr.gpr0, op_b); |
| 150 | LOG_WARNING(HW_GPU, "RRO instruction is incomplete"); | ||
| 151 | break; | 152 | break; |
| 152 | } | 153 | } |
| 153 | default: | 154 | default: |
diff --git a/src/video_core/shader/decode/arithmetic_half.cpp b/src/video_core/shader/decode/arithmetic_half.cpp index b06cbe441..ee7d9a29d 100644 --- a/src/video_core/shader/decode/arithmetic_half.cpp +++ b/src/video_core/shader/decode/arithmetic_half.cpp | |||
| @@ -21,8 +21,8 @@ u32 ShaderIR::DecodeArithmeticHalf(NodeBlock& bb, u32 pc) { | |||
| 21 | 21 | ||
| 22 | if (opcode->get().GetId() == OpCode::Id::HADD2_C || | 22 | if (opcode->get().GetId() == OpCode::Id::HADD2_C || |
| 23 | opcode->get().GetId() == OpCode::Id::HADD2_R) { | 23 | opcode->get().GetId() == OpCode::Id::HADD2_R) { |
| 24 | if (instr.alu_half.ftz != 0) { | 24 | if (instr.alu_half.ftz == 0) { |
| 25 | LOG_WARNING(HW_GPU, "{} FTZ not implemented", opcode->get().GetName()); | 25 | LOG_DEBUG(HW_GPU, "{} without FTZ is not implemented", opcode->get().GetName()); |
| 26 | } | 26 | } |
| 27 | } | 27 | } |
| 28 | 28 | ||
diff --git a/src/video_core/shader/decode/arithmetic_half_immediate.cpp b/src/video_core/shader/decode/arithmetic_half_immediate.cpp index 6466fc011..d179b9873 100644 --- a/src/video_core/shader/decode/arithmetic_half_immediate.cpp +++ b/src/video_core/shader/decode/arithmetic_half_immediate.cpp | |||
| @@ -19,12 +19,12 @@ u32 ShaderIR::DecodeArithmeticHalfImmediate(NodeBlock& bb, u32 pc) { | |||
| 19 | const auto opcode = OpCode::Decode(instr); | 19 | const auto opcode = OpCode::Decode(instr); |
| 20 | 20 | ||
| 21 | if (opcode->get().GetId() == OpCode::Id::HADD2_IMM) { | 21 | if (opcode->get().GetId() == OpCode::Id::HADD2_IMM) { |
| 22 | if (instr.alu_half_imm.ftz != 0) { | 22 | if (instr.alu_half_imm.ftz == 0) { |
| 23 | LOG_WARNING(HW_GPU, "{} FTZ not implemented", opcode->get().GetName()); | 23 | LOG_DEBUG(HW_GPU, "{} without FTZ is not implemented", opcode->get().GetName()); |
| 24 | } | 24 | } |
| 25 | } else { | 25 | } else { |
| 26 | if (instr.alu_half_imm.precision != Tegra::Shader::HalfPrecision::None) { | 26 | if (instr.alu_half_imm.precision != Tegra::Shader::HalfPrecision::FTZ) { |
| 27 | LOG_WARNING(HW_GPU, "{} FTZ not implemented", opcode->get().GetName()); | 27 | LOG_DEBUG(HW_GPU, "{} without FTZ is not implemented", opcode->get().GetName()); |
| 28 | } | 28 | } |
| 29 | } | 29 | } |
| 30 | 30 | ||
diff --git a/src/video_core/shader/decode/ffma.cpp b/src/video_core/shader/decode/ffma.cpp index ca2f39e8d..5973588d6 100644 --- a/src/video_core/shader/decode/ffma.cpp +++ b/src/video_core/shader/decode/ffma.cpp | |||
| @@ -19,10 +19,10 @@ u32 ShaderIR::DecodeFfma(NodeBlock& bb, u32 pc) { | |||
| 19 | 19 | ||
| 20 | UNIMPLEMENTED_IF_MSG(instr.ffma.cc != 0, "FFMA cc not implemented"); | 20 | UNIMPLEMENTED_IF_MSG(instr.ffma.cc != 0, "FFMA cc not implemented"); |
| 21 | if (instr.ffma.tab5980_0 != 1) { | 21 | if (instr.ffma.tab5980_0 != 1) { |
| 22 | LOG_WARNING(HW_GPU, "FFMA tab5980_0({}) not implemented", instr.ffma.tab5980_0.Value()); | 22 | LOG_DEBUG(HW_GPU, "FFMA tab5980_0({}) not implemented", instr.ffma.tab5980_0.Value()); |
| 23 | } | 23 | } |
| 24 | if (instr.ffma.tab5980_1 != 0) { | 24 | if (instr.ffma.tab5980_1 != 0) { |
| 25 | LOG_WARNING(HW_GPU, "FFMA tab5980_1({}) not implemented", instr.ffma.tab5980_1.Value()); | 25 | LOG_DEBUG(HW_GPU, "FFMA tab5980_1({}) not implemented", instr.ffma.tab5980_1.Value()); |
| 26 | } | 26 | } |
| 27 | 27 | ||
| 28 | const Node op_a = GetRegister(instr.gpr8); | 28 | const Node op_a = GetRegister(instr.gpr8); |
diff --git a/src/video_core/shader/decode/half_set.cpp b/src/video_core/shader/decode/half_set.cpp index 48ca7a4af..848e46874 100644 --- a/src/video_core/shader/decode/half_set.cpp +++ b/src/video_core/shader/decode/half_set.cpp | |||
| @@ -20,8 +20,8 @@ u32 ShaderIR::DecodeHalfSet(NodeBlock& bb, u32 pc) { | |||
| 20 | const Instruction instr = {program_code[pc]}; | 20 | const Instruction instr = {program_code[pc]}; |
| 21 | const auto opcode = OpCode::Decode(instr); | 21 | const auto opcode = OpCode::Decode(instr); |
| 22 | 22 | ||
| 23 | if (instr.hset2.ftz != 0) { | 23 | if (instr.hset2.ftz == 0) { |
| 24 | LOG_WARNING(HW_GPU, "{} FTZ not implemented", opcode->get().GetName()); | 24 | LOG_DEBUG(HW_GPU, "{} without FTZ is not implemented", opcode->get().GetName()); |
| 25 | } | 25 | } |
| 26 | 26 | ||
| 27 | Node op_a = UnpackHalfFloat(GetRegister(instr.gpr8), instr.hset2.type_a); | 27 | Node op_a = UnpackHalfFloat(GetRegister(instr.gpr8), instr.hset2.type_a); |
diff --git a/src/video_core/shader/decode/half_set_predicate.cpp b/src/video_core/shader/decode/half_set_predicate.cpp index fec8f2dbe..310655619 100644 --- a/src/video_core/shader/decode/half_set_predicate.cpp +++ b/src/video_core/shader/decode/half_set_predicate.cpp | |||
| @@ -19,7 +19,9 @@ u32 ShaderIR::DecodeHalfSetPredicate(NodeBlock& bb, u32 pc) { | |||
| 19 | const Instruction instr = {program_code[pc]}; | 19 | const Instruction instr = {program_code[pc]}; |
| 20 | const auto opcode = OpCode::Decode(instr); | 20 | const auto opcode = OpCode::Decode(instr); |
| 21 | 21 | ||
| 22 | LOG_DEBUG(HW_GPU, "ftz={}", static_cast<u32>(instr.hsetp2.ftz)); | 22 | if (instr.hsetp2.ftz != 0) { |
| 23 | LOG_DEBUG(HW_GPU, "{} without FTZ is not implemented", opcode->get().GetName()); | ||
| 24 | } | ||
| 23 | 25 | ||
| 24 | Node op_a = UnpackHalfFloat(GetRegister(instr.gpr8), instr.hsetp2.type_a); | 26 | Node op_a = UnpackHalfFloat(GetRegister(instr.gpr8), instr.hsetp2.type_a); |
| 25 | op_a = GetOperandAbsNegHalf(op_a, instr.hsetp2.abs_a, instr.hsetp2.negate_a); | 27 | op_a = GetOperandAbsNegHalf(op_a, instr.hsetp2.abs_a, instr.hsetp2.negate_a); |
diff --git a/src/video_core/shader/decode/image.cpp b/src/video_core/shader/decode/image.cpp index b02d2cb95..d2fe4ec5d 100644 --- a/src/video_core/shader/decode/image.cpp +++ b/src/video_core/shader/decode/image.cpp | |||
| @@ -143,39 +143,37 @@ u32 ShaderIR::DecodeImage(NodeBlock& bb, u32 pc) { | |||
| 143 | } | 143 | } |
| 144 | 144 | ||
| 145 | Image& ShaderIR::GetImage(Tegra::Shader::Image image, Tegra::Shader::ImageType type) { | 145 | Image& ShaderIR::GetImage(Tegra::Shader::Image image, Tegra::Shader::ImageType type) { |
| 146 | const auto offset{static_cast<std::size_t>(image.index.Value())}; | 146 | const auto offset = static_cast<u32>(image.index.Value()); |
| 147 | if (const auto existing_image = TryUseExistingImage(offset, type)) { | 147 | |
| 148 | return *existing_image; | 148 | const auto it = |
| 149 | std::find_if(std::begin(used_images), std::end(used_images), | ||
| 150 | [offset](const Image& entry) { return entry.GetOffset() == offset; }); | ||
| 151 | if (it != std::end(used_images)) { | ||
| 152 | ASSERT(!it->IsBindless() && it->GetType() == it->GetType()); | ||
| 153 | return *it; | ||
| 149 | } | 154 | } |
| 150 | 155 | ||
| 151 | const std::size_t next_index{used_images.size()}; | 156 | const auto next_index = static_cast<u32>(used_images.size()); |
| 152 | return used_images.emplace(offset, Image{offset, next_index, type}).first->second; | 157 | return used_images.emplace_back(next_index, offset, type); |
| 153 | } | 158 | } |
| 154 | 159 | ||
| 155 | Image& ShaderIR::GetBindlessImage(Tegra::Shader::Register reg, Tegra::Shader::ImageType type) { | 160 | Image& ShaderIR::GetBindlessImage(Tegra::Shader::Register reg, Tegra::Shader::ImageType type) { |
| 156 | const Node image_register{GetRegister(reg)}; | 161 | const Node image_register = GetRegister(reg); |
| 157 | const auto [base_image, cbuf_index, cbuf_offset]{ | 162 | const auto [base_image, buffer, offset] = |
| 158 | TrackCbuf(image_register, global_code, static_cast<s64>(global_code.size()))}; | 163 | TrackCbuf(image_register, global_code, static_cast<s64>(global_code.size())); |
| 159 | const auto cbuf_key{(static_cast<u64>(cbuf_index) << 32) | static_cast<u64>(cbuf_offset)}; | 164 | |
| 160 | 165 | const auto it = | |
| 161 | if (const auto image = TryUseExistingImage(cbuf_key, type)) { | 166 | std::find_if(std::begin(used_images), std::end(used_images), |
| 162 | return *image; | 167 | [buffer = buffer, offset = offset](const Image& entry) { |
| 163 | } | 168 | return entry.GetBuffer() == buffer && entry.GetOffset() == offset; |
| 164 | 169 | }); | |
| 165 | const std::size_t next_index{used_images.size()}; | 170 | if (it != std::end(used_images)) { |
| 166 | return used_images.emplace(cbuf_key, Image{cbuf_index, cbuf_offset, next_index, type}) | 171 | ASSERT(it->IsBindless() && it->GetType() == it->GetType()); |
| 167 | .first->second; | 172 | return *it; |
| 168 | } | ||
| 169 | |||
| 170 | Image* ShaderIR::TryUseExistingImage(u64 offset, Tegra::Shader::ImageType type) { | ||
| 171 | auto it = used_images.find(offset); | ||
| 172 | if (it == used_images.end()) { | ||
| 173 | return nullptr; | ||
| 174 | } | 173 | } |
| 175 | auto& image = it->second; | ||
| 176 | ASSERT(image.GetType() == type); | ||
| 177 | 174 | ||
| 178 | return ℑ | 175 | const auto next_index = static_cast<u32>(used_images.size()); |
| 176 | return used_images.emplace_back(next_index, offset, buffer, type); | ||
| 179 | } | 177 | } |
| 180 | 178 | ||
| 181 | } // namespace VideoCommon::Shader | 179 | } // namespace VideoCommon::Shader |
diff --git a/src/video_core/shader/decode/texture.cpp b/src/video_core/shader/decode/texture.cpp index 0599ef34f..bb926a132 100644 --- a/src/video_core/shader/decode/texture.cpp +++ b/src/video_core/shader/decode/texture.cpp | |||
| @@ -44,10 +44,6 @@ u32 ShaderIR::DecodeTexture(NodeBlock& bb, u32 pc) { | |||
| 44 | bool is_bindless = false; | 44 | bool is_bindless = false; |
| 45 | switch (opcode->get().GetId()) { | 45 | switch (opcode->get().GetId()) { |
| 46 | case OpCode::Id::TEX: { | 46 | case OpCode::Id::TEX: { |
| 47 | if (instr.tex.UsesMiscMode(TextureMiscMode::NODEP)) { | ||
| 48 | LOG_WARNING(HW_GPU, "TEX.NODEP implementation is incomplete"); | ||
| 49 | } | ||
| 50 | |||
| 51 | const TextureType texture_type{instr.tex.texture_type}; | 47 | const TextureType texture_type{instr.tex.texture_type}; |
| 52 | const bool is_array = instr.tex.array != 0; | 48 | const bool is_array = instr.tex.array != 0; |
| 53 | const bool is_aoffi = instr.tex.UsesMiscMode(TextureMiscMode::AOFFI); | 49 | const bool is_aoffi = instr.tex.UsesMiscMode(TextureMiscMode::AOFFI); |
| @@ -62,10 +58,6 @@ u32 ShaderIR::DecodeTexture(NodeBlock& bb, u32 pc) { | |||
| 62 | UNIMPLEMENTED_IF_MSG(instr.tex.UsesMiscMode(TextureMiscMode::AOFFI), | 58 | UNIMPLEMENTED_IF_MSG(instr.tex.UsesMiscMode(TextureMiscMode::AOFFI), |
| 63 | "AOFFI is not implemented"); | 59 | "AOFFI is not implemented"); |
| 64 | 60 | ||
| 65 | if (instr.tex.UsesMiscMode(TextureMiscMode::NODEP)) { | ||
| 66 | LOG_WARNING(HW_GPU, "TEX.NODEP implementation is incomplete"); | ||
| 67 | } | ||
| 68 | |||
| 69 | const TextureType texture_type{instr.tex_b.texture_type}; | 61 | const TextureType texture_type{instr.tex_b.texture_type}; |
| 70 | const bool is_array = instr.tex_b.array != 0; | 62 | const bool is_array = instr.tex_b.array != 0; |
| 71 | const bool is_aoffi = instr.tex.UsesMiscMode(TextureMiscMode::AOFFI); | 63 | const bool is_aoffi = instr.tex.UsesMiscMode(TextureMiscMode::AOFFI); |
| @@ -82,10 +74,6 @@ u32 ShaderIR::DecodeTexture(NodeBlock& bb, u32 pc) { | |||
| 82 | const bool depth_compare = instr.texs.UsesMiscMode(TextureMiscMode::DC); | 74 | const bool depth_compare = instr.texs.UsesMiscMode(TextureMiscMode::DC); |
| 83 | const auto process_mode = instr.texs.GetTextureProcessMode(); | 75 | const auto process_mode = instr.texs.GetTextureProcessMode(); |
| 84 | 76 | ||
| 85 | if (instr.texs.UsesMiscMode(TextureMiscMode::NODEP)) { | ||
| 86 | LOG_WARNING(HW_GPU, "TEXS.NODEP implementation is incomplete"); | ||
| 87 | } | ||
| 88 | |||
| 89 | const Node4 components = | 77 | const Node4 components = |
| 90 | GetTexsCode(instr, texture_type, process_mode, depth_compare, is_array); | 78 | GetTexsCode(instr, texture_type, process_mode, depth_compare, is_array); |
| 91 | 79 | ||
| @@ -107,10 +95,6 @@ u32 ShaderIR::DecodeTexture(NodeBlock& bb, u32 pc) { | |||
| 107 | UNIMPLEMENTED_IF_MSG(instr.tld4.UsesMiscMode(TextureMiscMode::PTP), | 95 | UNIMPLEMENTED_IF_MSG(instr.tld4.UsesMiscMode(TextureMiscMode::PTP), |
| 108 | "PTP is not implemented"); | 96 | "PTP is not implemented"); |
| 109 | 97 | ||
| 110 | if (instr.tld4.UsesMiscMode(TextureMiscMode::NODEP)) { | ||
| 111 | LOG_WARNING(HW_GPU, "TLD4.NODEP implementation is incomplete"); | ||
| 112 | } | ||
| 113 | |||
| 114 | const auto texture_type = instr.tld4.texture_type.Value(); | 98 | const auto texture_type = instr.tld4.texture_type.Value(); |
| 115 | const bool depth_compare = is_bindless ? instr.tld4_b.UsesMiscMode(TextureMiscMode::DC) | 99 | const bool depth_compare = is_bindless ? instr.tld4_b.UsesMiscMode(TextureMiscMode::DC) |
| 116 | : instr.tld4.UsesMiscMode(TextureMiscMode::DC); | 100 | : instr.tld4.UsesMiscMode(TextureMiscMode::DC); |
| @@ -119,15 +103,12 @@ u32 ShaderIR::DecodeTexture(NodeBlock& bb, u32 pc) { | |||
| 119 | : instr.tld4.UsesMiscMode(TextureMiscMode::AOFFI); | 103 | : instr.tld4.UsesMiscMode(TextureMiscMode::AOFFI); |
| 120 | WriteTexInstructionFloat( | 104 | WriteTexInstructionFloat( |
| 121 | bb, instr, | 105 | bb, instr, |
| 122 | GetTld4Code(instr, texture_type, depth_compare, is_array, is_aoffi, is_bindless), true); | 106 | GetTld4Code(instr, texture_type, depth_compare, is_array, is_aoffi, is_bindless)); |
| 123 | break; | 107 | break; |
| 124 | } | 108 | } |
| 125 | case OpCode::Id::TLD4S: { | 109 | case OpCode::Id::TLD4S: { |
| 126 | UNIMPLEMENTED_IF_MSG(instr.tld4s.UsesMiscMode(TextureMiscMode::AOFFI), | 110 | UNIMPLEMENTED_IF_MSG(instr.tld4s.UsesMiscMode(TextureMiscMode::AOFFI), |
| 127 | "AOFFI is not implemented"); | 111 | "AOFFI is not implemented"); |
| 128 | if (instr.tld4s.UsesMiscMode(TextureMiscMode::NODEP)) { | ||
| 129 | LOG_WARNING(HW_GPU, "TLD4S.NODEP implementation is incomplete"); | ||
| 130 | } | ||
| 131 | 112 | ||
| 132 | const bool depth_compare = instr.tld4s.UsesMiscMode(TextureMiscMode::DC); | 113 | const bool depth_compare = instr.tld4s.UsesMiscMode(TextureMiscMode::DC); |
| 133 | const Node op_a = GetRegister(instr.gpr8); | 114 | const Node op_a = GetRegister(instr.gpr8); |
| @@ -164,10 +145,6 @@ u32 ShaderIR::DecodeTexture(NodeBlock& bb, u32 pc) { | |||
| 164 | is_bindless = true; | 145 | is_bindless = true; |
| 165 | [[fallthrough]]; | 146 | [[fallthrough]]; |
| 166 | case OpCode::Id::TXQ: { | 147 | case OpCode::Id::TXQ: { |
| 167 | if (instr.txq.UsesMiscMode(TextureMiscMode::NODEP)) { | ||
| 168 | LOG_WARNING(HW_GPU, "TXQ.NODEP implementation is incomplete"); | ||
| 169 | } | ||
| 170 | |||
| 171 | // TODO: The new commits on the texture refactor, change the way samplers work. | 148 | // TODO: The new commits on the texture refactor, change the way samplers work. |
| 172 | // Sadly, not all texture instructions specify the type of texture their sampler | 149 | // Sadly, not all texture instructions specify the type of texture their sampler |
| 173 | // uses. This must be fixed at a later instance. | 150 | // uses. This must be fixed at a later instance. |
| @@ -205,10 +182,6 @@ u32 ShaderIR::DecodeTexture(NodeBlock& bb, u32 pc) { | |||
| 205 | UNIMPLEMENTED_IF_MSG(instr.tmml.UsesMiscMode(Tegra::Shader::TextureMiscMode::NDV), | 182 | UNIMPLEMENTED_IF_MSG(instr.tmml.UsesMiscMode(Tegra::Shader::TextureMiscMode::NDV), |
| 206 | "NDV is not implemented"); | 183 | "NDV is not implemented"); |
| 207 | 184 | ||
| 208 | if (instr.tmml.UsesMiscMode(TextureMiscMode::NODEP)) { | ||
| 209 | LOG_WARNING(HW_GPU, "TMML.NODEP implementation is incomplete"); | ||
| 210 | } | ||
| 211 | |||
| 212 | auto texture_type = instr.tmml.texture_type.Value(); | 185 | auto texture_type = instr.tmml.texture_type.Value(); |
| 213 | const bool is_array = instr.tmml.array != 0; | 186 | const bool is_array = instr.tmml.array != 0; |
| 214 | const auto& sampler = | 187 | const auto& sampler = |
| @@ -254,25 +227,17 @@ u32 ShaderIR::DecodeTexture(NodeBlock& bb, u32 pc) { | |||
| 254 | UNIMPLEMENTED_IF_MSG(instr.tld.ms, "MS is not implemented"); | 227 | UNIMPLEMENTED_IF_MSG(instr.tld.ms, "MS is not implemented"); |
| 255 | UNIMPLEMENTED_IF_MSG(instr.tld.cl, "CL is not implemented"); | 228 | UNIMPLEMENTED_IF_MSG(instr.tld.cl, "CL is not implemented"); |
| 256 | 229 | ||
| 257 | if (instr.tld.nodep_flag) { | ||
| 258 | LOG_WARNING(HW_GPU, "TLD.NODEP implementation is incomplete"); | ||
| 259 | } | ||
| 260 | |||
| 261 | WriteTexInstructionFloat(bb, instr, GetTldCode(instr)); | 230 | WriteTexInstructionFloat(bb, instr, GetTldCode(instr)); |
| 262 | break; | 231 | break; |
| 263 | } | 232 | } |
| 264 | case OpCode::Id::TLDS: { | 233 | case OpCode::Id::TLDS: { |
| 265 | const Tegra::Shader::TextureType texture_type{instr.tlds.GetTextureType()}; | 234 | const TextureType texture_type{instr.tlds.GetTextureType()}; |
| 266 | const bool is_array{instr.tlds.IsArrayTexture()}; | 235 | const bool is_array{instr.tlds.IsArrayTexture()}; |
| 267 | 236 | ||
| 268 | UNIMPLEMENTED_IF_MSG(instr.tlds.UsesMiscMode(TextureMiscMode::AOFFI), | 237 | UNIMPLEMENTED_IF_MSG(instr.tlds.UsesMiscMode(TextureMiscMode::AOFFI), |
| 269 | "AOFFI is not implemented"); | 238 | "AOFFI is not implemented"); |
| 270 | UNIMPLEMENTED_IF_MSG(instr.tlds.UsesMiscMode(TextureMiscMode::MZ), "MZ is not implemented"); | 239 | UNIMPLEMENTED_IF_MSG(instr.tlds.UsesMiscMode(TextureMiscMode::MZ), "MZ is not implemented"); |
| 271 | 240 | ||
| 272 | if (instr.tlds.UsesMiscMode(TextureMiscMode::NODEP)) { | ||
| 273 | LOG_WARNING(HW_GPU, "TLDS.NODEP implementation is incomplete"); | ||
| 274 | } | ||
| 275 | |||
| 276 | const Node4 components = GetTldsCode(instr, texture_type, is_array); | 241 | const Node4 components = GetTldsCode(instr, texture_type, is_array); |
| 277 | 242 | ||
| 278 | if (instr.tlds.fp32_flag) { | 243 | if (instr.tlds.fp32_flag) { |
| @@ -293,84 +258,86 @@ const Sampler& ShaderIR::GetSampler(const Tegra::Shader::Sampler& sampler, | |||
| 293 | std::optional<SamplerInfo> sampler_info) { | 258 | std::optional<SamplerInfo> sampler_info) { |
| 294 | const auto offset = static_cast<u32>(sampler.index.Value()); | 259 | const auto offset = static_cast<u32>(sampler.index.Value()); |
| 295 | 260 | ||
| 296 | Tegra::Shader::TextureType type; | 261 | TextureType type; |
| 297 | bool is_array; | 262 | bool is_array; |
| 298 | bool is_shadow; | 263 | bool is_shadow; |
| 299 | if (sampler_info) { | 264 | if (sampler_info) { |
| 300 | type = sampler_info->type; | 265 | type = sampler_info->type; |
| 301 | is_array = sampler_info->is_array; | 266 | is_array = sampler_info->is_array; |
| 302 | is_shadow = sampler_info->is_shadow; | 267 | is_shadow = sampler_info->is_shadow; |
| 303 | } else if (auto sampler = locker.ObtainBoundSampler(offset); sampler) { | 268 | } else if (const auto sampler = locker.ObtainBoundSampler(offset)) { |
| 304 | type = sampler->texture_type.Value(); | 269 | type = sampler->texture_type.Value(); |
| 305 | is_array = sampler->is_array.Value() != 0; | 270 | is_array = sampler->is_array.Value() != 0; |
| 306 | is_shadow = sampler->is_shadow.Value() != 0; | 271 | is_shadow = sampler->is_shadow.Value() != 0; |
| 307 | } else { | 272 | } else { |
| 308 | type = Tegra::Shader::TextureType::Texture2D; | 273 | LOG_WARNING(HW_GPU, "Unknown sampler info"); |
| 274 | type = TextureType::Texture2D; | ||
| 309 | is_array = false; | 275 | is_array = false; |
| 310 | is_shadow = false; | 276 | is_shadow = false; |
| 311 | } | 277 | } |
| 312 | 278 | ||
| 313 | // If this sampler has already been used, return the existing mapping. | 279 | // If this sampler has already been used, return the existing mapping. |
| 314 | const auto itr = | 280 | const auto it = |
| 315 | std::find_if(used_samplers.begin(), used_samplers.end(), | 281 | std::find_if(used_samplers.begin(), used_samplers.end(), |
| 316 | [&](const Sampler& entry) { return entry.GetOffset() == offset; }); | 282 | [offset](const Sampler& entry) { return entry.GetOffset() == offset; }); |
| 317 | if (itr != used_samplers.end()) { | 283 | if (it != used_samplers.end()) { |
| 318 | ASSERT(itr->GetType() == type && itr->IsArray() == is_array && | 284 | ASSERT(!it->IsBindless() && it->GetType() == type && it->IsArray() == is_array && |
| 319 | itr->IsShadow() == is_shadow); | 285 | it->IsShadow() == is_shadow); |
| 320 | return *itr; | 286 | return *it; |
| 321 | } | 287 | } |
| 322 | 288 | ||
| 323 | // Otherwise create a new mapping for this sampler | 289 | // Otherwise create a new mapping for this sampler |
| 324 | const std::size_t next_index = used_samplers.size(); | 290 | const auto next_index = static_cast<u32>(used_samplers.size()); |
| 325 | const Sampler entry{offset, next_index, type, is_array, is_shadow}; | 291 | return used_samplers.emplace_back(Sampler(next_index, offset, type, is_array, is_shadow)); |
| 326 | return *used_samplers.emplace(entry).first; | 292 | } |
| 327 | } // namespace VideoCommon::Shader | ||
| 328 | 293 | ||
| 329 | const Sampler& ShaderIR::GetBindlessSampler(const Tegra::Shader::Register& reg, | 294 | const Sampler& ShaderIR::GetBindlessSampler(const Tegra::Shader::Register& reg, |
| 330 | std::optional<SamplerInfo> sampler_info) { | 295 | std::optional<SamplerInfo> sampler_info) { |
| 331 | const Node sampler_register = GetRegister(reg); | 296 | const Node sampler_register = GetRegister(reg); |
| 332 | const auto [base_sampler, cbuf_index, cbuf_offset] = | 297 | const auto [base_sampler, buffer, offset] = |
| 333 | TrackCbuf(sampler_register, global_code, static_cast<s64>(global_code.size())); | 298 | TrackCbuf(sampler_register, global_code, static_cast<s64>(global_code.size())); |
| 334 | ASSERT(base_sampler != nullptr); | 299 | ASSERT(base_sampler != nullptr); |
| 335 | const auto cbuf_key = (static_cast<u64>(cbuf_index) << 32) | static_cast<u64>(cbuf_offset); | 300 | |
| 336 | Tegra::Shader::TextureType type; | 301 | TextureType type; |
| 337 | bool is_array; | 302 | bool is_array; |
| 338 | bool is_shadow; | 303 | bool is_shadow; |
| 339 | if (sampler_info) { | 304 | if (sampler_info) { |
| 340 | type = sampler_info->type; | 305 | type = sampler_info->type; |
| 341 | is_array = sampler_info->is_array; | 306 | is_array = sampler_info->is_array; |
| 342 | is_shadow = sampler_info->is_shadow; | 307 | is_shadow = sampler_info->is_shadow; |
| 343 | } else if (auto sampler = locker.ObtainBindlessSampler(cbuf_index, cbuf_offset); sampler) { | 308 | } else if (const auto sampler = locker.ObtainBindlessSampler(buffer, offset)) { |
| 344 | type = sampler->texture_type.Value(); | 309 | type = sampler->texture_type.Value(); |
| 345 | is_array = sampler->is_array.Value() != 0; | 310 | is_array = sampler->is_array.Value() != 0; |
| 346 | is_shadow = sampler->is_shadow.Value() != 0; | 311 | is_shadow = sampler->is_shadow.Value() != 0; |
| 347 | } else { | 312 | } else { |
| 348 | type = Tegra::Shader::TextureType::Texture2D; | 313 | LOG_WARNING(HW_GPU, "Unknown sampler info"); |
| 314 | type = TextureType::Texture2D; | ||
| 349 | is_array = false; | 315 | is_array = false; |
| 350 | is_shadow = false; | 316 | is_shadow = false; |
| 351 | } | 317 | } |
| 352 | 318 | ||
| 353 | // If this sampler has already been used, return the existing mapping. | 319 | // If this sampler has already been used, return the existing mapping. |
| 354 | const auto itr = | 320 | const auto it = |
| 355 | std::find_if(used_samplers.begin(), used_samplers.end(), | 321 | std::find_if(used_samplers.begin(), used_samplers.end(), |
| 356 | [&](const Sampler& entry) { return entry.GetOffset() == cbuf_key; }); | 322 | [buffer = buffer, offset = offset](const Sampler& entry) { |
| 357 | if (itr != used_samplers.end()) { | 323 | return entry.GetBuffer() == buffer && entry.GetOffset() == offset; |
| 358 | ASSERT(itr->GetType() == type && itr->IsArray() == is_array && | 324 | }); |
| 359 | itr->IsShadow() == is_shadow); | 325 | if (it != used_samplers.end()) { |
| 360 | return *itr; | 326 | ASSERT(it->IsBindless() && it->GetType() == type && it->IsArray() == is_array && |
| 327 | it->IsShadow() == is_shadow); | ||
| 328 | return *it; | ||
| 361 | } | 329 | } |
| 362 | 330 | ||
| 363 | // Otherwise create a new mapping for this sampler | 331 | // Otherwise create a new mapping for this sampler |
| 364 | const std::size_t next_index = used_samplers.size(); | 332 | const auto next_index = static_cast<u32>(used_samplers.size()); |
| 365 | const Sampler entry{cbuf_index, cbuf_offset, next_index, type, is_array, is_shadow}; | 333 | return used_samplers.emplace_back( |
| 366 | return *used_samplers.emplace(entry).first; | 334 | Sampler(next_index, offset, buffer, type, is_array, is_shadow)); |
| 367 | } | 335 | } |
| 368 | 336 | ||
| 369 | void ShaderIR::WriteTexInstructionFloat(NodeBlock& bb, Instruction instr, const Node4& components, | 337 | void ShaderIR::WriteTexInstructionFloat(NodeBlock& bb, Instruction instr, const Node4& components) { |
| 370 | bool is_tld4) { | ||
| 371 | u32 dest_elem = 0; | 338 | u32 dest_elem = 0; |
| 372 | for (u32 elem = 0; elem < 4; ++elem) { | 339 | for (u32 elem = 0; elem < 4; ++elem) { |
| 373 | if (!is_tld4 && !instr.tex.IsComponentEnabled(elem)) { | 340 | if (!instr.tex.IsComponentEnabled(elem)) { |
| 374 | // Skip disabled components | 341 | // Skip disabled components |
| 375 | continue; | 342 | continue; |
| 376 | } | 343 | } |
diff --git a/src/video_core/shader/node.h b/src/video_core/shader/node.h index 447fb5c1d..4300d9ff4 100644 --- a/src/video_core/shader/node.h +++ b/src/video_core/shader/node.h | |||
| @@ -230,62 +230,49 @@ using NodeBlock = std::vector<Node>; | |||
| 230 | class Sampler { | 230 | class Sampler { |
| 231 | public: | 231 | public: |
| 232 | /// This constructor is for bound samplers | 232 | /// This constructor is for bound samplers |
| 233 | explicit Sampler(std::size_t offset, std::size_t index, Tegra::Shader::TextureType type, | 233 | constexpr explicit Sampler(u32 index, u32 offset, Tegra::Shader::TextureType type, |
| 234 | bool is_array, bool is_shadow) | 234 | bool is_array, bool is_shadow) |
| 235 | : offset{offset}, index{index}, type{type}, is_array{is_array}, is_shadow{is_shadow}, | 235 | : index{index}, offset{offset}, type{type}, is_array{is_array}, is_shadow{is_shadow} {} |
| 236 | is_bindless{false} {} | ||
| 237 | 236 | ||
| 238 | /// This constructor is for bindless samplers | 237 | /// This constructor is for bindless samplers |
| 239 | explicit Sampler(u32 cbuf_index, u32 cbuf_offset, std::size_t index, | 238 | constexpr explicit Sampler(u32 index, u32 offset, u32 buffer, Tegra::Shader::TextureType type, |
| 240 | Tegra::Shader::TextureType type, bool is_array, bool is_shadow) | 239 | bool is_array, bool is_shadow) |
| 241 | : offset{(static_cast<u64>(cbuf_index) << 32) | cbuf_offset}, index{index}, type{type}, | 240 | : index{index}, offset{offset}, buffer{buffer}, type{type}, is_array{is_array}, |
| 242 | is_array{is_array}, is_shadow{is_shadow}, is_bindless{true} {} | 241 | is_shadow{is_shadow}, is_bindless{true} {} |
| 243 | 242 | ||
| 244 | /// This constructor is for serialization/deserialization | 243 | constexpr u32 GetIndex() const { |
| 245 | explicit Sampler(std::size_t offset, std::size_t index, Tegra::Shader::TextureType type, | 244 | return index; |
| 246 | bool is_array, bool is_shadow, bool is_bindless) | 245 | } |
| 247 | : offset{offset}, index{index}, type{type}, is_array{is_array}, is_shadow{is_shadow}, | 246 | |
| 248 | is_bindless{is_bindless} {} | 247 | constexpr u32 GetOffset() const { |
| 249 | |||
| 250 | std::size_t GetOffset() const { | ||
| 251 | return offset; | 248 | return offset; |
| 252 | } | 249 | } |
| 253 | 250 | ||
| 254 | std::size_t GetIndex() const { | 251 | constexpr u32 GetBuffer() const { |
| 255 | return index; | 252 | return buffer; |
| 256 | } | 253 | } |
| 257 | 254 | ||
| 258 | Tegra::Shader::TextureType GetType() const { | 255 | constexpr Tegra::Shader::TextureType GetType() const { |
| 259 | return type; | 256 | return type; |
| 260 | } | 257 | } |
| 261 | 258 | ||
| 262 | bool IsArray() const { | 259 | constexpr bool IsArray() const { |
| 263 | return is_array; | 260 | return is_array; |
| 264 | } | 261 | } |
| 265 | 262 | ||
| 266 | bool IsShadow() const { | 263 | constexpr bool IsShadow() const { |
| 267 | return is_shadow; | 264 | return is_shadow; |
| 268 | } | 265 | } |
| 269 | 266 | ||
| 270 | bool IsBindless() const { | 267 | constexpr bool IsBindless() const { |
| 271 | return is_bindless; | 268 | return is_bindless; |
| 272 | } | 269 | } |
| 273 | 270 | ||
| 274 | std::pair<u32, u32> GetBindlessCBuf() const { | ||
| 275 | return {static_cast<u32>(offset >> 32), static_cast<u32>(offset)}; | ||
| 276 | } | ||
| 277 | |||
| 278 | bool operator<(const Sampler& rhs) const { | ||
| 279 | return std::tie(index, offset, type, is_array, is_shadow, is_bindless) < | ||
| 280 | std::tie(rhs.index, rhs.offset, rhs.type, rhs.is_array, rhs.is_shadow, | ||
| 281 | rhs.is_bindless); | ||
| 282 | } | ||
| 283 | |||
| 284 | private: | 271 | private: |
| 285 | /// Offset in TSC memory from which to read the sampler object, as specified by the sampling | 272 | u32 index{}; ///< Emulated index given for the this sampler. |
| 286 | /// instruction. | 273 | u32 offset{}; ///< Offset in the const buffer from where the sampler is being read. |
| 287 | std::size_t offset{}; | 274 | u32 buffer{}; ///< Buffer where the bindless sampler is being read (unused on bound samplers). |
| 288 | std::size_t index{}; ///< Value used to index into the generated GLSL sampler array. | 275 | |
| 289 | Tegra::Shader::TextureType type{}; ///< The type used to sample this texture (Texture2D, etc) | 276 | Tegra::Shader::TextureType type{}; ///< The type used to sample this texture (Texture2D, etc) |
| 290 | bool is_array{}; ///< Whether the texture is being sampled as an array texture or not. | 277 | bool is_array{}; ///< Whether the texture is being sampled as an array texture or not. |
| 291 | bool is_shadow{}; ///< Whether the texture is being sampled as a depth texture or not. | 278 | bool is_shadow{}; ///< Whether the texture is being sampled as a depth texture or not. |
| @@ -294,18 +281,13 @@ private: | |||
| 294 | 281 | ||
| 295 | class Image final { | 282 | class Image final { |
| 296 | public: | 283 | public: |
| 297 | constexpr explicit Image(std::size_t offset, std::size_t index, Tegra::Shader::ImageType type) | 284 | /// This constructor is for bound images |
| 298 | : offset{offset}, index{index}, type{type}, is_bindless{false} {} | 285 | constexpr explicit Image(u32 index, u32 offset, Tegra::Shader::ImageType type) |
| 299 | 286 | : index{index}, offset{offset}, type{type} {} | |
| 300 | constexpr explicit Image(u32 cbuf_index, u32 cbuf_offset, std::size_t index, | ||
| 301 | Tegra::Shader::ImageType type) | ||
| 302 | : offset{(static_cast<u64>(cbuf_index) << 32) | cbuf_offset}, index{index}, type{type}, | ||
| 303 | is_bindless{true} {} | ||
| 304 | 287 | ||
| 305 | constexpr explicit Image(std::size_t offset, std::size_t index, Tegra::Shader::ImageType type, | 288 | /// This constructor is for bindless samplers |
| 306 | bool is_bindless, bool is_written, bool is_read, bool is_atomic) | 289 | constexpr explicit Image(u32 index, u32 offset, u32 buffer, Tegra::Shader::ImageType type) |
| 307 | : offset{offset}, index{index}, type{type}, is_bindless{is_bindless}, | 290 | : index{index}, offset{offset}, buffer{buffer}, type{type}, is_bindless{true} {} |
| 308 | is_written{is_written}, is_read{is_read}, is_atomic{is_atomic} {} | ||
| 309 | 291 | ||
| 310 | void MarkWrite() { | 292 | void MarkWrite() { |
| 311 | is_written = true; | 293 | is_written = true; |
| @@ -321,12 +303,16 @@ public: | |||
| 321 | is_atomic = true; | 303 | is_atomic = true; |
| 322 | } | 304 | } |
| 323 | 305 | ||
| 324 | constexpr std::size_t GetOffset() const { | 306 | constexpr u32 GetIndex() const { |
| 307 | return index; | ||
| 308 | } | ||
| 309 | |||
| 310 | constexpr u32 GetOffset() const { | ||
| 325 | return offset; | 311 | return offset; |
| 326 | } | 312 | } |
| 327 | 313 | ||
| 328 | constexpr std::size_t GetIndex() const { | 314 | constexpr u32 GetBuffer() const { |
| 329 | return index; | 315 | return buffer; |
| 330 | } | 316 | } |
| 331 | 317 | ||
| 332 | constexpr Tegra::Shader::ImageType GetType() const { | 318 | constexpr Tegra::Shader::ImageType GetType() const { |
| @@ -349,18 +335,11 @@ public: | |||
| 349 | return is_atomic; | 335 | return is_atomic; |
| 350 | } | 336 | } |
| 351 | 337 | ||
| 352 | constexpr std::pair<u32, u32> GetBindlessCBuf() const { | ||
| 353 | return {static_cast<u32>(offset >> 32), static_cast<u32>(offset)}; | ||
| 354 | } | ||
| 355 | |||
| 356 | constexpr bool operator<(const Image& rhs) const { | ||
| 357 | return std::tie(offset, index, type, is_bindless) < | ||
| 358 | std::tie(rhs.offset, rhs.index, rhs.type, rhs.is_bindless); | ||
| 359 | } | ||
| 360 | |||
| 361 | private: | 338 | private: |
| 362 | u64 offset{}; | 339 | u32 index{}; |
| 363 | std::size_t index{}; | 340 | u32 offset{}; |
| 341 | u32 buffer{}; | ||
| 342 | |||
| 364 | Tegra::Shader::ImageType type{}; | 343 | Tegra::Shader::ImageType type{}; |
| 365 | bool is_bindless{}; | 344 | bool is_bindless{}; |
| 366 | bool is_written{}; | 345 | bool is_written{}; |
diff --git a/src/video_core/shader/shader_ir.h b/src/video_core/shader/shader_ir.h index 7582999a5..26c8fde22 100644 --- a/src/video_core/shader/shader_ir.h +++ b/src/video_core/shader/shader_ir.h | |||
| @@ -5,6 +5,7 @@ | |||
| 5 | #pragma once | 5 | #pragma once |
| 6 | 6 | ||
| 7 | #include <array> | 7 | #include <array> |
| 8 | #include <list> | ||
| 8 | #include <map> | 9 | #include <map> |
| 9 | #include <optional> | 10 | #include <optional> |
| 10 | #include <set> | 11 | #include <set> |
| @@ -95,11 +96,11 @@ public: | |||
| 95 | return used_cbufs; | 96 | return used_cbufs; |
| 96 | } | 97 | } |
| 97 | 98 | ||
| 98 | const std::set<Sampler>& GetSamplers() const { | 99 | const std::list<Sampler>& GetSamplers() const { |
| 99 | return used_samplers; | 100 | return used_samplers; |
| 100 | } | 101 | } |
| 101 | 102 | ||
| 102 | const std::map<u64, Image>& GetImages() const { | 103 | const std::list<Image>& GetImages() const { |
| 103 | return used_images; | 104 | return used_images; |
| 104 | } | 105 | } |
| 105 | 106 | ||
| @@ -316,9 +317,6 @@ private: | |||
| 316 | /// Access a bindless image sampler. | 317 | /// Access a bindless image sampler. |
| 317 | Image& GetBindlessImage(Tegra::Shader::Register reg, Tegra::Shader::ImageType type); | 318 | Image& GetBindlessImage(Tegra::Shader::Register reg, Tegra::Shader::ImageType type); |
| 318 | 319 | ||
| 319 | /// Tries to access an existing image, updating it's state as needed | ||
| 320 | Image* TryUseExistingImage(u64 offset, Tegra::Shader::ImageType type); | ||
| 321 | |||
| 322 | /// Extracts a sequence of bits from a node | 320 | /// Extracts a sequence of bits from a node |
| 323 | Node BitfieldExtract(Node value, u32 offset, u32 bits); | 321 | Node BitfieldExtract(Node value, u32 offset, u32 bits); |
| 324 | 322 | ||
| @@ -326,7 +324,7 @@ private: | |||
| 326 | Node BitfieldInsert(Node base, Node insert, u32 offset, u32 bits); | 324 | Node BitfieldInsert(Node base, Node insert, u32 offset, u32 bits); |
| 327 | 325 | ||
| 328 | void WriteTexInstructionFloat(NodeBlock& bb, Tegra::Shader::Instruction instr, | 326 | void WriteTexInstructionFloat(NodeBlock& bb, Tegra::Shader::Instruction instr, |
| 329 | const Node4& components, bool is_tld4 = false); | 327 | const Node4& components); |
| 330 | 328 | ||
| 331 | void WriteTexsInstructionFloat(NodeBlock& bb, Tegra::Shader::Instruction instr, | 329 | void WriteTexsInstructionFloat(NodeBlock& bb, Tegra::Shader::Instruction instr, |
| 332 | const Node4& components, bool ignore_mask = false); | 330 | const Node4& components, bool ignore_mask = false); |
| @@ -402,8 +400,8 @@ private: | |||
| 402 | std::set<Tegra::Shader::Attribute::Index> used_input_attributes; | 400 | std::set<Tegra::Shader::Attribute::Index> used_input_attributes; |
| 403 | std::set<Tegra::Shader::Attribute::Index> used_output_attributes; | 401 | std::set<Tegra::Shader::Attribute::Index> used_output_attributes; |
| 404 | std::map<u32, ConstBuffer> used_cbufs; | 402 | std::map<u32, ConstBuffer> used_cbufs; |
| 405 | std::set<Sampler> used_samplers; | 403 | std::list<Sampler> used_samplers; |
| 406 | std::map<u64, Image> used_images; | 404 | std::list<Image> used_images; |
| 407 | std::array<bool, Tegra::Engines::Maxwell3D::Regs::NumClipDistances> used_clip_distances{}; | 405 | std::array<bool, Tegra::Engines::Maxwell3D::Regs::NumClipDistances> used_clip_distances{}; |
| 408 | std::map<GlobalMemoryBase, GlobalMemoryUsage> used_global_memory; | 406 | std::map<GlobalMemoryBase, GlobalMemoryUsage> used_global_memory; |
| 409 | bool uses_layer{}; | 407 | bool uses_layer{}; |
diff --git a/src/video_core/textures/texture.h b/src/video_core/textures/texture.h index 0429af9c1..27c8ce975 100644 --- a/src/video_core/textures/texture.h +++ b/src/video_core/textures/texture.h | |||
| @@ -132,6 +132,8 @@ enum class SwizzleSource : u32 { | |||
| 132 | }; | 132 | }; |
| 133 | 133 | ||
| 134 | union TextureHandle { | 134 | union TextureHandle { |
| 135 | TextureHandle(u32 raw) : raw{raw} {} | ||
| 136 | |||
| 135 | u32 raw; | 137 | u32 raw; |
| 136 | BitField<0, 20, u32> tic_id; | 138 | BitField<0, 20, u32> tic_id; |
| 137 | BitField<20, 12, u32> tsc_id; | 139 | BitField<20, 12, u32> tsc_id; |
diff --git a/src/yuzu/debugger/wait_tree.cpp b/src/yuzu/debugger/wait_tree.cpp index c5b9aa08f..188f798c0 100644 --- a/src/yuzu/debugger/wait_tree.cpp +++ b/src/yuzu/debugger/wait_tree.cpp | |||
| @@ -172,17 +172,6 @@ std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeWaitObject::GetChildren() con | |||
| 172 | return list; | 172 | return list; |
| 173 | } | 173 | } |
| 174 | 174 | ||
| 175 | QString WaitTreeWaitObject::GetResetTypeQString(Kernel::ResetType reset_type) { | ||
| 176 | switch (reset_type) { | ||
| 177 | case Kernel::ResetType::Automatic: | ||
| 178 | return tr("automatic reset"); | ||
| 179 | case Kernel::ResetType::Manual: | ||
| 180 | return tr("manual reset"); | ||
| 181 | } | ||
| 182 | UNREACHABLE(); | ||
| 183 | return {}; | ||
| 184 | } | ||
| 185 | |||
| 186 | WaitTreeObjectList::WaitTreeObjectList( | 175 | WaitTreeObjectList::WaitTreeObjectList( |
| 187 | const std::vector<Kernel::SharedPtr<Kernel::WaitObject>>& list, bool w_all) | 176 | const std::vector<Kernel::SharedPtr<Kernel::WaitObject>>& list, bool w_all) |
| 188 | : object_list(list), wait_all(w_all) {} | 177 | : object_list(list), wait_all(w_all) {} |
| @@ -336,16 +325,6 @@ std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeThread::GetChildren() const { | |||
| 336 | WaitTreeEvent::WaitTreeEvent(const Kernel::ReadableEvent& object) : WaitTreeWaitObject(object) {} | 325 | WaitTreeEvent::WaitTreeEvent(const Kernel::ReadableEvent& object) : WaitTreeWaitObject(object) {} |
| 337 | WaitTreeEvent::~WaitTreeEvent() = default; | 326 | WaitTreeEvent::~WaitTreeEvent() = default; |
| 338 | 327 | ||
| 339 | std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeEvent::GetChildren() const { | ||
| 340 | std::vector<std::unique_ptr<WaitTreeItem>> list(WaitTreeWaitObject::GetChildren()); | ||
| 341 | |||
| 342 | list.push_back(std::make_unique<WaitTreeText>( | ||
| 343 | tr("reset type = %1") | ||
| 344 | .arg(GetResetTypeQString( | ||
| 345 | static_cast<const Kernel::ReadableEvent&>(object).GetResetType())))); | ||
| 346 | return list; | ||
| 347 | } | ||
| 348 | |||
| 349 | WaitTreeThreadList::WaitTreeThreadList(const std::vector<Kernel::SharedPtr<Kernel::Thread>>& list) | 328 | WaitTreeThreadList::WaitTreeThreadList(const std::vector<Kernel::SharedPtr<Kernel::Thread>>& list) |
| 350 | : thread_list(list) {} | 329 | : thread_list(list) {} |
| 351 | WaitTreeThreadList::~WaitTreeThreadList() = default; | 330 | WaitTreeThreadList::~WaitTreeThreadList() = default; |
diff --git a/src/yuzu/debugger/wait_tree.h b/src/yuzu/debugger/wait_tree.h index 62886609d..f2b13be24 100644 --- a/src/yuzu/debugger/wait_tree.h +++ b/src/yuzu/debugger/wait_tree.h | |||
| @@ -111,8 +111,6 @@ public: | |||
| 111 | 111 | ||
| 112 | protected: | 112 | protected: |
| 113 | const Kernel::WaitObject& object; | 113 | const Kernel::WaitObject& object; |
| 114 | |||
| 115 | static QString GetResetTypeQString(Kernel::ResetType reset_type); | ||
| 116 | }; | 114 | }; |
| 117 | 115 | ||
| 118 | class WaitTreeObjectList : public WaitTreeExpandableItem { | 116 | class WaitTreeObjectList : public WaitTreeExpandableItem { |
| @@ -146,8 +144,6 @@ class WaitTreeEvent : public WaitTreeWaitObject { | |||
| 146 | public: | 144 | public: |
| 147 | explicit WaitTreeEvent(const Kernel::ReadableEvent& object); | 145 | explicit WaitTreeEvent(const Kernel::ReadableEvent& object); |
| 148 | ~WaitTreeEvent() override; | 146 | ~WaitTreeEvent() override; |
| 149 | |||
| 150 | std::vector<std::unique_ptr<WaitTreeItem>> GetChildren() const override; | ||
| 151 | }; | 147 | }; |
| 152 | 148 | ||
| 153 | class WaitTreeThreadList : public WaitTreeExpandableItem { | 149 | class WaitTreeThreadList : public WaitTreeExpandableItem { |
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index d6bb18d24..160613ee1 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp | |||
| @@ -1839,6 +1839,10 @@ void GMainWindow::OnLoadAmiibo() { | |||
| 1839 | return; | 1839 | return; |
| 1840 | } | 1840 | } |
| 1841 | 1841 | ||
| 1842 | LoadAmiibo(filename); | ||
| 1843 | } | ||
| 1844 | |||
| 1845 | void GMainWindow::LoadAmiibo(const QString& filename) { | ||
| 1842 | Core::System& system{Core::System::GetInstance()}; | 1846 | Core::System& system{Core::System::GetInstance()}; |
| 1843 | Service::SM::ServiceManager& sm = system.ServiceManager(); | 1847 | Service::SM::ServiceManager& sm = system.ServiceManager(); |
| 1844 | auto nfc = sm.GetService<Service::NFP::Module::Interface>("nfp:user"); | 1848 | auto nfc = sm.GetService<Service::NFP::Module::Interface>("nfp:user"); |
| @@ -2189,10 +2193,19 @@ static bool IsSingleFileDropEvent(QDropEvent* event) { | |||
| 2189 | } | 2193 | } |
| 2190 | 2194 | ||
| 2191 | void GMainWindow::dropEvent(QDropEvent* event) { | 2195 | void GMainWindow::dropEvent(QDropEvent* event) { |
| 2192 | if (IsSingleFileDropEvent(event) && ConfirmChangeGame()) { | 2196 | if (!IsSingleFileDropEvent(event)) { |
| 2193 | const QMimeData* mimeData = event->mimeData(); | 2197 | return; |
| 2194 | QString filename = mimeData->urls().at(0).toLocalFile(); | 2198 | } |
| 2195 | BootGame(filename); | 2199 | |
| 2200 | const QMimeData* mime_data = event->mimeData(); | ||
| 2201 | const QString filename = mime_data->urls().at(0).toLocalFile(); | ||
| 2202 | |||
| 2203 | if (emulation_running && QFileInfo(filename).suffix() == QStringLiteral("bin")) { | ||
| 2204 | LoadAmiibo(filename); | ||
| 2205 | } else { | ||
| 2206 | if (ConfirmChangeGame()) { | ||
| 2207 | BootGame(filename); | ||
| 2208 | } | ||
| 2196 | } | 2209 | } |
| 2197 | } | 2210 | } |
| 2198 | 2211 | ||
diff --git a/src/yuzu/main.h b/src/yuzu/main.h index fd4b9ccf5..7f46bea2b 100644 --- a/src/yuzu/main.h +++ b/src/yuzu/main.h | |||
| @@ -142,6 +142,7 @@ private: | |||
| 142 | 142 | ||
| 143 | void ShowTelemetryCallout(); | 143 | void ShowTelemetryCallout(); |
| 144 | void SetDiscordEnabled(bool state); | 144 | void SetDiscordEnabled(bool state); |
| 145 | void LoadAmiibo(const QString& filename); | ||
| 145 | 146 | ||
| 146 | void SelectAndSetCurrentUser(); | 147 | void SelectAndSetCurrentUser(); |
| 147 | 148 | ||