diff options
38 files changed, 255 insertions, 129 deletions
diff --git a/externals/dynarmic b/externals/dynarmic | |||
| Subproject 73d3efc3e03887fb89c6a7b655d2f79d0e0711a | Subproject 4f96c63025af34c1490c59f6729497b9866ffa3 | ||
diff --git a/src/common/logging/backend.cpp b/src/common/logging/backend.cpp index 34dec06fe..816414e8d 100644 --- a/src/common/logging/backend.cpp +++ b/src/common/logging/backend.cpp | |||
| @@ -168,6 +168,7 @@ void FileBackend::Write(const Entry& entry) { | |||
| 168 | SUB(Service, AM) \ | 168 | SUB(Service, AM) \ |
| 169 | SUB(Service, AOC) \ | 169 | SUB(Service, AOC) \ |
| 170 | SUB(Service, APM) \ | 170 | SUB(Service, APM) \ |
| 171 | SUB(Service, ARP) \ | ||
| 171 | SUB(Service, BCAT) \ | 172 | SUB(Service, BCAT) \ |
| 172 | SUB(Service, BPC) \ | 173 | SUB(Service, BPC) \ |
| 173 | SUB(Service, BTM) \ | 174 | SUB(Service, BTM) \ |
diff --git a/src/common/logging/log.h b/src/common/logging/log.h index dd5c9e6be..7ab5277ea 100644 --- a/src/common/logging/log.h +++ b/src/common/logging/log.h | |||
| @@ -54,6 +54,7 @@ enum class Class : ClassType { | |||
| 54 | Service_AM, ///< The AM (Applet manager) service | 54 | Service_AM, ///< The AM (Applet manager) service |
| 55 | Service_AOC, ///< The AOC (AddOn Content) service | 55 | Service_AOC, ///< The AOC (AddOn Content) service |
| 56 | Service_APM, ///< The APM (Performance) service | 56 | Service_APM, ///< The APM (Performance) service |
| 57 | Service_ARP, ///< The ARP service | ||
| 57 | Service_Audio, ///< The Audio (Audio control) service | 58 | Service_Audio, ///< The Audio (Audio control) service |
| 58 | Service_BCAT, ///< The BCAT service | 59 | Service_BCAT, ///< The BCAT service |
| 59 | Service_BPC, ///< The BPC service | 60 | Service_BPC, ///< The BPC service |
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 28de22398..c11f017da 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt | |||
| @@ -134,6 +134,8 @@ add_library(core STATIC | |||
| 134 | hle/service/apm/apm.h | 134 | hle/service/apm/apm.h |
| 135 | hle/service/apm/interface.cpp | 135 | hle/service/apm/interface.cpp |
| 136 | hle/service/apm/interface.h | 136 | hle/service/apm/interface.h |
| 137 | hle/service/arp/arp.cpp | ||
| 138 | hle/service/arp/arp.h | ||
| 137 | hle/service/audio/audctl.cpp | 139 | hle/service/audio/audctl.cpp |
| 138 | hle/service/audio/audctl.h | 140 | hle/service/audio/audctl.h |
| 139 | hle/service/audio/auddbg.cpp | 141 | hle/service/audio/auddbg.cpp |
diff --git a/src/core/core.cpp b/src/core/core.cpp index e51e66550..e01c45cdd 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp | |||
| @@ -18,6 +18,7 @@ | |||
| 18 | #include "core/loader/loader.h" | 18 | #include "core/loader/loader.h" |
| 19 | #include "core/settings.h" | 19 | #include "core/settings.h" |
| 20 | #include "file_sys/vfs_real.h" | 20 | #include "file_sys/vfs_real.h" |
| 21 | #include "video_core/renderer_base.h" | ||
| 21 | #include "video_core/video_core.h" | 22 | #include "video_core/video_core.h" |
| 22 | 23 | ||
| 23 | namespace Core { | 24 | namespace Core { |
| @@ -178,7 +179,6 @@ System::ResultStatus System::Init(EmuWindow& emu_window) { | |||
| 178 | cpu_cores[index] = std::make_shared<Cpu>(cpu_exclusive_monitor, cpu_barrier, index); | 179 | cpu_cores[index] = std::make_shared<Cpu>(cpu_exclusive_monitor, cpu_barrier, index); |
| 179 | } | 180 | } |
| 180 | 181 | ||
| 181 | gpu_core = std::make_unique<Tegra::GPU>(); | ||
| 182 | telemetry_session = std::make_unique<Core::TelemetrySession>(); | 182 | telemetry_session = std::make_unique<Core::TelemetrySession>(); |
| 183 | service_manager = std::make_shared<Service::SM::ServiceManager>(); | 183 | service_manager = std::make_shared<Service::SM::ServiceManager>(); |
| 184 | 184 | ||
| @@ -186,10 +186,13 @@ System::ResultStatus System::Init(EmuWindow& emu_window) { | |||
| 186 | Service::Init(service_manager); | 186 | Service::Init(service_manager); |
| 187 | GDBStub::Init(); | 187 | GDBStub::Init(); |
| 188 | 188 | ||
| 189 | if (!VideoCore::Init(emu_window)) { | 189 | renderer = VideoCore::CreateRenderer(emu_window); |
| 190 | if (!renderer->Init()) { | ||
| 190 | return ResultStatus::ErrorVideoCore; | 191 | return ResultStatus::ErrorVideoCore; |
| 191 | } | 192 | } |
| 192 | 193 | ||
| 194 | gpu_core = std::make_unique<Tegra::GPU>(renderer->Rasterizer()); | ||
| 195 | |||
| 193 | // Create threads for CPU cores 1-3, and build thread_to_cpu map | 196 | // Create threads for CPU cores 1-3, and build thread_to_cpu map |
| 194 | // CPU core 0 is run on the main thread | 197 | // CPU core 0 is run on the main thread |
| 195 | thread_to_cpu[std::this_thread::get_id()] = cpu_cores[0]; | 198 | thread_to_cpu[std::this_thread::get_id()] = cpu_cores[0]; |
| @@ -221,7 +224,7 @@ void System::Shutdown() { | |||
| 221 | perf_results.frametime * 1000.0); | 224 | perf_results.frametime * 1000.0); |
| 222 | 225 | ||
| 223 | // Shutdown emulation session | 226 | // Shutdown emulation session |
| 224 | VideoCore::Shutdown(); | 227 | renderer.reset(); |
| 225 | GDBStub::Shutdown(); | 228 | GDBStub::Shutdown(); |
| 226 | Service::Shutdown(); | 229 | Service::Shutdown(); |
| 227 | Kernel::Shutdown(); | 230 | Kernel::Shutdown(); |
diff --git a/src/core/core.h b/src/core/core.h index 4c9967559..a3be88aa8 100644 --- a/src/core/core.h +++ b/src/core/core.h | |||
| @@ -27,6 +27,10 @@ namespace Service::SM { | |||
| 27 | class ServiceManager; | 27 | class ServiceManager; |
| 28 | } | 28 | } |
| 29 | 29 | ||
| 30 | namespace VideoCore { | ||
| 31 | class RendererBase; | ||
| 32 | } | ||
| 33 | |||
| 30 | namespace Core { | 34 | namespace Core { |
| 31 | 35 | ||
| 32 | class System { | 36 | class System { |
| @@ -129,11 +133,26 @@ public: | |||
| 129 | /// Gets a CPU interface to the CPU core with the specified index | 133 | /// Gets a CPU interface to the CPU core with the specified index |
| 130 | Cpu& CpuCore(size_t core_index); | 134 | Cpu& CpuCore(size_t core_index); |
| 131 | 135 | ||
| 132 | /// Gets the GPU interface | 136 | /// Gets a mutable reference to the GPU interface |
| 133 | Tegra::GPU& GPU() { | 137 | Tegra::GPU& GPU() { |
| 134 | return *gpu_core; | 138 | return *gpu_core; |
| 135 | } | 139 | } |
| 136 | 140 | ||
| 141 | /// Gets an immutable reference to the GPU interface. | ||
| 142 | const Tegra::GPU& GPU() const { | ||
| 143 | return *gpu_core; | ||
| 144 | } | ||
| 145 | |||
| 146 | /// Gets a mutable reference to the renderer. | ||
| 147 | VideoCore::RendererBase& Renderer() { | ||
| 148 | return *renderer; | ||
| 149 | } | ||
| 150 | |||
| 151 | /// Gets an immutable reference to the renderer. | ||
| 152 | const VideoCore::RendererBase& Renderer() const { | ||
| 153 | return *renderer; | ||
| 154 | } | ||
| 155 | |||
| 137 | /// Gets the scheduler for the CPU core that is currently running | 156 | /// Gets the scheduler for the CPU core that is currently running |
| 138 | Kernel::Scheduler& CurrentScheduler() { | 157 | Kernel::Scheduler& CurrentScheduler() { |
| 139 | return *CurrentCpuCore().Scheduler(); | 158 | return *CurrentCpuCore().Scheduler(); |
| @@ -197,6 +216,7 @@ private: | |||
| 197 | 216 | ||
| 198 | /// AppLoader used to load the current executing application | 217 | /// AppLoader used to load the current executing application |
| 199 | std::unique_ptr<Loader::AppLoader> app_loader; | 218 | std::unique_ptr<Loader::AppLoader> app_loader; |
| 219 | std::unique_ptr<VideoCore::RendererBase> renderer; | ||
| 200 | std::unique_ptr<Tegra::GPU> gpu_core; | 220 | std::unique_ptr<Tegra::GPU> gpu_core; |
| 201 | std::shared_ptr<Tegra::DebugContext> debug_context; | 221 | std::shared_ptr<Tegra::DebugContext> debug_context; |
| 202 | Kernel::SharedPtr<Kernel::Process> current_process; | 222 | Kernel::SharedPtr<Kernel::Process> current_process; |
diff --git a/src/core/crypto/aes_util.cpp b/src/core/crypto/aes_util.cpp index 4690af5f8..a9876c83e 100644 --- a/src/core/crypto/aes_util.cpp +++ b/src/core/crypto/aes_util.cpp | |||
| @@ -3,10 +3,22 @@ | |||
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include <mbedtls/cipher.h> | 5 | #include <mbedtls/cipher.h> |
| 6 | #include "common/assert.h" | ||
| 7 | #include "common/logging/log.h" | ||
| 6 | #include "core/crypto/aes_util.h" | 8 | #include "core/crypto/aes_util.h" |
| 7 | #include "core/crypto/key_manager.h" | 9 | #include "core/crypto/key_manager.h" |
| 8 | 10 | ||
| 9 | namespace Core::Crypto { | 11 | namespace Core::Crypto { |
| 12 | namespace { | ||
| 13 | std::vector<u8> CalculateNintendoTweak(size_t sector_id) { | ||
| 14 | std::vector<u8> out(0x10); | ||
| 15 | for (size_t i = 0xF; i <= 0xF; --i) { | ||
| 16 | out[i] = sector_id & 0xFF; | ||
| 17 | sector_id >>= 8; | ||
| 18 | } | ||
| 19 | return out; | ||
| 20 | } | ||
| 21 | } // Anonymous namespace | ||
| 10 | 22 | ||
| 11 | static_assert(static_cast<size_t>(Mode::CTR) == static_cast<size_t>(MBEDTLS_CIPHER_AES_128_CTR), | 23 | static_assert(static_cast<size_t>(Mode::CTR) == static_cast<size_t>(MBEDTLS_CIPHER_AES_128_CTR), |
| 12 | "CTR has incorrect value."); | 24 | "CTR has incorrect value."); |
| @@ -56,27 +68,28 @@ void AESCipher<Key, KeySize>::SetIV(std::vector<u8> iv) { | |||
| 56 | } | 68 | } |
| 57 | 69 | ||
| 58 | template <typename Key, size_t KeySize> | 70 | template <typename Key, size_t KeySize> |
| 59 | void AESCipher<Key, KeySize>::Transcode(const u8* src, size_t size, u8* dest, Op op) { | 71 | void AESCipher<Key, KeySize>::Transcode(const u8* src, size_t size, u8* dest, Op op) const { |
| 60 | size_t written = 0; | 72 | auto* const context = op == Op::Encrypt ? &ctx->encryption_context : &ctx->decryption_context; |
| 61 | |||
| 62 | const auto context = op == Op::Encrypt ? &ctx->encryption_context : &ctx->decryption_context; | ||
| 63 | 73 | ||
| 64 | mbedtls_cipher_reset(context); | 74 | mbedtls_cipher_reset(context); |
| 65 | 75 | ||
| 76 | size_t written = 0; | ||
| 66 | if (mbedtls_cipher_get_cipher_mode(context) == MBEDTLS_MODE_XTS) { | 77 | if (mbedtls_cipher_get_cipher_mode(context) == MBEDTLS_MODE_XTS) { |
| 67 | mbedtls_cipher_update(context, src, size, dest, &written); | 78 | mbedtls_cipher_update(context, src, size, dest, &written); |
| 68 | if (written != size) | 79 | if (written != size) { |
| 69 | LOG_WARNING(Crypto, "Not all data was decrypted requested={:016X}, actual={:016X}.", | 80 | LOG_WARNING(Crypto, "Not all data was decrypted requested={:016X}, actual={:016X}.", |
| 70 | size, written); | 81 | size, written); |
| 82 | } | ||
| 71 | } else { | 83 | } else { |
| 72 | const auto block_size = mbedtls_cipher_get_block_size(context); | 84 | const auto block_size = mbedtls_cipher_get_block_size(context); |
| 73 | 85 | ||
| 74 | for (size_t offset = 0; offset < size; offset += block_size) { | 86 | for (size_t offset = 0; offset < size; offset += block_size) { |
| 75 | auto length = std::min<size_t>(block_size, size - offset); | 87 | auto length = std::min<size_t>(block_size, size - offset); |
| 76 | mbedtls_cipher_update(context, src + offset, length, dest + offset, &written); | 88 | mbedtls_cipher_update(context, src + offset, length, dest + offset, &written); |
| 77 | if (written != length) | 89 | if (written != length) { |
| 78 | LOG_WARNING(Crypto, "Not all data was decrypted requested={:016X}, actual={:016X}.", | 90 | LOG_WARNING(Crypto, "Not all data was decrypted requested={:016X}, actual={:016X}.", |
| 79 | length, written); | 91 | length, written); |
| 92 | } | ||
| 80 | } | 93 | } |
| 81 | } | 94 | } |
| 82 | 95 | ||
| @@ -97,16 +110,6 @@ void AESCipher<Key, KeySize>::XTSTranscode(const u8* src, size_t size, u8* dest, | |||
| 97 | } | 110 | } |
| 98 | } | 111 | } |
| 99 | 112 | ||
| 100 | template <typename Key, size_t KeySize> | ||
| 101 | std::vector<u8> AESCipher<Key, KeySize>::CalculateNintendoTweak(size_t sector_id) { | ||
| 102 | std::vector<u8> out(0x10); | ||
| 103 | for (size_t i = 0xF; i <= 0xF; --i) { | ||
| 104 | out[i] = sector_id & 0xFF; | ||
| 105 | sector_id >>= 8; | ||
| 106 | } | ||
| 107 | return out; | ||
| 108 | } | ||
| 109 | |||
| 110 | template class AESCipher<Key128>; | 113 | template class AESCipher<Key128>; |
| 111 | template class AESCipher<Key256>; | 114 | template class AESCipher<Key256>; |
| 112 | } // namespace Core::Crypto \ No newline at end of file | 115 | } // namespace Core::Crypto \ No newline at end of file |
diff --git a/src/core/crypto/aes_util.h b/src/core/crypto/aes_util.h index 5b0b02738..8ce9d6612 100644 --- a/src/core/crypto/aes_util.h +++ b/src/core/crypto/aes_util.h | |||
| @@ -7,7 +7,7 @@ | |||
| 7 | #include <memory> | 7 | #include <memory> |
| 8 | #include <type_traits> | 8 | #include <type_traits> |
| 9 | #include <vector> | 9 | #include <vector> |
| 10 | #include "common/assert.h" | 10 | #include "common/common_types.h" |
| 11 | #include "core/file_sys/vfs.h" | 11 | #include "core/file_sys/vfs.h" |
| 12 | 12 | ||
| 13 | namespace Core::Crypto { | 13 | namespace Core::Crypto { |
| @@ -38,15 +38,19 @@ public: | |||
| 38 | void SetIV(std::vector<u8> iv); | 38 | void SetIV(std::vector<u8> iv); |
| 39 | 39 | ||
| 40 | template <typename Source, typename Dest> | 40 | template <typename Source, typename Dest> |
| 41 | void Transcode(const Source* src, size_t size, Dest* dest, Op op) { | 41 | void Transcode(const Source* src, size_t size, Dest* dest, Op op) const { |
| 42 | static_assert(std::is_trivially_copyable_v<Source> && std::is_trivially_copyable_v<Dest>, | ||
| 43 | "Transcode source and destination types must be trivially copyable."); | ||
| 42 | Transcode(reinterpret_cast<const u8*>(src), size, reinterpret_cast<u8*>(dest), op); | 44 | Transcode(reinterpret_cast<const u8*>(src), size, reinterpret_cast<u8*>(dest), op); |
| 43 | } | 45 | } |
| 44 | 46 | ||
| 45 | void Transcode(const u8* src, size_t size, u8* dest, Op op); | 47 | void Transcode(const u8* src, size_t size, u8* dest, Op op) const; |
| 46 | 48 | ||
| 47 | template <typename Source, typename Dest> | 49 | template <typename Source, typename Dest> |
| 48 | void XTSTranscode(const Source* src, size_t size, Dest* dest, size_t sector_id, | 50 | void XTSTranscode(const Source* src, size_t size, Dest* dest, size_t sector_id, |
| 49 | size_t sector_size, Op op) { | 51 | size_t sector_size, Op op) { |
| 52 | static_assert(std::is_trivially_copyable_v<Source> && std::is_trivially_copyable_v<Dest>, | ||
| 53 | "XTSTranscode source and destination types must be trivially copyable."); | ||
| 50 | XTSTranscode(reinterpret_cast<const u8*>(src), size, reinterpret_cast<u8*>(dest), sector_id, | 54 | XTSTranscode(reinterpret_cast<const u8*>(src), size, reinterpret_cast<u8*>(dest), sector_id, |
| 51 | sector_size, op); | 55 | sector_size, op); |
| 52 | } | 56 | } |
| @@ -56,7 +60,5 @@ public: | |||
| 56 | 60 | ||
| 57 | private: | 61 | private: |
| 58 | std::unique_ptr<CipherContext> ctx; | 62 | std::unique_ptr<CipherContext> ctx; |
| 59 | |||
| 60 | static std::vector<u8> CalculateNintendoTweak(size_t sector_id); | ||
| 61 | }; | 63 | }; |
| 62 | } // namespace Core::Crypto | 64 | } // namespace Core::Crypto |
diff --git a/src/core/crypto/encryption_layer.h b/src/core/crypto/encryption_layer.h index 71bca1f23..7f05af9b4 100644 --- a/src/core/crypto/encryption_layer.h +++ b/src/core/crypto/encryption_layer.h | |||
| @@ -4,6 +4,7 @@ | |||
| 4 | 4 | ||
| 5 | #pragma once | 5 | #pragma once |
| 6 | 6 | ||
| 7 | #include "common/common_types.h" | ||
| 7 | #include "core/file_sys/vfs.h" | 8 | #include "core/file_sys/vfs.h" |
| 8 | 9 | ||
| 9 | namespace Core::Crypto { | 10 | namespace Core::Crypto { |
diff --git a/src/core/crypto/key_manager.cpp b/src/core/crypto/key_manager.cpp index 678ac5752..fc45e7ab5 100644 --- a/src/core/crypto/key_manager.cpp +++ b/src/core/crypto/key_manager.cpp | |||
| @@ -2,19 +2,16 @@ | |||
| 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 | #include <algorithm> | ||
| 5 | #include <array> | 6 | #include <array> |
| 6 | #include <fstream> | 7 | #include <fstream> |
| 7 | #include <locale> | 8 | #include <locale> |
| 8 | #include <sstream> | 9 | #include <sstream> |
| 9 | #include <string_view> | 10 | #include <string_view> |
| 10 | #include <mbedtls/sha256.h> | ||
| 11 | #include "common/assert.h" | ||
| 12 | #include "common/common_paths.h" | 11 | #include "common/common_paths.h" |
| 13 | #include "common/file_util.h" | 12 | #include "common/file_util.h" |
| 14 | #include "common/logging/log.h" | ||
| 15 | #include "core/crypto/key_manager.h" | 13 | #include "core/crypto/key_manager.h" |
| 16 | #include "core/settings.h" | 14 | #include "core/settings.h" |
| 17 | #include "key_manager.h" | ||
| 18 | 15 | ||
| 19 | namespace Core::Crypto { | 16 | namespace Core::Crypto { |
| 20 | 17 | ||
| @@ -66,8 +63,7 @@ KeyManager::KeyManager() { | |||
| 66 | AttemptLoadKeyFile(yuzu_keys_dir, hactool_keys_dir, "title.keys", true); | 63 | AttemptLoadKeyFile(yuzu_keys_dir, hactool_keys_dir, "title.keys", true); |
| 67 | } | 64 | } |
| 68 | 65 | ||
| 69 | void KeyManager::LoadFromFile(std::string_view filename_, bool is_title_keys) { | 66 | void KeyManager::LoadFromFile(const std::string& filename, bool is_title_keys) { |
| 70 | const auto filename = std::string(filename_); | ||
| 71 | std::ifstream file(filename); | 67 | std::ifstream file(filename); |
| 72 | if (!file.is_open()) | 68 | if (!file.is_open()) |
| 73 | return; | 69 | return; |
| @@ -107,11 +103,8 @@ void KeyManager::LoadFromFile(std::string_view filename_, bool is_title_keys) { | |||
| 107 | } | 103 | } |
| 108 | } | 104 | } |
| 109 | 105 | ||
| 110 | void KeyManager::AttemptLoadKeyFile(std::string_view dir1_, std::string_view dir2_, | 106 | void KeyManager::AttemptLoadKeyFile(const std::string& dir1, const std::string& dir2, |
| 111 | std::string_view filename_, bool title) { | 107 | const std::string& filename, bool title) { |
| 112 | const std::string dir1(dir1_); | ||
| 113 | const std::string dir2(dir2_); | ||
| 114 | const std::string filename(filename_); | ||
| 115 | if (FileUtil::Exists(dir1 + DIR_SEP + filename)) | 108 | if (FileUtil::Exists(dir1 + DIR_SEP + filename)) |
| 116 | LoadFromFile(dir1 + DIR_SEP + filename, title); | 109 | LoadFromFile(dir1 + DIR_SEP + filename, title); |
| 117 | else if (FileUtil::Exists(dir2 + DIR_SEP + filename)) | 110 | else if (FileUtil::Exists(dir2 + DIR_SEP + filename)) |
diff --git a/src/core/crypto/key_manager.h b/src/core/crypto/key_manager.h index 03152a12c..c4c53cefc 100644 --- a/src/core/crypto/key_manager.h +++ b/src/core/crypto/key_manager.h | |||
| @@ -5,6 +5,7 @@ | |||
| 5 | #pragma once | 5 | #pragma once |
| 6 | 6 | ||
| 7 | #include <array> | 7 | #include <array> |
| 8 | #include <string> | ||
| 8 | #include <type_traits> | 9 | #include <type_traits> |
| 9 | #include <unordered_map> | 10 | #include <unordered_map> |
| 10 | #include <vector> | 11 | #include <vector> |
| @@ -109,9 +110,9 @@ private: | |||
| 109 | std::unordered_map<KeyIndex<S256KeyType>, Key256> s256_keys; | 110 | std::unordered_map<KeyIndex<S256KeyType>, Key256> s256_keys; |
| 110 | 111 | ||
| 111 | bool dev_mode; | 112 | bool dev_mode; |
| 112 | void LoadFromFile(std::string_view filename, bool is_title_keys); | 113 | void LoadFromFile(const std::string& filename, bool is_title_keys); |
| 113 | void AttemptLoadKeyFile(std::string_view dir1, std::string_view dir2, std::string_view filename, | 114 | void AttemptLoadKeyFile(const std::string& dir1, const std::string& dir2, |
| 114 | bool title); | 115 | const std::string& filename, bool title); |
| 115 | 116 | ||
| 116 | static const std::unordered_map<std::string, KeyIndex<S128KeyType>> s128_file_id; | 117 | static const std::unordered_map<std::string, KeyIndex<S128KeyType>> s128_file_id; |
| 117 | static const std::unordered_map<std::string, KeyIndex<S256KeyType>> s256_file_id; | 118 | static const std::unordered_map<std::string, KeyIndex<S256KeyType>> s256_file_id; |
diff --git a/src/core/hle/service/arp/arp.cpp b/src/core/hle/service/arp/arp.cpp new file mode 100644 index 000000000..358ef2576 --- /dev/null +++ b/src/core/hle/service/arp/arp.cpp | |||
| @@ -0,0 +1,75 @@ | |||
| 1 | // Copyright 2018 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include <memory> | ||
| 6 | |||
| 7 | #include "common/logging/log.h" | ||
| 8 | #include "core/hle/ipc_helpers.h" | ||
| 9 | #include "core/hle/kernel/hle_ipc.h" | ||
| 10 | #include "core/hle/service/arp/arp.h" | ||
| 11 | #include "core/hle/service/service.h" | ||
| 12 | #include "core/hle/service/sm/sm.h" | ||
| 13 | |||
| 14 | namespace Service::ARP { | ||
| 15 | |||
| 16 | class ARP_R final : public ServiceFramework<ARP_R> { | ||
| 17 | public: | ||
| 18 | explicit ARP_R() : ServiceFramework{"arp:r"} { | ||
| 19 | // clang-format off | ||
| 20 | static const FunctionInfo functions[] = { | ||
| 21 | {0, nullptr, "GetApplicationLaunchProperty"}, | ||
| 22 | {1, nullptr, "GetApplicationLaunchPropertyWithApplicationId"}, | ||
| 23 | {2, nullptr, "GetApplicationControlProperty"}, | ||
| 24 | {3, nullptr, "GetApplicationControlPropertyWithApplicationId"}, | ||
| 25 | }; | ||
| 26 | // clang-format on | ||
| 27 | |||
| 28 | RegisterHandlers(functions); | ||
| 29 | } | ||
| 30 | }; | ||
| 31 | |||
| 32 | class IRegistrar final : public ServiceFramework<IRegistrar> { | ||
| 33 | public: | ||
| 34 | explicit IRegistrar() : ServiceFramework{"IRegistrar"} { | ||
| 35 | // clang-format off | ||
| 36 | static const FunctionInfo functions[] = { | ||
| 37 | {0, nullptr, "Issue"}, | ||
| 38 | {1, nullptr, "SetApplicationLaunchProperty"}, | ||
| 39 | {2, nullptr, "SetApplicationControlProperty"}, | ||
| 40 | }; | ||
| 41 | // clang-format on | ||
| 42 | |||
| 43 | RegisterHandlers(functions); | ||
| 44 | } | ||
| 45 | }; | ||
| 46 | |||
| 47 | class ARP_W final : public ServiceFramework<ARP_W> { | ||
| 48 | public: | ||
| 49 | explicit ARP_W() : ServiceFramework{"arp:w"} { | ||
| 50 | // clang-format off | ||
| 51 | static const FunctionInfo functions[] = { | ||
| 52 | {0, &ARP_W::AcquireRegistrar, "AcquireRegistrar"}, | ||
| 53 | {1, nullptr, "DeleteProperties"}, | ||
| 54 | }; | ||
| 55 | // clang-format on | ||
| 56 | |||
| 57 | RegisterHandlers(functions); | ||
| 58 | } | ||
| 59 | |||
| 60 | private: | ||
| 61 | void AcquireRegistrar(Kernel::HLERequestContext& ctx) { | ||
| 62 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | ||
| 63 | rb.Push(RESULT_SUCCESS); | ||
| 64 | rb.PushIpcInterface<IRegistrar>(); | ||
| 65 | |||
| 66 | LOG_DEBUG(Service_ARP, "called"); | ||
| 67 | } | ||
| 68 | }; | ||
| 69 | |||
| 70 | void InstallInterfaces(SM::ServiceManager& sm) { | ||
| 71 | std::make_shared<ARP_R>()->InstallAsService(sm); | ||
| 72 | std::make_shared<ARP_W>()->InstallAsService(sm); | ||
| 73 | } | ||
| 74 | |||
| 75 | } // namespace Service::ARP | ||
diff --git a/src/core/hle/service/arp/arp.h b/src/core/hle/service/arp/arp.h new file mode 100644 index 000000000..9d100187c --- /dev/null +++ b/src/core/hle/service/arp/arp.h | |||
| @@ -0,0 +1,16 @@ | |||
| 1 | // Copyright 2018 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | namespace Service::SM { | ||
| 8 | class ServiceManager; | ||
| 9 | } | ||
| 10 | |||
| 11 | namespace Service::ARP { | ||
| 12 | |||
| 13 | /// Registers all ARP services with the specified service manager. | ||
| 14 | void InstallInterfaces(SM::ServiceManager& sm); | ||
| 15 | |||
| 16 | } // namespace Service::ARP | ||
diff --git a/src/core/hle/service/audio/audin_a.cpp b/src/core/hle/service/audio/audin_a.cpp index e62a27945..a70d5bca4 100644 --- a/src/core/hle/service/audio/audin_a.cpp +++ b/src/core/hle/service/audio/audin_a.cpp | |||
| @@ -2,8 +2,6 @@ | |||
| 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 | ||
| 6 | |||
| 7 | #include "core/hle/service/audio/audin_a.h" | 5 | #include "core/hle/service/audio/audin_a.h" |
| 8 | 6 | ||
| 9 | namespace Service::Audio { | 7 | namespace Service::Audio { |
diff --git a/src/core/hle/service/audio/audrec_a.cpp b/src/core/hle/service/audio/audrec_a.cpp index 9c32f9b98..016eabf53 100644 --- a/src/core/hle/service/audio/audrec_a.cpp +++ b/src/core/hle/service/audio/audrec_a.cpp | |||
| @@ -2,8 +2,6 @@ | |||
| 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 | ||
| 6 | |||
| 7 | #include "core/hle/service/audio/audrec_a.h" | 5 | #include "core/hle/service/audio/audrec_a.h" |
| 8 | 6 | ||
| 9 | namespace Service::Audio { | 7 | namespace Service::Audio { |
diff --git a/src/core/hle/service/audio/audren_a.cpp b/src/core/hle/service/audio/audren_a.cpp index bc9930d79..616ff3dc4 100644 --- a/src/core/hle/service/audio/audren_a.cpp +++ b/src/core/hle/service/audio/audren_a.cpp | |||
| @@ -2,8 +2,6 @@ | |||
| 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 | ||
| 6 | |||
| 7 | #include "core/hle/service/audio/audren_a.h" | 5 | #include "core/hle/service/audio/audren_a.h" |
| 8 | 6 | ||
| 9 | namespace Service::Audio { | 7 | namespace Service::Audio { |
diff --git a/src/core/hle/service/filesystem/fsp_ldr.cpp b/src/core/hle/service/filesystem/fsp_ldr.cpp index ee6d4d055..0ab9c2606 100644 --- a/src/core/hle/service/filesystem/fsp_ldr.cpp +++ b/src/core/hle/service/filesystem/fsp_ldr.cpp | |||
| @@ -2,8 +2,6 @@ | |||
| 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 | ||
| 6 | |||
| 7 | #include "core/hle/service/filesystem/fsp_ldr.h" | 5 | #include "core/hle/service/filesystem/fsp_ldr.h" |
| 8 | #include "core/hle/service/service.h" | 6 | #include "core/hle/service/service.h" |
| 9 | 7 | ||
diff --git a/src/core/hle/service/filesystem/fsp_pr.cpp b/src/core/hle/service/filesystem/fsp_pr.cpp index 0b51385ee..32b0ae454 100644 --- a/src/core/hle/service/filesystem/fsp_pr.cpp +++ b/src/core/hle/service/filesystem/fsp_pr.cpp | |||
| @@ -2,8 +2,6 @@ | |||
| 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 | ||
| 6 | |||
| 7 | #include "core/hle/service/filesystem/fsp_pr.h" | 5 | #include "core/hle/service/filesystem/fsp_pr.h" |
| 8 | #include "core/hle/service/service.h" | 6 | #include "core/hle/service/service.h" |
| 9 | 7 | ||
diff --git a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp index ed69a4325..2b74e6a33 100644 --- a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp +++ b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp | |||
| @@ -30,9 +30,9 @@ void nvdisp_disp0::flip(u32 buffer_handle, u32 offset, u32 format, u32 width, u3 | |||
| 30 | addr, offset, width, height, stride, static_cast<PixelFormat>(format), | 30 | addr, offset, width, height, stride, static_cast<PixelFormat>(format), |
| 31 | transform, crop_rect}; | 31 | transform, crop_rect}; |
| 32 | 32 | ||
| 33 | Core::System::GetInstance().perf_stats.EndGameFrame(); | 33 | auto& instance = Core::System::GetInstance(); |
| 34 | 34 | instance.perf_stats.EndGameFrame(); | |
| 35 | VideoCore::g_renderer->SwapBuffers(framebuffer); | 35 | instance.Renderer().SwapBuffers(framebuffer); |
| 36 | } | 36 | } |
| 37 | 37 | ||
| 38 | } // namespace Service::Nvidia::Devices | 38 | } // namespace Service::Nvidia::Devices |
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp index 57b128b40..4b601781f 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp | |||
| @@ -150,15 +150,16 @@ u32 nvhost_as_gpu::UnmapBuffer(const std::vector<u8>& input, std::vector<u8>& ou | |||
| 150 | 150 | ||
| 151 | LOG_DEBUG(Service_NVDRV, "called, offset=0x{:X}", params.offset); | 151 | LOG_DEBUG(Service_NVDRV, "called, offset=0x{:X}", params.offset); |
| 152 | 152 | ||
| 153 | auto& gpu = Core::System::GetInstance().GPU(); | 153 | const auto itr = buffer_mappings.find(params.offset); |
| 154 | |||
| 155 | auto itr = buffer_mappings.find(params.offset); | ||
| 156 | |||
| 157 | ASSERT_MSG(itr != buffer_mappings.end(), "Tried to unmap invalid mapping"); | 154 | ASSERT_MSG(itr != buffer_mappings.end(), "Tried to unmap invalid mapping"); |
| 158 | 155 | ||
| 156 | auto& system_instance = Core::System::GetInstance(); | ||
| 157 | |||
| 159 | // Remove this memory region from the rasterizer cache. | 158 | // Remove this memory region from the rasterizer cache. |
| 160 | VideoCore::g_renderer->Rasterizer()->FlushAndInvalidateRegion(params.offset, itr->second.size); | 159 | system_instance.Renderer().Rasterizer().FlushAndInvalidateRegion(params.offset, |
| 160 | itr->second.size); | ||
| 161 | 161 | ||
| 162 | auto& gpu = system_instance.GPU(); | ||
| 162 | params.offset = gpu.memory_manager->UnmapBuffer(params.offset, itr->second.size); | 163 | params.offset = gpu.memory_manager->UnmapBuffer(params.offset, itr->second.size); |
| 163 | 164 | ||
| 164 | buffer_mappings.erase(itr->second.offset); | 165 | buffer_mappings.erase(itr->second.offset); |
diff --git a/src/core/hle/service/nvflinger/nvflinger.cpp b/src/core/hle/service/nvflinger/nvflinger.cpp index 5344441e1..0bf51062c 100644 --- a/src/core/hle/service/nvflinger/nvflinger.cpp +++ b/src/core/hle/service/nvflinger/nvflinger.cpp | |||
| @@ -127,9 +127,11 @@ void NVFlinger::Compose() { | |||
| 127 | MicroProfileFlip(); | 127 | MicroProfileFlip(); |
| 128 | 128 | ||
| 129 | if (buffer == boost::none) { | 129 | if (buffer == boost::none) { |
| 130 | auto& system_instance = Core::System::GetInstance(); | ||
| 131 | |||
| 130 | // There was no queued buffer to draw, render previous frame | 132 | // There was no queued buffer to draw, render previous frame |
| 131 | Core::System::GetInstance().perf_stats.EndGameFrame(); | 133 | system_instance.perf_stats.EndGameFrame(); |
| 132 | VideoCore::g_renderer->SwapBuffers({}); | 134 | system_instance.Renderer().SwapBuffers({}); |
| 133 | continue; | 135 | continue; |
| 134 | } | 136 | } |
| 135 | 137 | ||
diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp index 61e0c34a0..31ea79773 100644 --- a/src/core/hle/service/service.cpp +++ b/src/core/hle/service/service.cpp | |||
| @@ -19,6 +19,7 @@ | |||
| 19 | #include "core/hle/service/am/am.h" | 19 | #include "core/hle/service/am/am.h" |
| 20 | #include "core/hle/service/aoc/aoc_u.h" | 20 | #include "core/hle/service/aoc/aoc_u.h" |
| 21 | #include "core/hle/service/apm/apm.h" | 21 | #include "core/hle/service/apm/apm.h" |
| 22 | #include "core/hle/service/arp/arp.h" | ||
| 22 | #include "core/hle/service/audio/audio.h" | 23 | #include "core/hle/service/audio/audio.h" |
| 23 | #include "core/hle/service/bcat/bcat.h" | 24 | #include "core/hle/service/bcat/bcat.h" |
| 24 | #include "core/hle/service/bpc/bpc.h" | 25 | #include "core/hle/service/bpc/bpc.h" |
| @@ -207,6 +208,7 @@ void Init(std::shared_ptr<SM::ServiceManager>& sm) { | |||
| 207 | AM::InstallInterfaces(*sm, nv_flinger); | 208 | AM::InstallInterfaces(*sm, nv_flinger); |
| 208 | AOC::InstallInterfaces(*sm); | 209 | AOC::InstallInterfaces(*sm); |
| 209 | APM::InstallInterfaces(*sm); | 210 | APM::InstallInterfaces(*sm); |
| 211 | ARP::InstallInterfaces(*sm); | ||
| 210 | Audio::InstallInterfaces(*sm); | 212 | Audio::InstallInterfaces(*sm); |
| 211 | BCAT::InstallInterfaces(*sm); | 213 | BCAT::InstallInterfaces(*sm); |
| 212 | BPC::InstallInterfaces(*sm); | 214 | BPC::InstallInterfaces(*sm); |
diff --git a/src/core/memory.cpp b/src/core/memory.cpp index 4b3bb7b31..1133bcbaf 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp | |||
| @@ -326,43 +326,45 @@ void RasterizerMarkRegionCached(Tegra::GPUVAddr gpu_addr, u64 size, bool cached) | |||
| 326 | } | 326 | } |
| 327 | 327 | ||
| 328 | void RasterizerFlushVirtualRegion(VAddr start, u64 size, FlushMode mode) { | 328 | void RasterizerFlushVirtualRegion(VAddr start, u64 size, FlushMode mode) { |
| 329 | auto& system_instance = Core::System::GetInstance(); | ||
| 330 | |||
| 329 | // Since pages are unmapped on shutdown after video core is shutdown, the renderer may be | 331 | // Since pages are unmapped on shutdown after video core is shutdown, the renderer may be |
| 330 | // null here | 332 | // null here |
| 331 | if (VideoCore::g_renderer == nullptr) { | 333 | if (!system_instance.IsPoweredOn()) { |
| 332 | return; | 334 | return; |
| 333 | } | 335 | } |
| 334 | 336 | ||
| 335 | VAddr end = start + size; | 337 | VAddr end = start + size; |
| 336 | 338 | ||
| 337 | auto CheckRegion = [&](VAddr region_start, VAddr region_end) { | 339 | const auto CheckRegion = [&](VAddr region_start, VAddr region_end) { |
| 338 | if (start >= region_end || end <= region_start) { | 340 | if (start >= region_end || end <= region_start) { |
| 339 | // No overlap with region | 341 | // No overlap with region |
| 340 | return; | 342 | return; |
| 341 | } | 343 | } |
| 342 | 344 | ||
| 343 | VAddr overlap_start = std::max(start, region_start); | 345 | const VAddr overlap_start = std::max(start, region_start); |
| 344 | VAddr overlap_end = std::min(end, region_end); | 346 | const VAddr overlap_end = std::min(end, region_end); |
| 345 | 347 | ||
| 346 | std::vector<Tegra::GPUVAddr> gpu_addresses = | 348 | const std::vector<Tegra::GPUVAddr> gpu_addresses = |
| 347 | Core::System::GetInstance().GPU().memory_manager->CpuToGpuAddress(overlap_start); | 349 | system_instance.GPU().memory_manager->CpuToGpuAddress(overlap_start); |
| 348 | 350 | ||
| 349 | if (gpu_addresses.empty()) { | 351 | if (gpu_addresses.empty()) { |
| 350 | return; | 352 | return; |
| 351 | } | 353 | } |
| 352 | 354 | ||
| 353 | u64 overlap_size = overlap_end - overlap_start; | 355 | const u64 overlap_size = overlap_end - overlap_start; |
| 354 | 356 | ||
| 355 | for (const auto& gpu_address : gpu_addresses) { | 357 | for (const auto& gpu_address : gpu_addresses) { |
| 356 | auto* rasterizer = VideoCore::g_renderer->Rasterizer(); | 358 | auto& rasterizer = system_instance.Renderer().Rasterizer(); |
| 357 | switch (mode) { | 359 | switch (mode) { |
| 358 | case FlushMode::Flush: | 360 | case FlushMode::Flush: |
| 359 | rasterizer->FlushRegion(gpu_address, overlap_size); | 361 | rasterizer.FlushRegion(gpu_address, overlap_size); |
| 360 | break; | 362 | break; |
| 361 | case FlushMode::Invalidate: | 363 | case FlushMode::Invalidate: |
| 362 | rasterizer->InvalidateRegion(gpu_address, overlap_size); | 364 | rasterizer.InvalidateRegion(gpu_address, overlap_size); |
| 363 | break; | 365 | break; |
| 364 | case FlushMode::FlushAndInvalidate: | 366 | case FlushMode::FlushAndInvalidate: |
| 365 | rasterizer->FlushAndInvalidateRegion(gpu_address, overlap_size); | 367 | rasterizer.FlushAndInvalidateRegion(gpu_address, overlap_size); |
| 366 | break; | 368 | break; |
| 367 | } | 369 | } |
| 368 | } | 370 | } |
diff --git a/src/core/settings.cpp b/src/core/settings.cpp index 79e0b347b..a4623223d 100644 --- a/src/core/settings.cpp +++ b/src/core/settings.cpp | |||
| @@ -2,6 +2,7 @@ | |||
| 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 | #include "core/core.h" | ||
| 5 | #include "core/gdbstub/gdbstub.h" | 6 | #include "core/gdbstub/gdbstub.h" |
| 6 | #include "core/hle/service/hid/hid.h" | 7 | #include "core/hle/service/hid/hid.h" |
| 7 | #include "core/settings.h" | 8 | #include "core/settings.h" |
| @@ -19,8 +20,9 @@ void Apply() { | |||
| 19 | 20 | ||
| 20 | VideoCore::g_toggle_framelimit_enabled = values.toggle_framelimit; | 21 | VideoCore::g_toggle_framelimit_enabled = values.toggle_framelimit; |
| 21 | 22 | ||
| 22 | if (VideoCore::g_renderer) { | 23 | auto& system_instance = Core::System::GetInstance(); |
| 23 | VideoCore::g_renderer->UpdateCurrentFramebufferLayout(); | 24 | if (system_instance.IsPoweredOn()) { |
| 25 | system_instance.Renderer().UpdateCurrentFramebufferLayout(); | ||
| 24 | } | 26 | } |
| 25 | 27 | ||
| 26 | Service::HID::ReloadInputDevices(); | 28 | Service::HID::ReloadInputDevices(); |
diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp index 0e205ed72..a235b543e 100644 --- a/src/video_core/engines/maxwell_3d.cpp +++ b/src/video_core/engines/maxwell_3d.cpp | |||
| @@ -19,8 +19,8 @@ namespace Engines { | |||
| 19 | /// First register id that is actually a Macro call. | 19 | /// First register id that is actually a Macro call. |
| 20 | constexpr u32 MacroRegistersStart = 0xE00; | 20 | constexpr u32 MacroRegistersStart = 0xE00; |
| 21 | 21 | ||
| 22 | Maxwell3D::Maxwell3D(MemoryManager& memory_manager) | 22 | Maxwell3D::Maxwell3D(VideoCore::RasterizerInterface& rasterizer, MemoryManager& memory_manager) |
| 23 | : memory_manager(memory_manager), macro_interpreter(*this) {} | 23 | : memory_manager(memory_manager), rasterizer{rasterizer}, macro_interpreter(*this) {} |
| 24 | 24 | ||
| 25 | void Maxwell3D::CallMacroMethod(u32 method, std::vector<u32> parameters) { | 25 | void Maxwell3D::CallMacroMethod(u32 method, std::vector<u32> parameters) { |
| 26 | auto macro_code = uploaded_macros.find(method); | 26 | auto macro_code = uploaded_macros.find(method); |
| @@ -130,7 +130,7 @@ void Maxwell3D::WriteReg(u32 method, u32 value, u32 remaining_params) { | |||
| 130 | break; | 130 | break; |
| 131 | } | 131 | } |
| 132 | 132 | ||
| 133 | VideoCore::g_renderer->Rasterizer()->NotifyMaxwellRegisterChanged(method); | 133 | rasterizer.NotifyMaxwellRegisterChanged(method); |
| 134 | 134 | ||
| 135 | if (debug_context) { | 135 | if (debug_context) { |
| 136 | debug_context->OnEvent(Tegra::DebugContext::Event::MaxwellCommandProcessed, nullptr); | 136 | debug_context->OnEvent(Tegra::DebugContext::Event::MaxwellCommandProcessed, nullptr); |
| @@ -218,7 +218,7 @@ void Maxwell3D::DrawArrays() { | |||
| 218 | } | 218 | } |
| 219 | 219 | ||
| 220 | const bool is_indexed{regs.index_array.count && !regs.vertex_buffer.count}; | 220 | const bool is_indexed{regs.index_array.count && !regs.vertex_buffer.count}; |
| 221 | VideoCore::g_renderer->Rasterizer()->AccelerateDrawBatch(is_indexed); | 221 | rasterizer.AccelerateDrawBatch(is_indexed); |
| 222 | 222 | ||
| 223 | // TODO(bunnei): Below, we reset vertex count so that we can use these registers to determine if | 223 | // TODO(bunnei): Below, we reset vertex count so that we can use these registers to determine if |
| 224 | // the game is trying to draw indexed or direct mode. This needs to be verified on HW still - | 224 | // the game is trying to draw indexed or direct mode. This needs to be verified on HW still - |
| @@ -393,7 +393,7 @@ void Maxwell3D::ProcessClearBuffers() { | |||
| 393 | regs.clear_buffers.R == regs.clear_buffers.B && | 393 | regs.clear_buffers.R == regs.clear_buffers.B && |
| 394 | regs.clear_buffers.R == regs.clear_buffers.A); | 394 | regs.clear_buffers.R == regs.clear_buffers.A); |
| 395 | 395 | ||
| 396 | VideoCore::g_renderer->Rasterizer()->Clear(); | 396 | rasterizer.Clear(); |
| 397 | } | 397 | } |
| 398 | 398 | ||
| 399 | } // namespace Engines | 399 | } // namespace Engines |
diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h index 3c32f1067..4d0ff96a5 100644 --- a/src/video_core/engines/maxwell_3d.h +++ b/src/video_core/engines/maxwell_3d.h | |||
| @@ -17,6 +17,10 @@ | |||
| 17 | #include "video_core/memory_manager.h" | 17 | #include "video_core/memory_manager.h" |
| 18 | #include "video_core/textures/texture.h" | 18 | #include "video_core/textures/texture.h" |
| 19 | 19 | ||
| 20 | namespace VideoCore { | ||
| 21 | class RasterizerInterface; | ||
| 22 | } | ||
| 23 | |||
| 20 | namespace Tegra::Engines { | 24 | namespace Tegra::Engines { |
| 21 | 25 | ||
| 22 | #define MAXWELL3D_REG_INDEX(field_name) \ | 26 | #define MAXWELL3D_REG_INDEX(field_name) \ |
| @@ -24,7 +28,7 @@ namespace Tegra::Engines { | |||
| 24 | 28 | ||
| 25 | class Maxwell3D final { | 29 | class Maxwell3D final { |
| 26 | public: | 30 | public: |
| 27 | explicit Maxwell3D(MemoryManager& memory_manager); | 31 | explicit Maxwell3D(VideoCore::RasterizerInterface& rasterizer, MemoryManager& memory_manager); |
| 28 | ~Maxwell3D() = default; | 32 | ~Maxwell3D() = default; |
| 29 | 33 | ||
| 30 | /// Register structure of the Maxwell3D engine. | 34 | /// Register structure of the Maxwell3D engine. |
| @@ -818,6 +822,8 @@ public: | |||
| 818 | Texture::FullTextureInfo GetStageTexture(Regs::ShaderStage stage, size_t offset) const; | 822 | Texture::FullTextureInfo GetStageTexture(Regs::ShaderStage stage, size_t offset) const; |
| 819 | 823 | ||
| 820 | private: | 824 | private: |
| 825 | VideoCore::RasterizerInterface& rasterizer; | ||
| 826 | |||
| 821 | std::unordered_map<u32, std::vector<u32>> uploaded_macros; | 827 | std::unordered_map<u32, std::vector<u32>> uploaded_macros; |
| 822 | 828 | ||
| 823 | /// Macro method that is currently being executed / being fed parameters. | 829 | /// Macro method that is currently being executed / being fed parameters. |
diff --git a/src/video_core/gpu.cpp b/src/video_core/gpu.cpp index 141e20444..b2a83ce0b 100644 --- a/src/video_core/gpu.cpp +++ b/src/video_core/gpu.cpp | |||
| @@ -7,12 +7,13 @@ | |||
| 7 | #include "video_core/engines/maxwell_compute.h" | 7 | #include "video_core/engines/maxwell_compute.h" |
| 8 | #include "video_core/engines/maxwell_dma.h" | 8 | #include "video_core/engines/maxwell_dma.h" |
| 9 | #include "video_core/gpu.h" | 9 | #include "video_core/gpu.h" |
| 10 | #include "video_core/rasterizer_interface.h" | ||
| 10 | 11 | ||
| 11 | namespace Tegra { | 12 | namespace Tegra { |
| 12 | 13 | ||
| 13 | GPU::GPU() { | 14 | GPU::GPU(VideoCore::RasterizerInterface& rasterizer) { |
| 14 | memory_manager = std::make_unique<MemoryManager>(); | 15 | memory_manager = std::make_unique<MemoryManager>(); |
| 15 | maxwell_3d = std::make_unique<Engines::Maxwell3D>(*memory_manager); | 16 | maxwell_3d = std::make_unique<Engines::Maxwell3D>(rasterizer, *memory_manager); |
| 16 | fermi_2d = std::make_unique<Engines::Fermi2D>(*memory_manager); | 17 | fermi_2d = std::make_unique<Engines::Fermi2D>(*memory_manager); |
| 17 | maxwell_compute = std::make_unique<Engines::MaxwellCompute>(); | 18 | maxwell_compute = std::make_unique<Engines::MaxwellCompute>(); |
| 18 | maxwell_dma = std::make_unique<Engines::MaxwellDMA>(*memory_manager); | 19 | maxwell_dma = std::make_unique<Engines::MaxwellDMA>(*memory_manager); |
diff --git a/src/video_core/gpu.h b/src/video_core/gpu.h index 08aa75503..440505c9d 100644 --- a/src/video_core/gpu.h +++ b/src/video_core/gpu.h | |||
| @@ -11,6 +11,10 @@ | |||
| 11 | #include "core/hle/service/nvflinger/buffer_queue.h" | 11 | #include "core/hle/service/nvflinger/buffer_queue.h" |
| 12 | #include "video_core/memory_manager.h" | 12 | #include "video_core/memory_manager.h" |
| 13 | 13 | ||
| 14 | namespace VideoCore { | ||
| 15 | class RasterizerInterface; | ||
| 16 | } | ||
| 17 | |||
| 14 | namespace Tegra { | 18 | namespace Tegra { |
| 15 | 19 | ||
| 16 | enum class RenderTargetFormat : u32 { | 20 | enum class RenderTargetFormat : u32 { |
| @@ -98,7 +102,7 @@ enum class EngineID { | |||
| 98 | 102 | ||
| 99 | class GPU final { | 103 | class GPU final { |
| 100 | public: | 104 | public: |
| 101 | GPU(); | 105 | explicit GPU(VideoCore::RasterizerInterface& rasterizer); |
| 102 | ~GPU(); | 106 | ~GPU(); |
| 103 | 107 | ||
| 104 | /// Processes a command list stored at the specified address in GPU memory. | 108 | /// Processes a command list stored at the specified address in GPU memory. |
diff --git a/src/video_core/renderer_base.cpp b/src/video_core/renderer_base.cpp index dbe3edf09..3ca350243 100644 --- a/src/video_core/renderer_base.cpp +++ b/src/video_core/renderer_base.cpp | |||
| @@ -7,6 +7,8 @@ | |||
| 7 | #include "video_core/renderer_base.h" | 7 | #include "video_core/renderer_base.h" |
| 8 | #include "video_core/renderer_opengl/gl_rasterizer.h" | 8 | #include "video_core/renderer_opengl/gl_rasterizer.h" |
| 9 | 9 | ||
| 10 | namespace VideoCore { | ||
| 11 | |||
| 10 | RendererBase::RendererBase(EmuWindow& window) : render_window{window} {} | 12 | RendererBase::RendererBase(EmuWindow& window) : render_window{window} {} |
| 11 | RendererBase::~RendererBase() = default; | 13 | RendererBase::~RendererBase() = default; |
| 12 | 14 | ||
| @@ -21,3 +23,5 @@ void RendererBase::RefreshRasterizerSetting() { | |||
| 21 | rasterizer = std::make_unique<RasterizerOpenGL>(render_window); | 23 | rasterizer = std::make_unique<RasterizerOpenGL>(render_window); |
| 22 | } | 24 | } |
| 23 | } | 25 | } |
| 26 | |||
| 27 | } // namespace VideoCore | ||
diff --git a/src/video_core/renderer_base.h b/src/video_core/renderer_base.h index 1cb161b7f..235de23a1 100644 --- a/src/video_core/renderer_base.h +++ b/src/video_core/renderer_base.h | |||
| @@ -13,6 +13,8 @@ | |||
| 13 | 13 | ||
| 14 | class EmuWindow; | 14 | class EmuWindow; |
| 15 | 15 | ||
| 16 | namespace VideoCore { | ||
| 17 | |||
| 16 | class RendererBase : NonCopyable { | 18 | class RendererBase : NonCopyable { |
| 17 | public: | 19 | public: |
| 18 | /// Used to reference a framebuffer | 20 | /// Used to reference a framebuffer |
| @@ -44,15 +46,21 @@ public: | |||
| 44 | return m_current_frame; | 46 | return m_current_frame; |
| 45 | } | 47 | } |
| 46 | 48 | ||
| 47 | VideoCore::RasterizerInterface* Rasterizer() const { | 49 | RasterizerInterface& Rasterizer() { |
| 48 | return rasterizer.get(); | 50 | return *rasterizer; |
| 51 | } | ||
| 52 | |||
| 53 | const RasterizerInterface& Rasterizer() const { | ||
| 54 | return *rasterizer; | ||
| 49 | } | 55 | } |
| 50 | 56 | ||
| 51 | void RefreshRasterizerSetting(); | 57 | void RefreshRasterizerSetting(); |
| 52 | 58 | ||
| 53 | protected: | 59 | protected: |
| 54 | EmuWindow& render_window; ///< Reference to the render window handle. | 60 | EmuWindow& render_window; ///< Reference to the render window handle. |
| 55 | std::unique_ptr<VideoCore::RasterizerInterface> rasterizer; | 61 | std::unique_ptr<RasterizerInterface> rasterizer; |
| 56 | f32 m_current_fps = 0.0f; ///< Current framerate, should be set by the renderer | 62 | f32 m_current_fps = 0.0f; ///< Current framerate, should be set by the renderer |
| 57 | int m_current_frame = 0; ///< Current frame, should be set by the renderer | 63 | int m_current_frame = 0; ///< Current frame, should be set by the renderer |
| 58 | }; | 64 | }; |
| 65 | |||
| 66 | } // namespace VideoCore | ||
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 6555db5bb..c2a931469 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp | |||
| @@ -169,8 +169,14 @@ std::pair<u8*, GLintptr> RasterizerOpenGL::SetupVertexArrays(u8* array_ptr, | |||
| 169 | ASSERT(buffer.IsEnabled()); | 169 | ASSERT(buffer.IsEnabled()); |
| 170 | 170 | ||
| 171 | glEnableVertexAttribArray(index); | 171 | glEnableVertexAttribArray(index); |
| 172 | glVertexAttribFormat(index, attrib.ComponentCount(), MaxwellToGL::VertexType(attrib), | 172 | if (attrib.type == Tegra::Engines::Maxwell3D::Regs::VertexAttribute::Type::SignedInt || |
| 173 | attrib.IsNormalized() ? GL_TRUE : GL_FALSE, attrib.offset); | 173 | attrib.type == Tegra::Engines::Maxwell3D::Regs::VertexAttribute::Type::UnsignedInt) { |
| 174 | glVertexAttribIFormat(index, attrib.ComponentCount(), MaxwellToGL::VertexType(attrib), | ||
| 175 | attrib.offset); | ||
| 176 | } else { | ||
| 177 | glVertexAttribFormat(index, attrib.ComponentCount(), MaxwellToGL::VertexType(attrib), | ||
| 178 | attrib.IsNormalized() ? GL_TRUE : GL_FALSE, attrib.offset); | ||
| 179 | } | ||
| 174 | glVertexAttribBinding(index, attrib.buffer); | 180 | glVertexAttribBinding(index, attrib.buffer); |
| 175 | } | 181 | } |
| 176 | 182 | ||
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp index 68db3c22a..e3217db81 100644 --- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp +++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp | |||
| @@ -766,13 +766,16 @@ private: | |||
| 766 | // goes into gpr28+0 and gpr28+1 | 766 | // goes into gpr28+0 and gpr28+1 |
| 767 | size_t texs_offset{}; | 767 | size_t texs_offset{}; |
| 768 | 768 | ||
| 769 | size_t src_elem{}; | ||
| 769 | for (const auto& dest : {instr.gpr0.Value(), instr.gpr28.Value()}) { | 770 | for (const auto& dest : {instr.gpr0.Value(), instr.gpr28.Value()}) { |
| 771 | size_t dest_elem{}; | ||
| 770 | for (unsigned elem = 0; elem < 2; ++elem) { | 772 | for (unsigned elem = 0; elem < 2; ++elem) { |
| 771 | if (!instr.texs.IsComponentEnabled(elem)) { | 773 | if (!instr.texs.IsComponentEnabled(src_elem++)) { |
| 772 | // Skip disabled components | 774 | // Skip disabled components |
| 773 | continue; | 775 | continue; |
| 774 | } | 776 | } |
| 775 | regs.SetRegisterToFloat(dest, elem + texs_offset, texture, 1, 4, false, elem); | 777 | regs.SetRegisterToFloat(dest, elem + texs_offset, texture, 1, 4, false, |
| 778 | dest_elem++); | ||
| 776 | } | 779 | } |
| 777 | 780 | ||
| 778 | if (!instr.texs.HasTwoDestinations()) { | 781 | if (!instr.texs.HasTwoDestinations()) { |
diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp index 74383c7cf..bf9131193 100644 --- a/src/video_core/renderer_opengl/renderer_opengl.cpp +++ b/src/video_core/renderer_opengl/renderer_opengl.cpp | |||
| @@ -103,7 +103,7 @@ ScopeAcquireGLContext::~ScopeAcquireGLContext() { | |||
| 103 | } | 103 | } |
| 104 | } | 104 | } |
| 105 | 105 | ||
| 106 | RendererOpenGL::RendererOpenGL(EmuWindow& window) : RendererBase{window} {} | 106 | RendererOpenGL::RendererOpenGL(EmuWindow& window) : VideoCore::RendererBase{window} {} |
| 107 | RendererOpenGL::~RendererOpenGL() = default; | 107 | RendererOpenGL::~RendererOpenGL() = default; |
| 108 | 108 | ||
| 109 | /// Swap buffers (render frame) | 109 | /// Swap buffers (render frame) |
| @@ -160,8 +160,8 @@ void RendererOpenGL::LoadFBToScreenInfo(const Tegra::FramebufferConfig& framebuf | |||
| 160 | // only allows rows to have a memory alignement of 4. | 160 | // only allows rows to have a memory alignement of 4. |
| 161 | ASSERT(framebuffer.stride % 4 == 0); | 161 | ASSERT(framebuffer.stride % 4 == 0); |
| 162 | 162 | ||
| 163 | if (!Rasterizer()->AccelerateDisplay(framebuffer, framebuffer_addr, framebuffer.stride, | 163 | if (!rasterizer->AccelerateDisplay(framebuffer, framebuffer_addr, framebuffer.stride, |
| 164 | screen_info)) { | 164 | screen_info)) { |
| 165 | // Reset the screen info's display texture to its own permanent texture | 165 | // Reset the screen info's display texture to its own permanent texture |
| 166 | screen_info.display_texture = screen_info.texture.resource.handle; | 166 | screen_info.display_texture = screen_info.texture.resource.handle; |
| 167 | 167 | ||
diff --git a/src/video_core/renderer_opengl/renderer_opengl.h b/src/video_core/renderer_opengl/renderer_opengl.h index ab7de41c8..428afa3b7 100644 --- a/src/video_core/renderer_opengl/renderer_opengl.h +++ b/src/video_core/renderer_opengl/renderer_opengl.h | |||
| @@ -41,7 +41,7 @@ private: | |||
| 41 | EmuWindow& emu_window; | 41 | EmuWindow& emu_window; |
| 42 | }; | 42 | }; |
| 43 | 43 | ||
| 44 | class RendererOpenGL : public RendererBase { | 44 | class RendererOpenGL : public VideoCore::RendererBase { |
| 45 | public: | 45 | public: |
| 46 | explicit RendererOpenGL(EmuWindow& window); | 46 | explicit RendererOpenGL(EmuWindow& window); |
| 47 | ~RendererOpenGL() override; | 47 | ~RendererOpenGL() override; |
diff --git a/src/video_core/video_core.cpp b/src/video_core/video_core.cpp index 06b13e681..5085ef96b 100644 --- a/src/video_core/video_core.cpp +++ b/src/video_core/video_core.cpp | |||
| @@ -3,37 +3,16 @@ | |||
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include <memory> | 5 | #include <memory> |
| 6 | #include "common/logging/log.h" | ||
| 7 | #include "video_core/renderer_base.h" | 6 | #include "video_core/renderer_base.h" |
| 8 | #include "video_core/renderer_opengl/renderer_opengl.h" | 7 | #include "video_core/renderer_opengl/renderer_opengl.h" |
| 9 | #include "video_core/video_core.h" | 8 | #include "video_core/video_core.h" |
| 10 | 9 | ||
| 11 | //////////////////////////////////////////////////////////////////////////////////////////////////// | ||
| 12 | // Video Core namespace | ||
| 13 | |||
| 14 | namespace VideoCore { | 10 | namespace VideoCore { |
| 15 | 11 | ||
| 16 | std::unique_ptr<RendererBase> g_renderer; ///< Renderer plugin | ||
| 17 | |||
| 18 | std::atomic<bool> g_toggle_framelimit_enabled; | 12 | std::atomic<bool> g_toggle_framelimit_enabled; |
| 19 | 13 | ||
| 20 | /// Initialize the video core | 14 | std::unique_ptr<RendererBase> CreateRenderer(EmuWindow& emu_window) { |
| 21 | bool Init(EmuWindow& emu_window) { | 15 | return std::make_unique<RendererOpenGL>(emu_window); |
| 22 | g_renderer = std::make_unique<RendererOpenGL>(emu_window); | ||
| 23 | if (g_renderer->Init()) { | ||
| 24 | LOG_DEBUG(Render, "initialized OK"); | ||
| 25 | } else { | ||
| 26 | LOG_CRITICAL(Render, "initialization failed !"); | ||
| 27 | return false; | ||
| 28 | } | ||
| 29 | return true; | ||
| 30 | } | ||
| 31 | |||
| 32 | /// Shutdown the video core | ||
| 33 | void Shutdown() { | ||
| 34 | g_renderer.reset(); | ||
| 35 | |||
| 36 | LOG_DEBUG(Render, "shutdown OK"); | ||
| 37 | } | 16 | } |
| 38 | 17 | ||
| 39 | } // namespace VideoCore | 18 | } // namespace VideoCore |
diff --git a/src/video_core/video_core.h b/src/video_core/video_core.h index 519b757f5..7c01c0b8d 100644 --- a/src/video_core/video_core.h +++ b/src/video_core/video_core.h | |||
| @@ -8,25 +8,23 @@ | |||
| 8 | #include <memory> | 8 | #include <memory> |
| 9 | 9 | ||
| 10 | class EmuWindow; | 10 | class EmuWindow; |
| 11 | class RendererBase; | ||
| 12 | |||
| 13 | //////////////////////////////////////////////////////////////////////////////////////////////////// | ||
| 14 | // Video Core namespace | ||
| 15 | 11 | ||
| 16 | namespace VideoCore { | 12 | namespace VideoCore { |
| 17 | 13 | ||
| 18 | enum class Renderer { Software, OpenGL }; | 14 | class RendererBase; |
| 19 | 15 | ||
| 20 | extern std::unique_ptr<RendererBase> g_renderer; ///< Renderer plugin | 16 | enum class Renderer { Software, OpenGL }; |
| 21 | 17 | ||
| 22 | // TODO: Wrap these in a user settings struct along with any other graphics settings (often set from | 18 | // TODO: Wrap these in a user settings struct along with any other graphics settings (often set from |
| 23 | // qt ui) | 19 | // qt ui) |
| 24 | extern std::atomic<bool> g_toggle_framelimit_enabled; | 20 | extern std::atomic<bool> g_toggle_framelimit_enabled; |
| 25 | 21 | ||
| 26 | /// Initialize the video core | 22 | /** |
| 27 | bool Init(EmuWindow& emu_window); | 23 | * Creates a renderer instance. |
| 28 | 24 | * | |
| 29 | /// Shutdown the video core | 25 | * @note The returned renderer instance is simply allocated. Its Init() |
| 30 | void Shutdown(); | 26 | * function still needs to be called to fully complete its setup. |
| 27 | */ | ||
| 28 | std::unique_ptr<RendererBase> CreateRenderer(EmuWindow& emu_window); | ||
| 31 | 29 | ||
| 32 | } // namespace VideoCore | 30 | } // namespace VideoCore |
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index eac41553a..e28679cd1 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp | |||
| @@ -477,7 +477,7 @@ bool GMainWindow::LoadROM(const QString& filename) { | |||
| 477 | 477 | ||
| 478 | case Core::System::ResultStatus::ErrorVideoCore: | 478 | case Core::System::ResultStatus::ErrorVideoCore: |
| 479 | QMessageBox::critical( | 479 | QMessageBox::critical( |
| 480 | this, tr("An error occured in the video core."), | 480 | this, tr("An error occurred initializing the video core."), |
| 481 | tr("yuzu has encountered an error while running the video core, please see the " | 481 | tr("yuzu has encountered an error while running the video core, please see the " |
| 482 | "log for more details." | 482 | "log for more details." |
| 483 | "For more information on accessing the log, please see the following page: " | 483 | "For more information on accessing the log, please see the following page: " |
| @@ -491,7 +491,7 @@ bool GMainWindow::LoadROM(const QString& filename) { | |||
| 491 | default: | 491 | default: |
| 492 | QMessageBox::critical( | 492 | QMessageBox::critical( |
| 493 | this, tr("Error while loading ROM!"), | 493 | this, tr("Error while loading ROM!"), |
| 494 | tr("An unknown error occured. Please see the log for more details.")); | 494 | tr("An unknown error occurred. Please see the log for more details.")); |
| 495 | break; | 495 | break; |
| 496 | } | 496 | } |
| 497 | return false; | 497 | return false; |
diff --git a/src/yuzu_cmd/yuzu.cpp b/src/yuzu_cmd/yuzu.cpp index b23213cf6..d637dbd0c 100644 --- a/src/yuzu_cmd/yuzu.cpp +++ b/src/yuzu_cmd/yuzu.cpp | |||
| @@ -193,7 +193,7 @@ int main(int argc, char** argv) { | |||
| 193 | LOG_CRITICAL(Frontend, "Failed to determine system mode!"); | 193 | LOG_CRITICAL(Frontend, "Failed to determine system mode!"); |
| 194 | return -1; | 194 | return -1; |
| 195 | case Core::System::ResultStatus::ErrorVideoCore: | 195 | case Core::System::ResultStatus::ErrorVideoCore: |
| 196 | LOG_CRITICAL(Frontend, "VideoCore not initialized"); | 196 | LOG_CRITICAL(Frontend, "Failed to initialize VideoCore!"); |
| 197 | return -1; | 197 | return -1; |
| 198 | case Core::System::ResultStatus::Success: | 198 | case Core::System::ResultStatus::Success: |
| 199 | break; // Expected case | 199 | break; // Expected case |