diff options
110 files changed, 1811 insertions, 2244 deletions
diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index 32cb85de0..f49a31612 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt | |||
| @@ -31,7 +31,6 @@ add_library(common STATIC | |||
| 31 | bit_set.h | 31 | bit_set.h |
| 32 | break_points.cpp | 32 | break_points.cpp |
| 33 | break_points.h | 33 | break_points.h |
| 34 | chunk_file.h | ||
| 35 | cityhash.cpp | 34 | cityhash.cpp |
| 36 | cityhash.h | 35 | cityhash.h |
| 37 | color.h | 36 | color.h |
| @@ -41,7 +40,6 @@ add_library(common STATIC | |||
| 41 | file_util.cpp | 40 | file_util.cpp |
| 42 | file_util.h | 41 | file_util.h |
| 43 | hash.h | 42 | hash.h |
| 44 | linear_disk_cache.h | ||
| 45 | logging/backend.cpp | 43 | logging/backend.cpp |
| 46 | logging/backend.h | 44 | logging/backend.h |
| 47 | logging/filter.cpp | 45 | logging/filter.cpp |
diff --git a/src/common/chunk_file.h b/src/common/chunk_file.h deleted file mode 100644 index 972ef9039..000000000 --- a/src/common/chunk_file.h +++ /dev/null | |||
| @@ -1,623 +0,0 @@ | |||
| 1 | // Copyright (C) 2003 Dolphin Project. | ||
| 2 | |||
| 3 | // This program is free software: you can redistribute it and/or modify | ||
| 4 | // it under the terms of the GNU General Public License as published by | ||
| 5 | // the Free Software Foundation, version 2.0 or later versions. | ||
| 6 | |||
| 7 | // This program is distributed in the hope that it will be useful, | ||
| 8 | // but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 9 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 10 | // GNU General Public License 2.0 for more details. | ||
| 11 | |||
| 12 | // A copy of the GPL 2.0 should have been included with the program. | ||
| 13 | // If not, see http://www.gnu.org/licenses/ | ||
| 14 | |||
| 15 | // Official SVN repository and contact information can be found at | ||
| 16 | // http://code.google.com/p/dolphin-emu/ | ||
| 17 | |||
| 18 | #pragma once | ||
| 19 | |||
| 20 | // Extremely simple serialization framework. | ||
| 21 | |||
| 22 | // (mis)-features: | ||
| 23 | // + Super fast | ||
| 24 | // + Very simple | ||
| 25 | // + Same code is used for serialization and deserializaition (in most cases) | ||
| 26 | // - Zero backwards/forwards compatibility | ||
| 27 | // - Serialization code for anything complex has to be manually written. | ||
| 28 | |||
| 29 | #include <cstring> | ||
| 30 | #include <deque> | ||
| 31 | #include <list> | ||
| 32 | #include <map> | ||
| 33 | #include <set> | ||
| 34 | #include <string> | ||
| 35 | #include <type_traits> | ||
| 36 | #include <utility> | ||
| 37 | #include <vector> | ||
| 38 | #include "common/assert.h" | ||
| 39 | #include "common/common_types.h" | ||
| 40 | #include "common/logging/log.h" | ||
| 41 | |||
| 42 | template <class T> | ||
| 43 | struct LinkedListItem : public T { | ||
| 44 | LinkedListItem<T>* next; | ||
| 45 | }; | ||
| 46 | |||
| 47 | class PointerWrap; | ||
| 48 | |||
| 49 | class PointerWrapSection { | ||
| 50 | public: | ||
| 51 | PointerWrapSection(PointerWrap& p, int ver, const char* title) | ||
| 52 | : p_(p), ver_(ver), title_(title) {} | ||
| 53 | ~PointerWrapSection(); | ||
| 54 | |||
| 55 | bool operator==(const int& v) const { | ||
| 56 | return ver_ == v; | ||
| 57 | } | ||
| 58 | bool operator!=(const int& v) const { | ||
| 59 | return ver_ != v; | ||
| 60 | } | ||
| 61 | bool operator<=(const int& v) const { | ||
| 62 | return ver_ <= v; | ||
| 63 | } | ||
| 64 | bool operator>=(const int& v) const { | ||
| 65 | return ver_ >= v; | ||
| 66 | } | ||
| 67 | bool operator<(const int& v) const { | ||
| 68 | return ver_ < v; | ||
| 69 | } | ||
| 70 | bool operator>(const int& v) const { | ||
| 71 | return ver_ > v; | ||
| 72 | } | ||
| 73 | |||
| 74 | operator bool() const { | ||
| 75 | return ver_ > 0; | ||
| 76 | } | ||
| 77 | |||
| 78 | private: | ||
| 79 | PointerWrap& p_; | ||
| 80 | int ver_; | ||
| 81 | const char* title_; | ||
| 82 | }; | ||
| 83 | |||
| 84 | // Wrapper class | ||
| 85 | class PointerWrap { | ||
| 86 | // This makes it a compile error if you forget to define DoState() on non-POD. | ||
| 87 | // Which also can be a problem, for example struct tm is non-POD on linux, for whatever reason... | ||
| 88 | #ifdef _MSC_VER | ||
| 89 | template <typename T, bool isPOD = std::is_pod<T>::value, | ||
| 90 | bool isPointer = std::is_pointer<T>::value> | ||
| 91 | #else | ||
| 92 | template <typename T, bool isPOD = __is_pod(T), bool isPointer = std::is_pointer<T>::value> | ||
| 93 | #endif | ||
| 94 | struct DoHelper { | ||
| 95 | static void DoArray(PointerWrap* p, T* x, int count) { | ||
| 96 | for (int i = 0; i < count; ++i) | ||
| 97 | p->Do(x[i]); | ||
| 98 | } | ||
| 99 | |||
| 100 | static void Do(PointerWrap* p, T& x) { | ||
| 101 | p->DoClass(x); | ||
| 102 | } | ||
| 103 | }; | ||
| 104 | |||
| 105 | template <typename T> | ||
| 106 | struct DoHelper<T, true, false> { | ||
| 107 | static void DoArray(PointerWrap* p, T* x, int count) { | ||
| 108 | p->DoVoid((void*)x, sizeof(T) * count); | ||
| 109 | } | ||
| 110 | |||
| 111 | static void Do(PointerWrap* p, T& x) { | ||
| 112 | p->DoVoid((void*)&x, sizeof(x)); | ||
| 113 | } | ||
| 114 | }; | ||
| 115 | |||
| 116 | public: | ||
| 117 | enum Mode { | ||
| 118 | MODE_READ = 1, // load | ||
| 119 | MODE_WRITE, // save | ||
| 120 | MODE_MEASURE, // calculate size | ||
| 121 | MODE_VERIFY, // compare | ||
| 122 | }; | ||
| 123 | |||
| 124 | enum Error { | ||
| 125 | ERROR_NONE = 0, | ||
| 126 | ERROR_WARNING = 1, | ||
| 127 | ERROR_FAILURE = 2, | ||
| 128 | }; | ||
| 129 | |||
| 130 | u8** ptr; | ||
| 131 | Mode mode; | ||
| 132 | Error error; | ||
| 133 | |||
| 134 | public: | ||
| 135 | PointerWrap(u8** ptr_, Mode mode_) : ptr(ptr_), mode(mode_), error(ERROR_NONE) {} | ||
| 136 | PointerWrap(unsigned char** ptr_, int mode_) | ||
| 137 | : ptr((u8**)ptr_), mode((Mode)mode_), error(ERROR_NONE) {} | ||
| 138 | |||
| 139 | PointerWrapSection Section(const char* title, int ver) { | ||
| 140 | return Section(title, ver, ver); | ||
| 141 | } | ||
| 142 | |||
| 143 | // The returned object can be compared against the version that was loaded. | ||
| 144 | // This can be used to support versions as old as minVer. | ||
| 145 | // Version = 0 means the section was not found. | ||
| 146 | PointerWrapSection Section(const char* title, int minVer, int ver) { | ||
| 147 | char marker[16] = {0}; | ||
| 148 | int foundVersion = ver; | ||
| 149 | |||
| 150 | strncpy(marker, title, sizeof(marker)); | ||
| 151 | if (!ExpectVoid(marker, sizeof(marker))) { | ||
| 152 | // Might be before we added name markers for safety. | ||
| 153 | if (foundVersion == 1 && ExpectVoid(&foundVersion, sizeof(foundVersion))) | ||
| 154 | DoMarker(title); | ||
| 155 | // Wasn't found, but maybe we can still load the state. | ||
| 156 | else | ||
| 157 | foundVersion = 0; | ||
| 158 | } else | ||
| 159 | Do(foundVersion); | ||
| 160 | |||
| 161 | if (error == ERROR_FAILURE || foundVersion < minVer || foundVersion > ver) { | ||
| 162 | LOG_ERROR(Common, "Savestate failure: wrong version %d found for %s", foundVersion, | ||
| 163 | title); | ||
| 164 | SetError(ERROR_FAILURE); | ||
| 165 | return PointerWrapSection(*this, -1, title); | ||
| 166 | } | ||
| 167 | return PointerWrapSection(*this, foundVersion, title); | ||
| 168 | } | ||
| 169 | |||
| 170 | void SetMode(Mode mode_) { | ||
| 171 | mode = mode_; | ||
| 172 | } | ||
| 173 | Mode GetMode() const { | ||
| 174 | return mode; | ||
| 175 | } | ||
| 176 | u8** GetPPtr() { | ||
| 177 | return ptr; | ||
| 178 | } | ||
| 179 | void SetError(Error error_) { | ||
| 180 | if (error < error_) | ||
| 181 | error = error_; | ||
| 182 | if (error > ERROR_WARNING) | ||
| 183 | mode = PointerWrap::MODE_MEASURE; | ||
| 184 | } | ||
| 185 | |||
| 186 | bool ExpectVoid(void* data, int size) { | ||
| 187 | switch (mode) { | ||
| 188 | case MODE_READ: | ||
| 189 | if (memcmp(data, *ptr, size) != 0) | ||
| 190 | return false; | ||
| 191 | break; | ||
| 192 | case MODE_WRITE: | ||
| 193 | memcpy(*ptr, data, size); | ||
| 194 | break; | ||
| 195 | case MODE_MEASURE: | ||
| 196 | break; // MODE_MEASURE - don't need to do anything | ||
| 197 | case MODE_VERIFY: | ||
| 198 | for (int i = 0; i < size; i++) { | ||
| 199 | DEBUG_ASSERT_MSG( | ||
| 200 | ((u8*)data)[i] == (*ptr)[i], | ||
| 201 | "Savestate verification failure: %d (0x%X) (at %p) != %d (0x%X) (at %p).\n", | ||
| 202 | ((u8*)data)[i], ((u8*)data)[i], &((u8*)data)[i], (*ptr)[i], (*ptr)[i], | ||
| 203 | &(*ptr)[i]); | ||
| 204 | } | ||
| 205 | break; | ||
| 206 | default: | ||
| 207 | break; // throw an error? | ||
| 208 | } | ||
| 209 | (*ptr) += size; | ||
| 210 | return true; | ||
| 211 | } | ||
| 212 | |||
| 213 | void DoVoid(void* data, int size) { | ||
| 214 | switch (mode) { | ||
| 215 | case MODE_READ: | ||
| 216 | memcpy(data, *ptr, size); | ||
| 217 | break; | ||
| 218 | case MODE_WRITE: | ||
| 219 | memcpy(*ptr, data, size); | ||
| 220 | break; | ||
| 221 | case MODE_MEASURE: | ||
| 222 | break; // MODE_MEASURE - don't need to do anything | ||
| 223 | case MODE_VERIFY: | ||
| 224 | for (int i = 0; i < size; i++) { | ||
| 225 | DEBUG_ASSERT_MSG( | ||
| 226 | ((u8*)data)[i] == (*ptr)[i], | ||
| 227 | "Savestate verification failure: %d (0x%X) (at %p) != %d (0x%X) (at %p).\n", | ||
| 228 | ((u8*)data)[i], ((u8*)data)[i], &((u8*)data)[i], (*ptr)[i], (*ptr)[i], | ||
| 229 | &(*ptr)[i]); | ||
| 230 | } | ||
| 231 | break; | ||
| 232 | default: | ||
| 233 | break; // throw an error? | ||
| 234 | } | ||
| 235 | (*ptr) += size; | ||
| 236 | } | ||
| 237 | |||
| 238 | template <class K, class T> | ||
| 239 | void Do(std::map<K, T*>& x) { | ||
| 240 | if (mode == MODE_READ) { | ||
| 241 | for (auto it = x.begin(), end = x.end(); it != end; ++it) { | ||
| 242 | if (it->second != nullptr) | ||
| 243 | delete it->second; | ||
| 244 | } | ||
| 245 | } | ||
| 246 | T* dv = nullptr; | ||
| 247 | DoMap(x, dv); | ||
| 248 | } | ||
| 249 | |||
| 250 | template <class K, class T> | ||
| 251 | void Do(std::map<K, T>& x) { | ||
| 252 | T dv = T(); | ||
| 253 | DoMap(x, dv); | ||
| 254 | } | ||
| 255 | |||
| 256 | template <class K, class T> | ||
| 257 | void DoMap(std::map<K, T>& x, T& default_val) { | ||
| 258 | unsigned int number = (unsigned int)x.size(); | ||
| 259 | Do(number); | ||
| 260 | switch (mode) { | ||
| 261 | case MODE_READ: { | ||
| 262 | x.clear(); | ||
| 263 | while (number > 0) { | ||
| 264 | K first = K(); | ||
| 265 | Do(first); | ||
| 266 | T second = default_val; | ||
| 267 | Do(second); | ||
| 268 | x[first] = second; | ||
| 269 | --number; | ||
| 270 | } | ||
| 271 | } break; | ||
| 272 | case MODE_WRITE: | ||
| 273 | case MODE_MEASURE: | ||
| 274 | case MODE_VERIFY: { | ||
| 275 | typename std::map<K, T>::iterator itr = x.begin(); | ||
| 276 | while (number > 0) { | ||
| 277 | K first = itr->first; | ||
| 278 | Do(first); | ||
| 279 | Do(itr->second); | ||
| 280 | --number; | ||
| 281 | ++itr; | ||
| 282 | } | ||
| 283 | } break; | ||
| 284 | } | ||
| 285 | } | ||
| 286 | |||
| 287 | template <class K, class T> | ||
| 288 | void Do(std::multimap<K, T*>& x) { | ||
| 289 | if (mode == MODE_READ) { | ||
| 290 | for (auto it = x.begin(), end = x.end(); it != end; ++it) { | ||
| 291 | if (it->second != nullptr) | ||
| 292 | delete it->second; | ||
| 293 | } | ||
| 294 | } | ||
| 295 | T* dv = nullptr; | ||
| 296 | DoMultimap(x, dv); | ||
| 297 | } | ||
| 298 | |||
| 299 | template <class K, class T> | ||
| 300 | void Do(std::multimap<K, T>& x) { | ||
| 301 | T dv = T(); | ||
| 302 | DoMultimap(x, dv); | ||
| 303 | } | ||
| 304 | |||
| 305 | template <class K, class T> | ||
| 306 | void DoMultimap(std::multimap<K, T>& x, T& default_val) { | ||
| 307 | unsigned int number = (unsigned int)x.size(); | ||
| 308 | Do(number); | ||
| 309 | switch (mode) { | ||
| 310 | case MODE_READ: { | ||
| 311 | x.clear(); | ||
| 312 | while (number > 0) { | ||
| 313 | K first = K(); | ||
| 314 | Do(first); | ||
| 315 | T second = default_val; | ||
| 316 | Do(second); | ||
| 317 | x.insert(std::make_pair(first, second)); | ||
| 318 | --number; | ||
| 319 | } | ||
| 320 | } break; | ||
| 321 | case MODE_WRITE: | ||
| 322 | case MODE_MEASURE: | ||
| 323 | case MODE_VERIFY: { | ||
| 324 | typename std::multimap<K, T>::iterator itr = x.begin(); | ||
| 325 | while (number > 0) { | ||
| 326 | Do(itr->first); | ||
| 327 | Do(itr->second); | ||
| 328 | --number; | ||
| 329 | ++itr; | ||
| 330 | } | ||
| 331 | } break; | ||
| 332 | } | ||
| 333 | } | ||
| 334 | |||
| 335 | // Store vectors. | ||
| 336 | template <class T> | ||
| 337 | void Do(std::vector<T*>& x) { | ||
| 338 | T* dv = nullptr; | ||
| 339 | DoVector(x, dv); | ||
| 340 | } | ||
| 341 | |||
| 342 | template <class T> | ||
| 343 | void Do(std::vector<T>& x) { | ||
| 344 | T dv = T(); | ||
| 345 | DoVector(x, dv); | ||
| 346 | } | ||
| 347 | |||
| 348 | template <class T> | ||
| 349 | void DoPOD(std::vector<T>& x) { | ||
| 350 | T dv = T(); | ||
| 351 | DoVectorPOD(x, dv); | ||
| 352 | } | ||
| 353 | |||
| 354 | template <class T> | ||
| 355 | void Do(std::vector<T>& x, T& default_val) { | ||
| 356 | DoVector(x, default_val); | ||
| 357 | } | ||
| 358 | |||
| 359 | template <class T> | ||
| 360 | void DoVector(std::vector<T>& x, T& default_val) { | ||
| 361 | u32 vec_size = (u32)x.size(); | ||
| 362 | Do(vec_size); | ||
| 363 | x.resize(vec_size, default_val); | ||
| 364 | if (vec_size > 0) | ||
| 365 | DoArray(&x[0], vec_size); | ||
| 366 | } | ||
| 367 | |||
| 368 | template <class T> | ||
| 369 | void DoVectorPOD(std::vector<T>& x, T& default_val) { | ||
| 370 | u32 vec_size = (u32)x.size(); | ||
| 371 | Do(vec_size); | ||
| 372 | x.resize(vec_size, default_val); | ||
| 373 | if (vec_size > 0) | ||
| 374 | DoArray(&x[0], vec_size); | ||
| 375 | } | ||
| 376 | |||
| 377 | // Store deques. | ||
| 378 | template <class T> | ||
| 379 | void Do(std::deque<T*>& x) { | ||
| 380 | T* dv = nullptr; | ||
| 381 | DoDeque(x, dv); | ||
| 382 | } | ||
| 383 | |||
| 384 | template <class T> | ||
| 385 | void Do(std::deque<T>& x) { | ||
| 386 | T dv = T(); | ||
| 387 | DoDeque(x, dv); | ||
| 388 | } | ||
| 389 | |||
| 390 | template <class T> | ||
| 391 | void DoDeque(std::deque<T>& x, T& default_val) { | ||
| 392 | u32 deq_size = (u32)x.size(); | ||
| 393 | Do(deq_size); | ||
| 394 | x.resize(deq_size, default_val); | ||
| 395 | u32 i; | ||
| 396 | for (i = 0; i < deq_size; i++) | ||
| 397 | Do(x[i]); | ||
| 398 | } | ||
| 399 | |||
| 400 | // Store STL lists. | ||
| 401 | template <class T> | ||
| 402 | void Do(std::list<T*>& x) { | ||
| 403 | T* dv = nullptr; | ||
| 404 | Do(x, dv); | ||
| 405 | } | ||
| 406 | |||
| 407 | template <class T> | ||
| 408 | void Do(std::list<T>& x) { | ||
| 409 | T dv = T(); | ||
| 410 | DoList(x, dv); | ||
| 411 | } | ||
| 412 | |||
| 413 | template <class T> | ||
| 414 | void Do(std::list<T>& x, T& default_val) { | ||
| 415 | DoList(x, default_val); | ||
| 416 | } | ||
| 417 | |||
| 418 | template <class T> | ||
| 419 | void DoList(std::list<T>& x, T& default_val) { | ||
| 420 | u32 list_size = (u32)x.size(); | ||
| 421 | Do(list_size); | ||
| 422 | x.resize(list_size, default_val); | ||
| 423 | |||
| 424 | typename std::list<T>::iterator itr, end; | ||
| 425 | for (itr = x.begin(), end = x.end(); itr != end; ++itr) | ||
| 426 | Do(*itr); | ||
| 427 | } | ||
| 428 | |||
| 429 | // Store STL sets. | ||
| 430 | template <class T> | ||
| 431 | void Do(std::set<T*>& x) { | ||
| 432 | if (mode == MODE_READ) { | ||
| 433 | for (auto it = x.begin(), end = x.end(); it != end; ++it) { | ||
| 434 | if (*it != nullptr) | ||
| 435 | delete *it; | ||
| 436 | } | ||
| 437 | } | ||
| 438 | DoSet(x); | ||
| 439 | } | ||
| 440 | |||
| 441 | template <class T> | ||
| 442 | void Do(std::set<T>& x) { | ||
| 443 | DoSet(x); | ||
| 444 | } | ||
| 445 | |||
| 446 | template <class T> | ||
| 447 | void DoSet(std::set<T>& x) { | ||
| 448 | unsigned int number = (unsigned int)x.size(); | ||
| 449 | Do(number); | ||
| 450 | |||
| 451 | switch (mode) { | ||
| 452 | case MODE_READ: { | ||
| 453 | x.clear(); | ||
| 454 | while (number-- > 0) { | ||
| 455 | T it = T(); | ||
| 456 | Do(it); | ||
| 457 | x.insert(it); | ||
| 458 | } | ||
| 459 | } break; | ||
| 460 | case MODE_WRITE: | ||
| 461 | case MODE_MEASURE: | ||
| 462 | case MODE_VERIFY: { | ||
| 463 | typename std::set<T>::iterator itr = x.begin(); | ||
| 464 | while (number-- > 0) | ||
| 465 | Do(*itr++); | ||
| 466 | } break; | ||
| 467 | |||
| 468 | default: | ||
| 469 | LOG_ERROR(Common, "Savestate error: invalid mode %d.", mode); | ||
| 470 | } | ||
| 471 | } | ||
| 472 | |||
| 473 | // Store strings. | ||
| 474 | void Do(std::string& x) { | ||
| 475 | int stringLen = (int)x.length() + 1; | ||
| 476 | Do(stringLen); | ||
| 477 | |||
| 478 | switch (mode) { | ||
| 479 | case MODE_READ: | ||
| 480 | x = (char*)*ptr; | ||
| 481 | break; | ||
| 482 | case MODE_WRITE: | ||
| 483 | memcpy(*ptr, x.c_str(), stringLen); | ||
| 484 | break; | ||
| 485 | case MODE_MEASURE: | ||
| 486 | break; | ||
| 487 | case MODE_VERIFY: | ||
| 488 | DEBUG_ASSERT_MSG((x == (char*)*ptr), | ||
| 489 | "Savestate verification failure: \"%s\" != \"%s\" (at %p).\n", | ||
| 490 | x.c_str(), (char*)*ptr, ptr); | ||
| 491 | break; | ||
| 492 | } | ||
| 493 | (*ptr) += stringLen; | ||
| 494 | } | ||
| 495 | |||
| 496 | void Do(std::wstring& x) { | ||
| 497 | int stringLen = sizeof(wchar_t) * ((int)x.length() + 1); | ||
| 498 | Do(stringLen); | ||
| 499 | |||
| 500 | switch (mode) { | ||
| 501 | case MODE_READ: | ||
| 502 | x = (wchar_t*)*ptr; | ||
| 503 | break; | ||
| 504 | case MODE_WRITE: | ||
| 505 | memcpy(*ptr, x.c_str(), stringLen); | ||
| 506 | break; | ||
| 507 | case MODE_MEASURE: | ||
| 508 | break; | ||
| 509 | case MODE_VERIFY: | ||
| 510 | DEBUG_ASSERT_MSG((x == (wchar_t*)*ptr), | ||
| 511 | "Savestate verification failure: \"%ls\" != \"%ls\" (at %p).\n", | ||
| 512 | x.c_str(), (wchar_t*)*ptr, ptr); | ||
| 513 | break; | ||
| 514 | } | ||
| 515 | (*ptr) += stringLen; | ||
| 516 | } | ||
| 517 | |||
| 518 | template <class T> | ||
| 519 | void DoClass(T& x) { | ||
| 520 | x.DoState(*this); | ||
| 521 | } | ||
| 522 | |||
| 523 | template <class T> | ||
| 524 | void DoClass(T*& x) { | ||
| 525 | if (mode == MODE_READ) { | ||
| 526 | if (x != nullptr) | ||
| 527 | delete x; | ||
| 528 | x = new T(); | ||
| 529 | } | ||
| 530 | x->DoState(*this); | ||
| 531 | } | ||
| 532 | |||
| 533 | template <class T> | ||
| 534 | void DoArray(T* x, int count) { | ||
| 535 | DoHelper<T>::DoArray(this, x, count); | ||
| 536 | } | ||
| 537 | |||
| 538 | template <class T> | ||
| 539 | void Do(T& x) { | ||
| 540 | DoHelper<T>::Do(this, x); | ||
| 541 | } | ||
| 542 | |||
| 543 | template <class T> | ||
| 544 | void DoPOD(T& x) { | ||
| 545 | DoHelper<T>::Do(this, x); | ||
| 546 | } | ||
| 547 | |||
| 548 | template <class T> | ||
| 549 | void DoPointer(T*& x, T* const base) { | ||
| 550 | // pointers can be more than 2^31 apart, but you're using this function wrong if you need | ||
| 551 | // that much range | ||
| 552 | s32 offset = x - base; | ||
| 553 | Do(offset); | ||
| 554 | if (mode == MODE_READ) | ||
| 555 | x = base + offset; | ||
| 556 | } | ||
| 557 | |||
| 558 | template <class T, LinkedListItem<T>* (*TNew)(), void (*TFree)(LinkedListItem<T>*), | ||
| 559 | void (*TDo)(PointerWrap&, T*)> | ||
| 560 | void DoLinkedList(LinkedListItem<T>*& list_start, LinkedListItem<T>** list_end = nullptr) { | ||
| 561 | LinkedListItem<T>* list_cur = list_start; | ||
| 562 | LinkedListItem<T>* prev = nullptr; | ||
| 563 | |||
| 564 | while (true) { | ||
| 565 | u8 shouldExist = (list_cur ? 1 : 0); | ||
| 566 | Do(shouldExist); | ||
| 567 | if (shouldExist == 1) { | ||
| 568 | LinkedListItem<T>* cur = list_cur ? list_cur : TNew(); | ||
| 569 | TDo(*this, (T*)cur); | ||
| 570 | if (!list_cur) { | ||
| 571 | if (mode == MODE_READ) { | ||
| 572 | cur->next = nullptr; | ||
| 573 | list_cur = cur; | ||
| 574 | if (prev) | ||
| 575 | prev->next = cur; | ||
| 576 | else | ||
| 577 | list_start = cur; | ||
| 578 | } else { | ||
| 579 | TFree(cur); | ||
| 580 | continue; | ||
| 581 | } | ||
| 582 | } | ||
| 583 | } else { | ||
| 584 | if (mode == MODE_READ) { | ||
| 585 | if (prev) | ||
| 586 | prev->next = nullptr; | ||
| 587 | if (list_end) | ||
| 588 | *list_end = prev; | ||
| 589 | if (list_cur) { | ||
| 590 | if (list_start == list_cur) | ||
| 591 | list_start = nullptr; | ||
| 592 | do { | ||
| 593 | LinkedListItem<T>* next = list_cur->next; | ||
| 594 | TFree(list_cur); | ||
| 595 | list_cur = next; | ||
| 596 | } while (list_cur); | ||
| 597 | } | ||
| 598 | } | ||
| 599 | break; | ||
| 600 | } | ||
| 601 | prev = list_cur; | ||
| 602 | list_cur = list_cur->next; | ||
| 603 | } | ||
| 604 | } | ||
| 605 | |||
| 606 | void DoMarker(const char* prevName, u32 arbitraryNumber = 0x42) { | ||
| 607 | u32 cookie = arbitraryNumber; | ||
| 608 | Do(cookie); | ||
| 609 | if (mode == PointerWrap::MODE_READ && cookie != arbitraryNumber) { | ||
| 610 | LOG_ERROR(Common, | ||
| 611 | "After \"%s\", found %d (0x%X) instead of save marker %d (0x%X). " | ||
| 612 | "Aborting savestate load...", | ||
| 613 | prevName, cookie, cookie, arbitraryNumber, arbitraryNumber); | ||
| 614 | SetError(ERROR_FAILURE); | ||
| 615 | } | ||
| 616 | } | ||
| 617 | }; | ||
| 618 | |||
| 619 | inline PointerWrapSection::~PointerWrapSection() { | ||
| 620 | if (ver_ > 0) { | ||
| 621 | p_.DoMarker(title_); | ||
| 622 | } | ||
| 623 | } | ||
diff --git a/src/common/linear_disk_cache.h b/src/common/linear_disk_cache.h deleted file mode 100644 index 94c695163..000000000 --- a/src/common/linear_disk_cache.h +++ /dev/null | |||
| @@ -1,167 +0,0 @@ | |||
| 1 | // Copyright 2013 Dolphin Emulator Project / 2014 Citra Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include <fstream> | ||
| 8 | #include "common/common_types.h" | ||
| 9 | |||
| 10 | // defined in Version.cpp | ||
| 11 | extern const char* scm_rev_git_str; | ||
| 12 | |||
| 13 | // On disk format: | ||
| 14 | // header{ | ||
| 15 | // u32 'DCAC'; | ||
| 16 | // u32 version; // svn_rev | ||
| 17 | // u16 sizeof(key_type); | ||
| 18 | // u16 sizeof(value_type); | ||
| 19 | //} | ||
| 20 | |||
| 21 | // key_value_pair{ | ||
| 22 | // u32 value_size; | ||
| 23 | // key_type key; | ||
| 24 | // value_type[value_size] value; | ||
| 25 | //} | ||
| 26 | |||
| 27 | template <typename K, typename V> | ||
| 28 | class LinearDiskCacheReader { | ||
| 29 | public: | ||
| 30 | virtual void Read(const K& key, const V* value, u32 value_size) = 0; | ||
| 31 | }; | ||
| 32 | |||
| 33 | // Dead simple unsorted key-value store with append functionality. | ||
| 34 | // No random read functionality, all reading is done in OpenAndRead. | ||
| 35 | // Keys and values can contain any characters, including \0. | ||
| 36 | // | ||
| 37 | // Suitable for caching generated shader bytecode between executions. | ||
| 38 | // Not tuned for extreme performance but should be reasonably fast. | ||
| 39 | // Does not support keys or values larger than 2GB, which should be reasonable. | ||
| 40 | // Keys must have non-zero length; values can have zero length. | ||
| 41 | |||
| 42 | // K and V are some POD type | ||
| 43 | // K : the key type | ||
| 44 | // V : value array type | ||
| 45 | template <typename K, typename V> | ||
| 46 | class LinearDiskCache { | ||
| 47 | public: | ||
| 48 | // return number of read entries | ||
| 49 | u32 OpenAndRead(const char* filename, LinearDiskCacheReader<K, V>& reader) { | ||
| 50 | using std::ios_base; | ||
| 51 | |||
| 52 | // close any currently opened file | ||
| 53 | Close(); | ||
| 54 | m_num_entries = 0; | ||
| 55 | |||
| 56 | // try opening for reading/writing | ||
| 57 | OpenFStream(m_file, filename, ios_base::in | ios_base::out | ios_base::binary); | ||
| 58 | |||
| 59 | m_file.seekg(0, std::ios::end); | ||
| 60 | std::fstream::pos_type end_pos = m_file.tellg(); | ||
| 61 | m_file.seekg(0, std::ios::beg); | ||
| 62 | std::fstream::pos_type start_pos = m_file.tellg(); | ||
| 63 | std::streamoff file_size = end_pos - start_pos; | ||
| 64 | |||
| 65 | if (m_file.is_open() && ValidateHeader()) { | ||
| 66 | // good header, read some key/value pairs | ||
| 67 | K key; | ||
| 68 | |||
| 69 | V* value = nullptr; | ||
| 70 | u32 value_size; | ||
| 71 | u32 entry_number; | ||
| 72 | |||
| 73 | std::fstream::pos_type last_pos = m_file.tellg(); | ||
| 74 | |||
| 75 | while (Read(&value_size)) { | ||
| 76 | std::streamoff next_extent = | ||
| 77 | (last_pos - start_pos) + sizeof(value_size) + value_size; | ||
| 78 | if (next_extent > file_size) | ||
| 79 | break; | ||
| 80 | |||
| 81 | delete[] value; | ||
| 82 | value = new V[value_size]; | ||
| 83 | |||
| 84 | // read key/value and pass to reader | ||
| 85 | if (Read(&key) && Read(value, value_size) && Read(&entry_number) && | ||
| 86 | entry_number == m_num_entries + 1) { | ||
| 87 | reader.Read(key, value, value_size); | ||
| 88 | } else { | ||
| 89 | break; | ||
| 90 | } | ||
| 91 | |||
| 92 | m_num_entries++; | ||
| 93 | last_pos = m_file.tellg(); | ||
| 94 | } | ||
| 95 | m_file.seekp(last_pos); | ||
| 96 | m_file.clear(); | ||
| 97 | |||
| 98 | delete[] value; | ||
| 99 | return m_num_entries; | ||
| 100 | } | ||
| 101 | |||
| 102 | // failed to open file for reading or bad header | ||
| 103 | // close and recreate file | ||
| 104 | Close(); | ||
| 105 | m_file.open(filename, ios_base::out | ios_base::trunc | ios_base::binary); | ||
| 106 | WriteHeader(); | ||
| 107 | return 0; | ||
| 108 | } | ||
| 109 | |||
| 110 | void Sync() { | ||
| 111 | m_file.flush(); | ||
| 112 | } | ||
| 113 | |||
| 114 | void Close() { | ||
| 115 | if (m_file.is_open()) | ||
| 116 | m_file.close(); | ||
| 117 | // clear any error flags | ||
| 118 | m_file.clear(); | ||
| 119 | } | ||
| 120 | |||
| 121 | // Appends a key-value pair to the store. | ||
| 122 | void Append(const K& key, const V* value, u32 value_size) { | ||
| 123 | // TODO: Should do a check that we don't already have "key"? (I think each caller does that | ||
| 124 | // already.) | ||
| 125 | Write(&value_size); | ||
| 126 | Write(&key); | ||
| 127 | Write(value, value_size); | ||
| 128 | m_num_entries++; | ||
| 129 | Write(&m_num_entries); | ||
| 130 | } | ||
| 131 | |||
| 132 | private: | ||
| 133 | void WriteHeader() { | ||
| 134 | Write(&m_header); | ||
| 135 | } | ||
| 136 | |||
| 137 | bool ValidateHeader() { | ||
| 138 | char file_header[sizeof(Header)]; | ||
| 139 | |||
| 140 | return (Read(file_header, sizeof(Header)) && | ||
| 141 | !memcmp((const char*)&m_header, file_header, sizeof(Header))); | ||
| 142 | } | ||
| 143 | |||
| 144 | template <typename D> | ||
| 145 | bool Write(const D* data, u32 count = 1) { | ||
| 146 | return m_file.write((const char*)data, count * sizeof(D)).good(); | ||
| 147 | } | ||
| 148 | |||
| 149 | template <typename D> | ||
| 150 | bool Read(const D* data, u32 count = 1) { | ||
| 151 | return m_file.read((char*)data, count * sizeof(D)).good(); | ||
| 152 | } | ||
| 153 | |||
| 154 | struct Header { | ||
| 155 | Header() : id(*(u32*)"DCAC"), key_t_size(sizeof(K)), value_t_size(sizeof(V)) { | ||
| 156 | memcpy(ver, scm_rev_git_str, 40); | ||
| 157 | } | ||
| 158 | |||
| 159 | const u32 id; | ||
| 160 | const u16 key_t_size, value_t_size; | ||
| 161 | char ver[40]; | ||
| 162 | |||
| 163 | } m_header; | ||
| 164 | |||
| 165 | std::fstream m_file; | ||
| 166 | u32 m_num_entries; | ||
| 167 | }; | ||
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index c2a6f56cd..45dbd6796 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt | |||
| @@ -42,8 +42,6 @@ add_library(core STATIC | |||
| 42 | hle/kernel/client_port.h | 42 | hle/kernel/client_port.h |
| 43 | hle/kernel/client_session.cpp | 43 | hle/kernel/client_session.cpp |
| 44 | hle/kernel/client_session.h | 44 | hle/kernel/client_session.h |
| 45 | hle/kernel/condition_variable.cpp | ||
| 46 | hle/kernel/condition_variable.h | ||
| 47 | hle/kernel/errors.h | 45 | hle/kernel/errors.h |
| 48 | hle/kernel/event.cpp | 46 | hle/kernel/event.cpp |
| 49 | hle/kernel/event.h | 47 | hle/kernel/event.h |
| @@ -183,10 +181,10 @@ add_library(core STATIC | |||
| 183 | hle/service/nvflinger/buffer_queue.h | 181 | hle/service/nvflinger/buffer_queue.h |
| 184 | hle/service/nvflinger/nvflinger.cpp | 182 | hle/service/nvflinger/nvflinger.cpp |
| 185 | hle/service/nvflinger/nvflinger.h | 183 | hle/service/nvflinger/nvflinger.h |
| 184 | hle/service/pctl/module.cpp | ||
| 185 | hle/service/pctl/module.h | ||
| 186 | hle/service/pctl/pctl.cpp | 186 | hle/service/pctl/pctl.cpp |
| 187 | hle/service/pctl/pctl.h | 187 | hle/service/pctl/pctl.h |
| 188 | hle/service/pctl/pctl_a.cpp | ||
| 189 | hle/service/pctl/pctl_a.h | ||
| 190 | hle/service/prepo/prepo.cpp | 188 | hle/service/prepo/prepo.cpp |
| 191 | hle/service/prepo/prepo.h | 189 | hle/service/prepo/prepo.h |
| 192 | hle/service/service.cpp | 190 | hle/service/service.cpp |
diff --git a/src/core/file_sys/disk_filesystem.cpp b/src/core/file_sys/disk_filesystem.cpp index ca1323873..8aa0e0aa4 100644 --- a/src/core/file_sys/disk_filesystem.cpp +++ b/src/core/file_sys/disk_filesystem.cpp | |||
| @@ -67,26 +67,32 @@ ResultCode Disk_FileSystem::DeleteFile(const std::string& path) const { | |||
| 67 | return RESULT_SUCCESS; | 67 | return RESULT_SUCCESS; |
| 68 | } | 68 | } |
| 69 | 69 | ||
| 70 | ResultCode Disk_FileSystem::RenameFile(const Path& src_path, const Path& dest_path) const { | 70 | ResultCode Disk_FileSystem::RenameFile(const std::string& src_path, |
| 71 | LOG_WARNING(Service_FS, "(STUBBED) called"); | 71 | const std::string& dest_path) const { |
| 72 | const std::string full_src_path = base_directory + src_path; | ||
| 73 | const std::string full_dest_path = base_directory + dest_path; | ||
| 74 | |||
| 75 | if (!FileUtil::Exists(full_src_path)) { | ||
| 76 | return ERROR_PATH_NOT_FOUND; | ||
| 77 | } | ||
| 72 | // TODO(wwylele): Use correct error code | 78 | // TODO(wwylele): Use correct error code |
| 73 | return ResultCode(-1); | 79 | return FileUtil::Rename(full_src_path, full_dest_path) ? RESULT_SUCCESS : ResultCode(-1); |
| 74 | } | 80 | } |
| 75 | 81 | ||
| 76 | ResultCode Disk_FileSystem::DeleteDirectory(const Path& path) const { | 82 | ResultCode Disk_FileSystem::DeleteDirectory(const Path& path) const { |
| 77 | LOG_WARNING(Service_FS, "(STUBBED) called"); | 83 | NGLOG_WARNING(Service_FS, "(STUBBED) called"); |
| 78 | // TODO(wwylele): Use correct error code | 84 | // TODO(wwylele): Use correct error code |
| 79 | return ResultCode(-1); | 85 | return ResultCode(-1); |
| 80 | } | 86 | } |
| 81 | 87 | ||
| 82 | ResultCode Disk_FileSystem::DeleteDirectoryRecursively(const Path& path) const { | 88 | ResultCode Disk_FileSystem::DeleteDirectoryRecursively(const Path& path) const { |
| 83 | LOG_WARNING(Service_FS, "(STUBBED) called"); | 89 | NGLOG_WARNING(Service_FS, "(STUBBED) called"); |
| 84 | // TODO(wwylele): Use correct error code | 90 | // TODO(wwylele): Use correct error code |
| 85 | return ResultCode(-1); | 91 | return ResultCode(-1); |
| 86 | } | 92 | } |
| 87 | 93 | ||
| 88 | ResultCode Disk_FileSystem::CreateFile(const std::string& path, u64 size) const { | 94 | ResultCode Disk_FileSystem::CreateFile(const std::string& path, u64 size) const { |
| 89 | LOG_WARNING(Service_FS, "(STUBBED) called"); | 95 | NGLOG_WARNING(Service_FS, "(STUBBED) called"); |
| 90 | 96 | ||
| 91 | std::string full_path = base_directory + path; | 97 | std::string full_path = base_directory + path; |
| 92 | if (size == 0) { | 98 | if (size == 0) { |
| @@ -101,7 +107,7 @@ ResultCode Disk_FileSystem::CreateFile(const std::string& path, u64 size) const | |||
| 101 | return RESULT_SUCCESS; | 107 | return RESULT_SUCCESS; |
| 102 | } | 108 | } |
| 103 | 109 | ||
| 104 | LOG_ERROR(Service_FS, "Too large file"); | 110 | NGLOG_ERROR(Service_FS, "Too large file"); |
| 105 | // TODO(Subv): Find out the correct error code | 111 | // TODO(Subv): Find out the correct error code |
| 106 | return ResultCode(-1); | 112 | return ResultCode(-1); |
| 107 | } | 113 | } |
| @@ -114,13 +120,13 @@ ResultCode Disk_FileSystem::CreateDirectory(const std::string& path) const { | |||
| 114 | return RESULT_SUCCESS; | 120 | return RESULT_SUCCESS; |
| 115 | } | 121 | } |
| 116 | 122 | ||
| 117 | LOG_CRITICAL(Service_FS, "(unreachable) Unknown error creating %s", full_path.c_str()); | 123 | NGLOG_CRITICAL(Service_FS, "(unreachable) Unknown error creating {}", full_path); |
| 118 | // TODO(wwylele): Use correct error code | 124 | // TODO(wwylele): Use correct error code |
| 119 | return ResultCode(-1); | 125 | return ResultCode(-1); |
| 120 | } | 126 | } |
| 121 | 127 | ||
| 122 | ResultCode Disk_FileSystem::RenameDirectory(const Path& src_path, const Path& dest_path) const { | 128 | ResultCode Disk_FileSystem::RenameDirectory(const Path& src_path, const Path& dest_path) const { |
| 123 | LOG_WARNING(Service_FS, "(STUBBED) called"); | 129 | NGLOG_WARNING(Service_FS, "(STUBBED) called"); |
| 124 | // TODO(wwylele): Use correct error code | 130 | // TODO(wwylele): Use correct error code |
| 125 | return ResultCode(-1); | 131 | return ResultCode(-1); |
| 126 | } | 132 | } |
| @@ -140,7 +146,7 @@ ResultVal<std::unique_ptr<DirectoryBackend>> Disk_FileSystem::OpenDirectory( | |||
| 140 | } | 146 | } |
| 141 | 147 | ||
| 142 | u64 Disk_FileSystem::GetFreeSpaceSize() const { | 148 | u64 Disk_FileSystem::GetFreeSpaceSize() const { |
| 143 | LOG_WARNING(Service_FS, "(STUBBED) called"); | 149 | NGLOG_WARNING(Service_FS, "(STUBBED) called"); |
| 144 | return 0; | 150 | return 0; |
| 145 | } | 151 | } |
| 146 | 152 | ||
| @@ -157,14 +163,14 @@ ResultVal<FileSys::EntryType> Disk_FileSystem::GetEntryType(const std::string& p | |||
| 157 | } | 163 | } |
| 158 | 164 | ||
| 159 | ResultVal<size_t> Disk_Storage::Read(const u64 offset, const size_t length, u8* buffer) const { | 165 | ResultVal<size_t> Disk_Storage::Read(const u64 offset, const size_t length, u8* buffer) const { |
| 160 | LOG_TRACE(Service_FS, "called offset=%llu, length=%zu", offset, length); | 166 | NGLOG_TRACE(Service_FS, "called offset={}, length={}", offset, length); |
| 161 | file->Seek(offset, SEEK_SET); | 167 | file->Seek(offset, SEEK_SET); |
| 162 | return MakeResult<size_t>(file->ReadBytes(buffer, length)); | 168 | return MakeResult<size_t>(file->ReadBytes(buffer, length)); |
| 163 | } | 169 | } |
| 164 | 170 | ||
| 165 | ResultVal<size_t> Disk_Storage::Write(const u64 offset, const size_t length, const bool flush, | 171 | ResultVal<size_t> Disk_Storage::Write(const u64 offset, const size_t length, const bool flush, |
| 166 | const u8* buffer) const { | 172 | const u8* buffer) const { |
| 167 | LOG_WARNING(Service_FS, "(STUBBED) called"); | 173 | NGLOG_WARNING(Service_FS, "(STUBBED) called"); |
| 168 | file->Seek(offset, SEEK_SET); | 174 | file->Seek(offset, SEEK_SET); |
| 169 | size_t written = file->WriteBytes(buffer, length); | 175 | size_t written = file->WriteBytes(buffer, length); |
| 170 | if (flush) { | 176 | if (flush) { |
| @@ -198,8 +204,7 @@ u64 Disk_Directory::Read(const u64 count, Entry* entries) { | |||
| 198 | const std::string& filename = file.virtualName; | 204 | const std::string& filename = file.virtualName; |
| 199 | Entry& entry = entries[entries_read]; | 205 | Entry& entry = entries[entries_read]; |
| 200 | 206 | ||
| 201 | LOG_TRACE(Service_FS, "File %s: size=%llu dir=%d", filename.c_str(), file.size, | 207 | NGLOG_TRACE(Service_FS, "File {}: size={} dir={}", filename, file.size, file.isDirectory); |
| 202 | file.isDirectory); | ||
| 203 | 208 | ||
| 204 | // TODO(Link Mauve): use a proper conversion to UTF-16. | 209 | // TODO(Link Mauve): use a proper conversion to UTF-16. |
| 205 | for (size_t j = 0; j < FILENAME_LENGTH; ++j) { | 210 | for (size_t j = 0; j < FILENAME_LENGTH; ++j) { |
diff --git a/src/core/file_sys/disk_filesystem.h b/src/core/file_sys/disk_filesystem.h index 8f9e1145a..591e39fda 100644 --- a/src/core/file_sys/disk_filesystem.h +++ b/src/core/file_sys/disk_filesystem.h | |||
| @@ -26,7 +26,7 @@ public: | |||
| 26 | ResultVal<std::unique_ptr<StorageBackend>> OpenFile(const std::string& path, | 26 | ResultVal<std::unique_ptr<StorageBackend>> OpenFile(const std::string& path, |
| 27 | Mode mode) const override; | 27 | Mode mode) const override; |
| 28 | ResultCode DeleteFile(const std::string& path) const override; | 28 | ResultCode DeleteFile(const std::string& path) const override; |
| 29 | ResultCode RenameFile(const Path& src_path, const Path& dest_path) const override; | 29 | ResultCode RenameFile(const std::string& src_path, const std::string& dest_path) const override; |
| 30 | ResultCode DeleteDirectory(const Path& path) const override; | 30 | ResultCode DeleteDirectory(const Path& path) const override; |
| 31 | ResultCode DeleteDirectoryRecursively(const Path& path) const override; | 31 | ResultCode DeleteDirectoryRecursively(const Path& path) const override; |
| 32 | ResultCode CreateFile(const std::string& path, u64 size) const override; | 32 | ResultCode CreateFile(const std::string& path, u64 size) const override; |
diff --git a/src/core/file_sys/filesystem.cpp b/src/core/file_sys/filesystem.cpp index 82fdb3c46..87083878b 100644 --- a/src/core/file_sys/filesystem.cpp +++ b/src/core/file_sys/filesystem.cpp | |||
| @@ -71,7 +71,7 @@ std::string Path::AsString() const { | |||
| 71 | case Binary: | 71 | case Binary: |
| 72 | default: | 72 | default: |
| 73 | // TODO(yuriks): Add assert | 73 | // TODO(yuriks): Add assert |
| 74 | LOG_ERROR(Service_FS, "LowPathType cannot be converted to string!"); | 74 | NGLOG_ERROR(Service_FS, "LowPathType cannot be converted to string!"); |
| 75 | return {}; | 75 | return {}; |
| 76 | } | 76 | } |
| 77 | } | 77 | } |
| @@ -87,7 +87,7 @@ std::u16string Path::AsU16Str() const { | |||
| 87 | case Invalid: | 87 | case Invalid: |
| 88 | case Binary: | 88 | case Binary: |
| 89 | // TODO(yuriks): Add assert | 89 | // TODO(yuriks): Add assert |
| 90 | LOG_ERROR(Service_FS, "LowPathType cannot be converted to u16string!"); | 90 | NGLOG_ERROR(Service_FS, "LowPathType cannot be converted to u16string!"); |
| 91 | return {}; | 91 | return {}; |
| 92 | } | 92 | } |
| 93 | 93 | ||
| @@ -115,7 +115,7 @@ std::vector<u8> Path::AsBinary() const { | |||
| 115 | case Invalid: | 115 | case Invalid: |
| 116 | default: | 116 | default: |
| 117 | // TODO(yuriks): Add assert | 117 | // TODO(yuriks): Add assert |
| 118 | LOG_ERROR(Service_FS, "LowPathType cannot be converted to binary!"); | 118 | NGLOG_ERROR(Service_FS, "LowPathType cannot be converted to binary!"); |
| 119 | return {}; | 119 | return {}; |
| 120 | } | 120 | } |
| 121 | } | 121 | } |
diff --git a/src/core/file_sys/filesystem.h b/src/core/file_sys/filesystem.h index beefcfdb2..295a3133e 100644 --- a/src/core/file_sys/filesystem.h +++ b/src/core/file_sys/filesystem.h | |||
| @@ -126,7 +126,8 @@ public: | |||
| 126 | * @param dest_path Destination path relative to the archive | 126 | * @param dest_path Destination path relative to the archive |
| 127 | * @return Result of the operation | 127 | * @return Result of the operation |
| 128 | */ | 128 | */ |
| 129 | virtual ResultCode RenameFile(const Path& src_path, const Path& dest_path) const = 0; | 129 | virtual ResultCode RenameFile(const std::string& src_path, |
| 130 | const std::string& dest_path) const = 0; | ||
| 130 | 131 | ||
| 131 | /** | 132 | /** |
| 132 | * Rename a Directory specified by its path | 133 | * Rename a Directory specified by its path |
diff --git a/src/core/file_sys/partition_filesystem.cpp b/src/core/file_sys/partition_filesystem.cpp index 4a58a9291..808254ecc 100644 --- a/src/core/file_sys/partition_filesystem.cpp +++ b/src/core/file_sys/partition_filesystem.cpp | |||
| @@ -2,7 +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 | #include <cinttypes> | ||
| 6 | #include <utility> | 5 | #include <utility> |
| 7 | #include "common/file_util.h" | 6 | #include "common/file_util.h" |
| 8 | #include "common/logging/log.h" | 7 | #include "common/logging/log.h" |
| @@ -40,7 +39,7 @@ Loader::ResultStatus PartitionFilesystem::Load(const std::string& file_path, siz | |||
| 40 | 39 | ||
| 41 | Loader::ResultStatus result = Load(file_data); | 40 | Loader::ResultStatus result = Load(file_data); |
| 42 | if (result != Loader::ResultStatus::Success) | 41 | if (result != Loader::ResultStatus::Success) |
| 43 | LOG_ERROR(Service_FS, "Failed to load PFS from file %s!", file_path.c_str()); | 42 | NGLOG_ERROR(Service_FS, "Failed to load PFS from file {}!", file_path); |
| 44 | 43 | ||
| 45 | return result; | 44 | return result; |
| 46 | } | 45 | } |
diff --git a/src/core/file_sys/program_metadata.cpp b/src/core/file_sys/program_metadata.cpp index a6dcebcc3..1f5ded514 100644 --- a/src/core/file_sys/program_metadata.cpp +++ b/src/core/file_sys/program_metadata.cpp | |||
| @@ -2,7 +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 | #include <cinttypes> | ||
| 6 | #include "common/file_util.h" | 5 | #include "common/file_util.h" |
| 7 | #include "common/logging/log.h" | 6 | #include "common/logging/log.h" |
| 8 | #include "core/file_sys/program_metadata.h" | 7 | #include "core/file_sys/program_metadata.h" |
| @@ -22,7 +21,7 @@ Loader::ResultStatus ProgramMetadata::Load(const std::string& file_path) { | |||
| 22 | 21 | ||
| 23 | Loader::ResultStatus result = Load(file_data); | 22 | Loader::ResultStatus result = Load(file_data); |
| 24 | if (result != Loader::ResultStatus::Success) | 23 | if (result != Loader::ResultStatus::Success) |
| 25 | LOG_ERROR(Service_FS, "Failed to load NPDM from file %s!", file_path.c_str()); | 24 | NGLOG_ERROR(Service_FS, "Failed to load NPDM from file {}!", file_path); |
| 26 | 25 | ||
| 27 | return result; | 26 | return result; |
| 28 | } | 27 | } |
| @@ -77,14 +76,14 @@ u64 ProgramMetadata::GetFilesystemPermissions() const { | |||
| 77 | } | 76 | } |
| 78 | 77 | ||
| 79 | void ProgramMetadata::Print() const { | 78 | void ProgramMetadata::Print() const { |
| 80 | LOG_DEBUG(Service_FS, "Magic: %.4s", npdm_header.magic.data()); | 79 | NGLOG_DEBUG(Service_FS, "Magic: {:.4}", npdm_header.magic.data()); |
| 81 | LOG_DEBUG(Service_FS, "Main thread priority: 0x%02x", npdm_header.main_thread_priority); | 80 | NGLOG_DEBUG(Service_FS, "Main thread priority: {:#04X}", npdm_header.main_thread_priority); |
| 82 | LOG_DEBUG(Service_FS, "Main thread core: %u", npdm_header.main_thread_cpu); | 81 | NGLOG_DEBUG(Service_FS, "Main thread core: {}", npdm_header.main_thread_cpu); |
| 83 | LOG_DEBUG(Service_FS, "Main thread stack size: 0x%x bytes", npdm_header.main_stack_size); | 82 | NGLOG_DEBUG(Service_FS, "Main thread stack size: {:#X} bytes", npdm_header.main_stack_size); |
| 84 | LOG_DEBUG(Service_FS, "Process category: %u", npdm_header.process_category); | 83 | NGLOG_DEBUG(Service_FS, "Process category: {}", npdm_header.process_category); |
| 85 | LOG_DEBUG(Service_FS, "Flags: %02x", npdm_header.flags); | 84 | NGLOG_DEBUG(Service_FS, "Flags: {:02X}", npdm_header.flags); |
| 86 | LOG_DEBUG(Service_FS, " > 64-bit instructions: %s", | 85 | NGLOG_DEBUG(Service_FS, " > 64-bit instructions: {}", |
| 87 | npdm_header.has_64_bit_instructions ? "YES" : "NO"); | 86 | npdm_header.has_64_bit_instructions ? "YES" : "NO"); |
| 88 | 87 | ||
| 89 | auto address_space = "Unknown"; | 88 | auto address_space = "Unknown"; |
| 90 | switch (npdm_header.address_space_type) { | 89 | switch (npdm_header.address_space_type) { |
| @@ -96,19 +95,19 @@ void ProgramMetadata::Print() const { | |||
| 96 | break; | 95 | break; |
| 97 | } | 96 | } |
| 98 | 97 | ||
| 99 | LOG_DEBUG(Service_FS, " > Address space: %s\n", address_space); | 98 | NGLOG_DEBUG(Service_FS, " > Address space: {}\n", address_space); |
| 100 | 99 | ||
| 101 | // Begin ACID printing (potential perms, signed) | 100 | // Begin ACID printing (potential perms, signed) |
| 102 | LOG_DEBUG(Service_FS, "Magic: %.4s", acid_header.magic.data()); | 101 | NGLOG_DEBUG(Service_FS, "Magic: {:.4}", acid_header.magic.data()); |
| 103 | LOG_DEBUG(Service_FS, "Flags: %02x", acid_header.flags); | 102 | NGLOG_DEBUG(Service_FS, "Flags: {:02X}", acid_header.flags); |
| 104 | LOG_DEBUG(Service_FS, " > Is Retail: %s", acid_header.is_retail ? "YES" : "NO"); | 103 | NGLOG_DEBUG(Service_FS, " > Is Retail: {}", acid_header.is_retail ? "YES" : "NO"); |
| 105 | LOG_DEBUG(Service_FS, "Title ID Min: %016" PRIX64, acid_header.title_id_min); | 104 | NGLOG_DEBUG(Service_FS, "Title ID Min: {:016X}", acid_header.title_id_min); |
| 106 | LOG_DEBUG(Service_FS, "Title ID Max: %016" PRIX64, acid_header.title_id_max); | 105 | NGLOG_DEBUG(Service_FS, "Title ID Max: {:016X}", acid_header.title_id_max); |
| 107 | LOG_DEBUG(Service_FS, "Filesystem Access: %016" PRIX64 "\n", acid_file_access.permissions); | 106 | NGLOG_DEBUG(Service_FS, "Filesystem Access: {:016X}\n", acid_file_access.permissions); |
| 108 | 107 | ||
| 109 | // Begin ACI0 printing (actual perms, unsigned) | 108 | // Begin ACI0 printing (actual perms, unsigned) |
| 110 | LOG_DEBUG(Service_FS, "Magic: %.4s", aci_header.magic.data()); | 109 | NGLOG_DEBUG(Service_FS, "Magic: {:.4}", aci_header.magic.data()); |
| 111 | LOG_DEBUG(Service_FS, "Title ID: %016" PRIX64, aci_header.title_id); | 110 | NGLOG_DEBUG(Service_FS, "Title ID: {:016X}", aci_header.title_id); |
| 112 | LOG_DEBUG(Service_FS, "Filesystem Access: %016" PRIX64 "\n", aci_file_access.permissions); | 111 | NGLOG_DEBUG(Service_FS, "Filesystem Access: {:016X}\n", aci_file_access.permissions); |
| 113 | } | 112 | } |
| 114 | } // namespace FileSys | 113 | } // namespace FileSys |
diff --git a/src/core/file_sys/romfs_factory.cpp b/src/core/file_sys/romfs_factory.cpp index b21427948..dc7591aca 100644 --- a/src/core/file_sys/romfs_factory.cpp +++ b/src/core/file_sys/romfs_factory.cpp | |||
| @@ -14,7 +14,7 @@ namespace FileSys { | |||
| 14 | RomFS_Factory::RomFS_Factory(Loader::AppLoader& app_loader) { | 14 | RomFS_Factory::RomFS_Factory(Loader::AppLoader& app_loader) { |
| 15 | // Load the RomFS from the app | 15 | // Load the RomFS from the app |
| 16 | if (Loader::ResultStatus::Success != app_loader.ReadRomFS(romfs_file, data_offset, data_size)) { | 16 | if (Loader::ResultStatus::Success != app_loader.ReadRomFS(romfs_file, data_offset, data_size)) { |
| 17 | LOG_ERROR(Service_FS, "Unable to read RomFS!"); | 17 | NGLOG_ERROR(Service_FS, "Unable to read RomFS!"); |
| 18 | } | 18 | } |
| 19 | } | 19 | } |
| 20 | 20 | ||
| @@ -24,13 +24,13 @@ ResultVal<std::unique_ptr<FileSystemBackend>> RomFS_Factory::Open(const Path& pa | |||
| 24 | } | 24 | } |
| 25 | 25 | ||
| 26 | ResultCode RomFS_Factory::Format(const Path& path) { | 26 | ResultCode RomFS_Factory::Format(const Path& path) { |
| 27 | LOG_ERROR(Service_FS, "Unimplemented Format archive %s", GetName().c_str()); | 27 | NGLOG_ERROR(Service_FS, "Unimplemented Format archive {}", GetName()); |
| 28 | // TODO(bunnei): Find the right error code for this | 28 | // TODO(bunnei): Find the right error code for this |
| 29 | return ResultCode(-1); | 29 | return ResultCode(-1); |
| 30 | } | 30 | } |
| 31 | 31 | ||
| 32 | ResultVal<ArchiveFormatInfo> RomFS_Factory::GetFormatInfo(const Path& path) const { | 32 | ResultVal<ArchiveFormatInfo> RomFS_Factory::GetFormatInfo(const Path& path) const { |
| 33 | LOG_ERROR(Service_FS, "Unimplemented GetFormatInfo archive %s", GetName().c_str()); | 33 | NGLOG_ERROR(Service_FS, "Unimplemented GetFormatInfo archive {}", GetName()); |
| 34 | // TODO(bunnei): Find the right error code for this | 34 | // TODO(bunnei): Find the right error code for this |
| 35 | return ResultCode(-1); | 35 | return ResultCode(-1); |
| 36 | } | 36 | } |
diff --git a/src/core/file_sys/romfs_filesystem.cpp b/src/core/file_sys/romfs_filesystem.cpp index 3d77e2d5f..8e2bce687 100644 --- a/src/core/file_sys/romfs_filesystem.cpp +++ b/src/core/file_sys/romfs_filesystem.cpp | |||
| @@ -21,73 +21,72 @@ ResultVal<std::unique_ptr<StorageBackend>> RomFS_FileSystem::OpenFile(const std: | |||
| 21 | } | 21 | } |
| 22 | 22 | ||
| 23 | ResultCode RomFS_FileSystem::DeleteFile(const std::string& path) const { | 23 | ResultCode RomFS_FileSystem::DeleteFile(const std::string& path) const { |
| 24 | LOG_CRITICAL(Service_FS, "Attempted to delete a file from an ROMFS archive (%s).", | 24 | NGLOG_CRITICAL(Service_FS, "Attempted to delete a file from an ROMFS archive ({}).", GetName()); |
| 25 | GetName().c_str()); | ||
| 26 | // TODO(bunnei): Use correct error code | 25 | // TODO(bunnei): Use correct error code |
| 27 | return ResultCode(-1); | 26 | return ResultCode(-1); |
| 28 | } | 27 | } |
| 29 | 28 | ||
| 30 | ResultCode RomFS_FileSystem::RenameFile(const Path& src_path, const Path& dest_path) const { | 29 | ResultCode RomFS_FileSystem::RenameFile(const std::string& src_path, |
| 31 | LOG_CRITICAL(Service_FS, "Attempted to rename a file within an ROMFS archive (%s).", | 30 | const std::string& dest_path) const { |
| 32 | GetName().c_str()); | 31 | NGLOG_CRITICAL(Service_FS, "Attempted to rename a file within an ROMFS archive ({}).", |
| 32 | GetName()); | ||
| 33 | // TODO(wwylele): Use correct error code | 33 | // TODO(wwylele): Use correct error code |
| 34 | return ResultCode(-1); | 34 | return ResultCode(-1); |
| 35 | } | 35 | } |
| 36 | 36 | ||
| 37 | ResultCode RomFS_FileSystem::DeleteDirectory(const Path& path) const { | 37 | ResultCode RomFS_FileSystem::DeleteDirectory(const Path& path) const { |
| 38 | LOG_CRITICAL(Service_FS, "Attempted to delete a directory from an ROMFS archive (%s).", | 38 | NGLOG_CRITICAL(Service_FS, "Attempted to delete a directory from an ROMFS archive ({}).", |
| 39 | GetName().c_str()); | 39 | GetName()); |
| 40 | // TODO(wwylele): Use correct error code | 40 | // TODO(wwylele): Use correct error code |
| 41 | return ResultCode(-1); | 41 | return ResultCode(-1); |
| 42 | } | 42 | } |
| 43 | 43 | ||
| 44 | ResultCode RomFS_FileSystem::DeleteDirectoryRecursively(const Path& path) const { | 44 | ResultCode RomFS_FileSystem::DeleteDirectoryRecursively(const Path& path) const { |
| 45 | LOG_CRITICAL(Service_FS, "Attempted to delete a directory from an ROMFS archive (%s).", | 45 | NGLOG_CRITICAL(Service_FS, "Attempted to delete a directory from an ROMFS archive ({}).", |
| 46 | GetName().c_str()); | 46 | GetName()); |
| 47 | // TODO(wwylele): Use correct error code | 47 | // TODO(wwylele): Use correct error code |
| 48 | return ResultCode(-1); | 48 | return ResultCode(-1); |
| 49 | } | 49 | } |
| 50 | 50 | ||
| 51 | ResultCode RomFS_FileSystem::CreateFile(const std::string& path, u64 size) const { | 51 | ResultCode RomFS_FileSystem::CreateFile(const std::string& path, u64 size) const { |
| 52 | LOG_CRITICAL(Service_FS, "Attempted to create a file in an ROMFS archive (%s).", | 52 | NGLOG_CRITICAL(Service_FS, "Attempted to create a file in an ROMFS archive ({}).", GetName()); |
| 53 | GetName().c_str()); | ||
| 54 | // TODO(bunnei): Use correct error code | 53 | // TODO(bunnei): Use correct error code |
| 55 | return ResultCode(-1); | 54 | return ResultCode(-1); |
| 56 | } | 55 | } |
| 57 | 56 | ||
| 58 | ResultCode RomFS_FileSystem::CreateDirectory(const std::string& path) const { | 57 | ResultCode RomFS_FileSystem::CreateDirectory(const std::string& path) const { |
| 59 | LOG_CRITICAL(Service_FS, "Attempted to create a directory in an ROMFS archive (%s).", | 58 | NGLOG_CRITICAL(Service_FS, "Attempted to create a directory in an ROMFS archive ({}).", |
| 60 | GetName().c_str()); | 59 | GetName()); |
| 61 | // TODO(wwylele): Use correct error code | 60 | // TODO(wwylele): Use correct error code |
| 62 | return ResultCode(-1); | 61 | return ResultCode(-1); |
| 63 | } | 62 | } |
| 64 | 63 | ||
| 65 | ResultCode RomFS_FileSystem::RenameDirectory(const Path& src_path, const Path& dest_path) const { | 64 | ResultCode RomFS_FileSystem::RenameDirectory(const Path& src_path, const Path& dest_path) const { |
| 66 | LOG_CRITICAL(Service_FS, "Attempted to rename a file within an ROMFS archive (%s).", | 65 | NGLOG_CRITICAL(Service_FS, "Attempted to rename a file within an ROMFS archive ({}).", |
| 67 | GetName().c_str()); | 66 | GetName()); |
| 68 | // TODO(wwylele): Use correct error code | 67 | // TODO(wwylele): Use correct error code |
| 69 | return ResultCode(-1); | 68 | return ResultCode(-1); |
| 70 | } | 69 | } |
| 71 | 70 | ||
| 72 | ResultVal<std::unique_ptr<DirectoryBackend>> RomFS_FileSystem::OpenDirectory( | 71 | ResultVal<std::unique_ptr<DirectoryBackend>> RomFS_FileSystem::OpenDirectory( |
| 73 | const std::string& path) const { | 72 | const std::string& path) const { |
| 74 | LOG_WARNING(Service_FS, "Opening Directory in a ROMFS archive"); | 73 | NGLOG_WARNING(Service_FS, "Opening Directory in a ROMFS archive"); |
| 75 | return MakeResult<std::unique_ptr<DirectoryBackend>>(std::make_unique<ROMFSDirectory>()); | 74 | return MakeResult<std::unique_ptr<DirectoryBackend>>(std::make_unique<ROMFSDirectory>()); |
| 76 | } | 75 | } |
| 77 | 76 | ||
| 78 | u64 RomFS_FileSystem::GetFreeSpaceSize() const { | 77 | u64 RomFS_FileSystem::GetFreeSpaceSize() const { |
| 79 | LOG_WARNING(Service_FS, "Attempted to get the free space in an ROMFS archive"); | 78 | NGLOG_WARNING(Service_FS, "Attempted to get the free space in an ROMFS archive"); |
| 80 | return 0; | 79 | return 0; |
| 81 | } | 80 | } |
| 82 | 81 | ||
| 83 | ResultVal<FileSys::EntryType> RomFS_FileSystem::GetEntryType(const std::string& path) const { | 82 | ResultVal<FileSys::EntryType> RomFS_FileSystem::GetEntryType(const std::string& path) const { |
| 84 | LOG_CRITICAL(Service_FS, "Called within an ROMFS archive (path %s).", path.c_str()); | 83 | NGLOG_CRITICAL(Service_FS, "Called within an ROMFS archive (path {}).", path); |
| 85 | // TODO(wwylele): Use correct error code | 84 | // TODO(wwylele): Use correct error code |
| 86 | return ResultCode(-1); | 85 | return ResultCode(-1); |
| 87 | } | 86 | } |
| 88 | 87 | ||
| 89 | ResultVal<size_t> RomFS_Storage::Read(const u64 offset, const size_t length, u8* buffer) const { | 88 | ResultVal<size_t> RomFS_Storage::Read(const u64 offset, const size_t length, u8* buffer) const { |
| 90 | LOG_TRACE(Service_FS, "called offset=%llu, length=%zu", offset, length); | 89 | NGLOG_TRACE(Service_FS, "called offset={}, length={}", offset, length); |
| 91 | romfs_file->Seek(data_offset + offset, SEEK_SET); | 90 | romfs_file->Seek(data_offset + offset, SEEK_SET); |
| 92 | size_t read_length = (size_t)std::min((u64)length, data_size - offset); | 91 | size_t read_length = (size_t)std::min((u64)length, data_size - offset); |
| 93 | 92 | ||
| @@ -96,7 +95,7 @@ ResultVal<size_t> RomFS_Storage::Read(const u64 offset, const size_t length, u8* | |||
| 96 | 95 | ||
| 97 | ResultVal<size_t> RomFS_Storage::Write(const u64 offset, const size_t length, const bool flush, | 96 | ResultVal<size_t> RomFS_Storage::Write(const u64 offset, const size_t length, const bool flush, |
| 98 | const u8* buffer) const { | 97 | const u8* buffer) const { |
| 99 | LOG_ERROR(Service_FS, "Attempted to write to ROMFS file"); | 98 | NGLOG_ERROR(Service_FS, "Attempted to write to ROMFS file"); |
| 100 | // TODO(Subv): Find error code | 99 | // TODO(Subv): Find error code |
| 101 | return MakeResult<size_t>(0); | 100 | return MakeResult<size_t>(0); |
| 102 | } | 101 | } |
| @@ -106,7 +105,7 @@ u64 RomFS_Storage::GetSize() const { | |||
| 106 | } | 105 | } |
| 107 | 106 | ||
| 108 | bool RomFS_Storage::SetSize(const u64 size) const { | 107 | bool RomFS_Storage::SetSize(const u64 size) const { |
| 109 | LOG_ERROR(Service_FS, "Attempted to set the size of an ROMFS file"); | 108 | NGLOG_ERROR(Service_FS, "Attempted to set the size of an ROMFS file"); |
| 110 | return false; | 109 | return false; |
| 111 | } | 110 | } |
| 112 | 111 | ||
diff --git a/src/core/file_sys/romfs_filesystem.h b/src/core/file_sys/romfs_filesystem.h index 1b5cac409..ba9d85823 100644 --- a/src/core/file_sys/romfs_filesystem.h +++ b/src/core/file_sys/romfs_filesystem.h | |||
| @@ -32,7 +32,7 @@ public: | |||
| 32 | ResultVal<std::unique_ptr<StorageBackend>> OpenFile(const std::string& path, | 32 | ResultVal<std::unique_ptr<StorageBackend>> OpenFile(const std::string& path, |
| 33 | Mode mode) const override; | 33 | Mode mode) const override; |
| 34 | ResultCode DeleteFile(const std::string& path) const override; | 34 | ResultCode DeleteFile(const std::string& path) const override; |
| 35 | ResultCode RenameFile(const Path& src_path, const Path& dest_path) const override; | 35 | ResultCode RenameFile(const std::string& src_path, const std::string& dest_path) const override; |
| 36 | ResultCode DeleteDirectory(const Path& path) const override; | 36 | ResultCode DeleteDirectory(const Path& path) const override; |
| 37 | ResultCode DeleteDirectoryRecursively(const Path& path) const override; | 37 | ResultCode DeleteDirectoryRecursively(const Path& path) const override; |
| 38 | ResultCode CreateFile(const std::string& path, u64 size) const override; | 38 | ResultCode CreateFile(const std::string& path, u64 size) const override; |
diff --git a/src/core/file_sys/savedata_factory.cpp b/src/core/file_sys/savedata_factory.cpp index 14868fed2..c1be8fee4 100644 --- a/src/core/file_sys/savedata_factory.cpp +++ b/src/core/file_sys/savedata_factory.cpp | |||
| @@ -2,11 +2,9 @@ | |||
| 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 <cinttypes> | ||
| 6 | #include <memory> | 5 | #include <memory> |
| 7 | #include "common/common_types.h" | 6 | #include "common/common_types.h" |
| 8 | #include "common/logging/log.h" | 7 | #include "common/logging/log.h" |
| 9 | #include "common/string_util.h" | ||
| 10 | #include "core/core.h" | 8 | #include "core/core.h" |
| 11 | #include "core/file_sys/disk_filesystem.h" | 9 | #include "core/file_sys/disk_filesystem.h" |
| 12 | #include "core/file_sys/savedata_factory.h" | 10 | #include "core/file_sys/savedata_factory.h" |
| @@ -30,7 +28,7 @@ ResultVal<std::unique_ptr<FileSystemBackend>> SaveData_Factory::Open(const Path& | |||
| 30 | } | 28 | } |
| 31 | 29 | ||
| 32 | ResultCode SaveData_Factory::Format(const Path& path) { | 30 | ResultCode SaveData_Factory::Format(const Path& path) { |
| 33 | LOG_WARNING(Service_FS, "Format archive %s", GetName().c_str()); | 31 | NGLOG_WARNING(Service_FS, "Format archive {}", GetName()); |
| 34 | // Create the save data directory. | 32 | // Create the save data directory. |
| 35 | if (!FileUtil::CreateFullPath(GetFullPath())) { | 33 | if (!FileUtil::CreateFullPath(GetFullPath())) { |
| 36 | // TODO(Subv): Find the correct error code. | 34 | // TODO(Subv): Find the correct error code. |
| @@ -41,7 +39,7 @@ ResultCode SaveData_Factory::Format(const Path& path) { | |||
| 41 | } | 39 | } |
| 42 | 40 | ||
| 43 | ResultVal<ArchiveFormatInfo> SaveData_Factory::GetFormatInfo(const Path& path) const { | 41 | ResultVal<ArchiveFormatInfo> SaveData_Factory::GetFormatInfo(const Path& path) const { |
| 44 | LOG_ERROR(Service_FS, "Unimplemented GetFormatInfo archive %s", GetName().c_str()); | 42 | NGLOG_ERROR(Service_FS, "Unimplemented GetFormatInfo archive {}", GetName()); |
| 45 | // TODO(bunnei): Find the right error code for this | 43 | // TODO(bunnei): Find the right error code for this |
| 46 | return ResultCode(-1); | 44 | return ResultCode(-1); |
| 47 | } | 45 | } |
| @@ -50,8 +48,7 @@ std::string SaveData_Factory::GetFullPath() const { | |||
| 50 | u64 title_id = Core::CurrentProcess()->program_id; | 48 | u64 title_id = Core::CurrentProcess()->program_id; |
| 51 | // TODO(Subv): Somehow obtain this value. | 49 | // TODO(Subv): Somehow obtain this value. |
| 52 | u32 user = 0; | 50 | u32 user = 0; |
| 53 | return Common::StringFromFormat("%ssave/%016" PRIX64 "/%08X/", nand_directory.c_str(), title_id, | 51 | return fmt::format("{}save/{:016X}/{:08X}/", nand_directory, title_id, user); |
| 54 | user); | ||
| 55 | } | 52 | } |
| 56 | 53 | ||
| 57 | } // namespace FileSys | 54 | } // namespace FileSys |
diff --git a/src/core/file_sys/sdmc_factory.cpp b/src/core/file_sys/sdmc_factory.cpp index 00e80d2a7..59ac3e0be 100644 --- a/src/core/file_sys/sdmc_factory.cpp +++ b/src/core/file_sys/sdmc_factory.cpp | |||
| @@ -2,7 +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 | #include <cinttypes> | ||
| 6 | #include <memory> | 5 | #include <memory> |
| 7 | #include "common/common_types.h" | 6 | #include "common/common_types.h" |
| 8 | #include "common/logging/log.h" | 7 | #include "common/logging/log.h" |
| @@ -26,13 +25,13 @@ ResultVal<std::unique_ptr<FileSystemBackend>> SDMC_Factory::Open(const Path& pat | |||
| 26 | } | 25 | } |
| 27 | 26 | ||
| 28 | ResultCode SDMC_Factory::Format(const Path& path) { | 27 | ResultCode SDMC_Factory::Format(const Path& path) { |
| 29 | LOG_ERROR(Service_FS, "Unimplemented Format archive %s", GetName().c_str()); | 28 | NGLOG_ERROR(Service_FS, "Unimplemented Format archive {}", GetName()); |
| 30 | // TODO(Subv): Find the right error code for this | 29 | // TODO(Subv): Find the right error code for this |
| 31 | return ResultCode(-1); | 30 | return ResultCode(-1); |
| 32 | } | 31 | } |
| 33 | 32 | ||
| 34 | ResultVal<ArchiveFormatInfo> SDMC_Factory::GetFormatInfo(const Path& path) const { | 33 | ResultVal<ArchiveFormatInfo> SDMC_Factory::GetFormatInfo(const Path& path) const { |
| 35 | LOG_ERROR(Service_FS, "Unimplemented GetFormatInfo archive %s", GetName().c_str()); | 34 | NGLOG_ERROR(Service_FS, "Unimplemented GetFormatInfo archive {}", GetName()); |
| 36 | // TODO(bunnei): Find the right error code for this | 35 | // TODO(bunnei): Find the right error code for this |
| 37 | return ResultCode(-1); | 36 | return ResultCode(-1); |
| 38 | } | 37 | } |
diff --git a/src/core/gdbstub/gdbstub.cpp b/src/core/gdbstub/gdbstub.cpp index e4f337a0a..46606b992 100644 --- a/src/core/gdbstub/gdbstub.cpp +++ b/src/core/gdbstub/gdbstub.cpp | |||
| @@ -6,7 +6,6 @@ | |||
| 6 | 6 | ||
| 7 | #include <algorithm> | 7 | #include <algorithm> |
| 8 | #include <atomic> | 8 | #include <atomic> |
| 9 | #include <cinttypes> | ||
| 10 | #include <climits> | 9 | #include <climits> |
| 11 | #include <csignal> | 10 | #include <csignal> |
| 12 | #include <cstdarg> | 11 | #include <cstdarg> |
| @@ -180,7 +179,7 @@ static u8 HexCharToValue(u8 hex) { | |||
| 180 | return hex - 'A' + 0xA; | 179 | return hex - 'A' + 0xA; |
| 181 | } | 180 | } |
| 182 | 181 | ||
| 183 | LOG_ERROR(Debug_GDBStub, "Invalid nibble: %c (%02x)\n", hex, hex); | 182 | NGLOG_ERROR(Debug_GDBStub, "Invalid nibble: {} ({:02X})", hex, hex); |
| 184 | return 0; | 183 | return 0; |
| 185 | } | 184 | } |
| 186 | 185 | ||
| @@ -320,7 +319,7 @@ static u8 ReadByte() { | |||
| 320 | u8 c; | 319 | u8 c; |
| 321 | size_t received_size = recv(gdbserver_socket, reinterpret_cast<char*>(&c), 1, MSG_WAITALL); | 320 | size_t received_size = recv(gdbserver_socket, reinterpret_cast<char*>(&c), 1, MSG_WAITALL); |
| 322 | if (received_size != 1) { | 321 | if (received_size != 1) { |
| 323 | LOG_ERROR(Debug_GDBStub, "recv failed : %ld", received_size); | 322 | NGLOG_ERROR(Debug_GDBStub, "recv failed: {}", received_size); |
| 324 | Shutdown(); | 323 | Shutdown(); |
| 325 | } | 324 | } |
| 326 | 325 | ||
| @@ -361,9 +360,8 @@ static void RemoveBreakpoint(BreakpointType type, PAddr addr) { | |||
| 361 | 360 | ||
| 362 | auto bp = p.find(static_cast<u64>(addr)); | 361 | auto bp = p.find(static_cast<u64>(addr)); |
| 363 | if (bp != p.end()) { | 362 | if (bp != p.end()) { |
| 364 | LOG_DEBUG(Debug_GDBStub, | 363 | NGLOG_DEBUG(Debug_GDBStub, "gdb: removed a breakpoint: {:016X} bytes at {:016X} of type {}", |
| 365 | "gdb: removed a breakpoint: %016" PRIx64 " bytes at %016" PRIx64 " of type %d\n", | 364 | bp->second.len, bp->second.addr, static_cast<int>(type)); |
| 366 | bp->second.len, bp->second.addr, static_cast<int>(type)); | ||
| 367 | p.erase(static_cast<u64>(addr)); | 365 | p.erase(static_cast<u64>(addr)); |
| 368 | } | 366 | } |
| 369 | } | 367 | } |
| @@ -408,10 +406,10 @@ bool CheckBreakpoint(PAddr addr, BreakpointType type) { | |||
| 408 | } | 406 | } |
| 409 | 407 | ||
| 410 | if (bp->second.active && (addr >= bp->second.addr && addr < bp->second.addr + len)) { | 408 | if (bp->second.active && (addr >= bp->second.addr && addr < bp->second.addr + len)) { |
| 411 | LOG_DEBUG(Debug_GDBStub, | 409 | NGLOG_DEBUG(Debug_GDBStub, |
| 412 | "Found breakpoint type %d @ %016" PRIx64 ", range: %016" PRIx64 | 410 | "Found breakpoint type {} @ {:016X}, range: {:016X}" |
| 413 | " - %016" PRIx64 " (%" PRIx64 " bytes)\n", | 411 | " - {:016X} ({:X} bytes)", |
| 414 | static_cast<int>(type), addr, bp->second.addr, bp->second.addr + len, len); | 412 | static_cast<int>(type), addr, bp->second.addr, bp->second.addr + len, len); |
| 415 | return true; | 413 | return true; |
| 416 | } | 414 | } |
| 417 | } | 415 | } |
| @@ -427,7 +425,7 @@ bool CheckBreakpoint(PAddr addr, BreakpointType type) { | |||
| 427 | static void SendPacket(const char packet) { | 425 | static void SendPacket(const char packet) { |
| 428 | size_t sent_size = send(gdbserver_socket, &packet, 1, 0); | 426 | size_t sent_size = send(gdbserver_socket, &packet, 1, 0); |
| 429 | if (sent_size != 1) { | 427 | if (sent_size != 1) { |
| 430 | LOG_ERROR(Debug_GDBStub, "send failed"); | 428 | NGLOG_ERROR(Debug_GDBStub, "send failed"); |
| 431 | } | 429 | } |
| 432 | } | 430 | } |
| 433 | 431 | ||
| @@ -445,7 +443,7 @@ static void SendReply(const char* reply) { | |||
| 445 | 443 | ||
| 446 | command_length = static_cast<u32>(strlen(reply)); | 444 | command_length = static_cast<u32>(strlen(reply)); |
| 447 | if (command_length + 4 > sizeof(command_buffer)) { | 445 | if (command_length + 4 > sizeof(command_buffer)) { |
| 448 | LOG_ERROR(Debug_GDBStub, "command_buffer overflow in SendReply"); | 446 | NGLOG_ERROR(Debug_GDBStub, "command_buffer overflow in SendReply"); |
| 449 | return; | 447 | return; |
| 450 | } | 448 | } |
| 451 | 449 | ||
| @@ -462,7 +460,7 @@ static void SendReply(const char* reply) { | |||
| 462 | while (left > 0) { | 460 | while (left > 0) { |
| 463 | int sent_size = send(gdbserver_socket, reinterpret_cast<char*>(ptr), left, 0); | 461 | int sent_size = send(gdbserver_socket, reinterpret_cast<char*>(ptr), left, 0); |
| 464 | if (sent_size < 0) { | 462 | if (sent_size < 0) { |
| 465 | LOG_ERROR(Debug_GDBStub, "gdb: send failed"); | 463 | NGLOG_ERROR(Debug_GDBStub, "gdb: send failed"); |
| 466 | return Shutdown(); | 464 | return Shutdown(); |
| 467 | } | 465 | } |
| 468 | 466 | ||
| @@ -473,7 +471,7 @@ static void SendReply(const char* reply) { | |||
| 473 | 471 | ||
| 474 | /// Handle query command from gdb client. | 472 | /// Handle query command from gdb client. |
| 475 | static void HandleQuery() { | 473 | static void HandleQuery() { |
| 476 | LOG_DEBUG(Debug_GDBStub, "gdb: query '%s'\n", command_buffer + 1); | 474 | NGLOG_DEBUG(Debug_GDBStub, "gdb: query '{}'", command_buffer + 1); |
| 477 | 475 | ||
| 478 | const char* query = reinterpret_cast<const char*>(command_buffer + 1); | 476 | const char* query = reinterpret_cast<const char*>(command_buffer + 1); |
| 479 | 477 | ||
| @@ -512,8 +510,8 @@ static void SendSignal(u32 signal) { | |||
| 512 | 510 | ||
| 513 | latest_signal = signal; | 511 | latest_signal = signal; |
| 514 | 512 | ||
| 515 | std::string buffer = Common::StringFromFormat("T%02x", latest_signal); | 513 | std::string buffer = fmt::format("T{:02x}", latest_signal); |
| 516 | LOG_DEBUG(Debug_GDBStub, "Response: %s", buffer.c_str()); | 514 | NGLOG_DEBUG(Debug_GDBStub, "Response: {}", buffer); |
| 517 | SendReply(buffer.c_str()); | 515 | SendReply(buffer.c_str()); |
| 518 | } | 516 | } |
| 519 | 517 | ||
| @@ -527,18 +525,18 @@ static void ReadCommand() { | |||
| 527 | // ignore ack | 525 | // ignore ack |
| 528 | return; | 526 | return; |
| 529 | } else if (c == 0x03) { | 527 | } else if (c == 0x03) { |
| 530 | LOG_INFO(Debug_GDBStub, "gdb: found break command\n"); | 528 | NGLOG_INFO(Debug_GDBStub, "gdb: found break command"); |
| 531 | halt_loop = true; | 529 | halt_loop = true; |
| 532 | SendSignal(SIGTRAP); | 530 | SendSignal(SIGTRAP); |
| 533 | return; | 531 | return; |
| 534 | } else if (c != GDB_STUB_START) { | 532 | } else if (c != GDB_STUB_START) { |
| 535 | LOG_DEBUG(Debug_GDBStub, "gdb: read invalid byte %02x\n", c); | 533 | NGLOG_DEBUG(Debug_GDBStub, "gdb: read invalid byte {:02X}", c); |
| 536 | return; | 534 | return; |
| 537 | } | 535 | } |
| 538 | 536 | ||
| 539 | while ((c = ReadByte()) != GDB_STUB_END) { | 537 | while ((c = ReadByte()) != GDB_STUB_END) { |
| 540 | if (command_length >= sizeof(command_buffer)) { | 538 | if (command_length >= sizeof(command_buffer)) { |
| 541 | LOG_ERROR(Debug_GDBStub, "gdb: command_buffer overflow\n"); | 539 | NGLOG_ERROR(Debug_GDBStub, "gdb: command_buffer overflow"); |
| 542 | SendPacket(GDB_STUB_NACK); | 540 | SendPacket(GDB_STUB_NACK); |
| 543 | return; | 541 | return; |
| 544 | } | 542 | } |
| @@ -551,9 +549,10 @@ static void ReadCommand() { | |||
| 551 | u8 checksum_calculated = CalculateChecksum(command_buffer, command_length); | 549 | u8 checksum_calculated = CalculateChecksum(command_buffer, command_length); |
| 552 | 550 | ||
| 553 | if (checksum_received != checksum_calculated) { | 551 | if (checksum_received != checksum_calculated) { |
| 554 | LOG_ERROR(Debug_GDBStub, | 552 | NGLOG_ERROR( |
| 555 | "gdb: invalid checksum: calculated %02x and read %02x for $%s# (length: %d)\n", | 553 | Debug_GDBStub, |
| 556 | checksum_calculated, checksum_received, command_buffer, command_length); | 554 | "gdb: invalid checksum: calculated {:02X} and read {:02X} for ${}# (length: {})", |
| 555 | checksum_calculated, checksum_received, command_buffer, command_length); | ||
| 557 | 556 | ||
| 558 | command_length = 0; | 557 | command_length = 0; |
| 559 | 558 | ||
| @@ -580,7 +579,7 @@ static bool IsDataAvailable() { | |||
| 580 | t.tv_usec = 0; | 579 | t.tv_usec = 0; |
| 581 | 580 | ||
| 582 | if (select(gdbserver_socket + 1, &fd_socket, nullptr, nullptr, &t) < 0) { | 581 | if (select(gdbserver_socket + 1, &fd_socket, nullptr, nullptr, &t) < 0) { |
| 583 | LOG_ERROR(Debug_GDBStub, "select failed"); | 582 | NGLOG_ERROR(Debug_GDBStub, "select failed"); |
| 584 | return false; | 583 | return false; |
| 585 | } | 584 | } |
| 586 | 585 | ||
| @@ -693,7 +692,7 @@ static void ReadMemory() { | |||
| 693 | u64 len = | 692 | u64 len = |
| 694 | HexToLong(start_offset, static_cast<u64>((command_buffer + command_length) - start_offset)); | 693 | HexToLong(start_offset, static_cast<u64>((command_buffer + command_length) - start_offset)); |
| 695 | 694 | ||
| 696 | LOG_DEBUG(Debug_GDBStub, "gdb: addr: %016lx len: %016lx\n", addr, len); | 695 | NGLOG_DEBUG(Debug_GDBStub, "gdb: addr: {:016X} len: {:016X}", addr, len); |
| 697 | 696 | ||
| 698 | if (len * 2 > sizeof(reply)) { | 697 | if (len * 2 > sizeof(reply)) { |
| 699 | SendReply("E01"); | 698 | SendReply("E01"); |
| @@ -781,8 +780,8 @@ static bool CommitBreakpoint(BreakpointType type, PAddr addr, u64 len) { | |||
| 781 | breakpoint.len = len; | 780 | breakpoint.len = len; |
| 782 | p.insert({addr, breakpoint}); | 781 | p.insert({addr, breakpoint}); |
| 783 | 782 | ||
| 784 | LOG_DEBUG(Debug_GDBStub, "gdb: added %d breakpoint: %016" PRIx64 " bytes at %016" PRIx64 "\n", | 783 | NGLOG_DEBUG(Debug_GDBStub, "gdb: added {} breakpoint: {:016X} bytes at {:016X}", |
| 785 | static_cast<int>(type), breakpoint.len, breakpoint.addr); | 784 | static_cast<int>(type), breakpoint.len, breakpoint.addr); |
| 786 | 785 | ||
| 787 | return true; | 786 | return true; |
| 788 | } | 787 | } |
| @@ -889,7 +888,7 @@ void HandlePacket() { | |||
| 889 | return; | 888 | return; |
| 890 | } | 889 | } |
| 891 | 890 | ||
| 892 | LOG_DEBUG(Debug_GDBStub, "Packet: %s", command_buffer); | 891 | NGLOG_DEBUG(Debug_GDBStub, "Packet: {}", command_buffer); |
| 893 | 892 | ||
| 894 | switch (command_buffer[0]) { | 893 | switch (command_buffer[0]) { |
| 895 | case 'q': | 894 | case 'q': |
| @@ -903,7 +902,7 @@ void HandlePacket() { | |||
| 903 | break; | 902 | break; |
| 904 | case 'k': | 903 | case 'k': |
| 905 | Shutdown(); | 904 | Shutdown(); |
| 906 | LOG_INFO(Debug_GDBStub, "killed by gdb"); | 905 | NGLOG_INFO(Debug_GDBStub, "killed by gdb"); |
| 907 | return; | 906 | return; |
| 908 | case 'g': | 907 | case 'g': |
| 909 | ReadRegisters(); | 908 | ReadRegisters(); |
| @@ -982,7 +981,7 @@ static void Init(u16 port) { | |||
| 982 | breakpoints_write.clear(); | 981 | breakpoints_write.clear(); |
| 983 | 982 | ||
| 984 | // Start gdb server | 983 | // Start gdb server |
| 985 | LOG_INFO(Debug_GDBStub, "Starting GDB server on port %d...", port); | 984 | NGLOG_INFO(Debug_GDBStub, "Starting GDB server on port {}...", port); |
| 986 | 985 | ||
| 987 | sockaddr_in saddr_server = {}; | 986 | sockaddr_in saddr_server = {}; |
| 988 | saddr_server.sin_family = AF_INET; | 987 | saddr_server.sin_family = AF_INET; |
| @@ -995,28 +994,28 @@ static void Init(u16 port) { | |||
| 995 | 994 | ||
| 996 | int tmpsock = static_cast<int>(socket(PF_INET, SOCK_STREAM, 0)); | 995 | int tmpsock = static_cast<int>(socket(PF_INET, SOCK_STREAM, 0)); |
| 997 | if (tmpsock == -1) { | 996 | if (tmpsock == -1) { |
| 998 | LOG_ERROR(Debug_GDBStub, "Failed to create gdb socket"); | 997 | NGLOG_ERROR(Debug_GDBStub, "Failed to create gdb socket"); |
| 999 | } | 998 | } |
| 1000 | 999 | ||
| 1001 | // Set socket to SO_REUSEADDR so it can always bind on the same port | 1000 | // Set socket to SO_REUSEADDR so it can always bind on the same port |
| 1002 | int reuse_enabled = 1; | 1001 | int reuse_enabled = 1; |
| 1003 | if (setsockopt(tmpsock, SOL_SOCKET, SO_REUSEADDR, (const char*)&reuse_enabled, | 1002 | if (setsockopt(tmpsock, SOL_SOCKET, SO_REUSEADDR, (const char*)&reuse_enabled, |
| 1004 | sizeof(reuse_enabled)) < 0) { | 1003 | sizeof(reuse_enabled)) < 0) { |
| 1005 | LOG_ERROR(Debug_GDBStub, "Failed to set gdb socket option"); | 1004 | NGLOG_ERROR(Debug_GDBStub, "Failed to set gdb socket option"); |
| 1006 | } | 1005 | } |
| 1007 | 1006 | ||
| 1008 | const sockaddr* server_addr = reinterpret_cast<const sockaddr*>(&saddr_server); | 1007 | const sockaddr* server_addr = reinterpret_cast<const sockaddr*>(&saddr_server); |
| 1009 | socklen_t server_addrlen = sizeof(saddr_server); | 1008 | socklen_t server_addrlen = sizeof(saddr_server); |
| 1010 | if (bind(tmpsock, server_addr, server_addrlen) < 0) { | 1009 | if (bind(tmpsock, server_addr, server_addrlen) < 0) { |
| 1011 | LOG_ERROR(Debug_GDBStub, "Failed to bind gdb socket"); | 1010 | NGLOG_ERROR(Debug_GDBStub, "Failed to bind gdb socket"); |
| 1012 | } | 1011 | } |
| 1013 | 1012 | ||
| 1014 | if (listen(tmpsock, 1) < 0) { | 1013 | if (listen(tmpsock, 1) < 0) { |
| 1015 | LOG_ERROR(Debug_GDBStub, "Failed to listen to gdb socket"); | 1014 | NGLOG_ERROR(Debug_GDBStub, "Failed to listen to gdb socket"); |
| 1016 | } | 1015 | } |
| 1017 | 1016 | ||
| 1018 | // Wait for gdb to connect | 1017 | // Wait for gdb to connect |
| 1019 | LOG_INFO(Debug_GDBStub, "Waiting for gdb to connect...\n"); | 1018 | NGLOG_INFO(Debug_GDBStub, "Waiting for gdb to connect..."); |
| 1020 | sockaddr_in saddr_client; | 1019 | sockaddr_in saddr_client; |
| 1021 | sockaddr* client_addr = reinterpret_cast<sockaddr*>(&saddr_client); | 1020 | sockaddr* client_addr = reinterpret_cast<sockaddr*>(&saddr_client); |
| 1022 | socklen_t client_addrlen = sizeof(saddr_client); | 1021 | socklen_t client_addrlen = sizeof(saddr_client); |
| @@ -1027,9 +1026,9 @@ static void Init(u16 port) { | |||
| 1027 | halt_loop = false; | 1026 | halt_loop = false; |
| 1028 | step_loop = false; | 1027 | step_loop = false; |
| 1029 | 1028 | ||
| 1030 | LOG_ERROR(Debug_GDBStub, "Failed to accept gdb client"); | 1029 | NGLOG_ERROR(Debug_GDBStub, "Failed to accept gdb client"); |
| 1031 | } else { | 1030 | } else { |
| 1032 | LOG_INFO(Debug_GDBStub, "Client connected.\n"); | 1031 | NGLOG_INFO(Debug_GDBStub, "Client connected."); |
| 1033 | saddr_client.sin_addr.s_addr = ntohl(saddr_client.sin_addr.s_addr); | 1032 | saddr_client.sin_addr.s_addr = ntohl(saddr_client.sin_addr.s_addr); |
| 1034 | } | 1033 | } |
| 1035 | 1034 | ||
| @@ -1048,7 +1047,7 @@ void Shutdown() { | |||
| 1048 | return; | 1047 | return; |
| 1049 | } | 1048 | } |
| 1050 | 1049 | ||
| 1051 | LOG_INFO(Debug_GDBStub, "Stopping GDB ..."); | 1050 | NGLOG_INFO(Debug_GDBStub, "Stopping GDB ..."); |
| 1052 | if (gdbserver_socket != -1) { | 1051 | if (gdbserver_socket != -1) { |
| 1053 | shutdown(gdbserver_socket, SHUT_RDWR); | 1052 | shutdown(gdbserver_socket, SHUT_RDWR); |
| 1054 | gdbserver_socket = -1; | 1053 | gdbserver_socket = -1; |
| @@ -1058,7 +1057,7 @@ void Shutdown() { | |||
| 1058 | WSACleanup(); | 1057 | WSACleanup(); |
| 1059 | #endif | 1058 | #endif |
| 1060 | 1059 | ||
| 1061 | LOG_INFO(Debug_GDBStub, "GDB stopped."); | 1060 | NGLOG_INFO(Debug_GDBStub, "GDB stopped."); |
| 1062 | } | 1061 | } |
| 1063 | 1062 | ||
| 1064 | bool IsServerEnabled() { | 1063 | bool IsServerEnabled() { |
diff --git a/src/core/hle/kernel/condition_variable.cpp b/src/core/hle/kernel/condition_variable.cpp deleted file mode 100644 index a786d7f74..000000000 --- a/src/core/hle/kernel/condition_variable.cpp +++ /dev/null | |||
| @@ -1,64 +0,0 @@ | |||
| 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 "common/assert.h" | ||
| 6 | #include "core/hle/kernel/condition_variable.h" | ||
| 7 | #include "core/hle/kernel/errors.h" | ||
| 8 | #include "core/hle/kernel/kernel.h" | ||
| 9 | #include "core/hle/kernel/object_address_table.h" | ||
| 10 | #include "core/hle/kernel/thread.h" | ||
| 11 | |||
| 12 | namespace Kernel { | ||
| 13 | |||
| 14 | ConditionVariable::ConditionVariable() {} | ||
| 15 | ConditionVariable::~ConditionVariable() {} | ||
| 16 | |||
| 17 | ResultVal<SharedPtr<ConditionVariable>> ConditionVariable::Create(VAddr guest_addr, | ||
| 18 | std::string name) { | ||
| 19 | SharedPtr<ConditionVariable> condition_variable(new ConditionVariable); | ||
| 20 | |||
| 21 | condition_variable->name = std::move(name); | ||
| 22 | condition_variable->guest_addr = guest_addr; | ||
| 23 | condition_variable->mutex_addr = 0; | ||
| 24 | |||
| 25 | // Condition variables are referenced by guest address, so track this in the kernel | ||
| 26 | g_object_address_table.Insert(guest_addr, condition_variable); | ||
| 27 | |||
| 28 | return MakeResult<SharedPtr<ConditionVariable>>(std::move(condition_variable)); | ||
| 29 | } | ||
| 30 | |||
| 31 | bool ConditionVariable::ShouldWait(Thread* thread) const { | ||
| 32 | return GetAvailableCount() <= 0; | ||
| 33 | } | ||
| 34 | |||
| 35 | void ConditionVariable::Acquire(Thread* thread) { | ||
| 36 | if (GetAvailableCount() <= 0) | ||
| 37 | return; | ||
| 38 | |||
| 39 | SetAvailableCount(GetAvailableCount() - 1); | ||
| 40 | } | ||
| 41 | |||
| 42 | ResultCode ConditionVariable::Release(s32 target) { | ||
| 43 | if (target == -1) { | ||
| 44 | // When -1, wake up all waiting threads | ||
| 45 | SetAvailableCount(static_cast<s32>(GetWaitingThreads().size())); | ||
| 46 | WakeupAllWaitingThreads(); | ||
| 47 | } else { | ||
| 48 | // Otherwise, wake up just a single thread | ||
| 49 | SetAvailableCount(target); | ||
| 50 | WakeupWaitingThread(GetHighestPriorityReadyThread()); | ||
| 51 | } | ||
| 52 | |||
| 53 | return RESULT_SUCCESS; | ||
| 54 | } | ||
| 55 | |||
| 56 | s32 ConditionVariable::GetAvailableCount() const { | ||
| 57 | return Memory::Read32(guest_addr); | ||
| 58 | } | ||
| 59 | |||
| 60 | void ConditionVariable::SetAvailableCount(s32 value) const { | ||
| 61 | Memory::Write32(guest_addr, value); | ||
| 62 | } | ||
| 63 | |||
| 64 | } // namespace Kernel | ||
diff --git a/src/core/hle/kernel/condition_variable.h b/src/core/hle/kernel/condition_variable.h deleted file mode 100644 index 1c9f06769..000000000 --- a/src/core/hle/kernel/condition_variable.h +++ /dev/null | |||
| @@ -1,63 +0,0 @@ | |||
| 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 | #include <string> | ||
| 8 | #include <queue> | ||
| 9 | #include "common/common_types.h" | ||
| 10 | #include "core/hle/kernel/kernel.h" | ||
| 11 | #include "core/hle/kernel/wait_object.h" | ||
| 12 | #include "core/hle/result.h" | ||
| 13 | |||
| 14 | namespace Kernel { | ||
| 15 | |||
| 16 | class ConditionVariable final : public WaitObject { | ||
| 17 | public: | ||
| 18 | /** | ||
| 19 | * Creates a condition variable. | ||
| 20 | * @param guest_addr Address of the object tracking the condition variable in guest memory. If | ||
| 21 | * specified, this condition variable will update the guest object when its state changes. | ||
| 22 | * @param name Optional name of condition variable. | ||
| 23 | * @return The created condition variable. | ||
| 24 | */ | ||
| 25 | static ResultVal<SharedPtr<ConditionVariable>> Create(VAddr guest_addr, | ||
| 26 | std::string name = "Unknown"); | ||
| 27 | |||
| 28 | std::string GetTypeName() const override { | ||
| 29 | return "ConditionVariable"; | ||
| 30 | } | ||
| 31 | std::string GetName() const override { | ||
| 32 | return name; | ||
| 33 | } | ||
| 34 | |||
| 35 | static const HandleType HANDLE_TYPE = HandleType::ConditionVariable; | ||
| 36 | HandleType GetHandleType() const override { | ||
| 37 | return HANDLE_TYPE; | ||
| 38 | } | ||
| 39 | |||
| 40 | s32 GetAvailableCount() const; | ||
| 41 | void SetAvailableCount(s32 value) const; | ||
| 42 | |||
| 43 | std::string name; ///< Name of condition variable (optional) | ||
| 44 | VAddr guest_addr; ///< Address of the guest condition variable value | ||
| 45 | VAddr mutex_addr; ///< (optional) Address of guest mutex value associated with this condition | ||
| 46 | ///< variable, used for implementing events | ||
| 47 | |||
| 48 | bool ShouldWait(Thread* thread) const override; | ||
| 49 | void Acquire(Thread* thread) override; | ||
| 50 | |||
| 51 | /** | ||
| 52 | * Releases a slot from a condition variable. | ||
| 53 | * @param target The number of threads to wakeup, -1 is all. | ||
| 54 | * @return ResultCode indicating if the operation succeeded. | ||
| 55 | */ | ||
| 56 | ResultCode Release(s32 target); | ||
| 57 | |||
| 58 | private: | ||
| 59 | ConditionVariable(); | ||
| 60 | ~ConditionVariable() override; | ||
| 61 | }; | ||
| 62 | |||
| 63 | } // namespace Kernel | ||
diff --git a/src/core/hle/kernel/errors.h b/src/core/hle/kernel/errors.h index 29d8dfdaa..5be20c878 100644 --- a/src/core/hle/kernel/errors.h +++ b/src/core/hle/kernel/errors.h | |||
| @@ -20,6 +20,7 @@ enum { | |||
| 20 | MaxConnectionsReached = 52, | 20 | MaxConnectionsReached = 52, |
| 21 | 21 | ||
| 22 | // Confirmed Switch OS error codes | 22 | // Confirmed Switch OS error codes |
| 23 | MisalignedAddress = 102, | ||
| 23 | InvalidHandle = 114, | 24 | InvalidHandle = 114, |
| 24 | Timeout = 117, | 25 | Timeout = 117, |
| 25 | SynchronizationCanceled = 118, | 26 | SynchronizationCanceled = 118, |
diff --git a/src/core/hle/kernel/handle_table.cpp b/src/core/hle/kernel/handle_table.cpp index 822449cd5..f7a9920d8 100644 --- a/src/core/hle/kernel/handle_table.cpp +++ b/src/core/hle/kernel/handle_table.cpp | |||
| @@ -26,7 +26,7 @@ ResultVal<Handle> HandleTable::Create(SharedPtr<Object> obj) { | |||
| 26 | 26 | ||
| 27 | u16 slot = next_free_slot; | 27 | u16 slot = next_free_slot; |
| 28 | if (slot >= generations.size()) { | 28 | if (slot >= generations.size()) { |
| 29 | LOG_ERROR(Kernel, "Unable to allocate Handle, too many slots in use."); | 29 | NGLOG_ERROR(Kernel, "Unable to allocate Handle, too many slots in use."); |
| 30 | return ERR_OUT_OF_HANDLES; | 30 | return ERR_OUT_OF_HANDLES; |
| 31 | } | 31 | } |
| 32 | next_free_slot = generations[slot]; | 32 | next_free_slot = generations[slot]; |
| @@ -48,7 +48,7 @@ ResultVal<Handle> HandleTable::Create(SharedPtr<Object> obj) { | |||
| 48 | ResultVal<Handle> HandleTable::Duplicate(Handle handle) { | 48 | ResultVal<Handle> HandleTable::Duplicate(Handle handle) { |
| 49 | SharedPtr<Object> object = GetGeneric(handle); | 49 | SharedPtr<Object> object = GetGeneric(handle); |
| 50 | if (object == nullptr) { | 50 | if (object == nullptr) { |
| 51 | LOG_ERROR(Kernel, "Tried to duplicate invalid handle: %08X", handle); | 51 | NGLOG_ERROR(Kernel, "Tried to duplicate invalid handle: {:08X}", handle); |
| 52 | return ERR_INVALID_HANDLE; | 52 | return ERR_INVALID_HANDLE; |
| 53 | } | 53 | } |
| 54 | return Create(std::move(object)); | 54 | return Create(std::move(object)); |
diff --git a/src/core/hle/kernel/hle_ipc.cpp b/src/core/hle/kernel/hle_ipc.cpp index bef4f15f5..aa6ca1026 100644 --- a/src/core/hle/kernel/hle_ipc.cpp +++ b/src/core/hle/kernel/hle_ipc.cpp | |||
| @@ -118,7 +118,7 @@ void HLERequestContext::ParseCommandBuffer(u32_le* src_cmdbuf, bool incoming) { | |||
| 118 | std::make_shared<IPC::DomainMessageHeader>(rp.PopRaw<IPC::DomainMessageHeader>()); | 118 | std::make_shared<IPC::DomainMessageHeader>(rp.PopRaw<IPC::DomainMessageHeader>()); |
| 119 | } else { | 119 | } else { |
| 120 | if (Session()->IsDomain()) | 120 | if (Session()->IsDomain()) |
| 121 | LOG_WARNING(IPC, "Domain request has no DomainMessageHeader!"); | 121 | NGLOG_WARNING(IPC, "Domain request has no DomainMessageHeader!"); |
| 122 | } | 122 | } |
| 123 | } | 123 | } |
| 124 | 124 | ||
| @@ -270,7 +270,8 @@ size_t HLERequestContext::WriteBuffer(const void* buffer, size_t size) const { | |||
| 270 | const bool is_buffer_b{BufferDescriptorB().size() && BufferDescriptorB()[0].Size()}; | 270 | const bool is_buffer_b{BufferDescriptorB().size() && BufferDescriptorB()[0].Size()}; |
| 271 | const size_t buffer_size{GetWriteBufferSize()}; | 271 | const size_t buffer_size{GetWriteBufferSize()}; |
| 272 | if (size > buffer_size) { | 272 | if (size > buffer_size) { |
| 273 | LOG_CRITICAL(Core, "size (%016zx) is greater than buffer_size (%016zx)", size, buffer_size); | 273 | NGLOG_CRITICAL(Core, "size ({:016X}) is greater than buffer_size ({:016X})", size, |
| 274 | buffer_size); | ||
| 274 | size = buffer_size; // TODO(bunnei): This needs to be HW tested | 275 | size = buffer_size; // TODO(bunnei): This needs to be HW tested |
| 275 | } | 276 | } |
| 276 | 277 | ||
diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h index 053bf4e17..402ae900f 100644 --- a/src/core/hle/kernel/kernel.h +++ b/src/core/hle/kernel/kernel.h | |||
| @@ -18,12 +18,10 @@ using Handle = u32; | |||
| 18 | enum class HandleType : u32 { | 18 | enum class HandleType : u32 { |
| 19 | Unknown, | 19 | Unknown, |
| 20 | Event, | 20 | Event, |
| 21 | Mutex, | ||
| 22 | SharedMemory, | 21 | SharedMemory, |
| 23 | Thread, | 22 | Thread, |
| 24 | Process, | 23 | Process, |
| 25 | AddressArbiter, | 24 | AddressArbiter, |
| 26 | ConditionVariable, | ||
| 27 | Timer, | 25 | Timer, |
| 28 | ResourceLimit, | 26 | ResourceLimit, |
| 29 | CodeSet, | 27 | CodeSet, |
| @@ -63,9 +61,7 @@ public: | |||
| 63 | bool IsWaitable() const { | 61 | bool IsWaitable() const { |
| 64 | switch (GetHandleType()) { | 62 | switch (GetHandleType()) { |
| 65 | case HandleType::Event: | 63 | case HandleType::Event: |
| 66 | case HandleType::Mutex: | ||
| 67 | case HandleType::Thread: | 64 | case HandleType::Thread: |
| 68 | case HandleType::ConditionVariable: | ||
| 69 | case HandleType::Timer: | 65 | case HandleType::Timer: |
| 70 | case HandleType::ServerPort: | 66 | case HandleType::ServerPort: |
| 71 | case HandleType::ServerSession: | 67 | case HandleType::ServerSession: |
diff --git a/src/core/hle/kernel/mutex.cpp b/src/core/hle/kernel/mutex.cpp index 0b9dc700c..63733ad79 100644 --- a/src/core/hle/kernel/mutex.cpp +++ b/src/core/hle/kernel/mutex.cpp | |||
| @@ -7,6 +7,7 @@ | |||
| 7 | #include <boost/range/algorithm_ext/erase.hpp> | 7 | #include <boost/range/algorithm_ext/erase.hpp> |
| 8 | #include "common/assert.h" | 8 | #include "common/assert.h" |
| 9 | #include "core/core.h" | 9 | #include "core/core.h" |
| 10 | #include "core/hle/kernel/errors.h" | ||
| 10 | #include "core/hle/kernel/handle_table.h" | 11 | #include "core/hle/kernel/handle_table.h" |
| 11 | #include "core/hle/kernel/kernel.h" | 12 | #include "core/hle/kernel/kernel.h" |
| 12 | #include "core/hle/kernel/mutex.h" | 13 | #include "core/hle/kernel/mutex.h" |
| @@ -15,124 +16,120 @@ | |||
| 15 | 16 | ||
| 16 | namespace Kernel { | 17 | namespace Kernel { |
| 17 | 18 | ||
| 18 | void ReleaseThreadMutexes(Thread* thread) { | 19 | /// Returns the number of threads that are waiting for a mutex, and the highest priority one among |
| 19 | for (auto& mtx : thread->held_mutexes) { | 20 | /// those. |
| 20 | mtx->SetHasWaiters(false); | 21 | static std::pair<SharedPtr<Thread>, u32> GetHighestPriorityMutexWaitingThread( |
| 21 | mtx->SetHoldingThread(nullptr); | 22 | SharedPtr<Thread> current_thread, VAddr mutex_addr) { |
| 22 | mtx->WakeupAllWaitingThreads(); | ||
| 23 | } | ||
| 24 | thread->held_mutexes.clear(); | ||
| 25 | } | ||
| 26 | 23 | ||
| 27 | Mutex::Mutex() {} | 24 | SharedPtr<Thread> highest_priority_thread; |
| 28 | Mutex::~Mutex() {} | 25 | u32 num_waiters = 0; |
| 29 | 26 | ||
| 30 | SharedPtr<Mutex> Mutex::Create(SharedPtr<Kernel::Thread> holding_thread, VAddr guest_addr, | 27 | for (auto& thread : current_thread->wait_mutex_threads) { |
| 31 | std::string name) { | 28 | if (thread->mutex_wait_address != mutex_addr) |
| 32 | SharedPtr<Mutex> mutex(new Mutex); | 29 | continue; |
| 33 | 30 | ||
| 34 | mutex->guest_addr = guest_addr; | 31 | ASSERT(thread->status == THREADSTATUS_WAIT_MUTEX); |
| 35 | mutex->name = std::move(name); | ||
| 36 | 32 | ||
| 37 | // If mutex was initialized with a holding thread, acquire it by the holding thread | 33 | ++num_waiters; |
| 38 | if (holding_thread) { | 34 | if (highest_priority_thread == nullptr || |
| 39 | mutex->Acquire(holding_thread.get()); | 35 | thread->GetPriority() < highest_priority_thread->GetPriority()) { |
| 36 | highest_priority_thread = thread; | ||
| 37 | } | ||
| 40 | } | 38 | } |
| 41 | 39 | ||
| 42 | // Mutexes are referenced by guest address, so track this in the kernel | 40 | return {highest_priority_thread, num_waiters}; |
| 43 | g_object_address_table.Insert(guest_addr, mutex); | ||
| 44 | |||
| 45 | return mutex; | ||
| 46 | } | 41 | } |
| 47 | 42 | ||
| 48 | bool Mutex::ShouldWait(Thread* thread) const { | 43 | /// Update the mutex owner field of all threads waiting on the mutex to point to the new owner. |
| 49 | auto holding_thread = GetHoldingThread(); | 44 | static void TransferMutexOwnership(VAddr mutex_addr, SharedPtr<Thread> current_thread, |
| 50 | return holding_thread != nullptr && thread != holding_thread; | 45 | SharedPtr<Thread> new_owner) { |
| 46 | auto threads = current_thread->wait_mutex_threads; | ||
| 47 | for (auto& thread : threads) { | ||
| 48 | if (thread->mutex_wait_address != mutex_addr) | ||
| 49 | continue; | ||
| 50 | |||
| 51 | ASSERT(thread->lock_owner == current_thread); | ||
| 52 | current_thread->RemoveMutexWaiter(thread); | ||
| 53 | if (new_owner != thread) | ||
| 54 | new_owner->AddMutexWaiter(thread); | ||
| 55 | } | ||
| 51 | } | 56 | } |
| 52 | 57 | ||
| 53 | void Mutex::Acquire(Thread* thread) { | 58 | ResultCode Mutex::TryAcquire(VAddr address, Handle holding_thread_handle, |
| 54 | ASSERT_MSG(!ShouldWait(thread), "object unavailable!"); | 59 | Handle requesting_thread_handle) { |
| 60 | // The mutex address must be 4-byte aligned | ||
| 61 | if ((address % sizeof(u32)) != 0) { | ||
| 62 | return ResultCode(ErrorModule::Kernel, ErrCodes::MisalignedAddress); | ||
| 63 | } | ||
| 55 | 64 | ||
| 56 | priority = thread->current_priority; | 65 | SharedPtr<Thread> holding_thread = g_handle_table.Get<Thread>(holding_thread_handle); |
| 57 | thread->held_mutexes.insert(this); | 66 | SharedPtr<Thread> requesting_thread = g_handle_table.Get<Thread>(requesting_thread_handle); |
| 58 | SetHoldingThread(thread); | ||
| 59 | thread->UpdatePriority(); | ||
| 60 | Core::System::GetInstance().PrepareReschedule(); | ||
| 61 | } | ||
| 62 | 67 | ||
| 63 | ResultCode Mutex::Release(Thread* thread) { | 68 | // TODO(Subv): It is currently unknown if it is possible to lock a mutex in behalf of another |
| 64 | auto holding_thread = GetHoldingThread(); | 69 | // thread. |
| 65 | ASSERT(holding_thread); | 70 | ASSERT(requesting_thread == GetCurrentThread()); |
| 66 | 71 | ||
| 67 | // We can only release the mutex if it's held by the calling thread. | 72 | u32 addr_value = Memory::Read32(address); |
| 68 | ASSERT(thread == holding_thread); | 73 | |
| 74 | // If the mutex isn't being held, just return success. | ||
| 75 | if (addr_value != (holding_thread_handle | Mutex::MutexHasWaitersFlag)) { | ||
| 76 | return RESULT_SUCCESS; | ||
| 77 | } | ||
| 78 | |||
| 79 | if (holding_thread == nullptr) | ||
| 80 | return ERR_INVALID_HANDLE; | ||
| 81 | |||
| 82 | // Wait until the mutex is released | ||
| 83 | GetCurrentThread()->mutex_wait_address = address; | ||
| 84 | GetCurrentThread()->wait_handle = requesting_thread_handle; | ||
| 85 | |||
| 86 | GetCurrentThread()->status = THREADSTATUS_WAIT_MUTEX; | ||
| 87 | GetCurrentThread()->wakeup_callback = nullptr; | ||
| 88 | |||
| 89 | // Update the lock holder thread's priority to prevent priority inversion. | ||
| 90 | holding_thread->AddMutexWaiter(GetCurrentThread()); | ||
| 69 | 91 | ||
| 70 | holding_thread->held_mutexes.erase(this); | ||
| 71 | holding_thread->UpdatePriority(); | ||
| 72 | SetHoldingThread(nullptr); | ||
| 73 | SetHasWaiters(!GetWaitingThreads().empty()); | ||
| 74 | WakeupAllWaitingThreads(); | ||
| 75 | Core::System::GetInstance().PrepareReschedule(); | 92 | Core::System::GetInstance().PrepareReschedule(); |
| 76 | 93 | ||
| 77 | return RESULT_SUCCESS; | 94 | return RESULT_SUCCESS; |
| 78 | } | 95 | } |
| 79 | 96 | ||
| 80 | void Mutex::AddWaitingThread(SharedPtr<Thread> thread) { | 97 | ResultCode Mutex::Release(VAddr address) { |
| 81 | WaitObject::AddWaitingThread(thread); | 98 | // The mutex address must be 4-byte aligned |
| 82 | thread->pending_mutexes.insert(this); | 99 | if ((address % sizeof(u32)) != 0) { |
| 83 | SetHasWaiters(true); | 100 | return ResultCode(ErrorModule::Kernel, ErrCodes::MisalignedAddress); |
| 84 | UpdatePriority(); | 101 | } |
| 85 | } | ||
| 86 | |||
| 87 | void Mutex::RemoveWaitingThread(Thread* thread) { | ||
| 88 | WaitObject::RemoveWaitingThread(thread); | ||
| 89 | thread->pending_mutexes.erase(this); | ||
| 90 | if (!GetHasWaiters()) | ||
| 91 | SetHasWaiters(!GetWaitingThreads().empty()); | ||
| 92 | UpdatePriority(); | ||
| 93 | } | ||
| 94 | 102 | ||
| 95 | void Mutex::UpdatePriority() { | 103 | auto [thread, num_waiters] = GetHighestPriorityMutexWaitingThread(GetCurrentThread(), address); |
| 96 | if (!GetHoldingThread()) | ||
| 97 | return; | ||
| 98 | 104 | ||
| 99 | u32 best_priority = THREADPRIO_LOWEST; | 105 | // There are no more threads waiting for the mutex, release it completely. |
| 100 | for (auto& waiter : GetWaitingThreads()) { | 106 | if (thread == nullptr) { |
| 101 | if (waiter->current_priority < best_priority) | 107 | ASSERT(GetCurrentThread()->wait_mutex_threads.empty()); |
| 102 | best_priority = waiter->current_priority; | 108 | Memory::Write32(address, 0); |
| 109 | return RESULT_SUCCESS; | ||
| 103 | } | 110 | } |
| 104 | 111 | ||
| 105 | if (best_priority != priority) { | 112 | // Transfer the ownership of the mutex from the previous owner to the new one. |
| 106 | priority = best_priority; | 113 | TransferMutexOwnership(address, GetCurrentThread(), thread); |
| 107 | GetHoldingThread()->UpdatePriority(); | ||
| 108 | } | ||
| 109 | } | ||
| 110 | 114 | ||
| 111 | Handle Mutex::GetOwnerHandle() const { | 115 | u32 mutex_value = thread->wait_handle; |
| 112 | GuestState guest_state{Memory::Read32(guest_addr)}; | ||
| 113 | return guest_state.holding_thread_handle; | ||
| 114 | } | ||
| 115 | 116 | ||
| 116 | SharedPtr<Thread> Mutex::GetHoldingThread() const { | 117 | if (num_waiters >= 2) { |
| 117 | GuestState guest_state{Memory::Read32(guest_addr)}; | 118 | // Notify the guest that there are still some threads waiting for the mutex |
| 118 | return g_handle_table.Get<Thread>(guest_state.holding_thread_handle); | 119 | mutex_value |= Mutex::MutexHasWaitersFlag; |
| 119 | } | 120 | } |
| 120 | 121 | ||
| 121 | void Mutex::SetHoldingThread(SharedPtr<Thread> thread) { | 122 | // Grant the mutex to the next waiting thread and resume it. |
| 122 | GuestState guest_state{Memory::Read32(guest_addr)}; | 123 | Memory::Write32(address, mutex_value); |
| 123 | guest_state.holding_thread_handle.Assign(thread ? thread->guest_handle : 0); | ||
| 124 | Memory::Write32(guest_addr, guest_state.raw); | ||
| 125 | } | ||
| 126 | 124 | ||
| 127 | bool Mutex::GetHasWaiters() const { | 125 | ASSERT(thread->status == THREADSTATUS_WAIT_MUTEX); |
| 128 | GuestState guest_state{Memory::Read32(guest_addr)}; | 126 | thread->ResumeFromWait(); |
| 129 | return guest_state.has_waiters != 0; | ||
| 130 | } | ||
| 131 | 127 | ||
| 132 | void Mutex::SetHasWaiters(bool has_waiters) { | 128 | thread->lock_owner = nullptr; |
| 133 | GuestState guest_state{Memory::Read32(guest_addr)}; | 129 | thread->condvar_wait_address = 0; |
| 134 | guest_state.has_waiters.Assign(has_waiters ? 1 : 0); | 130 | thread->mutex_wait_address = 0; |
| 135 | Memory::Write32(guest_addr, guest_state.raw); | 131 | thread->wait_handle = 0; |
| 136 | } | ||
| 137 | 132 | ||
| 133 | return RESULT_SUCCESS; | ||
| 134 | } | ||
| 138 | } // namespace Kernel | 135 | } // namespace Kernel |
diff --git a/src/core/hle/kernel/mutex.h b/src/core/hle/kernel/mutex.h index 38db21005..3117e7c70 100644 --- a/src/core/hle/kernel/mutex.h +++ b/src/core/hle/kernel/mutex.h | |||
| @@ -15,87 +15,23 @@ namespace Kernel { | |||
| 15 | 15 | ||
| 16 | class Thread; | 16 | class Thread; |
| 17 | 17 | ||
| 18 | class Mutex final : public WaitObject { | 18 | class Mutex final { |
| 19 | public: | 19 | public: |
| 20 | /** | 20 | /// Flag that indicates that a mutex still has threads waiting for it. |
| 21 | * Creates a mutex. | 21 | static constexpr u32 MutexHasWaitersFlag = 0x40000000; |
| 22 | * @param holding_thread Specifies a thread already holding the mutex. If not nullptr, this | 22 | /// Mask of the bits in a mutex address value that contain the mutex owner. |
| 23 | * thread will acquire the mutex. | 23 | static constexpr u32 MutexOwnerMask = 0xBFFFFFFF; |
| 24 | * @param guest_addr Address of the object tracking the mutex in guest memory. If specified, | ||
| 25 | * this mutex will update the guest object when its state changes. | ||
| 26 | * @param name Optional name of mutex | ||
| 27 | * @return Pointer to new Mutex object | ||
| 28 | */ | ||
| 29 | static SharedPtr<Mutex> Create(SharedPtr<Kernel::Thread> holding_thread, VAddr guest_addr = 0, | ||
| 30 | std::string name = "Unknown"); | ||
| 31 | 24 | ||
| 32 | std::string GetTypeName() const override { | 25 | /// Attempts to acquire a mutex at the specified address. |
| 33 | return "Mutex"; | 26 | static ResultCode TryAcquire(VAddr address, Handle holding_thread_handle, |
| 34 | } | 27 | Handle requesting_thread_handle); |
| 35 | std::string GetName() const override { | ||
| 36 | return name; | ||
| 37 | } | ||
| 38 | 28 | ||
| 39 | static const HandleType HANDLE_TYPE = HandleType::Mutex; | 29 | /// Releases the mutex at the specified address. |
| 40 | HandleType GetHandleType() const override { | 30 | static ResultCode Release(VAddr address); |
| 41 | return HANDLE_TYPE; | ||
| 42 | } | ||
| 43 | |||
| 44 | u32 priority; ///< The priority of the mutex, used for priority inheritance. | ||
| 45 | std::string name; ///< Name of mutex (optional) | ||
| 46 | VAddr guest_addr; ///< Address of the guest mutex value | ||
| 47 | |||
| 48 | /** | ||
| 49 | * Elevate the mutex priority to the best priority | ||
| 50 | * among the priorities of all its waiting threads. | ||
| 51 | */ | ||
| 52 | void UpdatePriority(); | ||
| 53 | |||
| 54 | bool ShouldWait(Thread* thread) const override; | ||
| 55 | void Acquire(Thread* thread) override; | ||
| 56 | |||
| 57 | void AddWaitingThread(SharedPtr<Thread> thread) override; | ||
| 58 | void RemoveWaitingThread(Thread* thread) override; | ||
| 59 | |||
| 60 | /** | ||
| 61 | * Attempts to release the mutex from the specified thread. | ||
| 62 | * @param thread Thread that wants to release the mutex. | ||
| 63 | * @returns The result code of the operation. | ||
| 64 | */ | ||
| 65 | ResultCode Release(Thread* thread); | ||
| 66 | |||
| 67 | /// Gets the handle to the holding process stored in the guest state. | ||
| 68 | Handle GetOwnerHandle() const; | ||
| 69 | |||
| 70 | /// Gets the Thread pointed to by the owner handle | ||
| 71 | SharedPtr<Thread> GetHoldingThread() const; | ||
| 72 | /// Sets the holding process handle in the guest state. | ||
| 73 | void SetHoldingThread(SharedPtr<Thread> thread); | ||
| 74 | |||
| 75 | /// Returns the has_waiters bit in the guest state. | ||
| 76 | bool GetHasWaiters() const; | ||
| 77 | /// Sets the has_waiters bit in the guest state. | ||
| 78 | void SetHasWaiters(bool has_waiters); | ||
| 79 | 31 | ||
| 80 | private: | 32 | private: |
| 81 | Mutex(); | 33 | Mutex() = default; |
| 82 | ~Mutex() override; | 34 | ~Mutex() = default; |
| 83 | |||
| 84 | /// Object in guest memory used to track the mutex state | ||
| 85 | union GuestState { | ||
| 86 | u32_le raw; | ||
| 87 | /// Handle of the thread that currently holds the mutex, 0 if available | ||
| 88 | BitField<0, 30, u32_le> holding_thread_handle; | ||
| 89 | /// 1 when there are threads waiting for this mutex, otherwise 0 | ||
| 90 | BitField<30, 1, u32_le> has_waiters; | ||
| 91 | }; | ||
| 92 | static_assert(sizeof(GuestState) == 4, "GuestState size is incorrect"); | ||
| 93 | }; | 35 | }; |
| 94 | 36 | ||
| 95 | /** | ||
| 96 | * Releases all the mutexes held by the specified thread | ||
| 97 | * @param thread Thread that is holding the mutexes | ||
| 98 | */ | ||
| 99 | void ReleaseThreadMutexes(Thread* thread); | ||
| 100 | |||
| 101 | } // namespace Kernel | 37 | } // namespace Kernel |
diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp index 2cffec198..751a0524d 100644 --- a/src/core/hle/kernel/process.cpp +++ b/src/core/hle/kernel/process.cpp | |||
| @@ -54,7 +54,7 @@ void Process::ParseKernelCaps(const u32* kernel_caps, size_t len) { | |||
| 54 | continue; | 54 | continue; |
| 55 | } else if ((type & 0xF00) == 0xE00) { // 0x0FFF | 55 | } else if ((type & 0xF00) == 0xE00) { // 0x0FFF |
| 56 | // Allowed interrupts list | 56 | // Allowed interrupts list |
| 57 | LOG_WARNING(Loader, "ExHeader allowed interrupts list ignored"); | 57 | NGLOG_WARNING(Loader, "ExHeader allowed interrupts list ignored"); |
| 58 | } else if ((type & 0xF80) == 0xF00) { // 0x07FF | 58 | } else if ((type & 0xF80) == 0xF00) { // 0x07FF |
| 59 | // Allowed syscalls mask | 59 | // Allowed syscalls mask |
| 60 | unsigned int index = ((descriptor >> 24) & 7) * 24; | 60 | unsigned int index = ((descriptor >> 24) & 7) * 24; |
| @@ -74,7 +74,7 @@ void Process::ParseKernelCaps(const u32* kernel_caps, size_t len) { | |||
| 74 | } else if ((type & 0xFFE) == 0xFF8) { // 0x001F | 74 | } else if ((type & 0xFFE) == 0xFF8) { // 0x001F |
| 75 | // Mapped memory range | 75 | // Mapped memory range |
| 76 | if (i + 1 >= len || ((kernel_caps[i + 1] >> 20) & 0xFFE) != 0xFF8) { | 76 | if (i + 1 >= len || ((kernel_caps[i + 1] >> 20) & 0xFFE) != 0xFF8) { |
| 77 | LOG_WARNING(Loader, "Incomplete exheader memory range descriptor ignored."); | 77 | NGLOG_WARNING(Loader, "Incomplete exheader memory range descriptor ignored."); |
| 78 | continue; | 78 | continue; |
| 79 | } | 79 | } |
| 80 | u32 end_desc = kernel_caps[i + 1]; | 80 | u32 end_desc = kernel_caps[i + 1]; |
| @@ -109,9 +109,9 @@ void Process::ParseKernelCaps(const u32* kernel_caps, size_t len) { | |||
| 109 | 109 | ||
| 110 | int minor = kernel_version & 0xFF; | 110 | int minor = kernel_version & 0xFF; |
| 111 | int major = (kernel_version >> 8) & 0xFF; | 111 | int major = (kernel_version >> 8) & 0xFF; |
| 112 | LOG_INFO(Loader, "ExHeader kernel version: %d.%d", major, minor); | 112 | NGLOG_INFO(Loader, "ExHeader kernel version: {}.{}", major, minor); |
| 113 | } else { | 113 | } else { |
| 114 | LOG_ERROR(Loader, "Unhandled kernel caps descriptor: 0x%08X", descriptor); | 114 | NGLOG_ERROR(Loader, "Unhandled kernel caps descriptor: {:#010X}", descriptor); |
| 115 | } | 115 | } |
| 116 | } | 116 | } |
| 117 | } | 117 | } |
diff --git a/src/core/hle/kernel/resource_limit.cpp b/src/core/hle/kernel/resource_limit.cpp index 88ca8ad7e..0ef5fc57d 100644 --- a/src/core/hle/kernel/resource_limit.cpp +++ b/src/core/hle/kernel/resource_limit.cpp | |||
| @@ -29,7 +29,7 @@ SharedPtr<ResourceLimit> ResourceLimit::GetForCategory(ResourceLimitCategory cat | |||
| 29 | case ResourceLimitCategory::OTHER: | 29 | case ResourceLimitCategory::OTHER: |
| 30 | return resource_limits[static_cast<u8>(category)]; | 30 | return resource_limits[static_cast<u8>(category)]; |
| 31 | default: | 31 | default: |
| 32 | LOG_CRITICAL(Kernel, "Unknown resource limit category"); | 32 | NGLOG_CRITICAL(Kernel, "Unknown resource limit category"); |
| 33 | UNREACHABLE(); | 33 | UNREACHABLE(); |
| 34 | } | 34 | } |
| 35 | } | 35 | } |
| @@ -55,7 +55,7 @@ s32 ResourceLimit::GetCurrentResourceValue(ResourceType resource) const { | |||
| 55 | case ResourceType::CPUTime: | 55 | case ResourceType::CPUTime: |
| 56 | return current_cpu_time; | 56 | return current_cpu_time; |
| 57 | default: | 57 | default: |
| 58 | LOG_ERROR(Kernel, "Unknown resource type=%08X", static_cast<u32>(resource)); | 58 | NGLOG_ERROR(Kernel, "Unknown resource type={:08X}", static_cast<u32>(resource)); |
| 59 | UNIMPLEMENTED(); | 59 | UNIMPLEMENTED(); |
| 60 | return 0; | 60 | return 0; |
| 61 | } | 61 | } |
| @@ -84,7 +84,7 @@ u32 ResourceLimit::GetMaxResourceValue(ResourceType resource) const { | |||
| 84 | case ResourceType::CPUTime: | 84 | case ResourceType::CPUTime: |
| 85 | return max_cpu_time; | 85 | return max_cpu_time; |
| 86 | default: | 86 | default: |
| 87 | LOG_ERROR(Kernel, "Unknown resource type=%08X", static_cast<u32>(resource)); | 87 | NGLOG_ERROR(Kernel, "Unknown resource type={:08X}", static_cast<u32>(resource)); |
| 88 | UNIMPLEMENTED(); | 88 | UNIMPLEMENTED(); |
| 89 | return 0; | 89 | return 0; |
| 90 | } | 90 | } |
diff --git a/src/core/hle/kernel/scheduler.cpp b/src/core/hle/kernel/scheduler.cpp index 921f27efb..ff6a0941a 100644 --- a/src/core/hle/kernel/scheduler.cpp +++ b/src/core/hle/kernel/scheduler.cpp | |||
| @@ -94,11 +94,11 @@ void Scheduler::Reschedule() { | |||
| 94 | Thread* next = PopNextReadyThread(); | 94 | Thread* next = PopNextReadyThread(); |
| 95 | 95 | ||
| 96 | if (cur && next) { | 96 | if (cur && next) { |
| 97 | LOG_TRACE(Kernel, "context switch %u -> %u", cur->GetObjectId(), next->GetObjectId()); | 97 | NGLOG_TRACE(Kernel, "context switch {} -> {}", cur->GetObjectId(), next->GetObjectId()); |
| 98 | } else if (cur) { | 98 | } else if (cur) { |
| 99 | LOG_TRACE(Kernel, "context switch %u -> idle", cur->GetObjectId()); | 99 | NGLOG_TRACE(Kernel, "context switch {} -> idle", cur->GetObjectId()); |
| 100 | } else if (next) { | 100 | } else if (next) { |
| 101 | LOG_TRACE(Kernel, "context switch idle -> %u", next->GetObjectId()); | 101 | NGLOG_TRACE(Kernel, "context switch idle -> {}", next->GetObjectId()); |
| 102 | } | 102 | } |
| 103 | 103 | ||
| 104 | SwitchContext(next); | 104 | SwitchContext(next); |
diff --git a/src/core/hle/kernel/server_session.cpp b/src/core/hle/kernel/server_session.cpp index 33397d84f..b1f8e771c 100644 --- a/src/core/hle/kernel/server_session.cpp +++ b/src/core/hle/kernel/server_session.cpp | |||
| @@ -68,7 +68,7 @@ ResultCode ServerSession::HandleDomainSyncRequest(Kernel::HLERequestContext& con | |||
| 68 | return domain_request_handlers[object_id - 1]->HandleSyncRequest(context); | 68 | return domain_request_handlers[object_id - 1]->HandleSyncRequest(context); |
| 69 | 69 | ||
| 70 | case IPC::DomainMessageHeader::CommandType::CloseVirtualHandle: { | 70 | case IPC::DomainMessageHeader::CommandType::CloseVirtualHandle: { |
| 71 | LOG_DEBUG(IPC, "CloseVirtualHandle, object_id=0x%08X", object_id); | 71 | NGLOG_DEBUG(IPC, "CloseVirtualHandle, object_id={:#010X}", object_id); |
| 72 | 72 | ||
| 73 | domain_request_handlers[object_id - 1] = nullptr; | 73 | domain_request_handlers[object_id - 1] = nullptr; |
| 74 | 74 | ||
| @@ -78,8 +78,8 @@ ResultCode ServerSession::HandleDomainSyncRequest(Kernel::HLERequestContext& con | |||
| 78 | } | 78 | } |
| 79 | } | 79 | } |
| 80 | 80 | ||
| 81 | LOG_CRITICAL(IPC, "Unknown domain command=%d", | 81 | NGLOG_CRITICAL(IPC, "Unknown domain command={}", |
| 82 | static_cast<int>(domain_message_header->command.Value())); | 82 | static_cast<int>(domain_message_header->command.Value())); |
| 83 | ASSERT(false); | 83 | ASSERT(false); |
| 84 | } | 84 | } |
| 85 | 85 | ||
diff --git a/src/core/hle/kernel/shared_memory.cpp b/src/core/hle/kernel/shared_memory.cpp index bc99993c8..f0b65c73d 100644 --- a/src/core/hle/kernel/shared_memory.cpp +++ b/src/core/hle/kernel/shared_memory.cpp | |||
| @@ -107,16 +107,16 @@ ResultCode SharedMemory::Map(Process* target_process, VAddr address, MemoryPermi | |||
| 107 | 107 | ||
| 108 | // Error out if the requested permissions don't match what the creator process allows. | 108 | // Error out if the requested permissions don't match what the creator process allows. |
| 109 | if (static_cast<u32>(permissions) & ~static_cast<u32>(own_other_permissions)) { | 109 | if (static_cast<u32>(permissions) & ~static_cast<u32>(own_other_permissions)) { |
| 110 | LOG_ERROR(Kernel, "cannot map id=%u, address=0x%lx name=%s, permissions don't match", | 110 | NGLOG_ERROR(Kernel, "cannot map id={}, address={:#X} name={}, permissions don't match", |
| 111 | GetObjectId(), address, name.c_str()); | 111 | GetObjectId(), address, name); |
| 112 | return ERR_INVALID_COMBINATION; | 112 | return ERR_INVALID_COMBINATION; |
| 113 | } | 113 | } |
| 114 | 114 | ||
| 115 | // Error out if the provided permissions are not compatible with what the creator process needs. | 115 | // Error out if the provided permissions are not compatible with what the creator process needs. |
| 116 | if (other_permissions != MemoryPermission::DontCare && | 116 | if (other_permissions != MemoryPermission::DontCare && |
| 117 | static_cast<u32>(this->permissions) & ~static_cast<u32>(other_permissions)) { | 117 | static_cast<u32>(this->permissions) & ~static_cast<u32>(other_permissions)) { |
| 118 | LOG_ERROR(Kernel, "cannot map id=%u, address=0x%lx name=%s, permissions don't match", | 118 | NGLOG_ERROR(Kernel, "cannot map id={}, address={:#X} name={}, permissions don't match", |
| 119 | GetObjectId(), address, name.c_str()); | 119 | GetObjectId(), address, name); |
| 120 | return ERR_WRONG_PERMISSION; | 120 | return ERR_WRONG_PERMISSION; |
| 121 | } | 121 | } |
| 122 | 122 | ||
| @@ -131,9 +131,10 @@ ResultCode SharedMemory::Map(Process* target_process, VAddr address, MemoryPermi | |||
| 131 | auto result = target_process->vm_manager.MapMemoryBlock( | 131 | auto result = target_process->vm_manager.MapMemoryBlock( |
| 132 | target_address, backing_block, backing_block_offset, size, MemoryState::Shared); | 132 | target_address, backing_block, backing_block_offset, size, MemoryState::Shared); |
| 133 | if (result.Failed()) { | 133 | if (result.Failed()) { |
| 134 | LOG_ERROR(Kernel, | 134 | NGLOG_ERROR( |
| 135 | "cannot map id=%u, target_address=0x%lx name=%s, error mapping to virtual memory", | 135 | Kernel, |
| 136 | GetObjectId(), target_address, name.c_str()); | 136 | "cannot map id={}, target_address={:#X} name={}, error mapping to virtual memory", |
| 137 | GetObjectId(), target_address, name); | ||
| 137 | return result.Code(); | 138 | return result.Code(); |
| 138 | } | 139 | } |
| 139 | 140 | ||
| @@ -151,7 +152,7 @@ VMAPermission SharedMemory::ConvertPermissions(MemoryPermission permission) { | |||
| 151 | u32 masked_permissions = | 152 | u32 masked_permissions = |
| 152 | static_cast<u32>(permission) & static_cast<u32>(MemoryPermission::ReadWriteExecute); | 153 | static_cast<u32>(permission) & static_cast<u32>(MemoryPermission::ReadWriteExecute); |
| 153 | return static_cast<VMAPermission>(masked_permissions); | 154 | return static_cast<VMAPermission>(masked_permissions); |
| 154 | }; | 155 | } |
| 155 | 156 | ||
| 156 | u8* SharedMemory::GetPointer(u32 offset) { | 157 | u8* SharedMemory::GetPointer(u32 offset) { |
| 157 | return backing_block->data() + backing_block_offset + offset; | 158 | return backing_block->data() + backing_block_offset + offset; |
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index 633740992..cb19b1a69 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp | |||
| @@ -13,7 +13,6 @@ | |||
| 13 | #include "core/core_timing.h" | 13 | #include "core/core_timing.h" |
| 14 | #include "core/hle/kernel/client_port.h" | 14 | #include "core/hle/kernel/client_port.h" |
| 15 | #include "core/hle/kernel/client_session.h" | 15 | #include "core/hle/kernel/client_session.h" |
| 16 | #include "core/hle/kernel/condition_variable.h" | ||
| 17 | #include "core/hle/kernel/event.h" | 16 | #include "core/hle/kernel/event.h" |
| 18 | #include "core/hle/kernel/handle_table.h" | 17 | #include "core/hle/kernel/handle_table.h" |
| 19 | #include "core/hle/kernel/mutex.h" | 18 | #include "core/hle/kernel/mutex.h" |
| @@ -32,7 +31,7 @@ namespace Kernel { | |||
| 32 | 31 | ||
| 33 | /// Set the process heap to a given Size. It can both extend and shrink the heap. | 32 | /// Set the process heap to a given Size. It can both extend and shrink the heap. |
| 34 | static ResultCode SetHeapSize(VAddr* heap_addr, u64 heap_size) { | 33 | static ResultCode SetHeapSize(VAddr* heap_addr, u64 heap_size) { |
| 35 | LOG_TRACE(Kernel_SVC, "called, heap_size=0x%llx", heap_size); | 34 | NGLOG_TRACE(Kernel_SVC, "called, heap_size={:#X}", heap_size); |
| 36 | auto& process = *Core::CurrentProcess(); | 35 | auto& process = *Core::CurrentProcess(); |
| 37 | CASCADE_RESULT(*heap_addr, | 36 | CASCADE_RESULT(*heap_addr, |
| 38 | process.HeapAllocate(Memory::HEAP_VADDR, heap_size, VMAPermission::ReadWrite)); | 37 | process.HeapAllocate(Memory::HEAP_VADDR, heap_size, VMAPermission::ReadWrite)); |
| @@ -40,21 +39,21 @@ static ResultCode SetHeapSize(VAddr* heap_addr, u64 heap_size) { | |||
| 40 | } | 39 | } |
| 41 | 40 | ||
| 42 | static ResultCode SetMemoryAttribute(VAddr addr, u64 size, u32 state0, u32 state1) { | 41 | static ResultCode SetMemoryAttribute(VAddr addr, u64 size, u32 state0, u32 state1) { |
| 43 | LOG_WARNING(Kernel_SVC, "(STUBBED) called, addr=0x%lx", addr); | 42 | NGLOG_WARNING(Kernel_SVC, "(STUBBED) called, addr={:#X}", addr); |
| 44 | return RESULT_SUCCESS; | 43 | return RESULT_SUCCESS; |
| 45 | } | 44 | } |
| 46 | 45 | ||
| 47 | /// Maps a memory range into a different range. | 46 | /// Maps a memory range into a different range. |
| 48 | static ResultCode MapMemory(VAddr dst_addr, VAddr src_addr, u64 size) { | 47 | static ResultCode MapMemory(VAddr dst_addr, VAddr src_addr, u64 size) { |
| 49 | LOG_TRACE(Kernel_SVC, "called, dst_addr=0x%llx, src_addr=0x%llx, size=0x%llx", dst_addr, | 48 | NGLOG_TRACE(Kernel_SVC, "called, dst_addr={:#X}, src_addr={:#X}, size={:#X}", dst_addr, |
| 50 | src_addr, size); | 49 | src_addr, size); |
| 51 | return Core::CurrentProcess()->MirrorMemory(dst_addr, src_addr, size); | 50 | return Core::CurrentProcess()->MirrorMemory(dst_addr, src_addr, size); |
| 52 | } | 51 | } |
| 53 | 52 | ||
| 54 | /// Unmaps a region that was previously mapped with svcMapMemory | 53 | /// Unmaps a region that was previously mapped with svcMapMemory |
| 55 | static ResultCode UnmapMemory(VAddr dst_addr, VAddr src_addr, u64 size) { | 54 | static ResultCode UnmapMemory(VAddr dst_addr, VAddr src_addr, u64 size) { |
| 56 | LOG_TRACE(Kernel_SVC, "called, dst_addr=0x%llx, src_addr=0x%llx, size=0x%llx", dst_addr, | 55 | NGLOG_TRACE(Kernel_SVC, "called, dst_addr={:#X}, src_addr={:#X}, size={:#X}", dst_addr, |
| 57 | src_addr, size); | 56 | src_addr, size); |
| 58 | return Core::CurrentProcess()->UnmapMemory(dst_addr, src_addr, size); | 57 | return Core::CurrentProcess()->UnmapMemory(dst_addr, src_addr, size); |
| 59 | } | 58 | } |
| 60 | 59 | ||
| @@ -69,11 +68,11 @@ static ResultCode ConnectToNamedPort(Handle* out_handle, VAddr port_name_address | |||
| 69 | if (port_name.size() > PortNameMaxLength) | 68 | if (port_name.size() > PortNameMaxLength) |
| 70 | return ERR_PORT_NAME_TOO_LONG; | 69 | return ERR_PORT_NAME_TOO_LONG; |
| 71 | 70 | ||
| 72 | LOG_TRACE(Kernel_SVC, "called port_name=%s", port_name.c_str()); | 71 | NGLOG_TRACE(Kernel_SVC, "called port_name={}", port_name); |
| 73 | 72 | ||
| 74 | auto it = Service::g_kernel_named_ports.find(port_name); | 73 | auto it = Service::g_kernel_named_ports.find(port_name); |
| 75 | if (it == Service::g_kernel_named_ports.end()) { | 74 | if (it == Service::g_kernel_named_ports.end()) { |
| 76 | LOG_WARNING(Kernel_SVC, "tried to connect to unknown port: %s", port_name.c_str()); | 75 | NGLOG_WARNING(Kernel_SVC, "tried to connect to unknown port: {}", port_name); |
| 77 | return ERR_NOT_FOUND; | 76 | return ERR_NOT_FOUND; |
| 78 | } | 77 | } |
| 79 | 78 | ||
| @@ -91,11 +90,11 @@ static ResultCode ConnectToNamedPort(Handle* out_handle, VAddr port_name_address | |||
| 91 | static ResultCode SendSyncRequest(Handle handle) { | 90 | static ResultCode SendSyncRequest(Handle handle) { |
| 92 | SharedPtr<ClientSession> session = g_handle_table.Get<ClientSession>(handle); | 91 | SharedPtr<ClientSession> session = g_handle_table.Get<ClientSession>(handle); |
| 93 | if (!session) { | 92 | if (!session) { |
| 94 | LOG_ERROR(Kernel_SVC, "called with invalid handle=0x%08X", handle); | 93 | NGLOG_ERROR(Kernel_SVC, "called with invalid handle={:#010X}", handle); |
| 95 | return ERR_INVALID_HANDLE; | 94 | return ERR_INVALID_HANDLE; |
| 96 | } | 95 | } |
| 97 | 96 | ||
| 98 | LOG_TRACE(Kernel_SVC, "called handle=0x%08X(%s)", handle, session->GetName().c_str()); | 97 | NGLOG_TRACE(Kernel_SVC, "called handle={:#010X}({})", handle, session->GetName()); |
| 99 | 98 | ||
| 100 | Core::System::GetInstance().PrepareReschedule(); | 99 | Core::System::GetInstance().PrepareReschedule(); |
| 101 | 100 | ||
| @@ -106,7 +105,7 @@ static ResultCode SendSyncRequest(Handle handle) { | |||
| 106 | 105 | ||
| 107 | /// Get the ID for the specified thread. | 106 | /// Get the ID for the specified thread. |
| 108 | static ResultCode GetThreadId(u32* thread_id, Handle thread_handle) { | 107 | static ResultCode GetThreadId(u32* thread_id, Handle thread_handle) { |
| 109 | LOG_TRACE(Kernel_SVC, "called thread=0x%08X", thread_handle); | 108 | NGLOG_TRACE(Kernel_SVC, "called thread={:#010X}", thread_handle); |
| 110 | 109 | ||
| 111 | const SharedPtr<Thread> thread = g_handle_table.Get<Thread>(thread_handle); | 110 | const SharedPtr<Thread> thread = g_handle_table.Get<Thread>(thread_handle); |
| 112 | if (!thread) { | 111 | if (!thread) { |
| @@ -119,7 +118,7 @@ static ResultCode GetThreadId(u32* thread_id, Handle thread_handle) { | |||
| 119 | 118 | ||
| 120 | /// Get the ID of the specified process | 119 | /// Get the ID of the specified process |
| 121 | static ResultCode GetProcessId(u32* process_id, Handle process_handle) { | 120 | static ResultCode GetProcessId(u32* process_id, Handle process_handle) { |
| 122 | LOG_TRACE(Kernel_SVC, "called process=0x%08X", process_handle); | 121 | NGLOG_TRACE(Kernel_SVC, "called process={:#010X}", process_handle); |
| 123 | 122 | ||
| 124 | const SharedPtr<Process> process = g_handle_table.Get<Process>(process_handle); | 123 | const SharedPtr<Process> process = g_handle_table.Get<Process>(process_handle); |
| 125 | if (!process) { | 124 | if (!process) { |
| @@ -179,8 +178,8 @@ static ResultCode WaitSynchronization1( | |||
| 179 | /// Wait for the given handles to synchronize, timeout after the specified nanoseconds | 178 | /// Wait for the given handles to synchronize, timeout after the specified nanoseconds |
| 180 | static ResultCode WaitSynchronization(Handle* index, VAddr handles_address, u64 handle_count, | 179 | static ResultCode WaitSynchronization(Handle* index, VAddr handles_address, u64 handle_count, |
| 181 | s64 nano_seconds) { | 180 | s64 nano_seconds) { |
| 182 | LOG_TRACE(Kernel_SVC, "called handles_address=0x%llx, handle_count=%d, nano_seconds=%d", | 181 | NGLOG_TRACE(Kernel_SVC, "called handles_address={:#X}, handle_count={}, nano_seconds={}", |
| 183 | handles_address, handle_count, nano_seconds); | 182 | handles_address, handle_count, nano_seconds); |
| 184 | 183 | ||
| 185 | if (!Memory::IsValidVirtualAddress(handles_address)) | 184 | if (!Memory::IsValidVirtualAddress(handles_address)) |
| 186 | return ERR_INVALID_POINTER; | 185 | return ERR_INVALID_POINTER; |
| @@ -240,7 +239,7 @@ static ResultCode WaitSynchronization(Handle* index, VAddr handles_address, u64 | |||
| 240 | 239 | ||
| 241 | /// Resumes a thread waiting on WaitSynchronization | 240 | /// Resumes a thread waiting on WaitSynchronization |
| 242 | static ResultCode CancelSynchronization(Handle thread_handle) { | 241 | static ResultCode CancelSynchronization(Handle thread_handle) { |
| 243 | LOG_TRACE(Kernel_SVC, "called thread=0x%08X", thread_handle); | 242 | NGLOG_TRACE(Kernel_SVC, "called thread={:#X}", thread_handle); |
| 244 | 243 | ||
| 245 | const SharedPtr<Thread> thread = g_handle_table.Get<Thread>(thread_handle); | 244 | const SharedPtr<Thread> thread = g_handle_table.Get<Thread>(thread_handle); |
| 246 | if (!thread) { | 245 | if (!thread) { |
| @@ -257,56 +256,38 @@ static ResultCode CancelSynchronization(Handle thread_handle) { | |||
| 257 | /// Attempts to locks a mutex, creating it if it does not already exist | 256 | /// Attempts to locks a mutex, creating it if it does not already exist |
| 258 | static ResultCode ArbitrateLock(Handle holding_thread_handle, VAddr mutex_addr, | 257 | static ResultCode ArbitrateLock(Handle holding_thread_handle, VAddr mutex_addr, |
| 259 | Handle requesting_thread_handle) { | 258 | Handle requesting_thread_handle) { |
| 260 | LOG_TRACE(Kernel_SVC, | 259 | NGLOG_TRACE(Kernel_SVC, |
| 261 | "called holding_thread_handle=0x%08X, mutex_addr=0x%llx, " | 260 | "called holding_thread_handle={:#010X}, mutex_addr={:#X}, " |
| 262 | "requesting_current_thread_handle=0x%08X", | 261 | "requesting_current_thread_handle={:#010X}", |
| 263 | holding_thread_handle, mutex_addr, requesting_thread_handle); | 262 | holding_thread_handle, mutex_addr, requesting_thread_handle); |
| 264 | |||
| 265 | SharedPtr<Thread> holding_thread = g_handle_table.Get<Thread>(holding_thread_handle); | ||
| 266 | SharedPtr<Thread> requesting_thread = g_handle_table.Get<Thread>(requesting_thread_handle); | ||
| 267 | |||
| 268 | ASSERT(requesting_thread); | ||
| 269 | ASSERT(requesting_thread == GetCurrentThread()); | ||
| 270 | |||
| 271 | SharedPtr<Mutex> mutex = g_object_address_table.Get<Mutex>(mutex_addr); | ||
| 272 | if (!mutex) { | ||
| 273 | // Create a new mutex for the specified address if one does not already exist | ||
| 274 | mutex = Mutex::Create(holding_thread, mutex_addr); | ||
| 275 | mutex->name = Common::StringFromFormat("mutex-%llx", mutex_addr); | ||
| 276 | } | ||
| 277 | |||
| 278 | ASSERT(holding_thread == mutex->GetHoldingThread()); | ||
| 279 | 263 | ||
| 280 | return WaitSynchronization1(mutex, requesting_thread.get()); | 264 | return Mutex::TryAcquire(mutex_addr, holding_thread_handle, requesting_thread_handle); |
| 281 | } | 265 | } |
| 282 | 266 | ||
| 283 | /// Unlock a mutex | 267 | /// Unlock a mutex |
| 284 | static ResultCode ArbitrateUnlock(VAddr mutex_addr) { | 268 | static ResultCode ArbitrateUnlock(VAddr mutex_addr) { |
| 285 | LOG_TRACE(Kernel_SVC, "called mutex_addr=0x%llx", mutex_addr); | 269 | NGLOG_TRACE(Kernel_SVC, "called mutex_addr={:#X}", mutex_addr); |
| 286 | 270 | ||
| 287 | SharedPtr<Mutex> mutex = g_object_address_table.Get<Mutex>(mutex_addr); | 271 | return Mutex::Release(mutex_addr); |
| 288 | ASSERT(mutex); | ||
| 289 | |||
| 290 | return mutex->Release(GetCurrentThread()); | ||
| 291 | } | 272 | } |
| 292 | 273 | ||
| 293 | /// Break program execution | 274 | /// Break program execution |
| 294 | static void Break(u64 unk_0, u64 unk_1, u64 unk_2) { | 275 | static void Break(u64 unk_0, u64 unk_1, u64 unk_2) { |
| 295 | LOG_CRITICAL(Debug_Emulated, "Emulated program broke execution!"); | 276 | NGLOG_CRITICAL(Debug_Emulated, "Emulated program broke execution!"); |
| 296 | ASSERT(false); | 277 | ASSERT(false); |
| 297 | } | 278 | } |
| 298 | 279 | ||
| 299 | /// Used to output a message on a debug hardware unit - does nothing on a retail unit | 280 | /// Used to output a message on a debug hardware unit - does nothing on a retail unit |
| 300 | static void OutputDebugString(VAddr address, s32 len) { | 281 | static void OutputDebugString(VAddr address, s32 len) { |
| 301 | std::vector<char> string(len); | 282 | std::string str(len, '\0'); |
| 302 | Memory::ReadBlock(address, string.data(), len); | 283 | Memory::ReadBlock(address, str.data(), str.size()); |
| 303 | LOG_DEBUG(Debug_Emulated, "%.*s", len, string.data()); | 284 | NGLOG_DEBUG(Debug_Emulated, "{}", str); |
| 304 | } | 285 | } |
| 305 | 286 | ||
| 306 | /// Gets system/memory information for the current process | 287 | /// Gets system/memory information for the current process |
| 307 | static ResultCode GetInfo(u64* result, u64 info_id, u64 handle, u64 info_sub_id) { | 288 | static ResultCode GetInfo(u64* result, u64 info_id, u64 handle, u64 info_sub_id) { |
| 308 | LOG_TRACE(Kernel_SVC, "called info_id=0x%X, info_sub_id=0x%X, handle=0x%08X", info_id, | 289 | NGLOG_TRACE(Kernel_SVC, "called info_id={:#X}, info_sub_id={:#X}, handle={:#010X}", info_id, |
| 309 | info_sub_id, handle); | 290 | info_sub_id, handle); |
| 310 | 291 | ||
| 311 | auto& vm_manager = Core::CurrentProcess()->vm_manager; | 292 | auto& vm_manager = Core::CurrentProcess()->vm_manager; |
| 312 | 293 | ||
| @@ -357,12 +338,12 @@ static ResultCode GetInfo(u64* result, u64 info_id, u64 handle, u64 info_sub_id) | |||
| 357 | *result = Core::CurrentProcess()->is_virtual_address_memory_enabled; | 338 | *result = Core::CurrentProcess()->is_virtual_address_memory_enabled; |
| 358 | break; | 339 | break; |
| 359 | case GetInfoType::TitleId: | 340 | case GetInfoType::TitleId: |
| 360 | LOG_WARNING(Kernel_SVC, "(STUBBED) Attempted to query titleid, returned 0"); | 341 | NGLOG_WARNING(Kernel_SVC, "(STUBBED) Attempted to query titleid, returned 0"); |
| 361 | *result = 0; | 342 | *result = 0; |
| 362 | break; | 343 | break; |
| 363 | case GetInfoType::PrivilegedProcessId: | 344 | case GetInfoType::PrivilegedProcessId: |
| 364 | LOG_WARNING(Kernel_SVC, | 345 | NGLOG_WARNING(Kernel_SVC, |
| 365 | "(STUBBED) Attempted to query priviledged process id bounds, returned 0"); | 346 | "(STUBBED) Attempted to query privileged process id bounds, returned 0"); |
| 366 | *result = 0; | 347 | *result = 0; |
| 367 | break; | 348 | break; |
| 368 | default: | 349 | default: |
| @@ -374,13 +355,14 @@ static ResultCode GetInfo(u64* result, u64 info_id, u64 handle, u64 info_sub_id) | |||
| 374 | 355 | ||
| 375 | /// Sets the thread activity | 356 | /// Sets the thread activity |
| 376 | static ResultCode SetThreadActivity(Handle handle, u32 unknown) { | 357 | static ResultCode SetThreadActivity(Handle handle, u32 unknown) { |
| 377 | LOG_WARNING(Kernel_SVC, "(STUBBED) called, handle=0x%08X, unknown=0x%08X", handle, unknown); | 358 | NGLOG_WARNING(Kernel_SVC, "(STUBBED) called, handle={:#010X}, unknown={:#010X}", handle, |
| 359 | unknown); | ||
| 378 | return RESULT_SUCCESS; | 360 | return RESULT_SUCCESS; |
| 379 | } | 361 | } |
| 380 | 362 | ||
| 381 | /// Gets the thread context | 363 | /// Gets the thread context |
| 382 | static ResultCode GetThreadContext(Handle handle, VAddr addr) { | 364 | static ResultCode GetThreadContext(Handle handle, VAddr addr) { |
| 383 | LOG_WARNING(Kernel_SVC, "(STUBBED) called, handle=0x%08X, addr=0x%" PRIx64, handle, addr); | 365 | NGLOG_WARNING(Kernel_SVC, "(STUBBED) called, handle={:#010X}, addr={:#X}", handle, addr); |
| 384 | return RESULT_SUCCESS; | 366 | return RESULT_SUCCESS; |
| 385 | } | 367 | } |
| 386 | 368 | ||
| @@ -412,11 +394,6 @@ static ResultCode SetThreadPriority(Handle handle, u32 priority) { | |||
| 412 | } | 394 | } |
| 413 | 395 | ||
| 414 | thread->SetPriority(priority); | 396 | thread->SetPriority(priority); |
| 415 | thread->UpdatePriority(); | ||
| 416 | |||
| 417 | // Update the mutexes that this thread is waiting for | ||
| 418 | for (auto& mutex : thread->pending_mutexes) | ||
| 419 | mutex->UpdatePriority(); | ||
| 420 | 397 | ||
| 421 | Core::System::GetInstance().PrepareReschedule(); | 398 | Core::System::GetInstance().PrepareReschedule(); |
| 422 | return RESULT_SUCCESS; | 399 | return RESULT_SUCCESS; |
| @@ -424,15 +401,15 @@ static ResultCode SetThreadPriority(Handle handle, u32 priority) { | |||
| 424 | 401 | ||
| 425 | /// Get which CPU core is executing the current thread | 402 | /// Get which CPU core is executing the current thread |
| 426 | static u32 GetCurrentProcessorNumber() { | 403 | static u32 GetCurrentProcessorNumber() { |
| 427 | LOG_WARNING(Kernel_SVC, "(STUBBED) called, defaulting to processor 0"); | 404 | NGLOG_WARNING(Kernel_SVC, "(STUBBED) called, defaulting to processor 0"); |
| 428 | return 0; | 405 | return 0; |
| 429 | } | 406 | } |
| 430 | 407 | ||
| 431 | static ResultCode MapSharedMemory(Handle shared_memory_handle, VAddr addr, u64 size, | 408 | static ResultCode MapSharedMemory(Handle shared_memory_handle, VAddr addr, u64 size, |
| 432 | u32 permissions) { | 409 | u32 permissions) { |
| 433 | LOG_TRACE(Kernel_SVC, | 410 | NGLOG_TRACE(Kernel_SVC, |
| 434 | "called, shared_memory_handle=0x%08X, addr=0x%llx, size=0x%llx, permissions=0x%08X", | 411 | "called, shared_memory_handle={:#X}, addr={:#X}, size={:#X}, permissions={:#010X}", |
| 435 | shared_memory_handle, addr, size, permissions); | 412 | shared_memory_handle, addr, size, permissions); |
| 436 | 413 | ||
| 437 | SharedPtr<SharedMemory> shared_memory = g_handle_table.Get<SharedMemory>(shared_memory_handle); | 414 | SharedPtr<SharedMemory> shared_memory = g_handle_table.Get<SharedMemory>(shared_memory_handle); |
| 438 | if (!shared_memory) { | 415 | if (!shared_memory) { |
| @@ -452,16 +429,15 @@ static ResultCode MapSharedMemory(Handle shared_memory_handle, VAddr addr, u64 s | |||
| 452 | return shared_memory->Map(Core::CurrentProcess().get(), addr, permissions_type, | 429 | return shared_memory->Map(Core::CurrentProcess().get(), addr, permissions_type, |
| 453 | MemoryPermission::DontCare); | 430 | MemoryPermission::DontCare); |
| 454 | default: | 431 | default: |
| 455 | LOG_ERROR(Kernel_SVC, "unknown permissions=0x%08X", permissions); | 432 | NGLOG_ERROR(Kernel_SVC, "unknown permissions={:#010X}", permissions); |
| 456 | } | 433 | } |
| 457 | 434 | ||
| 458 | return RESULT_SUCCESS; | 435 | return RESULT_SUCCESS; |
| 459 | } | 436 | } |
| 460 | 437 | ||
| 461 | static ResultCode UnmapSharedMemory(Handle shared_memory_handle, VAddr addr, u64 size) { | 438 | static ResultCode UnmapSharedMemory(Handle shared_memory_handle, VAddr addr, u64 size) { |
| 462 | LOG_WARNING(Kernel_SVC, | 439 | NGLOG_WARNING(Kernel_SVC, "called, shared_memory_handle={:#010X}, addr={:#X}, size={:#X}", |
| 463 | "called, shared_memory_handle=0x%08X, addr=0x%" PRIx64 ", size=0x%" PRIx64 "", | 440 | shared_memory_handle, addr, size); |
| 464 | shared_memory_handle, addr, size); | ||
| 465 | 441 | ||
| 466 | SharedPtr<SharedMemory> shared_memory = g_handle_table.Get<SharedMemory>(shared_memory_handle); | 442 | SharedPtr<SharedMemory> shared_memory = g_handle_table.Get<SharedMemory>(shared_memory_handle); |
| 467 | 443 | ||
| @@ -489,19 +465,19 @@ static ResultCode QueryProcessMemory(MemoryInfo* memory_info, PageInfo* /*page_i | |||
| 489 | memory_info->type = static_cast<u32>(vma->second.meminfo_state); | 465 | memory_info->type = static_cast<u32>(vma->second.meminfo_state); |
| 490 | } | 466 | } |
| 491 | 467 | ||
| 492 | LOG_TRACE(Kernel_SVC, "called process=0x%08X addr=%llx", process_handle, addr); | 468 | NGLOG_TRACE(Kernel_SVC, "called process={:#010X} addr={:X}", process_handle, addr); |
| 493 | return RESULT_SUCCESS; | 469 | return RESULT_SUCCESS; |
| 494 | } | 470 | } |
| 495 | 471 | ||
| 496 | /// Query memory | 472 | /// Query memory |
| 497 | static ResultCode QueryMemory(MemoryInfo* memory_info, PageInfo* page_info, VAddr addr) { | 473 | static ResultCode QueryMemory(MemoryInfo* memory_info, PageInfo* page_info, VAddr addr) { |
| 498 | LOG_TRACE(Kernel_SVC, "called, addr=%llx", addr); | 474 | NGLOG_TRACE(Kernel_SVC, "called, addr={:X}", addr); |
| 499 | return QueryProcessMemory(memory_info, page_info, CurrentProcess, addr); | 475 | return QueryProcessMemory(memory_info, page_info, CurrentProcess, addr); |
| 500 | } | 476 | } |
| 501 | 477 | ||
| 502 | /// Exits the current process | 478 | /// Exits the current process |
| 503 | static void ExitProcess() { | 479 | static void ExitProcess() { |
| 504 | LOG_INFO(Kernel_SVC, "Process %u exiting", Core::CurrentProcess()->process_id); | 480 | NGLOG_INFO(Kernel_SVC, "Process {} exiting", Core::CurrentProcess()->process_id); |
| 505 | 481 | ||
| 506 | ASSERT_MSG(Core::CurrentProcess()->status == ProcessStatus::Running, | 482 | ASSERT_MSG(Core::CurrentProcess()->status == ProcessStatus::Running, |
| 507 | "Process has already exited"); | 483 | "Process has already exited"); |
| @@ -558,9 +534,9 @@ static ResultCode CreateThread(Handle* out_handle, VAddr entry_point, u64 arg, V | |||
| 558 | case THREADPROCESSORID_2: | 534 | case THREADPROCESSORID_2: |
| 559 | case THREADPROCESSORID_3: | 535 | case THREADPROCESSORID_3: |
| 560 | // TODO(bunnei): Implement support for other processor IDs | 536 | // TODO(bunnei): Implement support for other processor IDs |
| 561 | LOG_ERROR(Kernel_SVC, | 537 | NGLOG_ERROR(Kernel_SVC, |
| 562 | "Newly created thread must run in another thread (%u), unimplemented.", | 538 | "Newly created thread must run in another thread ({}), unimplemented.", |
| 563 | processor_id); | 539 | processor_id); |
| 564 | break; | 540 | break; |
| 565 | default: | 541 | default: |
| 566 | ASSERT_MSG(false, "Unsupported thread processor ID: %d", processor_id); | 542 | ASSERT_MSG(false, "Unsupported thread processor ID: %d", processor_id); |
| @@ -575,17 +551,17 @@ static ResultCode CreateThread(Handle* out_handle, VAddr entry_point, u64 arg, V | |||
| 575 | 551 | ||
| 576 | Core::System::GetInstance().PrepareReschedule(); | 552 | Core::System::GetInstance().PrepareReschedule(); |
| 577 | 553 | ||
| 578 | LOG_TRACE(Kernel_SVC, | 554 | NGLOG_TRACE(Kernel_SVC, |
| 579 | "called entrypoint=0x%08X (%s), arg=0x%08X, stacktop=0x%08X, " | 555 | "called entrypoint={:#010X} ({}), arg={:#010X}, stacktop={:#010X}, " |
| 580 | "threadpriority=0x%08X, processorid=0x%08X : created handle=0x%08X", | 556 | "threadpriority={:#010X}, processorid={:#010X} : created handle={:#010X}", |
| 581 | entry_point, name.c_str(), arg, stack_top, priority, processor_id, *out_handle); | 557 | entry_point, name, arg, stack_top, priority, processor_id, *out_handle); |
| 582 | 558 | ||
| 583 | return RESULT_SUCCESS; | 559 | return RESULT_SUCCESS; |
| 584 | } | 560 | } |
| 585 | 561 | ||
| 586 | /// Starts the thread for the provided handle | 562 | /// Starts the thread for the provided handle |
| 587 | static ResultCode StartThread(Handle thread_handle) { | 563 | static ResultCode StartThread(Handle thread_handle) { |
| 588 | LOG_TRACE(Kernel_SVC, "called thread=0x%08X", thread_handle); | 564 | NGLOG_TRACE(Kernel_SVC, "called thread={:#010X}", thread_handle); |
| 589 | 565 | ||
| 590 | const SharedPtr<Thread> thread = g_handle_table.Get<Thread>(thread_handle); | 566 | const SharedPtr<Thread> thread = g_handle_table.Get<Thread>(thread_handle); |
| 591 | if (!thread) { | 567 | if (!thread) { |
| @@ -599,7 +575,7 @@ static ResultCode StartThread(Handle thread_handle) { | |||
| 599 | 575 | ||
| 600 | /// Called when a thread exits | 576 | /// Called when a thread exits |
| 601 | static void ExitThread() { | 577 | static void ExitThread() { |
| 602 | LOG_TRACE(Kernel_SVC, "called, pc=0x%08X", Core::CPU().GetPC()); | 578 | NGLOG_TRACE(Kernel_SVC, "called, pc={:#010X}", Core::CPU().GetPC()); |
| 603 | 579 | ||
| 604 | ExitCurrentThread(); | 580 | ExitCurrentThread(); |
| 605 | Core::System::GetInstance().PrepareReschedule(); | 581 | Core::System::GetInstance().PrepareReschedule(); |
| @@ -607,7 +583,7 @@ static void ExitThread() { | |||
| 607 | 583 | ||
| 608 | /// Sleep the current thread | 584 | /// Sleep the current thread |
| 609 | static void SleepThread(s64 nanoseconds) { | 585 | static void SleepThread(s64 nanoseconds) { |
| 610 | LOG_TRACE(Kernel_SVC, "called nanoseconds=%lld", nanoseconds); | 586 | NGLOG_TRACE(Kernel_SVC, "called nanoseconds={}", nanoseconds); |
| 611 | 587 | ||
| 612 | // Don't attempt to yield execution if there are no available threads to run, | 588 | // Don't attempt to yield execution if there are no available threads to run, |
| 613 | // this way we avoid a useless reschedule to the idle thread. | 589 | // this way we avoid a useless reschedule to the idle thread. |
| @@ -626,111 +602,83 @@ static void SleepThread(s64 nanoseconds) { | |||
| 626 | /// Signal process wide key atomic | 602 | /// Signal process wide key atomic |
| 627 | static ResultCode WaitProcessWideKeyAtomic(VAddr mutex_addr, VAddr condition_variable_addr, | 603 | static ResultCode WaitProcessWideKeyAtomic(VAddr mutex_addr, VAddr condition_variable_addr, |
| 628 | Handle thread_handle, s64 nano_seconds) { | 604 | Handle thread_handle, s64 nano_seconds) { |
| 629 | LOG_TRACE( | 605 | NGLOG_TRACE( |
| 630 | Kernel_SVC, | 606 | Kernel_SVC, |
| 631 | "called mutex_addr=%llx, condition_variable_addr=%llx, thread_handle=0x%08X, timeout=%d", | 607 | "called mutex_addr={:X}, condition_variable_addr={:X}, thread_handle={:#010X}, timeout={}", |
| 632 | mutex_addr, condition_variable_addr, thread_handle, nano_seconds); | 608 | mutex_addr, condition_variable_addr, thread_handle, nano_seconds); |
| 633 | 609 | ||
| 634 | SharedPtr<Thread> thread = g_handle_table.Get<Thread>(thread_handle); | 610 | SharedPtr<Thread> thread = g_handle_table.Get<Thread>(thread_handle); |
| 635 | ASSERT(thread); | 611 | ASSERT(thread); |
| 636 | 612 | ||
| 637 | SharedPtr<Mutex> mutex = g_object_address_table.Get<Mutex>(mutex_addr); | 613 | CASCADE_CODE(Mutex::Release(mutex_addr)); |
| 638 | if (!mutex) { | ||
| 639 | // Create a new mutex for the specified address if one does not already exist | ||
| 640 | mutex = Mutex::Create(thread, mutex_addr); | ||
| 641 | mutex->name = Common::StringFromFormat("mutex-%llx", mutex_addr); | ||
| 642 | } | ||
| 643 | 614 | ||
| 644 | SharedPtr<ConditionVariable> condition_variable = | 615 | SharedPtr<Thread> current_thread = GetCurrentThread(); |
| 645 | g_object_address_table.Get<ConditionVariable>(condition_variable_addr); | 616 | current_thread->condvar_wait_address = condition_variable_addr; |
| 646 | if (!condition_variable) { | 617 | current_thread->mutex_wait_address = mutex_addr; |
| 647 | // Create a new condition_variable for the specified address if one does not already exist | 618 | current_thread->wait_handle = thread_handle; |
| 648 | condition_variable = ConditionVariable::Create(condition_variable_addr).Unwrap(); | 619 | current_thread->status = THREADSTATUS_WAIT_MUTEX; |
| 649 | condition_variable->name = | 620 | current_thread->wakeup_callback = nullptr; |
| 650 | Common::StringFromFormat("condition-variable-%llx", condition_variable_addr); | ||
| 651 | } | ||
| 652 | 621 | ||
| 653 | if (condition_variable->mutex_addr) { | 622 | current_thread->WakeAfterDelay(nano_seconds); |
| 654 | // Previously created the ConditionVariable using WaitProcessWideKeyAtomic, verify | ||
| 655 | // everything is correct | ||
| 656 | ASSERT(condition_variable->mutex_addr == mutex_addr); | ||
| 657 | } else { | ||
| 658 | // Previously created the ConditionVariable using SignalProcessWideKey, set the mutex | ||
| 659 | // associated with it | ||
| 660 | condition_variable->mutex_addr = mutex_addr; | ||
| 661 | } | ||
| 662 | 623 | ||
| 663 | if (mutex->GetOwnerHandle()) { | 624 | // Note: Deliberately don't attempt to inherit the lock owner's priority. |
| 664 | // Release the mutex if the current thread is holding it | ||
| 665 | mutex->Release(thread.get()); | ||
| 666 | } | ||
| 667 | 625 | ||
| 668 | auto wakeup_callback = [mutex, nano_seconds](ThreadWakeupReason reason, | 626 | Core::System::GetInstance().PrepareReschedule(); |
| 669 | SharedPtr<Thread> thread, | 627 | return RESULT_SUCCESS; |
| 670 | SharedPtr<WaitObject> object, size_t index) { | 628 | } |
| 671 | ASSERT(thread->status == THREADSTATUS_WAIT_SYNCH_ANY); | ||
| 672 | 629 | ||
| 673 | if (reason == ThreadWakeupReason::Timeout) { | 630 | /// Signal process wide key |
| 674 | thread->SetWaitSynchronizationResult(RESULT_TIMEOUT); | 631 | static ResultCode SignalProcessWideKey(VAddr condition_variable_addr, s32 target) { |
| 675 | return true; | 632 | NGLOG_TRACE(Kernel_SVC, "called, condition_variable_addr={:#X}, target={:#010X}", |
| 676 | } | 633 | condition_variable_addr, target); |
| 677 | 634 | ||
| 678 | ASSERT(reason == ThreadWakeupReason::Signal); | 635 | u32 processed = 0; |
| 636 | auto& thread_list = Core::System::GetInstance().Scheduler().GetThreadList(); | ||
| 679 | 637 | ||
| 680 | // Now try to acquire the mutex and don't resume if it's not available. | 638 | for (auto& thread : thread_list) { |
| 681 | if (!mutex->ShouldWait(thread.get())) { | 639 | if (thread->condvar_wait_address != condition_variable_addr) |
| 682 | mutex->Acquire(thread.get()); | 640 | continue; |
| 683 | thread->SetWaitSynchronizationResult(RESULT_SUCCESS); | ||
| 684 | return true; | ||
| 685 | } | ||
| 686 | 641 | ||
| 687 | if (nano_seconds == 0) { | 642 | // Only process up to 'target' threads, unless 'target' is -1, in which case process |
| 688 | thread->SetWaitSynchronizationResult(RESULT_TIMEOUT); | 643 | // them all. |
| 689 | return true; | 644 | if (target != -1 && processed >= target) |
| 690 | } | 645 | break; |
| 691 | 646 | ||
| 692 | thread->wait_objects = {mutex}; | 647 | // If the mutex is not yet acquired, acquire it. |
| 693 | mutex->AddWaitingThread(thread); | 648 | u32 mutex_val = Memory::Read32(thread->mutex_wait_address); |
| 694 | thread->status = THREADSTATUS_WAIT_SYNCH_ANY; | ||
| 695 | 649 | ||
| 696 | // Create an event to wake the thread up after the | 650 | if (mutex_val == 0) { |
| 697 | // specified nanosecond delay has passed | 651 | // We were able to acquire the mutex, resume this thread. |
| 698 | thread->WakeAfterDelay(nano_seconds); | 652 | Memory::Write32(thread->mutex_wait_address, thread->wait_handle); |
| 699 | thread->wakeup_callback = DefaultThreadWakeupCallback; | 653 | ASSERT(thread->status == THREADSTATUS_WAIT_MUTEX); |
| 654 | thread->ResumeFromWait(); | ||
| 700 | 655 | ||
| 701 | Core::System::GetInstance().PrepareReschedule(); | 656 | auto lock_owner = thread->lock_owner; |
| 657 | if (lock_owner) | ||
| 658 | lock_owner->RemoveMutexWaiter(thread); | ||
| 702 | 659 | ||
| 703 | return false; | 660 | thread->lock_owner = nullptr; |
| 704 | }; | 661 | thread->mutex_wait_address = 0; |
| 705 | CASCADE_CODE( | 662 | thread->condvar_wait_address = 0; |
| 706 | WaitSynchronization1(condition_variable, thread.get(), nano_seconds, wakeup_callback)); | 663 | thread->wait_handle = 0; |
| 664 | } else { | ||
| 665 | // Couldn't acquire the mutex, block the thread. | ||
| 666 | Handle owner_handle = static_cast<Handle>(mutex_val & Mutex::MutexOwnerMask); | ||
| 667 | auto owner = g_handle_table.Get<Thread>(owner_handle); | ||
| 668 | ASSERT(owner); | ||
| 669 | ASSERT(thread->status != THREADSTATUS_RUNNING); | ||
| 670 | thread->status = THREADSTATUS_WAIT_MUTEX; | ||
| 671 | thread->wakeup_callback = nullptr; | ||
| 707 | 672 | ||
| 708 | return RESULT_SUCCESS; | 673 | // Signal that the mutex now has a waiting thread. |
| 709 | } | 674 | Memory::Write32(thread->mutex_wait_address, mutex_val | Mutex::MutexHasWaitersFlag); |
| 710 | 675 | ||
| 711 | /// Signal process wide key | 676 | owner->AddMutexWaiter(thread); |
| 712 | static ResultCode SignalProcessWideKey(VAddr condition_variable_addr, s32 target) { | ||
| 713 | LOG_TRACE(Kernel_SVC, "called, condition_variable_addr=0x%llx, target=0x%08x", | ||
| 714 | condition_variable_addr, target); | ||
| 715 | |||
| 716 | // Wakeup all or one thread - Any other value is unimplemented | ||
| 717 | ASSERT(target == -1 || target == 1); | ||
| 718 | |||
| 719 | SharedPtr<ConditionVariable> condition_variable = | ||
| 720 | g_object_address_table.Get<ConditionVariable>(condition_variable_addr); | ||
| 721 | if (!condition_variable) { | ||
| 722 | // Create a new condition_variable for the specified address if one does not already exist | ||
| 723 | condition_variable = ConditionVariable::Create(condition_variable_addr).Unwrap(); | ||
| 724 | condition_variable->name = | ||
| 725 | Common::StringFromFormat("condition-variable-%llx", condition_variable_addr); | ||
| 726 | } | ||
| 727 | 677 | ||
| 728 | CASCADE_CODE(condition_variable->Release(target)); | 678 | Core::System::GetInstance().PrepareReschedule(); |
| 679 | } | ||
| 729 | 680 | ||
| 730 | if (condition_variable->mutex_addr) { | 681 | ++processed; |
| 731 | // If a mutex was created for this condition_variable, wait the current thread on it | ||
| 732 | SharedPtr<Mutex> mutex = g_object_address_table.Get<Mutex>(condition_variable->mutex_addr); | ||
| 733 | return WaitSynchronization1(mutex, GetCurrentThread()); | ||
| 734 | } | 682 | } |
| 735 | 683 | ||
| 736 | return RESULT_SUCCESS; | 684 | return RESULT_SUCCESS; |
| @@ -748,13 +696,13 @@ static u64 GetSystemTick() { | |||
| 748 | 696 | ||
| 749 | /// Close a handle | 697 | /// Close a handle |
| 750 | static ResultCode CloseHandle(Handle handle) { | 698 | static ResultCode CloseHandle(Handle handle) { |
| 751 | LOG_TRACE(Kernel_SVC, "Closing handle 0x%08X", handle); | 699 | NGLOG_TRACE(Kernel_SVC, "Closing handle {:#010X}", handle); |
| 752 | return g_handle_table.Close(handle); | 700 | return g_handle_table.Close(handle); |
| 753 | } | 701 | } |
| 754 | 702 | ||
| 755 | /// Reset an event | 703 | /// Reset an event |
| 756 | static ResultCode ResetSignal(Handle handle) { | 704 | static ResultCode ResetSignal(Handle handle) { |
| 757 | LOG_WARNING(Kernel_SVC, "(STUBBED) called handle 0x%08X", handle); | 705 | NGLOG_WARNING(Kernel_SVC, "(STUBBED) called handle {:#010X}", handle); |
| 758 | auto event = g_handle_table.Get<Event>(handle); | 706 | auto event = g_handle_table.Get<Event>(handle); |
| 759 | ASSERT(event != nullptr); | 707 | ASSERT(event != nullptr); |
| 760 | event->Clear(); | 708 | event->Clear(); |
| @@ -763,29 +711,29 @@ static ResultCode ResetSignal(Handle handle) { | |||
| 763 | 711 | ||
| 764 | /// Creates a TransferMemory object | 712 | /// Creates a TransferMemory object |
| 765 | static ResultCode CreateTransferMemory(Handle* handle, VAddr addr, u64 size, u32 permissions) { | 713 | static ResultCode CreateTransferMemory(Handle* handle, VAddr addr, u64 size, u32 permissions) { |
| 766 | LOG_WARNING(Kernel_SVC, "(STUBBED) called addr=0x%lx, size=0x%lx, perms=%08X", addr, size, | 714 | NGLOG_WARNING(Kernel_SVC, "(STUBBED) called addr={:#X}, size={:#X}, perms={:010X}", addr, size, |
| 767 | permissions); | 715 | permissions); |
| 768 | *handle = 0; | 716 | *handle = 0; |
| 769 | return RESULT_SUCCESS; | 717 | return RESULT_SUCCESS; |
| 770 | } | 718 | } |
| 771 | 719 | ||
| 772 | static ResultCode GetThreadCoreMask(Handle handle, u32* mask, u64* unknown) { | 720 | static ResultCode GetThreadCoreMask(Handle handle, u32* mask, u64* unknown) { |
| 773 | LOG_WARNING(Kernel_SVC, "(STUBBED) called, handle=0x%08X", handle); | 721 | NGLOG_WARNING(Kernel_SVC, "(STUBBED) called, handle={:010X}", handle); |
| 774 | *mask = 0x0; | 722 | *mask = 0x0; |
| 775 | *unknown = 0xf; | 723 | *unknown = 0xf; |
| 776 | return RESULT_SUCCESS; | 724 | return RESULT_SUCCESS; |
| 777 | } | 725 | } |
| 778 | 726 | ||
| 779 | static ResultCode SetThreadCoreMask(Handle handle, u32 mask, u64 unknown) { | 727 | static ResultCode SetThreadCoreMask(Handle handle, u32 mask, u64 unknown) { |
| 780 | LOG_WARNING(Kernel_SVC, "(STUBBED) called, handle=0x%08X, mask=0x%08X, unknown=0x%lx", handle, | 728 | NGLOG_WARNING(Kernel_SVC, "(STUBBED) called, handle={:#010X}, mask={:#010X}, unknown={:#X}", |
| 781 | mask, unknown); | 729 | handle, mask, unknown); |
| 782 | return RESULT_SUCCESS; | 730 | return RESULT_SUCCESS; |
| 783 | } | 731 | } |
| 784 | 732 | ||
| 785 | static ResultCode CreateSharedMemory(Handle* handle, u64 size, u32 local_permissions, | 733 | static ResultCode CreateSharedMemory(Handle* handle, u64 size, u32 local_permissions, |
| 786 | u32 remote_permissions) { | 734 | u32 remote_permissions) { |
| 787 | LOG_TRACE(Kernel_SVC, "called, size=0x%llx, localPerms=0x%08x, remotePerms=0x%08x", size, | 735 | NGLOG_TRACE(Kernel_SVC, "called, size={:#X}, localPerms={:#010X}, remotePerms={:#010X}", size, |
| 788 | local_permissions, remote_permissions); | 736 | local_permissions, remote_permissions); |
| 789 | auto sharedMemHandle = | 737 | auto sharedMemHandle = |
| 790 | SharedMemory::Create(g_handle_table.Get<Process>(KernelHandle::CurrentProcess), size, | 738 | SharedMemory::Create(g_handle_table.Get<Process>(KernelHandle::CurrentProcess), size, |
| 791 | static_cast<MemoryPermission>(local_permissions), | 739 | static_cast<MemoryPermission>(local_permissions), |
| @@ -796,7 +744,7 @@ static ResultCode CreateSharedMemory(Handle* handle, u64 size, u32 local_permiss | |||
| 796 | } | 744 | } |
| 797 | 745 | ||
| 798 | static ResultCode ClearEvent(Handle handle) { | 746 | static ResultCode ClearEvent(Handle handle) { |
| 799 | LOG_TRACE(Kernel_SVC, "called, event=0xX", handle); | 747 | NGLOG_TRACE(Kernel_SVC, "called, event={:010X}", handle); |
| 800 | 748 | ||
| 801 | SharedPtr<Event> evt = g_handle_table.Get<Event>(handle); | 749 | SharedPtr<Event> evt = g_handle_table.Get<Event>(handle); |
| 802 | if (evt == nullptr) | 750 | if (evt == nullptr) |
| @@ -948,7 +896,7 @@ static const FunctionDef SVC_Table[] = { | |||
| 948 | 896 | ||
| 949 | static const FunctionDef* GetSVCInfo(u32 func_num) { | 897 | static const FunctionDef* GetSVCInfo(u32 func_num) { |
| 950 | if (func_num >= std::size(SVC_Table)) { | 898 | if (func_num >= std::size(SVC_Table)) { |
| 951 | LOG_ERROR(Kernel_SVC, "unknown svc=0x%02X", func_num); | 899 | NGLOG_ERROR(Kernel_SVC, "Unknown svc={:#04X}", func_num); |
| 952 | return nullptr; | 900 | return nullptr; |
| 953 | } | 901 | } |
| 954 | return &SVC_Table[func_num]; | 902 | return &SVC_Table[func_num]; |
| @@ -967,10 +915,10 @@ void CallSVC(u32 immediate) { | |||
| 967 | if (info->func) { | 915 | if (info->func) { |
| 968 | info->func(); | 916 | info->func(); |
| 969 | } else { | 917 | } else { |
| 970 | LOG_CRITICAL(Kernel_SVC, "unimplemented SVC function %s(..)", info->name); | 918 | NGLOG_CRITICAL(Kernel_SVC, "Unimplemented SVC function {}(..)", info->name); |
| 971 | } | 919 | } |
| 972 | } else { | 920 | } else { |
| 973 | LOG_CRITICAL(Kernel_SVC, "unknown SVC function 0x%x", immediate); | 921 | NGLOG_CRITICAL(Kernel_SVC, "Unknown SVC function {:#X}", immediate); |
| 974 | } | 922 | } |
| 975 | } | 923 | } |
| 976 | 924 | ||
diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index f3a8aa4aa..4cd57ab25 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp | |||
| @@ -77,9 +77,6 @@ void Thread::Stop() { | |||
| 77 | } | 77 | } |
| 78 | wait_objects.clear(); | 78 | wait_objects.clear(); |
| 79 | 79 | ||
| 80 | // Release all the mutexes that this thread holds | ||
| 81 | ReleaseThreadMutexes(this); | ||
| 82 | |||
| 83 | // Mark the TLS slot in the thread's page as free. | 80 | // Mark the TLS slot in the thread's page as free. |
| 84 | u64 tls_page = (tls_address - Memory::TLS_AREA_VADDR) / Memory::PAGE_SIZE; | 81 | u64 tls_page = (tls_address - Memory::TLS_AREA_VADDR) / Memory::PAGE_SIZE; |
| 85 | u64 tls_slot = | 82 | u64 tls_slot = |
| @@ -104,9 +101,10 @@ void ExitCurrentThread() { | |||
| 104 | * @param cycles_late The number of CPU cycles that have passed since the desired wakeup time | 101 | * @param cycles_late The number of CPU cycles that have passed since the desired wakeup time |
| 105 | */ | 102 | */ |
| 106 | static void ThreadWakeupCallback(u64 thread_handle, int cycles_late) { | 103 | static void ThreadWakeupCallback(u64 thread_handle, int cycles_late) { |
| 107 | SharedPtr<Thread> thread = wakeup_callback_handle_table.Get<Thread>((Handle)thread_handle); | 104 | const auto proper_handle = static_cast<Handle>(thread_handle); |
| 105 | SharedPtr<Thread> thread = wakeup_callback_handle_table.Get<Thread>(proper_handle); | ||
| 108 | if (thread == nullptr) { | 106 | if (thread == nullptr) { |
| 109 | LOG_CRITICAL(Kernel, "Callback fired for invalid thread %08X", (Handle)thread_handle); | 107 | NGLOG_CRITICAL(Kernel, "Callback fired for invalid thread {:08X}", proper_handle); |
| 110 | return; | 108 | return; |
| 111 | } | 109 | } |
| 112 | 110 | ||
| @@ -126,6 +124,19 @@ static void ThreadWakeupCallback(u64 thread_handle, int cycles_late) { | |||
| 126 | resume = thread->wakeup_callback(ThreadWakeupReason::Timeout, thread, nullptr, 0); | 124 | resume = thread->wakeup_callback(ThreadWakeupReason::Timeout, thread, nullptr, 0); |
| 127 | } | 125 | } |
| 128 | 126 | ||
| 127 | if (thread->mutex_wait_address != 0 || thread->condvar_wait_address != 0 || | ||
| 128 | thread->wait_handle) { | ||
| 129 | ASSERT(thread->status == THREADSTATUS_WAIT_MUTEX); | ||
| 130 | thread->mutex_wait_address = 0; | ||
| 131 | thread->condvar_wait_address = 0; | ||
| 132 | thread->wait_handle = 0; | ||
| 133 | |||
| 134 | auto lock_owner = thread->lock_owner; | ||
| 135 | // Threads waking up by timeout from WaitProcessWideKey do not perform priority inheritance | ||
| 136 | // and don't have a lock owner. | ||
| 137 | ASSERT(lock_owner == nullptr); | ||
| 138 | } | ||
| 139 | |||
| 129 | if (resume) | 140 | if (resume) |
| 130 | thread->ResumeFromWait(); | 141 | thread->ResumeFromWait(); |
| 131 | } | 142 | } |
| @@ -151,6 +162,7 @@ void Thread::ResumeFromWait() { | |||
| 151 | case THREADSTATUS_WAIT_HLE_EVENT: | 162 | case THREADSTATUS_WAIT_HLE_EVENT: |
| 152 | case THREADSTATUS_WAIT_SLEEP: | 163 | case THREADSTATUS_WAIT_SLEEP: |
| 153 | case THREADSTATUS_WAIT_IPC: | 164 | case THREADSTATUS_WAIT_IPC: |
| 165 | case THREADSTATUS_WAIT_MUTEX: | ||
| 154 | break; | 166 | break; |
| 155 | 167 | ||
| 156 | case THREADSTATUS_READY: | 168 | case THREADSTATUS_READY: |
| @@ -227,19 +239,19 @@ ResultVal<SharedPtr<Thread>> Thread::Create(std::string name, VAddr entry_point, | |||
| 227 | SharedPtr<Process> owner_process) { | 239 | SharedPtr<Process> owner_process) { |
| 228 | // Check if priority is in ranged. Lowest priority -> highest priority id. | 240 | // Check if priority is in ranged. Lowest priority -> highest priority id. |
| 229 | if (priority > THREADPRIO_LOWEST) { | 241 | if (priority > THREADPRIO_LOWEST) { |
| 230 | LOG_ERROR(Kernel_SVC, "Invalid thread priority: %u", priority); | 242 | NGLOG_ERROR(Kernel_SVC, "Invalid thread priority: {}", priority); |
| 231 | return ERR_OUT_OF_RANGE; | 243 | return ERR_OUT_OF_RANGE; |
| 232 | } | 244 | } |
| 233 | 245 | ||
| 234 | if (processor_id > THREADPROCESSORID_MAX) { | 246 | if (processor_id > THREADPROCESSORID_MAX) { |
| 235 | LOG_ERROR(Kernel_SVC, "Invalid processor id: %d", processor_id); | 247 | NGLOG_ERROR(Kernel_SVC, "Invalid processor id: {}", processor_id); |
| 236 | return ERR_OUT_OF_RANGE_KERNEL; | 248 | return ERR_OUT_OF_RANGE_KERNEL; |
| 237 | } | 249 | } |
| 238 | 250 | ||
| 239 | // TODO(yuriks): Other checks, returning 0xD9001BEA | 251 | // TODO(yuriks): Other checks, returning 0xD9001BEA |
| 240 | 252 | ||
| 241 | if (!Memory::IsValidVirtualAddress(*owner_process, entry_point)) { | 253 | if (!Memory::IsValidVirtualAddress(*owner_process, entry_point)) { |
| 242 | LOG_ERROR(Kernel_SVC, "(name=%s): invalid entry %016" PRIx64, name.c_str(), entry_point); | 254 | NGLOG_ERROR(Kernel_SVC, "(name={}): invalid entry {:016X}", name, entry_point); |
| 243 | // TODO (bunnei): Find the correct error code to use here | 255 | // TODO (bunnei): Find the correct error code to use here |
| 244 | return ResultCode(-1); | 256 | return ResultCode(-1); |
| 245 | } | 257 | } |
| @@ -256,7 +268,9 @@ ResultVal<SharedPtr<Thread>> Thread::Create(std::string name, VAddr entry_point, | |||
| 256 | thread->last_running_ticks = CoreTiming::GetTicks(); | 268 | thread->last_running_ticks = CoreTiming::GetTicks(); |
| 257 | thread->processor_id = processor_id; | 269 | thread->processor_id = processor_id; |
| 258 | thread->wait_objects.clear(); | 270 | thread->wait_objects.clear(); |
| 259 | thread->wait_address = 0; | 271 | thread->mutex_wait_address = 0; |
| 272 | thread->condvar_wait_address = 0; | ||
| 273 | thread->wait_handle = 0; | ||
| 260 | thread->name = std::move(name); | 274 | thread->name = std::move(name); |
| 261 | thread->callback_handle = wakeup_callback_handle_table.Create(thread).Unwrap(); | 275 | thread->callback_handle = wakeup_callback_handle_table.Create(thread).Unwrap(); |
| 262 | thread->owner_process = owner_process; | 276 | thread->owner_process = owner_process; |
| @@ -276,8 +290,8 @@ ResultVal<SharedPtr<Thread>> Thread::Create(std::string name, VAddr entry_point, | |||
| 276 | auto& linheap_memory = memory_region->linear_heap_memory; | 290 | auto& linheap_memory = memory_region->linear_heap_memory; |
| 277 | 291 | ||
| 278 | if (linheap_memory->size() + Memory::PAGE_SIZE > memory_region->size) { | 292 | if (linheap_memory->size() + Memory::PAGE_SIZE > memory_region->size) { |
| 279 | LOG_ERROR(Kernel_SVC, | 293 | NGLOG_ERROR(Kernel_SVC, |
| 280 | "Not enough space in region to allocate a new TLS page for thread"); | 294 | "Not enough space in region to allocate a new TLS page for thread"); |
| 281 | return ERR_OUT_OF_MEMORY; | 295 | return ERR_OUT_OF_MEMORY; |
| 282 | } | 296 | } |
| 283 | 297 | ||
| @@ -317,17 +331,8 @@ ResultVal<SharedPtr<Thread>> Thread::Create(std::string name, VAddr entry_point, | |||
| 317 | void Thread::SetPriority(u32 priority) { | 331 | void Thread::SetPriority(u32 priority) { |
| 318 | ASSERT_MSG(priority <= THREADPRIO_LOWEST && priority >= THREADPRIO_HIGHEST, | 332 | ASSERT_MSG(priority <= THREADPRIO_LOWEST && priority >= THREADPRIO_HIGHEST, |
| 319 | "Invalid priority value."); | 333 | "Invalid priority value."); |
| 320 | Core::System::GetInstance().Scheduler().SetThreadPriority(this, priority); | 334 | nominal_priority = priority; |
| 321 | nominal_priority = current_priority = priority; | 335 | UpdatePriority(); |
| 322 | } | ||
| 323 | |||
| 324 | void Thread::UpdatePriority() { | ||
| 325 | u32 best_priority = nominal_priority; | ||
| 326 | for (auto& mutex : held_mutexes) { | ||
| 327 | if (mutex->priority < best_priority) | ||
| 328 | best_priority = mutex->priority; | ||
| 329 | } | ||
| 330 | BoostPriority(best_priority); | ||
| 331 | } | 336 | } |
| 332 | 337 | ||
| 333 | void Thread::BoostPriority(u32 priority) { | 338 | void Thread::BoostPriority(u32 priority) { |
| @@ -377,6 +382,38 @@ VAddr Thread::GetCommandBufferAddress() const { | |||
| 377 | return GetTLSAddress() + CommandHeaderOffset; | 382 | return GetTLSAddress() + CommandHeaderOffset; |
| 378 | } | 383 | } |
| 379 | 384 | ||
| 385 | void Thread::AddMutexWaiter(SharedPtr<Thread> thread) { | ||
| 386 | thread->lock_owner = this; | ||
| 387 | wait_mutex_threads.emplace_back(std::move(thread)); | ||
| 388 | UpdatePriority(); | ||
| 389 | } | ||
| 390 | |||
| 391 | void Thread::RemoveMutexWaiter(SharedPtr<Thread> thread) { | ||
| 392 | boost::remove_erase(wait_mutex_threads, thread); | ||
| 393 | thread->lock_owner = nullptr; | ||
| 394 | UpdatePriority(); | ||
| 395 | } | ||
| 396 | |||
| 397 | void Thread::UpdatePriority() { | ||
| 398 | // Find the highest priority among all the threads that are waiting for this thread's lock | ||
| 399 | u32 new_priority = nominal_priority; | ||
| 400 | for (const auto& thread : wait_mutex_threads) { | ||
| 401 | if (thread->nominal_priority < new_priority) | ||
| 402 | new_priority = thread->nominal_priority; | ||
| 403 | } | ||
| 404 | |||
| 405 | if (new_priority == current_priority) | ||
| 406 | return; | ||
| 407 | |||
| 408 | Core::System::GetInstance().Scheduler().SetThreadPriority(this, new_priority); | ||
| 409 | |||
| 410 | current_priority = new_priority; | ||
| 411 | |||
| 412 | // Recursively update the priority of the thread that depends on the priority of this one. | ||
| 413 | if (lock_owner) | ||
| 414 | lock_owner->UpdatePriority(); | ||
| 415 | } | ||
| 416 | |||
| 380 | //////////////////////////////////////////////////////////////////////////////////////////////////// | 417 | //////////////////////////////////////////////////////////////////////////////////////////////////// |
| 381 | 418 | ||
| 382 | /** | 419 | /** |
diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h index dbf47e269..e0a3c0934 100644 --- a/src/core/hle/kernel/thread.h +++ b/src/core/hle/kernel/thread.h | |||
| @@ -18,7 +18,7 @@ | |||
| 18 | enum ThreadPriority : u32 { | 18 | enum ThreadPriority : u32 { |
| 19 | THREADPRIO_HIGHEST = 0, ///< Highest thread priority | 19 | THREADPRIO_HIGHEST = 0, ///< Highest thread priority |
| 20 | THREADPRIO_USERLAND_MAX = 24, ///< Highest thread priority for userland apps | 20 | THREADPRIO_USERLAND_MAX = 24, ///< Highest thread priority for userland apps |
| 21 | THREADPRIO_DEFAULT = 48, ///< Default thread priority for userland apps | 21 | THREADPRIO_DEFAULT = 44, ///< Default thread priority for userland apps |
| 22 | THREADPRIO_LOWEST = 63, ///< Lowest thread priority | 22 | THREADPRIO_LOWEST = 63, ///< Lowest thread priority |
| 23 | }; | 23 | }; |
| 24 | 24 | ||
| @@ -43,6 +43,7 @@ enum ThreadStatus { | |||
| 43 | THREADSTATUS_WAIT_IPC, ///< Waiting for the reply from an IPC request | 43 | THREADSTATUS_WAIT_IPC, ///< Waiting for the reply from an IPC request |
| 44 | THREADSTATUS_WAIT_SYNCH_ANY, ///< Waiting due to WaitSynch1 or WaitSynchN with wait_all = false | 44 | THREADSTATUS_WAIT_SYNCH_ANY, ///< Waiting due to WaitSynch1 or WaitSynchN with wait_all = false |
| 45 | THREADSTATUS_WAIT_SYNCH_ALL, ///< Waiting due to WaitSynchronizationN with wait_all = true | 45 | THREADSTATUS_WAIT_SYNCH_ALL, ///< Waiting due to WaitSynchronizationN with wait_all = true |
| 46 | THREADSTATUS_WAIT_MUTEX, ///< Waiting due to an ArbitrateLock/WaitProcessWideKey svc | ||
| 46 | THREADSTATUS_DORMANT, ///< Created but not yet made ready | 47 | THREADSTATUS_DORMANT, ///< Created but not yet made ready |
| 47 | THREADSTATUS_DEAD ///< Run to completion, or forcefully terminated | 48 | THREADSTATUS_DEAD ///< Run to completion, or forcefully terminated |
| 48 | }; | 49 | }; |
| @@ -54,7 +55,6 @@ enum class ThreadWakeupReason { | |||
| 54 | 55 | ||
| 55 | namespace Kernel { | 56 | namespace Kernel { |
| 56 | 57 | ||
| 57 | class Mutex; | ||
| 58 | class Process; | 58 | class Process; |
| 59 | 59 | ||
| 60 | class Thread final : public WaitObject { | 60 | class Thread final : public WaitObject { |
| @@ -104,17 +104,20 @@ public: | |||
| 104 | void SetPriority(u32 priority); | 104 | void SetPriority(u32 priority); |
| 105 | 105 | ||
| 106 | /** | 106 | /** |
| 107 | * Boost's a thread's priority to the best priority among the thread's held mutexes. | ||
| 108 | * This prevents priority inversion via priority inheritance. | ||
| 109 | */ | ||
| 110 | void UpdatePriority(); | ||
| 111 | |||
| 112 | /** | ||
| 113 | * Temporarily boosts the thread's priority until the next time it is scheduled | 107 | * Temporarily boosts the thread's priority until the next time it is scheduled |
| 114 | * @param priority The new priority | 108 | * @param priority The new priority |
| 115 | */ | 109 | */ |
| 116 | void BoostPriority(u32 priority); | 110 | void BoostPriority(u32 priority); |
| 117 | 111 | ||
| 112 | /// Adds a thread to the list of threads that are waiting for a lock held by this thread. | ||
| 113 | void AddMutexWaiter(SharedPtr<Thread> thread); | ||
| 114 | |||
| 115 | /// Removes a thread from the list of threads that are waiting for a lock held by this thread. | ||
| 116 | void RemoveMutexWaiter(SharedPtr<Thread> thread); | ||
| 117 | |||
| 118 | /// Recalculates the current priority taking into account priority inheritance. | ||
| 119 | void UpdatePriority(); | ||
| 120 | |||
| 118 | /** | 121 | /** |
| 119 | * Gets the thread's thread ID | 122 | * Gets the thread's thread ID |
| 120 | * @return The thread's ID | 123 | * @return The thread's ID |
| @@ -205,19 +208,22 @@ public: | |||
| 205 | 208 | ||
| 206 | VAddr tls_address; ///< Virtual address of the Thread Local Storage of the thread | 209 | VAddr tls_address; ///< Virtual address of the Thread Local Storage of the thread |
| 207 | 210 | ||
| 208 | /// Mutexes currently held by this thread, which will be released when it exits. | ||
| 209 | boost::container::flat_set<SharedPtr<Mutex>> held_mutexes; | ||
| 210 | |||
| 211 | /// Mutexes that this thread is currently waiting for. | ||
| 212 | boost::container::flat_set<SharedPtr<Mutex>> pending_mutexes; | ||
| 213 | |||
| 214 | SharedPtr<Process> owner_process; ///< Process that owns this thread | 211 | SharedPtr<Process> owner_process; ///< Process that owns this thread |
| 215 | 212 | ||
| 216 | /// Objects that the thread is waiting on, in the same order as they were | 213 | /// Objects that the thread is waiting on, in the same order as they were |
| 217 | // passed to WaitSynchronization1/N. | 214 | // passed to WaitSynchronization1/N. |
| 218 | std::vector<SharedPtr<WaitObject>> wait_objects; | 215 | std::vector<SharedPtr<WaitObject>> wait_objects; |
| 219 | 216 | ||
| 220 | VAddr wait_address; ///< If waiting on an AddressArbiter, this is the arbitration address | 217 | /// List of threads that are waiting for a mutex that is held by this thread. |
| 218 | std::vector<SharedPtr<Thread>> wait_mutex_threads; | ||
| 219 | |||
| 220 | /// Thread that owns the lock that this thread is waiting for. | ||
| 221 | SharedPtr<Thread> lock_owner; | ||
| 222 | |||
| 223 | // If waiting on a ConditionVariable, this is the ConditionVariable address | ||
| 224 | VAddr condvar_wait_address; | ||
| 225 | VAddr mutex_wait_address; ///< If waiting on a Mutex, this is the mutex address | ||
| 226 | Handle wait_handle; ///< The handle used to wait for the mutex. | ||
| 221 | 227 | ||
| 222 | std::string name; | 228 | std::string name; |
| 223 | 229 | ||
diff --git a/src/core/hle/kernel/timer.cpp b/src/core/hle/kernel/timer.cpp index 8da745634..ad58bf043 100644 --- a/src/core/hle/kernel/timer.cpp +++ b/src/core/hle/kernel/timer.cpp | |||
| @@ -77,7 +77,7 @@ void Timer::WakeupAllWaitingThreads() { | |||
| 77 | } | 77 | } |
| 78 | 78 | ||
| 79 | void Timer::Signal(int cycles_late) { | 79 | void Timer::Signal(int cycles_late) { |
| 80 | LOG_TRACE(Kernel, "Timer %u fired", GetObjectId()); | 80 | NGLOG_TRACE(Kernel, "Timer {} fired", GetObjectId()); |
| 81 | 81 | ||
| 82 | signaled = true; | 82 | signaled = true; |
| 83 | 83 | ||
| @@ -97,7 +97,7 @@ static void TimerCallback(u64 timer_handle, int cycles_late) { | |||
| 97 | timer_callback_handle_table.Get<Timer>(static_cast<Handle>(timer_handle)); | 97 | timer_callback_handle_table.Get<Timer>(static_cast<Handle>(timer_handle)); |
| 98 | 98 | ||
| 99 | if (timer == nullptr) { | 99 | if (timer == nullptr) { |
| 100 | LOG_CRITICAL(Kernel, "Callback fired for invalid timer %08" PRIx64, timer_handle); | 100 | NGLOG_CRITICAL(Kernel, "Callback fired for invalid timer {:016X}", timer_handle); |
| 101 | return; | 101 | return; |
| 102 | } | 102 | } |
| 103 | 103 | ||
diff --git a/src/core/hle/kernel/vm_manager.cpp b/src/core/hle/kernel/vm_manager.cpp index acd65ee68..eb2e35eed 100644 --- a/src/core/hle/kernel/vm_manager.cpp +++ b/src/core/hle/kernel/vm_manager.cpp | |||
| @@ -379,22 +379,22 @@ void VMManager::UpdatePageTableForVMA(const VirtualMemoryArea& vma) { | |||
| 379 | } | 379 | } |
| 380 | 380 | ||
| 381 | u64 VMManager::GetTotalMemoryUsage() { | 381 | u64 VMManager::GetTotalMemoryUsage() { |
| 382 | LOG_WARNING(Kernel, "(STUBBED) called"); | 382 | NGLOG_WARNING(Kernel, "(STUBBED) called"); |
| 383 | return 0xF8000000; | 383 | return 0xF8000000; |
| 384 | } | 384 | } |
| 385 | 385 | ||
| 386 | u64 VMManager::GetTotalHeapUsage() { | 386 | u64 VMManager::GetTotalHeapUsage() { |
| 387 | LOG_WARNING(Kernel, "(STUBBED) called"); | 387 | NGLOG_WARNING(Kernel, "(STUBBED) called"); |
| 388 | return 0x0; | 388 | return 0x0; |
| 389 | } | 389 | } |
| 390 | 390 | ||
| 391 | VAddr VMManager::GetAddressSpaceBaseAddr() { | 391 | VAddr VMManager::GetAddressSpaceBaseAddr() { |
| 392 | LOG_WARNING(Kernel, "(STUBBED) called"); | 392 | NGLOG_WARNING(Kernel, "(STUBBED) called"); |
| 393 | return 0x8000000; | 393 | return 0x8000000; |
| 394 | } | 394 | } |
| 395 | 395 | ||
| 396 | u64 VMManager::GetAddressSpaceSize() { | 396 | u64 VMManager::GetAddressSpaceSize() { |
| 397 | LOG_WARNING(Kernel, "(STUBBED) called"); | 397 | NGLOG_WARNING(Kernel, "(STUBBED) called"); |
| 398 | return MAX_ADDRESS; | 398 | return MAX_ADDRESS; |
| 399 | } | 399 | } |
| 400 | 400 | ||
diff --git a/src/core/hle/service/acc/acc.cpp b/src/core/hle/service/acc/acc.cpp index 6bafb2dce..f2fffa760 100644 --- a/src/core/hle/service/acc/acc.cpp +++ b/src/core/hle/service/acc/acc.cpp | |||
| @@ -47,7 +47,7 @@ public: | |||
| 47 | 47 | ||
| 48 | private: | 48 | private: |
| 49 | void GetBase(Kernel::HLERequestContext& ctx) { | 49 | void GetBase(Kernel::HLERequestContext& ctx) { |
| 50 | LOG_WARNING(Service_ACC, "(STUBBED) called"); | 50 | NGLOG_WARNING(Service_ACC, "(STUBBED) called"); |
| 51 | ProfileBase profile_base{}; | 51 | ProfileBase profile_base{}; |
| 52 | IPC::ResponseBuilder rb{ctx, 16}; | 52 | IPC::ResponseBuilder rb{ctx, 16}; |
| 53 | rb.Push(RESULT_SUCCESS); | 53 | rb.Push(RESULT_SUCCESS); |
| @@ -72,14 +72,14 @@ public: | |||
| 72 | 72 | ||
| 73 | private: | 73 | private: |
| 74 | void CheckAvailability(Kernel::HLERequestContext& ctx) { | 74 | void CheckAvailability(Kernel::HLERequestContext& ctx) { |
| 75 | LOG_WARNING(Service_ACC, "(STUBBED) called"); | 75 | NGLOG_WARNING(Service_ACC, "(STUBBED) called"); |
| 76 | IPC::ResponseBuilder rb{ctx, 3}; | 76 | IPC::ResponseBuilder rb{ctx, 3}; |
| 77 | rb.Push(RESULT_SUCCESS); | 77 | rb.Push(RESULT_SUCCESS); |
| 78 | rb.Push(true); // TODO: Check when this is supposed to return true and when not | 78 | rb.Push(true); // TODO: Check when this is supposed to return true and when not |
| 79 | } | 79 | } |
| 80 | 80 | ||
| 81 | void GetAccountId(Kernel::HLERequestContext& ctx) { | 81 | void GetAccountId(Kernel::HLERequestContext& ctx) { |
| 82 | LOG_WARNING(Service_ACC, "(STUBBED) called"); | 82 | NGLOG_WARNING(Service_ACC, "(STUBBED) called"); |
| 83 | IPC::ResponseBuilder rb{ctx, 4}; | 83 | IPC::ResponseBuilder rb{ctx, 4}; |
| 84 | rb.Push(RESULT_SUCCESS); | 84 | rb.Push(RESULT_SUCCESS); |
| 85 | rb.Push<u64>(0x12345678ABCDEF); | 85 | rb.Push<u64>(0x12345678ABCDEF); |
| @@ -87,14 +87,14 @@ private: | |||
| 87 | }; | 87 | }; |
| 88 | 88 | ||
| 89 | void Module::Interface::GetUserExistence(Kernel::HLERequestContext& ctx) { | 89 | void Module::Interface::GetUserExistence(Kernel::HLERequestContext& ctx) { |
| 90 | LOG_WARNING(Service_ACC, "(STUBBED) called"); | 90 | NGLOG_WARNING(Service_ACC, "(STUBBED) called"); |
| 91 | IPC::ResponseBuilder rb{ctx, 3}; | 91 | IPC::ResponseBuilder rb{ctx, 3}; |
| 92 | rb.Push(RESULT_SUCCESS); | 92 | rb.Push(RESULT_SUCCESS); |
| 93 | rb.Push(true); // TODO: Check when this is supposed to return true and when not | 93 | rb.Push(true); // TODO: Check when this is supposed to return true and when not |
| 94 | } | 94 | } |
| 95 | 95 | ||
| 96 | void Module::Interface::ListAllUsers(Kernel::HLERequestContext& ctx) { | 96 | void Module::Interface::ListAllUsers(Kernel::HLERequestContext& ctx) { |
| 97 | LOG_WARNING(Service_ACC, "(STUBBED) called"); | 97 | NGLOG_WARNING(Service_ACC, "(STUBBED) called"); |
| 98 | constexpr std::array<u128, 10> user_ids{DEFAULT_USER_ID}; | 98 | constexpr std::array<u128, 10> user_ids{DEFAULT_USER_ID}; |
| 99 | ctx.WriteBuffer(user_ids.data(), user_ids.size()); | 99 | ctx.WriteBuffer(user_ids.data(), user_ids.size()); |
| 100 | IPC::ResponseBuilder rb{ctx, 2}; | 100 | IPC::ResponseBuilder rb{ctx, 2}; |
| @@ -102,7 +102,7 @@ void Module::Interface::ListAllUsers(Kernel::HLERequestContext& ctx) { | |||
| 102 | } | 102 | } |
| 103 | 103 | ||
| 104 | void Module::Interface::ListOpenUsers(Kernel::HLERequestContext& ctx) { | 104 | void Module::Interface::ListOpenUsers(Kernel::HLERequestContext& ctx) { |
| 105 | LOG_WARNING(Service_ACC, "(STUBBED) called"); | 105 | NGLOG_WARNING(Service_ACC, "(STUBBED) called"); |
| 106 | constexpr std::array<u128, 10> user_ids{DEFAULT_USER_ID}; | 106 | constexpr std::array<u128, 10> user_ids{DEFAULT_USER_ID}; |
| 107 | ctx.WriteBuffer(user_ids.data(), user_ids.size()); | 107 | ctx.WriteBuffer(user_ids.data(), user_ids.size()); |
| 108 | IPC::ResponseBuilder rb{ctx, 2}; | 108 | IPC::ResponseBuilder rb{ctx, 2}; |
| @@ -113,11 +113,11 @@ void Module::Interface::GetProfile(Kernel::HLERequestContext& ctx) { | |||
| 113 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | 113 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; |
| 114 | rb.Push(RESULT_SUCCESS); | 114 | rb.Push(RESULT_SUCCESS); |
| 115 | rb.PushIpcInterface<IProfile>(); | 115 | rb.PushIpcInterface<IProfile>(); |
| 116 | LOG_DEBUG(Service_ACC, "called"); | 116 | NGLOG_DEBUG(Service_ACC, "called"); |
| 117 | } | 117 | } |
| 118 | 118 | ||
| 119 | void Module::Interface::InitializeApplicationInfo(Kernel::HLERequestContext& ctx) { | 119 | void Module::Interface::InitializeApplicationInfo(Kernel::HLERequestContext& ctx) { |
| 120 | LOG_WARNING(Service_ACC, "(STUBBED) called"); | 120 | NGLOG_WARNING(Service_ACC, "(STUBBED) called"); |
| 121 | IPC::ResponseBuilder rb{ctx, 2}; | 121 | IPC::ResponseBuilder rb{ctx, 2}; |
| 122 | rb.Push(RESULT_SUCCESS); | 122 | rb.Push(RESULT_SUCCESS); |
| 123 | } | 123 | } |
| @@ -126,11 +126,11 @@ void Module::Interface::GetBaasAccountManagerForApplication(Kernel::HLERequestCo | |||
| 126 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | 126 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; |
| 127 | rb.Push(RESULT_SUCCESS); | 127 | rb.Push(RESULT_SUCCESS); |
| 128 | rb.PushIpcInterface<IManagerForApplication>(); | 128 | rb.PushIpcInterface<IManagerForApplication>(); |
| 129 | LOG_DEBUG(Service_ACC, "called"); | 129 | NGLOG_DEBUG(Service_ACC, "called"); |
| 130 | } | 130 | } |
| 131 | 131 | ||
| 132 | void Module::Interface::GetLastOpenedUser(Kernel::HLERequestContext& ctx) { | 132 | void Module::Interface::GetLastOpenedUser(Kernel::HLERequestContext& ctx) { |
| 133 | LOG_WARNING(Service_ACC, "(STUBBED) called"); | 133 | NGLOG_WARNING(Service_ACC, "(STUBBED) called"); |
| 134 | IPC::ResponseBuilder rb{ctx, 6}; | 134 | IPC::ResponseBuilder rb{ctx, 6}; |
| 135 | rb.Push(RESULT_SUCCESS); | 135 | rb.Push(RESULT_SUCCESS); |
| 136 | rb.PushRaw(DEFAULT_USER_ID); | 136 | rb.PushRaw(DEFAULT_USER_ID); |
diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp index f41a59afe..19fadcb8e 100644 --- a/src/core/hle/service/am/am.cpp +++ b/src/core/hle/service/am/am.cpp | |||
| @@ -28,14 +28,14 @@ IWindowController::IWindowController() : ServiceFramework("IWindowController") { | |||
| 28 | } | 28 | } |
| 29 | 29 | ||
| 30 | void IWindowController::GetAppletResourceUserId(Kernel::HLERequestContext& ctx) { | 30 | void IWindowController::GetAppletResourceUserId(Kernel::HLERequestContext& ctx) { |
| 31 | LOG_WARNING(Service_AM, "(STUBBED) called"); | 31 | NGLOG_WARNING(Service_AM, "(STUBBED) called"); |
| 32 | IPC::ResponseBuilder rb{ctx, 4}; | 32 | IPC::ResponseBuilder rb{ctx, 4}; |
| 33 | rb.Push(RESULT_SUCCESS); | 33 | rb.Push(RESULT_SUCCESS); |
| 34 | rb.Push<u64>(0); | 34 | rb.Push<u64>(0); |
| 35 | } | 35 | } |
| 36 | 36 | ||
| 37 | void IWindowController::AcquireForegroundRights(Kernel::HLERequestContext& ctx) { | 37 | void IWindowController::AcquireForegroundRights(Kernel::HLERequestContext& ctx) { |
| 38 | LOG_WARNING(Service_AM, "(STUBBED) called"); | 38 | NGLOG_WARNING(Service_AM, "(STUBBED) called"); |
| 39 | IPC::ResponseBuilder rb{ctx, 2}; | 39 | IPC::ResponseBuilder rb{ctx, 2}; |
| 40 | rb.Push(RESULT_SUCCESS); | 40 | rb.Push(RESULT_SUCCESS); |
| 41 | } | 41 | } |
| @@ -54,20 +54,20 @@ IAudioController::IAudioController() : ServiceFramework("IAudioController") { | |||
| 54 | } | 54 | } |
| 55 | 55 | ||
| 56 | void IAudioController::SetExpectedMasterVolume(Kernel::HLERequestContext& ctx) { | 56 | void IAudioController::SetExpectedMasterVolume(Kernel::HLERequestContext& ctx) { |
| 57 | LOG_WARNING(Service_AM, "(STUBBED) called"); | 57 | NGLOG_WARNING(Service_AM, "(STUBBED) called"); |
| 58 | IPC::ResponseBuilder rb{ctx, 2}; | 58 | IPC::ResponseBuilder rb{ctx, 2}; |
| 59 | rb.Push(RESULT_SUCCESS); | 59 | rb.Push(RESULT_SUCCESS); |
| 60 | } | 60 | } |
| 61 | 61 | ||
| 62 | void IAudioController::GetMainAppletExpectedMasterVolume(Kernel::HLERequestContext& ctx) { | 62 | void IAudioController::GetMainAppletExpectedMasterVolume(Kernel::HLERequestContext& ctx) { |
| 63 | LOG_WARNING(Service_AM, "(STUBBED) called"); | 63 | NGLOG_WARNING(Service_AM, "(STUBBED) called"); |
| 64 | IPC::ResponseBuilder rb{ctx, 3}; | 64 | IPC::ResponseBuilder rb{ctx, 3}; |
| 65 | rb.Push(RESULT_SUCCESS); | 65 | rb.Push(RESULT_SUCCESS); |
| 66 | rb.Push(volume); | 66 | rb.Push(volume); |
| 67 | } | 67 | } |
| 68 | 68 | ||
| 69 | void IAudioController::GetLibraryAppletExpectedMasterVolume(Kernel::HLERequestContext& ctx) { | 69 | void IAudioController::GetLibraryAppletExpectedMasterVolume(Kernel::HLERequestContext& ctx) { |
| 70 | LOG_WARNING(Service_AM, "(STUBBED) called"); | 70 | NGLOG_WARNING(Service_AM, "(STUBBED) called"); |
| 71 | IPC::ResponseBuilder rb{ctx, 3}; | 71 | IPC::ResponseBuilder rb{ctx, 3}; |
| 72 | rb.Push(RESULT_SUCCESS); | 72 | rb.Push(RESULT_SUCCESS); |
| 73 | rb.Push(volume); | 73 | rb.Push(volume); |
| @@ -139,14 +139,14 @@ void ISelfController::SetFocusHandlingMode(Kernel::HLERequestContext& ctx) { | |||
| 139 | IPC::ResponseBuilder rb{ctx, 2}; | 139 | IPC::ResponseBuilder rb{ctx, 2}; |
| 140 | rb.Push(RESULT_SUCCESS); | 140 | rb.Push(RESULT_SUCCESS); |
| 141 | 141 | ||
| 142 | LOG_WARNING(Service_AM, "(STUBBED) called"); | 142 | NGLOG_WARNING(Service_AM, "(STUBBED) called"); |
| 143 | } | 143 | } |
| 144 | 144 | ||
| 145 | void ISelfController::SetRestartMessageEnabled(Kernel::HLERequestContext& ctx) { | 145 | void ISelfController::SetRestartMessageEnabled(Kernel::HLERequestContext& ctx) { |
| 146 | IPC::ResponseBuilder rb{ctx, 2}; | 146 | IPC::ResponseBuilder rb{ctx, 2}; |
| 147 | rb.Push(RESULT_SUCCESS); | 147 | rb.Push(RESULT_SUCCESS); |
| 148 | 148 | ||
| 149 | LOG_WARNING(Service_AM, "(STUBBED) called"); | 149 | NGLOG_WARNING(Service_AM, "(STUBBED) called"); |
| 150 | } | 150 | } |
| 151 | 151 | ||
| 152 | void ISelfController::SetPerformanceModeChangedNotification(Kernel::HLERequestContext& ctx) { | 152 | void ISelfController::SetPerformanceModeChangedNotification(Kernel::HLERequestContext& ctx) { |
| @@ -157,14 +157,14 @@ void ISelfController::SetPerformanceModeChangedNotification(Kernel::HLERequestCo | |||
| 157 | IPC::ResponseBuilder rb{ctx, 2}; | 157 | IPC::ResponseBuilder rb{ctx, 2}; |
| 158 | rb.Push(RESULT_SUCCESS); | 158 | rb.Push(RESULT_SUCCESS); |
| 159 | 159 | ||
| 160 | LOG_WARNING(Service_AM, "(STUBBED) called flag=%u", static_cast<u32>(flag)); | 160 | NGLOG_WARNING(Service_AM, "(STUBBED) called flag={}", flag); |
| 161 | } | 161 | } |
| 162 | 162 | ||
| 163 | void ISelfController::SetScreenShotPermission(Kernel::HLERequestContext& ctx) { | 163 | void ISelfController::SetScreenShotPermission(Kernel::HLERequestContext& ctx) { |
| 164 | IPC::ResponseBuilder rb{ctx, 2}; | 164 | IPC::ResponseBuilder rb{ctx, 2}; |
| 165 | rb.Push(RESULT_SUCCESS); | 165 | rb.Push(RESULT_SUCCESS); |
| 166 | 166 | ||
| 167 | LOG_WARNING(Service_AM, "(STUBBED) called"); | 167 | NGLOG_WARNING(Service_AM, "(STUBBED) called"); |
| 168 | } | 168 | } |
| 169 | 169 | ||
| 170 | void ISelfController::SetOperationModeChangedNotification(Kernel::HLERequestContext& ctx) { | 170 | void ISelfController::SetOperationModeChangedNotification(Kernel::HLERequestContext& ctx) { |
| @@ -175,7 +175,7 @@ void ISelfController::SetOperationModeChangedNotification(Kernel::HLERequestCont | |||
| 175 | IPC::ResponseBuilder rb{ctx, 2}; | 175 | IPC::ResponseBuilder rb{ctx, 2}; |
| 176 | rb.Push(RESULT_SUCCESS); | 176 | rb.Push(RESULT_SUCCESS); |
| 177 | 177 | ||
| 178 | LOG_WARNING(Service_AM, "(STUBBED) called flag=%u", static_cast<u32>(flag)); | 178 | NGLOG_WARNING(Service_AM, "(STUBBED) called flag={}", flag); |
| 179 | } | 179 | } |
| 180 | 180 | ||
| 181 | void ISelfController::SetOutOfFocusSuspendingEnabled(Kernel::HLERequestContext& ctx) { | 181 | void ISelfController::SetOutOfFocusSuspendingEnabled(Kernel::HLERequestContext& ctx) { |
| @@ -188,21 +188,21 @@ void ISelfController::SetOutOfFocusSuspendingEnabled(Kernel::HLERequestContext& | |||
| 188 | IPC::ResponseBuilder rb{ctx, 2}; | 188 | IPC::ResponseBuilder rb{ctx, 2}; |
| 189 | rb.Push(RESULT_SUCCESS); | 189 | rb.Push(RESULT_SUCCESS); |
| 190 | 190 | ||
| 191 | LOG_WARNING(Service_AM, "(STUBBED) called enabled=%u", static_cast<u32>(enabled)); | 191 | NGLOG_WARNING(Service_AM, "(STUBBED) called enabled={}", enabled); |
| 192 | } | 192 | } |
| 193 | 193 | ||
| 194 | void ISelfController::LockExit(Kernel::HLERequestContext& ctx) { | 194 | void ISelfController::LockExit(Kernel::HLERequestContext& ctx) { |
| 195 | IPC::ResponseBuilder rb{ctx, 2}; | 195 | IPC::ResponseBuilder rb{ctx, 2}; |
| 196 | rb.Push(RESULT_SUCCESS); | 196 | rb.Push(RESULT_SUCCESS); |
| 197 | 197 | ||
| 198 | LOG_WARNING(Service_AM, "(STUBBED) called"); | 198 | NGLOG_WARNING(Service_AM, "(STUBBED) called"); |
| 199 | } | 199 | } |
| 200 | 200 | ||
| 201 | void ISelfController::UnlockExit(Kernel::HLERequestContext& ctx) { | 201 | void ISelfController::UnlockExit(Kernel::HLERequestContext& ctx) { |
| 202 | IPC::ResponseBuilder rb{ctx, 2}; | 202 | IPC::ResponseBuilder rb{ctx, 2}; |
| 203 | rb.Push(RESULT_SUCCESS); | 203 | rb.Push(RESULT_SUCCESS); |
| 204 | 204 | ||
| 205 | LOG_WARNING(Service_AM, "(STUBBED) called"); | 205 | NGLOG_WARNING(Service_AM, "(STUBBED) called"); |
| 206 | } | 206 | } |
| 207 | 207 | ||
| 208 | void ISelfController::GetLibraryAppletLaunchableEvent(Kernel::HLERequestContext& ctx) { | 208 | void ISelfController::GetLibraryAppletLaunchableEvent(Kernel::HLERequestContext& ctx) { |
| @@ -212,7 +212,7 @@ void ISelfController::GetLibraryAppletLaunchableEvent(Kernel::HLERequestContext& | |||
| 212 | rb.Push(RESULT_SUCCESS); | 212 | rb.Push(RESULT_SUCCESS); |
| 213 | rb.PushCopyObjects(launchable_event); | 213 | rb.PushCopyObjects(launchable_event); |
| 214 | 214 | ||
| 215 | LOG_WARNING(Service_AM, "(STUBBED) called"); | 215 | NGLOG_WARNING(Service_AM, "(STUBBED) called"); |
| 216 | } | 216 | } |
| 217 | 217 | ||
| 218 | void ISelfController::CreateManagedDisplayLayer(Kernel::HLERequestContext& ctx) { | 218 | void ISelfController::CreateManagedDisplayLayer(Kernel::HLERequestContext& ctx) { |
| @@ -225,7 +225,7 @@ void ISelfController::CreateManagedDisplayLayer(Kernel::HLERequestContext& ctx) | |||
| 225 | rb.Push(RESULT_SUCCESS); | 225 | rb.Push(RESULT_SUCCESS); |
| 226 | rb.Push(layer_id); | 226 | rb.Push(layer_id); |
| 227 | 227 | ||
| 228 | LOG_WARNING(Service_AM, "(STUBBED) called"); | 228 | NGLOG_WARNING(Service_AM, "(STUBBED) called"); |
| 229 | } | 229 | } |
| 230 | 230 | ||
| 231 | ICommonStateGetter::ICommonStateGetter() : ServiceFramework("ICommonStateGetter") { | 231 | ICommonStateGetter::ICommonStateGetter() : ServiceFramework("ICommonStateGetter") { |
| @@ -269,7 +269,7 @@ void ICommonStateGetter::GetEventHandle(Kernel::HLERequestContext& ctx) { | |||
| 269 | rb.Push(RESULT_SUCCESS); | 269 | rb.Push(RESULT_SUCCESS); |
| 270 | rb.PushCopyObjects(event); | 270 | rb.PushCopyObjects(event); |
| 271 | 271 | ||
| 272 | LOG_WARNING(Service_AM, "(STUBBED) called"); | 272 | NGLOG_WARNING(Service_AM, "(STUBBED) called"); |
| 273 | } | 273 | } |
| 274 | 274 | ||
| 275 | void ICommonStateGetter::ReceiveMessage(Kernel::HLERequestContext& ctx) { | 275 | void ICommonStateGetter::ReceiveMessage(Kernel::HLERequestContext& ctx) { |
| @@ -277,7 +277,7 @@ void ICommonStateGetter::ReceiveMessage(Kernel::HLERequestContext& ctx) { | |||
| 277 | rb.Push(RESULT_SUCCESS); | 277 | rb.Push(RESULT_SUCCESS); |
| 278 | rb.Push<u32>(15); | 278 | rb.Push<u32>(15); |
| 279 | 279 | ||
| 280 | LOG_WARNING(Service_AM, "(STUBBED) called"); | 280 | NGLOG_WARNING(Service_AM, "(STUBBED) called"); |
| 281 | } | 281 | } |
| 282 | 282 | ||
| 283 | void ICommonStateGetter::GetCurrentFocusState(Kernel::HLERequestContext& ctx) { | 283 | void ICommonStateGetter::GetCurrentFocusState(Kernel::HLERequestContext& ctx) { |
| @@ -285,7 +285,7 @@ void ICommonStateGetter::GetCurrentFocusState(Kernel::HLERequestContext& ctx) { | |||
| 285 | rb.Push(RESULT_SUCCESS); | 285 | rb.Push(RESULT_SUCCESS); |
| 286 | rb.Push(static_cast<u8>(FocusState::InFocus)); | 286 | rb.Push(static_cast<u8>(FocusState::InFocus)); |
| 287 | 287 | ||
| 288 | LOG_WARNING(Service_AM, "(STUBBED) called"); | 288 | NGLOG_WARNING(Service_AM, "(STUBBED) called"); |
| 289 | } | 289 | } |
| 290 | 290 | ||
| 291 | void ICommonStateGetter::GetOperationMode(Kernel::HLERequestContext& ctx) { | 291 | void ICommonStateGetter::GetOperationMode(Kernel::HLERequestContext& ctx) { |
| @@ -294,7 +294,7 @@ void ICommonStateGetter::GetOperationMode(Kernel::HLERequestContext& ctx) { | |||
| 294 | rb.Push(RESULT_SUCCESS); | 294 | rb.Push(RESULT_SUCCESS); |
| 295 | rb.Push(static_cast<u8>(use_docked_mode ? OperationMode::Docked : OperationMode::Handheld)); | 295 | rb.Push(static_cast<u8>(use_docked_mode ? OperationMode::Docked : OperationMode::Handheld)); |
| 296 | 296 | ||
| 297 | LOG_WARNING(Service_AM, "(STUBBED) called"); | 297 | NGLOG_WARNING(Service_AM, "(STUBBED) called"); |
| 298 | } | 298 | } |
| 299 | 299 | ||
| 300 | void ICommonStateGetter::GetPerformanceMode(Kernel::HLERequestContext& ctx) { | 300 | void ICommonStateGetter::GetPerformanceMode(Kernel::HLERequestContext& ctx) { |
| @@ -304,7 +304,7 @@ void ICommonStateGetter::GetPerformanceMode(Kernel::HLERequestContext& ctx) { | |||
| 304 | rb.Push(static_cast<u32>(use_docked_mode ? APM::PerformanceMode::Docked | 304 | rb.Push(static_cast<u32>(use_docked_mode ? APM::PerformanceMode::Docked |
| 305 | : APM::PerformanceMode::Handheld)); | 305 | : APM::PerformanceMode::Handheld)); |
| 306 | 306 | ||
| 307 | LOG_WARNING(Service_AM, "(STUBBED) called"); | 307 | NGLOG_WARNING(Service_AM, "(STUBBED) called"); |
| 308 | } | 308 | } |
| 309 | 309 | ||
| 310 | class ILibraryAppletAccessor final : public ServiceFramework<ILibraryAppletAccessor> { | 310 | class ILibraryAppletAccessor final : public ServiceFramework<ILibraryAppletAccessor> { |
| @@ -344,7 +344,7 @@ private: | |||
| 344 | rb.Push(RESULT_SUCCESS); | 344 | rb.Push(RESULT_SUCCESS); |
| 345 | rb.PushCopyObjects(state_changed_event); | 345 | rb.PushCopyObjects(state_changed_event); |
| 346 | 346 | ||
| 347 | LOG_WARNING(Service_AM, "(STUBBED) called"); | 347 | NGLOG_WARNING(Service_AM, "(STUBBED) called"); |
| 348 | } | 348 | } |
| 349 | 349 | ||
| 350 | Kernel::SharedPtr<Kernel::Event> state_changed_event; | 350 | Kernel::SharedPtr<Kernel::Event> state_changed_event; |
| @@ -368,7 +368,7 @@ void ILibraryAppletCreator::CreateLibraryApplet(Kernel::HLERequestContext& ctx) | |||
| 368 | rb.Push(RESULT_SUCCESS); | 368 | rb.Push(RESULT_SUCCESS); |
| 369 | rb.PushIpcInterface<AM::ILibraryAppletAccessor>(); | 369 | rb.PushIpcInterface<AM::ILibraryAppletAccessor>(); |
| 370 | 370 | ||
| 371 | LOG_DEBUG(Service_AM, "called"); | 371 | NGLOG_DEBUG(Service_AM, "called"); |
| 372 | } | 372 | } |
| 373 | 373 | ||
| 374 | class IStorageAccessor final : public ServiceFramework<IStorageAccessor> { | 374 | class IStorageAccessor final : public ServiceFramework<IStorageAccessor> { |
| @@ -392,7 +392,7 @@ private: | |||
| 392 | rb.Push(RESULT_SUCCESS); | 392 | rb.Push(RESULT_SUCCESS); |
| 393 | rb.Push(static_cast<u64>(buffer.size())); | 393 | rb.Push(static_cast<u64>(buffer.size())); |
| 394 | 394 | ||
| 395 | LOG_DEBUG(Service_AM, "called"); | 395 | NGLOG_DEBUG(Service_AM, "called"); |
| 396 | } | 396 | } |
| 397 | 397 | ||
| 398 | void Read(Kernel::HLERequestContext& ctx) { | 398 | void Read(Kernel::HLERequestContext& ctx) { |
| @@ -410,7 +410,7 @@ private: | |||
| 410 | 410 | ||
| 411 | rb.Push(RESULT_SUCCESS); | 411 | rb.Push(RESULT_SUCCESS); |
| 412 | 412 | ||
| 413 | LOG_DEBUG(Service_AM, "called"); | 413 | NGLOG_DEBUG(Service_AM, "called"); |
| 414 | } | 414 | } |
| 415 | }; | 415 | }; |
| 416 | 416 | ||
| @@ -434,7 +434,7 @@ private: | |||
| 434 | rb.Push(RESULT_SUCCESS); | 434 | rb.Push(RESULT_SUCCESS); |
| 435 | rb.PushIpcInterface<AM::IStorageAccessor>(buffer); | 435 | rb.PushIpcInterface<AM::IStorageAccessor>(buffer); |
| 436 | 436 | ||
| 437 | LOG_DEBUG(Service_AM, "called"); | 437 | NGLOG_DEBUG(Service_AM, "called"); |
| 438 | } | 438 | } |
| 439 | }; | 439 | }; |
| 440 | 440 | ||
| @@ -498,14 +498,14 @@ void IApplicationFunctions::PopLaunchParameter(Kernel::HLERequestContext& ctx) { | |||
| 498 | rb.Push(RESULT_SUCCESS); | 498 | rb.Push(RESULT_SUCCESS); |
| 499 | rb.PushIpcInterface<AM::IStorage>(buffer); | 499 | rb.PushIpcInterface<AM::IStorage>(buffer); |
| 500 | 500 | ||
| 501 | LOG_DEBUG(Service_AM, "called"); | 501 | NGLOG_DEBUG(Service_AM, "called"); |
| 502 | } | 502 | } |
| 503 | 503 | ||
| 504 | void IApplicationFunctions::EnsureSaveData(Kernel::HLERequestContext& ctx) { | 504 | void IApplicationFunctions::EnsureSaveData(Kernel::HLERequestContext& ctx) { |
| 505 | IPC::RequestParser rp{ctx}; | 505 | IPC::RequestParser rp{ctx}; |
| 506 | u128 uid = rp.PopRaw<u128>(); | 506 | u128 uid = rp.PopRaw<u128>(); |
| 507 | 507 | ||
| 508 | LOG_WARNING(Service, "(STUBBED) called uid = %016" PRIX64 "%016" PRIX64, uid[1], uid[0]); | 508 | NGLOG_WARNING(Service, "(STUBBED) called uid = {:016X}{:016X}", uid[1], uid[0]); |
| 509 | 509 | ||
| 510 | IPC::ResponseBuilder rb{ctx, 4}; | 510 | IPC::ResponseBuilder rb{ctx, 4}; |
| 511 | 511 | ||
| @@ -533,27 +533,27 @@ void IApplicationFunctions::SetTerminateResult(Kernel::HLERequestContext& ctx) { | |||
| 533 | IPC::ResponseBuilder rb{ctx, 2}; | 533 | IPC::ResponseBuilder rb{ctx, 2}; |
| 534 | rb.Push(RESULT_SUCCESS); | 534 | rb.Push(RESULT_SUCCESS); |
| 535 | 535 | ||
| 536 | LOG_WARNING(Service_AM, "(STUBBED) called, result=0x%08X", result); | 536 | NGLOG_WARNING(Service_AM, "(STUBBED) called, result={:#010}", result); |
| 537 | } | 537 | } |
| 538 | 538 | ||
| 539 | void IApplicationFunctions::GetDesiredLanguage(Kernel::HLERequestContext& ctx) { | 539 | void IApplicationFunctions::GetDesiredLanguage(Kernel::HLERequestContext& ctx) { |
| 540 | IPC::ResponseBuilder rb{ctx, 4}; | 540 | IPC::ResponseBuilder rb{ctx, 4}; |
| 541 | rb.Push(RESULT_SUCCESS); | 541 | rb.Push(RESULT_SUCCESS); |
| 542 | rb.Push<u64>(SystemLanguage::English); | 542 | rb.Push<u64>(SystemLanguage::English); |
| 543 | LOG_WARNING(Service_AM, "(STUBBED) called"); | 543 | NGLOG_WARNING(Service_AM, "(STUBBED) called"); |
| 544 | } | 544 | } |
| 545 | 545 | ||
| 546 | void IApplicationFunctions::InitializeGamePlayRecording(Kernel::HLERequestContext& ctx) { | 546 | void IApplicationFunctions::InitializeGamePlayRecording(Kernel::HLERequestContext& ctx) { |
| 547 | IPC::ResponseBuilder rb{ctx, 2}; | 547 | IPC::ResponseBuilder rb{ctx, 2}; |
| 548 | rb.Push(RESULT_SUCCESS); | 548 | rb.Push(RESULT_SUCCESS); |
| 549 | LOG_WARNING(Service_AM, "(STUBBED) called"); | 549 | NGLOG_WARNING(Service_AM, "(STUBBED) called"); |
| 550 | } | 550 | } |
| 551 | 551 | ||
| 552 | void IApplicationFunctions::SetGamePlayRecordingState(Kernel::HLERequestContext& ctx) { | 552 | void IApplicationFunctions::SetGamePlayRecordingState(Kernel::HLERequestContext& ctx) { |
| 553 | IPC::ResponseBuilder rb{ctx, 2}; | 553 | IPC::ResponseBuilder rb{ctx, 2}; |
| 554 | rb.Push(RESULT_SUCCESS); | 554 | rb.Push(RESULT_SUCCESS); |
| 555 | 555 | ||
| 556 | LOG_WARNING(Service_AM, "(STUBBED) called"); | 556 | NGLOG_WARNING(Service_AM, "(STUBBED) called"); |
| 557 | } | 557 | } |
| 558 | 558 | ||
| 559 | void IApplicationFunctions::NotifyRunning(Kernel::HLERequestContext& ctx) { | 559 | void IApplicationFunctions::NotifyRunning(Kernel::HLERequestContext& ctx) { |
| @@ -561,7 +561,7 @@ void IApplicationFunctions::NotifyRunning(Kernel::HLERequestContext& ctx) { | |||
| 561 | rb.Push(RESULT_SUCCESS); | 561 | rb.Push(RESULT_SUCCESS); |
| 562 | rb.Push<u8>(0); // Unknown, seems to be ignored by official processes | 562 | rb.Push<u8>(0); // Unknown, seems to be ignored by official processes |
| 563 | 563 | ||
| 564 | LOG_WARNING(Service_AM, "(STUBBED) called"); | 564 | NGLOG_WARNING(Service_AM, "(STUBBED) called"); |
| 565 | } | 565 | } |
| 566 | 566 | ||
| 567 | void InstallInterfaces(SM::ServiceManager& service_manager, | 567 | void InstallInterfaces(SM::ServiceManager& service_manager, |
diff --git a/src/core/hle/service/am/applet_ae.cpp b/src/core/hle/service/am/applet_ae.cpp index 4f0698a8a..8951980cf 100644 --- a/src/core/hle/service/am/applet_ae.cpp +++ b/src/core/hle/service/am/applet_ae.cpp | |||
| @@ -33,56 +33,56 @@ private: | |||
| 33 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | 33 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; |
| 34 | rb.Push(RESULT_SUCCESS); | 34 | rb.Push(RESULT_SUCCESS); |
| 35 | rb.PushIpcInterface<ICommonStateGetter>(); | 35 | rb.PushIpcInterface<ICommonStateGetter>(); |
| 36 | LOG_DEBUG(Service_AM, "called"); | 36 | NGLOG_DEBUG(Service_AM, "called"); |
| 37 | } | 37 | } |
| 38 | 38 | ||
| 39 | void GetSelfController(Kernel::HLERequestContext& ctx) { | 39 | void GetSelfController(Kernel::HLERequestContext& ctx) { |
| 40 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | 40 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; |
| 41 | rb.Push(RESULT_SUCCESS); | 41 | rb.Push(RESULT_SUCCESS); |
| 42 | rb.PushIpcInterface<ISelfController>(nvflinger); | 42 | rb.PushIpcInterface<ISelfController>(nvflinger); |
| 43 | LOG_DEBUG(Service_AM, "called"); | 43 | NGLOG_DEBUG(Service_AM, "called"); |
| 44 | } | 44 | } |
| 45 | 45 | ||
| 46 | void GetWindowController(Kernel::HLERequestContext& ctx) { | 46 | void GetWindowController(Kernel::HLERequestContext& ctx) { |
| 47 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | 47 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; |
| 48 | rb.Push(RESULT_SUCCESS); | 48 | rb.Push(RESULT_SUCCESS); |
| 49 | rb.PushIpcInterface<IWindowController>(); | 49 | rb.PushIpcInterface<IWindowController>(); |
| 50 | LOG_DEBUG(Service_AM, "called"); | 50 | NGLOG_DEBUG(Service_AM, "called"); |
| 51 | } | 51 | } |
| 52 | 52 | ||
| 53 | void GetAudioController(Kernel::HLERequestContext& ctx) { | 53 | void GetAudioController(Kernel::HLERequestContext& ctx) { |
| 54 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | 54 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; |
| 55 | rb.Push(RESULT_SUCCESS); | 55 | rb.Push(RESULT_SUCCESS); |
| 56 | rb.PushIpcInterface<IAudioController>(); | 56 | rb.PushIpcInterface<IAudioController>(); |
| 57 | LOG_DEBUG(Service_AM, "called"); | 57 | NGLOG_DEBUG(Service_AM, "called"); |
| 58 | } | 58 | } |
| 59 | 59 | ||
| 60 | void GetDisplayController(Kernel::HLERequestContext& ctx) { | 60 | void GetDisplayController(Kernel::HLERequestContext& ctx) { |
| 61 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | 61 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; |
| 62 | rb.Push(RESULT_SUCCESS); | 62 | rb.Push(RESULT_SUCCESS); |
| 63 | rb.PushIpcInterface<IDisplayController>(); | 63 | rb.PushIpcInterface<IDisplayController>(); |
| 64 | LOG_DEBUG(Service_AM, "called"); | 64 | NGLOG_DEBUG(Service_AM, "called"); |
| 65 | } | 65 | } |
| 66 | 66 | ||
| 67 | void GetDebugFunctions(Kernel::HLERequestContext& ctx) { | 67 | void GetDebugFunctions(Kernel::HLERequestContext& ctx) { |
| 68 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | 68 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; |
| 69 | rb.Push(RESULT_SUCCESS); | 69 | rb.Push(RESULT_SUCCESS); |
| 70 | rb.PushIpcInterface<IDebugFunctions>(); | 70 | rb.PushIpcInterface<IDebugFunctions>(); |
| 71 | LOG_DEBUG(Service_AM, "called"); | 71 | NGLOG_DEBUG(Service_AM, "called"); |
| 72 | } | 72 | } |
| 73 | 73 | ||
| 74 | void GetLibraryAppletCreator(Kernel::HLERequestContext& ctx) { | 74 | void GetLibraryAppletCreator(Kernel::HLERequestContext& ctx) { |
| 75 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | 75 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; |
| 76 | rb.Push(RESULT_SUCCESS); | 76 | rb.Push(RESULT_SUCCESS); |
| 77 | rb.PushIpcInterface<ILibraryAppletCreator>(); | 77 | rb.PushIpcInterface<ILibraryAppletCreator>(); |
| 78 | LOG_DEBUG(Service_AM, "called"); | 78 | NGLOG_DEBUG(Service_AM, "called"); |
| 79 | } | 79 | } |
| 80 | 80 | ||
| 81 | void GetApplicationFunctions(Kernel::HLERequestContext& ctx) { | 81 | void GetApplicationFunctions(Kernel::HLERequestContext& ctx) { |
| 82 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | 82 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; |
| 83 | rb.Push(RESULT_SUCCESS); | 83 | rb.Push(RESULT_SUCCESS); |
| 84 | rb.PushIpcInterface<IApplicationFunctions>(); | 84 | rb.PushIpcInterface<IApplicationFunctions>(); |
| 85 | LOG_DEBUG(Service_AM, "called"); | 85 | NGLOG_DEBUG(Service_AM, "called"); |
| 86 | } | 86 | } |
| 87 | 87 | ||
| 88 | std::shared_ptr<NVFlinger::NVFlinger> nvflinger; | 88 | std::shared_ptr<NVFlinger::NVFlinger> nvflinger; |
| @@ -92,7 +92,7 @@ void AppletAE::OpenLibraryAppletProxyOld(Kernel::HLERequestContext& ctx) { | |||
| 92 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | 92 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; |
| 93 | rb.Push(RESULT_SUCCESS); | 93 | rb.Push(RESULT_SUCCESS); |
| 94 | rb.PushIpcInterface<ILibraryAppletProxy>(nvflinger); | 94 | rb.PushIpcInterface<ILibraryAppletProxy>(nvflinger); |
| 95 | LOG_DEBUG(Service_AM, "called"); | 95 | NGLOG_DEBUG(Service_AM, "called"); |
| 96 | } | 96 | } |
| 97 | 97 | ||
| 98 | AppletAE::AppletAE(std::shared_ptr<NVFlinger::NVFlinger> nvflinger) | 98 | AppletAE::AppletAE(std::shared_ptr<NVFlinger::NVFlinger> nvflinger) |
diff --git a/src/core/hle/service/am/applet_oe.cpp b/src/core/hle/service/am/applet_oe.cpp index 674b4d753..68388bf5e 100644 --- a/src/core/hle/service/am/applet_oe.cpp +++ b/src/core/hle/service/am/applet_oe.cpp | |||
| @@ -33,56 +33,56 @@ private: | |||
| 33 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | 33 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; |
| 34 | rb.Push(RESULT_SUCCESS); | 34 | rb.Push(RESULT_SUCCESS); |
| 35 | rb.PushIpcInterface<IAudioController>(); | 35 | rb.PushIpcInterface<IAudioController>(); |
| 36 | LOG_DEBUG(Service_AM, "called"); | 36 | NGLOG_DEBUG(Service_AM, "called"); |
| 37 | } | 37 | } |
| 38 | 38 | ||
| 39 | void GetDisplayController(Kernel::HLERequestContext& ctx) { | 39 | void GetDisplayController(Kernel::HLERequestContext& ctx) { |
| 40 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | 40 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; |
| 41 | rb.Push(RESULT_SUCCESS); | 41 | rb.Push(RESULT_SUCCESS); |
| 42 | rb.PushIpcInterface<IDisplayController>(); | 42 | rb.PushIpcInterface<IDisplayController>(); |
| 43 | LOG_DEBUG(Service_AM, "called"); | 43 | NGLOG_DEBUG(Service_AM, "called"); |
| 44 | } | 44 | } |
| 45 | 45 | ||
| 46 | void GetDebugFunctions(Kernel::HLERequestContext& ctx) { | 46 | void GetDebugFunctions(Kernel::HLERequestContext& ctx) { |
| 47 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | 47 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; |
| 48 | rb.Push(RESULT_SUCCESS); | 48 | rb.Push(RESULT_SUCCESS); |
| 49 | rb.PushIpcInterface<IDebugFunctions>(); | 49 | rb.PushIpcInterface<IDebugFunctions>(); |
| 50 | LOG_DEBUG(Service_AM, "called"); | 50 | NGLOG_DEBUG(Service_AM, "called"); |
| 51 | } | 51 | } |
| 52 | 52 | ||
| 53 | void GetWindowController(Kernel::HLERequestContext& ctx) { | 53 | void GetWindowController(Kernel::HLERequestContext& ctx) { |
| 54 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | 54 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; |
| 55 | rb.Push(RESULT_SUCCESS); | 55 | rb.Push(RESULT_SUCCESS); |
| 56 | rb.PushIpcInterface<IWindowController>(); | 56 | rb.PushIpcInterface<IWindowController>(); |
| 57 | LOG_DEBUG(Service_AM, "called"); | 57 | NGLOG_DEBUG(Service_AM, "called"); |
| 58 | } | 58 | } |
| 59 | 59 | ||
| 60 | void GetSelfController(Kernel::HLERequestContext& ctx) { | 60 | void GetSelfController(Kernel::HLERequestContext& ctx) { |
| 61 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | 61 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; |
| 62 | rb.Push(RESULT_SUCCESS); | 62 | rb.Push(RESULT_SUCCESS); |
| 63 | rb.PushIpcInterface<ISelfController>(nvflinger); | 63 | rb.PushIpcInterface<ISelfController>(nvflinger); |
| 64 | LOG_DEBUG(Service_AM, "called"); | 64 | NGLOG_DEBUG(Service_AM, "called"); |
| 65 | } | 65 | } |
| 66 | 66 | ||
| 67 | void GetCommonStateGetter(Kernel::HLERequestContext& ctx) { | 67 | void GetCommonStateGetter(Kernel::HLERequestContext& ctx) { |
| 68 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | 68 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; |
| 69 | rb.Push(RESULT_SUCCESS); | 69 | rb.Push(RESULT_SUCCESS); |
| 70 | rb.PushIpcInterface<ICommonStateGetter>(); | 70 | rb.PushIpcInterface<ICommonStateGetter>(); |
| 71 | LOG_DEBUG(Service_AM, "called"); | 71 | NGLOG_DEBUG(Service_AM, "called"); |
| 72 | } | 72 | } |
| 73 | 73 | ||
| 74 | void GetLibraryAppletCreator(Kernel::HLERequestContext& ctx) { | 74 | void GetLibraryAppletCreator(Kernel::HLERequestContext& ctx) { |
| 75 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | 75 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; |
| 76 | rb.Push(RESULT_SUCCESS); | 76 | rb.Push(RESULT_SUCCESS); |
| 77 | rb.PushIpcInterface<ILibraryAppletCreator>(); | 77 | rb.PushIpcInterface<ILibraryAppletCreator>(); |
| 78 | LOG_DEBUG(Service_AM, "called"); | 78 | NGLOG_DEBUG(Service_AM, "called"); |
| 79 | } | 79 | } |
| 80 | 80 | ||
| 81 | void GetApplicationFunctions(Kernel::HLERequestContext& ctx) { | 81 | void GetApplicationFunctions(Kernel::HLERequestContext& ctx) { |
| 82 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | 82 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; |
| 83 | rb.Push(RESULT_SUCCESS); | 83 | rb.Push(RESULT_SUCCESS); |
| 84 | rb.PushIpcInterface<IApplicationFunctions>(); | 84 | rb.PushIpcInterface<IApplicationFunctions>(); |
| 85 | LOG_DEBUG(Service_AM, "called"); | 85 | NGLOG_DEBUG(Service_AM, "called"); |
| 86 | } | 86 | } |
| 87 | 87 | ||
| 88 | std::shared_ptr<NVFlinger::NVFlinger> nvflinger; | 88 | std::shared_ptr<NVFlinger::NVFlinger> nvflinger; |
| @@ -92,7 +92,7 @@ void AppletOE::OpenApplicationProxy(Kernel::HLERequestContext& ctx) { | |||
| 92 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | 92 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; |
| 93 | rb.Push(RESULT_SUCCESS); | 93 | rb.Push(RESULT_SUCCESS); |
| 94 | rb.PushIpcInterface<IApplicationProxy>(nvflinger); | 94 | rb.PushIpcInterface<IApplicationProxy>(nvflinger); |
| 95 | LOG_DEBUG(Service_AM, "called"); | 95 | NGLOG_DEBUG(Service_AM, "called"); |
| 96 | } | 96 | } |
| 97 | 97 | ||
| 98 | AppletOE::AppletOE(std::shared_ptr<NVFlinger::NVFlinger> nvflinger) | 98 | AppletOE::AppletOE(std::shared_ptr<NVFlinger::NVFlinger> nvflinger) |
diff --git a/src/core/hle/service/aoc/aoc_u.cpp b/src/core/hle/service/aoc/aoc_u.cpp index 6e7438580..5b6dfb48f 100644 --- a/src/core/hle/service/aoc/aoc_u.cpp +++ b/src/core/hle/service/aoc/aoc_u.cpp | |||
| @@ -27,14 +27,14 @@ void AOC_U::CountAddOnContent(Kernel::HLERequestContext& ctx) { | |||
| 27 | IPC::ResponseBuilder rb{ctx, 4}; | 27 | IPC::ResponseBuilder rb{ctx, 4}; |
| 28 | rb.Push(RESULT_SUCCESS); | 28 | rb.Push(RESULT_SUCCESS); |
| 29 | rb.Push<u64>(0); | 29 | rb.Push<u64>(0); |
| 30 | LOG_WARNING(Service_AOC, "(STUBBED) called"); | 30 | NGLOG_WARNING(Service_AOC, "(STUBBED) called"); |
| 31 | } | 31 | } |
| 32 | 32 | ||
| 33 | void AOC_U::ListAddOnContent(Kernel::HLERequestContext& ctx) { | 33 | void AOC_U::ListAddOnContent(Kernel::HLERequestContext& ctx) { |
| 34 | IPC::ResponseBuilder rb{ctx, 4}; | 34 | IPC::ResponseBuilder rb{ctx, 4}; |
| 35 | rb.Push(RESULT_SUCCESS); | 35 | rb.Push(RESULT_SUCCESS); |
| 36 | rb.Push<u64>(0); | 36 | rb.Push<u64>(0); |
| 37 | LOG_WARNING(Service_AOC, "(STUBBED) called"); | 37 | NGLOG_WARNING(Service_AOC, "(STUBBED) called"); |
| 38 | } | 38 | } |
| 39 | 39 | ||
| 40 | void InstallInterfaces(SM::ServiceManager& service_manager) { | 40 | void InstallInterfaces(SM::ServiceManager& service_manager) { |
diff --git a/src/core/hle/service/apm/interface.cpp b/src/core/hle/service/apm/interface.cpp index 4e11f3f14..3a03188ce 100644 --- a/src/core/hle/service/apm/interface.cpp +++ b/src/core/hle/service/apm/interface.cpp | |||
| @@ -29,8 +29,8 @@ private: | |||
| 29 | IPC::ResponseBuilder rb{ctx, 2}; | 29 | IPC::ResponseBuilder rb{ctx, 2}; |
| 30 | rb.Push(RESULT_SUCCESS); | 30 | rb.Push(RESULT_SUCCESS); |
| 31 | 31 | ||
| 32 | LOG_WARNING(Service_APM, "(STUBBED) called mode=%u config=%u", static_cast<u32>(mode), | 32 | NGLOG_WARNING(Service_APM, "(STUBBED) called mode={} config={}", static_cast<u32>(mode), |
| 33 | config); | 33 | config); |
| 34 | } | 34 | } |
| 35 | 35 | ||
| 36 | void GetPerformanceConfiguration(Kernel::HLERequestContext& ctx) { | 36 | void GetPerformanceConfiguration(Kernel::HLERequestContext& ctx) { |
| @@ -42,7 +42,7 @@ private: | |||
| 42 | rb.Push(RESULT_SUCCESS); | 42 | rb.Push(RESULT_SUCCESS); |
| 43 | rb.Push<u32>(0); // Performance configuration | 43 | rb.Push<u32>(0); // Performance configuration |
| 44 | 44 | ||
| 45 | LOG_WARNING(Service_APM, "(STUBBED) called mode=%u", static_cast<u32>(mode)); | 45 | NGLOG_WARNING(Service_APM, "(STUBBED) called mode={}", static_cast<u32>(mode)); |
| 46 | } | 46 | } |
| 47 | }; | 47 | }; |
| 48 | 48 | ||
diff --git a/src/core/hle/service/audio/audout_u.cpp b/src/core/hle/service/audio/audout_u.cpp index 2d7f8cb04..6297dc450 100644 --- a/src/core/hle/service/audio/audout_u.cpp +++ b/src/core/hle/service/audio/audout_u.cpp | |||
| @@ -60,14 +60,14 @@ public: | |||
| 60 | 60 | ||
| 61 | private: | 61 | private: |
| 62 | void GetAudioOutState(Kernel::HLERequestContext& ctx) { | 62 | void GetAudioOutState(Kernel::HLERequestContext& ctx) { |
| 63 | LOG_DEBUG(Service_Audio, "called"); | 63 | NGLOG_DEBUG(Service_Audio, "called"); |
| 64 | IPC::ResponseBuilder rb{ctx, 3}; | 64 | IPC::ResponseBuilder rb{ctx, 3}; |
| 65 | rb.Push(RESULT_SUCCESS); | 65 | rb.Push(RESULT_SUCCESS); |
| 66 | rb.Push(static_cast<u32>(audio_out_state)); | 66 | rb.Push(static_cast<u32>(audio_out_state)); |
| 67 | } | 67 | } |
| 68 | 68 | ||
| 69 | void StartAudioOut(Kernel::HLERequestContext& ctx) { | 69 | void StartAudioOut(Kernel::HLERequestContext& ctx) { |
| 70 | LOG_WARNING(Service_Audio, "(STUBBED) called"); | 70 | NGLOG_WARNING(Service_Audio, "(STUBBED) called"); |
| 71 | 71 | ||
| 72 | // Start audio | 72 | // Start audio |
| 73 | audio_out_state = AudioState::Started; | 73 | audio_out_state = AudioState::Started; |
| @@ -77,7 +77,7 @@ private: | |||
| 77 | } | 77 | } |
| 78 | 78 | ||
| 79 | void StopAudioOut(Kernel::HLERequestContext& ctx) { | 79 | void StopAudioOut(Kernel::HLERequestContext& ctx) { |
| 80 | LOG_WARNING(Service_Audio, "(STUBBED) called"); | 80 | NGLOG_WARNING(Service_Audio, "(STUBBED) called"); |
| 81 | 81 | ||
| 82 | // Stop audio | 82 | // Stop audio |
| 83 | audio_out_state = AudioState::Stopped; | 83 | audio_out_state = AudioState::Stopped; |
| @@ -89,7 +89,7 @@ private: | |||
| 89 | } | 89 | } |
| 90 | 90 | ||
| 91 | void RegisterBufferEvent(Kernel::HLERequestContext& ctx) { | 91 | void RegisterBufferEvent(Kernel::HLERequestContext& ctx) { |
| 92 | LOG_WARNING(Service_Audio, "(STUBBED) called"); | 92 | NGLOG_WARNING(Service_Audio, "(STUBBED) called"); |
| 93 | 93 | ||
| 94 | IPC::ResponseBuilder rb{ctx, 2, 1}; | 94 | IPC::ResponseBuilder rb{ctx, 2, 1}; |
| 95 | rb.Push(RESULT_SUCCESS); | 95 | rb.Push(RESULT_SUCCESS); |
| @@ -97,7 +97,7 @@ private: | |||
| 97 | } | 97 | } |
| 98 | 98 | ||
| 99 | void AppendAudioOutBuffer(Kernel::HLERequestContext& ctx) { | 99 | void AppendAudioOutBuffer(Kernel::HLERequestContext& ctx) { |
| 100 | LOG_WARNING(Service_Audio, "(STUBBED) called"); | 100 | NGLOG_WARNING(Service_Audio, "(STUBBED) called"); |
| 101 | IPC::RequestParser rp{ctx}; | 101 | IPC::RequestParser rp{ctx}; |
| 102 | 102 | ||
| 103 | const u64 key{rp.Pop<u64>()}; | 103 | const u64 key{rp.Pop<u64>()}; |
| @@ -108,7 +108,7 @@ private: | |||
| 108 | } | 108 | } |
| 109 | 109 | ||
| 110 | void GetReleasedAudioOutBuffer(Kernel::HLERequestContext& ctx) { | 110 | void GetReleasedAudioOutBuffer(Kernel::HLERequestContext& ctx) { |
| 111 | LOG_WARNING(Service_Audio, "(STUBBED) called"); | 111 | NGLOG_WARNING(Service_Audio, "(STUBBED) called"); |
| 112 | 112 | ||
| 113 | // TODO(st4rk): This is how libtransistor currently implements the | 113 | // TODO(st4rk): This is how libtransistor currently implements the |
| 114 | // GetReleasedAudioOutBuffer, it should return the key (a VAddr) to the app and this address | 114 | // GetReleasedAudioOutBuffer, it should return the key (a VAddr) to the app and this address |
| @@ -164,7 +164,7 @@ private: | |||
| 164 | }; | 164 | }; |
| 165 | 165 | ||
| 166 | void AudOutU::ListAudioOuts(Kernel::HLERequestContext& ctx) { | 166 | void AudOutU::ListAudioOuts(Kernel::HLERequestContext& ctx) { |
| 167 | LOG_WARNING(Service_Audio, "(STUBBED) called"); | 167 | NGLOG_WARNING(Service_Audio, "(STUBBED) called"); |
| 168 | IPC::RequestParser rp{ctx}; | 168 | IPC::RequestParser rp{ctx}; |
| 169 | 169 | ||
| 170 | const std::string audio_interface = "AudioInterface"; | 170 | const std::string audio_interface = "AudioInterface"; |
| @@ -180,7 +180,7 @@ void AudOutU::ListAudioOuts(Kernel::HLERequestContext& ctx) { | |||
| 180 | } | 180 | } |
| 181 | 181 | ||
| 182 | void AudOutU::OpenAudioOut(Kernel::HLERequestContext& ctx) { | 182 | void AudOutU::OpenAudioOut(Kernel::HLERequestContext& ctx) { |
| 183 | LOG_WARNING(Service_Audio, "(STUBBED) called"); | 183 | NGLOG_WARNING(Service_Audio, "(STUBBED) called"); |
| 184 | 184 | ||
| 185 | if (!audio_out_interface) { | 185 | if (!audio_out_interface) { |
| 186 | audio_out_interface = std::make_shared<IAudioOut>(); | 186 | audio_out_interface = std::make_shared<IAudioOut>(); |
diff --git a/src/core/hle/service/audio/audren_u.cpp b/src/core/hle/service/audio/audren_u.cpp index a9360614c..291885db8 100644 --- a/src/core/hle/service/audio/audren_u.cpp +++ b/src/core/hle/service/audio/audren_u.cpp | |||
| @@ -56,7 +56,7 @@ private: | |||
| 56 | } | 56 | } |
| 57 | 57 | ||
| 58 | void RequestUpdateAudioRenderer(Kernel::HLERequestContext& ctx) { | 58 | void RequestUpdateAudioRenderer(Kernel::HLERequestContext& ctx) { |
| 59 | LOG_DEBUG(Service_Audio, "%s", ctx.Description().c_str()); | 59 | NGLOG_DEBUG(Service_Audio, "{}", ctx.Description()); |
| 60 | AudioRendererResponseData response_data{}; | 60 | AudioRendererResponseData response_data{}; |
| 61 | 61 | ||
| 62 | response_data.section_0_size = | 62 | response_data.section_0_size = |
| @@ -79,7 +79,7 @@ private: | |||
| 79 | 79 | ||
| 80 | rb.Push(RESULT_SUCCESS); | 80 | rb.Push(RESULT_SUCCESS); |
| 81 | 81 | ||
| 82 | LOG_WARNING(Service_Audio, "(STUBBED) called"); | 82 | NGLOG_WARNING(Service_Audio, "(STUBBED) called"); |
| 83 | } | 83 | } |
| 84 | 84 | ||
| 85 | void StartAudioRenderer(Kernel::HLERequestContext& ctx) { | 85 | void StartAudioRenderer(Kernel::HLERequestContext& ctx) { |
| @@ -87,7 +87,7 @@ private: | |||
| 87 | 87 | ||
| 88 | rb.Push(RESULT_SUCCESS); | 88 | rb.Push(RESULT_SUCCESS); |
| 89 | 89 | ||
| 90 | LOG_WARNING(Service_Audio, "(STUBBED) called"); | 90 | NGLOG_WARNING(Service_Audio, "(STUBBED) called"); |
| 91 | } | 91 | } |
| 92 | 92 | ||
| 93 | void StopAudioRenderer(Kernel::HLERequestContext& ctx) { | 93 | void StopAudioRenderer(Kernel::HLERequestContext& ctx) { |
| @@ -95,7 +95,7 @@ private: | |||
| 95 | 95 | ||
| 96 | rb.Push(RESULT_SUCCESS); | 96 | rb.Push(RESULT_SUCCESS); |
| 97 | 97 | ||
| 98 | LOG_WARNING(Service_Audio, "(STUBBED) called"); | 98 | NGLOG_WARNING(Service_Audio, "(STUBBED) called"); |
| 99 | } | 99 | } |
| 100 | 100 | ||
| 101 | void QuerySystemEvent(Kernel::HLERequestContext& ctx) { | 101 | void QuerySystemEvent(Kernel::HLERequestContext& ctx) { |
| @@ -105,7 +105,7 @@ private: | |||
| 105 | rb.Push(RESULT_SUCCESS); | 105 | rb.Push(RESULT_SUCCESS); |
| 106 | rb.PushCopyObjects(system_event); | 106 | rb.PushCopyObjects(system_event); |
| 107 | 107 | ||
| 108 | LOG_WARNING(Service_Audio, "(STUBBED) called"); | 108 | NGLOG_WARNING(Service_Audio, "(STUBBED) called"); |
| 109 | } | 109 | } |
| 110 | 110 | ||
| 111 | struct AudioRendererStateEntry { | 111 | struct AudioRendererStateEntry { |
| @@ -177,7 +177,7 @@ public: | |||
| 177 | 177 | ||
| 178 | private: | 178 | private: |
| 179 | void ListAudioDeviceName(Kernel::HLERequestContext& ctx) { | 179 | void ListAudioDeviceName(Kernel::HLERequestContext& ctx) { |
| 180 | LOG_WARNING(Service_Audio, "(STUBBED) called"); | 180 | NGLOG_WARNING(Service_Audio, "(STUBBED) called"); |
| 181 | IPC::RequestParser rp{ctx}; | 181 | IPC::RequestParser rp{ctx}; |
| 182 | 182 | ||
| 183 | const std::string audio_interface = "AudioInterface"; | 183 | const std::string audio_interface = "AudioInterface"; |
| @@ -189,7 +189,7 @@ private: | |||
| 189 | } | 189 | } |
| 190 | 190 | ||
| 191 | void SetAudioDeviceOutputVolume(Kernel::HLERequestContext& ctx) { | 191 | void SetAudioDeviceOutputVolume(Kernel::HLERequestContext& ctx) { |
| 192 | LOG_WARNING(Service_Audio, "(STUBBED) called"); | 192 | NGLOG_WARNING(Service_Audio, "(STUBBED) called"); |
| 193 | 193 | ||
| 194 | IPC::RequestParser rp{ctx}; | 194 | IPC::RequestParser rp{ctx}; |
| 195 | f32 volume = static_cast<f32>(rp.Pop<u32>()); | 195 | f32 volume = static_cast<f32>(rp.Pop<u32>()); |
| @@ -202,7 +202,7 @@ private: | |||
| 202 | } | 202 | } |
| 203 | 203 | ||
| 204 | void GetActiveAudioDeviceName(Kernel::HLERequestContext& ctx) { | 204 | void GetActiveAudioDeviceName(Kernel::HLERequestContext& ctx) { |
| 205 | LOG_WARNING(Service_Audio, "(STUBBED) called"); | 205 | NGLOG_WARNING(Service_Audio, "(STUBBED) called"); |
| 206 | IPC::RequestParser rp{ctx}; | 206 | IPC::RequestParser rp{ctx}; |
| 207 | 207 | ||
| 208 | const std::string audio_interface = "AudioDevice"; | 208 | const std::string audio_interface = "AudioDevice"; |
| @@ -214,7 +214,7 @@ private: | |||
| 214 | } | 214 | } |
| 215 | 215 | ||
| 216 | void QueryAudioDeviceSystemEvent(Kernel::HLERequestContext& ctx) { | 216 | void QueryAudioDeviceSystemEvent(Kernel::HLERequestContext& ctx) { |
| 217 | LOG_WARNING(Service_Audio, "(STUBBED) called"); | 217 | NGLOG_WARNING(Service_Audio, "(STUBBED) called"); |
| 218 | 218 | ||
| 219 | buffer_event->Signal(); | 219 | buffer_event->Signal(); |
| 220 | 220 | ||
| @@ -224,7 +224,7 @@ private: | |||
| 224 | } | 224 | } |
| 225 | 225 | ||
| 226 | void GetActiveChannelCount(Kernel::HLERequestContext& ctx) { | 226 | void GetActiveChannelCount(Kernel::HLERequestContext& ctx) { |
| 227 | LOG_WARNING(Service_Audio, "(STUBBED) called"); | 227 | NGLOG_WARNING(Service_Audio, "(STUBBED) called"); |
| 228 | IPC::ResponseBuilder rb{ctx, 3}; | 228 | IPC::ResponseBuilder rb{ctx, 3}; |
| 229 | rb.Push(RESULT_SUCCESS); | 229 | rb.Push(RESULT_SUCCESS); |
| 230 | rb.Push<u32>(1); | 230 | rb.Push<u32>(1); |
| @@ -251,7 +251,7 @@ void AudRenU::OpenAudioRenderer(Kernel::HLERequestContext& ctx) { | |||
| 251 | rb.Push(RESULT_SUCCESS); | 251 | rb.Push(RESULT_SUCCESS); |
| 252 | rb.PushIpcInterface<Audio::IAudioRenderer>(); | 252 | rb.PushIpcInterface<Audio::IAudioRenderer>(); |
| 253 | 253 | ||
| 254 | LOG_DEBUG(Service_Audio, "called"); | 254 | NGLOG_DEBUG(Service_Audio, "called"); |
| 255 | } | 255 | } |
| 256 | 256 | ||
| 257 | void AudRenU::GetAudioRendererWorkBufferSize(Kernel::HLERequestContext& ctx) { | 257 | void AudRenU::GetAudioRendererWorkBufferSize(Kernel::HLERequestContext& ctx) { |
| @@ -260,7 +260,7 @@ void AudRenU::GetAudioRendererWorkBufferSize(Kernel::HLERequestContext& ctx) { | |||
| 260 | rb.Push(RESULT_SUCCESS); | 260 | rb.Push(RESULT_SUCCESS); |
| 261 | rb.Push<u64>(0x4000); | 261 | rb.Push<u64>(0x4000); |
| 262 | 262 | ||
| 263 | LOG_WARNING(Service_Audio, "(STUBBED) called"); | 263 | NGLOG_WARNING(Service_Audio, "(STUBBED) called"); |
| 264 | } | 264 | } |
| 265 | 265 | ||
| 266 | void AudRenU::GetAudioDevice(Kernel::HLERequestContext& ctx) { | 266 | void AudRenU::GetAudioDevice(Kernel::HLERequestContext& ctx) { |
| @@ -269,7 +269,7 @@ void AudRenU::GetAudioDevice(Kernel::HLERequestContext& ctx) { | |||
| 269 | rb.Push(RESULT_SUCCESS); | 269 | rb.Push(RESULT_SUCCESS); |
| 270 | rb.PushIpcInterface<Audio::IAudioDevice>(); | 270 | rb.PushIpcInterface<Audio::IAudioDevice>(); |
| 271 | 271 | ||
| 272 | LOG_DEBUG(Service_Audio, "called"); | 272 | NGLOG_DEBUG(Service_Audio, "called"); |
| 273 | } | 273 | } |
| 274 | 274 | ||
| 275 | } // namespace Service::Audio | 275 | } // namespace Service::Audio |
diff --git a/src/core/hle/service/fatal/fatal.cpp b/src/core/hle/service/fatal/fatal.cpp index 41d58f999..d7ad0600a 100644 --- a/src/core/hle/service/fatal/fatal.cpp +++ b/src/core/hle/service/fatal/fatal.cpp | |||
| @@ -16,13 +16,13 @@ Module::Interface::Interface(std::shared_ptr<Module> module, const char* name) | |||
| 16 | void Module::Interface::FatalSimple(Kernel::HLERequestContext& ctx) { | 16 | void Module::Interface::FatalSimple(Kernel::HLERequestContext& ctx) { |
| 17 | IPC::RequestParser rp(ctx); | 17 | IPC::RequestParser rp(ctx); |
| 18 | u32 error_code = rp.Pop<u32>(); | 18 | u32 error_code = rp.Pop<u32>(); |
| 19 | LOG_WARNING(Service_Fatal, "(STUBBED) called, error_code=0x%X", error_code); | 19 | NGLOG_WARNING(Service_Fatal, "(STUBBED) called, error_code={:#X}", error_code); |
| 20 | IPC::ResponseBuilder rb{ctx, 2}; | 20 | IPC::ResponseBuilder rb{ctx, 2}; |
| 21 | rb.Push(RESULT_SUCCESS); | 21 | rb.Push(RESULT_SUCCESS); |
| 22 | } | 22 | } |
| 23 | 23 | ||
| 24 | void Module::Interface::TransitionToFatalError(Kernel::HLERequestContext& ctx) { | 24 | void Module::Interface::TransitionToFatalError(Kernel::HLERequestContext& ctx) { |
| 25 | LOG_WARNING(Service_Fatal, "(STUBBED) called"); | 25 | NGLOG_WARNING(Service_Fatal, "(STUBBED) called"); |
| 26 | IPC::ResponseBuilder rb{ctx, 2}; | 26 | IPC::ResponseBuilder rb{ctx, 2}; |
| 27 | rb.Push(RESULT_SUCCESS); | 27 | rb.Push(RESULT_SUCCESS); |
| 28 | } | 28 | } |
diff --git a/src/core/hle/service/filesystem/filesystem.cpp b/src/core/hle/service/filesystem/filesystem.cpp index 9e504992f..c2951c560 100644 --- a/src/core/hle/service/filesystem/filesystem.cpp +++ b/src/core/hle/service/filesystem/filesystem.cpp | |||
| @@ -25,14 +25,14 @@ ResultCode RegisterFileSystem(std::unique_ptr<FileSys::FileSystemFactory>&& fact | |||
| 25 | ASSERT_MSG(inserted, "Tried to register more than one system with same id code"); | 25 | ASSERT_MSG(inserted, "Tried to register more than one system with same id code"); |
| 26 | 26 | ||
| 27 | auto& filesystem = result.first->second; | 27 | auto& filesystem = result.first->second; |
| 28 | LOG_DEBUG(Service_FS, "Registered file system %s with id code 0x%08X", | 28 | NGLOG_DEBUG(Service_FS, "Registered file system {} with id code {:#010X}", |
| 29 | filesystem->GetName().c_str(), static_cast<u32>(type)); | 29 | filesystem->GetName(), static_cast<u32>(type)); |
| 30 | return RESULT_SUCCESS; | 30 | return RESULT_SUCCESS; |
| 31 | } | 31 | } |
| 32 | 32 | ||
| 33 | ResultVal<std::unique_ptr<FileSys::FileSystemBackend>> OpenFileSystem(Type type, | 33 | ResultVal<std::unique_ptr<FileSys::FileSystemBackend>> OpenFileSystem(Type type, |
| 34 | FileSys::Path& path) { | 34 | FileSys::Path& path) { |
| 35 | LOG_TRACE(Service_FS, "Opening FileSystem with type=%d", type); | 35 | NGLOG_TRACE(Service_FS, "Opening FileSystem with type={}", static_cast<u32>(type)); |
| 36 | 36 | ||
| 37 | auto itr = filesystem_map.find(type); | 37 | auto itr = filesystem_map.find(type); |
| 38 | if (itr == filesystem_map.end()) { | 38 | if (itr == filesystem_map.end()) { |
| @@ -44,7 +44,7 @@ ResultVal<std::unique_ptr<FileSys::FileSystemBackend>> OpenFileSystem(Type type, | |||
| 44 | } | 44 | } |
| 45 | 45 | ||
| 46 | ResultCode FormatFileSystem(Type type) { | 46 | ResultCode FormatFileSystem(Type type) { |
| 47 | LOG_TRACE(Service_FS, "Formatting FileSystem with type=%d", type); | 47 | NGLOG_TRACE(Service_FS, "Formatting FileSystem with type={}", static_cast<u32>(type)); |
| 48 | 48 | ||
| 49 | auto itr = filesystem_map.find(type); | 49 | auto itr = filesystem_map.find(type); |
| 50 | if (itr == filesystem_map.end()) { | 50 | if (itr == filesystem_map.end()) { |
diff --git a/src/core/hle/service/filesystem/fsp_srv.cpp b/src/core/hle/service/filesystem/fsp_srv.cpp index 2f476c869..ed9f2ef72 100644 --- a/src/core/hle/service/filesystem/fsp_srv.cpp +++ b/src/core/hle/service/filesystem/fsp_srv.cpp | |||
| @@ -35,7 +35,7 @@ private: | |||
| 35 | const s64 offset = rp.Pop<s64>(); | 35 | const s64 offset = rp.Pop<s64>(); |
| 36 | const s64 length = rp.Pop<s64>(); | 36 | const s64 length = rp.Pop<s64>(); |
| 37 | 37 | ||
| 38 | LOG_DEBUG(Service_FS, "called, offset=0x%ld, length=0x%ld", offset, length); | 38 | NGLOG_DEBUG(Service_FS, "called, offset={:#X}, length={}", offset, length); |
| 39 | 39 | ||
| 40 | // Error checking | 40 | // Error checking |
| 41 | if (length < 0) { | 41 | if (length < 0) { |
| @@ -87,7 +87,7 @@ private: | |||
| 87 | const s64 offset = rp.Pop<s64>(); | 87 | const s64 offset = rp.Pop<s64>(); |
| 88 | const s64 length = rp.Pop<s64>(); | 88 | const s64 length = rp.Pop<s64>(); |
| 89 | 89 | ||
| 90 | LOG_DEBUG(Service_FS, "called, offset=0x%ld, length=0x%ld", offset, length); | 90 | NGLOG_DEBUG(Service_FS, "called, offset={:#X}, length={}", offset, length); |
| 91 | 91 | ||
| 92 | // Error checking | 92 | // Error checking |
| 93 | if (length < 0) { | 93 | if (length < 0) { |
| @@ -124,7 +124,7 @@ private: | |||
| 124 | const s64 offset = rp.Pop<s64>(); | 124 | const s64 offset = rp.Pop<s64>(); |
| 125 | const s64 length = rp.Pop<s64>(); | 125 | const s64 length = rp.Pop<s64>(); |
| 126 | 126 | ||
| 127 | LOG_DEBUG(Service_FS, "called, offset=0x%ld, length=0x%ld", offset, length); | 127 | NGLOG_DEBUG(Service_FS, "called, offset={:#X}, length={}", offset, length); |
| 128 | 128 | ||
| 129 | // Error checking | 129 | // Error checking |
| 130 | if (length < 0) { | 130 | if (length < 0) { |
| @@ -152,7 +152,7 @@ private: | |||
| 152 | } | 152 | } |
| 153 | 153 | ||
| 154 | void Flush(Kernel::HLERequestContext& ctx) { | 154 | void Flush(Kernel::HLERequestContext& ctx) { |
| 155 | LOG_DEBUG(Service_FS, "called"); | 155 | NGLOG_DEBUG(Service_FS, "called"); |
| 156 | backend->Flush(); | 156 | backend->Flush(); |
| 157 | 157 | ||
| 158 | IPC::ResponseBuilder rb{ctx, 2}; | 158 | IPC::ResponseBuilder rb{ctx, 2}; |
| @@ -163,7 +163,7 @@ private: | |||
| 163 | IPC::RequestParser rp{ctx}; | 163 | IPC::RequestParser rp{ctx}; |
| 164 | const u64 size = rp.Pop<u64>(); | 164 | const u64 size = rp.Pop<u64>(); |
| 165 | backend->SetSize(size); | 165 | backend->SetSize(size); |
| 166 | LOG_DEBUG(Service_FS, "called, size=%" PRIu64, size); | 166 | NGLOG_DEBUG(Service_FS, "called, size={}", size); |
| 167 | 167 | ||
| 168 | IPC::ResponseBuilder rb{ctx, 2}; | 168 | IPC::ResponseBuilder rb{ctx, 2}; |
| 169 | rb.Push(RESULT_SUCCESS); | 169 | rb.Push(RESULT_SUCCESS); |
| @@ -171,7 +171,7 @@ private: | |||
| 171 | 171 | ||
| 172 | void GetSize(Kernel::HLERequestContext& ctx) { | 172 | void GetSize(Kernel::HLERequestContext& ctx) { |
| 173 | const u64 size = backend->GetSize(); | 173 | const u64 size = backend->GetSize(); |
| 174 | LOG_DEBUG(Service_FS, "called, size=%" PRIu64, size); | 174 | NGLOG_DEBUG(Service_FS, "called, size={}", size); |
| 175 | 175 | ||
| 176 | IPC::ResponseBuilder rb{ctx, 4}; | 176 | IPC::ResponseBuilder rb{ctx, 4}; |
| 177 | rb.Push(RESULT_SUCCESS); | 177 | rb.Push(RESULT_SUCCESS); |
| @@ -197,7 +197,7 @@ private: | |||
| 197 | IPC::RequestParser rp{ctx}; | 197 | IPC::RequestParser rp{ctx}; |
| 198 | const u64 unk = rp.Pop<u64>(); | 198 | const u64 unk = rp.Pop<u64>(); |
| 199 | 199 | ||
| 200 | LOG_DEBUG(Service_FS, "called, unk=0x%llx", unk); | 200 | NGLOG_DEBUG(Service_FS, "called, unk={:#X}", unk); |
| 201 | 201 | ||
| 202 | // Calculate how many entries we can fit in the output buffer | 202 | // Calculate how many entries we can fit in the output buffer |
| 203 | u64 count_entries = ctx.GetWriteBufferSize() / sizeof(FileSys::Entry); | 203 | u64 count_entries = ctx.GetWriteBufferSize() / sizeof(FileSys::Entry); |
| @@ -219,7 +219,7 @@ private: | |||
| 219 | } | 219 | } |
| 220 | 220 | ||
| 221 | void GetEntryCount(Kernel::HLERequestContext& ctx) { | 221 | void GetEntryCount(Kernel::HLERequestContext& ctx) { |
| 222 | LOG_DEBUG(Service_FS, "called"); | 222 | NGLOG_DEBUG(Service_FS, "called"); |
| 223 | 223 | ||
| 224 | u64 count = backend->GetEntryCount(); | 224 | u64 count = backend->GetEntryCount(); |
| 225 | 225 | ||
| @@ -239,7 +239,7 @@ public: | |||
| 239 | {2, &IFileSystem::CreateDirectory, "CreateDirectory"}, | 239 | {2, &IFileSystem::CreateDirectory, "CreateDirectory"}, |
| 240 | {3, nullptr, "DeleteDirectory"}, | 240 | {3, nullptr, "DeleteDirectory"}, |
| 241 | {4, nullptr, "DeleteDirectoryRecursively"}, | 241 | {4, nullptr, "DeleteDirectoryRecursively"}, |
| 242 | {5, nullptr, "RenameFile"}, | 242 | {5, &IFileSystem::RenameFile, "RenameFile"}, |
| 243 | {6, nullptr, "RenameDirectory"}, | 243 | {6, nullptr, "RenameDirectory"}, |
| 244 | {7, &IFileSystem::GetEntryType, "GetEntryType"}, | 244 | {7, &IFileSystem::GetEntryType, "GetEntryType"}, |
| 245 | {8, &IFileSystem::OpenFile, "OpenFile"}, | 245 | {8, &IFileSystem::OpenFile, "OpenFile"}, |
| @@ -265,8 +265,7 @@ public: | |||
| 265 | u64 mode = rp.Pop<u64>(); | 265 | u64 mode = rp.Pop<u64>(); |
| 266 | u32 size = rp.Pop<u32>(); | 266 | u32 size = rp.Pop<u32>(); |
| 267 | 267 | ||
| 268 | LOG_DEBUG(Service_FS, "called file %s mode 0x%" PRIX64 " size 0x%08X", name.c_str(), mode, | 268 | NGLOG_DEBUG(Service_FS, "called file {} mode {:#X} size {:#010X}", name, mode, size); |
| 269 | size); | ||
| 270 | 269 | ||
| 271 | IPC::ResponseBuilder rb{ctx, 2}; | 270 | IPC::ResponseBuilder rb{ctx, 2}; |
| 272 | rb.Push(backend->CreateFile(name, size)); | 271 | rb.Push(backend->CreateFile(name, size)); |
| @@ -280,7 +279,7 @@ public: | |||
| 280 | 279 | ||
| 281 | std::string name(file_buffer.begin(), end); | 280 | std::string name(file_buffer.begin(), end); |
| 282 | 281 | ||
| 283 | LOG_DEBUG(Service_FS, "called file %s", name.c_str()); | 282 | NGLOG_DEBUG(Service_FS, "called file {}", name); |
| 284 | 283 | ||
| 285 | IPC::ResponseBuilder rb{ctx, 2}; | 284 | IPC::ResponseBuilder rb{ctx, 2}; |
| 286 | rb.Push(backend->DeleteFile(name)); | 285 | rb.Push(backend->DeleteFile(name)); |
| @@ -294,12 +293,32 @@ public: | |||
| 294 | 293 | ||
| 295 | std::string name(file_buffer.begin(), end); | 294 | std::string name(file_buffer.begin(), end); |
| 296 | 295 | ||
| 297 | LOG_DEBUG(Service_FS, "called directory %s", name.c_str()); | 296 | NGLOG_DEBUG(Service_FS, "called directory {}", name); |
| 298 | 297 | ||
| 299 | IPC::ResponseBuilder rb{ctx, 2}; | 298 | IPC::ResponseBuilder rb{ctx, 2}; |
| 300 | rb.Push(backend->CreateDirectory(name)); | 299 | rb.Push(backend->CreateDirectory(name)); |
| 301 | } | 300 | } |
| 302 | 301 | ||
| 302 | void RenameFile(Kernel::HLERequestContext& ctx) { | ||
| 303 | IPC::RequestParser rp{ctx}; | ||
| 304 | |||
| 305 | std::vector<u8> buffer; | ||
| 306 | buffer.resize(ctx.BufferDescriptorX()[0].Size()); | ||
| 307 | Memory::ReadBlock(ctx.BufferDescriptorX()[0].Address(), buffer.data(), buffer.size()); | ||
| 308 | auto end = std::find(buffer.begin(), buffer.end(), '\0'); | ||
| 309 | std::string src_name(buffer.begin(), end); | ||
| 310 | |||
| 311 | buffer.resize(ctx.BufferDescriptorX()[1].Size()); | ||
| 312 | Memory::ReadBlock(ctx.BufferDescriptorX()[1].Address(), buffer.data(), buffer.size()); | ||
| 313 | end = std::find(buffer.begin(), buffer.end(), '\0'); | ||
| 314 | std::string dst_name(buffer.begin(), end); | ||
| 315 | |||
| 316 | NGLOG_DEBUG(Service_FS, "called file '{}' to file '{}'", src_name, dst_name); | ||
| 317 | |||
| 318 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 319 | rb.Push(backend->RenameFile(src_name, dst_name)); | ||
| 320 | } | ||
| 321 | |||
| 303 | void OpenFile(Kernel::HLERequestContext& ctx) { | 322 | void OpenFile(Kernel::HLERequestContext& ctx) { |
| 304 | IPC::RequestParser rp{ctx}; | 323 | IPC::RequestParser rp{ctx}; |
| 305 | 324 | ||
| @@ -310,7 +329,7 @@ public: | |||
| 310 | 329 | ||
| 311 | auto mode = static_cast<FileSys::Mode>(rp.Pop<u32>()); | 330 | auto mode = static_cast<FileSys::Mode>(rp.Pop<u32>()); |
| 312 | 331 | ||
| 313 | LOG_DEBUG(Service_FS, "called file %s mode %u", name.c_str(), static_cast<u32>(mode)); | 332 | NGLOG_DEBUG(Service_FS, "called file {} mode {}", name, static_cast<u32>(mode)); |
| 314 | 333 | ||
| 315 | auto result = backend->OpenFile(name, mode); | 334 | auto result = backend->OpenFile(name, mode); |
| 316 | if (result.Failed()) { | 335 | if (result.Failed()) { |
| @@ -337,7 +356,7 @@ public: | |||
| 337 | // TODO(Subv): Implement this filter. | 356 | // TODO(Subv): Implement this filter. |
| 338 | u32 filter_flags = rp.Pop<u32>(); | 357 | u32 filter_flags = rp.Pop<u32>(); |
| 339 | 358 | ||
| 340 | LOG_DEBUG(Service_FS, "called directory %s filter %u", name.c_str(), filter_flags); | 359 | NGLOG_DEBUG(Service_FS, "called directory {} filter {}", name, filter_flags); |
| 341 | 360 | ||
| 342 | auto result = backend->OpenDirectory(name); | 361 | auto result = backend->OpenDirectory(name); |
| 343 | if (result.Failed()) { | 362 | if (result.Failed()) { |
| @@ -361,7 +380,7 @@ public: | |||
| 361 | 380 | ||
| 362 | std::string name(file_buffer.begin(), end); | 381 | std::string name(file_buffer.begin(), end); |
| 363 | 382 | ||
| 364 | LOG_DEBUG(Service_FS, "called file %s", name.c_str()); | 383 | NGLOG_DEBUG(Service_FS, "called file {}", name); |
| 365 | 384 | ||
| 366 | auto result = backend->GetEntryType(name); | 385 | auto result = backend->GetEntryType(name); |
| 367 | if (result.Failed()) { | 386 | if (result.Failed()) { |
| @@ -376,7 +395,7 @@ public: | |||
| 376 | } | 395 | } |
| 377 | 396 | ||
| 378 | void Commit(Kernel::HLERequestContext& ctx) { | 397 | void Commit(Kernel::HLERequestContext& ctx) { |
| 379 | LOG_WARNING(Service_FS, "(STUBBED) called"); | 398 | NGLOG_WARNING(Service_FS, "(STUBBED) called"); |
| 380 | 399 | ||
| 381 | IPC::ResponseBuilder rb{ctx, 2}; | 400 | IPC::ResponseBuilder rb{ctx, 2}; |
| 382 | rb.Push(RESULT_SUCCESS); | 401 | rb.Push(RESULT_SUCCESS); |
| @@ -492,14 +511,14 @@ void FSP_SRV::TryLoadRomFS() { | |||
| 492 | } | 511 | } |
| 493 | 512 | ||
| 494 | void FSP_SRV::Initialize(Kernel::HLERequestContext& ctx) { | 513 | void FSP_SRV::Initialize(Kernel::HLERequestContext& ctx) { |
| 495 | LOG_WARNING(Service_FS, "(STUBBED) called"); | 514 | NGLOG_WARNING(Service_FS, "(STUBBED) called"); |
| 496 | 515 | ||
| 497 | IPC::ResponseBuilder rb{ctx, 2}; | 516 | IPC::ResponseBuilder rb{ctx, 2}; |
| 498 | rb.Push(RESULT_SUCCESS); | 517 | rb.Push(RESULT_SUCCESS); |
| 499 | } | 518 | } |
| 500 | 519 | ||
| 501 | void FSP_SRV::MountSdCard(Kernel::HLERequestContext& ctx) { | 520 | void FSP_SRV::MountSdCard(Kernel::HLERequestContext& ctx) { |
| 502 | LOG_DEBUG(Service_FS, "called"); | 521 | NGLOG_DEBUG(Service_FS, "called"); |
| 503 | 522 | ||
| 504 | FileSys::Path unused; | 523 | FileSys::Path unused; |
| 505 | auto filesystem = OpenFileSystem(Type::SDMC, unused).Unwrap(); | 524 | auto filesystem = OpenFileSystem(Type::SDMC, unused).Unwrap(); |
| @@ -516,14 +535,14 @@ void FSP_SRV::CreateSaveData(Kernel::HLERequestContext& ctx) { | |||
| 516 | auto save_create_struct = rp.PopRaw<std::array<u8, 0x40>>(); | 535 | auto save_create_struct = rp.PopRaw<std::array<u8, 0x40>>(); |
| 517 | u128 uid = rp.PopRaw<u128>(); | 536 | u128 uid = rp.PopRaw<u128>(); |
| 518 | 537 | ||
| 519 | LOG_WARNING(Service_FS, "(STUBBED) called uid = %016" PRIX64 "%016" PRIX64, uid[1], uid[0]); | 538 | NGLOG_WARNING(Service_FS, "(STUBBED) called uid = {:016X}{:016X}", uid[1], uid[0]); |
| 520 | 539 | ||
| 521 | IPC::ResponseBuilder rb{ctx, 2}; | 540 | IPC::ResponseBuilder rb{ctx, 2}; |
| 522 | rb.Push(RESULT_SUCCESS); | 541 | rb.Push(RESULT_SUCCESS); |
| 523 | } | 542 | } |
| 524 | 543 | ||
| 525 | void FSP_SRV::MountSaveData(Kernel::HLERequestContext& ctx) { | 544 | void FSP_SRV::MountSaveData(Kernel::HLERequestContext& ctx) { |
| 526 | LOG_WARNING(Service_FS, "(STUBBED) called"); | 545 | NGLOG_WARNING(Service_FS, "(STUBBED) called"); |
| 527 | 546 | ||
| 528 | FileSys::Path unused; | 547 | FileSys::Path unused; |
| 529 | auto filesystem = OpenFileSystem(Type::SaveData, unused).Unwrap(); | 548 | auto filesystem = OpenFileSystem(Type::SaveData, unused).Unwrap(); |
| @@ -534,7 +553,7 @@ void FSP_SRV::MountSaveData(Kernel::HLERequestContext& ctx) { | |||
| 534 | } | 553 | } |
| 535 | 554 | ||
| 536 | void FSP_SRV::GetGlobalAccessLogMode(Kernel::HLERequestContext& ctx) { | 555 | void FSP_SRV::GetGlobalAccessLogMode(Kernel::HLERequestContext& ctx) { |
| 537 | LOG_WARNING(Service_FS, "(STUBBED) called"); | 556 | NGLOG_WARNING(Service_FS, "(STUBBED) called"); |
| 538 | 557 | ||
| 539 | IPC::ResponseBuilder rb{ctx, 3}; | 558 | IPC::ResponseBuilder rb{ctx, 3}; |
| 540 | rb.Push(RESULT_SUCCESS); | 559 | rb.Push(RESULT_SUCCESS); |
| @@ -542,12 +561,12 @@ void FSP_SRV::GetGlobalAccessLogMode(Kernel::HLERequestContext& ctx) { | |||
| 542 | } | 561 | } |
| 543 | 562 | ||
| 544 | void FSP_SRV::OpenDataStorageByCurrentProcess(Kernel::HLERequestContext& ctx) { | 563 | void FSP_SRV::OpenDataStorageByCurrentProcess(Kernel::HLERequestContext& ctx) { |
| 545 | LOG_DEBUG(Service_FS, "called"); | 564 | NGLOG_DEBUG(Service_FS, "called"); |
| 546 | 565 | ||
| 547 | TryLoadRomFS(); | 566 | TryLoadRomFS(); |
| 548 | if (!romfs) { | 567 | if (!romfs) { |
| 549 | // TODO (bunnei): Find the right error code to use here | 568 | // TODO (bunnei): Find the right error code to use here |
| 550 | LOG_CRITICAL(Service_FS, "no file system interface available!"); | 569 | NGLOG_CRITICAL(Service_FS, "no file system interface available!"); |
| 551 | IPC::ResponseBuilder rb{ctx, 2}; | 570 | IPC::ResponseBuilder rb{ctx, 2}; |
| 552 | rb.Push(ResultCode(-1)); | 571 | rb.Push(ResultCode(-1)); |
| 553 | return; | 572 | return; |
| @@ -556,7 +575,7 @@ void FSP_SRV::OpenDataStorageByCurrentProcess(Kernel::HLERequestContext& ctx) { | |||
| 556 | // Attempt to open a StorageBackend interface to the RomFS | 575 | // Attempt to open a StorageBackend interface to the RomFS |
| 557 | auto storage = romfs->OpenFile({}, {}); | 576 | auto storage = romfs->OpenFile({}, {}); |
| 558 | if (storage.Failed()) { | 577 | if (storage.Failed()) { |
| 559 | LOG_CRITICAL(Service_FS, "no storage interface available!"); | 578 | NGLOG_CRITICAL(Service_FS, "no storage interface available!"); |
| 560 | IPC::ResponseBuilder rb{ctx, 2}; | 579 | IPC::ResponseBuilder rb{ctx, 2}; |
| 561 | rb.Push(storage.Code()); | 580 | rb.Push(storage.Code()); |
| 562 | return; | 581 | return; |
| @@ -568,7 +587,7 @@ void FSP_SRV::OpenDataStorageByCurrentProcess(Kernel::HLERequestContext& ctx) { | |||
| 568 | } | 587 | } |
| 569 | 588 | ||
| 570 | void FSP_SRV::OpenRomStorage(Kernel::HLERequestContext& ctx) { | 589 | void FSP_SRV::OpenRomStorage(Kernel::HLERequestContext& ctx) { |
| 571 | LOG_WARNING(Service_FS, "(STUBBED) called, using OpenDataStorageByCurrentProcess"); | 590 | NGLOG_WARNING(Service_FS, "(STUBBED) called, using OpenDataStorageByCurrentProcess"); |
| 572 | OpenDataStorageByCurrentProcess(ctx); | 591 | OpenDataStorageByCurrentProcess(ctx); |
| 573 | } | 592 | } |
| 574 | 593 | ||
diff --git a/src/core/hle/service/friend/friend.cpp b/src/core/hle/service/friend/friend.cpp index c98a46e05..94d9fbf25 100644 --- a/src/core/hle/service/friend/friend.cpp +++ b/src/core/hle/service/friend/friend.cpp | |||
| @@ -13,7 +13,7 @@ namespace Service::Friend { | |||
| 13 | void Module::Interface::CreateFriendService(Kernel::HLERequestContext& ctx) { | 13 | void Module::Interface::CreateFriendService(Kernel::HLERequestContext& ctx) { |
| 14 | IPC::ResponseBuilder rb{ctx, 2}; | 14 | IPC::ResponseBuilder rb{ctx, 2}; |
| 15 | rb.Push(RESULT_SUCCESS); | 15 | rb.Push(RESULT_SUCCESS); |
| 16 | LOG_WARNING(Service_Friend, "(STUBBED) called"); | 16 | NGLOG_WARNING(Service_Friend, "(STUBBED) called"); |
| 17 | } | 17 | } |
| 18 | 18 | ||
| 19 | Module::Interface::Interface(std::shared_ptr<Module> module, const char* name) | 19 | Module::Interface::Interface(std::shared_ptr<Module> module, const char* name) |
diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp index aad5e688b..736180b63 100644 --- a/src/core/hle/service/hid/hid.cpp +++ b/src/core/hle/service/hid/hid.cpp | |||
| @@ -53,7 +53,7 @@ private: | |||
| 53 | IPC::ResponseBuilder rb{ctx, 2, 1}; | 53 | IPC::ResponseBuilder rb{ctx, 2, 1}; |
| 54 | rb.Push(RESULT_SUCCESS); | 54 | rb.Push(RESULT_SUCCESS); |
| 55 | rb.PushCopyObjects(shared_mem); | 55 | rb.PushCopyObjects(shared_mem); |
| 56 | LOG_DEBUG(Service_HID, "called"); | 56 | NGLOG_DEBUG(Service_HID, "called"); |
| 57 | } | 57 | } |
| 58 | 58 | ||
| 59 | void LoadInputDevices() { | 59 | void LoadInputDevices() { |
| @@ -184,7 +184,7 @@ private: | |||
| 184 | void ActivateVibrationDevice(Kernel::HLERequestContext& ctx) { | 184 | void ActivateVibrationDevice(Kernel::HLERequestContext& ctx) { |
| 185 | IPC::ResponseBuilder rb{ctx, 2}; | 185 | IPC::ResponseBuilder rb{ctx, 2}; |
| 186 | rb.Push(RESULT_SUCCESS); | 186 | rb.Push(RESULT_SUCCESS); |
| 187 | LOG_WARNING(Service_HID, "(STUBBED) called"); | 187 | NGLOG_WARNING(Service_HID, "(STUBBED) called"); |
| 188 | } | 188 | } |
| 189 | }; | 189 | }; |
| 190 | 190 | ||
| @@ -286,144 +286,144 @@ private: | |||
| 286 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | 286 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; |
| 287 | rb.Push(RESULT_SUCCESS); | 287 | rb.Push(RESULT_SUCCESS); |
| 288 | rb.PushIpcInterface<IAppletResource>(applet_resource); | 288 | rb.PushIpcInterface<IAppletResource>(applet_resource); |
| 289 | LOG_DEBUG(Service_HID, "called"); | 289 | NGLOG_DEBUG(Service_HID, "called"); |
| 290 | } | 290 | } |
| 291 | 291 | ||
| 292 | void ActivateDebugPad(Kernel::HLERequestContext& ctx) { | 292 | void ActivateDebugPad(Kernel::HLERequestContext& ctx) { |
| 293 | IPC::ResponseBuilder rb{ctx, 2}; | 293 | IPC::ResponseBuilder rb{ctx, 2}; |
| 294 | rb.Push(RESULT_SUCCESS); | 294 | rb.Push(RESULT_SUCCESS); |
| 295 | LOG_WARNING(Service_HID, "(STUBBED) called"); | 295 | NGLOG_WARNING(Service_HID, "(STUBBED) called"); |
| 296 | } | 296 | } |
| 297 | 297 | ||
| 298 | void ActivateTouchScreen(Kernel::HLERequestContext& ctx) { | 298 | void ActivateTouchScreen(Kernel::HLERequestContext& ctx) { |
| 299 | IPC::ResponseBuilder rb{ctx, 2}; | 299 | IPC::ResponseBuilder rb{ctx, 2}; |
| 300 | rb.Push(RESULT_SUCCESS); | 300 | rb.Push(RESULT_SUCCESS); |
| 301 | LOG_WARNING(Service_HID, "(STUBBED) called"); | 301 | NGLOG_WARNING(Service_HID, "(STUBBED) called"); |
| 302 | } | 302 | } |
| 303 | 303 | ||
| 304 | void ActivateMouse(Kernel::HLERequestContext& ctx) { | 304 | void ActivateMouse(Kernel::HLERequestContext& ctx) { |
| 305 | IPC::ResponseBuilder rb{ctx, 2}; | 305 | IPC::ResponseBuilder rb{ctx, 2}; |
| 306 | rb.Push(RESULT_SUCCESS); | 306 | rb.Push(RESULT_SUCCESS); |
| 307 | LOG_WARNING(Service_HID, "(STUBBED) called"); | 307 | NGLOG_WARNING(Service_HID, "(STUBBED) called"); |
| 308 | } | 308 | } |
| 309 | 309 | ||
| 310 | void ActivateKeyboard(Kernel::HLERequestContext& ctx) { | 310 | void ActivateKeyboard(Kernel::HLERequestContext& ctx) { |
| 311 | IPC::ResponseBuilder rb{ctx, 2}; | 311 | IPC::ResponseBuilder rb{ctx, 2}; |
| 312 | rb.Push(RESULT_SUCCESS); | 312 | rb.Push(RESULT_SUCCESS); |
| 313 | LOG_WARNING(Service_HID, "(STUBBED) called"); | 313 | NGLOG_WARNING(Service_HID, "(STUBBED) called"); |
| 314 | } | 314 | } |
| 315 | 315 | ||
| 316 | void StartSixAxisSensor(Kernel::HLERequestContext& ctx) { | 316 | void StartSixAxisSensor(Kernel::HLERequestContext& ctx) { |
| 317 | IPC::ResponseBuilder rb{ctx, 2}; | 317 | IPC::ResponseBuilder rb{ctx, 2}; |
| 318 | rb.Push(RESULT_SUCCESS); | 318 | rb.Push(RESULT_SUCCESS); |
| 319 | LOG_WARNING(Service_HID, "(STUBBED) called"); | 319 | NGLOG_WARNING(Service_HID, "(STUBBED) called"); |
| 320 | } | 320 | } |
| 321 | 321 | ||
| 322 | void SetGyroscopeZeroDriftMode(Kernel::HLERequestContext& ctx) { | 322 | void SetGyroscopeZeroDriftMode(Kernel::HLERequestContext& ctx) { |
| 323 | IPC::ResponseBuilder rb{ctx, 2}; | 323 | IPC::ResponseBuilder rb{ctx, 2}; |
| 324 | rb.Push(RESULT_SUCCESS); | 324 | rb.Push(RESULT_SUCCESS); |
| 325 | LOG_WARNING(Service_HID, "(STUBBED) called"); | 325 | NGLOG_WARNING(Service_HID, "(STUBBED) called"); |
| 326 | } | 326 | } |
| 327 | 327 | ||
| 328 | void SetSupportedNpadStyleSet(Kernel::HLERequestContext& ctx) { | 328 | void SetSupportedNpadStyleSet(Kernel::HLERequestContext& ctx) { |
| 329 | IPC::ResponseBuilder rb{ctx, 2}; | 329 | IPC::ResponseBuilder rb{ctx, 2}; |
| 330 | rb.Push(RESULT_SUCCESS); | 330 | rb.Push(RESULT_SUCCESS); |
| 331 | LOG_WARNING(Service_HID, "(STUBBED) called"); | 331 | NGLOG_WARNING(Service_HID, "(STUBBED) called"); |
| 332 | } | 332 | } |
| 333 | 333 | ||
| 334 | void GetSupportedNpadStyleSet(Kernel::HLERequestContext& ctx) { | 334 | void GetSupportedNpadStyleSet(Kernel::HLERequestContext& ctx) { |
| 335 | IPC::ResponseBuilder rb{ctx, 3}; | 335 | IPC::ResponseBuilder rb{ctx, 3}; |
| 336 | rb.Push(RESULT_SUCCESS); | 336 | rb.Push(RESULT_SUCCESS); |
| 337 | rb.Push<u32>(0); | 337 | rb.Push<u32>(0); |
| 338 | LOG_WARNING(Service_HID, "(STUBBED) called"); | 338 | NGLOG_WARNING(Service_HID, "(STUBBED) called"); |
| 339 | } | 339 | } |
| 340 | 340 | ||
| 341 | void SetSupportedNpadIdType(Kernel::HLERequestContext& ctx) { | 341 | void SetSupportedNpadIdType(Kernel::HLERequestContext& ctx) { |
| 342 | IPC::ResponseBuilder rb{ctx, 2}; | 342 | IPC::ResponseBuilder rb{ctx, 2}; |
| 343 | rb.Push(RESULT_SUCCESS); | 343 | rb.Push(RESULT_SUCCESS); |
| 344 | LOG_WARNING(Service_HID, "(STUBBED) called"); | 344 | NGLOG_WARNING(Service_HID, "(STUBBED) called"); |
| 345 | } | 345 | } |
| 346 | 346 | ||
| 347 | void ActivateNpad(Kernel::HLERequestContext& ctx) { | 347 | void ActivateNpad(Kernel::HLERequestContext& ctx) { |
| 348 | IPC::ResponseBuilder rb{ctx, 2}; | 348 | IPC::ResponseBuilder rb{ctx, 2}; |
| 349 | rb.Push(RESULT_SUCCESS); | 349 | rb.Push(RESULT_SUCCESS); |
| 350 | LOG_WARNING(Service_HID, "(STUBBED) called"); | 350 | NGLOG_WARNING(Service_HID, "(STUBBED) called"); |
| 351 | } | 351 | } |
| 352 | 352 | ||
| 353 | void AcquireNpadStyleSetUpdateEventHandle(Kernel::HLERequestContext& ctx) { | 353 | void AcquireNpadStyleSetUpdateEventHandle(Kernel::HLERequestContext& ctx) { |
| 354 | IPC::ResponseBuilder rb{ctx, 2, 1}; | 354 | IPC::ResponseBuilder rb{ctx, 2, 1}; |
| 355 | rb.Push(RESULT_SUCCESS); | 355 | rb.Push(RESULT_SUCCESS); |
| 356 | rb.PushCopyObjects(event); | 356 | rb.PushCopyObjects(event); |
| 357 | LOG_WARNING(Service_HID, "(STUBBED) called"); | 357 | NGLOG_WARNING(Service_HID, "(STUBBED) called"); |
| 358 | } | 358 | } |
| 359 | 359 | ||
| 360 | void GetPlayerLedPattern(Kernel::HLERequestContext& ctx) { | 360 | void GetPlayerLedPattern(Kernel::HLERequestContext& ctx) { |
| 361 | IPC::ResponseBuilder rb{ctx, 2}; | 361 | IPC::ResponseBuilder rb{ctx, 2}; |
| 362 | rb.Push(RESULT_SUCCESS); | 362 | rb.Push(RESULT_SUCCESS); |
| 363 | LOG_WARNING(Service_HID, "(STUBBED) called"); | 363 | NGLOG_WARNING(Service_HID, "(STUBBED) called"); |
| 364 | } | 364 | } |
| 365 | 365 | ||
| 366 | void SetNpadJoyHoldType(Kernel::HLERequestContext& ctx) { | 366 | void SetNpadJoyHoldType(Kernel::HLERequestContext& ctx) { |
| 367 | IPC::ResponseBuilder rb{ctx, 2}; | 367 | IPC::ResponseBuilder rb{ctx, 2}; |
| 368 | rb.Push(RESULT_SUCCESS); | 368 | rb.Push(RESULT_SUCCESS); |
| 369 | LOG_WARNING(Service_HID, "(STUBBED) called"); | 369 | NGLOG_WARNING(Service_HID, "(STUBBED) called"); |
| 370 | } | 370 | } |
| 371 | 371 | ||
| 372 | void GetNpadJoyHoldType(Kernel::HLERequestContext& ctx) { | 372 | void GetNpadJoyHoldType(Kernel::HLERequestContext& ctx) { |
| 373 | IPC::ResponseBuilder rb{ctx, 3}; | 373 | IPC::ResponseBuilder rb{ctx, 3}; |
| 374 | rb.Push(RESULT_SUCCESS); | 374 | rb.Push(RESULT_SUCCESS); |
| 375 | rb.Push(joy_hold_type); | 375 | rb.Push(joy_hold_type); |
| 376 | LOG_WARNING(Service_HID, "(STUBBED) called"); | 376 | NGLOG_WARNING(Service_HID, "(STUBBED) called"); |
| 377 | } | 377 | } |
| 378 | 378 | ||
| 379 | void SetNpadJoyAssignmentModeSingleByDefault(Kernel::HLERequestContext& ctx) { | 379 | void SetNpadJoyAssignmentModeSingleByDefault(Kernel::HLERequestContext& ctx) { |
| 380 | IPC::ResponseBuilder rb{ctx, 2}; | 380 | IPC::ResponseBuilder rb{ctx, 2}; |
| 381 | rb.Push(RESULT_SUCCESS); | 381 | rb.Push(RESULT_SUCCESS); |
| 382 | LOG_WARNING(Service_HID, "(STUBBED) called"); | 382 | NGLOG_WARNING(Service_HID, "(STUBBED) called"); |
| 383 | } | 383 | } |
| 384 | 384 | ||
| 385 | void SendVibrationValue(Kernel::HLERequestContext& ctx) { | 385 | void SendVibrationValue(Kernel::HLERequestContext& ctx) { |
| 386 | IPC::ResponseBuilder rb{ctx, 2}; | 386 | IPC::ResponseBuilder rb{ctx, 2}; |
| 387 | rb.Push(RESULT_SUCCESS); | 387 | rb.Push(RESULT_SUCCESS); |
| 388 | LOG_WARNING(Service_HID, "(STUBBED) called"); | 388 | NGLOG_WARNING(Service_HID, "(STUBBED) called"); |
| 389 | } | 389 | } |
| 390 | 390 | ||
| 391 | void GetActualVibrationValue(Kernel::HLERequestContext& ctx) { | 391 | void GetActualVibrationValue(Kernel::HLERequestContext& ctx) { |
| 392 | IPC::ResponseBuilder rb{ctx, 2}; | 392 | IPC::ResponseBuilder rb{ctx, 2}; |
| 393 | rb.Push(RESULT_SUCCESS); | 393 | rb.Push(RESULT_SUCCESS); |
| 394 | LOG_WARNING(Service_HID, "(STUBBED) called"); | 394 | NGLOG_WARNING(Service_HID, "(STUBBED) called"); |
| 395 | } | 395 | } |
| 396 | 396 | ||
| 397 | void SetNpadJoyAssignmentModeDual(Kernel::HLERequestContext& ctx) { | 397 | void SetNpadJoyAssignmentModeDual(Kernel::HLERequestContext& ctx) { |
| 398 | IPC::ResponseBuilder rb{ctx, 2}; | 398 | IPC::ResponseBuilder rb{ctx, 2}; |
| 399 | rb.Push(RESULT_SUCCESS); | 399 | rb.Push(RESULT_SUCCESS); |
| 400 | LOG_WARNING(Service_HID, "(STUBBED) called"); | 400 | NGLOG_WARNING(Service_HID, "(STUBBED) called"); |
| 401 | } | 401 | } |
| 402 | 402 | ||
| 403 | void SetNpadHandheldActivationMode(Kernel::HLERequestContext& ctx) { | 403 | void SetNpadHandheldActivationMode(Kernel::HLERequestContext& ctx) { |
| 404 | IPC::ResponseBuilder rb{ctx, 2}; | 404 | IPC::ResponseBuilder rb{ctx, 2}; |
| 405 | rb.Push(RESULT_SUCCESS); | 405 | rb.Push(RESULT_SUCCESS); |
| 406 | LOG_WARNING(Service_HID, "(STUBBED) called"); | 406 | NGLOG_WARNING(Service_HID, "(STUBBED) called"); |
| 407 | } | 407 | } |
| 408 | 408 | ||
| 409 | void GetVibrationDeviceInfo(Kernel::HLERequestContext& ctx) { | 409 | void GetVibrationDeviceInfo(Kernel::HLERequestContext& ctx) { |
| 410 | IPC::ResponseBuilder rb{ctx, 4}; | 410 | IPC::ResponseBuilder rb{ctx, 4}; |
| 411 | rb.Push(RESULT_SUCCESS); | 411 | rb.Push(RESULT_SUCCESS); |
| 412 | rb.Push<u64>(0); | 412 | rb.Push<u64>(0); |
| 413 | LOG_WARNING(Service_HID, "(STUBBED) called"); | 413 | NGLOG_WARNING(Service_HID, "(STUBBED) called"); |
| 414 | } | 414 | } |
| 415 | 415 | ||
| 416 | void CreateActiveVibrationDeviceList(Kernel::HLERequestContext& ctx) { | 416 | void CreateActiveVibrationDeviceList(Kernel::HLERequestContext& ctx) { |
| 417 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | 417 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; |
| 418 | rb.Push(RESULT_SUCCESS); | 418 | rb.Push(RESULT_SUCCESS); |
| 419 | rb.PushIpcInterface<IActiveVibrationDeviceList>(); | 419 | rb.PushIpcInterface<IActiveVibrationDeviceList>(); |
| 420 | LOG_DEBUG(Service_HID, "called"); | 420 | NGLOG_DEBUG(Service_HID, "called"); |
| 421 | } | 421 | } |
| 422 | 422 | ||
| 423 | void SendVibrationValues(Kernel::HLERequestContext& ctx) { | 423 | void SendVibrationValues(Kernel::HLERequestContext& ctx) { |
| 424 | IPC::ResponseBuilder rb{ctx, 2}; | 424 | IPC::ResponseBuilder rb{ctx, 2}; |
| 425 | rb.Push(RESULT_SUCCESS); | 425 | rb.Push(RESULT_SUCCESS); |
| 426 | LOG_WARNING(Service_HID, "(STUBBED) called"); | 426 | NGLOG_WARNING(Service_HID, "(STUBBED) called"); |
| 427 | } | 427 | } |
| 428 | }; | 428 | }; |
| 429 | 429 | ||
diff --git a/src/core/hle/service/lm/lm.cpp b/src/core/hle/service/lm/lm.cpp index b87172dff..46194643e 100644 --- a/src/core/hle/service/lm/lm.cpp +++ b/src/core/hle/service/lm/lm.cpp | |||
| @@ -141,19 +141,19 @@ private: | |||
| 141 | if (header.IsTailLog()) { | 141 | if (header.IsTailLog()) { |
| 142 | switch (header.severity) { | 142 | switch (header.severity) { |
| 143 | case MessageHeader::Severity::Trace: | 143 | case MessageHeader::Severity::Trace: |
| 144 | LOG_TRACE(Debug_Emulated, "%s", log_stream.str().c_str()); | 144 | NGLOG_TRACE(Debug_Emulated, "{}", log_stream.str()); |
| 145 | break; | 145 | break; |
| 146 | case MessageHeader::Severity::Info: | 146 | case MessageHeader::Severity::Info: |
| 147 | LOG_INFO(Debug_Emulated, "%s", log_stream.str().c_str()); | 147 | NGLOG_INFO(Debug_Emulated, "{}", log_stream.str()); |
| 148 | break; | 148 | break; |
| 149 | case MessageHeader::Severity::Warning: | 149 | case MessageHeader::Severity::Warning: |
| 150 | LOG_WARNING(Debug_Emulated, "%s", log_stream.str().c_str()); | 150 | NGLOG_WARNING(Debug_Emulated, "{}", log_stream.str()); |
| 151 | break; | 151 | break; |
| 152 | case MessageHeader::Severity::Error: | 152 | case MessageHeader::Severity::Error: |
| 153 | LOG_ERROR(Debug_Emulated, "%s", log_stream.str().c_str()); | 153 | NGLOG_ERROR(Debug_Emulated, "{}", log_stream.str()); |
| 154 | break; | 154 | break; |
| 155 | case MessageHeader::Severity::Critical: | 155 | case MessageHeader::Severity::Critical: |
| 156 | LOG_CRITICAL(Debug_Emulated, "%s", log_stream.str().c_str()); | 156 | NGLOG_CRITICAL(Debug_Emulated, "{}", log_stream.str()); |
| 157 | break; | 157 | break; |
| 158 | } | 158 | } |
| 159 | } | 159 | } |
| @@ -178,7 +178,7 @@ void LM::Initialize(Kernel::HLERequestContext& ctx) { | |||
| 178 | rb.Push(RESULT_SUCCESS); | 178 | rb.Push(RESULT_SUCCESS); |
| 179 | rb.PushIpcInterface<Logger>(); | 179 | rb.PushIpcInterface<Logger>(); |
| 180 | 180 | ||
| 181 | LOG_DEBUG(Service_LM, "called"); | 181 | NGLOG_DEBUG(Service_LM, "called"); |
| 182 | } | 182 | } |
| 183 | 183 | ||
| 184 | LM::LM() : ServiceFramework("lm") { | 184 | LM::LM() : ServiceFramework("lm") { |
diff --git a/src/core/hle/service/nifm/nifm.cpp b/src/core/hle/service/nifm/nifm.cpp index df1e7f8fe..eee92cfcd 100644 --- a/src/core/hle/service/nifm/nifm.cpp +++ b/src/core/hle/service/nifm/nifm.cpp | |||
| @@ -62,24 +62,24 @@ public: | |||
| 62 | 62 | ||
| 63 | private: | 63 | private: |
| 64 | void GetRequestState(Kernel::HLERequestContext& ctx) { | 64 | void GetRequestState(Kernel::HLERequestContext& ctx) { |
| 65 | LOG_WARNING(Service_NIFM, "(STUBBED) called"); | 65 | NGLOG_WARNING(Service_NIFM, "(STUBBED) called"); |
| 66 | IPC::ResponseBuilder rb{ctx, 3}; | 66 | IPC::ResponseBuilder rb{ctx, 3}; |
| 67 | rb.Push(RESULT_SUCCESS); | 67 | rb.Push(RESULT_SUCCESS); |
| 68 | rb.Push<u32>(0); | 68 | rb.Push<u32>(0); |
| 69 | } | 69 | } |
| 70 | void GetResult(Kernel::HLERequestContext& ctx) { | 70 | void GetResult(Kernel::HLERequestContext& ctx) { |
| 71 | LOG_WARNING(Service_NIFM, "(STUBBED) called"); | 71 | NGLOG_WARNING(Service_NIFM, "(STUBBED) called"); |
| 72 | IPC::ResponseBuilder rb{ctx, 2}; | 72 | IPC::ResponseBuilder rb{ctx, 2}; |
| 73 | rb.Push(RESULT_SUCCESS); | 73 | rb.Push(RESULT_SUCCESS); |
| 74 | } | 74 | } |
| 75 | void GetSystemEventReadableHandles(Kernel::HLERequestContext& ctx) { | 75 | void GetSystemEventReadableHandles(Kernel::HLERequestContext& ctx) { |
| 76 | LOG_WARNING(Service_NIFM, "(STUBBED) called"); | 76 | NGLOG_WARNING(Service_NIFM, "(STUBBED) called"); |
| 77 | IPC::ResponseBuilder rb{ctx, 2, 2}; | 77 | IPC::ResponseBuilder rb{ctx, 2, 2}; |
| 78 | rb.Push(RESULT_SUCCESS); | 78 | rb.Push(RESULT_SUCCESS); |
| 79 | rb.PushCopyObjects(event1, event2); | 79 | rb.PushCopyObjects(event1, event2); |
| 80 | } | 80 | } |
| 81 | void Cancel(Kernel::HLERequestContext& ctx) { | 81 | void Cancel(Kernel::HLERequestContext& ctx) { |
| 82 | LOG_WARNING(Service_NIFM, "(STUBBED) called"); | 82 | NGLOG_WARNING(Service_NIFM, "(STUBBED) called"); |
| 83 | IPC::ResponseBuilder rb{ctx, 2}; | 83 | IPC::ResponseBuilder rb{ctx, 2}; |
| 84 | rb.Push(RESULT_SUCCESS); | 84 | rb.Push(RESULT_SUCCESS); |
| 85 | } | 85 | } |
| @@ -105,7 +105,7 @@ public: | |||
| 105 | 105 | ||
| 106 | private: | 106 | private: |
| 107 | void GetClientId(Kernel::HLERequestContext& ctx) { | 107 | void GetClientId(Kernel::HLERequestContext& ctx) { |
| 108 | LOG_WARNING(Service_NIFM, "(STUBBED) called"); | 108 | NGLOG_WARNING(Service_NIFM, "(STUBBED) called"); |
| 109 | IPC::ResponseBuilder rb{ctx, 4}; | 109 | IPC::ResponseBuilder rb{ctx, 4}; |
| 110 | rb.Push(RESULT_SUCCESS); | 110 | rb.Push(RESULT_SUCCESS); |
| 111 | rb.Push<u64>(0); | 111 | rb.Push<u64>(0); |
| @@ -116,7 +116,7 @@ private: | |||
| 116 | rb.Push(RESULT_SUCCESS); | 116 | rb.Push(RESULT_SUCCESS); |
| 117 | rb.PushIpcInterface<IScanRequest>(); | 117 | rb.PushIpcInterface<IScanRequest>(); |
| 118 | 118 | ||
| 119 | LOG_DEBUG(Service_NIFM, "called"); | 119 | NGLOG_DEBUG(Service_NIFM, "called"); |
| 120 | } | 120 | } |
| 121 | void CreateRequest(Kernel::HLERequestContext& ctx) { | 121 | void CreateRequest(Kernel::HLERequestContext& ctx) { |
| 122 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | 122 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; |
| @@ -124,10 +124,10 @@ private: | |||
| 124 | rb.Push(RESULT_SUCCESS); | 124 | rb.Push(RESULT_SUCCESS); |
| 125 | rb.PushIpcInterface<IRequest>(); | 125 | rb.PushIpcInterface<IRequest>(); |
| 126 | 126 | ||
| 127 | LOG_DEBUG(Service_NIFM, "called"); | 127 | NGLOG_DEBUG(Service_NIFM, "called"); |
| 128 | } | 128 | } |
| 129 | void RemoveNetworkProfile(Kernel::HLERequestContext& ctx) { | 129 | void RemoveNetworkProfile(Kernel::HLERequestContext& ctx) { |
| 130 | LOG_WARNING(Service_NIFM, "(STUBBED) called"); | 130 | NGLOG_WARNING(Service_NIFM, "(STUBBED) called"); |
| 131 | IPC::ResponseBuilder rb{ctx, 2}; | 131 | IPC::ResponseBuilder rb{ctx, 2}; |
| 132 | rb.Push(RESULT_SUCCESS); | 132 | rb.Push(RESULT_SUCCESS); |
| 133 | } | 133 | } |
| @@ -137,7 +137,7 @@ private: | |||
| 137 | rb.Push(RESULT_SUCCESS); | 137 | rb.Push(RESULT_SUCCESS); |
| 138 | rb.PushIpcInterface<INetworkProfile>(); | 138 | rb.PushIpcInterface<INetworkProfile>(); |
| 139 | 139 | ||
| 140 | LOG_DEBUG(Service_NIFM, "called"); | 140 | NGLOG_DEBUG(Service_NIFM, "called"); |
| 141 | } | 141 | } |
| 142 | }; | 142 | }; |
| 143 | 143 | ||
| @@ -187,14 +187,14 @@ void Module::Interface::CreateGeneralServiceOld(Kernel::HLERequestContext& ctx) | |||
| 187 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | 187 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; |
| 188 | rb.Push(RESULT_SUCCESS); | 188 | rb.Push(RESULT_SUCCESS); |
| 189 | rb.PushIpcInterface<IGeneralService>(); | 189 | rb.PushIpcInterface<IGeneralService>(); |
| 190 | LOG_DEBUG(Service_NIFM, "called"); | 190 | NGLOG_DEBUG(Service_NIFM, "called"); |
| 191 | } | 191 | } |
| 192 | 192 | ||
| 193 | void Module::Interface::CreateGeneralService(Kernel::HLERequestContext& ctx) { | 193 | void Module::Interface::CreateGeneralService(Kernel::HLERequestContext& ctx) { |
| 194 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | 194 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; |
| 195 | rb.Push(RESULT_SUCCESS); | 195 | rb.Push(RESULT_SUCCESS); |
| 196 | rb.PushIpcInterface<IGeneralService>(); | 196 | rb.PushIpcInterface<IGeneralService>(); |
| 197 | LOG_DEBUG(Service_NIFM, "called"); | 197 | NGLOG_DEBUG(Service_NIFM, "called"); |
| 198 | } | 198 | } |
| 199 | 199 | ||
| 200 | Module::Interface::Interface(std::shared_ptr<Module> module, const char* name) | 200 | Module::Interface::Interface(std::shared_ptr<Module> module, const char* name) |
diff --git a/src/core/hle/service/ns/pl_u.cpp b/src/core/hle/service/ns/pl_u.cpp index c416ad720..c2a647e89 100644 --- a/src/core/hle/service/ns/pl_u.cpp +++ b/src/core/hle/service/ns/pl_u.cpp | |||
| @@ -52,7 +52,7 @@ PL_U::PL_U() : ServiceFramework("pl:u") { | |||
| 52 | ASSERT(file.GetSize() == SHARED_FONT_MEM_SIZE); | 52 | ASSERT(file.GetSize() == SHARED_FONT_MEM_SIZE); |
| 53 | file.ReadBytes(shared_font->data(), shared_font->size()); | 53 | file.ReadBytes(shared_font->data(), shared_font->size()); |
| 54 | } else { | 54 | } else { |
| 55 | LOG_WARNING(Service_NS, "Unable to load shared font: %s", filepath.c_str()); | 55 | NGLOG_WARNING(Service_NS, "Unable to load shared font: {}", filepath); |
| 56 | } | 56 | } |
| 57 | } | 57 | } |
| 58 | 58 | ||
| @@ -60,7 +60,7 @@ void PL_U::RequestLoad(Kernel::HLERequestContext& ctx) { | |||
| 60 | IPC::RequestParser rp{ctx}; | 60 | IPC::RequestParser rp{ctx}; |
| 61 | const u32 shared_font_type{rp.Pop<u32>()}; | 61 | const u32 shared_font_type{rp.Pop<u32>()}; |
| 62 | 62 | ||
| 63 | LOG_DEBUG(Service_NS, "called, shared_font_type=%d", shared_font_type); | 63 | NGLOG_DEBUG(Service_NS, "called, shared_font_type={}", shared_font_type); |
| 64 | IPC::ResponseBuilder rb{ctx, 2}; | 64 | IPC::ResponseBuilder rb{ctx, 2}; |
| 65 | rb.Push(RESULT_SUCCESS); | 65 | rb.Push(RESULT_SUCCESS); |
| 66 | } | 66 | } |
| @@ -69,7 +69,7 @@ void PL_U::GetLoadState(Kernel::HLERequestContext& ctx) { | |||
| 69 | IPC::RequestParser rp{ctx}; | 69 | IPC::RequestParser rp{ctx}; |
| 70 | const u32 font_id{rp.Pop<u32>()}; | 70 | const u32 font_id{rp.Pop<u32>()}; |
| 71 | 71 | ||
| 72 | LOG_DEBUG(Service_NS, "called, font_id=%d", font_id); | 72 | NGLOG_DEBUG(Service_NS, "called, font_id={}", font_id); |
| 73 | IPC::ResponseBuilder rb{ctx, 3}; | 73 | IPC::ResponseBuilder rb{ctx, 3}; |
| 74 | rb.Push(RESULT_SUCCESS); | 74 | rb.Push(RESULT_SUCCESS); |
| 75 | rb.Push<u32>(static_cast<u32>(LoadState::Done)); | 75 | rb.Push<u32>(static_cast<u32>(LoadState::Done)); |
| @@ -79,7 +79,7 @@ void PL_U::GetSize(Kernel::HLERequestContext& ctx) { | |||
| 79 | IPC::RequestParser rp{ctx}; | 79 | IPC::RequestParser rp{ctx}; |
| 80 | const u32 font_id{rp.Pop<u32>()}; | 80 | const u32 font_id{rp.Pop<u32>()}; |
| 81 | 81 | ||
| 82 | LOG_DEBUG(Service_NS, "called, font_id=%d", font_id); | 82 | NGLOG_DEBUG(Service_NS, "called, font_id={}", font_id); |
| 83 | IPC::ResponseBuilder rb{ctx, 3}; | 83 | IPC::ResponseBuilder rb{ctx, 3}; |
| 84 | rb.Push(RESULT_SUCCESS); | 84 | rb.Push(RESULT_SUCCESS); |
| 85 | rb.Push<u32>(SHARED_FONT_REGIONS[font_id].size); | 85 | rb.Push<u32>(SHARED_FONT_REGIONS[font_id].size); |
| @@ -89,7 +89,7 @@ void PL_U::GetSharedMemoryAddressOffset(Kernel::HLERequestContext& ctx) { | |||
| 89 | IPC::RequestParser rp{ctx}; | 89 | IPC::RequestParser rp{ctx}; |
| 90 | const u32 font_id{rp.Pop<u32>()}; | 90 | const u32 font_id{rp.Pop<u32>()}; |
| 91 | 91 | ||
| 92 | LOG_DEBUG(Service_NS, "called, font_id=%d", font_id); | 92 | NGLOG_DEBUG(Service_NS, "called, font_id={}", font_id); |
| 93 | IPC::ResponseBuilder rb{ctx, 3}; | 93 | IPC::ResponseBuilder rb{ctx, 3}; |
| 94 | rb.Push(RESULT_SUCCESS); | 94 | rb.Push(RESULT_SUCCESS); |
| 95 | rb.Push<u32>(SHARED_FONT_REGIONS[font_id].offset); | 95 | rb.Push<u32>(SHARED_FONT_REGIONS[font_id].offset); |
| @@ -110,7 +110,7 @@ void PL_U::GetSharedMemoryNativeHandle(Kernel::HLERequestContext& ctx) { | |||
| 110 | Kernel::MemoryPermission::Read, SHARED_FONT_MEM_VADDR, Kernel::MemoryRegion::BASE, | 110 | Kernel::MemoryPermission::Read, SHARED_FONT_MEM_VADDR, Kernel::MemoryRegion::BASE, |
| 111 | "PL_U:shared_font_mem"); | 111 | "PL_U:shared_font_mem"); |
| 112 | 112 | ||
| 113 | LOG_DEBUG(Service_NS, "called"); | 113 | NGLOG_DEBUG(Service_NS, "called"); |
| 114 | IPC::ResponseBuilder rb{ctx, 2, 1}; | 114 | IPC::ResponseBuilder rb{ctx, 2, 1}; |
| 115 | rb.Push(RESULT_SUCCESS); | 115 | rb.Push(RESULT_SUCCESS); |
| 116 | rb.PushCopyObjects(shared_font_mem); | 116 | rb.PushCopyObjects(shared_font_mem); |
diff --git a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp index 61f22b1a5..103e66d0c 100644 --- a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp +++ b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp | |||
| @@ -13,16 +13,16 @@ | |||
| 13 | namespace Service::Nvidia::Devices { | 13 | namespace Service::Nvidia::Devices { |
| 14 | 14 | ||
| 15 | u32 nvdisp_disp0::ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) { | 15 | u32 nvdisp_disp0::ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) { |
| 16 | UNIMPLEMENTED(); | 16 | UNIMPLEMENTED_MSG("Unimplemented ioctl"); |
| 17 | return 0; | 17 | return 0; |
| 18 | } | 18 | } |
| 19 | 19 | ||
| 20 | void nvdisp_disp0::flip(u32 buffer_handle, u32 offset, u32 format, u32 width, u32 height, | 20 | void nvdisp_disp0::flip(u32 buffer_handle, u32 offset, u32 format, u32 width, u32 height, |
| 21 | u32 stride, NVFlinger::BufferQueue::BufferTransformFlags transform) { | 21 | u32 stride, NVFlinger::BufferQueue::BufferTransformFlags transform) { |
| 22 | VAddr addr = nvmap_dev->GetObjectAddress(buffer_handle); | 22 | VAddr addr = nvmap_dev->GetObjectAddress(buffer_handle); |
| 23 | LOG_WARNING(Service, | 23 | NGLOG_WARNING(Service, |
| 24 | "Drawing from address %lx offset %08X Width %u Height %u Stride %u Format %u", addr, | 24 | "Drawing from address {:X} offset {:08X} Width {} Height {} Stride {} Format {}", |
| 25 | offset, width, height, stride, format); | 25 | addr, offset, width, height, stride, format); |
| 26 | 26 | ||
| 27 | using PixelFormat = Tegra::FramebufferConfig::PixelFormat; | 27 | using PixelFormat = Tegra::FramebufferConfig::PixelFormat; |
| 28 | const Tegra::FramebufferConfig framebuffer{ | 28 | const Tegra::FramebufferConfig framebuffer{ |
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 71e844959..36d7f837b 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp | |||
| @@ -12,8 +12,8 @@ | |||
| 12 | namespace Service::Nvidia::Devices { | 12 | namespace Service::Nvidia::Devices { |
| 13 | 13 | ||
| 14 | u32 nvhost_as_gpu::ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) { | 14 | u32 nvhost_as_gpu::ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) { |
| 15 | LOG_DEBUG(Service_NVDRV, "called, command=0x%08x, input_size=0x%zx, output_size=0x%zx", | 15 | NGLOG_DEBUG(Service_NVDRV, "called, command={:#010X}, input_size={:#X}, output_size={:#X}", |
| 16 | command.raw, input.size(), output.size()); | 16 | command.raw, input.size(), output.size()); |
| 17 | 17 | ||
| 18 | switch (static_cast<IoctlCommand>(command.raw)) { | 18 | switch (static_cast<IoctlCommand>(command.raw)) { |
| 19 | case IoctlCommand::IocInitalizeExCommand: | 19 | case IoctlCommand::IocInitalizeExCommand: |
| @@ -27,13 +27,18 @@ u32 nvhost_as_gpu::ioctl(Ioctl command, const std::vector<u8>& input, std::vecto | |||
| 27 | case IoctlCommand::IocGetVaRegionsCommand: | 27 | case IoctlCommand::IocGetVaRegionsCommand: |
| 28 | return GetVARegions(input, output); | 28 | return GetVARegions(input, output); |
| 29 | } | 29 | } |
| 30 | |||
| 31 | if (static_cast<IoctlCommand>(command.cmd.Value()) == IoctlCommand::IocRemapCommand) | ||
| 32 | return Remap(input, output); | ||
| 33 | |||
| 34 | UNIMPLEMENTED_MSG("Unimplemented ioctl command"); | ||
| 30 | return 0; | 35 | return 0; |
| 31 | } | 36 | } |
| 32 | 37 | ||
| 33 | u32 nvhost_as_gpu::InitalizeEx(const std::vector<u8>& input, std::vector<u8>& output) { | 38 | u32 nvhost_as_gpu::InitalizeEx(const std::vector<u8>& input, std::vector<u8>& output) { |
| 34 | IoctlInitalizeEx params{}; | 39 | IoctlInitalizeEx params{}; |
| 35 | std::memcpy(¶ms, input.data(), input.size()); | 40 | std::memcpy(¶ms, input.data(), input.size()); |
| 36 | LOG_WARNING(Service_NVDRV, "(STUBBED) called, big_page_size=0x%x", params.big_page_size); | 41 | NGLOG_WARNING(Service_NVDRV, "(STUBBED) called, big_page_size={:#X}", params.big_page_size); |
| 37 | std::memcpy(output.data(), ¶ms, output.size()); | 42 | std::memcpy(output.data(), ¶ms, output.size()); |
| 38 | return 0; | 43 | return 0; |
| 39 | } | 44 | } |
| @@ -41,8 +46,8 @@ u32 nvhost_as_gpu::InitalizeEx(const std::vector<u8>& input, std::vector<u8>& ou | |||
| 41 | u32 nvhost_as_gpu::AllocateSpace(const std::vector<u8>& input, std::vector<u8>& output) { | 46 | u32 nvhost_as_gpu::AllocateSpace(const std::vector<u8>& input, std::vector<u8>& output) { |
| 42 | IoctlAllocSpace params{}; | 47 | IoctlAllocSpace params{}; |
| 43 | std::memcpy(¶ms, input.data(), input.size()); | 48 | std::memcpy(¶ms, input.data(), input.size()); |
| 44 | LOG_DEBUG(Service_NVDRV, "called, pages=%x, page_size=%x, flags=%x", params.pages, | 49 | NGLOG_DEBUG(Service_NVDRV, "called, pages={:X}, page_size={:X}, flags={:X}", params.pages, |
| 45 | params.page_size, params.flags); | 50 | params.page_size, params.flags); |
| 46 | 51 | ||
| 47 | auto& gpu = Core::System::GetInstance().GPU(); | 52 | auto& gpu = Core::System::GetInstance().GPU(); |
| 48 | const u64 size{static_cast<u64>(params.pages) * static_cast<u64>(params.page_size)}; | 53 | const u64 size{static_cast<u64>(params.pages) * static_cast<u64>(params.page_size)}; |
| @@ -56,15 +61,45 @@ u32 nvhost_as_gpu::AllocateSpace(const std::vector<u8>& input, std::vector<u8>& | |||
| 56 | return 0; | 61 | return 0; |
| 57 | } | 62 | } |
| 58 | 63 | ||
| 64 | u32 nvhost_as_gpu::Remap(const std::vector<u8>& input, std::vector<u8>& output) { | ||
| 65 | size_t num_entries = input.size() / sizeof(IoctlRemapEntry); | ||
| 66 | |||
| 67 | NGLOG_WARNING(Service_NVDRV, "(STUBBED) called, num_entries=0x{:X}", num_entries); | ||
| 68 | |||
| 69 | std::vector<IoctlRemapEntry> entries(num_entries); | ||
| 70 | std::memcpy(entries.data(), input.data(), input.size()); | ||
| 71 | |||
| 72 | auto& gpu = Core::System::GetInstance().GPU(); | ||
| 73 | |||
| 74 | for (const auto& entry : entries) { | ||
| 75 | NGLOG_WARNING(Service_NVDRV, "remap entry, offset=0x{:X} handle=0x{:X} pages=0x{:X}", | ||
| 76 | entry.offset, entry.nvmap_handle, entry.pages); | ||
| 77 | Tegra::GPUVAddr offset = static_cast<Tegra::GPUVAddr>(entry.offset) << 0x10; | ||
| 78 | |||
| 79 | auto object = nvmap_dev->GetObject(entry.nvmap_handle); | ||
| 80 | ASSERT(object); | ||
| 81 | |||
| 82 | ASSERT(object->status == nvmap::Object::Status::Allocated); | ||
| 83 | |||
| 84 | u64 size = static_cast<u64>(entry.pages) << 0x10; | ||
| 85 | ASSERT(size <= object->size); | ||
| 86 | |||
| 87 | Tegra::GPUVAddr returned = gpu.memory_manager->MapBufferEx(object->addr, offset, size); | ||
| 88 | ASSERT(returned == offset); | ||
| 89 | } | ||
| 90 | std::memcpy(output.data(), entries.data(), output.size()); | ||
| 91 | return 0; | ||
| 92 | } | ||
| 93 | |||
| 59 | u32 nvhost_as_gpu::MapBufferEx(const std::vector<u8>& input, std::vector<u8>& output) { | 94 | u32 nvhost_as_gpu::MapBufferEx(const std::vector<u8>& input, std::vector<u8>& output) { |
| 60 | IoctlMapBufferEx params{}; | 95 | IoctlMapBufferEx params{}; |
| 61 | std::memcpy(¶ms, input.data(), input.size()); | 96 | std::memcpy(¶ms, input.data(), input.size()); |
| 62 | 97 | ||
| 63 | LOG_DEBUG(Service_NVDRV, | 98 | NGLOG_DEBUG(Service_NVDRV, |
| 64 | "called, flags=%x, nvmap_handle=%x, buffer_offset=%" PRIu64 ", mapping_size=%" PRIu64 | 99 | "called, flags={:X}, nvmap_handle={:X}, buffer_offset={}, mapping_size={}" |
| 65 | ", offset=%" PRIu64, | 100 | ", offset={}", |
| 66 | params.flags, params.nvmap_handle, params.buffer_offset, params.mapping_size, | 101 | params.flags, params.nvmap_handle, params.buffer_offset, params.mapping_size, |
| 67 | params.offset); | 102 | params.offset); |
| 68 | 103 | ||
| 69 | if (!params.nvmap_handle) { | 104 | if (!params.nvmap_handle) { |
| 70 | return 0; | 105 | return 0; |
| @@ -73,6 +108,16 @@ u32 nvhost_as_gpu::MapBufferEx(const std::vector<u8>& input, std::vector<u8>& ou | |||
| 73 | auto object = nvmap_dev->GetObject(params.nvmap_handle); | 108 | auto object = nvmap_dev->GetObject(params.nvmap_handle); |
| 74 | ASSERT(object); | 109 | ASSERT(object); |
| 75 | 110 | ||
| 111 | // We can only map objects that have already been assigned a CPU address. | ||
| 112 | ASSERT(object->status == nvmap::Object::Status::Allocated); | ||
| 113 | |||
| 114 | ASSERT(params.buffer_offset == 0); | ||
| 115 | |||
| 116 | // The real nvservices doesn't make a distinction between handles and ids, and | ||
| 117 | // object can only have one handle and it will be the same as its id. Assert that this is the | ||
| 118 | // case to prevent unexpected behavior. | ||
| 119 | ASSERT(object->id == params.nvmap_handle); | ||
| 120 | |||
| 76 | auto& gpu = Core::System::GetInstance().GPU(); | 121 | auto& gpu = Core::System::GetInstance().GPU(); |
| 77 | 122 | ||
| 78 | if (params.flags & 1) { | 123 | if (params.flags & 1) { |
| @@ -88,7 +133,7 @@ u32 nvhost_as_gpu::MapBufferEx(const std::vector<u8>& input, std::vector<u8>& ou | |||
| 88 | u32 nvhost_as_gpu::BindChannel(const std::vector<u8>& input, std::vector<u8>& output) { | 133 | u32 nvhost_as_gpu::BindChannel(const std::vector<u8>& input, std::vector<u8>& output) { |
| 89 | IoctlBindChannel params{}; | 134 | IoctlBindChannel params{}; |
| 90 | std::memcpy(¶ms, input.data(), input.size()); | 135 | std::memcpy(¶ms, input.data(), input.size()); |
| 91 | LOG_DEBUG(Service_NVDRV, "called, fd=%x", params.fd); | 136 | NGLOG_DEBUG(Service_NVDRV, "called, fd={:X}", params.fd); |
| 92 | channel = params.fd; | 137 | channel = params.fd; |
| 93 | std::memcpy(output.data(), ¶ms, output.size()); | 138 | std::memcpy(output.data(), ¶ms, output.size()); |
| 94 | return 0; | 139 | return 0; |
| @@ -97,8 +142,8 @@ u32 nvhost_as_gpu::BindChannel(const std::vector<u8>& input, std::vector<u8>& ou | |||
| 97 | u32 nvhost_as_gpu::GetVARegions(const std::vector<u8>& input, std::vector<u8>& output) { | 142 | u32 nvhost_as_gpu::GetVARegions(const std::vector<u8>& input, std::vector<u8>& output) { |
| 98 | IoctlGetVaRegions params{}; | 143 | IoctlGetVaRegions params{}; |
| 99 | std::memcpy(¶ms, input.data(), input.size()); | 144 | std::memcpy(¶ms, input.data(), input.size()); |
| 100 | LOG_WARNING(Service_NVDRV, "(STUBBED) called, buf_addr=%" PRIu64 ", buf_size=%x", | 145 | NGLOG_WARNING(Service_NVDRV, "(STUBBED) called, buf_addr={:X}, buf_size={:X}", params.buf_addr, |
| 101 | params.buf_addr, params.buf_size); | 146 | params.buf_size); |
| 102 | 147 | ||
| 103 | params.buf_size = 0x30; | 148 | params.buf_size = 0x30; |
| 104 | params.regions[0].offset = 0x04000000; | 149 | params.regions[0].offset = 0x04000000; |
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.h b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.h index d86c3ebd9..f2dd0c3b3 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.h +++ b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.h | |||
| @@ -26,6 +26,7 @@ private: | |||
| 26 | enum class IoctlCommand : u32_le { | 26 | enum class IoctlCommand : u32_le { |
| 27 | IocInitalizeExCommand = 0x40284109, | 27 | IocInitalizeExCommand = 0x40284109, |
| 28 | IocAllocateSpaceCommand = 0xC0184102, | 28 | IocAllocateSpaceCommand = 0xC0184102, |
| 29 | IocRemapCommand = 0x00000014, | ||
| 29 | IocMapBufferExCommand = 0xC0284106, | 30 | IocMapBufferExCommand = 0xC0284106, |
| 30 | IocBindChannelCommand = 0x40044101, | 31 | IocBindChannelCommand = 0x40044101, |
| 31 | IocGetVaRegionsCommand = 0xC0404108, | 32 | IocGetVaRegionsCommand = 0xC0404108, |
| @@ -54,6 +55,16 @@ private: | |||
| 54 | }; | 55 | }; |
| 55 | static_assert(sizeof(IoctlAllocSpace) == 24, "IoctlInitalizeEx is incorrect size"); | 56 | static_assert(sizeof(IoctlAllocSpace) == 24, "IoctlInitalizeEx is incorrect size"); |
| 56 | 57 | ||
| 58 | struct IoctlRemapEntry { | ||
| 59 | u16_le flags; | ||
| 60 | u16_le kind; | ||
| 61 | u32_le nvmap_handle; | ||
| 62 | INSERT_PADDING_WORDS(1); | ||
| 63 | u32_le offset; | ||
| 64 | u32_le pages; | ||
| 65 | }; | ||
| 66 | static_assert(sizeof(IoctlRemapEntry) == 20, "IoctlRemapEntry is incorrect size"); | ||
| 67 | |||
| 57 | struct IoctlMapBufferEx { | 68 | struct IoctlMapBufferEx { |
| 58 | u32_le flags; // bit0: fixed_offset, bit2: cacheable | 69 | u32_le flags; // bit0: fixed_offset, bit2: cacheable |
| 59 | u32_le kind; // -1 is default | 70 | u32_le kind; // -1 is default |
| @@ -91,6 +102,7 @@ private: | |||
| 91 | 102 | ||
| 92 | u32 InitalizeEx(const std::vector<u8>& input, std::vector<u8>& output); | 103 | u32 InitalizeEx(const std::vector<u8>& input, std::vector<u8>& output); |
| 93 | u32 AllocateSpace(const std::vector<u8>& input, std::vector<u8>& output); | 104 | u32 AllocateSpace(const std::vector<u8>& input, std::vector<u8>& output); |
| 105 | u32 Remap(const std::vector<u8>& input, std::vector<u8>& output); | ||
| 94 | u32 MapBufferEx(const std::vector<u8>& input, std::vector<u8>& output); | 106 | u32 MapBufferEx(const std::vector<u8>& input, std::vector<u8>& output); |
| 95 | u32 BindChannel(const std::vector<u8>& input, std::vector<u8>& output); | 107 | u32 BindChannel(const std::vector<u8>& input, std::vector<u8>& output); |
| 96 | u32 GetVARegions(const std::vector<u8>& input, std::vector<u8>& output); | 108 | u32 GetVARegions(const std::vector<u8>& input, std::vector<u8>& output); |
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp index 660a0f665..46f0b6862 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp | |||
| @@ -9,8 +9,8 @@ | |||
| 9 | namespace Service::Nvidia::Devices { | 9 | namespace Service::Nvidia::Devices { |
| 10 | 10 | ||
| 11 | u32 nvhost_ctrl::ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) { | 11 | u32 nvhost_ctrl::ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) { |
| 12 | LOG_DEBUG(Service_NVDRV, "called, command=0x%08x, input_size=0x%zx, output_size=0x%zx", | 12 | NGLOG_DEBUG(Service_NVDRV, "called, command={:#010X}, input_size={:#X}, output_size={:#X}", |
| 13 | command.raw, input.size(), output.size()); | 13 | command.raw, input.size(), output.size()); |
| 14 | 14 | ||
| 15 | switch (static_cast<IoctlCommand>(command.raw)) { | 15 | switch (static_cast<IoctlCommand>(command.raw)) { |
| 16 | case IoctlCommand::IocGetConfigCommand: | 16 | case IoctlCommand::IocGetConfigCommand: |
| @@ -18,15 +18,15 @@ u32 nvhost_ctrl::ioctl(Ioctl command, const std::vector<u8>& input, std::vector< | |||
| 18 | case IoctlCommand::IocCtrlEventWaitCommand: | 18 | case IoctlCommand::IocCtrlEventWaitCommand: |
| 19 | return IocCtrlEventWait(input, output); | 19 | return IocCtrlEventWait(input, output); |
| 20 | } | 20 | } |
| 21 | UNIMPLEMENTED(); | 21 | UNIMPLEMENTED_MSG("Unimplemented ioctl"); |
| 22 | return 0; | 22 | return 0; |
| 23 | } | 23 | } |
| 24 | 24 | ||
| 25 | u32 nvhost_ctrl::NvOsGetConfigU32(const std::vector<u8>& input, std::vector<u8>& output) { | 25 | u32 nvhost_ctrl::NvOsGetConfigU32(const std::vector<u8>& input, std::vector<u8>& output) { |
| 26 | IocGetConfigParams params{}; | 26 | IocGetConfigParams params{}; |
| 27 | std::memcpy(¶ms, input.data(), sizeof(params)); | 27 | std::memcpy(¶ms, input.data(), sizeof(params)); |
| 28 | LOG_DEBUG(Service_NVDRV, "called, setting=%s!%s", params.domain_str.data(), | 28 | NGLOG_DEBUG(Service_NVDRV, "called, setting={}!{}", params.domain_str.data(), |
| 29 | params.param_str.data()); | 29 | params.param_str.data()); |
| 30 | 30 | ||
| 31 | if (!strcmp(params.domain_str.data(), "nv")) { | 31 | if (!strcmp(params.domain_str.data(), "nv")) { |
| 32 | if (!strcmp(params.param_str.data(), "NV_MEMORY_PROFILER")) { | 32 | if (!strcmp(params.param_str.data(), "NV_MEMORY_PROFILER")) { |
| @@ -48,8 +48,8 @@ u32 nvhost_ctrl::NvOsGetConfigU32(const std::vector<u8>& input, std::vector<u8>& | |||
| 48 | u32 nvhost_ctrl::IocCtrlEventWait(const std::vector<u8>& input, std::vector<u8>& output) { | 48 | u32 nvhost_ctrl::IocCtrlEventWait(const std::vector<u8>& input, std::vector<u8>& output) { |
| 49 | IocCtrlEventWaitParams params{}; | 49 | IocCtrlEventWaitParams params{}; |
| 50 | std::memcpy(¶ms, input.data(), sizeof(params)); | 50 | std::memcpy(¶ms, input.data(), sizeof(params)); |
| 51 | LOG_WARNING(Service_NVDRV, "(STUBBED) called, syncpt_id=%u threshold=%u timeout=%d", | 51 | NGLOG_WARNING(Service_NVDRV, "(STUBBED) called, syncpt_id={} threshold={} timeout={}", |
| 52 | params.syncpt_id, params.threshold, params.timeout); | 52 | params.syncpt_id, params.threshold, params.timeout); |
| 53 | 53 | ||
| 54 | // TODO(Subv): Implement actual syncpt waiting. | 54 | // TODO(Subv): Implement actual syncpt waiting. |
| 55 | params.value = 0; | 55 | params.value = 0; |
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp index 5008d7cbf..3c78ecaea 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp | |||
| @@ -10,8 +10,8 @@ | |||
| 10 | namespace Service::Nvidia::Devices { | 10 | namespace Service::Nvidia::Devices { |
| 11 | 11 | ||
| 12 | u32 nvhost_ctrl_gpu::ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) { | 12 | u32 nvhost_ctrl_gpu::ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) { |
| 13 | LOG_DEBUG(Service_NVDRV, "called, command=0x%08x, input_size=0x%zx, output_size=0x%zx", | 13 | NGLOG_DEBUG(Service_NVDRV, "called, command={:#010X}, input_size={:#X}, output_size={:#X}", |
| 14 | command.raw, input.size(), output.size()); | 14 | command.raw, input.size(), output.size()); |
| 15 | 15 | ||
| 16 | switch (static_cast<IoctlCommand>(command.raw)) { | 16 | switch (static_cast<IoctlCommand>(command.raw)) { |
| 17 | case IoctlCommand::IocGetCharacteristicsCommand: | 17 | case IoctlCommand::IocGetCharacteristicsCommand: |
| @@ -25,12 +25,12 @@ u32 nvhost_ctrl_gpu::ioctl(Ioctl command, const std::vector<u8>& input, std::vec | |||
| 25 | case IoctlCommand::IocZcullGetInfo: | 25 | case IoctlCommand::IocZcullGetInfo: |
| 26 | return ZCullGetInfo(input, output); | 26 | return ZCullGetInfo(input, output); |
| 27 | } | 27 | } |
| 28 | UNIMPLEMENTED(); | 28 | UNIMPLEMENTED_MSG("Unimplemented ioctl"); |
| 29 | return 0; | 29 | return 0; |
| 30 | } | 30 | } |
| 31 | 31 | ||
| 32 | u32 nvhost_ctrl_gpu::GetCharacteristics(const std::vector<u8>& input, std::vector<u8>& output) { | 32 | u32 nvhost_ctrl_gpu::GetCharacteristics(const std::vector<u8>& input, std::vector<u8>& output) { |
| 33 | LOG_DEBUG(Service_NVDRV, "called"); | 33 | NGLOG_DEBUG(Service_NVDRV, "called"); |
| 34 | IoctlCharacteristics params{}; | 34 | IoctlCharacteristics params{}; |
| 35 | std::memcpy(¶ms, input.data(), input.size()); | 35 | std::memcpy(¶ms, input.data(), input.size()); |
| 36 | params.gc.arch = 0x120; | 36 | params.gc.arch = 0x120; |
| @@ -77,15 +77,15 @@ u32 nvhost_ctrl_gpu::GetCharacteristics(const std::vector<u8>& input, std::vecto | |||
| 77 | u32 nvhost_ctrl_gpu::GetTPCMasks(const std::vector<u8>& input, std::vector<u8>& output) { | 77 | u32 nvhost_ctrl_gpu::GetTPCMasks(const std::vector<u8>& input, std::vector<u8>& output) { |
| 78 | IoctlGpuGetTpcMasksArgs params{}; | 78 | IoctlGpuGetTpcMasksArgs params{}; |
| 79 | std::memcpy(¶ms, input.data(), input.size()); | 79 | std::memcpy(¶ms, input.data(), input.size()); |
| 80 | LOG_WARNING(Service_NVDRV, "(STUBBED) called, mask=0x%x, mask_buf_addr=0x%" PRIx64, | 80 | NGLOG_WARNING(Service_NVDRV, "(STUBBED) called, mask={:#X}, mask_buf_addr={:#X}", |
| 81 | params.mask_buf_size, params.mask_buf_addr); | 81 | params.mask_buf_size, params.mask_buf_addr); |
| 82 | params.unk = 0xcafe; // TODO(ogniK): Needs to be non 0, what does this actually do? | 82 | params.unk = 0xcafe; // TODO(ogniK): Needs to be non 0, what does this actually do? |
| 83 | std::memcpy(output.data(), ¶ms, sizeof(params)); | 83 | std::memcpy(output.data(), ¶ms, sizeof(params)); |
| 84 | return 0; | 84 | return 0; |
| 85 | } | 85 | } |
| 86 | 86 | ||
| 87 | u32 nvhost_ctrl_gpu::GetActiveSlotMask(const std::vector<u8>& input, std::vector<u8>& output) { | 87 | u32 nvhost_ctrl_gpu::GetActiveSlotMask(const std::vector<u8>& input, std::vector<u8>& output) { |
| 88 | LOG_DEBUG(Service_NVDRV, "called"); | 88 | NGLOG_DEBUG(Service_NVDRV, "called"); |
| 89 | IoctlActiveSlotMask params{}; | 89 | IoctlActiveSlotMask params{}; |
| 90 | std::memcpy(¶ms, input.data(), input.size()); | 90 | std::memcpy(¶ms, input.data(), input.size()); |
| 91 | params.slot = 0x07; | 91 | params.slot = 0x07; |
| @@ -95,7 +95,7 @@ u32 nvhost_ctrl_gpu::GetActiveSlotMask(const std::vector<u8>& input, std::vector | |||
| 95 | } | 95 | } |
| 96 | 96 | ||
| 97 | u32 nvhost_ctrl_gpu::ZCullGetCtxSize(const std::vector<u8>& input, std::vector<u8>& output) { | 97 | u32 nvhost_ctrl_gpu::ZCullGetCtxSize(const std::vector<u8>& input, std::vector<u8>& output) { |
| 98 | LOG_DEBUG(Service_NVDRV, "called"); | 98 | NGLOG_DEBUG(Service_NVDRV, "called"); |
| 99 | IoctlZcullGetCtxSize params{}; | 99 | IoctlZcullGetCtxSize params{}; |
| 100 | std::memcpy(¶ms, input.data(), input.size()); | 100 | std::memcpy(¶ms, input.data(), input.size()); |
| 101 | params.size = 0x1; | 101 | params.size = 0x1; |
| @@ -104,7 +104,7 @@ u32 nvhost_ctrl_gpu::ZCullGetCtxSize(const std::vector<u8>& input, std::vector<u | |||
| 104 | } | 104 | } |
| 105 | 105 | ||
| 106 | u32 nvhost_ctrl_gpu::ZCullGetInfo(const std::vector<u8>& input, std::vector<u8>& output) { | 106 | u32 nvhost_ctrl_gpu::ZCullGetInfo(const std::vector<u8>& input, std::vector<u8>& output) { |
| 107 | LOG_DEBUG(Service_NVDRV, "called"); | 107 | NGLOG_DEBUG(Service_NVDRV, "called"); |
| 108 | IoctlNvgpuGpuZcullGetInfoArgs params{}; | 108 | IoctlNvgpuGpuZcullGetInfoArgs params{}; |
| 109 | std::memcpy(¶ms, input.data(), input.size()); | 109 | std::memcpy(¶ms, input.data(), input.size()); |
| 110 | params.width_align_pixels = 0x20; | 110 | params.width_align_pixels = 0x20; |
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp index a16e90457..70625211e 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp | |||
| @@ -12,8 +12,8 @@ | |||
| 12 | namespace Service::Nvidia::Devices { | 12 | namespace Service::Nvidia::Devices { |
| 13 | 13 | ||
| 14 | u32 nvhost_gpu::ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) { | 14 | u32 nvhost_gpu::ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) { |
| 15 | LOG_DEBUG(Service_NVDRV, "called, command=0x%08x, input_size=0x%zx, output_size=0x%zx", | 15 | NGLOG_DEBUG(Service_NVDRV, "called, command={:#010X}, input_size={:#X}, output_size={:#X}", |
| 16 | command.raw, input.size(), output.size()); | 16 | command.raw, input.size(), output.size()); |
| 17 | 17 | ||
| 18 | switch (static_cast<IoctlCommand>(command.raw)) { | 18 | switch (static_cast<IoctlCommand>(command.raw)) { |
| 19 | case IoctlCommand::IocSetNVMAPfdCommand: | 19 | case IoctlCommand::IocSetNVMAPfdCommand: |
| @@ -40,21 +40,21 @@ u32 nvhost_gpu::ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u | |||
| 40 | } | 40 | } |
| 41 | } | 41 | } |
| 42 | 42 | ||
| 43 | UNIMPLEMENTED(); | 43 | UNIMPLEMENTED_MSG("Unimplemented ioctl"); |
| 44 | return 0; | 44 | return 0; |
| 45 | }; | 45 | }; |
| 46 | 46 | ||
| 47 | u32 nvhost_gpu::SetNVMAPfd(const std::vector<u8>& input, std::vector<u8>& output) { | 47 | u32 nvhost_gpu::SetNVMAPfd(const std::vector<u8>& input, std::vector<u8>& output) { |
| 48 | IoctlSetNvmapFD params{}; | 48 | IoctlSetNvmapFD params{}; |
| 49 | std::memcpy(¶ms, input.data(), input.size()); | 49 | std::memcpy(¶ms, input.data(), input.size()); |
| 50 | LOG_DEBUG(Service_NVDRV, "called, fd=%x", params.nvmap_fd); | 50 | NGLOG_DEBUG(Service_NVDRV, "called, fd={}", params.nvmap_fd); |
| 51 | nvmap_fd = params.nvmap_fd; | 51 | nvmap_fd = params.nvmap_fd; |
| 52 | std::memcpy(output.data(), ¶ms, output.size()); | 52 | std::memcpy(output.data(), ¶ms, output.size()); |
| 53 | return 0; | 53 | return 0; |
| 54 | } | 54 | } |
| 55 | 55 | ||
| 56 | u32 nvhost_gpu::SetClientData(const std::vector<u8>& input, std::vector<u8>& output) { | 56 | u32 nvhost_gpu::SetClientData(const std::vector<u8>& input, std::vector<u8>& output) { |
| 57 | LOG_DEBUG(Service_NVDRV, "called"); | 57 | NGLOG_DEBUG(Service_NVDRV, "called"); |
| 58 | IoctlClientData params{}; | 58 | IoctlClientData params{}; |
| 59 | std::memcpy(¶ms, input.data(), input.size()); | 59 | std::memcpy(¶ms, input.data(), input.size()); |
| 60 | user_data = params.data; | 60 | user_data = params.data; |
| @@ -63,7 +63,7 @@ u32 nvhost_gpu::SetClientData(const std::vector<u8>& input, std::vector<u8>& out | |||
| 63 | } | 63 | } |
| 64 | 64 | ||
| 65 | u32 nvhost_gpu::GetClientData(const std::vector<u8>& input, std::vector<u8>& output) { | 65 | u32 nvhost_gpu::GetClientData(const std::vector<u8>& input, std::vector<u8>& output) { |
| 66 | LOG_DEBUG(Service_NVDRV, "called"); | 66 | NGLOG_DEBUG(Service_NVDRV, "called"); |
| 67 | IoctlClientData params{}; | 67 | IoctlClientData params{}; |
| 68 | std::memcpy(¶ms, input.data(), input.size()); | 68 | std::memcpy(¶ms, input.data(), input.size()); |
| 69 | params.data = user_data; | 69 | params.data = user_data; |
| @@ -73,8 +73,8 @@ u32 nvhost_gpu::GetClientData(const std::vector<u8>& input, std::vector<u8>& out | |||
| 73 | 73 | ||
| 74 | u32 nvhost_gpu::ZCullBind(const std::vector<u8>& input, std::vector<u8>& output) { | 74 | u32 nvhost_gpu::ZCullBind(const std::vector<u8>& input, std::vector<u8>& output) { |
| 75 | std::memcpy(&zcull_params, input.data(), input.size()); | 75 | std::memcpy(&zcull_params, input.data(), input.size()); |
| 76 | LOG_DEBUG(Service_NVDRV, "called, gpu_va=%" PRIx64 ", mode=%x", zcull_params.gpu_va, | 76 | NGLOG_DEBUG(Service_NVDRV, "called, gpu_va={:X}, mode={:X}", zcull_params.gpu_va, |
| 77 | zcull_params.mode); | 77 | zcull_params.mode); |
| 78 | std::memcpy(output.data(), &zcull_params, output.size()); | 78 | std::memcpy(output.data(), &zcull_params, output.size()); |
| 79 | return 0; | 79 | return 0; |
| 80 | } | 80 | } |
| @@ -82,15 +82,15 @@ u32 nvhost_gpu::ZCullBind(const std::vector<u8>& input, std::vector<u8>& output) | |||
| 82 | u32 nvhost_gpu::SetErrorNotifier(const std::vector<u8>& input, std::vector<u8>& output) { | 82 | u32 nvhost_gpu::SetErrorNotifier(const std::vector<u8>& input, std::vector<u8>& output) { |
| 83 | IoctlSetErrorNotifier params{}; | 83 | IoctlSetErrorNotifier params{}; |
| 84 | std::memcpy(¶ms, input.data(), input.size()); | 84 | std::memcpy(¶ms, input.data(), input.size()); |
| 85 | LOG_WARNING(Service_NVDRV, "(STUBBED) called, offset=%" PRIx64 ", size=%" PRIx64 ", mem=%x", | 85 | NGLOG_WARNING(Service_NVDRV, "(STUBBED) called, offset={:X}, size={:X}, mem={:X}", |
| 86 | params.offset, params.size, params.mem); | 86 | params.offset, params.size, params.mem); |
| 87 | std::memcpy(output.data(), ¶ms, output.size()); | 87 | std::memcpy(output.data(), ¶ms, output.size()); |
| 88 | return 0; | 88 | return 0; |
| 89 | } | 89 | } |
| 90 | 90 | ||
| 91 | u32 nvhost_gpu::SetChannelPriority(const std::vector<u8>& input, std::vector<u8>& output) { | 91 | u32 nvhost_gpu::SetChannelPriority(const std::vector<u8>& input, std::vector<u8>& output) { |
| 92 | std::memcpy(&channel_priority, input.data(), input.size()); | 92 | std::memcpy(&channel_priority, input.data(), input.size()); |
| 93 | LOG_DEBUG(Service_NVDRV, "(STUBBED) called, priority=%x", channel_priority); | 93 | NGLOG_DEBUG(Service_NVDRV, "(STUBBED) called, priority={:X}", channel_priority); |
| 94 | std::memcpy(output.data(), &channel_priority, output.size()); | 94 | std::memcpy(output.data(), &channel_priority, output.size()); |
| 95 | return 0; | 95 | return 0; |
| 96 | } | 96 | } |
| @@ -98,10 +98,11 @@ u32 nvhost_gpu::SetChannelPriority(const std::vector<u8>& input, std::vector<u8> | |||
| 98 | u32 nvhost_gpu::AllocGPFIFOEx2(const std::vector<u8>& input, std::vector<u8>& output) { | 98 | u32 nvhost_gpu::AllocGPFIFOEx2(const std::vector<u8>& input, std::vector<u8>& output) { |
| 99 | IoctlAllocGpfifoEx2 params{}; | 99 | IoctlAllocGpfifoEx2 params{}; |
| 100 | std::memcpy(¶ms, input.data(), input.size()); | 100 | std::memcpy(¶ms, input.data(), input.size()); |
| 101 | LOG_WARNING(Service_NVDRV, | 101 | NGLOG_WARNING(Service_NVDRV, |
| 102 | "(STUBBED) called, num_entries=%x, flags=%x, unk0=%x, unk1=%x, unk2=%x, unk3=%x", | 102 | "(STUBBED) called, num_entries={:X}, flags={:X}, unk0={:X}, " |
| 103 | params.num_entries, params.flags, params.unk0, params.unk1, params.unk2, | 103 | "unk1={:X}, unk2={:X}, unk3={:X}", |
| 104 | params.unk3); | 104 | params.num_entries, params.flags, params.unk0, params.unk1, params.unk2, |
| 105 | params.unk3); | ||
| 105 | params.fence_out.id = 0; | 106 | params.fence_out.id = 0; |
| 106 | params.fence_out.value = 0; | 107 | params.fence_out.value = 0; |
| 107 | std::memcpy(output.data(), ¶ms, output.size()); | 108 | std::memcpy(output.data(), ¶ms, output.size()); |
| @@ -111,8 +112,8 @@ u32 nvhost_gpu::AllocGPFIFOEx2(const std::vector<u8>& input, std::vector<u8>& ou | |||
| 111 | u32 nvhost_gpu::AllocateObjectContext(const std::vector<u8>& input, std::vector<u8>& output) { | 112 | u32 nvhost_gpu::AllocateObjectContext(const std::vector<u8>& input, std::vector<u8>& output) { |
| 112 | IoctlAllocObjCtx params{}; | 113 | IoctlAllocObjCtx params{}; |
| 113 | std::memcpy(¶ms, input.data(), input.size()); | 114 | std::memcpy(¶ms, input.data(), input.size()); |
| 114 | LOG_WARNING(Service_NVDRV, "(STUBBED) called, class_num=%x, flags=%x", params.class_num, | 115 | NGLOG_WARNING(Service_NVDRV, "(STUBBED) called, class_num={:X}, flags={:X}", params.class_num, |
| 115 | params.flags); | 116 | params.flags); |
| 116 | params.obj_id = 0x0; | 117 | params.obj_id = 0x0; |
| 117 | std::memcpy(output.data(), ¶ms, output.size()); | 118 | std::memcpy(output.data(), ¶ms, output.size()); |
| 118 | return 0; | 119 | return 0; |
| @@ -123,8 +124,8 @@ u32 nvhost_gpu::SubmitGPFIFO(const std::vector<u8>& input, std::vector<u8>& outp | |||
| 123 | UNIMPLEMENTED(); | 124 | UNIMPLEMENTED(); |
| 124 | IoctlSubmitGpfifo params{}; | 125 | IoctlSubmitGpfifo params{}; |
| 125 | std::memcpy(¶ms, input.data(), sizeof(IoctlSubmitGpfifo)); | 126 | std::memcpy(¶ms, input.data(), sizeof(IoctlSubmitGpfifo)); |
| 126 | LOG_WARNING(Service_NVDRV, "(STUBBED) called, gpfifo=%" PRIx64 ", num_entries=%x, flags=%x", | 127 | NGLOG_WARNING(Service_NVDRV, "(STUBBED) called, gpfifo={:X}, num_entries={:X}, flags={:X}", |
| 127 | params.gpfifo, params.num_entries, params.flags); | 128 | params.gpfifo, params.num_entries, params.flags); |
| 128 | 129 | ||
| 129 | auto entries = std::vector<IoctlGpfifoEntry>(); | 130 | auto entries = std::vector<IoctlGpfifoEntry>(); |
| 130 | entries.resize(params.num_entries); | 131 | entries.resize(params.num_entries); |
diff --git a/src/core/hle/service/nvdrv/devices/nvmap.cpp b/src/core/hle/service/nvdrv/devices/nvmap.cpp index 4bb1f57f6..11df8849d 100644 --- a/src/core/hle/service/nvdrv/devices/nvmap.cpp +++ b/src/core/hle/service/nvdrv/devices/nvmap.cpp | |||
| @@ -32,7 +32,7 @@ u32 nvmap::ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& o | |||
| 32 | return IocParam(input, output); | 32 | return IocParam(input, output); |
| 33 | } | 33 | } |
| 34 | 34 | ||
| 35 | UNIMPLEMENTED(); | 35 | UNIMPLEMENTED_MSG("Unimplemented ioctl"); |
| 36 | return 0; | 36 | return 0; |
| 37 | } | 37 | } |
| 38 | 38 | ||
| @@ -49,7 +49,7 @@ u32 nvmap::IocCreate(const std::vector<u8>& input, std::vector<u8>& output) { | |||
| 49 | u32 handle = next_handle++; | 49 | u32 handle = next_handle++; |
| 50 | handles[handle] = std::move(object); | 50 | handles[handle] = std::move(object); |
| 51 | 51 | ||
| 52 | LOG_DEBUG(Service_NVDRV, "size=0x%08X", params.size); | 52 | NGLOG_DEBUG(Service_NVDRV, "size={:#010X}", params.size); |
| 53 | 53 | ||
| 54 | params.handle = handle; | 54 | params.handle = handle; |
| 55 | 55 | ||
| @@ -70,7 +70,7 @@ u32 nvmap::IocAlloc(const std::vector<u8>& input, std::vector<u8>& output) { | |||
| 70 | object->addr = params.addr; | 70 | object->addr = params.addr; |
| 71 | object->status = Object::Status::Allocated; | 71 | object->status = Object::Status::Allocated; |
| 72 | 72 | ||
| 73 | LOG_DEBUG(Service_NVDRV, "called, addr=0x%" PRIx64, params.addr); | 73 | NGLOG_DEBUG(Service_NVDRV, "called, addr={:X}", params.addr); |
| 74 | 74 | ||
| 75 | std::memcpy(output.data(), ¶ms, sizeof(params)); | 75 | std::memcpy(output.data(), ¶ms, sizeof(params)); |
| 76 | return 0; | 76 | return 0; |
| @@ -80,7 +80,7 @@ u32 nvmap::IocGetId(const std::vector<u8>& input, std::vector<u8>& output) { | |||
| 80 | IocGetIdParams params; | 80 | IocGetIdParams params; |
| 81 | std::memcpy(¶ms, input.data(), sizeof(params)); | 81 | std::memcpy(¶ms, input.data(), sizeof(params)); |
| 82 | 82 | ||
| 83 | LOG_WARNING(Service_NVDRV, "called"); | 83 | NGLOG_WARNING(Service_NVDRV, "called"); |
| 84 | 84 | ||
| 85 | auto object = GetObject(params.handle); | 85 | auto object = GetObject(params.handle); |
| 86 | ASSERT(object); | 86 | ASSERT(object); |
| @@ -95,7 +95,7 @@ u32 nvmap::IocFromId(const std::vector<u8>& input, std::vector<u8>& output) { | |||
| 95 | IocFromIdParams params; | 95 | IocFromIdParams params; |
| 96 | std::memcpy(¶ms, input.data(), sizeof(params)); | 96 | std::memcpy(¶ms, input.data(), sizeof(params)); |
| 97 | 97 | ||
| 98 | LOG_WARNING(Service_NVDRV, "(STUBBED) called"); | 98 | NGLOG_WARNING(Service_NVDRV, "(STUBBED) called"); |
| 99 | 99 | ||
| 100 | auto itr = std::find_if(handles.begin(), handles.end(), | 100 | auto itr = std::find_if(handles.begin(), handles.end(), |
| 101 | [&](const auto& entry) { return entry.second->id == params.id; }); | 101 | [&](const auto& entry) { return entry.second->id == params.id; }); |
| @@ -114,7 +114,7 @@ u32 nvmap::IocParam(const std::vector<u8>& input, std::vector<u8>& output) { | |||
| 114 | IocParamParams params; | 114 | IocParamParams params; |
| 115 | std::memcpy(¶ms, input.data(), sizeof(params)); | 115 | std::memcpy(¶ms, input.data(), sizeof(params)); |
| 116 | 116 | ||
| 117 | LOG_WARNING(Service_NVDRV, "(STUBBED) called type=%u", params.type); | 117 | NGLOG_WARNING(Service_NVDRV, "(STUBBED) called type={}", params.type); |
| 118 | 118 | ||
| 119 | auto object = GetObject(params.handle); | 119 | auto object = GetObject(params.handle); |
| 120 | ASSERT(object); | 120 | ASSERT(object); |
diff --git a/src/core/hle/service/nvdrv/interface.cpp b/src/core/hle/service/nvdrv/interface.cpp index d0d64a840..38b3a9a84 100644 --- a/src/core/hle/service/nvdrv/interface.cpp +++ b/src/core/hle/service/nvdrv/interface.cpp | |||
| @@ -12,7 +12,7 @@ | |||
| 12 | namespace Service::Nvidia { | 12 | namespace Service::Nvidia { |
| 13 | 13 | ||
| 14 | void NVDRV::Open(Kernel::HLERequestContext& ctx) { | 14 | void NVDRV::Open(Kernel::HLERequestContext& ctx) { |
| 15 | LOG_DEBUG(Service_NVDRV, "called"); | 15 | NGLOG_DEBUG(Service_NVDRV, "called"); |
| 16 | 16 | ||
| 17 | const auto& buffer = ctx.ReadBuffer(); | 17 | const auto& buffer = ctx.ReadBuffer(); |
| 18 | std::string device_name(buffer.begin(), buffer.end()); | 18 | std::string device_name(buffer.begin(), buffer.end()); |
| @@ -25,7 +25,7 @@ void NVDRV::Open(Kernel::HLERequestContext& ctx) { | |||
| 25 | } | 25 | } |
| 26 | 26 | ||
| 27 | void NVDRV::Ioctl(Kernel::HLERequestContext& ctx) { | 27 | void NVDRV::Ioctl(Kernel::HLERequestContext& ctx) { |
| 28 | LOG_DEBUG(Service_NVDRV, "called"); | 28 | NGLOG_DEBUG(Service_NVDRV, "called"); |
| 29 | 29 | ||
| 30 | IPC::RequestParser rp{ctx}; | 30 | IPC::RequestParser rp{ctx}; |
| 31 | u32 fd = rp.Pop<u32>(); | 31 | u32 fd = rp.Pop<u32>(); |
| @@ -41,7 +41,7 @@ void NVDRV::Ioctl(Kernel::HLERequestContext& ctx) { | |||
| 41 | } | 41 | } |
| 42 | 42 | ||
| 43 | void NVDRV::Close(Kernel::HLERequestContext& ctx) { | 43 | void NVDRV::Close(Kernel::HLERequestContext& ctx) { |
| 44 | LOG_DEBUG(Service_NVDRV, "called"); | 44 | NGLOG_DEBUG(Service_NVDRV, "called"); |
| 45 | 45 | ||
| 46 | IPC::RequestParser rp{ctx}; | 46 | IPC::RequestParser rp{ctx}; |
| 47 | u32 fd = rp.Pop<u32>(); | 47 | u32 fd = rp.Pop<u32>(); |
| @@ -53,7 +53,7 @@ void NVDRV::Close(Kernel::HLERequestContext& ctx) { | |||
| 53 | } | 53 | } |
| 54 | 54 | ||
| 55 | void NVDRV::Initialize(Kernel::HLERequestContext& ctx) { | 55 | void NVDRV::Initialize(Kernel::HLERequestContext& ctx) { |
| 56 | LOG_WARNING(Service_NVDRV, "(STUBBED) called"); | 56 | NGLOG_WARNING(Service_NVDRV, "(STUBBED) called"); |
| 57 | IPC::ResponseBuilder rb{ctx, 3}; | 57 | IPC::ResponseBuilder rb{ctx, 3}; |
| 58 | rb.Push(RESULT_SUCCESS); | 58 | rb.Push(RESULT_SUCCESS); |
| 59 | rb.Push<u32>(0); | 59 | rb.Push<u32>(0); |
| @@ -63,7 +63,7 @@ void NVDRV::QueryEvent(Kernel::HLERequestContext& ctx) { | |||
| 63 | IPC::RequestParser rp{ctx}; | 63 | IPC::RequestParser rp{ctx}; |
| 64 | u32 fd = rp.Pop<u32>(); | 64 | u32 fd = rp.Pop<u32>(); |
| 65 | u32 event_id = rp.Pop<u32>(); | 65 | u32 event_id = rp.Pop<u32>(); |
| 66 | LOG_WARNING(Service_NVDRV, "(STUBBED) called, fd=%x, event_id=%x", fd, event_id); | 66 | NGLOG_WARNING(Service_NVDRV, "(STUBBED) called, fd={:X}, event_id={:X}", fd, event_id); |
| 67 | 67 | ||
| 68 | IPC::ResponseBuilder rb{ctx, 3, 1}; | 68 | IPC::ResponseBuilder rb{ctx, 3, 1}; |
| 69 | rb.Push(RESULT_SUCCESS); | 69 | rb.Push(RESULT_SUCCESS); |
| @@ -75,14 +75,14 @@ void NVDRV::SetClientPID(Kernel::HLERequestContext& ctx) { | |||
| 75 | IPC::RequestParser rp{ctx}; | 75 | IPC::RequestParser rp{ctx}; |
| 76 | pid = rp.Pop<u64>(); | 76 | pid = rp.Pop<u64>(); |
| 77 | 77 | ||
| 78 | LOG_WARNING(Service_NVDRV, "(STUBBED) called, pid=0x%" PRIx64, pid); | 78 | NGLOG_WARNING(Service_NVDRV, "(STUBBED) called, pid={:#X}", pid); |
| 79 | IPC::ResponseBuilder rb{ctx, 3}; | 79 | IPC::ResponseBuilder rb{ctx, 3}; |
| 80 | rb.Push(RESULT_SUCCESS); | 80 | rb.Push(RESULT_SUCCESS); |
| 81 | rb.Push<u32>(0); | 81 | rb.Push<u32>(0); |
| 82 | } | 82 | } |
| 83 | 83 | ||
| 84 | void NVDRV::FinishInitialize(Kernel::HLERequestContext& ctx) { | 84 | void NVDRV::FinishInitialize(Kernel::HLERequestContext& ctx) { |
| 85 | LOG_WARNING(Service_NVDRV, "(STUBBED) called"); | 85 | NGLOG_WARNING(Service_NVDRV, "(STUBBED) called"); |
| 86 | IPC::ResponseBuilder rb{ctx, 2}; | 86 | IPC::ResponseBuilder rb{ctx, 2}; |
| 87 | rb.Push(RESULT_SUCCESS); | 87 | rb.Push(RESULT_SUCCESS); |
| 88 | } | 88 | } |
diff --git a/src/core/hle/service/nvflinger/buffer_queue.cpp b/src/core/hle/service/nvflinger/buffer_queue.cpp index 03a4fed59..49e88b394 100644 --- a/src/core/hle/service/nvflinger/buffer_queue.cpp +++ b/src/core/hle/service/nvflinger/buffer_queue.cpp | |||
| @@ -9,7 +9,8 @@ | |||
| 9 | #include "core/core_timing.h" | 9 | #include "core/core_timing.h" |
| 10 | #include "core/hle/service/nvflinger/buffer_queue.h" | 10 | #include "core/hle/service/nvflinger/buffer_queue.h" |
| 11 | 11 | ||
| 12 | namespace Service::NVFlinger { | 12 | namespace Service { |
| 13 | namespace NVFlinger { | ||
| 13 | 14 | ||
| 14 | BufferQueue::BufferQueue(u32 id, u64 layer_id) : id(id), layer_id(layer_id) { | 15 | BufferQueue::BufferQueue(u32 id, u64 layer_id) : id(id), layer_id(layer_id) { |
| 15 | native_handle = Kernel::Event::Create(Kernel::ResetType::OneShot, "BufferQueue NativeHandle"); | 16 | native_handle = Kernel::Event::Create(Kernel::ResetType::OneShot, "BufferQueue NativeHandle"); |
| @@ -22,7 +23,7 @@ void BufferQueue::SetPreallocatedBuffer(u32 slot, IGBPBuffer& igbp_buffer) { | |||
| 22 | buffer.igbp_buffer = igbp_buffer; | 23 | buffer.igbp_buffer = igbp_buffer; |
| 23 | buffer.status = Buffer::Status::Free; | 24 | buffer.status = Buffer::Status::Free; |
| 24 | 25 | ||
| 25 | LOG_WARNING(Service, "Adding graphics buffer %u", slot); | 26 | NGLOG_WARNING(Service, "Adding graphics buffer {}", slot); |
| 26 | 27 | ||
| 27 | queue.emplace_back(buffer); | 28 | queue.emplace_back(buffer); |
| 28 | 29 | ||
| @@ -93,7 +94,7 @@ void BufferQueue::ReleaseBuffer(u32 slot) { | |||
| 93 | } | 94 | } |
| 94 | 95 | ||
| 95 | u32 BufferQueue::Query(QueryType type) { | 96 | u32 BufferQueue::Query(QueryType type) { |
| 96 | LOG_WARNING(Service, "(STUBBED) called type=%u", static_cast<u32>(type)); | 97 | NGLOG_WARNING(Service, "(STUBBED) called type={}", static_cast<u32>(type)); |
| 97 | switch (type) { | 98 | switch (type) { |
| 98 | case QueryType::NativeWindowFormat: | 99 | case QueryType::NativeWindowFormat: |
| 99 | // TODO(Subv): Use an enum for this | 100 | // TODO(Subv): Use an enum for this |
| @@ -110,4 +111,5 @@ void BufferQueue::SetBufferWaitEvent(Kernel::SharedPtr<Kernel::Event>&& wait_eve | |||
| 110 | buffer_wait_event = std::move(wait_event); | 111 | buffer_wait_event = std::move(wait_event); |
| 111 | } | 112 | } |
| 112 | 113 | ||
| 113 | } // namespace Service::NVFlinger | 114 | } // namespace NVFlinger |
| 115 | } // namespace Service | ||
diff --git a/src/core/hle/service/nvflinger/buffer_queue.h b/src/core/hle/service/nvflinger/buffer_queue.h index 95adc4706..1de5767cb 100644 --- a/src/core/hle/service/nvflinger/buffer_queue.h +++ b/src/core/hle/service/nvflinger/buffer_queue.h | |||
| @@ -13,7 +13,8 @@ namespace CoreTiming { | |||
| 13 | struct EventType; | 13 | struct EventType; |
| 14 | } | 14 | } |
| 15 | 15 | ||
| 16 | namespace Service::NVFlinger { | 16 | namespace Service { |
| 17 | namespace NVFlinger { | ||
| 17 | 18 | ||
| 18 | struct IGBPBuffer { | 19 | struct IGBPBuffer { |
| 19 | u32_le magic; | 20 | u32_le magic; |
| @@ -97,4 +98,5 @@ private: | |||
| 97 | Kernel::SharedPtr<Kernel::Event> buffer_wait_event; | 98 | Kernel::SharedPtr<Kernel::Event> buffer_wait_event; |
| 98 | }; | 99 | }; |
| 99 | 100 | ||
| 100 | } // namespace Service::NVFlinger | 101 | } // namespace NVFlinger |
| 102 | } // namespace Service | ||
diff --git a/src/core/hle/service/nvflinger/nvflinger.cpp b/src/core/hle/service/nvflinger/nvflinger.cpp index a99ebc8e6..3481e48d0 100644 --- a/src/core/hle/service/nvflinger/nvflinger.cpp +++ b/src/core/hle/service/nvflinger/nvflinger.cpp | |||
| @@ -48,7 +48,7 @@ NVFlinger::~NVFlinger() { | |||
| 48 | } | 48 | } |
| 49 | 49 | ||
| 50 | u64 NVFlinger::OpenDisplay(const std::string& name) { | 50 | u64 NVFlinger::OpenDisplay(const std::string& name) { |
| 51 | LOG_WARNING(Service, "Opening display %s", name.c_str()); | 51 | NGLOG_WARNING(Service, "Opening display {}", name); |
| 52 | 52 | ||
| 53 | // TODO(Subv): Currently we only support the Default display. | 53 | // TODO(Subv): Currently we only support the Default display. |
| 54 | ASSERT(name == "Default"); | 54 | ASSERT(name == "Default"); |
diff --git a/src/core/hle/service/pctl/pctl_a.cpp b/src/core/hle/service/pctl/module.cpp index 9fb4628ad..dd20d5ae7 100644 --- a/src/core/hle/service/pctl/pctl_a.cpp +++ b/src/core/hle/service/pctl/module.cpp | |||
| @@ -4,7 +4,8 @@ | |||
| 4 | 4 | ||
| 5 | #include "common/logging/log.h" | 5 | #include "common/logging/log.h" |
| 6 | #include "core/hle/ipc_helpers.h" | 6 | #include "core/hle/ipc_helpers.h" |
| 7 | #include "core/hle/service/pctl/pctl_a.h" | 7 | #include "core/hle/service/pctl/module.h" |
| 8 | #include "core/hle/service/pctl/pctl.h" | ||
| 8 | 9 | ||
| 9 | namespace Service::PCTL { | 10 | namespace Service::PCTL { |
| 10 | 11 | ||
| @@ -12,7 +13,7 @@ class IParentalControlService final : public ServiceFramework<IParentalControlSe | |||
| 12 | public: | 13 | public: |
| 13 | IParentalControlService() : ServiceFramework("IParentalControlService") { | 14 | IParentalControlService() : ServiceFramework("IParentalControlService") { |
| 14 | static const FunctionInfo functions[] = { | 15 | static const FunctionInfo functions[] = { |
| 15 | {1, nullptr, "Initialize"}, | 16 | {1, &IParentalControlService::Initialize, "Initialize"}, |
| 16 | {1001, nullptr, "CheckFreeCommunicationPermission"}, | 17 | {1001, nullptr, "CheckFreeCommunicationPermission"}, |
| 17 | {1002, nullptr, "ConfirmLaunchApplicationPermission"}, | 18 | {1002, nullptr, "ConfirmLaunchApplicationPermission"}, |
| 18 | {1003, nullptr, "ConfirmResumeApplicationPermission"}, | 19 | {1003, nullptr, "ConfirmResumeApplicationPermission"}, |
| @@ -108,20 +109,38 @@ public: | |||
| 108 | }; | 109 | }; |
| 109 | RegisterHandlers(functions); | 110 | RegisterHandlers(functions); |
| 110 | } | 111 | } |
| 112 | |||
| 113 | private: | ||
| 114 | void Initialize(Kernel::HLERequestContext& ctx) { | ||
| 115 | NGLOG_WARNING(Service_PCTL, "(STUBBED) called"); | ||
| 116 | IPC::ResponseBuilder rb{ctx, 2, 0, 0}; | ||
| 117 | rb.Push(RESULT_SUCCESS); | ||
| 118 | } | ||
| 111 | }; | 119 | }; |
| 112 | void PCTL_A::CreateService(Kernel::HLERequestContext& ctx) { | 120 | |
| 121 | void Module::Interface::CreateService(Kernel::HLERequestContext& ctx) { | ||
| 113 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | 122 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; |
| 114 | rb.Push(RESULT_SUCCESS); | 123 | rb.Push(RESULT_SUCCESS); |
| 115 | rb.PushIpcInterface<IParentalControlService>(); | 124 | rb.PushIpcInterface<IParentalControlService>(); |
| 116 | LOG_DEBUG(Service_PCTL, "called"); | 125 | NGLOG_DEBUG(Service_PCTL, "called"); |
| 117 | } | 126 | } |
| 118 | 127 | ||
| 119 | PCTL_A::PCTL_A() : ServiceFramework("pctl:a") { | 128 | void Module::Interface::CreateServiceWithoutInitialize(Kernel::HLERequestContext& ctx) { |
| 120 | static const FunctionInfo functions[] = { | 129 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; |
| 121 | {0, &PCTL_A::CreateService, "CreateService"}, | 130 | rb.Push(RESULT_SUCCESS); |
| 122 | {1, nullptr, "CreateServiceWithoutInitialize"}, | 131 | rb.PushIpcInterface<IParentalControlService>(); |
| 123 | }; | 132 | NGLOG_DEBUG(Service_PCTL, "called"); |
| 124 | RegisterHandlers(functions); | 133 | } |
| 134 | |||
| 135 | Module::Interface::Interface(std::shared_ptr<Module> module, const char* name) | ||
| 136 | : ServiceFramework(name), module(std::move(module)) {} | ||
| 137 | |||
| 138 | void InstallInterfaces(SM::ServiceManager& service_manager) { | ||
| 139 | auto module = std::make_shared<Module>(); | ||
| 140 | std::make_shared<PCTL>(module, "pctl")->InstallAsService(service_manager); | ||
| 141 | std::make_shared<PCTL>(module, "pctl:a")->InstallAsService(service_manager); | ||
| 142 | std::make_shared<PCTL>(module, "pctl:r")->InstallAsService(service_manager); | ||
| 143 | std::make_shared<PCTL>(module, "pctl:s")->InstallAsService(service_manager); | ||
| 125 | } | 144 | } |
| 126 | 145 | ||
| 127 | } // namespace Service::PCTL | 146 | } // namespace Service::PCTL |
diff --git a/src/core/hle/service/pctl/module.h b/src/core/hle/service/pctl/module.h new file mode 100644 index 000000000..68da628a8 --- /dev/null +++ b/src/core/hle/service/pctl/module.h | |||
| @@ -0,0 +1,28 @@ | |||
| 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 | #include "core/hle/service/service.h" | ||
| 8 | |||
| 9 | namespace Service::PCTL { | ||
| 10 | |||
| 11 | class Module final { | ||
| 12 | public: | ||
| 13 | class Interface : public ServiceFramework<Interface> { | ||
| 14 | public: | ||
| 15 | Interface(std::shared_ptr<Module> module, const char* name); | ||
| 16 | |||
| 17 | void CreateService(Kernel::HLERequestContext& ctx); | ||
| 18 | void CreateServiceWithoutInitialize(Kernel::HLERequestContext& ctx); | ||
| 19 | |||
| 20 | protected: | ||
| 21 | std::shared_ptr<Module> module; | ||
| 22 | }; | ||
| 23 | }; | ||
| 24 | |||
| 25 | /// Registers all PCTL services with the specified service manager. | ||
| 26 | void InstallInterfaces(SM::ServiceManager& service_manager); | ||
| 27 | |||
| 28 | } // namespace Service::PCTL | ||
diff --git a/src/core/hle/service/pctl/pctl.cpp b/src/core/hle/service/pctl/pctl.cpp index 6ee81866d..de2741d66 100644 --- a/src/core/hle/service/pctl/pctl.cpp +++ b/src/core/hle/service/pctl/pctl.cpp | |||
| @@ -3,12 +3,15 @@ | |||
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include "core/hle/service/pctl/pctl.h" | 5 | #include "core/hle/service/pctl/pctl.h" |
| 6 | #include "core/hle/service/pctl/pctl_a.h" | ||
| 7 | 6 | ||
| 8 | namespace Service::PCTL { | 7 | namespace Service::PCTL { |
| 9 | 8 | ||
| 10 | void InstallInterfaces(SM::ServiceManager& service_manager) { | 9 | PCTL::PCTL(std::shared_ptr<Module> module, const char* name) |
| 11 | std::make_shared<PCTL_A>()->InstallAsService(service_manager); | 10 | : Module::Interface(std::move(module), name) { |
| 11 | static const FunctionInfo functions[] = { | ||
| 12 | {0, &PCTL::CreateService, "CreateService"}, | ||
| 13 | {1, &PCTL::CreateServiceWithoutInitialize, "CreateServiceWithoutInitialize"}, | ||
| 14 | }; | ||
| 15 | RegisterHandlers(functions); | ||
| 12 | } | 16 | } |
| 13 | |||
| 14 | } // namespace Service::PCTL | 17 | } // namespace Service::PCTL |
diff --git a/src/core/hle/service/pctl/pctl.h b/src/core/hle/service/pctl/pctl.h index f0a84b115..8ddf69128 100644 --- a/src/core/hle/service/pctl/pctl.h +++ b/src/core/hle/service/pctl/pctl.h | |||
| @@ -4,11 +4,13 @@ | |||
| 4 | 4 | ||
| 5 | #pragma once | 5 | #pragma once |
| 6 | 6 | ||
| 7 | #include "core/hle/service/service.h" | 7 | #include "core/hle/service/pctl/module.h" |
| 8 | 8 | ||
| 9 | namespace Service::PCTL { | 9 | namespace Service::PCTL { |
| 10 | 10 | ||
| 11 | /// Registers all PCTL services with the specified service manager. | 11 | class PCTL final : public Module::Interface { |
| 12 | void InstallInterfaces(SM::ServiceManager& service_manager); | 12 | public: |
| 13 | explicit PCTL(std::shared_ptr<Module> module, const char* name); | ||
| 14 | }; | ||
| 13 | 15 | ||
| 14 | } // namespace Service::PCTL | 16 | } // namespace Service::PCTL |
diff --git a/src/core/hle/service/pctl/pctl_a.h b/src/core/hle/service/pctl/pctl_a.h deleted file mode 100644 index 09ed82e1b..000000000 --- a/src/core/hle/service/pctl/pctl_a.h +++ /dev/null | |||
| @@ -1,20 +0,0 @@ | |||
| 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 | #include "core/hle/service/service.h" | ||
| 8 | |||
| 9 | namespace Service::PCTL { | ||
| 10 | |||
| 11 | class PCTL_A final : public ServiceFramework<PCTL_A> { | ||
| 12 | public: | ||
| 13 | PCTL_A(); | ||
| 14 | ~PCTL_A() = default; | ||
| 15 | |||
| 16 | private: | ||
| 17 | void CreateService(Kernel::HLERequestContext& ctx); | ||
| 18 | }; | ||
| 19 | |||
| 20 | } // namespace Service::PCTL | ||
diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp index 68d2b9f17..34d691b90 100644 --- a/src/core/hle/service/service.cpp +++ b/src/core/hle/service/service.cpp | |||
| @@ -121,7 +121,7 @@ void ServiceFrameworkBase::ReportUnimplementedFunction(Kernel::HLERequestContext | |||
| 121 | } | 121 | } |
| 122 | buf.push_back('}'); | 122 | buf.push_back('}'); |
| 123 | 123 | ||
| 124 | LOG_ERROR(Service, "unknown / unimplemented %s", fmt::to_string(buf).c_str()); | 124 | NGLOG_ERROR(Service, "unknown / unimplemented {}", fmt::to_string(buf)); |
| 125 | UNIMPLEMENTED(); | 125 | UNIMPLEMENTED(); |
| 126 | } | 126 | } |
| 127 | 127 | ||
| @@ -132,8 +132,8 @@ void ServiceFrameworkBase::InvokeRequest(Kernel::HLERequestContext& ctx) { | |||
| 132 | return ReportUnimplementedFunction(ctx, info); | 132 | return ReportUnimplementedFunction(ctx, info); |
| 133 | } | 133 | } |
| 134 | 134 | ||
| 135 | LOG_TRACE( | 135 | NGLOG_TRACE( |
| 136 | Service, "%s", | 136 | Service, "{}", |
| 137 | MakeFunctionString(info->name, GetServiceName().c_str(), ctx.CommandBuffer()).c_str()); | 137 | MakeFunctionString(info->name, GetServiceName().c_str(), ctx.CommandBuffer()).c_str()); |
| 138 | handler_invoker(this, info->handler_callback, ctx); | 138 | handler_invoker(this, info->handler_callback, ctx); |
| 139 | } | 139 | } |
| @@ -201,12 +201,12 @@ void Init(std::shared_ptr<SM::ServiceManager>& sm) { | |||
| 201 | VI::InstallInterfaces(*sm, nv_flinger); | 201 | VI::InstallInterfaces(*sm, nv_flinger); |
| 202 | Set::InstallInterfaces(*sm); | 202 | Set::InstallInterfaces(*sm); |
| 203 | 203 | ||
| 204 | LOG_DEBUG(Service, "initialized OK"); | 204 | NGLOG_DEBUG(Service, "initialized OK"); |
| 205 | } | 205 | } |
| 206 | 206 | ||
| 207 | /// Shutdown ServiceManager | 207 | /// Shutdown ServiceManager |
| 208 | void Shutdown() { | 208 | void Shutdown() { |
| 209 | g_kernel_named_ports.clear(); | 209 | g_kernel_named_ports.clear(); |
| 210 | LOG_DEBUG(Service, "shutdown OK"); | 210 | NGLOG_DEBUG(Service, "shutdown OK"); |
| 211 | } | 211 | } |
| 212 | } // namespace Service | 212 | } // namespace Service |
diff --git a/src/core/hle/service/set/set.cpp b/src/core/hle/service/set/set.cpp index fc3e424d0..ece29aa70 100644 --- a/src/core/hle/service/set/set.cpp +++ b/src/core/hle/service/set/set.cpp | |||
| @@ -22,7 +22,7 @@ void SET::GetAvailableLanguageCodes(Kernel::HLERequestContext& ctx) { | |||
| 22 | 22 | ||
| 23 | rb.Push(RESULT_SUCCESS); | 23 | rb.Push(RESULT_SUCCESS); |
| 24 | 24 | ||
| 25 | LOG_WARNING(Service_SET, "(STUBBED) called"); | 25 | NGLOG_WARNING(Service_SET, "(STUBBED) called"); |
| 26 | } | 26 | } |
| 27 | 27 | ||
| 28 | SET::SET() : ServiceFramework("set") { | 28 | SET::SET() : ServiceFramework("set") { |
diff --git a/src/core/hle/service/set/set_sys.cpp b/src/core/hle/service/set/set_sys.cpp index fa85277fe..762a664c5 100644 --- a/src/core/hle/service/set/set_sys.cpp +++ b/src/core/hle/service/set/set_sys.cpp | |||
| @@ -16,7 +16,7 @@ void SET_SYS::GetColorSetId(Kernel::HLERequestContext& ctx) { | |||
| 16 | rb.Push(RESULT_SUCCESS); | 16 | rb.Push(RESULT_SUCCESS); |
| 17 | rb.Push<u32>(0); | 17 | rb.Push<u32>(0); |
| 18 | 18 | ||
| 19 | LOG_WARNING(Service_SET, "(STUBBED) called"); | 19 | NGLOG_WARNING(Service_SET, "(STUBBED) called"); |
| 20 | } | 20 | } |
| 21 | 21 | ||
| 22 | SET_SYS::SET_SYS() : ServiceFramework("set:sys") { | 22 | SET_SYS::SET_SYS() : ServiceFramework("set:sys") { |
diff --git a/src/core/hle/service/sm/controller.cpp b/src/core/hle/service/sm/controller.cpp index 13e31620d..fe5097cdc 100644 --- a/src/core/hle/service/sm/controller.cpp +++ b/src/core/hle/service/sm/controller.cpp | |||
| @@ -17,7 +17,7 @@ void Controller::ConvertSessionToDomain(Kernel::HLERequestContext& ctx) { | |||
| 17 | rb.Push(RESULT_SUCCESS); | 17 | rb.Push(RESULT_SUCCESS); |
| 18 | rb.Push<u32>(1); // Converted sessions start with 1 request handler | 18 | rb.Push<u32>(1); // Converted sessions start with 1 request handler |
| 19 | 19 | ||
| 20 | LOG_DEBUG(Service, "called, server_session=%d", ctx.Session()->GetObjectId()); | 20 | NGLOG_DEBUG(Service, "called, server_session={}", ctx.Session()->GetObjectId()); |
| 21 | } | 21 | } |
| 22 | 22 | ||
| 23 | void Controller::DuplicateSession(Kernel::HLERequestContext& ctx) { | 23 | void Controller::DuplicateSession(Kernel::HLERequestContext& ctx) { |
| @@ -29,11 +29,11 @@ void Controller::DuplicateSession(Kernel::HLERequestContext& ctx) { | |||
| 29 | Kernel::SharedPtr<Kernel::ClientSession> session{ctx.Session()->parent->client}; | 29 | Kernel::SharedPtr<Kernel::ClientSession> session{ctx.Session()->parent->client}; |
| 30 | rb.PushMoveObjects(session); | 30 | rb.PushMoveObjects(session); |
| 31 | 31 | ||
| 32 | LOG_DEBUG(Service, "called, session=%u", session->GetObjectId()); | 32 | NGLOG_DEBUG(Service, "called, session={}", session->GetObjectId()); |
| 33 | } | 33 | } |
| 34 | 34 | ||
| 35 | void Controller::DuplicateSessionEx(Kernel::HLERequestContext& ctx) { | 35 | void Controller::DuplicateSessionEx(Kernel::HLERequestContext& ctx) { |
| 36 | LOG_WARNING(Service, "(STUBBED) called, using DuplicateSession"); | 36 | NGLOG_WARNING(Service, "(STUBBED) called, using DuplicateSession"); |
| 37 | 37 | ||
| 38 | DuplicateSession(ctx); | 38 | DuplicateSession(ctx); |
| 39 | } | 39 | } |
| @@ -43,7 +43,7 @@ void Controller::QueryPointerBufferSize(Kernel::HLERequestContext& ctx) { | |||
| 43 | rb.Push(RESULT_SUCCESS); | 43 | rb.Push(RESULT_SUCCESS); |
| 44 | rb.Push<u32>(0x500); | 44 | rb.Push<u32>(0x500); |
| 45 | 45 | ||
| 46 | LOG_WARNING(Service, "(STUBBED) called"); | 46 | NGLOG_WARNING(Service, "(STUBBED) called"); |
| 47 | } | 47 | } |
| 48 | 48 | ||
| 49 | Controller::Controller() : ServiceFramework("IpcController") { | 49 | Controller::Controller() : ServiceFramework("IpcController") { |
diff --git a/src/core/hle/service/sm/sm.cpp b/src/core/hle/service/sm/sm.cpp index 4578fc05f..073277ade 100644 --- a/src/core/hle/service/sm/sm.cpp +++ b/src/core/hle/service/sm/sm.cpp | |||
| @@ -86,7 +86,7 @@ SM::~SM() = default; | |||
| 86 | void SM::Initialize(Kernel::HLERequestContext& ctx) { | 86 | void SM::Initialize(Kernel::HLERequestContext& ctx) { |
| 87 | IPC::ResponseBuilder rb{ctx, 2}; | 87 | IPC::ResponseBuilder rb{ctx, 2}; |
| 88 | rb.Push(RESULT_SUCCESS); | 88 | rb.Push(RESULT_SUCCESS); |
| 89 | LOG_DEBUG(Service_SM, "called"); | 89 | NGLOG_DEBUG(Service_SM, "called"); |
| 90 | } | 90 | } |
| 91 | 91 | ||
| 92 | void SM::GetService(Kernel::HLERequestContext& ctx) { | 92 | void SM::GetService(Kernel::HLERequestContext& ctx) { |
| @@ -102,8 +102,8 @@ void SM::GetService(Kernel::HLERequestContext& ctx) { | |||
| 102 | if (client_port.Failed()) { | 102 | if (client_port.Failed()) { |
| 103 | IPC::ResponseBuilder rb = rp.MakeBuilder(2, 0, 0); | 103 | IPC::ResponseBuilder rb = rp.MakeBuilder(2, 0, 0); |
| 104 | rb.Push(client_port.Code()); | 104 | rb.Push(client_port.Code()); |
| 105 | LOG_ERROR(Service_SM, "called service=%s -> error 0x%08X", name.c_str(), | 105 | NGLOG_ERROR(Service_SM, "called service={} -> error {:#010X}", name, |
| 106 | client_port.Code().raw); | 106 | client_port.Code().raw); |
| 107 | if (name.length() == 0) | 107 | if (name.length() == 0) |
| 108 | return; // LibNX Fix | 108 | return; // LibNX Fix |
| 109 | UNIMPLEMENTED(); | 109 | UNIMPLEMENTED(); |
| @@ -113,8 +113,7 @@ void SM::GetService(Kernel::HLERequestContext& ctx) { | |||
| 113 | auto session = client_port.Unwrap()->Connect(); | 113 | auto session = client_port.Unwrap()->Connect(); |
| 114 | ASSERT(session.Succeeded()); | 114 | ASSERT(session.Succeeded()); |
| 115 | if (session.Succeeded()) { | 115 | if (session.Succeeded()) { |
| 116 | LOG_DEBUG(Service_SM, "called service=%s -> session=%u", name.c_str(), | 116 | NGLOG_DEBUG(Service_SM, "called service={} -> session={}", name, (*session)->GetObjectId()); |
| 117 | (*session)->GetObjectId()); | ||
| 118 | IPC::ResponseBuilder rb = | 117 | IPC::ResponseBuilder rb = |
| 119 | rp.MakeBuilder(2, 0, 1, IPC::ResponseBuilder::Flags::AlwaysMoveHandles); | 118 | rp.MakeBuilder(2, 0, 1, IPC::ResponseBuilder::Flags::AlwaysMoveHandles); |
| 120 | rb.Push(session.Code()); | 119 | rb.Push(session.Code()); |
diff --git a/src/core/hle/service/sockets/bsd.cpp b/src/core/hle/service/sockets/bsd.cpp index f99809bed..ab909fdaa 100644 --- a/src/core/hle/service/sockets/bsd.cpp +++ b/src/core/hle/service/sockets/bsd.cpp | |||
| @@ -8,7 +8,7 @@ | |||
| 8 | namespace Service::Sockets { | 8 | namespace Service::Sockets { |
| 9 | 9 | ||
| 10 | void BSD::RegisterClient(Kernel::HLERequestContext& ctx) { | 10 | void BSD::RegisterClient(Kernel::HLERequestContext& ctx) { |
| 11 | LOG_WARNING(Service, "(STUBBED) called"); | 11 | NGLOG_WARNING(Service, "(STUBBED) called"); |
| 12 | 12 | ||
| 13 | IPC::ResponseBuilder rb{ctx, 3}; | 13 | IPC::ResponseBuilder rb{ctx, 3}; |
| 14 | 14 | ||
| @@ -17,7 +17,7 @@ void BSD::RegisterClient(Kernel::HLERequestContext& ctx) { | |||
| 17 | } | 17 | } |
| 18 | 18 | ||
| 19 | void BSD::StartMonitoring(Kernel::HLERequestContext& ctx) { | 19 | void BSD::StartMonitoring(Kernel::HLERequestContext& ctx) { |
| 20 | LOG_WARNING(Service, "(STUBBED) called"); | 20 | NGLOG_WARNING(Service, "(STUBBED) called"); |
| 21 | 21 | ||
| 22 | IPC::ResponseBuilder rb{ctx, 3}; | 22 | IPC::ResponseBuilder rb{ctx, 3}; |
| 23 | 23 | ||
| @@ -32,7 +32,8 @@ void BSD::Socket(Kernel::HLERequestContext& ctx) { | |||
| 32 | u32 type = rp.Pop<u32>(); | 32 | u32 type = rp.Pop<u32>(); |
| 33 | u32 protocol = rp.Pop<u32>(); | 33 | u32 protocol = rp.Pop<u32>(); |
| 34 | 34 | ||
| 35 | LOG_WARNING(Service, "(STUBBED) called domain=%u type=%u protocol=%u", domain, type, protocol); | 35 | NGLOG_WARNING(Service, "(STUBBED) called domain={} type={} protocol={}", domain, type, |
| 36 | protocol); | ||
| 36 | 37 | ||
| 37 | u32 fd = next_fd++; | 38 | u32 fd = next_fd++; |
| 38 | 39 | ||
| @@ -44,7 +45,7 @@ void BSD::Socket(Kernel::HLERequestContext& ctx) { | |||
| 44 | } | 45 | } |
| 45 | 46 | ||
| 46 | void BSD::Connect(Kernel::HLERequestContext& ctx) { | 47 | void BSD::Connect(Kernel::HLERequestContext& ctx) { |
| 47 | LOG_WARNING(Service, "(STUBBED) called"); | 48 | NGLOG_WARNING(Service, "(STUBBED) called"); |
| 48 | 49 | ||
| 49 | IPC::ResponseBuilder rb{ctx, 4}; | 50 | IPC::ResponseBuilder rb{ctx, 4}; |
| 50 | 51 | ||
| @@ -54,7 +55,7 @@ void BSD::Connect(Kernel::HLERequestContext& ctx) { | |||
| 54 | } | 55 | } |
| 55 | 56 | ||
| 56 | void BSD::SendTo(Kernel::HLERequestContext& ctx) { | 57 | void BSD::SendTo(Kernel::HLERequestContext& ctx) { |
| 57 | LOG_WARNING(Service, "(STUBBED) called"); | 58 | NGLOG_WARNING(Service, "(STUBBED) called"); |
| 58 | 59 | ||
| 59 | IPC::ResponseBuilder rb{ctx, 4}; | 60 | IPC::ResponseBuilder rb{ctx, 4}; |
| 60 | 61 | ||
| @@ -64,7 +65,7 @@ void BSD::SendTo(Kernel::HLERequestContext& ctx) { | |||
| 64 | } | 65 | } |
| 65 | 66 | ||
| 66 | void BSD::Close(Kernel::HLERequestContext& ctx) { | 67 | void BSD::Close(Kernel::HLERequestContext& ctx) { |
| 67 | LOG_WARNING(Service, "(STUBBED) called"); | 68 | NGLOG_WARNING(Service, "(STUBBED) called"); |
| 68 | 69 | ||
| 69 | IPC::ResponseBuilder rb{ctx, 4}; | 70 | IPC::ResponseBuilder rb{ctx, 4}; |
| 70 | 71 | ||
diff --git a/src/core/hle/service/sockets/sfdnsres.cpp b/src/core/hle/service/sockets/sfdnsres.cpp index d235c4cfd..f377e59f2 100644 --- a/src/core/hle/service/sockets/sfdnsres.cpp +++ b/src/core/hle/service/sockets/sfdnsres.cpp | |||
| @@ -10,7 +10,7 @@ namespace Service::Sockets { | |||
| 10 | void SFDNSRES::GetAddrInfo(Kernel::HLERequestContext& ctx) { | 10 | void SFDNSRES::GetAddrInfo(Kernel::HLERequestContext& ctx) { |
| 11 | IPC::RequestParser rp{ctx}; | 11 | IPC::RequestParser rp{ctx}; |
| 12 | 12 | ||
| 13 | LOG_WARNING(Service, "(STUBBED) called"); | 13 | NGLOG_WARNING(Service, "(STUBBED) called"); |
| 14 | 14 | ||
| 15 | IPC::ResponseBuilder rb{ctx, 2}; | 15 | IPC::ResponseBuilder rb{ctx, 2}; |
| 16 | 16 | ||
diff --git a/src/core/hle/service/spl/module.cpp b/src/core/hle/service/spl/module.cpp index 3f5a342a7..76ba97156 100644 --- a/src/core/hle/service/spl/module.cpp +++ b/src/core/hle/service/spl/module.cpp | |||
| @@ -28,7 +28,7 @@ void Module::Interface::GetRandomBytes(Kernel::HLERequestContext& ctx) { | |||
| 28 | 28 | ||
| 29 | IPC::ResponseBuilder rb{ctx, 2}; | 29 | IPC::ResponseBuilder rb{ctx, 2}; |
| 30 | rb.Push(RESULT_SUCCESS); | 30 | rb.Push(RESULT_SUCCESS); |
| 31 | LOG_DEBUG(Service_SPL, "called"); | 31 | NGLOG_DEBUG(Service_SPL, "called"); |
| 32 | } | 32 | } |
| 33 | 33 | ||
| 34 | void InstallInterfaces(SM::ServiceManager& service_manager) { | 34 | void InstallInterfaces(SM::ServiceManager& service_manager) { |
diff --git a/src/core/hle/service/ssl/ssl.cpp b/src/core/hle/service/ssl/ssl.cpp index 40aea6090..8a85df91a 100644 --- a/src/core/hle/service/ssl/ssl.cpp +++ b/src/core/hle/service/ssl/ssl.cpp | |||
| @@ -65,7 +65,7 @@ public: | |||
| 65 | 65 | ||
| 66 | private: | 66 | private: |
| 67 | void SetOption(Kernel::HLERequestContext& ctx) { | 67 | void SetOption(Kernel::HLERequestContext& ctx) { |
| 68 | LOG_WARNING(Service_SSL, "(STUBBED) called"); | 68 | NGLOG_WARNING(Service_SSL, "(STUBBED) called"); |
| 69 | IPC::RequestParser rp{ctx}; | 69 | IPC::RequestParser rp{ctx}; |
| 70 | 70 | ||
| 71 | IPC::ResponseBuilder rb = rp.MakeBuilder(2, 0, 0); | 71 | IPC::ResponseBuilder rb = rp.MakeBuilder(2, 0, 0); |
| @@ -73,7 +73,7 @@ private: | |||
| 73 | } | 73 | } |
| 74 | 74 | ||
| 75 | void CreateConnection(Kernel::HLERequestContext& ctx) { | 75 | void CreateConnection(Kernel::HLERequestContext& ctx) { |
| 76 | LOG_WARNING(Service_SSL, "(STUBBED) called"); | 76 | NGLOG_WARNING(Service_SSL, "(STUBBED) called"); |
| 77 | 77 | ||
| 78 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | 78 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; |
| 79 | rb.Push(RESULT_SUCCESS); | 79 | rb.Push(RESULT_SUCCESS); |
| @@ -82,7 +82,7 @@ private: | |||
| 82 | }; | 82 | }; |
| 83 | 83 | ||
| 84 | void SSL::CreateContext(Kernel::HLERequestContext& ctx) { | 84 | void SSL::CreateContext(Kernel::HLERequestContext& ctx) { |
| 85 | LOG_WARNING(Service_SSL, "(STUBBED) called"); | 85 | NGLOG_WARNING(Service_SSL, "(STUBBED) called"); |
| 86 | 86 | ||
| 87 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | 87 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; |
| 88 | rb.Push(RESULT_SUCCESS); | 88 | rb.Push(RESULT_SUCCESS); |
diff --git a/src/core/hle/service/time/time.cpp b/src/core/hle/service/time/time.cpp index 2604ecc1c..278465358 100644 --- a/src/core/hle/service/time/time.cpp +++ b/src/core/hle/service/time/time.cpp | |||
| @@ -32,14 +32,14 @@ private: | |||
| 32 | const s64 time_since_epoch{std::chrono::duration_cast<std::chrono::seconds>( | 32 | const s64 time_since_epoch{std::chrono::duration_cast<std::chrono::seconds>( |
| 33 | std::chrono::system_clock::now().time_since_epoch()) | 33 | std::chrono::system_clock::now().time_since_epoch()) |
| 34 | .count()}; | 34 | .count()}; |
| 35 | LOG_DEBUG(Service_Time, "called"); | 35 | NGLOG_DEBUG(Service_Time, "called"); |
| 36 | IPC::ResponseBuilder rb{ctx, 4}; | 36 | IPC::ResponseBuilder rb{ctx, 4}; |
| 37 | rb.Push(RESULT_SUCCESS); | 37 | rb.Push(RESULT_SUCCESS); |
| 38 | rb.Push<u64>(time_since_epoch); | 38 | rb.Push<u64>(time_since_epoch); |
| 39 | } | 39 | } |
| 40 | 40 | ||
| 41 | void GetSystemClockContext(Kernel::HLERequestContext& ctx) { | 41 | void GetSystemClockContext(Kernel::HLERequestContext& ctx) { |
| 42 | LOG_WARNING(Service_Time, "(STUBBED) called"); | 42 | NGLOG_WARNING(Service_Time, "(STUBBED) called"); |
| 43 | SystemClockContext system_clock_ontext{}; | 43 | SystemClockContext system_clock_ontext{}; |
| 44 | IPC::ResponseBuilder rb{ctx, (sizeof(SystemClockContext) / 4) + 2}; | 44 | IPC::ResponseBuilder rb{ctx, (sizeof(SystemClockContext) / 4) + 2}; |
| 45 | rb.Push(RESULT_SUCCESS); | 45 | rb.Push(RESULT_SUCCESS); |
| @@ -58,7 +58,7 @@ public: | |||
| 58 | 58 | ||
| 59 | private: | 59 | private: |
| 60 | void GetCurrentTimePoint(Kernel::HLERequestContext& ctx) { | 60 | void GetCurrentTimePoint(Kernel::HLERequestContext& ctx) { |
| 61 | LOG_DEBUG(Service_Time, "called"); | 61 | NGLOG_DEBUG(Service_Time, "called"); |
| 62 | SteadyClockTimePoint steady_clock_time_point{cyclesToMs(CoreTiming::GetTicks()) / 1000}; | 62 | SteadyClockTimePoint steady_clock_time_point{cyclesToMs(CoreTiming::GetTicks()) / 1000}; |
| 63 | IPC::ResponseBuilder rb{ctx, (sizeof(SteadyClockTimePoint) / 4) + 2}; | 63 | IPC::ResponseBuilder rb{ctx, (sizeof(SteadyClockTimePoint) / 4) + 2}; |
| 64 | rb.Push(RESULT_SUCCESS); | 64 | rb.Push(RESULT_SUCCESS); |
| @@ -86,7 +86,7 @@ public: | |||
| 86 | 86 | ||
| 87 | private: | 87 | private: |
| 88 | void GetDeviceLocationName(Kernel::HLERequestContext& ctx) { | 88 | void GetDeviceLocationName(Kernel::HLERequestContext& ctx) { |
| 89 | LOG_WARNING(Service_Time, "(STUBBED) called"); | 89 | NGLOG_WARNING(Service_Time, "(STUBBED) called"); |
| 90 | LocationName location_name{}; | 90 | LocationName location_name{}; |
| 91 | IPC::ResponseBuilder rb{ctx, (sizeof(LocationName) / 4) + 2}; | 91 | IPC::ResponseBuilder rb{ctx, (sizeof(LocationName) / 4) + 2}; |
| 92 | rb.Push(RESULT_SUCCESS); | 92 | rb.Push(RESULT_SUCCESS); |
| @@ -94,14 +94,14 @@ private: | |||
| 94 | } | 94 | } |
| 95 | 95 | ||
| 96 | void GetTotalLocationNameCount(Kernel::HLERequestContext& ctx) { | 96 | void GetTotalLocationNameCount(Kernel::HLERequestContext& ctx) { |
| 97 | LOG_WARNING(Service_Time, "(STUBBED) called"); | 97 | NGLOG_WARNING(Service_Time, "(STUBBED) called"); |
| 98 | IPC::ResponseBuilder rb{ctx, 3}; | 98 | IPC::ResponseBuilder rb{ctx, 3}; |
| 99 | rb.Push(RESULT_SUCCESS); | 99 | rb.Push(RESULT_SUCCESS); |
| 100 | rb.Push<u32>(0); | 100 | rb.Push<u32>(0); |
| 101 | } | 101 | } |
| 102 | 102 | ||
| 103 | void LoadTimeZoneRule(Kernel::HLERequestContext& ctx) { | 103 | void LoadTimeZoneRule(Kernel::HLERequestContext& ctx) { |
| 104 | LOG_WARNING(Service_Time, "(STUBBED) called"); | 104 | NGLOG_WARNING(Service_Time, "(STUBBED) called"); |
| 105 | IPC::ResponseBuilder rb{ctx, 2}; | 105 | IPC::ResponseBuilder rb{ctx, 2}; |
| 106 | rb.Push(RESULT_SUCCESS); | 106 | rb.Push(RESULT_SUCCESS); |
| 107 | } | 107 | } |
| @@ -110,7 +110,7 @@ private: | |||
| 110 | IPC::RequestParser rp{ctx}; | 110 | IPC::RequestParser rp{ctx}; |
| 111 | u64 posix_time = rp.Pop<u64>(); | 111 | u64 posix_time = rp.Pop<u64>(); |
| 112 | 112 | ||
| 113 | LOG_WARNING(Service_Time, "(STUBBED) called, posix_time=0x%016lX", posix_time); | 113 | NGLOG_WARNING(Service_Time, "(STUBBED) called, posix_time={:#018X}", posix_time); |
| 114 | 114 | ||
| 115 | CalendarTime calendar_time{2018, 1, 1, 0, 0, 0}; | 115 | CalendarTime calendar_time{2018, 1, 1, 0, 0, 0}; |
| 116 | CalendarAdditionalInfo additional_info{}; | 116 | CalendarAdditionalInfo additional_info{}; |
| @@ -125,35 +125,35 @@ void Module::Interface::GetStandardUserSystemClock(Kernel::HLERequestContext& ct | |||
| 125 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | 125 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; |
| 126 | rb.Push(RESULT_SUCCESS); | 126 | rb.Push(RESULT_SUCCESS); |
| 127 | rb.PushIpcInterface<ISystemClock>(); | 127 | rb.PushIpcInterface<ISystemClock>(); |
| 128 | LOG_DEBUG(Service_Time, "called"); | 128 | NGLOG_DEBUG(Service_Time, "called"); |
| 129 | } | 129 | } |
| 130 | 130 | ||
| 131 | void Module::Interface::GetStandardNetworkSystemClock(Kernel::HLERequestContext& ctx) { | 131 | void Module::Interface::GetStandardNetworkSystemClock(Kernel::HLERequestContext& ctx) { |
| 132 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | 132 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; |
| 133 | rb.Push(RESULT_SUCCESS); | 133 | rb.Push(RESULT_SUCCESS); |
| 134 | rb.PushIpcInterface<ISystemClock>(); | 134 | rb.PushIpcInterface<ISystemClock>(); |
| 135 | LOG_DEBUG(Service_Time, "called"); | 135 | NGLOG_DEBUG(Service_Time, "called"); |
| 136 | } | 136 | } |
| 137 | 137 | ||
| 138 | void Module::Interface::GetStandardSteadyClock(Kernel::HLERequestContext& ctx) { | 138 | void Module::Interface::GetStandardSteadyClock(Kernel::HLERequestContext& ctx) { |
| 139 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | 139 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; |
| 140 | rb.Push(RESULT_SUCCESS); | 140 | rb.Push(RESULT_SUCCESS); |
| 141 | rb.PushIpcInterface<ISteadyClock>(); | 141 | rb.PushIpcInterface<ISteadyClock>(); |
| 142 | LOG_DEBUG(Service_Time, "called"); | 142 | NGLOG_DEBUG(Service_Time, "called"); |
| 143 | } | 143 | } |
| 144 | 144 | ||
| 145 | void Module::Interface::GetTimeZoneService(Kernel::HLERequestContext& ctx) { | 145 | void Module::Interface::GetTimeZoneService(Kernel::HLERequestContext& ctx) { |
| 146 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | 146 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; |
| 147 | rb.Push(RESULT_SUCCESS); | 147 | rb.Push(RESULT_SUCCESS); |
| 148 | rb.PushIpcInterface<ITimeZoneService>(); | 148 | rb.PushIpcInterface<ITimeZoneService>(); |
| 149 | LOG_DEBUG(Service_Time, "called"); | 149 | NGLOG_DEBUG(Service_Time, "called"); |
| 150 | } | 150 | } |
| 151 | 151 | ||
| 152 | void Module::Interface::GetStandardLocalSystemClock(Kernel::HLERequestContext& ctx) { | 152 | void Module::Interface::GetStandardLocalSystemClock(Kernel::HLERequestContext& ctx) { |
| 153 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | 153 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; |
| 154 | rb.Push(RESULT_SUCCESS); | 154 | rb.Push(RESULT_SUCCESS); |
| 155 | rb.PushIpcInterface<ISystemClock>(); | 155 | rb.PushIpcInterface<ISystemClock>(); |
| 156 | LOG_DEBUG(Service_Time, "called"); | 156 | NGLOG_DEBUG(Service_Time, "called"); |
| 157 | } | 157 | } |
| 158 | 158 | ||
| 159 | Module::Interface::Interface(std::shared_ptr<Module> time, const char* name) | 159 | Module::Interface::Interface(std::shared_ptr<Module> time, const char* name) |
diff --git a/src/core/hle/service/vi/vi.cpp b/src/core/hle/service/vi/vi.cpp index 36ae2215f..45f3568d2 100644 --- a/src/core/hle/service/vi/vi.cpp +++ b/src/core/hle/service/vi/vi.cpp | |||
| @@ -470,7 +470,7 @@ private: | |||
| 470 | u32 flags = rp.Pop<u32>(); | 470 | u32 flags = rp.Pop<u32>(); |
| 471 | auto buffer_queue = nv_flinger->GetBufferQueue(id); | 471 | auto buffer_queue = nv_flinger->GetBufferQueue(id); |
| 472 | 472 | ||
| 473 | LOG_DEBUG(Service_VI, "called, transaction=%x", static_cast<u32>(transaction)); | 473 | NGLOG_DEBUG(Service_VI, "called, transaction={:X}", static_cast<u32>(transaction)); |
| 474 | 474 | ||
| 475 | if (transaction == TransactionId::Connect) { | 475 | if (transaction == TransactionId::Connect) { |
| 476 | IGBPConnectRequestParcel request{ctx.ReadBuffer()}; | 476 | IGBPConnectRequestParcel request{ctx.ReadBuffer()}; |
| @@ -532,7 +532,7 @@ private: | |||
| 532 | IGBPQueryResponseParcel response{value}; | 532 | IGBPQueryResponseParcel response{value}; |
| 533 | ctx.WriteBuffer(response.Serialize()); | 533 | ctx.WriteBuffer(response.Serialize()); |
| 534 | } else if (transaction == TransactionId::CancelBuffer) { | 534 | } else if (transaction == TransactionId::CancelBuffer) { |
| 535 | LOG_WARNING(Service_VI, "(STUBBED) called, transaction=CancelBuffer"); | 535 | NGLOG_WARNING(Service_VI, "(STUBBED) called, transaction=CancelBuffer"); |
| 536 | } else { | 536 | } else { |
| 537 | ASSERT_MSG(false, "Unimplemented"); | 537 | ASSERT_MSG(false, "Unimplemented"); |
| 538 | } | 538 | } |
| @@ -547,7 +547,8 @@ private: | |||
| 547 | s32 addval = rp.PopRaw<s32>(); | 547 | s32 addval = rp.PopRaw<s32>(); |
| 548 | u32 type = rp.Pop<u32>(); | 548 | u32 type = rp.Pop<u32>(); |
| 549 | 549 | ||
| 550 | LOG_WARNING(Service_VI, "(STUBBED) called id=%u, addval=%08X, type=%08X", id, addval, type); | 550 | NGLOG_WARNING(Service_VI, "(STUBBED) called id={}, addval={:08X}, type={:08X}", id, addval, |
| 551 | type); | ||
| 551 | IPC::ResponseBuilder rb{ctx, 2}; | 552 | IPC::ResponseBuilder rb{ctx, 2}; |
| 552 | rb.Push(RESULT_SUCCESS); | 553 | rb.Push(RESULT_SUCCESS); |
| 553 | } | 554 | } |
| @@ -561,7 +562,7 @@ private: | |||
| 561 | 562 | ||
| 562 | // TODO(Subv): Find out what this actually is. | 563 | // TODO(Subv): Find out what this actually is. |
| 563 | 564 | ||
| 564 | LOG_WARNING(Service_VI, "(STUBBED) called id=%u, unknown=%08X", id, unknown); | 565 | NGLOG_WARNING(Service_VI, "(STUBBED) called id={}, unknown={:08X}", id, unknown); |
| 565 | IPC::ResponseBuilder rb{ctx, 2, 1}; | 566 | IPC::ResponseBuilder rb{ctx, 2, 1}; |
| 566 | rb.Push(RESULT_SUCCESS); | 567 | rb.Push(RESULT_SUCCESS); |
| 567 | rb.PushCopyObjects(buffer_queue->GetNativeHandle()); | 568 | rb.PushCopyObjects(buffer_queue->GetNativeHandle()); |
| @@ -624,7 +625,7 @@ public: | |||
| 624 | 625 | ||
| 625 | private: | 626 | private: |
| 626 | void SetLayerZ(Kernel::HLERequestContext& ctx) { | 627 | void SetLayerZ(Kernel::HLERequestContext& ctx) { |
| 627 | LOG_WARNING(Service_VI, "(STUBBED) called"); | 628 | NGLOG_WARNING(Service_VI, "(STUBBED) called"); |
| 628 | IPC::RequestParser rp{ctx}; | 629 | IPC::RequestParser rp{ctx}; |
| 629 | u64 layer_id = rp.Pop<u64>(); | 630 | u64 layer_id = rp.Pop<u64>(); |
| 630 | u64 z_value = rp.Pop<u64>(); | 631 | u64 z_value = rp.Pop<u64>(); |
| @@ -639,8 +640,8 @@ private: | |||
| 639 | bool visibility = rp.Pop<bool>(); | 640 | bool visibility = rp.Pop<bool>(); |
| 640 | IPC::ResponseBuilder rb = rp.MakeBuilder(2, 0, 0); | 641 | IPC::ResponseBuilder rb = rp.MakeBuilder(2, 0, 0); |
| 641 | rb.Push(RESULT_SUCCESS); | 642 | rb.Push(RESULT_SUCCESS); |
| 642 | LOG_WARNING(Service_VI, "(STUBBED) called, layer_id=0x%x, visibility=%u", layer_id, | 643 | NGLOG_WARNING(Service_VI, "(STUBBED) called, layer_id={:#010X}, visibility={}", layer_id, |
| 643 | visibility); | 644 | visibility); |
| 644 | } | 645 | } |
| 645 | }; | 646 | }; |
| 646 | 647 | ||
| @@ -722,7 +723,7 @@ public: | |||
| 722 | 723 | ||
| 723 | private: | 724 | private: |
| 724 | void CloseDisplay(Kernel::HLERequestContext& ctx) { | 725 | void CloseDisplay(Kernel::HLERequestContext& ctx) { |
| 725 | LOG_WARNING(Service_VI, "(STUBBED) called"); | 726 | NGLOG_WARNING(Service_VI, "(STUBBED) called"); |
| 726 | IPC::RequestParser rp{ctx}; | 727 | IPC::RequestParser rp{ctx}; |
| 727 | u64 display = rp.Pop<u64>(); | 728 | u64 display = rp.Pop<u64>(); |
| 728 | 729 | ||
| @@ -731,7 +732,7 @@ private: | |||
| 731 | } | 732 | } |
| 732 | 733 | ||
| 733 | void CreateManagedLayer(Kernel::HLERequestContext& ctx) { | 734 | void CreateManagedLayer(Kernel::HLERequestContext& ctx) { |
| 734 | LOG_WARNING(Service_VI, "(STUBBED) called"); | 735 | NGLOG_WARNING(Service_VI, "(STUBBED) called"); |
| 735 | IPC::RequestParser rp{ctx}; | 736 | IPC::RequestParser rp{ctx}; |
| 736 | u32 unknown = rp.Pop<u32>(); | 737 | u32 unknown = rp.Pop<u32>(); |
| 737 | rp.Skip(1, false); | 738 | rp.Skip(1, false); |
| @@ -746,7 +747,7 @@ private: | |||
| 746 | } | 747 | } |
| 747 | 748 | ||
| 748 | void AddToLayerStack(Kernel::HLERequestContext& ctx) { | 749 | void AddToLayerStack(Kernel::HLERequestContext& ctx) { |
| 749 | LOG_WARNING(Service_VI, "(STUBBED) called"); | 750 | NGLOG_WARNING(Service_VI, "(STUBBED) called"); |
| 750 | IPC::RequestParser rp{ctx}; | 751 | IPC::RequestParser rp{ctx}; |
| 751 | u32 stack = rp.Pop<u32>(); | 752 | u32 stack = rp.Pop<u32>(); |
| 752 | u64 layer_id = rp.Pop<u64>(); | 753 | u64 layer_id = rp.Pop<u64>(); |
| @@ -761,8 +762,8 @@ private: | |||
| 761 | bool visibility = rp.Pop<bool>(); | 762 | bool visibility = rp.Pop<bool>(); |
| 762 | IPC::ResponseBuilder rb = rp.MakeBuilder(2, 0, 0); | 763 | IPC::ResponseBuilder rb = rp.MakeBuilder(2, 0, 0); |
| 763 | rb.Push(RESULT_SUCCESS); | 764 | rb.Push(RESULT_SUCCESS); |
| 764 | LOG_WARNING(Service_VI, "(STUBBED) called, layer_id=0x%x, visibility=%u", layer_id, | 765 | NGLOG_WARNING(Service_VI, "(STUBBED) called, layer_id={:#X}, visibility={}", layer_id, |
| 765 | visibility); | 766 | visibility); |
| 766 | } | 767 | } |
| 767 | 768 | ||
| 768 | std::shared_ptr<NVFlinger::NVFlinger> nv_flinger; | 769 | std::shared_ptr<NVFlinger::NVFlinger> nv_flinger; |
| @@ -775,7 +776,7 @@ public: | |||
| 775 | 776 | ||
| 776 | private: | 777 | private: |
| 777 | void GetRelayService(Kernel::HLERequestContext& ctx) { | 778 | void GetRelayService(Kernel::HLERequestContext& ctx) { |
| 778 | LOG_WARNING(Service_VI, "(STUBBED) called"); | 779 | NGLOG_WARNING(Service_VI, "(STUBBED) called"); |
| 779 | 780 | ||
| 780 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | 781 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; |
| 781 | rb.Push(RESULT_SUCCESS); | 782 | rb.Push(RESULT_SUCCESS); |
| @@ -783,7 +784,7 @@ private: | |||
| 783 | } | 784 | } |
| 784 | 785 | ||
| 785 | void GetSystemDisplayService(Kernel::HLERequestContext& ctx) { | 786 | void GetSystemDisplayService(Kernel::HLERequestContext& ctx) { |
| 786 | LOG_WARNING(Service_VI, "(STUBBED) called"); | 787 | NGLOG_WARNING(Service_VI, "(STUBBED) called"); |
| 787 | 788 | ||
| 788 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | 789 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; |
| 789 | rb.Push(RESULT_SUCCESS); | 790 | rb.Push(RESULT_SUCCESS); |
| @@ -791,7 +792,7 @@ private: | |||
| 791 | } | 792 | } |
| 792 | 793 | ||
| 793 | void GetManagerDisplayService(Kernel::HLERequestContext& ctx) { | 794 | void GetManagerDisplayService(Kernel::HLERequestContext& ctx) { |
| 794 | LOG_WARNING(Service_VI, "(STUBBED) called"); | 795 | NGLOG_WARNING(Service_VI, "(STUBBED) called"); |
| 795 | 796 | ||
| 796 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | 797 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; |
| 797 | rb.Push(RESULT_SUCCESS); | 798 | rb.Push(RESULT_SUCCESS); |
| @@ -799,7 +800,7 @@ private: | |||
| 799 | } | 800 | } |
| 800 | 801 | ||
| 801 | void GetIndirectDisplayTransactionService(Kernel::HLERequestContext& ctx) { | 802 | void GetIndirectDisplayTransactionService(Kernel::HLERequestContext& ctx) { |
| 802 | LOG_WARNING(Service_VI, "(STUBBED) called"); | 803 | NGLOG_WARNING(Service_VI, "(STUBBED) called"); |
| 803 | 804 | ||
| 804 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | 805 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; |
| 805 | rb.Push(RESULT_SUCCESS); | 806 | rb.Push(RESULT_SUCCESS); |
| @@ -807,7 +808,7 @@ private: | |||
| 807 | } | 808 | } |
| 808 | 809 | ||
| 809 | void OpenDisplay(Kernel::HLERequestContext& ctx) { | 810 | void OpenDisplay(Kernel::HLERequestContext& ctx) { |
| 810 | LOG_WARNING(Service_VI, "(STUBBED) called"); | 811 | NGLOG_WARNING(Service_VI, "(STUBBED) called"); |
| 811 | IPC::RequestParser rp{ctx}; | 812 | IPC::RequestParser rp{ctx}; |
| 812 | auto name_buf = rp.PopRaw<std::array<u8, 0x40>>(); | 813 | auto name_buf = rp.PopRaw<std::array<u8, 0x40>>(); |
| 813 | auto end = std::find(name_buf.begin(), name_buf.end(), '\0'); | 814 | auto end = std::find(name_buf.begin(), name_buf.end(), '\0'); |
| @@ -822,7 +823,7 @@ private: | |||
| 822 | } | 823 | } |
| 823 | 824 | ||
| 824 | void CloseDisplay(Kernel::HLERequestContext& ctx) { | 825 | void CloseDisplay(Kernel::HLERequestContext& ctx) { |
| 825 | LOG_WARNING(Service_VI, "(STUBBED) called"); | 826 | NGLOG_WARNING(Service_VI, "(STUBBED) called"); |
| 826 | IPC::RequestParser rp{ctx}; | 827 | IPC::RequestParser rp{ctx}; |
| 827 | u64 display_id = rp.Pop<u64>(); | 828 | u64 display_id = rp.Pop<u64>(); |
| 828 | 829 | ||
| @@ -831,7 +832,7 @@ private: | |||
| 831 | } | 832 | } |
| 832 | 833 | ||
| 833 | void GetDisplayResolution(Kernel::HLERequestContext& ctx) { | 834 | void GetDisplayResolution(Kernel::HLERequestContext& ctx) { |
| 834 | LOG_WARNING(Service_VI, "(STUBBED) called"); | 835 | NGLOG_WARNING(Service_VI, "(STUBBED) called"); |
| 835 | IPC::RequestParser rp{ctx}; | 836 | IPC::RequestParser rp{ctx}; |
| 836 | u64 display_id = rp.Pop<u64>(); | 837 | u64 display_id = rp.Pop<u64>(); |
| 837 | 838 | ||
| @@ -848,7 +849,7 @@ private: | |||
| 848 | } | 849 | } |
| 849 | 850 | ||
| 850 | void SetLayerScalingMode(Kernel::HLERequestContext& ctx) { | 851 | void SetLayerScalingMode(Kernel::HLERequestContext& ctx) { |
| 851 | LOG_WARNING(Service_VI, "(STUBBED) called"); | 852 | NGLOG_WARNING(Service_VI, "(STUBBED) called"); |
| 852 | IPC::RequestParser rp{ctx}; | 853 | IPC::RequestParser rp{ctx}; |
| 853 | u32 scaling_mode = rp.Pop<u32>(); | 854 | u32 scaling_mode = rp.Pop<u32>(); |
| 854 | u64 unknown = rp.Pop<u64>(); | 855 | u64 unknown = rp.Pop<u64>(); |
| @@ -864,11 +865,11 @@ private: | |||
| 864 | IPC::ResponseBuilder rb = rp.MakeBuilder(4, 0, 0); | 865 | IPC::ResponseBuilder rb = rp.MakeBuilder(4, 0, 0); |
| 865 | rb.Push(RESULT_SUCCESS); | 866 | rb.Push(RESULT_SUCCESS); |
| 866 | rb.Push<u64>(1); | 867 | rb.Push<u64>(1); |
| 867 | LOG_WARNING(Service_VI, "(STUBBED) called"); | 868 | NGLOG_WARNING(Service_VI, "(STUBBED) called"); |
| 868 | } | 869 | } |
| 869 | 870 | ||
| 870 | void OpenLayer(Kernel::HLERequestContext& ctx) { | 871 | void OpenLayer(Kernel::HLERequestContext& ctx) { |
| 871 | LOG_DEBUG(Service_VI, "called"); | 872 | NGLOG_DEBUG(Service_VI, "called"); |
| 872 | IPC::RequestParser rp{ctx}; | 873 | IPC::RequestParser rp{ctx}; |
| 873 | auto name_buf = rp.PopRaw<std::array<u8, 0x40>>(); | 874 | auto name_buf = rp.PopRaw<std::array<u8, 0x40>>(); |
| 874 | auto end = std::find(name_buf.begin(), name_buf.end(), '\0'); | 875 | auto end = std::find(name_buf.begin(), name_buf.end(), '\0'); |
| @@ -888,7 +889,7 @@ private: | |||
| 888 | } | 889 | } |
| 889 | 890 | ||
| 890 | void CreateStrayLayer(Kernel::HLERequestContext& ctx) { | 891 | void CreateStrayLayer(Kernel::HLERequestContext& ctx) { |
| 891 | LOG_DEBUG(Service_VI, "called"); | 892 | NGLOG_DEBUG(Service_VI, "called"); |
| 892 | 893 | ||
| 893 | IPC::RequestParser rp{ctx}; | 894 | IPC::RequestParser rp{ctx}; |
| 894 | u32 flags = rp.Pop<u32>(); | 895 | u32 flags = rp.Pop<u32>(); |
| @@ -908,7 +909,7 @@ private: | |||
| 908 | } | 909 | } |
| 909 | 910 | ||
| 910 | void DestroyStrayLayer(Kernel::HLERequestContext& ctx) { | 911 | void DestroyStrayLayer(Kernel::HLERequestContext& ctx) { |
| 911 | LOG_WARNING(Service_VI, "(STUBBED) called"); | 912 | NGLOG_WARNING(Service_VI, "(STUBBED) called"); |
| 912 | 913 | ||
| 913 | IPC::RequestParser rp{ctx}; | 914 | IPC::RequestParser rp{ctx}; |
| 914 | u64 layer_id = rp.Pop<u64>(); | 915 | u64 layer_id = rp.Pop<u64>(); |
| @@ -918,7 +919,7 @@ private: | |||
| 918 | } | 919 | } |
| 919 | 920 | ||
| 920 | void GetDisplayVsyncEvent(Kernel::HLERequestContext& ctx) { | 921 | void GetDisplayVsyncEvent(Kernel::HLERequestContext& ctx) { |
| 921 | LOG_WARNING(Service_VI, "(STUBBED) called"); | 922 | NGLOG_WARNING(Service_VI, "(STUBBED) called"); |
| 922 | IPC::RequestParser rp{ctx}; | 923 | IPC::RequestParser rp{ctx}; |
| 923 | u64 display_id = rp.Pop<u64>(); | 924 | u64 display_id = rp.Pop<u64>(); |
| 924 | 925 | ||
| @@ -967,7 +968,7 @@ Module::Interface::Interface(std::shared_ptr<Module> module, const char* name, | |||
| 967 | : ServiceFramework(name), module(std::move(module)), nv_flinger(std::move(nv_flinger)) {} | 968 | : ServiceFramework(name), module(std::move(module)), nv_flinger(std::move(nv_flinger)) {} |
| 968 | 969 | ||
| 969 | void Module::Interface::GetDisplayService(Kernel::HLERequestContext& ctx) { | 970 | void Module::Interface::GetDisplayService(Kernel::HLERequestContext& ctx) { |
| 970 | LOG_WARNING(Service_VI, "(STUBBED) called"); | 971 | NGLOG_WARNING(Service_VI, "(STUBBED) called"); |
| 971 | 972 | ||
| 972 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | 973 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; |
| 973 | rb.Push(RESULT_SUCCESS); | 974 | rb.Push(RESULT_SUCCESS); |
diff --git a/src/core/hw/hw.cpp b/src/core/hw/hw.cpp index 0db604c76..f8a40390a 100644 --- a/src/core/hw/hw.cpp +++ b/src/core/hw/hw.cpp | |||
| @@ -33,7 +33,8 @@ inline void Read(T& var, const u32 addr) { | |||
| 33 | LCD::Read(var, addr); | 33 | LCD::Read(var, addr); |
| 34 | break; | 34 | break; |
| 35 | default: | 35 | default: |
| 36 | LOG_ERROR(HW_Memory, "unknown Read%lu @ 0x%08X", sizeof(var) * 8, addr); | 36 | NGLOG_ERROR(HW_Memory, "Unknown Read{} @ {:#010X}", sizeof(var) * 8, addr); |
| 37 | break; | ||
| 37 | } | 38 | } |
| 38 | } | 39 | } |
| 39 | 40 | ||
| @@ -61,7 +62,8 @@ inline void Write(u32 addr, const T data) { | |||
| 61 | LCD::Write(addr, data); | 62 | LCD::Write(addr, data); |
| 62 | break; | 63 | break; |
| 63 | default: | 64 | default: |
| 64 | LOG_ERROR(HW_Memory, "unknown Write%lu 0x%08X @ 0x%08X", sizeof(data) * 8, (u32)data, addr); | 65 | NGLOG_ERROR(HW_Memory, "Unknown Write{} {:#010X} @ {:#010X}", sizeof(data) * 8, data, addr); |
| 66 | break; | ||
| 65 | } | 67 | } |
| 66 | } | 68 | } |
| 67 | 69 | ||
| @@ -83,12 +85,12 @@ void Update() {} | |||
| 83 | /// Initialize hardware | 85 | /// Initialize hardware |
| 84 | void Init() { | 86 | void Init() { |
| 85 | LCD::Init(); | 87 | LCD::Init(); |
| 86 | LOG_DEBUG(HW, "initialized OK"); | 88 | NGLOG_DEBUG(HW, "Initialized OK"); |
| 87 | } | 89 | } |
| 88 | 90 | ||
| 89 | /// Shutdown hardware | 91 | /// Shutdown hardware |
| 90 | void Shutdown() { | 92 | void Shutdown() { |
| 91 | LCD::Shutdown(); | 93 | LCD::Shutdown(); |
| 92 | LOG_DEBUG(HW, "shutdown OK"); | 94 | NGLOG_DEBUG(HW, "Shutdown OK"); |
| 93 | } | 95 | } |
| 94 | } // namespace HW | 96 | } // namespace HW |
diff --git a/src/core/hw/lcd.cpp b/src/core/hw/lcd.cpp index 690079b65..7d0046bf3 100644 --- a/src/core/hw/lcd.cpp +++ b/src/core/hw/lcd.cpp | |||
| @@ -20,7 +20,7 @@ inline void Read(T& var, const u32 raw_addr) { | |||
| 20 | 20 | ||
| 21 | // Reads other than u32 are untested, so I'd rather have them abort than silently fail | 21 | // Reads other than u32 are untested, so I'd rather have them abort than silently fail |
| 22 | if (index >= 0x400 || !std::is_same<T, u32>::value) { | 22 | if (index >= 0x400 || !std::is_same<T, u32>::value) { |
| 23 | LOG_ERROR(HW_LCD, "unknown Read%lu @ 0x%08X", sizeof(var) * 8, addr); | 23 | NGLOG_ERROR(HW_LCD, "Unknown Read{} @ {:#010X}", sizeof(var) * 8, addr); |
| 24 | return; | 24 | return; |
| 25 | } | 25 | } |
| 26 | 26 | ||
| @@ -34,7 +34,7 @@ inline void Write(u32 addr, const T data) { | |||
| 34 | 34 | ||
| 35 | // Writes other than u32 are untested, so I'd rather have them abort than silently fail | 35 | // Writes other than u32 are untested, so I'd rather have them abort than silently fail |
| 36 | if (index >= 0x400 || !std::is_same<T, u32>::value) { | 36 | if (index >= 0x400 || !std::is_same<T, u32>::value) { |
| 37 | LOG_ERROR(HW_LCD, "unknown Write%lu 0x%08X @ 0x%08X", sizeof(data) * 8, (u32)data, addr); | 37 | NGLOG_ERROR(HW_LCD, "Unknown Write{} {:#010X} @ {:#010X}", sizeof(data) * 8, data, addr); |
| 38 | return; | 38 | return; |
| 39 | } | 39 | } |
| 40 | 40 | ||
| @@ -56,12 +56,12 @@ template void Write<u8>(u32 addr, const u8 data); | |||
| 56 | /// Initialize hardware | 56 | /// Initialize hardware |
| 57 | void Init() { | 57 | void Init() { |
| 58 | memset(&g_regs, 0, sizeof(g_regs)); | 58 | memset(&g_regs, 0, sizeof(g_regs)); |
| 59 | LOG_DEBUG(HW_LCD, "initialized OK"); | 59 | NGLOG_DEBUG(HW_LCD, "Initialized OK"); |
| 60 | } | 60 | } |
| 61 | 61 | ||
| 62 | /// Shutdown hardware | 62 | /// Shutdown hardware |
| 63 | void Shutdown() { | 63 | void Shutdown() { |
| 64 | LOG_DEBUG(HW_LCD, "shutdown OK"); | 64 | NGLOG_DEBUG(HW_LCD, "Shutdown OK"); |
| 65 | } | 65 | } |
| 66 | 66 | ||
| 67 | } // namespace LCD | 67 | } // namespace LCD |
diff --git a/src/core/loader/deconstructed_rom_directory.cpp b/src/core/loader/deconstructed_rom_directory.cpp index 8696c28bd..40a81025f 100644 --- a/src/core/loader/deconstructed_rom_directory.cpp +++ b/src/core/loader/deconstructed_rom_directory.cpp | |||
| @@ -132,7 +132,7 @@ ResultStatus AppLoader_DeconstructedRomDirectory::Load( | |||
| 132 | const VAddr load_addr = next_load_addr; | 132 | const VAddr load_addr = next_load_addr; |
| 133 | next_load_addr = AppLoader_NSO::LoadModule(path, load_addr); | 133 | next_load_addr = AppLoader_NSO::LoadModule(path, load_addr); |
| 134 | if (next_load_addr) { | 134 | if (next_load_addr) { |
| 135 | LOG_DEBUG(Loader, "loaded module %s @ 0x%" PRIx64, module, load_addr); | 135 | NGLOG_DEBUG(Loader, "loaded module {} @ {:#X}", module, load_addr); |
| 136 | } else { | 136 | } else { |
| 137 | next_load_addr = load_addr; | 137 | next_load_addr = load_addr; |
| 138 | } | 138 | } |
| @@ -163,7 +163,7 @@ ResultStatus AppLoader_DeconstructedRomDirectory::ReadRomFS( | |||
| 163 | std::shared_ptr<FileUtil::IOFile>& romfs_file, u64& offset, u64& size) { | 163 | std::shared_ptr<FileUtil::IOFile>& romfs_file, u64& offset, u64& size) { |
| 164 | 164 | ||
| 165 | if (filepath_romfs.empty()) { | 165 | if (filepath_romfs.empty()) { |
| 166 | LOG_DEBUG(Loader, "No RomFS available"); | 166 | NGLOG_DEBUG(Loader, "No RomFS available"); |
| 167 | return ResultStatus::ErrorNotUsed; | 167 | return ResultStatus::ErrorNotUsed; |
| 168 | } | 168 | } |
| 169 | 169 | ||
| @@ -176,8 +176,8 @@ ResultStatus AppLoader_DeconstructedRomDirectory::ReadRomFS( | |||
| 176 | offset = 0; | 176 | offset = 0; |
| 177 | size = romfs_file->GetSize(); | 177 | size = romfs_file->GetSize(); |
| 178 | 178 | ||
| 179 | LOG_DEBUG(Loader, "RomFS offset: 0x%016" PRIX64, offset); | 179 | NGLOG_DEBUG(Loader, "RomFS offset: {:#018X}", offset); |
| 180 | LOG_DEBUG(Loader, "RomFS size: 0x%016" PRIX64, size); | 180 | NGLOG_DEBUG(Loader, "RomFS size: {:#018X}", size); |
| 181 | 181 | ||
| 182 | // Reset read pointer | 182 | // Reset read pointer |
| 183 | file.Seek(0, SEEK_SET); | 183 | file.Seek(0, SEEK_SET); |
diff --git a/src/core/loader/elf.cpp b/src/core/loader/elf.cpp index e9f462196..e42d3a870 100644 --- a/src/core/loader/elf.cpp +++ b/src/core/loader/elf.cpp | |||
| @@ -273,18 +273,18 @@ const char* ElfReader::GetSectionName(int section) const { | |||
| 273 | } | 273 | } |
| 274 | 274 | ||
| 275 | SharedPtr<CodeSet> ElfReader::LoadInto(u32 vaddr) { | 275 | SharedPtr<CodeSet> ElfReader::LoadInto(u32 vaddr) { |
| 276 | LOG_DEBUG(Loader, "String section: %i", header->e_shstrndx); | 276 | NGLOG_DEBUG(Loader, "String section: {}", header->e_shstrndx); |
| 277 | 277 | ||
| 278 | // Should we relocate? | 278 | // Should we relocate? |
| 279 | relocate = (header->e_type != ET_EXEC); | 279 | relocate = (header->e_type != ET_EXEC); |
| 280 | 280 | ||
| 281 | if (relocate) { | 281 | if (relocate) { |
| 282 | LOG_DEBUG(Loader, "Relocatable module"); | 282 | NGLOG_DEBUG(Loader, "Relocatable module"); |
| 283 | entryPoint += vaddr; | 283 | entryPoint += vaddr; |
| 284 | } else { | 284 | } else { |
| 285 | LOG_DEBUG(Loader, "Prerelocated executable"); | 285 | NGLOG_DEBUG(Loader, "Prerelocated executable"); |
| 286 | } | 286 | } |
| 287 | LOG_DEBUG(Loader, "%i segments:", header->e_phnum); | 287 | NGLOG_DEBUG(Loader, "{} segments:", header->e_phnum); |
| 288 | 288 | ||
| 289 | // First pass : Get the bits into RAM | 289 | // First pass : Get the bits into RAM |
| 290 | u32 base_addr = relocate ? vaddr : 0; | 290 | u32 base_addr = relocate ? vaddr : 0; |
| @@ -304,8 +304,8 @@ SharedPtr<CodeSet> ElfReader::LoadInto(u32 vaddr) { | |||
| 304 | 304 | ||
| 305 | for (unsigned int i = 0; i < header->e_phnum; ++i) { | 305 | for (unsigned int i = 0; i < header->e_phnum; ++i) { |
| 306 | Elf32_Phdr* p = &segments[i]; | 306 | Elf32_Phdr* p = &segments[i]; |
| 307 | LOG_DEBUG(Loader, "Type: %i Vaddr: %08X Filesz: %8X Memsz: %8X ", p->p_type, p->p_vaddr, | 307 | NGLOG_DEBUG(Loader, "Type: {} Vaddr: {:08X} Filesz: {:08X} Memsz: {:08X} ", p->p_type, |
| 308 | p->p_filesz, p->p_memsz); | 308 | p->p_vaddr, p->p_filesz, p->p_memsz); |
| 309 | 309 | ||
| 310 | if (p->p_type == PT_LOAD) { | 310 | if (p->p_type == PT_LOAD) { |
| 311 | CodeSet::Segment* codeset_segment; | 311 | CodeSet::Segment* codeset_segment; |
| @@ -317,16 +317,16 @@ SharedPtr<CodeSet> ElfReader::LoadInto(u32 vaddr) { | |||
| 317 | } else if (permission_flags == (PF_R | PF_W)) { | 317 | } else if (permission_flags == (PF_R | PF_W)) { |
| 318 | codeset_segment = &codeset->data; | 318 | codeset_segment = &codeset->data; |
| 319 | } else { | 319 | } else { |
| 320 | LOG_ERROR(Loader, "Unexpected ELF PT_LOAD segment id %u with flags %X", i, | 320 | NGLOG_ERROR(Loader, "Unexpected ELF PT_LOAD segment id {} with flags {:X}", i, |
| 321 | p->p_flags); | 321 | p->p_flags); |
| 322 | continue; | 322 | continue; |
| 323 | } | 323 | } |
| 324 | 324 | ||
| 325 | if (codeset_segment->size != 0) { | 325 | if (codeset_segment->size != 0) { |
| 326 | LOG_ERROR(Loader, | 326 | NGLOG_ERROR(Loader, |
| 327 | "ELF has more than one segment of the same type. Skipping extra " | 327 | "ELF has more than one segment of the same type. Skipping extra " |
| 328 | "segment (id %i)", | 328 | "segment (id {})", |
| 329 | i); | 329 | i); |
| 330 | continue; | 330 | continue; |
| 331 | } | 331 | } |
| 332 | 332 | ||
| @@ -345,7 +345,7 @@ SharedPtr<CodeSet> ElfReader::LoadInto(u32 vaddr) { | |||
| 345 | codeset->entrypoint = base_addr + header->e_entry; | 345 | codeset->entrypoint = base_addr + header->e_entry; |
| 346 | codeset->memory = std::make_shared<std::vector<u8>>(std::move(program_image)); | 346 | codeset->memory = std::make_shared<std::vector<u8>>(std::move(program_image)); |
| 347 | 347 | ||
| 348 | LOG_DEBUG(Loader, "Done loading."); | 348 | NGLOG_DEBUG(Loader, "Done loading."); |
| 349 | 349 | ||
| 350 | return codeset; | 350 | return codeset; |
| 351 | } | 351 | } |
diff --git a/src/core/loader/linker.cpp b/src/core/loader/linker.cpp index 69198e3e3..c7be5f265 100644 --- a/src/core/loader/linker.cpp +++ b/src/core/loader/linker.cpp | |||
| @@ -84,7 +84,7 @@ void Linker::WriteRelocations(std::vector<u8>& program_image, const std::vector< | |||
| 84 | } | 84 | } |
| 85 | break; | 85 | break; |
| 86 | default: | 86 | default: |
| 87 | LOG_CRITICAL(Loader, "Unknown relocation type: %d", static_cast<int>(rela.type)); | 87 | NGLOG_CRITICAL(Loader, "Unknown relocation type: {}", static_cast<int>(rela.type)); |
| 88 | break; | 88 | break; |
| 89 | } | 89 | } |
| 90 | } | 90 | } |
| @@ -141,7 +141,7 @@ void Linker::ResolveImports() { | |||
| 141 | if (search != exports.end()) { | 141 | if (search != exports.end()) { |
| 142 | Memory::Write64(import.second.ea, search->second + import.second.addend); | 142 | Memory::Write64(import.second.ea, search->second + import.second.addend); |
| 143 | } else { | 143 | } else { |
| 144 | LOG_ERROR(Loader, "Unresolved import: %s", import.first.c_str()); | 144 | NGLOG_ERROR(Loader, "Unresolved import: {}", import.first); |
| 145 | } | 145 | } |
| 146 | } | 146 | } |
| 147 | } | 147 | } |
diff --git a/src/core/loader/loader.cpp b/src/core/loader/loader.cpp index 2ec08506d..6a4fd38cb 100644 --- a/src/core/loader/loader.cpp +++ b/src/core/loader/loader.cpp | |||
| @@ -41,7 +41,7 @@ FileType IdentifyFile(FileUtil::IOFile& file, const std::string& filepath) { | |||
| 41 | FileType IdentifyFile(const std::string& file_name) { | 41 | FileType IdentifyFile(const std::string& file_name) { |
| 42 | FileUtil::IOFile file(file_name, "rb"); | 42 | FileUtil::IOFile file(file_name, "rb"); |
| 43 | if (!file.IsOpen()) { | 43 | if (!file.IsOpen()) { |
| 44 | LOG_ERROR(Loader, "Failed to load file %s", file_name.c_str()); | 44 | NGLOG_ERROR(Loader, "Failed to load file {}", file_name); |
| 45 | return FileType::Unknown; | 45 | return FileType::Unknown; |
| 46 | } | 46 | } |
| 47 | 47 | ||
| @@ -116,7 +116,7 @@ static std::unique_ptr<AppLoader> GetFileLoader(FileUtil::IOFile&& file, FileTyp | |||
| 116 | std::unique_ptr<AppLoader> GetLoader(const std::string& filename) { | 116 | std::unique_ptr<AppLoader> GetLoader(const std::string& filename) { |
| 117 | FileUtil::IOFile file(filename, "rb"); | 117 | FileUtil::IOFile file(filename, "rb"); |
| 118 | if (!file.IsOpen()) { | 118 | if (!file.IsOpen()) { |
| 119 | LOG_ERROR(Loader, "Failed to load file %s", filename.c_str()); | 119 | NGLOG_ERROR(Loader, "Failed to load file {}", filename); |
| 120 | return nullptr; | 120 | return nullptr; |
| 121 | } | 121 | } |
| 122 | 122 | ||
| @@ -127,12 +127,12 @@ std::unique_ptr<AppLoader> GetLoader(const std::string& filename) { | |||
| 127 | FileType filename_type = GuessFromExtension(filename_extension); | 127 | FileType filename_type = GuessFromExtension(filename_extension); |
| 128 | 128 | ||
| 129 | if (type != filename_type) { | 129 | if (type != filename_type) { |
| 130 | LOG_WARNING(Loader, "File %s has a different type than its extension.", filename.c_str()); | 130 | NGLOG_WARNING(Loader, "File {} has a different type than its extension.", filename); |
| 131 | if (FileType::Unknown == type) | 131 | if (FileType::Unknown == type) |
| 132 | type = filename_type; | 132 | type = filename_type; |
| 133 | } | 133 | } |
| 134 | 134 | ||
| 135 | LOG_DEBUG(Loader, "Loading file %s as %s...", filename.c_str(), GetFileTypeString(type)); | 135 | NGLOG_DEBUG(Loader, "Loading file {} as {}...", filename, GetFileTypeString(type)); |
| 136 | 136 | ||
| 137 | return GetFileLoader(std::move(file), type, filename_filename, filename); | 137 | return GetFileLoader(std::move(file), type, filename_filename, filename); |
| 138 | } | 138 | } |
diff --git a/src/core/loader/nro.cpp b/src/core/loader/nro.cpp index b5133e4d6..3853cfa1a 100644 --- a/src/core/loader/nro.cpp +++ b/src/core/loader/nro.cpp | |||
| @@ -137,7 +137,7 @@ ResultStatus AppLoader_NRO::Load(Kernel::SharedPtr<Kernel::Process>& process) { | |||
| 137 | process->address_mappings = default_address_mappings; | 137 | process->address_mappings = default_address_mappings; |
| 138 | process->resource_limit = | 138 | process->resource_limit = |
| 139 | Kernel::ResourceLimit::GetForCategory(Kernel::ResourceLimitCategory::APPLICATION); | 139 | Kernel::ResourceLimit::GetForCategory(Kernel::ResourceLimitCategory::APPLICATION); |
| 140 | process->Run(base_addr, 48, Memory::DEFAULT_STACK_SIZE); | 140 | process->Run(base_addr, THREADPRIO_DEFAULT, Memory::DEFAULT_STACK_SIZE); |
| 141 | 141 | ||
| 142 | is_loaded = true; | 142 | is_loaded = true; |
| 143 | return ResultStatus::Success; | 143 | return ResultStatus::Success; |
diff --git a/src/core/loader/nso.cpp b/src/core/loader/nso.cpp index 3bc10ed0d..1842bae20 100644 --- a/src/core/loader/nso.cpp +++ b/src/core/loader/nso.cpp | |||
| @@ -73,7 +73,7 @@ static std::vector<u8> ReadSegment(FileUtil::IOFile& file, const NsoSegmentHeade | |||
| 73 | 73 | ||
| 74 | file.Seek(header.offset, SEEK_SET); | 74 | file.Seek(header.offset, SEEK_SET); |
| 75 | if (compressed_size != file.ReadBytes(compressed_data.data(), compressed_size)) { | 75 | if (compressed_size != file.ReadBytes(compressed_data.data(), compressed_size)) { |
| 76 | LOG_CRITICAL(Loader, "Failed to read %d NSO LZ4 compressed bytes", compressed_size); | 76 | NGLOG_CRITICAL(Loader, "Failed to read {} NSO LZ4 compressed bytes", compressed_size); |
| 77 | return {}; | 77 | return {}; |
| 78 | } | 78 | } |
| 79 | 79 | ||
| @@ -158,14 +158,13 @@ ResultStatus AppLoader_NSO::Load(Kernel::SharedPtr<Kernel::Process>& process) { | |||
| 158 | 158 | ||
| 159 | // Load module | 159 | // Load module |
| 160 | LoadModule(filepath, Memory::PROCESS_IMAGE_VADDR); | 160 | LoadModule(filepath, Memory::PROCESS_IMAGE_VADDR); |
| 161 | LOG_DEBUG(Loader, "loaded module %s @ 0x%" PRIx64, filepath.c_str(), | 161 | NGLOG_DEBUG(Loader, "loaded module {} @ {:#X}", filepath, Memory::PROCESS_IMAGE_VADDR); |
| 162 | Memory::PROCESS_IMAGE_VADDR); | ||
| 163 | 162 | ||
| 164 | process->svc_access_mask.set(); | 163 | process->svc_access_mask.set(); |
| 165 | process->address_mappings = default_address_mappings; | 164 | process->address_mappings = default_address_mappings; |
| 166 | process->resource_limit = | 165 | process->resource_limit = |
| 167 | Kernel::ResourceLimit::GetForCategory(Kernel::ResourceLimitCategory::APPLICATION); | 166 | Kernel::ResourceLimit::GetForCategory(Kernel::ResourceLimitCategory::APPLICATION); |
| 168 | process->Run(Memory::PROCESS_IMAGE_VADDR, 48, Memory::DEFAULT_STACK_SIZE); | 167 | process->Run(Memory::PROCESS_IMAGE_VADDR, THREADPRIO_DEFAULT, Memory::DEFAULT_STACK_SIZE); |
| 169 | 168 | ||
| 170 | is_loaded = true; | 169 | is_loaded = true; |
| 171 | return ResultStatus::Success; | 170 | return ResultStatus::Success; |
diff --git a/src/core/memory.cpp b/src/core/memory.cpp index 291bf066f..2afa0916d 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp | |||
| @@ -39,8 +39,8 @@ PageTable* GetCurrentPageTable() { | |||
| 39 | } | 39 | } |
| 40 | 40 | ||
| 41 | static void MapPages(PageTable& page_table, VAddr base, u64 size, u8* memory, PageType type) { | 41 | static void MapPages(PageTable& page_table, VAddr base, u64 size, u8* memory, PageType type) { |
| 42 | LOG_DEBUG(HW_Memory, "Mapping %p onto %016" PRIX64 "-%016" PRIX64, memory, base * PAGE_SIZE, | 42 | NGLOG_DEBUG(HW_Memory, "Mapping {} onto {:016X}-{:016X}", fmt::ptr(memory), base * PAGE_SIZE, |
| 43 | (base + size) * PAGE_SIZE); | 43 | (base + size) * PAGE_SIZE); |
| 44 | 44 | ||
| 45 | RasterizerFlushVirtualRegion(base << PAGE_BITS, size * PAGE_SIZE, | 45 | RasterizerFlushVirtualRegion(base << PAGE_BITS, size * PAGE_SIZE, |
| 46 | FlushMode::FlushAndInvalidate); | 46 | FlushMode::FlushAndInvalidate); |
| @@ -169,10 +169,10 @@ T Read(const VAddr vaddr) { | |||
| 169 | PageType type = current_page_table->attributes[vaddr >> PAGE_BITS]; | 169 | PageType type = current_page_table->attributes[vaddr >> PAGE_BITS]; |
| 170 | switch (type) { | 170 | switch (type) { |
| 171 | case PageType::Unmapped: | 171 | case PageType::Unmapped: |
| 172 | LOG_ERROR(HW_Memory, "unmapped Read%lu @ 0x%08X", sizeof(T) * 8, vaddr); | 172 | NGLOG_ERROR(HW_Memory, "Unmapped Read{} @ {:#010X}", sizeof(T) * 8, vaddr); |
| 173 | return 0; | 173 | return 0; |
| 174 | case PageType::Memory: | 174 | case PageType::Memory: |
| 175 | ASSERT_MSG(false, "Mapped memory page without a pointer @ %08X", vaddr); | 175 | ASSERT_MSG(false, "Mapped memory page without a pointer @ %016" PRIX64, vaddr); |
| 176 | break; | 176 | break; |
| 177 | case PageType::RasterizerCachedMemory: { | 177 | case PageType::RasterizerCachedMemory: { |
| 178 | RasterizerFlushVirtualRegion(vaddr, sizeof(T), FlushMode::Flush); | 178 | RasterizerFlushVirtualRegion(vaddr, sizeof(T), FlushMode::Flush); |
| @@ -201,11 +201,11 @@ void Write(const VAddr vaddr, const T data) { | |||
| 201 | PageType type = current_page_table->attributes[vaddr >> PAGE_BITS]; | 201 | PageType type = current_page_table->attributes[vaddr >> PAGE_BITS]; |
| 202 | switch (type) { | 202 | switch (type) { |
| 203 | case PageType::Unmapped: | 203 | case PageType::Unmapped: |
| 204 | LOG_ERROR(HW_Memory, "unmapped Write%lu 0x%08X @ 0x%08X", sizeof(data) * 8, (u32)data, | 204 | NGLOG_ERROR(HW_Memory, "Unmapped Write{} {:#010X} @ {:#018X}", sizeof(data) * 8, (u32)data, |
| 205 | vaddr); | 205 | vaddr); |
| 206 | return; | 206 | return; |
| 207 | case PageType::Memory: | 207 | case PageType::Memory: |
| 208 | ASSERT_MSG(false, "Mapped memory page without a pointer @ %08X", vaddr); | 208 | ASSERT_MSG(false, "Mapped memory page without a pointer @ %016" PRIX64, vaddr); |
| 209 | break; | 209 | break; |
| 210 | case PageType::RasterizerCachedMemory: { | 210 | case PageType::RasterizerCachedMemory: { |
| 211 | RasterizerFlushVirtualRegion(vaddr, sizeof(T), FlushMode::Invalidate); | 211 | RasterizerFlushVirtualRegion(vaddr, sizeof(T), FlushMode::Invalidate); |
| @@ -251,7 +251,7 @@ u8* GetPointer(const VAddr vaddr) { | |||
| 251 | return GetPointerFromVMA(vaddr); | 251 | return GetPointerFromVMA(vaddr); |
| 252 | } | 252 | } |
| 253 | 253 | ||
| 254 | LOG_ERROR(HW_Memory, "unknown GetPointer @ 0x%08x", vaddr); | 254 | NGLOG_ERROR(HW_Memory, "Unknown GetPointer @ {:#018X}", vaddr); |
| 255 | return nullptr; | 255 | return nullptr; |
| 256 | } | 256 | } |
| 257 | 257 | ||
| @@ -288,13 +288,12 @@ u8* GetPhysicalPointer(PAddr address) { | |||
| 288 | }); | 288 | }); |
| 289 | 289 | ||
| 290 | if (area == std::end(memory_areas)) { | 290 | if (area == std::end(memory_areas)) { |
| 291 | LOG_ERROR(HW_Memory, "unknown GetPhysicalPointer @ 0x%016" PRIX64, address); | 291 | NGLOG_ERROR(HW_Memory, "Unknown GetPhysicalPointer @ {:#018X}", address); |
| 292 | return nullptr; | 292 | return nullptr; |
| 293 | } | 293 | } |
| 294 | 294 | ||
| 295 | if (area->paddr_base == IO_AREA_PADDR) { | 295 | if (area->paddr_base == IO_AREA_PADDR) { |
| 296 | LOG_ERROR(HW_Memory, "MMIO mappings are not supported yet. phys_addr=0x%016" PRIX64, | 296 | NGLOG_ERROR(HW_Memory, "MMIO mappings are not supported yet. phys_addr={:018X}", address); |
| 297 | address); | ||
| 298 | return nullptr; | 297 | return nullptr; |
| 299 | } | 298 | } |
| 300 | 299 | ||
| @@ -325,15 +324,29 @@ u8* GetPhysicalPointer(PAddr address) { | |||
| 325 | return target_pointer; | 324 | return target_pointer; |
| 326 | } | 325 | } |
| 327 | 326 | ||
| 328 | void RasterizerMarkRegionCached(VAddr start, u64 size, bool cached) { | 327 | void RasterizerMarkRegionCached(Tegra::GPUVAddr gpu_addr, u64 size, bool cached) { |
| 329 | if (start == 0) { | 328 | if (gpu_addr == 0) { |
| 330 | return; | 329 | return; |
| 331 | } | 330 | } |
| 332 | 331 | ||
| 333 | u64 num_pages = ((start + size - 1) >> PAGE_BITS) - (start >> PAGE_BITS) + 1; | 332 | // Iterate over a contiguous CPU address space, which corresponds to the specified GPU address |
| 334 | VAddr vaddr = start; | 333 | // space, marking the region as un/cached. The region is marked un/cached at a granularity of |
| 334 | // CPU pages, hence why we iterate on a CPU page basis (note: GPU page size is different). This | ||
| 335 | // assumes the specified GPU address region is contiguous as well. | ||
| 336 | |||
| 337 | u64 num_pages = ((gpu_addr + size - 1) >> PAGE_BITS) - (gpu_addr >> PAGE_BITS) + 1; | ||
| 338 | for (unsigned i = 0; i < num_pages; ++i, gpu_addr += PAGE_SIZE) { | ||
| 339 | boost::optional<VAddr> maybe_vaddr = | ||
| 340 | Core::System::GetInstance().GPU().memory_manager->GpuToCpuAddress(gpu_addr); | ||
| 341 | // The GPU <-> CPU virtual memory mapping is not 1:1 | ||
| 342 | if (!maybe_vaddr) { | ||
| 343 | NGLOG_ERROR(HW_Memory, | ||
| 344 | "Trying to flush a cached region to an invalid physical address {:016X}", | ||
| 345 | gpu_addr); | ||
| 346 | continue; | ||
| 347 | } | ||
| 348 | VAddr vaddr = *maybe_vaddr; | ||
| 335 | 349 | ||
| 336 | for (unsigned i = 0; i < num_pages; ++i, vaddr += PAGE_SIZE) { | ||
| 337 | PageType& page_type = current_page_table->attributes[vaddr >> PAGE_BITS]; | 350 | PageType& page_type = current_page_table->attributes[vaddr >> PAGE_BITS]; |
| 338 | 351 | ||
| 339 | if (cached) { | 352 | if (cached) { |
| @@ -347,6 +360,10 @@ void RasterizerMarkRegionCached(VAddr start, u64 size, bool cached) { | |||
| 347 | page_type = PageType::RasterizerCachedMemory; | 360 | page_type = PageType::RasterizerCachedMemory; |
| 348 | current_page_table->pointers[vaddr >> PAGE_BITS] = nullptr; | 361 | current_page_table->pointers[vaddr >> PAGE_BITS] = nullptr; |
| 349 | break; | 362 | break; |
| 363 | case PageType::RasterizerCachedMemory: | ||
| 364 | // There can be more than one GPU region mapped per CPU region, so it's common that | ||
| 365 | // this area is already marked as cached. | ||
| 366 | break; | ||
| 350 | default: | 367 | default: |
| 351 | UNREACHABLE(); | 368 | UNREACHABLE(); |
| 352 | } | 369 | } |
| @@ -357,6 +374,10 @@ void RasterizerMarkRegionCached(VAddr start, u64 size, bool cached) { | |||
| 357 | // It is not necessary for a process to have this region mapped into its address | 374 | // It is not necessary for a process to have this region mapped into its address |
| 358 | // space, for example, a system module need not have a VRAM mapping. | 375 | // space, for example, a system module need not have a VRAM mapping. |
| 359 | break; | 376 | break; |
| 377 | case PageType::Memory: | ||
| 378 | // There can be more than one GPU region mapped per CPU region, so it's common that | ||
| 379 | // this area is already unmarked as cached. | ||
| 380 | break; | ||
| 360 | case PageType::RasterizerCachedMemory: { | 381 | case PageType::RasterizerCachedMemory: { |
| 361 | u8* pointer = GetPointerFromVMA(vaddr & ~PAGE_MASK); | 382 | u8* pointer = GetPointerFromVMA(vaddr & ~PAGE_MASK); |
| 362 | if (pointer == nullptr) { | 383 | if (pointer == nullptr) { |
| @@ -394,19 +415,29 @@ void RasterizerFlushVirtualRegion(VAddr start, u64 size, FlushMode mode) { | |||
| 394 | 415 | ||
| 395 | VAddr overlap_start = std::max(start, region_start); | 416 | VAddr overlap_start = std::max(start, region_start); |
| 396 | VAddr overlap_end = std::min(end, region_end); | 417 | VAddr overlap_end = std::min(end, region_end); |
| 418 | |||
| 419 | std::vector<Tegra::GPUVAddr> gpu_addresses = | ||
| 420 | Core::System::GetInstance().GPU().memory_manager->CpuToGpuAddress(overlap_start); | ||
| 421 | |||
| 422 | if (gpu_addresses.empty()) { | ||
| 423 | return; | ||
| 424 | } | ||
| 425 | |||
| 397 | u64 overlap_size = overlap_end - overlap_start; | 426 | u64 overlap_size = overlap_end - overlap_start; |
| 398 | 427 | ||
| 399 | auto* rasterizer = VideoCore::g_renderer->Rasterizer(); | 428 | for (const auto& gpu_address : gpu_addresses) { |
| 400 | switch (mode) { | 429 | auto* rasterizer = VideoCore::g_renderer->Rasterizer(); |
| 401 | case FlushMode::Flush: | 430 | switch (mode) { |
| 402 | rasterizer->FlushRegion(overlap_start, overlap_size); | 431 | case FlushMode::Flush: |
| 403 | break; | 432 | rasterizer->FlushRegion(gpu_address, overlap_size); |
| 404 | case FlushMode::Invalidate: | 433 | break; |
| 405 | rasterizer->InvalidateRegion(overlap_start, overlap_size); | 434 | case FlushMode::Invalidate: |
| 406 | break; | 435 | rasterizer->InvalidateRegion(gpu_address, overlap_size); |
| 407 | case FlushMode::FlushAndInvalidate: | 436 | break; |
| 408 | rasterizer->FlushAndInvalidateRegion(overlap_start, overlap_size); | 437 | case FlushMode::FlushAndInvalidate: |
| 409 | break; | 438 | rasterizer->FlushAndInvalidateRegion(gpu_address, overlap_size); |
| 439 | break; | ||
| 440 | } | ||
| 410 | } | 441 | } |
| 411 | }; | 442 | }; |
| 412 | 443 | ||
| @@ -445,8 +476,9 @@ void ReadBlock(const Kernel::Process& process, const VAddr src_addr, void* dest_ | |||
| 445 | 476 | ||
| 446 | switch (page_table.attributes[page_index]) { | 477 | switch (page_table.attributes[page_index]) { |
| 447 | case PageType::Unmapped: { | 478 | case PageType::Unmapped: { |
| 448 | LOG_ERROR(HW_Memory, "unmapped ReadBlock @ 0x%08X (start address = 0x%08X, size = %zu)", | 479 | NGLOG_ERROR(HW_Memory, |
| 449 | current_vaddr, src_addr, size); | 480 | "Unmapped ReadBlock @ {:#018X} (start address = {:#018X}, size = {})", |
| 481 | current_vaddr, src_addr, size); | ||
| 450 | std::memset(dest_buffer, 0, copy_amount); | 482 | std::memset(dest_buffer, 0, copy_amount); |
| 451 | break; | 483 | break; |
| 452 | } | 484 | } |
| @@ -508,9 +540,9 @@ void WriteBlock(const Kernel::Process& process, const VAddr dest_addr, const voi | |||
| 508 | 540 | ||
| 509 | switch (page_table.attributes[page_index]) { | 541 | switch (page_table.attributes[page_index]) { |
| 510 | case PageType::Unmapped: { | 542 | case PageType::Unmapped: { |
| 511 | LOG_ERROR(HW_Memory, | 543 | NGLOG_ERROR(HW_Memory, |
| 512 | "unmapped WriteBlock @ 0x%08X (start address = 0x%08X, size = %zu)", | 544 | "Unmapped WriteBlock @ {:#018X} (start address = {:#018X}, size = {})", |
| 513 | current_vaddr, dest_addr, size); | 545 | current_vaddr, dest_addr, size); |
| 514 | break; | 546 | break; |
| 515 | } | 547 | } |
| 516 | case PageType::Memory: { | 548 | case PageType::Memory: { |
| @@ -556,8 +588,9 @@ void ZeroBlock(const Kernel::Process& process, const VAddr dest_addr, const size | |||
| 556 | 588 | ||
| 557 | switch (page_table.attributes[page_index]) { | 589 | switch (page_table.attributes[page_index]) { |
| 558 | case PageType::Unmapped: { | 590 | case PageType::Unmapped: { |
| 559 | LOG_ERROR(HW_Memory, "unmapped ZeroBlock @ 0x%08X (start address = 0x%08X, size = %zu)", | 591 | NGLOG_ERROR(HW_Memory, |
| 560 | current_vaddr, dest_addr, size); | 592 | "Unmapped ZeroBlock @ {:#018X} (start address = {#:018X}, size = {})", |
| 593 | current_vaddr, dest_addr, size); | ||
| 561 | break; | 594 | break; |
| 562 | } | 595 | } |
| 563 | case PageType::Memory: { | 596 | case PageType::Memory: { |
| @@ -596,8 +629,9 @@ void CopyBlock(const Kernel::Process& process, VAddr dest_addr, VAddr src_addr, | |||
| 596 | 629 | ||
| 597 | switch (page_table.attributes[page_index]) { | 630 | switch (page_table.attributes[page_index]) { |
| 598 | case PageType::Unmapped: { | 631 | case PageType::Unmapped: { |
| 599 | LOG_ERROR(HW_Memory, "unmapped CopyBlock @ 0x%08X (start address = 0x%08X, size = %zu)", | 632 | NGLOG_ERROR(HW_Memory, |
| 600 | current_vaddr, src_addr, size); | 633 | "Unmapped CopyBlock @ {:#018X} (start address = {:#018X}, size = {})", |
| 634 | current_vaddr, src_addr, size); | ||
| 601 | ZeroBlock(process, dest_addr, copy_amount); | 635 | ZeroBlock(process, dest_addr, copy_amount); |
| 602 | break; | 636 | break; |
| 603 | } | 637 | } |
| @@ -625,6 +659,10 @@ void CopyBlock(const Kernel::Process& process, VAddr dest_addr, VAddr src_addr, | |||
| 625 | } | 659 | } |
| 626 | } | 660 | } |
| 627 | 661 | ||
| 662 | void CopyBlock(VAddr dest_addr, VAddr src_addr, size_t size) { | ||
| 663 | CopyBlock(*Core::CurrentProcess(), dest_addr, src_addr, size); | ||
| 664 | } | ||
| 665 | |||
| 628 | boost::optional<PAddr> TryVirtualToPhysicalAddress(const VAddr addr) { | 666 | boost::optional<PAddr> TryVirtualToPhysicalAddress(const VAddr addr) { |
| 629 | if (addr == 0) { | 667 | if (addr == 0) { |
| 630 | return 0; | 668 | return 0; |
| @@ -646,7 +684,7 @@ boost::optional<PAddr> TryVirtualToPhysicalAddress(const VAddr addr) { | |||
| 646 | PAddr VirtualToPhysicalAddress(const VAddr addr) { | 684 | PAddr VirtualToPhysicalAddress(const VAddr addr) { |
| 647 | auto paddr = TryVirtualToPhysicalAddress(addr); | 685 | auto paddr = TryVirtualToPhysicalAddress(addr); |
| 648 | if (!paddr) { | 686 | if (!paddr) { |
| 649 | LOG_ERROR(HW_Memory, "Unknown virtual address @ 0x%016" PRIX64, addr); | 687 | NGLOG_ERROR(HW_Memory, "Unknown virtual address @ {:#018X}", addr); |
| 650 | // To help with debugging, set bit on address so that it's obviously invalid. | 688 | // To help with debugging, set bit on address so that it's obviously invalid. |
| 651 | return addr | 0x80000000; | 689 | return addr | 0x80000000; |
| 652 | } | 690 | } |
diff --git a/src/core/memory.h b/src/core/memory.h index e9b8ca873..3f56a2c6a 100644 --- a/src/core/memory.h +++ b/src/core/memory.h | |||
| @@ -14,6 +14,7 @@ | |||
| 14 | #include <boost/optional.hpp> | 14 | #include <boost/optional.hpp> |
| 15 | #include "common/common_types.h" | 15 | #include "common/common_types.h" |
| 16 | #include "core/memory_hook.h" | 16 | #include "core/memory_hook.h" |
| 17 | #include "video_core/memory_manager.h" | ||
| 17 | 18 | ||
| 18 | namespace Kernel { | 19 | namespace Kernel { |
| 19 | class Process; | 20 | class Process; |
| @@ -258,7 +259,7 @@ enum class FlushMode { | |||
| 258 | /** | 259 | /** |
| 259 | * Mark each page touching the region as cached. | 260 | * Mark each page touching the region as cached. |
| 260 | */ | 261 | */ |
| 261 | void RasterizerMarkRegionCached(VAddr start, u64 size, bool cached); | 262 | void RasterizerMarkRegionCached(Tegra::GPUVAddr start, u64 size, bool cached); |
| 262 | 263 | ||
| 263 | /** | 264 | /** |
| 264 | * Flushes and invalidates any externally cached rasterizer resources touching the given virtual | 265 | * Flushes and invalidates any externally cached rasterizer resources touching the given virtual |
diff --git a/src/video_core/command_processor.cpp b/src/video_core/command_processor.cpp index d4cdb4ab2..2eaece298 100644 --- a/src/video_core/command_processor.cpp +++ b/src/video_core/command_processor.cpp | |||
| @@ -24,41 +24,18 @@ namespace Tegra { | |||
| 24 | 24 | ||
| 25 | enum class BufferMethods { | 25 | enum class BufferMethods { |
| 26 | BindObject = 0, | 26 | BindObject = 0, |
| 27 | SetGraphMacroCode = 0x45, | 27 | CountBufferMethods = 0x40, |
| 28 | SetGraphMacroCodeArg = 0x46, | ||
| 29 | SetGraphMacroEntry = 0x47, | ||
| 30 | CountBufferMethods = 0x100, | ||
| 31 | }; | 28 | }; |
| 32 | 29 | ||
| 33 | void GPU::WriteReg(u32 method, u32 subchannel, u32 value, u32 remaining_params) { | 30 | void GPU::WriteReg(u32 method, u32 subchannel, u32 value, u32 remaining_params) { |
| 34 | LOG_WARNING(HW_GPU, "Processing method %08X on subchannel %u value %08X remaining params %u", | 31 | NGLOG_WARNING(HW_GPU, |
| 35 | method, subchannel, value, remaining_params); | 32 | "Processing method {:08X} on subchannel {} value " |
| 36 | 33 | "{:08X} remaining params {}", | |
| 37 | if (method == static_cast<u32>(BufferMethods::SetGraphMacroEntry)) { | 34 | method, subchannel, value, remaining_params); |
| 38 | // Prepare to upload a new macro, reset the upload counter. | ||
| 39 | LOG_DEBUG(HW_GPU, "Uploading GPU macro %08X", value); | ||
| 40 | current_macro_entry = value; | ||
| 41 | current_macro_code.clear(); | ||
| 42 | return; | ||
| 43 | } | ||
| 44 | |||
| 45 | if (method == static_cast<u32>(BufferMethods::SetGraphMacroCodeArg)) { | ||
| 46 | // Append a new code word to the current macro. | ||
| 47 | current_macro_code.push_back(value); | ||
| 48 | |||
| 49 | // There are no more params remaining, submit the code to the 3D engine. | ||
| 50 | if (remaining_params == 0) { | ||
| 51 | maxwell_3d->SubmitMacroCode(current_macro_entry, std::move(current_macro_code)); | ||
| 52 | current_macro_entry = InvalidGraphMacroEntry; | ||
| 53 | current_macro_code.clear(); | ||
| 54 | } | ||
| 55 | |||
| 56 | return; | ||
| 57 | } | ||
| 58 | 35 | ||
| 59 | if (method == static_cast<u32>(BufferMethods::BindObject)) { | 36 | if (method == static_cast<u32>(BufferMethods::BindObject)) { |
| 60 | // Bind the current subchannel to the desired engine id. | 37 | // Bind the current subchannel to the desired engine id. |
| 61 | LOG_DEBUG(HW_GPU, "Binding subchannel %u to engine %u", subchannel, value); | 38 | NGLOG_DEBUG(HW_GPU, "Binding subchannel {} to engine {}", subchannel, value); |
| 62 | ASSERT(bound_engines.find(subchannel) == bound_engines.end()); | 39 | ASSERT(bound_engines.find(subchannel) == bound_engines.end()); |
| 63 | bound_engines[subchannel] = static_cast<EngineID>(value); | 40 | bound_engines[subchannel] = static_cast<EngineID>(value); |
| 64 | return; | 41 | return; |
| @@ -66,7 +43,7 @@ void GPU::WriteReg(u32 method, u32 subchannel, u32 value, u32 remaining_params) | |||
| 66 | 43 | ||
| 67 | if (method < static_cast<u32>(BufferMethods::CountBufferMethods)) { | 44 | if (method < static_cast<u32>(BufferMethods::CountBufferMethods)) { |
| 68 | // TODO(Subv): Research and implement these methods. | 45 | // TODO(Subv): Research and implement these methods. |
| 69 | LOG_ERROR(HW_GPU, "Special buffer methods other than Bind are not implemented"); | 46 | NGLOG_ERROR(HW_GPU, "Special buffer methods other than Bind are not implemented"); |
| 70 | return; | 47 | return; |
| 71 | } | 48 | } |
| 72 | 49 | ||
| @@ -90,11 +67,9 @@ void GPU::WriteReg(u32 method, u32 subchannel, u32 value, u32 remaining_params) | |||
| 90 | } | 67 | } |
| 91 | 68 | ||
| 92 | void GPU::ProcessCommandList(GPUVAddr address, u32 size) { | 69 | void GPU::ProcessCommandList(GPUVAddr address, u32 size) { |
| 93 | // TODO(Subv): PhysicalToVirtualAddress is a misnomer, it converts a GPU VAddr into an | 70 | const boost::optional<VAddr> head_address = memory_manager->GpuToCpuAddress(address); |
| 94 | // application VAddr. | 71 | VAddr current_addr = *head_address; |
| 95 | const VAddr head_address = memory_manager->PhysicalToVirtualAddress(address); | 72 | while (current_addr < *head_address + size * sizeof(CommandHeader)) { |
| 96 | VAddr current_addr = head_address; | ||
| 97 | while (current_addr < head_address + size * sizeof(CommandHeader)) { | ||
| 98 | const CommandHeader header = {Memory::Read32(current_addr)}; | 73 | const CommandHeader header = {Memory::Read32(current_addr)}; |
| 99 | current_addr += sizeof(u32); | 74 | current_addr += sizeof(u32); |
| 100 | 75 | ||
diff --git a/src/video_core/engines/fermi_2d.cpp b/src/video_core/engines/fermi_2d.cpp index 7aab163dc..9019f2504 100644 --- a/src/video_core/engines/fermi_2d.cpp +++ b/src/video_core/engines/fermi_2d.cpp | |||
| @@ -2,12 +2,71 @@ | |||
| 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/memory.h" | ||
| 5 | #include "video_core/engines/fermi_2d.h" | 6 | #include "video_core/engines/fermi_2d.h" |
| 7 | #include "video_core/textures/decoders.h" | ||
| 6 | 8 | ||
| 7 | namespace Tegra { | 9 | namespace Tegra { |
| 8 | namespace Engines { | 10 | namespace Engines { |
| 9 | 11 | ||
| 10 | void Fermi2D::WriteReg(u32 method, u32 value) {} | 12 | Fermi2D::Fermi2D(MemoryManager& memory_manager) : memory_manager(memory_manager) {} |
| 13 | |||
| 14 | void Fermi2D::WriteReg(u32 method, u32 value) { | ||
| 15 | ASSERT_MSG(method < Regs::NUM_REGS, | ||
| 16 | "Invalid Fermi2D register, increase the size of the Regs structure"); | ||
| 17 | |||
| 18 | regs.reg_array[method] = value; | ||
| 19 | |||
| 20 | switch (method) { | ||
| 21 | case FERMI2D_REG_INDEX(trigger): { | ||
| 22 | HandleSurfaceCopy(); | ||
| 23 | break; | ||
| 24 | } | ||
| 25 | } | ||
| 26 | } | ||
| 27 | |||
| 28 | void Fermi2D::HandleSurfaceCopy() { | ||
| 29 | NGLOG_WARNING(HW_GPU, "Requested a surface copy with operation {}", | ||
| 30 | static_cast<u32>(regs.operation)); | ||
| 31 | |||
| 32 | const GPUVAddr source = regs.src.Address(); | ||
| 33 | const GPUVAddr dest = regs.dst.Address(); | ||
| 34 | |||
| 35 | // TODO(Subv): Only same-format and same-size copies are allowed for now. | ||
| 36 | ASSERT(regs.src.format == regs.dst.format); | ||
| 37 | ASSERT(regs.src.width * regs.src.height == regs.dst.width * regs.dst.height); | ||
| 38 | |||
| 39 | // TODO(Subv): Only raw copies are implemented. | ||
| 40 | ASSERT(regs.operation == Regs::Operation::SrcCopy); | ||
| 41 | |||
| 42 | const VAddr source_cpu = *memory_manager.GpuToCpuAddress(source); | ||
| 43 | const VAddr dest_cpu = *memory_manager.GpuToCpuAddress(dest); | ||
| 44 | |||
| 45 | u32 src_bytes_per_pixel = RenderTargetBytesPerPixel(regs.src.format); | ||
| 46 | u32 dst_bytes_per_pixel = RenderTargetBytesPerPixel(regs.dst.format); | ||
| 47 | |||
| 48 | if (regs.src.linear == regs.dst.linear) { | ||
| 49 | // If the input layout and the output layout are the same, just perform a raw copy. | ||
| 50 | Memory::CopyBlock(dest_cpu, source_cpu, | ||
| 51 | src_bytes_per_pixel * regs.dst.width * regs.dst.height); | ||
| 52 | return; | ||
| 53 | } | ||
| 54 | |||
| 55 | u8* src_buffer = Memory::GetPointer(source_cpu); | ||
| 56 | u8* dst_buffer = Memory::GetPointer(dest_cpu); | ||
| 57 | |||
| 58 | if (!regs.src.linear && regs.dst.linear) { | ||
| 59 | // If the input is tiled and the output is linear, deswizzle the input and copy it over. | ||
| 60 | Texture::CopySwizzledData(regs.src.width, regs.src.height, src_bytes_per_pixel, | ||
| 61 | dst_bytes_per_pixel, src_buffer, dst_buffer, true, | ||
| 62 | regs.src.block_height); | ||
| 63 | } else { | ||
| 64 | // If the input is linear and the output is tiled, swizzle the input and copy it over. | ||
| 65 | Texture::CopySwizzledData(regs.src.width, regs.src.height, src_bytes_per_pixel, | ||
| 66 | dst_bytes_per_pixel, dst_buffer, src_buffer, false, | ||
| 67 | regs.dst.block_height); | ||
| 68 | } | ||
| 69 | } | ||
| 11 | 70 | ||
| 12 | } // namespace Engines | 71 | } // namespace Engines |
| 13 | } // namespace Tegra | 72 | } // namespace Tegra |
diff --git a/src/video_core/engines/fermi_2d.h b/src/video_core/engines/fermi_2d.h index 8967ddede..0c5b413cc 100644 --- a/src/video_core/engines/fermi_2d.h +++ b/src/video_core/engines/fermi_2d.h | |||
| @@ -4,19 +4,106 @@ | |||
| 4 | 4 | ||
| 5 | #pragma once | 5 | #pragma once |
| 6 | 6 | ||
| 7 | #include <array> | ||
| 8 | #include "common/assert.h" | ||
| 9 | #include "common/bit_field.h" | ||
| 10 | #include "common/common_funcs.h" | ||
| 7 | #include "common/common_types.h" | 11 | #include "common/common_types.h" |
| 12 | #include "video_core/gpu.h" | ||
| 13 | #include "video_core/memory_manager.h" | ||
| 8 | 14 | ||
| 9 | namespace Tegra { | 15 | namespace Tegra { |
| 10 | namespace Engines { | 16 | namespace Engines { |
| 11 | 17 | ||
| 18 | #define FERMI2D_REG_INDEX(field_name) \ | ||
| 19 | (offsetof(Tegra::Engines::Fermi2D::Regs, field_name) / sizeof(u32)) | ||
| 20 | |||
| 12 | class Fermi2D final { | 21 | class Fermi2D final { |
| 13 | public: | 22 | public: |
| 14 | Fermi2D() = default; | 23 | explicit Fermi2D(MemoryManager& memory_manager); |
| 15 | ~Fermi2D() = default; | 24 | ~Fermi2D() = default; |
| 16 | 25 | ||
| 17 | /// Write the value to the register identified by method. | 26 | /// Write the value to the register identified by method. |
| 18 | void WriteReg(u32 method, u32 value); | 27 | void WriteReg(u32 method, u32 value); |
| 28 | |||
| 29 | struct Regs { | ||
| 30 | static constexpr size_t NUM_REGS = 0x258; | ||
| 31 | |||
| 32 | struct Surface { | ||
| 33 | RenderTargetFormat format; | ||
| 34 | BitField<0, 1, u32> linear; | ||
| 35 | union { | ||
| 36 | BitField<0, 4, u32> block_depth; | ||
| 37 | BitField<4, 4, u32> block_height; | ||
| 38 | BitField<8, 4, u32> block_width; | ||
| 39 | }; | ||
| 40 | u32 depth; | ||
| 41 | u32 layer; | ||
| 42 | u32 pitch; | ||
| 43 | u32 width; | ||
| 44 | u32 height; | ||
| 45 | u32 address_high; | ||
| 46 | u32 address_low; | ||
| 47 | |||
| 48 | GPUVAddr Address() const { | ||
| 49 | return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) | | ||
| 50 | address_low); | ||
| 51 | } | ||
| 52 | }; | ||
| 53 | static_assert(sizeof(Surface) == 0x28, "Surface has incorrect size"); | ||
| 54 | |||
| 55 | enum class Operation : u32 { | ||
| 56 | SrcCopyAnd = 0, | ||
| 57 | ROPAnd = 1, | ||
| 58 | Blend = 2, | ||
| 59 | SrcCopy = 3, | ||
| 60 | ROP = 4, | ||
| 61 | SrcCopyPremult = 5, | ||
| 62 | BlendPremult = 6, | ||
| 63 | }; | ||
| 64 | |||
| 65 | union { | ||
| 66 | struct { | ||
| 67 | INSERT_PADDING_WORDS(0x80); | ||
| 68 | |||
| 69 | Surface dst; | ||
| 70 | |||
| 71 | INSERT_PADDING_WORDS(2); | ||
| 72 | |||
| 73 | Surface src; | ||
| 74 | |||
| 75 | INSERT_PADDING_WORDS(0x15); | ||
| 76 | |||
| 77 | Operation operation; | ||
| 78 | |||
| 79 | INSERT_PADDING_WORDS(0x9); | ||
| 80 | |||
| 81 | // TODO(Subv): This is only a guess. | ||
| 82 | u32 trigger; | ||
| 83 | |||
| 84 | INSERT_PADDING_WORDS(0x1A3); | ||
| 85 | }; | ||
| 86 | std::array<u32, NUM_REGS> reg_array; | ||
| 87 | }; | ||
| 88 | } regs{}; | ||
| 89 | |||
| 90 | MemoryManager& memory_manager; | ||
| 91 | |||
| 92 | private: | ||
| 93 | /// Performs the copy from the source surface to the destination surface as configured in the | ||
| 94 | /// registers. | ||
| 95 | void HandleSurfaceCopy(); | ||
| 19 | }; | 96 | }; |
| 20 | 97 | ||
| 98 | #define ASSERT_REG_POSITION(field_name, position) \ | ||
| 99 | static_assert(offsetof(Fermi2D::Regs, field_name) == position * 4, \ | ||
| 100 | "Field " #field_name " has invalid position") | ||
| 101 | |||
| 102 | ASSERT_REG_POSITION(dst, 0x80); | ||
| 103 | ASSERT_REG_POSITION(src, 0x8C); | ||
| 104 | ASSERT_REG_POSITION(operation, 0xAB); | ||
| 105 | ASSERT_REG_POSITION(trigger, 0xB5); | ||
| 106 | #undef ASSERT_REG_POSITION | ||
| 107 | |||
| 21 | } // namespace Engines | 108 | } // namespace Engines |
| 22 | } // namespace Tegra | 109 | } // namespace Tegra |
diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp index 2a3ff234a..4306b894f 100644 --- a/src/video_core/engines/maxwell_3d.cpp +++ b/src/video_core/engines/maxwell_3d.cpp | |||
| @@ -22,10 +22,6 @@ constexpr u32 MacroRegistersStart = 0xE00; | |||
| 22 | Maxwell3D::Maxwell3D(MemoryManager& memory_manager) | 22 | Maxwell3D::Maxwell3D(MemoryManager& memory_manager) |
| 23 | : memory_manager(memory_manager), macro_interpreter(*this) {} | 23 | : memory_manager(memory_manager), macro_interpreter(*this) {} |
| 24 | 24 | ||
| 25 | void Maxwell3D::SubmitMacroCode(u32 entry, std::vector<u32> code) { | ||
| 26 | uploaded_macros[entry * 2 + MacroRegistersStart] = std::move(code); | ||
| 27 | } | ||
| 28 | |||
| 29 | void Maxwell3D::CallMacroMethod(u32 method, std::vector<u32> parameters) { | 25 | void Maxwell3D::CallMacroMethod(u32 method, std::vector<u32> parameters) { |
| 30 | auto macro_code = uploaded_macros.find(method); | 26 | auto macro_code = uploaded_macros.find(method); |
| 31 | // The requested macro must have been uploaded already. | 27 | // The requested macro must have been uploaded already. |
| @@ -37,9 +33,6 @@ void Maxwell3D::CallMacroMethod(u32 method, std::vector<u32> parameters) { | |||
| 37 | } | 33 | } |
| 38 | 34 | ||
| 39 | void Maxwell3D::WriteReg(u32 method, u32 value, u32 remaining_params) { | 35 | void Maxwell3D::WriteReg(u32 method, u32 value, u32 remaining_params) { |
| 40 | ASSERT_MSG(method < Regs::NUM_REGS, | ||
| 41 | "Invalid Maxwell3D register, increase the size of the Regs structure"); | ||
| 42 | |||
| 43 | auto debug_context = Core::System::GetInstance().GetGPUDebugContext(); | 36 | auto debug_context = Core::System::GetInstance().GetGPUDebugContext(); |
| 44 | 37 | ||
| 45 | // It is an error to write to a register other than the current macro's ARG register before it | 38 | // It is an error to write to a register other than the current macro's ARG register before it |
| @@ -68,6 +61,9 @@ void Maxwell3D::WriteReg(u32 method, u32 value, u32 remaining_params) { | |||
| 68 | return; | 61 | return; |
| 69 | } | 62 | } |
| 70 | 63 | ||
| 64 | ASSERT_MSG(method < Regs::NUM_REGS, | ||
| 65 | "Invalid Maxwell3D register, increase the size of the Regs structure"); | ||
| 66 | |||
| 71 | if (debug_context) { | 67 | if (debug_context) { |
| 72 | debug_context->OnEvent(Tegra::DebugContext::Event::MaxwellCommandLoaded, nullptr); | 68 | debug_context->OnEvent(Tegra::DebugContext::Event::MaxwellCommandLoaded, nullptr); |
| 73 | } | 69 | } |
| @@ -75,6 +71,10 @@ void Maxwell3D::WriteReg(u32 method, u32 value, u32 remaining_params) { | |||
| 75 | regs.reg_array[method] = value; | 71 | regs.reg_array[method] = value; |
| 76 | 72 | ||
| 77 | switch (method) { | 73 | switch (method) { |
| 74 | case MAXWELL3D_REG_INDEX(macros.data): { | ||
| 75 | ProcessMacroUpload(value); | ||
| 76 | break; | ||
| 77 | } | ||
| 78 | case MAXWELL3D_REG_INDEX(code_address.code_address_high): | 78 | case MAXWELL3D_REG_INDEX(code_address.code_address_high): |
| 79 | case MAXWELL3D_REG_INDEX(code_address.code_address_low): { | 79 | case MAXWELL3D_REG_INDEX(code_address.code_address_low): { |
| 80 | // Note: For some reason games (like Puyo Puyo Tetris) seem to write 0 to the CODE_ADDRESS | 80 | // Note: For some reason games (like Puyo Puyo Tetris) seem to write 0 to the CODE_ADDRESS |
| @@ -141,17 +141,48 @@ void Maxwell3D::WriteReg(u32 method, u32 value, u32 remaining_params) { | |||
| 141 | } | 141 | } |
| 142 | } | 142 | } |
| 143 | 143 | ||
| 144 | void Maxwell3D::ProcessMacroUpload(u32 data) { | ||
| 145 | // Store the uploaded macro code to interpret them when they're called. | ||
| 146 | auto& macro = uploaded_macros[regs.macros.entry * 2 + MacroRegistersStart]; | ||
| 147 | macro.push_back(data); | ||
| 148 | } | ||
| 149 | |||
| 144 | void Maxwell3D::ProcessQueryGet() { | 150 | void Maxwell3D::ProcessQueryGet() { |
| 145 | GPUVAddr sequence_address = regs.query.QueryAddress(); | 151 | GPUVAddr sequence_address = regs.query.QueryAddress(); |
| 146 | // Since the sequence address is given as a GPU VAddr, we have to convert it to an application | 152 | // Since the sequence address is given as a GPU VAddr, we have to convert it to an application |
| 147 | // VAddr before writing. | 153 | // VAddr before writing. |
| 148 | VAddr address = memory_manager.PhysicalToVirtualAddress(sequence_address); | 154 | boost::optional<VAddr> address = memory_manager.GpuToCpuAddress(sequence_address); |
| 155 | |||
| 156 | // TODO(Subv): Support the other query units. | ||
| 157 | ASSERT_MSG(regs.query.query_get.unit == Regs::QueryUnit::Crop, | ||
| 158 | "Units other than CROP are unimplemented"); | ||
| 159 | ASSERT_MSG(regs.query.query_get.short_query, | ||
| 160 | "Writing the entire query result structure is unimplemented"); | ||
| 161 | |||
| 162 | u32 value = Memory::Read32(*address); | ||
| 163 | u32 result = 0; | ||
| 164 | |||
| 165 | // TODO(Subv): Support the other query variables | ||
| 166 | switch (regs.query.query_get.select) { | ||
| 167 | case Regs::QuerySelect::Zero: | ||
| 168 | result = 0; | ||
| 169 | break; | ||
| 170 | default: | ||
| 171 | UNIMPLEMENTED_MSG("Unimplemented query select type %u", | ||
| 172 | static_cast<u32>(regs.query.query_get.select.Value())); | ||
| 173 | } | ||
| 174 | |||
| 175 | // TODO(Subv): Research and implement how query sync conditions work. | ||
| 149 | 176 | ||
| 150 | switch (regs.query.query_get.mode) { | 177 | switch (regs.query.query_get.mode) { |
| 151 | case Regs::QueryMode::Write: { | 178 | case Regs::QueryMode::Write: |
| 179 | case Regs::QueryMode::Write2: { | ||
| 152 | // Write the current query sequence to the sequence address. | 180 | // Write the current query sequence to the sequence address. |
| 153 | u32 sequence = regs.query.query_sequence; | 181 | u32 sequence = regs.query.query_sequence; |
| 154 | Memory::Write32(address, sequence); | 182 | Memory::Write32(*address, sequence); |
| 183 | |||
| 184 | // TODO(Subv): Write the proper query response structure to the address when not using short | ||
| 185 | // mode. | ||
| 155 | break; | 186 | break; |
| 156 | } | 187 | } |
| 157 | default: | 188 | default: |
| @@ -161,8 +192,8 @@ void Maxwell3D::ProcessQueryGet() { | |||
| 161 | } | 192 | } |
| 162 | 193 | ||
| 163 | void Maxwell3D::DrawArrays() { | 194 | void Maxwell3D::DrawArrays() { |
| 164 | LOG_DEBUG(HW_GPU, "called, topology=%d, count=%d", regs.draw.topology.Value(), | 195 | NGLOG_DEBUG(HW_GPU, "called, topology={}, count={}", |
| 165 | regs.vertex_buffer.count); | 196 | static_cast<u32>(regs.draw.topology.Value()), regs.vertex_buffer.count); |
| 166 | ASSERT_MSG(!(regs.index_array.count && regs.vertex_buffer.count), "Both indexed and direct?"); | 197 | ASSERT_MSG(!(regs.index_array.count && regs.vertex_buffer.count), "Both indexed and direct?"); |
| 167 | 198 | ||
| 168 | auto debug_context = Core::System::GetInstance().GetGPUDebugContext(); | 199 | auto debug_context = Core::System::GetInstance().GetGPUDebugContext(); |
| @@ -200,10 +231,10 @@ void Maxwell3D::ProcessCBData(u32 value) { | |||
| 200 | // Don't allow writing past the end of the buffer. | 231 | // Don't allow writing past the end of the buffer. |
| 201 | ASSERT(regs.const_buffer.cb_pos + sizeof(u32) <= regs.const_buffer.cb_size); | 232 | ASSERT(regs.const_buffer.cb_pos + sizeof(u32) <= regs.const_buffer.cb_size); |
| 202 | 233 | ||
| 203 | VAddr address = | 234 | boost::optional<VAddr> address = |
| 204 | memory_manager.PhysicalToVirtualAddress(buffer_address + regs.const_buffer.cb_pos); | 235 | memory_manager.GpuToCpuAddress(buffer_address + regs.const_buffer.cb_pos); |
| 205 | 236 | ||
| 206 | Memory::Write32(address, value); | 237 | Memory::Write32(*address, value); |
| 207 | 238 | ||
| 208 | // Increment the current buffer position. | 239 | // Increment the current buffer position. |
| 209 | regs.const_buffer.cb_pos = regs.const_buffer.cb_pos + 4; | 240 | regs.const_buffer.cb_pos = regs.const_buffer.cb_pos + 4; |
| @@ -213,10 +244,10 @@ Texture::TICEntry Maxwell3D::GetTICEntry(u32 tic_index) const { | |||
| 213 | GPUVAddr tic_base_address = regs.tic.TICAddress(); | 244 | GPUVAddr tic_base_address = regs.tic.TICAddress(); |
| 214 | 245 | ||
| 215 | GPUVAddr tic_address_gpu = tic_base_address + tic_index * sizeof(Texture::TICEntry); | 246 | GPUVAddr tic_address_gpu = tic_base_address + tic_index * sizeof(Texture::TICEntry); |
| 216 | VAddr tic_address_cpu = memory_manager.PhysicalToVirtualAddress(tic_address_gpu); | 247 | boost::optional<VAddr> tic_address_cpu = memory_manager.GpuToCpuAddress(tic_address_gpu); |
| 217 | 248 | ||
| 218 | Texture::TICEntry tic_entry; | 249 | Texture::TICEntry tic_entry; |
| 219 | Memory::ReadBlock(tic_address_cpu, &tic_entry, sizeof(Texture::TICEntry)); | 250 | Memory::ReadBlock(*tic_address_cpu, &tic_entry, sizeof(Texture::TICEntry)); |
| 220 | 251 | ||
| 221 | ASSERT_MSG(tic_entry.header_version == Texture::TICHeaderVersion::BlockLinear || | 252 | ASSERT_MSG(tic_entry.header_version == Texture::TICHeaderVersion::BlockLinear || |
| 222 | tic_entry.header_version == Texture::TICHeaderVersion::Pitch, | 253 | tic_entry.header_version == Texture::TICHeaderVersion::Pitch, |
| @@ -243,10 +274,10 @@ Texture::TSCEntry Maxwell3D::GetTSCEntry(u32 tsc_index) const { | |||
| 243 | GPUVAddr tsc_base_address = regs.tsc.TSCAddress(); | 274 | GPUVAddr tsc_base_address = regs.tsc.TSCAddress(); |
| 244 | 275 | ||
| 245 | GPUVAddr tsc_address_gpu = tsc_base_address + tsc_index * sizeof(Texture::TSCEntry); | 276 | GPUVAddr tsc_address_gpu = tsc_base_address + tsc_index * sizeof(Texture::TSCEntry); |
| 246 | VAddr tsc_address_cpu = memory_manager.PhysicalToVirtualAddress(tsc_address_gpu); | 277 | boost::optional<VAddr> tsc_address_cpu = memory_manager.GpuToCpuAddress(tsc_address_gpu); |
| 247 | 278 | ||
| 248 | Texture::TSCEntry tsc_entry; | 279 | Texture::TSCEntry tsc_entry; |
| 249 | Memory::ReadBlock(tsc_address_cpu, &tsc_entry, sizeof(Texture::TSCEntry)); | 280 | Memory::ReadBlock(*tsc_address_cpu, &tsc_entry, sizeof(Texture::TSCEntry)); |
| 250 | return tsc_entry; | 281 | return tsc_entry; |
| 251 | } | 282 | } |
| 252 | 283 | ||
| @@ -268,7 +299,7 @@ std::vector<Texture::FullTextureInfo> Maxwell3D::GetStageTextures(Regs::ShaderSt | |||
| 268 | current_texture < tex_info_buffer_end; current_texture += sizeof(Texture::TextureHandle)) { | 299 | current_texture < tex_info_buffer_end; current_texture += sizeof(Texture::TextureHandle)) { |
| 269 | 300 | ||
| 270 | Texture::TextureHandle tex_handle{ | 301 | Texture::TextureHandle tex_handle{ |
| 271 | Memory::Read32(memory_manager.PhysicalToVirtualAddress(current_texture))}; | 302 | Memory::Read32(*memory_manager.GpuToCpuAddress(current_texture))}; |
| 272 | 303 | ||
| 273 | Texture::FullTextureInfo tex_info{}; | 304 | Texture::FullTextureInfo tex_info{}; |
| 274 | // TODO(Subv): Use the shader to determine which textures are actually accessed. | 305 | // TODO(Subv): Use the shader to determine which textures are actually accessed. |
diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h index d4fcedace..5cf62fb01 100644 --- a/src/video_core/engines/maxwell_3d.h +++ b/src/video_core/engines/maxwell_3d.h | |||
| @@ -31,7 +31,7 @@ public: | |||
| 31 | /// Register structure of the Maxwell3D engine. | 31 | /// Register structure of the Maxwell3D engine. |
| 32 | /// TODO(Subv): This structure will need to be made bigger as more registers are discovered. | 32 | /// TODO(Subv): This structure will need to be made bigger as more registers are discovered. |
| 33 | struct Regs { | 33 | struct Regs { |
| 34 | static constexpr size_t NUM_REGS = 0xE36; | 34 | static constexpr size_t NUM_REGS = 0xE00; |
| 35 | 35 | ||
| 36 | static constexpr size_t NumRenderTargets = 8; | 36 | static constexpr size_t NumRenderTargets = 8; |
| 37 | static constexpr size_t NumViewports = 16; | 37 | static constexpr size_t NumViewports = 16; |
| @@ -46,6 +46,29 @@ public: | |||
| 46 | enum class QueryMode : u32 { | 46 | enum class QueryMode : u32 { |
| 47 | Write = 0, | 47 | Write = 0, |
| 48 | Sync = 1, | 48 | Sync = 1, |
| 49 | // TODO(Subv): It is currently unknown what the difference between method 2 and method 0 | ||
| 50 | // is. | ||
| 51 | Write2 = 2, | ||
| 52 | }; | ||
| 53 | |||
| 54 | enum class QueryUnit : u32 { | ||
| 55 | VFetch = 1, | ||
| 56 | VP = 2, | ||
| 57 | Rast = 4, | ||
| 58 | StrmOut = 5, | ||
| 59 | GP = 6, | ||
| 60 | ZCull = 7, | ||
| 61 | Prop = 10, | ||
| 62 | Crop = 15, | ||
| 63 | }; | ||
| 64 | |||
| 65 | enum class QuerySelect : u32 { | ||
| 66 | Zero = 0, | ||
| 67 | }; | ||
| 68 | |||
| 69 | enum class QuerySyncCondition : u32 { | ||
| 70 | NotEqual = 0, | ||
| 71 | GreaterThan = 1, | ||
| 49 | }; | 72 | }; |
| 50 | 73 | ||
| 51 | enum class ShaderProgram : u32 { | 74 | enum class ShaderProgram : u32 { |
| @@ -299,7 +322,15 @@ public: | |||
| 299 | 322 | ||
| 300 | union { | 323 | union { |
| 301 | struct { | 324 | struct { |
| 302 | INSERT_PADDING_WORDS(0x200); | 325 | INSERT_PADDING_WORDS(0x45); |
| 326 | |||
| 327 | struct { | ||
| 328 | INSERT_PADDING_WORDS(1); | ||
| 329 | u32 data; | ||
| 330 | u32 entry; | ||
| 331 | } macros; | ||
| 332 | |||
| 333 | INSERT_PADDING_WORDS(0x1B8); | ||
| 303 | 334 | ||
| 304 | struct { | 335 | struct { |
| 305 | u32 address_high; | 336 | u32 address_high; |
| @@ -476,7 +507,10 @@ public: | |||
| 476 | u32 raw; | 507 | u32 raw; |
| 477 | BitField<0, 2, QueryMode> mode; | 508 | BitField<0, 2, QueryMode> mode; |
| 478 | BitField<4, 1, u32> fence; | 509 | BitField<4, 1, u32> fence; |
| 479 | BitField<12, 4, u32> unit; | 510 | BitField<12, 4, QueryUnit> unit; |
| 511 | BitField<16, 1, QuerySyncCondition> sync_cond; | ||
| 512 | BitField<23, 5, QuerySelect> select; | ||
| 513 | BitField<28, 1, u32> short_query; | ||
| 480 | } query_get; | 514 | } query_get; |
| 481 | 515 | ||
| 482 | GPUVAddr QueryAddress() const { | 516 | GPUVAddr QueryAddress() const { |
| @@ -500,6 +534,11 @@ public: | |||
| 500 | return static_cast<GPUVAddr>((static_cast<GPUVAddr>(start_high) << 32) | | 534 | return static_cast<GPUVAddr>((static_cast<GPUVAddr>(start_high) << 32) | |
| 501 | start_low); | 535 | start_low); |
| 502 | } | 536 | } |
| 537 | |||
| 538 | bool IsEnabled() const { | ||
| 539 | return enable != 0 && StartAddress() != 0; | ||
| 540 | } | ||
| 541 | |||
| 503 | } vertex_array[NumVertexArrays]; | 542 | } vertex_array[NumVertexArrays]; |
| 504 | 543 | ||
| 505 | Blend blend; | 544 | Blend blend; |
| @@ -574,7 +613,7 @@ public: | |||
| 574 | u32 size[MaxShaderStage]; | 613 | u32 size[MaxShaderStage]; |
| 575 | } tex_info_buffers; | 614 | } tex_info_buffers; |
| 576 | 615 | ||
| 577 | INSERT_PADDING_WORDS(0x102); | 616 | INSERT_PADDING_WORDS(0xCC); |
| 578 | }; | 617 | }; |
| 579 | std::array<u32, NUM_REGS> reg_array; | 618 | std::array<u32, NUM_REGS> reg_array; |
| 580 | }; | 619 | }; |
| @@ -606,9 +645,6 @@ public: | |||
| 606 | /// Write the value to the register identified by method. | 645 | /// Write the value to the register identified by method. |
| 607 | void WriteReg(u32 method, u32 value, u32 remaining_params); | 646 | void WriteReg(u32 method, u32 value, u32 remaining_params); |
| 608 | 647 | ||
| 609 | /// Uploads the code for a GPU macro program associated with the specified entry. | ||
| 610 | void SubmitMacroCode(u32 entry, std::vector<u32> code); | ||
| 611 | |||
| 612 | /// Returns a list of enabled textures for the specified shader stage. | 648 | /// Returns a list of enabled textures for the specified shader stage. |
| 613 | std::vector<Texture::FullTextureInfo> GetStageTextures(Regs::ShaderStage stage) const; | 649 | std::vector<Texture::FullTextureInfo> GetStageTextures(Regs::ShaderStage stage) const; |
| 614 | 650 | ||
| @@ -639,6 +675,9 @@ private: | |||
| 639 | */ | 675 | */ |
| 640 | void CallMacroMethod(u32 method, std::vector<u32> parameters); | 676 | void CallMacroMethod(u32 method, std::vector<u32> parameters); |
| 641 | 677 | ||
| 678 | /// Handles writes to the macro uploading registers. | ||
| 679 | void ProcessMacroUpload(u32 data); | ||
| 680 | |||
| 642 | /// Handles a write to the QUERY_GET register. | 681 | /// Handles a write to the QUERY_GET register. |
| 643 | void ProcessQueryGet(); | 682 | void ProcessQueryGet(); |
| 644 | 683 | ||
| @@ -656,6 +695,7 @@ private: | |||
| 656 | static_assert(offsetof(Maxwell3D::Regs, field_name) == position * 4, \ | 695 | static_assert(offsetof(Maxwell3D::Regs, field_name) == position * 4, \ |
| 657 | "Field " #field_name " has invalid position") | 696 | "Field " #field_name " has invalid position") |
| 658 | 697 | ||
| 698 | ASSERT_REG_POSITION(macros, 0x45); | ||
| 659 | ASSERT_REG_POSITION(rt, 0x200); | 699 | ASSERT_REG_POSITION(rt, 0x200); |
| 660 | ASSERT_REG_POSITION(viewport_transform[0], 0x280); | 700 | ASSERT_REG_POSITION(viewport_transform[0], 0x280); |
| 661 | ASSERT_REG_POSITION(viewport, 0x300); | 701 | ASSERT_REG_POSITION(viewport, 0x300); |
diff --git a/src/video_core/engines/shader_bytecode.h b/src/video_core/engines/shader_bytecode.h index 5a006aee5..f4d11fa5d 100644 --- a/src/video_core/engines/shader_bytecode.h +++ b/src/video_core/engines/shader_bytecode.h | |||
| @@ -214,6 +214,20 @@ union Instruction { | |||
| 214 | BitField<56, 1, u64> neg_b; | 214 | BitField<56, 1, u64> neg_b; |
| 215 | } fsetp; | 215 | } fsetp; |
| 216 | 216 | ||
| 217 | union { | ||
| 218 | BitField<39, 3, u64> pred39; | ||
| 219 | BitField<42, 1, u64> neg_pred; | ||
| 220 | BitField<43, 1, u64> neg_a; | ||
| 221 | BitField<44, 1, u64> abs_b; | ||
| 222 | BitField<45, 2, PredOperation> op; | ||
| 223 | BitField<48, 4, PredCondition> cond; | ||
| 224 | BitField<53, 1, u64> neg_b; | ||
| 225 | BitField<54, 1, u64> abs_a; | ||
| 226 | BitField<52, 1, u64> bf; | ||
| 227 | BitField<55, 1, u64> ftz; | ||
| 228 | BitField<56, 1, u64> neg_imm; | ||
| 229 | } fset; | ||
| 230 | |||
| 217 | BitField<61, 1, u64> is_b_imm; | 231 | BitField<61, 1, u64> is_b_imm; |
| 218 | BitField<60, 1, u64> is_b_gpr; | 232 | BitField<60, 1, u64> is_b_gpr; |
| 219 | BitField<59, 1, u64> is_c_gpr; | 233 | BitField<59, 1, u64> is_c_gpr; |
| @@ -261,6 +275,9 @@ public: | |||
| 261 | I2F_C, | 275 | I2F_C, |
| 262 | I2F_R, | 276 | I2F_R, |
| 263 | I2F_IMM, | 277 | I2F_IMM, |
| 278 | I2I_C, | ||
| 279 | I2I_R, | ||
| 280 | I2I_IMM, | ||
| 264 | LOP32I, | 281 | LOP32I, |
| 265 | MOV_C, | 282 | MOV_C, |
| 266 | MOV_R, | 283 | MOV_R, |
| @@ -272,6 +289,9 @@ public: | |||
| 272 | FSETP_C, // Set Predicate | 289 | FSETP_C, // Set Predicate |
| 273 | FSETP_R, | 290 | FSETP_R, |
| 274 | FSETP_IMM, | 291 | FSETP_IMM, |
| 292 | FSET_C, | ||
| 293 | FSET_R, | ||
| 294 | FSET_IMM, | ||
| 275 | ISETP_C, | 295 | ISETP_C, |
| 276 | ISETP_IMM, | 296 | ISETP_IMM, |
| 277 | ISETP_R, | 297 | ISETP_R, |
| @@ -283,8 +303,9 @@ public: | |||
| 283 | Ffma, | 303 | Ffma, |
| 284 | Flow, | 304 | Flow, |
| 285 | Memory, | 305 | Memory, |
| 286 | FloatPredicate, | 306 | FloatSet, |
| 287 | IntegerPredicate, | 307 | FloatSetPredicate, |
| 308 | IntegerSetPredicate, | ||
| 288 | Unknown, | 309 | Unknown, |
| 289 | }; | 310 | }; |
| 290 | 311 | ||
| @@ -409,6 +430,9 @@ private: | |||
| 409 | INST("0100110010111---", Id::I2F_C, Type::Arithmetic, "I2F_C"), | 430 | INST("0100110010111---", Id::I2F_C, Type::Arithmetic, "I2F_C"), |
| 410 | INST("0101110010111---", Id::I2F_R, Type::Arithmetic, "I2F_R"), | 431 | INST("0101110010111---", Id::I2F_R, Type::Arithmetic, "I2F_R"), |
| 411 | INST("0011100-10111---", Id::I2F_IMM, Type::Arithmetic, "I2F_IMM"), | 432 | INST("0011100-10111---", Id::I2F_IMM, Type::Arithmetic, "I2F_IMM"), |
| 433 | INST("0100110011100---", Id::I2I_C, Type::Arithmetic, "I2I_C"), | ||
| 434 | INST("0101110011100---", Id::I2I_R, Type::Arithmetic, "I2I_R"), | ||
| 435 | INST("01110001-1000---", Id::I2I_IMM, Type::Arithmetic, "I2I_IMM"), | ||
| 412 | INST("000001----------", Id::LOP32I, Type::Arithmetic, "LOP32I"), | 436 | INST("000001----------", Id::LOP32I, Type::Arithmetic, "LOP32I"), |
| 413 | INST("0100110010011---", Id::MOV_C, Type::Arithmetic, "MOV_C"), | 437 | INST("0100110010011---", Id::MOV_C, Type::Arithmetic, "MOV_C"), |
| 414 | INST("0101110010011---", Id::MOV_R, Type::Arithmetic, "MOV_R"), | 438 | INST("0101110010011---", Id::MOV_R, Type::Arithmetic, "MOV_R"), |
| @@ -417,12 +441,15 @@ private: | |||
| 417 | INST("0100110000101---", Id::SHR_C, Type::Arithmetic, "SHR_C"), | 441 | INST("0100110000101---", Id::SHR_C, Type::Arithmetic, "SHR_C"), |
| 418 | INST("0101110000101---", Id::SHR_R, Type::Arithmetic, "SHR_R"), | 442 | INST("0101110000101---", Id::SHR_R, Type::Arithmetic, "SHR_R"), |
| 419 | INST("0011100-00101---", Id::SHR_IMM, Type::Arithmetic, "SHR_IMM"), | 443 | INST("0011100-00101---", Id::SHR_IMM, Type::Arithmetic, "SHR_IMM"), |
| 420 | INST("010010111011----", Id::FSETP_C, Type::FloatPredicate, "FSETP_C"), | 444 | INST("01011000--------", Id::FSET_R, Type::FloatSet, "FSET_R"), |
| 421 | INST("010110111011----", Id::FSETP_R, Type::FloatPredicate, "FSETP_R"), | 445 | INST("0100100---------", Id::FSET_C, Type::FloatSet, "FSET_C"), |
| 422 | INST("0011011-1011----", Id::FSETP_IMM, Type::FloatPredicate, "FSETP_IMM"), | 446 | INST("0011000---------", Id::FSET_IMM, Type::FloatSet, "FSET_IMM"), |
| 423 | INST("010010110110----", Id::ISETP_C, Type::IntegerPredicate, "ISETP_C"), | 447 | INST("010010111011----", Id::FSETP_C, Type::FloatSetPredicate, "FSETP_C"), |
| 424 | INST("010110110110----", Id::ISETP_R, Type::IntegerPredicate, "ISETP_R"), | 448 | INST("010110111011----", Id::FSETP_R, Type::FloatSetPredicate, "FSETP_R"), |
| 425 | INST("0011011-0110----", Id::ISETP_IMM, Type::IntegerPredicate, "ISETP_IMM"), | 449 | INST("0011011-1011----", Id::FSETP_IMM, Type::FloatSetPredicate, "FSETP_IMM"), |
| 450 | INST("010010110110----", Id::ISETP_C, Type::IntegerSetPredicate, "ISETP_C"), | ||
| 451 | INST("010110110110----", Id::ISETP_R, Type::IntegerSetPredicate, "ISETP_R"), | ||
| 452 | INST("0011011-0110----", Id::ISETP_IMM, Type::IntegerSetPredicate, "ISETP_IMM"), | ||
| 426 | }; | 453 | }; |
| 427 | #undef INST | 454 | #undef INST |
| 428 | std::stable_sort(table.begin(), table.end(), [](const auto& a, const auto& b) { | 455 | std::stable_sort(table.begin(), table.end(), [](const auto& a, const auto& b) { |
diff --git a/src/video_core/gpu.cpp b/src/video_core/gpu.cpp index 9463cd5d6..9eb143918 100644 --- a/src/video_core/gpu.cpp +++ b/src/video_core/gpu.cpp | |||
| @@ -12,7 +12,7 @@ namespace Tegra { | |||
| 12 | GPU::GPU() { | 12 | GPU::GPU() { |
| 13 | memory_manager = std::make_unique<MemoryManager>(); | 13 | memory_manager = std::make_unique<MemoryManager>(); |
| 14 | maxwell_3d = std::make_unique<Engines::Maxwell3D>(*memory_manager); | 14 | maxwell_3d = std::make_unique<Engines::Maxwell3D>(*memory_manager); |
| 15 | fermi_2d = std::make_unique<Engines::Fermi2D>(); | 15 | fermi_2d = std::make_unique<Engines::Fermi2D>(*memory_manager); |
| 16 | maxwell_compute = std::make_unique<Engines::MaxwellCompute>(); | 16 | maxwell_compute = std::make_unique<Engines::MaxwellCompute>(); |
| 17 | } | 17 | } |
| 18 | 18 | ||
| @@ -22,4 +22,16 @@ const Tegra::Engines::Maxwell3D& GPU::Get3DEngine() const { | |||
| 22 | return *maxwell_3d; | 22 | return *maxwell_3d; |
| 23 | } | 23 | } |
| 24 | 24 | ||
| 25 | u32 RenderTargetBytesPerPixel(RenderTargetFormat format) { | ||
| 26 | ASSERT(format != RenderTargetFormat::NONE); | ||
| 27 | |||
| 28 | switch (format) { | ||
| 29 | case RenderTargetFormat::RGBA8_UNORM: | ||
| 30 | case RenderTargetFormat::RGB10_A2_UNORM: | ||
| 31 | return 4; | ||
| 32 | default: | ||
| 33 | UNIMPLEMENTED_MSG("Unimplemented render target format %u", static_cast<u32>(format)); | ||
| 34 | } | ||
| 35 | } | ||
| 36 | |||
| 25 | } // namespace Tegra | 37 | } // namespace Tegra |
diff --git a/src/video_core/gpu.h b/src/video_core/gpu.h index 2888daedc..f168a5171 100644 --- a/src/video_core/gpu.h +++ b/src/video_core/gpu.h | |||
| @@ -21,6 +21,9 @@ enum class RenderTargetFormat : u32 { | |||
| 21 | RGBA8_SRGB = 0xD6, | 21 | RGBA8_SRGB = 0xD6, |
| 22 | }; | 22 | }; |
| 23 | 23 | ||
| 24 | /// Returns the number of bytes per pixel of each rendertarget format. | ||
| 25 | u32 RenderTargetBytesPerPixel(RenderTargetFormat format); | ||
| 26 | |||
| 24 | class DebugContext; | 27 | class DebugContext; |
| 25 | 28 | ||
| 26 | /** | 29 | /** |
| @@ -86,8 +89,6 @@ public: | |||
| 86 | } | 89 | } |
| 87 | 90 | ||
| 88 | private: | 91 | private: |
| 89 | static constexpr u32 InvalidGraphMacroEntry = 0xFFFFFFFF; | ||
| 90 | |||
| 91 | /// Writes a single register in the engine bound to the specified subchannel | 92 | /// Writes a single register in the engine bound to the specified subchannel |
| 92 | void WriteReg(u32 method, u32 subchannel, u32 value, u32 remaining_params); | 93 | void WriteReg(u32 method, u32 subchannel, u32 value, u32 remaining_params); |
| 93 | 94 | ||
| @@ -100,11 +101,6 @@ private: | |||
| 100 | std::unique_ptr<Engines::Fermi2D> fermi_2d; | 101 | std::unique_ptr<Engines::Fermi2D> fermi_2d; |
| 101 | /// Compute engine | 102 | /// Compute engine |
| 102 | std::unique_ptr<Engines::MaxwellCompute> maxwell_compute; | 103 | std::unique_ptr<Engines::MaxwellCompute> maxwell_compute; |
| 103 | |||
| 104 | /// Entry of the macro that is currently being uploaded | ||
| 105 | u32 current_macro_entry = InvalidGraphMacroEntry; | ||
| 106 | /// Code being uploaded for the current macro | ||
| 107 | std::vector<u32> current_macro_code; | ||
| 108 | }; | 104 | }; |
| 109 | 105 | ||
| 110 | } // namespace Tegra | 106 | } // namespace Tegra |
diff --git a/src/video_core/memory_manager.cpp b/src/video_core/memory_manager.cpp index 2789a4ca1..25984439d 100644 --- a/src/video_core/memory_manager.cpp +++ b/src/video_core/memory_manager.cpp | |||
| @@ -2,109 +2,118 @@ | |||
| 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 "common/alignment.h" | ||
| 5 | #include "common/assert.h" | 6 | #include "common/assert.h" |
| 6 | #include "video_core/memory_manager.h" | 7 | #include "video_core/memory_manager.h" |
| 7 | 8 | ||
| 8 | namespace Tegra { | 9 | namespace Tegra { |
| 9 | 10 | ||
| 10 | PAddr MemoryManager::AllocateSpace(u64 size, u64 align) { | 11 | GPUVAddr MemoryManager::AllocateSpace(u64 size, u64 align) { |
| 11 | boost::optional<PAddr> paddr = FindFreeBlock(size, align); | 12 | boost::optional<GPUVAddr> gpu_addr = FindFreeBlock(size, align); |
| 12 | ASSERT(paddr); | 13 | ASSERT(gpu_addr); |
| 13 | 14 | ||
| 14 | for (u64 offset = 0; offset < size; offset += Memory::PAGE_SIZE) { | 15 | for (u64 offset = 0; offset < size; offset += PAGE_SIZE) { |
| 15 | PageSlot(*paddr + offset) = static_cast<u64>(PageStatus::Allocated); | 16 | ASSERT(PageSlot(*gpu_addr + offset) == static_cast<u64>(PageStatus::Unmapped)); |
| 17 | PageSlot(*gpu_addr + offset) = static_cast<u64>(PageStatus::Allocated); | ||
| 16 | } | 18 | } |
| 17 | 19 | ||
| 18 | return *paddr; | 20 | return *gpu_addr; |
| 19 | } | 21 | } |
| 20 | 22 | ||
| 21 | PAddr MemoryManager::AllocateSpace(PAddr paddr, u64 size, u64 align) { | 23 | GPUVAddr MemoryManager::AllocateSpace(GPUVAddr gpu_addr, u64 size, u64 align) { |
| 22 | for (u64 offset = 0; offset < size; offset += Memory::PAGE_SIZE) { | 24 | for (u64 offset = 0; offset < size; offset += PAGE_SIZE) { |
| 23 | if (IsPageMapped(paddr + offset)) { | 25 | ASSERT(PageSlot(gpu_addr + offset) == static_cast<u64>(PageStatus::Unmapped)); |
| 24 | return AllocateSpace(size, align); | 26 | PageSlot(gpu_addr + offset) = static_cast<u64>(PageStatus::Allocated); |
| 25 | } | ||
| 26 | } | ||
| 27 | |||
| 28 | for (u64 offset = 0; offset < size; offset += Memory::PAGE_SIZE) { | ||
| 29 | PageSlot(paddr + offset) = static_cast<u64>(PageStatus::Allocated); | ||
| 30 | } | 27 | } |
| 31 | 28 | ||
| 32 | return paddr; | 29 | return gpu_addr; |
| 33 | } | 30 | } |
| 34 | 31 | ||
| 35 | PAddr MemoryManager::MapBufferEx(VAddr vaddr, u64 size) { | 32 | GPUVAddr MemoryManager::MapBufferEx(VAddr cpu_addr, u64 size) { |
| 36 | vaddr &= ~Memory::PAGE_MASK; | 33 | boost::optional<GPUVAddr> gpu_addr = FindFreeBlock(size, PAGE_SIZE); |
| 37 | 34 | ASSERT(gpu_addr); | |
| 38 | boost::optional<PAddr> paddr = FindFreeBlock(size); | ||
| 39 | ASSERT(paddr); | ||
| 40 | 35 | ||
| 41 | for (u64 offset = 0; offset < size; offset += Memory::PAGE_SIZE) { | 36 | for (u64 offset = 0; offset < size; offset += PAGE_SIZE) { |
| 42 | PageSlot(*paddr + offset) = vaddr + offset; | 37 | ASSERT(PageSlot(*gpu_addr + offset) == static_cast<u64>(PageStatus::Unmapped)); |
| 38 | PageSlot(*gpu_addr + offset) = cpu_addr + offset; | ||
| 43 | } | 39 | } |
| 44 | 40 | ||
| 45 | return *paddr; | 41 | MappedRegion region{cpu_addr, *gpu_addr, size}; |
| 42 | mapped_regions.push_back(region); | ||
| 43 | |||
| 44 | return *gpu_addr; | ||
| 46 | } | 45 | } |
| 47 | 46 | ||
| 48 | PAddr MemoryManager::MapBufferEx(VAddr vaddr, PAddr paddr, u64 size) { | 47 | GPUVAddr MemoryManager::MapBufferEx(VAddr cpu_addr, GPUVAddr gpu_addr, u64 size) { |
| 49 | vaddr &= ~Memory::PAGE_MASK; | 48 | ASSERT((gpu_addr & PAGE_MASK) == 0); |
| 50 | paddr &= ~Memory::PAGE_MASK; | ||
| 51 | 49 | ||
| 52 | for (u64 offset = 0; offset < size; offset += Memory::PAGE_SIZE) { | 50 | for (u64 offset = 0; offset < size; offset += PAGE_SIZE) { |
| 53 | if (PageSlot(paddr + offset) != static_cast<u64>(PageStatus::Allocated)) { | 51 | ASSERT(PageSlot(gpu_addr + offset) == static_cast<u64>(PageStatus::Allocated)); |
| 54 | return MapBufferEx(vaddr, size); | 52 | PageSlot(gpu_addr + offset) = cpu_addr + offset; |
| 55 | } | ||
| 56 | } | 53 | } |
| 57 | 54 | ||
| 58 | for (u64 offset = 0; offset < size; offset += Memory::PAGE_SIZE) { | 55 | MappedRegion region{cpu_addr, gpu_addr, size}; |
| 59 | PageSlot(paddr + offset) = vaddr + offset; | 56 | mapped_regions.push_back(region); |
| 60 | } | ||
| 61 | 57 | ||
| 62 | return paddr; | 58 | return gpu_addr; |
| 63 | } | 59 | } |
| 64 | 60 | ||
| 65 | boost::optional<PAddr> MemoryManager::FindFreeBlock(u64 size, u64 align) { | 61 | boost::optional<GPUVAddr> MemoryManager::FindFreeBlock(u64 size, u64 align) { |
| 66 | PAddr paddr{}; | 62 | GPUVAddr gpu_addr = 0; |
| 67 | u64 free_space{}; | 63 | u64 free_space = 0; |
| 68 | align = (align + Memory::PAGE_MASK) & ~Memory::PAGE_MASK; | 64 | align = (align + PAGE_MASK) & ~PAGE_MASK; |
| 69 | 65 | ||
| 70 | while (paddr + free_space < MAX_ADDRESS) { | 66 | while (gpu_addr + free_space < MAX_ADDRESS) { |
| 71 | if (!IsPageMapped(paddr + free_space)) { | 67 | if (!IsPageMapped(gpu_addr + free_space)) { |
| 72 | free_space += Memory::PAGE_SIZE; | 68 | free_space += PAGE_SIZE; |
| 73 | if (free_space >= size) { | 69 | if (free_space >= size) { |
| 74 | return paddr; | 70 | return gpu_addr; |
| 75 | } | 71 | } |
| 76 | } else { | 72 | } else { |
| 77 | paddr += free_space + Memory::PAGE_SIZE; | 73 | gpu_addr += free_space + PAGE_SIZE; |
| 78 | free_space = 0; | 74 | free_space = 0; |
| 79 | const u64 remainder{paddr % align}; | 75 | gpu_addr = Common::AlignUp(gpu_addr, align); |
| 80 | if (!remainder) { | ||
| 81 | paddr = (paddr - remainder) + align; | ||
| 82 | } | ||
| 83 | } | 76 | } |
| 84 | } | 77 | } |
| 85 | 78 | ||
| 86 | return {}; | 79 | return {}; |
| 87 | } | 80 | } |
| 88 | 81 | ||
| 89 | VAddr MemoryManager::PhysicalToVirtualAddress(PAddr paddr) { | 82 | boost::optional<VAddr> MemoryManager::GpuToCpuAddress(GPUVAddr gpu_addr) { |
| 90 | VAddr base_addr = PageSlot(paddr); | 83 | VAddr base_addr = PageSlot(gpu_addr); |
| 91 | ASSERT(base_addr != static_cast<u64>(PageStatus::Unmapped)); | 84 | ASSERT(base_addr != static_cast<u64>(PageStatus::Unmapped)); |
| 92 | return base_addr + (paddr & Memory::PAGE_MASK); | 85 | |
| 86 | if (base_addr == static_cast<u64>(PageStatus::Allocated)) { | ||
| 87 | return {}; | ||
| 88 | } | ||
| 89 | |||
| 90 | return base_addr + (gpu_addr & PAGE_MASK); | ||
| 91 | } | ||
| 92 | |||
| 93 | std::vector<GPUVAddr> MemoryManager::CpuToGpuAddress(VAddr cpu_addr) const { | ||
| 94 | std::vector<GPUVAddr> results; | ||
| 95 | for (const auto& region : mapped_regions) { | ||
| 96 | if (cpu_addr >= region.cpu_addr && cpu_addr < (region.cpu_addr + region.size)) { | ||
| 97 | u64 offset = cpu_addr - region.cpu_addr; | ||
| 98 | results.push_back(region.gpu_addr + offset); | ||
| 99 | } | ||
| 100 | } | ||
| 101 | return results; | ||
| 93 | } | 102 | } |
| 94 | 103 | ||
| 95 | bool MemoryManager::IsPageMapped(PAddr paddr) { | 104 | bool MemoryManager::IsPageMapped(GPUVAddr gpu_addr) { |
| 96 | return PageSlot(paddr) != static_cast<u64>(PageStatus::Unmapped); | 105 | return PageSlot(gpu_addr) != static_cast<u64>(PageStatus::Unmapped); |
| 97 | } | 106 | } |
| 98 | 107 | ||
| 99 | VAddr& MemoryManager::PageSlot(PAddr paddr) { | 108 | VAddr& MemoryManager::PageSlot(GPUVAddr gpu_addr) { |
| 100 | auto& block = page_table[(paddr >> (Memory::PAGE_BITS + PAGE_TABLE_BITS)) & PAGE_TABLE_MASK]; | 109 | auto& block = page_table[(gpu_addr >> (PAGE_BITS + PAGE_TABLE_BITS)) & PAGE_TABLE_MASK]; |
| 101 | if (!block) { | 110 | if (!block) { |
| 102 | block = std::make_unique<PageBlock>(); | 111 | block = std::make_unique<PageBlock>(); |
| 103 | for (unsigned index = 0; index < PAGE_BLOCK_SIZE; index++) { | 112 | for (unsigned index = 0; index < PAGE_BLOCK_SIZE; index++) { |
| 104 | (*block)[index] = static_cast<u64>(PageStatus::Unmapped); | 113 | (*block)[index] = static_cast<u64>(PageStatus::Unmapped); |
| 105 | } | 114 | } |
| 106 | } | 115 | } |
| 107 | return (*block)[(paddr >> Memory::PAGE_BITS) & PAGE_BLOCK_MASK]; | 116 | return (*block)[(gpu_addr >> PAGE_BITS) & PAGE_BLOCK_MASK]; |
| 108 | } | 117 | } |
| 109 | 118 | ||
| 110 | } // namespace Tegra | 119 | } // namespace Tegra |
diff --git a/src/video_core/memory_manager.h b/src/video_core/memory_manager.h index 47da7acd6..08140c83a 100644 --- a/src/video_core/memory_manager.h +++ b/src/video_core/memory_manager.h | |||
| @@ -6,8 +6,11 @@ | |||
| 6 | 6 | ||
| 7 | #include <array> | 7 | #include <array> |
| 8 | #include <memory> | 8 | #include <memory> |
| 9 | #include <vector> | ||
| 10 | |||
| 11 | #include <boost/optional.hpp> | ||
| 12 | |||
| 9 | #include "common/common_types.h" | 13 | #include "common/common_types.h" |
| 10 | #include "core/memory.h" | ||
| 11 | 14 | ||
| 12 | namespace Tegra { | 15 | namespace Tegra { |
| 13 | 16 | ||
| @@ -18,16 +21,21 @@ class MemoryManager final { | |||
| 18 | public: | 21 | public: |
| 19 | MemoryManager() = default; | 22 | MemoryManager() = default; |
| 20 | 23 | ||
| 21 | PAddr AllocateSpace(u64 size, u64 align); | 24 | GPUVAddr AllocateSpace(u64 size, u64 align); |
| 22 | PAddr AllocateSpace(PAddr paddr, u64 size, u64 align); | 25 | GPUVAddr AllocateSpace(GPUVAddr gpu_addr, u64 size, u64 align); |
| 23 | PAddr MapBufferEx(VAddr vaddr, u64 size); | 26 | GPUVAddr MapBufferEx(VAddr cpu_addr, u64 size); |
| 24 | PAddr MapBufferEx(VAddr vaddr, PAddr paddr, u64 size); | 27 | GPUVAddr MapBufferEx(VAddr cpu_addr, GPUVAddr gpu_addr, u64 size); |
| 25 | VAddr PhysicalToVirtualAddress(PAddr paddr); | 28 | boost::optional<VAddr> GpuToCpuAddress(GPUVAddr gpu_addr); |
| 29 | std::vector<GPUVAddr> CpuToGpuAddress(VAddr cpu_addr) const; | ||
| 30 | |||
| 31 | static constexpr u64 PAGE_BITS = 16; | ||
| 32 | static constexpr u64 PAGE_SIZE = 1 << PAGE_BITS; | ||
| 33 | static constexpr u64 PAGE_MASK = PAGE_SIZE - 1; | ||
| 26 | 34 | ||
| 27 | private: | 35 | private: |
| 28 | boost::optional<PAddr> FindFreeBlock(u64 size, u64 align = 1); | 36 | boost::optional<GPUVAddr> FindFreeBlock(u64 size, u64 align = 1); |
| 29 | bool IsPageMapped(PAddr paddr); | 37 | bool IsPageMapped(GPUVAddr gpu_addr); |
| 30 | VAddr& PageSlot(PAddr paddr); | 38 | VAddr& PageSlot(GPUVAddr gpu_addr); |
| 31 | 39 | ||
| 32 | enum class PageStatus : u64 { | 40 | enum class PageStatus : u64 { |
| 33 | Unmapped = 0xFFFFFFFFFFFFFFFFULL, | 41 | Unmapped = 0xFFFFFFFFFFFFFFFFULL, |
| @@ -35,7 +43,7 @@ private: | |||
| 35 | }; | 43 | }; |
| 36 | 44 | ||
| 37 | static constexpr u64 MAX_ADDRESS{0x10000000000ULL}; | 45 | static constexpr u64 MAX_ADDRESS{0x10000000000ULL}; |
| 38 | static constexpr u64 PAGE_TABLE_BITS{14}; | 46 | static constexpr u64 PAGE_TABLE_BITS{10}; |
| 39 | static constexpr u64 PAGE_TABLE_SIZE{1 << PAGE_TABLE_BITS}; | 47 | static constexpr u64 PAGE_TABLE_SIZE{1 << PAGE_TABLE_BITS}; |
| 40 | static constexpr u64 PAGE_TABLE_MASK{PAGE_TABLE_SIZE - 1}; | 48 | static constexpr u64 PAGE_TABLE_MASK{PAGE_TABLE_SIZE - 1}; |
| 41 | static constexpr u64 PAGE_BLOCK_BITS{14}; | 49 | static constexpr u64 PAGE_BLOCK_BITS{14}; |
| @@ -44,6 +52,14 @@ private: | |||
| 44 | 52 | ||
| 45 | using PageBlock = std::array<VAddr, PAGE_BLOCK_SIZE>; | 53 | using PageBlock = std::array<VAddr, PAGE_BLOCK_SIZE>; |
| 46 | std::array<std::unique_ptr<PageBlock>, PAGE_TABLE_SIZE> page_table{}; | 54 | std::array<std::unique_ptr<PageBlock>, PAGE_TABLE_SIZE> page_table{}; |
| 55 | |||
| 56 | struct MappedRegion { | ||
| 57 | VAddr cpu_addr; | ||
| 58 | GPUVAddr gpu_addr; | ||
| 59 | u64 size; | ||
| 60 | }; | ||
| 61 | |||
| 62 | std::vector<MappedRegion> mapped_regions; | ||
| 47 | }; | 63 | }; |
| 48 | 64 | ||
| 49 | } // namespace Tegra | 65 | } // namespace Tegra |
diff --git a/src/video_core/rasterizer_interface.h b/src/video_core/rasterizer_interface.h index 36629dd11..f0e48a802 100644 --- a/src/video_core/rasterizer_interface.h +++ b/src/video_core/rasterizer_interface.h | |||
| @@ -6,6 +6,7 @@ | |||
| 6 | 6 | ||
| 7 | #include "common/common_types.h" | 7 | #include "common/common_types.h" |
| 8 | #include "video_core/gpu.h" | 8 | #include "video_core/gpu.h" |
| 9 | #include "video_core/memory_manager.h" | ||
| 9 | 10 | ||
| 10 | struct ScreenInfo; | 11 | struct ScreenInfo; |
| 11 | 12 | ||
| @@ -25,14 +26,14 @@ public: | |||
| 25 | virtual void FlushAll() = 0; | 26 | virtual void FlushAll() = 0; |
| 26 | 27 | ||
| 27 | /// Notify rasterizer that any caches of the specified region should be flushed to Switch memory | 28 | /// Notify rasterizer that any caches of the specified region should be flushed to Switch memory |
| 28 | virtual void FlushRegion(VAddr addr, u64 size) = 0; | 29 | virtual void FlushRegion(Tegra::GPUVAddr addr, u64 size) = 0; |
| 29 | 30 | ||
| 30 | /// Notify rasterizer that any caches of the specified region should be invalidated | 31 | /// Notify rasterizer that any caches of the specified region should be invalidated |
| 31 | virtual void InvalidateRegion(VAddr addr, u64 size) = 0; | 32 | virtual void InvalidateRegion(Tegra::GPUVAddr addr, u64 size) = 0; |
| 32 | 33 | ||
| 33 | /// Notify rasterizer that any caches of the specified region should be flushed to Switch memory | 34 | /// Notify rasterizer that any caches of the specified region should be flushed to Switch memory |
| 34 | /// and invalidated | 35 | /// and invalidated |
| 35 | virtual void FlushAndInvalidateRegion(VAddr addr, u64 size) = 0; | 36 | virtual void FlushAndInvalidateRegion(Tegra::GPUVAddr addr, u64 size) = 0; |
| 36 | 37 | ||
| 37 | /// Attempt to use a faster method to perform a display transfer with is_texture_copy = 0 | 38 | /// Attempt to use a faster method to perform a display transfer with is_texture_copy = 0 |
| 38 | virtual bool AccelerateDisplayTransfer(const void* config) { | 39 | virtual bool AccelerateDisplayTransfer(const void* config) { |
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 2d4a0d6db..9b3542e10 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp | |||
| @@ -116,7 +116,7 @@ RasterizerOpenGL::RasterizerOpenGL() { | |||
| 116 | 116 | ||
| 117 | glEnable(GL_BLEND); | 117 | glEnable(GL_BLEND); |
| 118 | 118 | ||
| 119 | LOG_CRITICAL(Render_OpenGL, "Sync fixed function OpenGL state here!"); | 119 | NGLOG_CRITICAL(Render_OpenGL, "Sync fixed function OpenGL state here!"); |
| 120 | } | 120 | } |
| 121 | 121 | ||
| 122 | RasterizerOpenGL::~RasterizerOpenGL() { | 122 | RasterizerOpenGL::~RasterizerOpenGL() { |
| @@ -127,7 +127,8 @@ RasterizerOpenGL::~RasterizerOpenGL() { | |||
| 127 | } | 127 | } |
| 128 | } | 128 | } |
| 129 | 129 | ||
| 130 | void RasterizerOpenGL::SetupVertexArray(u8* array_ptr, GLintptr buffer_offset) { | 130 | std::pair<u8*, GLintptr> RasterizerOpenGL::SetupVertexArrays(u8* array_ptr, |
| 131 | GLintptr buffer_offset) { | ||
| 131 | MICROPROFILE_SCOPE(OpenGL_VAO); | 132 | MICROPROFILE_SCOPE(OpenGL_VAO); |
| 132 | const auto& regs = Core::System().GetInstance().GPU().Maxwell3D().regs; | 133 | const auto& regs = Core::System().GetInstance().GPU().Maxwell3D().regs; |
| 133 | const auto& memory_manager = Core::System().GetInstance().GPU().memory_manager; | 134 | const auto& memory_manager = Core::System().GetInstance().GPU().memory_manager; |
| @@ -136,43 +137,58 @@ void RasterizerOpenGL::SetupVertexArray(u8* array_ptr, GLintptr buffer_offset) { | |||
| 136 | state.draw.vertex_buffer = stream_buffer->GetHandle(); | 137 | state.draw.vertex_buffer = stream_buffer->GetHandle(); |
| 137 | state.Apply(); | 138 | state.Apply(); |
| 138 | 139 | ||
| 139 | // TODO(bunnei): Add support for 1+ vertex arrays | 140 | // Upload all guest vertex arrays sequentially to our buffer |
| 140 | const auto& vertex_array{regs.vertex_array[0]}; | 141 | for (u32 index = 0; index < Maxwell::NumVertexArrays; ++index) { |
| 141 | const auto& vertex_array_limit{regs.vertex_array_limit[0]}; | 142 | const auto& vertex_array = regs.vertex_array[index]; |
| 142 | ASSERT_MSG(vertex_array.enable, "vertex array 0 is disabled?"); | 143 | if (!vertex_array.IsEnabled()) |
| 143 | ASSERT_MSG(!vertex_array.divisor, "vertex array 0 divisor is unimplemented!"); | 144 | continue; |
| 144 | for (unsigned index = 1; index < Maxwell::NumVertexArrays; ++index) { | 145 | |
| 145 | ASSERT_MSG(!regs.vertex_array[index].enable, "vertex array %d is unimplemented!", index); | 146 | const Tegra::GPUVAddr start = vertex_array.StartAddress(); |
| 147 | const Tegra::GPUVAddr end = regs.vertex_array_limit[index].LimitAddress(); | ||
| 148 | |||
| 149 | ASSERT(end > start); | ||
| 150 | u64 size = end - start + 1; | ||
| 151 | |||
| 152 | // Copy vertex array data | ||
| 153 | res_cache.FlushRegion(start, size, nullptr); | ||
| 154 | Memory::ReadBlock(*memory_manager->GpuToCpuAddress(start), array_ptr, size); | ||
| 155 | |||
| 156 | // Bind the vertex array to the buffer at the current offset. | ||
| 157 | glBindVertexBuffer(index, stream_buffer->GetHandle(), buffer_offset, vertex_array.stride); | ||
| 158 | |||
| 159 | ASSERT_MSG(vertex_array.divisor == 0, "Vertex buffer divisor unimplemented"); | ||
| 160 | |||
| 161 | array_ptr += size; | ||
| 162 | buffer_offset += size; | ||
| 146 | } | 163 | } |
| 147 | 164 | ||
| 148 | // Use the vertex array as-is, assumes that the data is formatted correctly for OpenGL. | 165 | // Use the vertex array as-is, assumes that the data is formatted correctly for OpenGL. |
| 149 | // Enables the first 16 vertex attributes always, as we don't know which ones are actually used | 166 | // Enables the first 16 vertex attributes always, as we don't know which ones are actually used |
| 150 | // until shader time. Note, Tegra technically supports 32, but we're cappinig this to 16 for now | 167 | // until shader time. Note, Tegra technically supports 32, but we're capping this to 16 for now |
| 151 | // to avoid OpenGL errors. | 168 | // to avoid OpenGL errors. |
| 169 | // TODO(Subv): Analyze the shader to identify which attributes are actually used and don't | ||
| 170 | // assume every shader uses them all. | ||
| 152 | for (unsigned index = 0; index < 16; ++index) { | 171 | for (unsigned index = 0; index < 16; ++index) { |
| 153 | auto& attrib = regs.vertex_attrib_format[index]; | 172 | auto& attrib = regs.vertex_attrib_format[index]; |
| 154 | NGLOG_DEBUG(HW_GPU, "vertex attrib {}, count={}, size={}, type={}, offset={}, normalize={}", | 173 | NGLOG_DEBUG(HW_GPU, "vertex attrib {}, count={}, size={}, type={}, offset={}, normalize={}", |
| 155 | index, attrib.ComponentCount(), attrib.SizeString(), attrib.TypeString(), | 174 | index, attrib.ComponentCount(), attrib.SizeString(), attrib.TypeString(), |
| 156 | attrib.offset.Value(), attrib.IsNormalized()); | 175 | attrib.offset.Value(), attrib.IsNormalized()); |
| 157 | 176 | ||
| 158 | glVertexAttribPointer(index, attrib.ComponentCount(), MaxwellToGL::VertexType(attrib), | 177 | auto& buffer = regs.vertex_array[attrib.buffer]; |
| 159 | attrib.IsNormalized() ? GL_TRUE : GL_FALSE, vertex_array.stride, | 178 | ASSERT(buffer.IsEnabled()); |
| 160 | reinterpret_cast<GLvoid*>(buffer_offset + attrib.offset)); | 179 | |
| 161 | glEnableVertexAttribArray(index); | 180 | glEnableVertexAttribArray(index); |
| 181 | glVertexAttribFormat(index, attrib.ComponentCount(), MaxwellToGL::VertexType(attrib), | ||
| 182 | attrib.IsNormalized() ? GL_TRUE : GL_FALSE, attrib.offset); | ||
| 183 | glVertexAttribBinding(index, attrib.buffer); | ||
| 184 | |||
| 162 | hw_vao_enabled_attributes[index] = true; | 185 | hw_vao_enabled_attributes[index] = true; |
| 163 | } | 186 | } |
| 164 | 187 | ||
| 165 | // Copy vertex array data | 188 | return {array_ptr, buffer_offset}; |
| 166 | const u64 data_size{vertex_array_limit.LimitAddress() - vertex_array.StartAddress() + 1}; | ||
| 167 | const VAddr data_addr{memory_manager->PhysicalToVirtualAddress(vertex_array.StartAddress())}; | ||
| 168 | res_cache.FlushRegion(data_addr, data_size, nullptr); | ||
| 169 | Memory::ReadBlock(data_addr, array_ptr, data_size); | ||
| 170 | |||
| 171 | array_ptr += data_size; | ||
| 172 | buffer_offset += data_size; | ||
| 173 | } | 189 | } |
| 174 | 190 | ||
| 175 | void RasterizerOpenGL::SetupShaders(u8* buffer_ptr, GLintptr buffer_offset, size_t ptr_pos) { | 191 | void RasterizerOpenGL::SetupShaders(u8* buffer_ptr, GLintptr buffer_offset) { |
| 176 | // Helper function for uploading uniform data | 192 | // Helper function for uploading uniform data |
| 177 | const auto copy_buffer = [&](GLuint handle, GLintptr offset, GLsizeiptr size) { | 193 | const auto copy_buffer = [&](GLuint handle, GLintptr offset, GLsizeiptr size) { |
| 178 | if (has_ARB_direct_state_access) { | 194 | if (has_ARB_direct_state_access) { |
| @@ -190,8 +206,6 @@ void RasterizerOpenGL::SetupShaders(u8* buffer_ptr, GLintptr buffer_offset, size | |||
| 190 | u32 current_constbuffer_bindpoint = 0; | 206 | u32 current_constbuffer_bindpoint = 0; |
| 191 | 207 | ||
| 192 | for (unsigned index = 1; index < Maxwell::MaxShaderProgram; ++index) { | 208 | for (unsigned index = 1; index < Maxwell::MaxShaderProgram; ++index) { |
| 193 | ptr_pos += sizeof(GLShader::MaxwellUniformData); | ||
| 194 | |||
| 195 | auto& shader_config = gpu.regs.shader_config[index]; | 209 | auto& shader_config = gpu.regs.shader_config[index]; |
| 196 | const Maxwell::ShaderProgram program{static_cast<Maxwell::ShaderProgram>(index)}; | 210 | const Maxwell::ShaderProgram program{static_cast<Maxwell::ShaderProgram>(index)}; |
| 197 | 211 | ||
| @@ -205,18 +219,21 @@ void RasterizerOpenGL::SetupShaders(u8* buffer_ptr, GLintptr buffer_offset, size | |||
| 205 | } | 219 | } |
| 206 | 220 | ||
| 207 | // Upload uniform data as one UBO per stage | 221 | // Upload uniform data as one UBO per stage |
| 208 | const GLintptr ubo_offset = buffer_offset + static_cast<GLintptr>(ptr_pos); | 222 | const GLintptr ubo_offset = buffer_offset; |
| 209 | copy_buffer(uniform_buffers[stage].handle, ubo_offset, | 223 | copy_buffer(uniform_buffers[stage].handle, ubo_offset, |
| 210 | sizeof(GLShader::MaxwellUniformData)); | 224 | sizeof(GLShader::MaxwellUniformData)); |
| 211 | GLShader::MaxwellUniformData* ub_ptr = | 225 | GLShader::MaxwellUniformData* ub_ptr = |
| 212 | reinterpret_cast<GLShader::MaxwellUniformData*>(&buffer_ptr[ptr_pos]); | 226 | reinterpret_cast<GLShader::MaxwellUniformData*>(buffer_ptr); |
| 213 | ub_ptr->SetFromRegs(gpu.state.shader_stages[stage]); | 227 | ub_ptr->SetFromRegs(gpu.state.shader_stages[stage]); |
| 214 | 228 | ||
| 229 | buffer_ptr += sizeof(GLShader::MaxwellUniformData); | ||
| 230 | buffer_offset += sizeof(GLShader::MaxwellUniformData); | ||
| 231 | |||
| 215 | // Fetch program code from memory | 232 | // Fetch program code from memory |
| 216 | GLShader::ProgramCode program_code; | 233 | GLShader::ProgramCode program_code; |
| 217 | const u64 gpu_address{gpu.regs.code_address.CodeAddress() + shader_config.offset}; | 234 | const u64 gpu_address{gpu.regs.code_address.CodeAddress() + shader_config.offset}; |
| 218 | const VAddr cpu_address{gpu.memory_manager.PhysicalToVirtualAddress(gpu_address)}; | 235 | const boost::optional<VAddr> cpu_address{gpu.memory_manager.GpuToCpuAddress(gpu_address)}; |
| 219 | Memory::ReadBlock(cpu_address, program_code.data(), program_code.size() * sizeof(u64)); | 236 | Memory::ReadBlock(*cpu_address, program_code.data(), program_code.size() * sizeof(u64)); |
| 220 | GLShader::ShaderSetup setup{std::move(program_code)}; | 237 | GLShader::ShaderSetup setup{std::move(program_code)}; |
| 221 | 238 | ||
| 222 | GLShader::ShaderEntries shader_resources; | 239 | GLShader::ShaderEntries shader_resources; |
| @@ -235,8 +252,8 @@ void RasterizerOpenGL::SetupShaders(u8* buffer_ptr, GLintptr buffer_offset, size | |||
| 235 | break; | 252 | break; |
| 236 | } | 253 | } |
| 237 | default: | 254 | default: |
| 238 | LOG_CRITICAL(HW_GPU, "Unimplemented shader index=%d, enable=%d, offset=0x%08X", index, | 255 | NGLOG_CRITICAL(HW_GPU, "Unimplemented shader index={}, enable={}, offset={:#010X}", |
| 239 | shader_config.enable.Value(), shader_config.offset); | 256 | index, shader_config.enable.Value(), shader_config.offset); |
| 240 | UNREACHABLE(); | 257 | UNREACHABLE(); |
| 241 | } | 258 | } |
| 242 | 259 | ||
| @@ -252,6 +269,24 @@ void RasterizerOpenGL::SetupShaders(u8* buffer_ptr, GLintptr buffer_offset, size | |||
| 252 | shader_program_manager->UseTrivialGeometryShader(); | 269 | shader_program_manager->UseTrivialGeometryShader(); |
| 253 | } | 270 | } |
| 254 | 271 | ||
| 272 | size_t RasterizerOpenGL::CalculateVertexArraysSize() const { | ||
| 273 | const auto& regs = Core::System().GetInstance().GPU().Maxwell3D().regs; | ||
| 274 | |||
| 275 | size_t size = 0; | ||
| 276 | for (u32 index = 0; index < Maxwell::NumVertexArrays; ++index) { | ||
| 277 | if (!regs.vertex_array[index].IsEnabled()) | ||
| 278 | continue; | ||
| 279 | |||
| 280 | const Tegra::GPUVAddr start = regs.vertex_array[index].StartAddress(); | ||
| 281 | const Tegra::GPUVAddr end = regs.vertex_array_limit[index].LimitAddress(); | ||
| 282 | |||
| 283 | ASSERT(end > start); | ||
| 284 | size += end - start + 1; | ||
| 285 | } | ||
| 286 | |||
| 287 | return size; | ||
| 288 | } | ||
| 289 | |||
| 255 | bool RasterizerOpenGL::AccelerateDrawBatch(bool is_indexed) { | 290 | bool RasterizerOpenGL::AccelerateDrawBatch(bool is_indexed) { |
| 256 | accelerate_draw = is_indexed ? AccelDraw::Indexed : AccelDraw::Arrays; | 291 | accelerate_draw = is_indexed ? AccelDraw::Indexed : AccelDraw::Arrays; |
| 257 | DrawArrays(); | 292 | DrawArrays(); |
| @@ -329,44 +364,49 @@ void RasterizerOpenGL::DrawArrays() { | |||
| 329 | const u64 index_buffer_size{regs.index_array.count * regs.index_array.FormatSizeInBytes()}; | 364 | const u64 index_buffer_size{regs.index_array.count * regs.index_array.FormatSizeInBytes()}; |
| 330 | const unsigned vertex_num{is_indexed ? regs.index_array.count : regs.vertex_buffer.count}; | 365 | const unsigned vertex_num{is_indexed ? regs.index_array.count : regs.vertex_buffer.count}; |
| 331 | 366 | ||
| 332 | // TODO(bunnei): Add support for 1+ vertex arrays | ||
| 333 | vs_input_size = vertex_num * regs.vertex_array[0].stride; | ||
| 334 | |||
| 335 | state.draw.vertex_buffer = stream_buffer->GetHandle(); | 367 | state.draw.vertex_buffer = stream_buffer->GetHandle(); |
| 336 | state.Apply(); | 368 | state.Apply(); |
| 337 | 369 | ||
| 338 | size_t buffer_size = static_cast<size_t>(vs_input_size); | 370 | size_t buffer_size = CalculateVertexArraysSize(); |
| 371 | |||
| 339 | if (is_indexed) { | 372 | if (is_indexed) { |
| 340 | buffer_size = Common::AlignUp(buffer_size, 4) + index_buffer_size; | 373 | buffer_size = Common::AlignUp<size_t>(buffer_size, 4) + index_buffer_size; |
| 341 | } | 374 | } |
| 342 | 375 | ||
| 343 | // Uniform space for the 5 shader stages | 376 | // Uniform space for the 5 shader stages |
| 344 | buffer_size += sizeof(GLShader::MaxwellUniformData) * Maxwell::MaxShaderStage; | 377 | buffer_size = Common::AlignUp<size_t>(buffer_size, 4) + |
| 378 | sizeof(GLShader::MaxwellUniformData) * Maxwell::MaxShaderStage; | ||
| 345 | 379 | ||
| 346 | size_t ptr_pos = 0; | ||
| 347 | u8* buffer_ptr; | 380 | u8* buffer_ptr; |
| 348 | GLintptr buffer_offset; | 381 | GLintptr buffer_offset; |
| 349 | std::tie(buffer_ptr, buffer_offset) = | 382 | std::tie(buffer_ptr, buffer_offset) = |
| 350 | stream_buffer->Map(static_cast<GLsizeiptr>(buffer_size), 4); | 383 | stream_buffer->Map(static_cast<GLsizeiptr>(buffer_size), 4); |
| 351 | 384 | ||
| 352 | SetupVertexArray(buffer_ptr, buffer_offset); | 385 | u8* offseted_buffer; |
| 353 | ptr_pos += vs_input_size; | 386 | std::tie(offseted_buffer, buffer_offset) = SetupVertexArrays(buffer_ptr, buffer_offset); |
| 387 | |||
| 388 | offseted_buffer = | ||
| 389 | reinterpret_cast<u8*>(Common::AlignUp(reinterpret_cast<size_t>(offseted_buffer), 4)); | ||
| 390 | buffer_offset = Common::AlignUp<size_t>(buffer_offset, 4); | ||
| 354 | 391 | ||
| 355 | // If indexed mode, copy the index buffer | 392 | // If indexed mode, copy the index buffer |
| 356 | GLintptr index_buffer_offset = 0; | 393 | GLintptr index_buffer_offset = 0; |
| 357 | if (is_indexed) { | 394 | if (is_indexed) { |
| 358 | ptr_pos = Common::AlignUp(ptr_pos, 4); | ||
| 359 | |||
| 360 | const auto& memory_manager = Core::System().GetInstance().GPU().memory_manager; | 395 | const auto& memory_manager = Core::System().GetInstance().GPU().memory_manager; |
| 361 | const VAddr index_data_addr{ | 396 | const boost::optional<VAddr> index_data_addr{ |
| 362 | memory_manager->PhysicalToVirtualAddress(regs.index_array.StartAddress())}; | 397 | memory_manager->GpuToCpuAddress(regs.index_array.StartAddress())}; |
| 363 | Memory::ReadBlock(index_data_addr, &buffer_ptr[ptr_pos], index_buffer_size); | 398 | Memory::ReadBlock(*index_data_addr, offseted_buffer, index_buffer_size); |
| 364 | 399 | ||
| 365 | index_buffer_offset = buffer_offset + static_cast<GLintptr>(ptr_pos); | 400 | index_buffer_offset = buffer_offset; |
| 366 | ptr_pos += index_buffer_size; | 401 | offseted_buffer += index_buffer_size; |
| 402 | buffer_offset += index_buffer_size; | ||
| 367 | } | 403 | } |
| 368 | 404 | ||
| 369 | SetupShaders(buffer_ptr, buffer_offset, ptr_pos); | 405 | offseted_buffer = |
| 406 | reinterpret_cast<u8*>(Common::AlignUp(reinterpret_cast<size_t>(offseted_buffer), 4)); | ||
| 407 | buffer_offset = Common::AlignUp<size_t>(buffer_offset, 4); | ||
| 408 | |||
| 409 | SetupShaders(offseted_buffer, buffer_offset); | ||
| 370 | 410 | ||
| 371 | stream_buffer->Unmap(); | 411 | stream_buffer->Unmap(); |
| 372 | 412 | ||
| @@ -478,17 +518,17 @@ void RasterizerOpenGL::FlushAll() { | |||
| 478 | res_cache.FlushAll(); | 518 | res_cache.FlushAll(); |
| 479 | } | 519 | } |
| 480 | 520 | ||
| 481 | void RasterizerOpenGL::FlushRegion(VAddr addr, u64 size) { | 521 | void RasterizerOpenGL::FlushRegion(Tegra::GPUVAddr addr, u64 size) { |
| 482 | MICROPROFILE_SCOPE(OpenGL_CacheManagement); | 522 | MICROPROFILE_SCOPE(OpenGL_CacheManagement); |
| 483 | res_cache.FlushRegion(addr, size); | 523 | res_cache.FlushRegion(addr, size); |
| 484 | } | 524 | } |
| 485 | 525 | ||
| 486 | void RasterizerOpenGL::InvalidateRegion(VAddr addr, u64 size) { | 526 | void RasterizerOpenGL::InvalidateRegion(Tegra::GPUVAddr addr, u64 size) { |
| 487 | MICROPROFILE_SCOPE(OpenGL_CacheManagement); | 527 | MICROPROFILE_SCOPE(OpenGL_CacheManagement); |
| 488 | res_cache.InvalidateRegion(addr, size, nullptr); | 528 | res_cache.InvalidateRegion(addr, size, nullptr); |
| 489 | } | 529 | } |
| 490 | 530 | ||
| 491 | void RasterizerOpenGL::FlushAndInvalidateRegion(VAddr addr, u64 size) { | 531 | void RasterizerOpenGL::FlushAndInvalidateRegion(Tegra::GPUVAddr addr, u64 size) { |
| 492 | MICROPROFILE_SCOPE(OpenGL_CacheManagement); | 532 | MICROPROFILE_SCOPE(OpenGL_CacheManagement); |
| 493 | res_cache.FlushRegion(addr, size); | 533 | res_cache.FlushRegion(addr, size); |
| 494 | res_cache.InvalidateRegion(addr, size, nullptr); | 534 | res_cache.InvalidateRegion(addr, size, nullptr); |
| @@ -519,7 +559,8 @@ bool RasterizerOpenGL::AccelerateDisplay(const Tegra::FramebufferConfig& framebu | |||
| 519 | MICROPROFILE_SCOPE(OpenGL_CacheManagement); | 559 | MICROPROFILE_SCOPE(OpenGL_CacheManagement); |
| 520 | 560 | ||
| 521 | SurfaceParams src_params; | 561 | SurfaceParams src_params; |
| 522 | src_params.addr = framebuffer_addr; | 562 | src_params.cpu_addr = framebuffer_addr; |
| 563 | src_params.addr = res_cache.TryFindFramebufferGpuAddress(framebuffer_addr).get_value_or(0); | ||
| 523 | src_params.width = std::min(framebuffer.width, pixel_stride); | 564 | src_params.width = std::min(framebuffer.width, pixel_stride); |
| 524 | src_params.height = framebuffer.height; | 565 | src_params.height = framebuffer.height; |
| 525 | src_params.stride = pixel_stride; | 566 | src_params.stride = pixel_stride; |
| @@ -618,9 +659,9 @@ u32 RasterizerOpenGL::SetupConstBuffers(Maxwell::ShaderStage stage, GLuint progr | |||
| 618 | buffer_draw_state.enabled = true; | 659 | buffer_draw_state.enabled = true; |
| 619 | buffer_draw_state.bindpoint = current_bindpoint + bindpoint; | 660 | buffer_draw_state.bindpoint = current_bindpoint + bindpoint; |
| 620 | 661 | ||
| 621 | VAddr addr = gpu.memory_manager->PhysicalToVirtualAddress(buffer.address); | 662 | boost::optional<VAddr> addr = gpu.memory_manager->GpuToCpuAddress(buffer.address); |
| 622 | std::vector<u8> data(used_buffer.GetSize() * sizeof(float)); | 663 | std::vector<u8> data(used_buffer.GetSize() * sizeof(float)); |
| 623 | Memory::ReadBlock(addr, data.data(), data.size()); | 664 | Memory::ReadBlock(*addr, data.data(), data.size()); |
| 624 | 665 | ||
| 625 | glBindBuffer(GL_SHADER_STORAGE_BUFFER, buffer_draw_state.ssbo); | 666 | glBindBuffer(GL_SHADER_STORAGE_BUFFER, buffer_draw_state.ssbo); |
| 626 | glBufferData(GL_SHADER_STORAGE_BUFFER, data.size(), data.data(), GL_DYNAMIC_DRAW); | 667 | glBufferData(GL_SHADER_STORAGE_BUFFER, data.size(), data.data(), GL_DYNAMIC_DRAW); |
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h index 03e02b52a..9709e595e 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.h +++ b/src/video_core/renderer_opengl/gl_rasterizer.h | |||
| @@ -11,6 +11,7 @@ | |||
| 11 | #include <glad/glad.h> | 11 | #include <glad/glad.h> |
| 12 | #include "common/common_types.h" | 12 | #include "common/common_types.h" |
| 13 | #include "video_core/engines/maxwell_3d.h" | 13 | #include "video_core/engines/maxwell_3d.h" |
| 14 | #include "video_core/memory_manager.h" | ||
| 14 | #include "video_core/rasterizer_interface.h" | 15 | #include "video_core/rasterizer_interface.h" |
| 15 | #include "video_core/renderer_opengl/gl_rasterizer_cache.h" | 16 | #include "video_core/renderer_opengl/gl_rasterizer_cache.h" |
| 16 | #include "video_core/renderer_opengl/gl_resource_manager.h" | 17 | #include "video_core/renderer_opengl/gl_resource_manager.h" |
| @@ -29,9 +30,9 @@ public: | |||
| 29 | void DrawArrays() override; | 30 | void DrawArrays() override; |
| 30 | void NotifyMaxwellRegisterChanged(u32 method) override; | 31 | void NotifyMaxwellRegisterChanged(u32 method) override; |
| 31 | void FlushAll() override; | 32 | void FlushAll() override; |
| 32 | void FlushRegion(VAddr addr, u64 size) override; | 33 | void FlushRegion(Tegra::GPUVAddr addr, u64 size) override; |
| 33 | void InvalidateRegion(VAddr addr, u64 size) override; | 34 | void InvalidateRegion(Tegra::GPUVAddr addr, u64 size) override; |
| 34 | void FlushAndInvalidateRegion(VAddr addr, u64 size) override; | 35 | void FlushAndInvalidateRegion(Tegra::GPUVAddr addr, u64 size) override; |
| 35 | bool AccelerateDisplayTransfer(const void* config) override; | 36 | bool AccelerateDisplayTransfer(const void* config) override; |
| 36 | bool AccelerateTextureCopy(const void* config) override; | 37 | bool AccelerateTextureCopy(const void* config) override; |
| 37 | bool AccelerateFill(const void* config) override; | 38 | bool AccelerateFill(const void* config) override; |
| @@ -148,13 +149,13 @@ private: | |||
| 148 | static constexpr size_t STREAM_BUFFER_SIZE = 4 * 1024 * 1024; | 149 | static constexpr size_t STREAM_BUFFER_SIZE = 4 * 1024 * 1024; |
| 149 | std::unique_ptr<OGLStreamBuffer> stream_buffer; | 150 | std::unique_ptr<OGLStreamBuffer> stream_buffer; |
| 150 | 151 | ||
| 151 | GLsizeiptr vs_input_size; | 152 | size_t CalculateVertexArraysSize() const; |
| 152 | 153 | ||
| 153 | void SetupVertexArray(u8* array_ptr, GLintptr buffer_offset); | 154 | std::pair<u8*, GLintptr> SetupVertexArrays(u8* array_ptr, GLintptr buffer_offset); |
| 154 | 155 | ||
| 155 | std::array<OGLBuffer, Tegra::Engines::Maxwell3D::Regs::MaxShaderStage> uniform_buffers; | 156 | std::array<OGLBuffer, Tegra::Engines::Maxwell3D::Regs::MaxShaderStage> uniform_buffers; |
| 156 | 157 | ||
| 157 | void SetupShaders(u8* buffer_ptr, GLintptr buffer_offset, size_t ptr_pos); | 158 | void SetupShaders(u8* buffer_ptr, GLintptr buffer_offset); |
| 158 | 159 | ||
| 159 | enum class AccelDraw { Disabled, Arrays, Indexed }; | 160 | enum class AccelDraw { Disabled, Arrays, Indexed }; |
| 160 | AccelDraw accelerate_draw; | 161 | AccelDraw accelerate_draw; |
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp index 7410471cc..501d15e98 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp | |||
| @@ -41,18 +41,15 @@ struct FormatTuple { | |||
| 41 | GLenum format; | 41 | GLenum format; |
| 42 | GLenum type; | 42 | GLenum type; |
| 43 | bool compressed; | 43 | bool compressed; |
| 44 | // How many pixels in the original texture are equivalent to one pixel in the compressed | ||
| 45 | // texture. | ||
| 46 | u32 compression_factor; | ||
| 47 | }; | 44 | }; |
| 48 | 45 | ||
| 49 | static constexpr std::array<FormatTuple, SurfaceParams::MaxPixelFormat> tex_format_tuples = {{ | 46 | static constexpr std::array<FormatTuple, SurfaceParams::MaxPixelFormat> tex_format_tuples = {{ |
| 50 | {GL_RGBA8, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, false, 1}, // ABGR8 | 47 | {GL_RGBA8, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, false}, // ABGR8 |
| 51 | {GL_RGB, GL_RGB, GL_UNSIGNED_SHORT_5_6_5_REV, false, 1}, // B5G6R5 | 48 | {GL_RGB, GL_RGB, GL_UNSIGNED_SHORT_5_6_5_REV, false}, // B5G6R5 |
| 52 | {GL_RGB10_A2, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, false, 1}, // A2B10G10R10 | 49 | {GL_RGB10_A2, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, false}, // A2B10G10R10 |
| 53 | {GL_COMPRESSED_RGB_S3TC_DXT1_EXT, GL_RGB, GL_UNSIGNED_INT_8_8_8_8, true, 16}, // DXT1 | 50 | {GL_COMPRESSED_RGB_S3TC_DXT1_EXT, GL_RGB, GL_UNSIGNED_INT_8_8_8_8, true}, // DXT1 |
| 54 | {GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, true, 16}, // DXT23 | 51 | {GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, true}, // DXT23 |
| 55 | {GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, true, 16}, // DXT45 | 52 | {GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, true}, // DXT45 |
| 56 | }}; | 53 | }}; |
| 57 | 54 | ||
| 58 | static const FormatTuple& GetFormatTuple(PixelFormat pixel_format, ComponentType component_type) { | 55 | static const FormatTuple& GetFormatTuple(PixelFormat pixel_format, ComponentType component_type) { |
| @@ -83,26 +80,30 @@ static u16 GetResolutionScaleFactor() { | |||
| 83 | } | 80 | } |
| 84 | 81 | ||
| 85 | template <bool morton_to_gl, PixelFormat format> | 82 | template <bool morton_to_gl, PixelFormat format> |
| 86 | void MortonCopy(u32 stride, u32 block_height, u32 height, u8* gl_buffer, VAddr base, VAddr start, | 83 | void MortonCopy(u32 stride, u32 block_height, u32 height, u8* gl_buffer, Tegra::GPUVAddr base, |
| 87 | VAddr end) { | 84 | Tegra::GPUVAddr start, Tegra::GPUVAddr end) { |
| 88 | constexpr u32 bytes_per_pixel = SurfaceParams::GetFormatBpp(format) / 8; | 85 | constexpr u32 bytes_per_pixel = SurfaceParams::GetFormatBpp(format) / CHAR_BIT; |
| 89 | constexpr u32 gl_bytes_per_pixel = CachedSurface::GetGLBytesPerPixel(format); | 86 | constexpr u32 gl_bytes_per_pixel = CachedSurface::GetGLBytesPerPixel(format); |
| 87 | const auto& gpu = Core::System::GetInstance().GPU(); | ||
| 90 | 88 | ||
| 91 | if (morton_to_gl) { | 89 | if (morton_to_gl) { |
| 92 | auto data = Tegra::Texture::UnswizzleTexture( | 90 | auto data = Tegra::Texture::UnswizzleTexture( |
| 93 | base, SurfaceParams::TextureFormatFromPixelFormat(format), stride, height, | 91 | *gpu.memory_manager->GpuToCpuAddress(base), |
| 94 | block_height); | 92 | SurfaceParams::TextureFormatFromPixelFormat(format), stride, height, block_height); |
| 95 | std::memcpy(gl_buffer, data.data(), data.size()); | 93 | std::memcpy(gl_buffer, data.data(), data.size()); |
| 96 | } else { | 94 | } else { |
| 97 | // TODO(bunnei): Assumes the default rendering GOB size of 16 (128 lines). We should check | 95 | // TODO(bunnei): Assumes the default rendering GOB size of 16 (128 lines). We should check |
| 98 | // the configuration for this and perform more generic un/swizzle | 96 | // the configuration for this and perform more generic un/swizzle |
| 99 | LOG_WARNING(Render_OpenGL, "need to use correct swizzle/GOB parameters!"); | 97 | NGLOG_WARNING(Render_OpenGL, "need to use correct swizzle/GOB parameters!"); |
| 100 | VideoCore::MortonCopyPixels128(stride, height, bytes_per_pixel, gl_bytes_per_pixel, | 98 | VideoCore::MortonCopyPixels128( |
| 101 | Memory::GetPointer(base), gl_buffer, morton_to_gl); | 99 | stride, height, bytes_per_pixel, gl_bytes_per_pixel, |
| 100 | Memory::GetPointer(*gpu.memory_manager->GpuToCpuAddress(base)), gl_buffer, | ||
| 101 | morton_to_gl); | ||
| 102 | } | 102 | } |
| 103 | } | 103 | } |
| 104 | 104 | ||
| 105 | static constexpr std::array<void (*)(u32, u32, u32, u8*, VAddr, VAddr, VAddr), | 105 | static constexpr std::array<void (*)(u32, u32, u32, u8*, Tegra::GPUVAddr, Tegra::GPUVAddr, |
| 106 | Tegra::GPUVAddr), | ||
| 106 | SurfaceParams::MaxPixelFormat> | 107 | SurfaceParams::MaxPixelFormat> |
| 107 | morton_to_gl_fns = { | 108 | morton_to_gl_fns = { |
| 108 | MortonCopy<true, PixelFormat::ABGR8>, MortonCopy<true, PixelFormat::B5G6R5>, | 109 | MortonCopy<true, PixelFormat::ABGR8>, MortonCopy<true, PixelFormat::B5G6R5>, |
| @@ -110,7 +111,8 @@ static constexpr std::array<void (*)(u32, u32, u32, u8*, VAddr, VAddr, VAddr), | |||
| 110 | MortonCopy<true, PixelFormat::DXT23>, MortonCopy<true, PixelFormat::DXT45>, | 111 | MortonCopy<true, PixelFormat::DXT23>, MortonCopy<true, PixelFormat::DXT45>, |
| 111 | }; | 112 | }; |
| 112 | 113 | ||
| 113 | static constexpr std::array<void (*)(u32, u32, u32, u8*, VAddr, VAddr, VAddr), | 114 | static constexpr std::array<void (*)(u32, u32, u32, u8*, Tegra::GPUVAddr, Tegra::GPUVAddr, |
| 115 | Tegra::GPUVAddr), | ||
| 114 | SurfaceParams::MaxPixelFormat> | 116 | SurfaceParams::MaxPixelFormat> |
| 115 | gl_to_morton_fns = { | 117 | gl_to_morton_fns = { |
| 116 | MortonCopy<false, PixelFormat::ABGR8>, | 118 | MortonCopy<false, PixelFormat::ABGR8>, |
| @@ -219,9 +221,9 @@ SurfaceParams SurfaceParams::FromInterval(SurfaceInterval interval) const { | |||
| 219 | SurfaceParams params = *this; | 221 | SurfaceParams params = *this; |
| 220 | const u32 tiled_size = is_tiled ? 8 : 1; | 222 | const u32 tiled_size = is_tiled ? 8 : 1; |
| 221 | const u64 stride_tiled_bytes = BytesInPixels(stride * tiled_size); | 223 | const u64 stride_tiled_bytes = BytesInPixels(stride * tiled_size); |
| 222 | VAddr aligned_start = | 224 | Tegra::GPUVAddr aligned_start = |
| 223 | addr + Common::AlignDown(boost::icl::first(interval) - addr, stride_tiled_bytes); | 225 | addr + Common::AlignDown(boost::icl::first(interval) - addr, stride_tiled_bytes); |
| 224 | VAddr aligned_end = | 226 | Tegra::GPUVAddr aligned_end = |
| 225 | addr + Common::AlignUp(boost::icl::last_next(interval) - addr, stride_tiled_bytes); | 227 | addr + Common::AlignUp(boost::icl::last_next(interval) - addr, stride_tiled_bytes); |
| 226 | 228 | ||
| 227 | if (aligned_end - aligned_start > stride_tiled_bytes) { | 229 | if (aligned_end - aligned_start > stride_tiled_bytes) { |
| @@ -342,6 +344,13 @@ bool SurfaceParams::CanTexCopy(const SurfaceParams& texcopy_params) const { | |||
| 342 | return FromInterval(texcopy_params.GetInterval()).GetInterval() == texcopy_params.GetInterval(); | 344 | return FromInterval(texcopy_params.GetInterval()).GetInterval() == texcopy_params.GetInterval(); |
| 343 | } | 345 | } |
| 344 | 346 | ||
| 347 | VAddr SurfaceParams::GetCpuAddr() const { | ||
| 348 | // When this function is used, only cpu_addr or (GPU) addr should be set, not both | ||
| 349 | ASSERT(!(cpu_addr && addr)); | ||
| 350 | const auto& gpu = Core::System::GetInstance().GPU(); | ||
| 351 | return cpu_addr.get_value_or(*gpu.memory_manager->GpuToCpuAddress(addr)); | ||
| 352 | } | ||
| 353 | |||
| 345 | bool CachedSurface::CanFill(const SurfaceParams& dest_surface, | 354 | bool CachedSurface::CanFill(const SurfaceParams& dest_surface, |
| 346 | SurfaceInterval fill_interval) const { | 355 | SurfaceInterval fill_interval) const { |
| 347 | if (type == SurfaceType::Fill && IsRegionValid(fill_interval) && | 356 | if (type == SurfaceType::Fill && IsRegionValid(fill_interval) && |
| @@ -349,9 +358,9 @@ bool CachedSurface::CanFill(const SurfaceParams& dest_surface, | |||
| 349 | boost::icl::last_next(fill_interval) <= end && // dest_surface is within our fill range | 358 | boost::icl::last_next(fill_interval) <= end && // dest_surface is within our fill range |
| 350 | dest_surface.FromInterval(fill_interval).GetInterval() == | 359 | dest_surface.FromInterval(fill_interval).GetInterval() == |
| 351 | fill_interval) { // make sure interval is a rectangle in dest surface | 360 | fill_interval) { // make sure interval is a rectangle in dest surface |
| 352 | if (fill_size * 8 != dest_surface.GetFormatBpp()) { | 361 | if (fill_size * CHAR_BIT != dest_surface.GetFormatBpp()) { |
| 353 | // Check if bits repeat for our fill_size | 362 | // Check if bits repeat for our fill_size |
| 354 | const u32 dest_bytes_per_pixel = std::max(dest_surface.GetFormatBpp() / 8, 1u); | 363 | const u32 dest_bytes_per_pixel = std::max(dest_surface.GetFormatBpp() / CHAR_BIT, 1u); |
| 355 | std::vector<u8> fill_test(fill_size * dest_bytes_per_pixel); | 364 | std::vector<u8> fill_test(fill_size * dest_bytes_per_pixel); |
| 356 | 365 | ||
| 357 | for (u32 i = 0; i < dest_bytes_per_pixel; ++i) | 366 | for (u32 i = 0; i < dest_bytes_per_pixel; ++i) |
| @@ -456,15 +465,15 @@ void RasterizerCacheOpenGL::CopySurface(const Surface& src_surface, const Surfac | |||
| 456 | } | 465 | } |
| 457 | 466 | ||
| 458 | MICROPROFILE_DEFINE(OpenGL_SurfaceLoad, "OpenGL", "Surface Load", MP_RGB(128, 64, 192)); | 467 | MICROPROFILE_DEFINE(OpenGL_SurfaceLoad, "OpenGL", "Surface Load", MP_RGB(128, 64, 192)); |
| 459 | void CachedSurface::LoadGLBuffer(VAddr load_start, VAddr load_end) { | 468 | void CachedSurface::LoadGLBuffer(Tegra::GPUVAddr load_start, Tegra::GPUVAddr load_end) { |
| 460 | ASSERT(type != SurfaceType::Fill); | 469 | ASSERT(type != SurfaceType::Fill); |
| 461 | 470 | ||
| 462 | u8* const texture_src_data = Memory::GetPointer(addr); | 471 | u8* const texture_src_data = Memory::GetPointer(GetCpuAddr()); |
| 463 | if (texture_src_data == nullptr) | 472 | if (texture_src_data == nullptr) |
| 464 | return; | 473 | return; |
| 465 | 474 | ||
| 466 | if (gl_buffer == nullptr) { | 475 | if (gl_buffer == nullptr) { |
| 467 | gl_buffer_size = width * height * GetGLBytesPerPixel(pixel_format); | 476 | gl_buffer_size = GetActualWidth() * GetActualHeight() * GetGLBytesPerPixel(pixel_format); |
| 468 | gl_buffer.reset(new u8[gl_buffer_size]); | 477 | gl_buffer.reset(new u8[gl_buffer_size]); |
| 469 | } | 478 | } |
| 470 | 479 | ||
| @@ -479,14 +488,15 @@ void CachedSurface::LoadGLBuffer(VAddr load_start, VAddr load_end) { | |||
| 479 | std::memcpy(&gl_buffer[start_offset], texture_src_data + start_offset, | 488 | std::memcpy(&gl_buffer[start_offset], texture_src_data + start_offset, |
| 480 | bytes_per_pixel * width * height); | 489 | bytes_per_pixel * width * height); |
| 481 | } else { | 490 | } else { |
| 482 | morton_to_gl_fns[static_cast<size_t>(pixel_format)]( | 491 | morton_to_gl_fns[static_cast<size_t>(pixel_format)](GetActualWidth(), block_height, |
| 483 | stride, block_height, height, &gl_buffer[0], addr, load_start, load_end); | 492 | GetActualHeight(), &gl_buffer[0], addr, |
| 493 | load_start, load_end); | ||
| 484 | } | 494 | } |
| 485 | } | 495 | } |
| 486 | 496 | ||
| 487 | MICROPROFILE_DEFINE(OpenGL_SurfaceFlush, "OpenGL", "Surface Flush", MP_RGB(128, 192, 64)); | 497 | MICROPROFILE_DEFINE(OpenGL_SurfaceFlush, "OpenGL", "Surface Flush", MP_RGB(128, 192, 64)); |
| 488 | void CachedSurface::FlushGLBuffer(VAddr flush_start, VAddr flush_end) { | 498 | void CachedSurface::FlushGLBuffer(Tegra::GPUVAddr flush_start, Tegra::GPUVAddr flush_end) { |
| 489 | u8* const dst_buffer = Memory::GetPointer(addr); | 499 | u8* const dst_buffer = Memory::GetPointer(GetCpuAddr()); |
| 490 | if (dst_buffer == nullptr) | 500 | if (dst_buffer == nullptr) |
| 491 | return; | 501 | return; |
| 492 | 502 | ||
| @@ -536,7 +546,8 @@ void CachedSurface::UploadGLTexture(const MathUtil::Rectangle<u32>& rect, GLuint | |||
| 536 | 546 | ||
| 537 | MICROPROFILE_SCOPE(OpenGL_TextureUL); | 547 | MICROPROFILE_SCOPE(OpenGL_TextureUL); |
| 538 | 548 | ||
| 539 | ASSERT(gl_buffer_size == width * height * GetGLBytesPerPixel(pixel_format)); | 549 | ASSERT(gl_buffer_size == |
| 550 | GetActualWidth() * GetActualHeight() * GetGLBytesPerPixel(pixel_format)); | ||
| 540 | 551 | ||
| 541 | // Load data from memory to the surface | 552 | // Load data from memory to the surface |
| 542 | GLint x0 = static_cast<GLint>(rect.left); | 553 | GLint x0 = static_cast<GLint>(rect.left); |
| @@ -571,11 +582,9 @@ void CachedSurface::UploadGLTexture(const MathUtil::Rectangle<u32>& rect, GLuint | |||
| 571 | glActiveTexture(GL_TEXTURE0); | 582 | glActiveTexture(GL_TEXTURE0); |
| 572 | if (tuple.compressed) { | 583 | if (tuple.compressed) { |
| 573 | glCompressedTexImage2D(GL_TEXTURE_2D, 0, tuple.internal_format, | 584 | glCompressedTexImage2D(GL_TEXTURE_2D, 0, tuple.internal_format, |
| 574 | static_cast<GLsizei>(rect.GetWidth()), | 585 | static_cast<GLsizei>(rect.GetWidth() * GetCompresssionFactor()), |
| 575 | static_cast<GLsizei>(rect.GetHeight()), 0, | 586 | static_cast<GLsizei>(rect.GetHeight() * GetCompresssionFactor()), 0, |
| 576 | rect.GetWidth() * rect.GetHeight() * | 587 | size, &gl_buffer[buffer_offset]); |
| 577 | GetGLBytesPerPixel(pixel_format) / tuple.compression_factor, | ||
| 578 | &gl_buffer[buffer_offset]); | ||
| 579 | } else { | 588 | } else { |
| 580 | glTexSubImage2D(GL_TEXTURE_2D, 0, x0, y0, static_cast<GLsizei>(rect.GetWidth()), | 589 | glTexSubImage2D(GL_TEXTURE_2D, 0, x0, y0, static_cast<GLsizei>(rect.GetWidth()), |
| 581 | static_cast<GLsizei>(rect.GetHeight()), tuple.format, tuple.type, | 590 | static_cast<GLsizei>(rect.GetHeight()), tuple.format, tuple.type, |
| @@ -945,6 +954,33 @@ Surface RasterizerCacheOpenGL::GetSurface(const SurfaceParams& params, ScaleMatc | |||
| 945 | return surface; | 954 | return surface; |
| 946 | } | 955 | } |
| 947 | 956 | ||
| 957 | boost::optional<Tegra::GPUVAddr> RasterizerCacheOpenGL::TryFindFramebufferGpuAddress( | ||
| 958 | VAddr cpu_addr) const { | ||
| 959 | // Tries to find the GPU address of a framebuffer based on the CPU address. This is because | ||
| 960 | // final output framebuffers are specified by CPU address, but internally our GPU cache uses GPU | ||
| 961 | // addresses. We iterate through all cached framebuffers, and compare their starting CPU address | ||
| 962 | // to the one provided. This is obviously not great, and won't work if the framebuffer overlaps | ||
| 963 | // surfaces. | ||
| 964 | |||
| 965 | std::vector<Tegra::GPUVAddr> gpu_addresses; | ||
| 966 | for (const auto& pair : surface_cache) { | ||
| 967 | for (const auto& surface : pair.second) { | ||
| 968 | const VAddr surface_cpu_addr = surface->GetCpuAddr(); | ||
| 969 | if (cpu_addr >= surface_cpu_addr && cpu_addr < (surface_cpu_addr + surface->size)) { | ||
| 970 | ASSERT_MSG(cpu_addr == surface_cpu_addr, "overlapping surfaces are unsupported"); | ||
| 971 | gpu_addresses.push_back(surface->addr); | ||
| 972 | } | ||
| 973 | } | ||
| 974 | } | ||
| 975 | |||
| 976 | if (gpu_addresses.empty()) { | ||
| 977 | return {}; | ||
| 978 | } | ||
| 979 | |||
| 980 | ASSERT_MSG(gpu_addresses.size() == 1, ">1 surface is unsupported"); | ||
| 981 | return gpu_addresses[0]; | ||
| 982 | } | ||
| 983 | |||
| 948 | SurfaceRect_Tuple RasterizerCacheOpenGL::GetSurfaceSubRect(const SurfaceParams& params, | 984 | SurfaceRect_Tuple RasterizerCacheOpenGL::GetSurfaceSubRect(const SurfaceParams& params, |
| 949 | ScaleMatch match_res_scale, | 985 | ScaleMatch match_res_scale, |
| 950 | bool load_if_create) { | 986 | bool load_if_create) { |
| @@ -1028,11 +1064,11 @@ Surface RasterizerCacheOpenGL::GetTextureSurface(const Tegra::Texture::FullTextu | |||
| 1028 | auto& gpu = Core::System::GetInstance().GPU(); | 1064 | auto& gpu = Core::System::GetInstance().GPU(); |
| 1029 | 1065 | ||
| 1030 | SurfaceParams params; | 1066 | SurfaceParams params; |
| 1031 | params.addr = gpu.memory_manager->PhysicalToVirtualAddress(config.tic.Address()); | 1067 | params.addr = config.tic.Address(); |
| 1032 | params.width = config.tic.Width(); | ||
| 1033 | params.height = config.tic.Height(); | ||
| 1034 | params.is_tiled = config.tic.IsTiled(); | 1068 | params.is_tiled = config.tic.IsTiled(); |
| 1035 | params.pixel_format = SurfaceParams::PixelFormatFromTextureFormat(config.tic.format); | 1069 | params.pixel_format = SurfaceParams::PixelFormatFromTextureFormat(config.tic.format); |
| 1070 | params.width = config.tic.Width() / params.GetCompresssionFactor(); | ||
| 1071 | params.height = config.tic.Height() / params.GetCompresssionFactor(); | ||
| 1036 | 1072 | ||
| 1037 | // TODO(Subv): Different types per component are not supported. | 1073 | // TODO(Subv): Different types per component are not supported. |
| 1038 | ASSERT(config.tic.r_type.Value() == config.tic.g_type.Value() && | 1074 | ASSERT(config.tic.r_type.Value() == config.tic.g_type.Value() && |
| @@ -1045,7 +1081,7 @@ Surface RasterizerCacheOpenGL::GetTextureSurface(const Tegra::Texture::FullTextu | |||
| 1045 | params.block_height = config.tic.BlockHeight(); | 1081 | params.block_height = config.tic.BlockHeight(); |
| 1046 | } else { | 1082 | } else { |
| 1047 | // Use the texture-provided stride value if the texture isn't tiled. | 1083 | // Use the texture-provided stride value if the texture isn't tiled. |
| 1048 | params.stride = params.PixelsInBytes(config.tic.Pitch()); | 1084 | params.stride = static_cast<u32>(params.PixelsInBytes(config.tic.Pitch())); |
| 1049 | } | 1085 | } |
| 1050 | 1086 | ||
| 1051 | params.UpdateParams(); | 1087 | params.UpdateParams(); |
| @@ -1073,11 +1109,10 @@ Surface RasterizerCacheOpenGL::GetTextureSurface(const Tegra::Texture::FullTextu | |||
| 1073 | SurfaceSurfaceRect_Tuple RasterizerCacheOpenGL::GetFramebufferSurfaces( | 1109 | SurfaceSurfaceRect_Tuple RasterizerCacheOpenGL::GetFramebufferSurfaces( |
| 1074 | bool using_color_fb, bool using_depth_fb, const MathUtil::Rectangle<s32>& viewport) { | 1110 | bool using_color_fb, bool using_depth_fb, const MathUtil::Rectangle<s32>& viewport) { |
| 1075 | const auto& regs = Core::System().GetInstance().GPU().Maxwell3D().regs; | 1111 | const auto& regs = Core::System().GetInstance().GPU().Maxwell3D().regs; |
| 1076 | const auto& memory_manager = Core::System().GetInstance().GPU().memory_manager; | ||
| 1077 | const auto& config = regs.rt[0]; | 1112 | const auto& config = regs.rt[0]; |
| 1078 | 1113 | ||
| 1079 | // TODO(bunnei): This is hard corded to use just the first render buffer | 1114 | // TODO(bunnei): This is hard corded to use just the first render buffer |
| 1080 | LOG_WARNING(Render_OpenGL, "hard-coded for render target 0!"); | 1115 | NGLOG_WARNING(Render_OpenGL, "hard-coded for render target 0!"); |
| 1081 | 1116 | ||
| 1082 | // update resolution_scale_factor and reset cache if changed | 1117 | // update resolution_scale_factor and reset cache if changed |
| 1083 | // TODO (bunnei): This code was ported as-is from Citra, and is technically not thread-safe. We | 1118 | // TODO (bunnei): This code was ported as-is from Citra, and is technically not thread-safe. We |
| @@ -1106,7 +1141,7 @@ SurfaceSurfaceRect_Tuple RasterizerCacheOpenGL::GetFramebufferSurfaces( | |||
| 1106 | color_params.block_height = Tegra::Texture::TICEntry::DefaultBlockHeight; | 1141 | color_params.block_height = Tegra::Texture::TICEntry::DefaultBlockHeight; |
| 1107 | SurfaceParams depth_params = color_params; | 1142 | SurfaceParams depth_params = color_params; |
| 1108 | 1143 | ||
| 1109 | color_params.addr = memory_manager->PhysicalToVirtualAddress(config.Address()); | 1144 | color_params.addr = config.Address(); |
| 1110 | color_params.pixel_format = SurfaceParams::PixelFormatFromRenderTargetFormat(config.format); | 1145 | color_params.pixel_format = SurfaceParams::PixelFormatFromRenderTargetFormat(config.format); |
| 1111 | color_params.component_type = SurfaceParams::ComponentTypeFromRenderTarget(config.format); | 1146 | color_params.component_type = SurfaceParams::ComponentTypeFromRenderTarget(config.format); |
| 1112 | color_params.UpdateParams(); | 1147 | color_params.UpdateParams(); |
| @@ -1122,8 +1157,8 @@ SurfaceSurfaceRect_Tuple RasterizerCacheOpenGL::GetFramebufferSurfaces( | |||
| 1122 | // Make sure that framebuffers don't overlap if both color and depth are being used | 1157 | // Make sure that framebuffers don't overlap if both color and depth are being used |
| 1123 | if (using_color_fb && using_depth_fb && | 1158 | if (using_color_fb && using_depth_fb && |
| 1124 | boost::icl::length(color_vp_interval & depth_vp_interval)) { | 1159 | boost::icl::length(color_vp_interval & depth_vp_interval)) { |
| 1125 | LOG_CRITICAL(Render_OpenGL, "Color and depth framebuffer memory regions overlap; " | 1160 | NGLOG_CRITICAL(Render_OpenGL, "Color and depth framebuffer memory regions overlap; " |
| 1126 | "overlapping framebuffers not supported!"); | 1161 | "overlapping framebuffers not supported!"); |
| 1127 | using_depth_fb = false; | 1162 | using_depth_fb = false; |
| 1128 | } | 1163 | } |
| 1129 | 1164 | ||
| @@ -1222,7 +1257,8 @@ void RasterizerCacheOpenGL::DuplicateSurface(const Surface& src_surface, | |||
| 1222 | } | 1257 | } |
| 1223 | } | 1258 | } |
| 1224 | 1259 | ||
| 1225 | void RasterizerCacheOpenGL::ValidateSurface(const Surface& surface, VAddr addr, u64 size) { | 1260 | void RasterizerCacheOpenGL::ValidateSurface(const Surface& surface, Tegra::GPUVAddr addr, |
| 1261 | u64 size) { | ||
| 1226 | if (size == 0) | 1262 | if (size == 0) |
| 1227 | return; | 1263 | return; |
| 1228 | 1264 | ||
| @@ -1261,7 +1297,7 @@ void RasterizerCacheOpenGL::ValidateSurface(const Surface& surface, VAddr addr, | |||
| 1261 | } | 1297 | } |
| 1262 | } | 1298 | } |
| 1263 | 1299 | ||
| 1264 | void RasterizerCacheOpenGL::FlushRegion(VAddr addr, u64 size, Surface flush_surface) { | 1300 | void RasterizerCacheOpenGL::FlushRegion(Tegra::GPUVAddr addr, u64 size, Surface flush_surface) { |
| 1265 | if (size == 0) | 1301 | if (size == 0) |
| 1266 | return; | 1302 | return; |
| 1267 | 1303 | ||
| @@ -1297,7 +1333,8 @@ void RasterizerCacheOpenGL::FlushAll() { | |||
| 1297 | FlushRegion(0, Kernel::VMManager::MAX_ADDRESS); | 1333 | FlushRegion(0, Kernel::VMManager::MAX_ADDRESS); |
| 1298 | } | 1334 | } |
| 1299 | 1335 | ||
| 1300 | void RasterizerCacheOpenGL::InvalidateRegion(VAddr addr, u64 size, const Surface& region_owner) { | 1336 | void RasterizerCacheOpenGL::InvalidateRegion(Tegra::GPUVAddr addr, u64 size, |
| 1337 | const Surface& region_owner) { | ||
| 1301 | if (size == 0) | 1338 | if (size == 0) |
| 1302 | return; | 1339 | return; |
| 1303 | 1340 | ||
| @@ -1390,10 +1427,10 @@ void RasterizerCacheOpenGL::UnregisterSurface(const Surface& surface) { | |||
| 1390 | surface_cache.subtract({surface->GetInterval(), SurfaceSet{surface}}); | 1427 | surface_cache.subtract({surface->GetInterval(), SurfaceSet{surface}}); |
| 1391 | } | 1428 | } |
| 1392 | 1429 | ||
| 1393 | void RasterizerCacheOpenGL::UpdatePagesCachedCount(VAddr addr, u64 size, int delta) { | 1430 | void RasterizerCacheOpenGL::UpdatePagesCachedCount(Tegra::GPUVAddr addr, u64 size, int delta) { |
| 1394 | const u64 num_pages = | 1431 | const u64 num_pages = ((addr + size - 1) >> Tegra::MemoryManager::PAGE_BITS) - |
| 1395 | ((addr + size - 1) >> Memory::PAGE_BITS) - (addr >> Memory::PAGE_BITS) + 1; | 1432 | (addr >> Tegra::MemoryManager::PAGE_BITS) + 1; |
| 1396 | const u64 page_start = addr >> Memory::PAGE_BITS; | 1433 | const u64 page_start = addr >> Tegra::MemoryManager::PAGE_BITS; |
| 1397 | const u64 page_end = page_start + num_pages; | 1434 | const u64 page_end = page_start + num_pages; |
| 1398 | 1435 | ||
| 1399 | // Interval maps will erase segments if count reaches 0, so if delta is negative we have to | 1436 | // Interval maps will erase segments if count reaches 0, so if delta is negative we have to |
| @@ -1406,8 +1443,10 @@ void RasterizerCacheOpenGL::UpdatePagesCachedCount(VAddr addr, u64 size, int del | |||
| 1406 | const auto interval = pair.first & pages_interval; | 1443 | const auto interval = pair.first & pages_interval; |
| 1407 | const int count = pair.second; | 1444 | const int count = pair.second; |
| 1408 | 1445 | ||
| 1409 | const VAddr interval_start_addr = boost::icl::first(interval) << Memory::PAGE_BITS; | 1446 | const Tegra::GPUVAddr interval_start_addr = boost::icl::first(interval) |
| 1410 | const VAddr interval_end_addr = boost::icl::last_next(interval) << Memory::PAGE_BITS; | 1447 | << Tegra::MemoryManager::PAGE_BITS; |
| 1448 | const Tegra::GPUVAddr interval_end_addr = boost::icl::last_next(interval) | ||
| 1449 | << Tegra::MemoryManager::PAGE_BITS; | ||
| 1411 | const u64 interval_size = interval_end_addr - interval_start_addr; | 1450 | const u64 interval_size = interval_end_addr - interval_start_addr; |
| 1412 | 1451 | ||
| 1413 | if (delta > 0 && count == delta) | 1452 | if (delta > 0 && count == delta) |
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.h b/src/video_core/renderer_opengl/gl_rasterizer_cache.h index e4cb3390f..55f1bdee8 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.h +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.h | |||
| @@ -17,12 +17,14 @@ | |||
| 17 | #ifdef __GNUC__ | 17 | #ifdef __GNUC__ |
| 18 | #pragma GCC diagnostic pop | 18 | #pragma GCC diagnostic pop |
| 19 | #endif | 19 | #endif |
| 20 | #include <boost/optional.hpp> | ||
| 20 | #include <glad/glad.h> | 21 | #include <glad/glad.h> |
| 21 | #include "common/assert.h" | 22 | #include "common/assert.h" |
| 22 | #include "common/common_funcs.h" | 23 | #include "common/common_funcs.h" |
| 23 | #include "common/common_types.h" | 24 | #include "common/common_types.h" |
| 24 | #include "common/math_util.h" | 25 | #include "common/math_util.h" |
| 25 | #include "video_core/gpu.h" | 26 | #include "video_core/gpu.h" |
| 27 | #include "video_core/memory_manager.h" | ||
| 26 | #include "video_core/renderer_opengl/gl_resource_manager.h" | 28 | #include "video_core/renderer_opengl/gl_resource_manager.h" |
| 27 | #include "video_core/textures/texture.h" | 29 | #include "video_core/textures/texture.h" |
| 28 | 30 | ||
| @@ -30,9 +32,9 @@ struct CachedSurface; | |||
| 30 | using Surface = std::shared_ptr<CachedSurface>; | 32 | using Surface = std::shared_ptr<CachedSurface>; |
| 31 | using SurfaceSet = std::set<Surface>; | 33 | using SurfaceSet = std::set<Surface>; |
| 32 | 34 | ||
| 33 | using SurfaceRegions = boost::icl::interval_set<VAddr>; | 35 | using SurfaceRegions = boost::icl::interval_set<Tegra::GPUVAddr>; |
| 34 | using SurfaceMap = boost::icl::interval_map<VAddr, Surface>; | 36 | using SurfaceMap = boost::icl::interval_map<Tegra::GPUVAddr, Surface>; |
| 35 | using SurfaceCache = boost::icl::interval_map<VAddr, SurfaceSet>; | 37 | using SurfaceCache = boost::icl::interval_map<Tegra::GPUVAddr, SurfaceSet>; |
| 36 | 38 | ||
| 37 | using SurfaceInterval = SurfaceCache::interval_type; | 39 | using SurfaceInterval = SurfaceCache::interval_type; |
| 38 | static_assert(std::is_same<SurfaceRegions::interval_type, SurfaceCache::interval_type>() && | 40 | static_assert(std::is_same<SurfaceRegions::interval_type, SurfaceCache::interval_type>() && |
| @@ -82,23 +84,49 @@ struct SurfaceParams { | |||
| 82 | Invalid = 4, | 84 | Invalid = 4, |
| 83 | }; | 85 | }; |
| 84 | 86 | ||
| 85 | static constexpr unsigned int GetFormatBpp(PixelFormat format) { | 87 | /** |
| 88 | * Gets the compression factor for the specified PixelFormat. This applies to just the | ||
| 89 | * "compressed width" and "compressed height", not the overall compression factor of a | ||
| 90 | * compressed image. This is used for maintaining proper surface sizes for compressed texture | ||
| 91 | * formats. | ||
| 92 | */ | ||
| 93 | static constexpr u32 GetCompresssionFactor(PixelFormat format) { | ||
| 86 | if (format == PixelFormat::Invalid) | 94 | if (format == PixelFormat::Invalid) |
| 87 | return 0; | 95 | return 0; |
| 88 | 96 | ||
| 89 | constexpr std::array<unsigned int, MaxPixelFormat> bpp_table = { | 97 | constexpr std::array<u32, MaxPixelFormat> compression_factor_table = {{ |
| 98 | 1, // ABGR8 | ||
| 99 | 1, // B5G6R5 | ||
| 100 | 1, // A2B10G10R10 | ||
| 101 | 4, // DXT1 | ||
| 102 | 4, // DXT23 | ||
| 103 | 4, // DXT45 | ||
| 104 | }}; | ||
| 105 | |||
| 106 | ASSERT(static_cast<size_t>(format) < compression_factor_table.size()); | ||
| 107 | return compression_factor_table[static_cast<size_t>(format)]; | ||
| 108 | } | ||
| 109 | u32 GetCompresssionFactor() const { | ||
| 110 | return GetCompresssionFactor(pixel_format); | ||
| 111 | } | ||
| 112 | |||
| 113 | static constexpr u32 GetFormatBpp(PixelFormat format) { | ||
| 114 | if (format == PixelFormat::Invalid) | ||
| 115 | return 0; | ||
| 116 | |||
| 117 | constexpr std::array<u32, MaxPixelFormat> bpp_table = {{ | ||
| 90 | 32, // ABGR8 | 118 | 32, // ABGR8 |
| 91 | 16, // B5G6R5 | 119 | 16, // B5G6R5 |
| 92 | 32, // A2B10G10R10 | 120 | 32, // A2B10G10R10 |
| 93 | 64, // DXT1 | 121 | 64, // DXT1 |
| 94 | 128, // DXT23 | 122 | 128, // DXT23 |
| 95 | 128, // DXT45 | 123 | 128, // DXT45 |
| 96 | }; | 124 | }}; |
| 97 | 125 | ||
| 98 | ASSERT(static_cast<size_t>(format) < bpp_table.size()); | 126 | ASSERT(static_cast<size_t>(format) < bpp_table.size()); |
| 99 | return bpp_table[static_cast<size_t>(format)]; | 127 | return bpp_table[static_cast<size_t>(format)]; |
| 100 | } | 128 | } |
| 101 | unsigned int GetFormatBpp() const { | 129 | u32 GetFormatBpp() const { |
| 102 | return GetFormatBpp(pixel_format); | 130 | return GetFormatBpp(pixel_format); |
| 103 | } | 131 | } |
| 104 | 132 | ||
| @@ -106,6 +134,8 @@ struct SurfaceParams { | |||
| 106 | switch (format) { | 134 | switch (format) { |
| 107 | case Tegra::RenderTargetFormat::RGBA8_UNORM: | 135 | case Tegra::RenderTargetFormat::RGBA8_UNORM: |
| 108 | return PixelFormat::ABGR8; | 136 | return PixelFormat::ABGR8; |
| 137 | case Tegra::RenderTargetFormat::RGB10_A2_UNORM: | ||
| 138 | return PixelFormat::A2B10G10R10; | ||
| 109 | default: | 139 | default: |
| 110 | NGLOG_CRITICAL(HW_GPU, "Unimplemented format={}", static_cast<u32>(format)); | 140 | NGLOG_CRITICAL(HW_GPU, "Unimplemented format={}", static_cast<u32>(format)); |
| 111 | UNREACHABLE(); | 141 | UNREACHABLE(); |
| @@ -251,6 +281,24 @@ struct SurfaceParams { | |||
| 251 | // Returns the region of the biggest valid rectange within interval | 281 | // Returns the region of the biggest valid rectange within interval |
| 252 | SurfaceInterval GetCopyableInterval(const Surface& src_surface) const; | 282 | SurfaceInterval GetCopyableInterval(const Surface& src_surface) const; |
| 253 | 283 | ||
| 284 | /** | ||
| 285 | * Gets the actual width (in pixels) of the surface. This is provided because `width` is used | ||
| 286 | * for tracking the surface region in memory, which may be compressed for certain formats. In | ||
| 287 | * this scenario, `width` is actually the compressed width. | ||
| 288 | */ | ||
| 289 | u32 GetActualWidth() const { | ||
| 290 | return width * GetCompresssionFactor(); | ||
| 291 | } | ||
| 292 | |||
| 293 | /** | ||
| 294 | * Gets the actual height (in pixels) of the surface. This is provided because `height` is used | ||
| 295 | * for tracking the surface region in memory, which may be compressed for certain formats. In | ||
| 296 | * this scenario, `height` is actually the compressed height. | ||
| 297 | */ | ||
| 298 | u32 GetActualHeight() const { | ||
| 299 | return height * GetCompresssionFactor(); | ||
| 300 | } | ||
| 301 | |||
| 254 | u32 GetScaledWidth() const { | 302 | u32 GetScaledWidth() const { |
| 255 | return width * res_scale; | 303 | return width * res_scale; |
| 256 | } | 304 | } |
| @@ -275,6 +323,8 @@ struct SurfaceParams { | |||
| 275 | return pixels * GetFormatBpp(pixel_format) / CHAR_BIT; | 323 | return pixels * GetFormatBpp(pixel_format) / CHAR_BIT; |
| 276 | } | 324 | } |
| 277 | 325 | ||
| 326 | VAddr GetCpuAddr() const; | ||
| 327 | |||
| 278 | bool ExactMatch(const SurfaceParams& other_surface) const; | 328 | bool ExactMatch(const SurfaceParams& other_surface) const; |
| 279 | bool CanSubRect(const SurfaceParams& sub_surface) const; | 329 | bool CanSubRect(const SurfaceParams& sub_surface) const; |
| 280 | bool CanExpand(const SurfaceParams& expanded_surface) const; | 330 | bool CanExpand(const SurfaceParams& expanded_surface) const; |
| @@ -283,8 +333,9 @@ struct SurfaceParams { | |||
| 283 | MathUtil::Rectangle<u32> GetSubRect(const SurfaceParams& sub_surface) const; | 333 | MathUtil::Rectangle<u32> GetSubRect(const SurfaceParams& sub_surface) const; |
| 284 | MathUtil::Rectangle<u32> GetScaledSubRect(const SurfaceParams& sub_surface) const; | 334 | MathUtil::Rectangle<u32> GetScaledSubRect(const SurfaceParams& sub_surface) const; |
| 285 | 335 | ||
| 286 | VAddr addr = 0; | 336 | Tegra::GPUVAddr addr = 0; |
| 287 | VAddr end = 0; | 337 | Tegra::GPUVAddr end = 0; |
| 338 | boost::optional<VAddr> cpu_addr; | ||
| 288 | u64 size = 0; | 339 | u64 size = 0; |
| 289 | 340 | ||
| 290 | u32 width = 0; | 341 | u32 width = 0; |
| @@ -323,15 +374,15 @@ struct CachedSurface : SurfaceParams { | |||
| 323 | if (format == PixelFormat::Invalid) | 374 | if (format == PixelFormat::Invalid) |
| 324 | return 0; | 375 | return 0; |
| 325 | 376 | ||
| 326 | return SurfaceParams::GetFormatBpp(format) / 8; | 377 | return SurfaceParams::GetFormatBpp(format) / CHAR_BIT; |
| 327 | } | 378 | } |
| 328 | 379 | ||
| 329 | std::unique_ptr<u8[]> gl_buffer; | 380 | std::unique_ptr<u8[]> gl_buffer; |
| 330 | size_t gl_buffer_size = 0; | 381 | size_t gl_buffer_size = 0; |
| 331 | 382 | ||
| 332 | // Read/Write data in Switch memory to/from gl_buffer | 383 | // Read/Write data in Switch memory to/from gl_buffer |
| 333 | void LoadGLBuffer(VAddr load_start, VAddr load_end); | 384 | void LoadGLBuffer(Tegra::GPUVAddr load_start, Tegra::GPUVAddr load_end); |
| 334 | void FlushGLBuffer(VAddr flush_start, VAddr flush_end); | 385 | void FlushGLBuffer(Tegra::GPUVAddr flush_start, Tegra::GPUVAddr flush_end); |
| 335 | 386 | ||
| 336 | // Upload/Download data in gl_buffer in/to this surface's texture | 387 | // Upload/Download data in gl_buffer in/to this surface's texture |
| 337 | void UploadGLTexture(const MathUtil::Rectangle<u32>& rect, GLuint read_fb_handle, | 388 | void UploadGLTexture(const MathUtil::Rectangle<u32>& rect, GLuint read_fb_handle, |
| @@ -360,6 +411,9 @@ public: | |||
| 360 | Surface GetSurface(const SurfaceParams& params, ScaleMatch match_res_scale, | 411 | Surface GetSurface(const SurfaceParams& params, ScaleMatch match_res_scale, |
| 361 | bool load_if_create); | 412 | bool load_if_create); |
| 362 | 413 | ||
| 414 | /// Tries to find a framebuffer GPU address based on the provided CPU address | ||
| 415 | boost::optional<Tegra::GPUVAddr> TryFindFramebufferGpuAddress(VAddr cpu_addr) const; | ||
| 416 | |||
| 363 | /// Attempt to find a subrect (resolution scaled) of a surface, otherwise loads a texture from | 417 | /// Attempt to find a subrect (resolution scaled) of a surface, otherwise loads a texture from |
| 364 | /// Switch memory to OpenGL and caches it (if not already cached) | 418 | /// Switch memory to OpenGL and caches it (if not already cached) |
| 365 | SurfaceRect_Tuple GetSurfaceSubRect(const SurfaceParams& params, ScaleMatch match_res_scale, | 419 | SurfaceRect_Tuple GetSurfaceSubRect(const SurfaceParams& params, ScaleMatch match_res_scale, |
| @@ -379,10 +433,10 @@ public: | |||
| 379 | SurfaceRect_Tuple GetTexCopySurface(const SurfaceParams& params); | 433 | SurfaceRect_Tuple GetTexCopySurface(const SurfaceParams& params); |
| 380 | 434 | ||
| 381 | /// Write any cached resources overlapping the region back to memory (if dirty) | 435 | /// Write any cached resources overlapping the region back to memory (if dirty) |
| 382 | void FlushRegion(VAddr addr, u64 size, Surface flush_surface = nullptr); | 436 | void FlushRegion(Tegra::GPUVAddr addr, u64 size, Surface flush_surface = nullptr); |
| 383 | 437 | ||
| 384 | /// Mark region as being invalidated by region_owner (nullptr if Switch memory) | 438 | /// Mark region as being invalidated by region_owner (nullptr if Switch memory) |
| 385 | void InvalidateRegion(VAddr addr, u64 size, const Surface& region_owner); | 439 | void InvalidateRegion(Tegra::GPUVAddr addr, u64 size, const Surface& region_owner); |
| 386 | 440 | ||
| 387 | /// Flush all cached resources tracked by this cache manager | 441 | /// Flush all cached resources tracked by this cache manager |
| 388 | void FlushAll(); | 442 | void FlushAll(); |
| @@ -391,7 +445,7 @@ private: | |||
| 391 | void DuplicateSurface(const Surface& src_surface, const Surface& dest_surface); | 445 | void DuplicateSurface(const Surface& src_surface, const Surface& dest_surface); |
| 392 | 446 | ||
| 393 | /// Update surface's texture for given region when necessary | 447 | /// Update surface's texture for given region when necessary |
| 394 | void ValidateSurface(const Surface& surface, VAddr addr, u64 size); | 448 | void ValidateSurface(const Surface& surface, Tegra::GPUVAddr addr, u64 size); |
| 395 | 449 | ||
| 396 | /// Create a new surface | 450 | /// Create a new surface |
| 397 | Surface CreateSurface(const SurfaceParams& params); | 451 | Surface CreateSurface(const SurfaceParams& params); |
| @@ -403,7 +457,7 @@ private: | |||
| 403 | void UnregisterSurface(const Surface& surface); | 457 | void UnregisterSurface(const Surface& surface); |
| 404 | 458 | ||
| 405 | /// Increase/decrease the number of surface in pages touching the specified region | 459 | /// Increase/decrease the number of surface in pages touching the specified region |
| 406 | void UpdatePagesCachedCount(VAddr addr, u64 size, int delta); | 460 | void UpdatePagesCachedCount(Tegra::GPUVAddr addr, u64 size, int delta); |
| 407 | 461 | ||
| 408 | SurfaceCache surface_cache; | 462 | SurfaceCache surface_cache; |
| 409 | PageMap cached_pages; | 463 | PageMap cached_pages; |
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp index 086424395..3dffb205d 100644 --- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp +++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp | |||
| @@ -519,7 +519,7 @@ private: | |||
| 519 | } | 519 | } |
| 520 | break; | 520 | break; |
| 521 | } | 521 | } |
| 522 | case OpCode::Type::FloatPredicate: { | 522 | case OpCode::Type::FloatSetPredicate: { |
| 523 | std::string op_a = instr.fsetp.neg_a ? "-" : ""; | 523 | std::string op_a = instr.fsetp.neg_a ? "-" : ""; |
| 524 | op_a += GetRegister(instr.gpr8); | 524 | op_a += GetRegister(instr.gpr8); |
| 525 | 525 | ||
| @@ -570,6 +570,59 @@ private: | |||
| 570 | } | 570 | } |
| 571 | break; | 571 | break; |
| 572 | } | 572 | } |
| 573 | case OpCode::Type::FloatSet: { | ||
| 574 | std::string dest = GetRegister(instr.gpr0); | ||
| 575 | std::string op_a = instr.fset.neg_a ? "-" : ""; | ||
| 576 | op_a += GetRegister(instr.gpr8); | ||
| 577 | |||
| 578 | if (instr.fset.abs_a) { | ||
| 579 | op_a = "abs(" + op_a + ')'; | ||
| 580 | } | ||
| 581 | |||
| 582 | std::string op_b = instr.fset.neg_b ? "-" : ""; | ||
| 583 | |||
| 584 | if (instr.is_b_imm) { | ||
| 585 | std::string imm = GetImmediate19(instr); | ||
| 586 | if (instr.fset.neg_imm) | ||
| 587 | op_b += "(-" + imm + ')'; | ||
| 588 | else | ||
| 589 | op_b += imm; | ||
| 590 | } else { | ||
| 591 | if (instr.is_b_gpr) { | ||
| 592 | op_b += GetRegister(instr.gpr20); | ||
| 593 | } else { | ||
| 594 | op_b += GetUniform(instr.uniform); | ||
| 595 | } | ||
| 596 | } | ||
| 597 | |||
| 598 | if (instr.fset.abs_b) { | ||
| 599 | op_b = "abs(" + op_b + ")"; | ||
| 600 | } | ||
| 601 | |||
| 602 | using Tegra::Shader::Pred; | ||
| 603 | ASSERT_MSG(instr.fset.pred39 == static_cast<u64>(Pred::UnusedIndex), | ||
| 604 | "Compound predicates are not implemented"); | ||
| 605 | |||
| 606 | // The fset instruction sets a register to 1.0 if the condition is true, and to 0 | ||
| 607 | // otherwise. | ||
| 608 | using Tegra::Shader::PredCondition; | ||
| 609 | switch (instr.fset.cond) { | ||
| 610 | case PredCondition::LessThan: | ||
| 611 | SetDest(0, dest, "((" + op_a + ") < (" + op_b + ")) ? 1.0 : 0", 1, 1); | ||
| 612 | break; | ||
| 613 | case PredCondition::Equal: | ||
| 614 | SetDest(0, dest, "((" + op_a + ") == (" + op_b + ")) ? 1.0 : 0", 1, 1); | ||
| 615 | break; | ||
| 616 | case PredCondition::GreaterThan: | ||
| 617 | SetDest(0, dest, "((" + op_a + ") > (" + op_b + ")) ? 1.0 : 0", 1, 1); | ||
| 618 | break; | ||
| 619 | default: | ||
| 620 | NGLOG_CRITICAL(HW_GPU, "Unhandled predicate condition: {} (a: {}, b: {})", | ||
| 621 | static_cast<unsigned>(instr.fset.cond.Value()), op_a, op_b); | ||
| 622 | UNREACHABLE(); | ||
| 623 | } | ||
| 624 | break; | ||
| 625 | } | ||
| 573 | default: { | 626 | default: { |
| 574 | switch (opcode->GetId()) { | 627 | switch (opcode->GetId()) { |
| 575 | case OpCode::Id::EXIT: { | 628 | case OpCode::Id::EXIT: { |
diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp index ab0acb20a..77d1692f4 100644 --- a/src/video_core/renderer_opengl/renderer_opengl.cpp +++ b/src/video_core/renderer_opengl/renderer_opengl.cpp | |||
| @@ -152,7 +152,8 @@ void RendererOpenGL::LoadFBToScreenInfo(const Tegra::FramebufferConfig& framebuf | |||
| 152 | screen_info.display_texture = screen_info.texture.resource.handle; | 152 | screen_info.display_texture = screen_info.texture.resource.handle; |
| 153 | screen_info.display_texcoords = MathUtil::Rectangle<float>(0.f, 0.f, 1.f, 1.f); | 153 | screen_info.display_texcoords = MathUtil::Rectangle<float>(0.f, 0.f, 1.f, 1.f); |
| 154 | 154 | ||
| 155 | Rasterizer()->FlushRegion(framebuffer_addr, size_in_bytes); | 155 | Memory::RasterizerFlushVirtualRegion(framebuffer_addr, size_in_bytes, |
| 156 | Memory::FlushMode::Flush); | ||
| 156 | 157 | ||
| 157 | VideoCore::MortonCopyPixels128(framebuffer.width, framebuffer.height, bytes_per_pixel, 4, | 158 | VideoCore::MortonCopyPixels128(framebuffer.width, framebuffer.height, bytes_per_pixel, 4, |
| 158 | Memory::GetPointer(framebuffer_addr), | 159 | Memory::GetPointer(framebuffer_addr), |
| @@ -269,10 +270,9 @@ void RendererOpenGL::ConfigureFramebufferTexture(TextureInfo& texture, | |||
| 269 | GLint internal_format; | 270 | GLint internal_format; |
| 270 | switch (framebuffer.pixel_format) { | 271 | switch (framebuffer.pixel_format) { |
| 271 | case Tegra::FramebufferConfig::PixelFormat::ABGR8: | 272 | case Tegra::FramebufferConfig::PixelFormat::ABGR8: |
| 272 | // Use RGBA8 and swap in the fragment shader | ||
| 273 | internal_format = GL_RGBA; | 273 | internal_format = GL_RGBA; |
| 274 | texture.gl_format = GL_RGBA; | 274 | texture.gl_format = GL_RGBA; |
| 275 | texture.gl_type = GL_UNSIGNED_INT_8_8_8_8; | 275 | texture.gl_type = GL_UNSIGNED_INT_8_8_8_8_REV; |
| 276 | gl_framebuffer_data.resize(texture.width * texture.height * 4); | 276 | gl_framebuffer_data.resize(texture.width * texture.height * 4); |
| 277 | break; | 277 | break; |
| 278 | default: | 278 | default: |
| @@ -295,17 +295,18 @@ void RendererOpenGL::DrawScreenTriangles(const ScreenInfo& screen_info, float x, | |||
| 295 | const auto& texcoords = screen_info.display_texcoords; | 295 | const auto& texcoords = screen_info.display_texcoords; |
| 296 | auto left = texcoords.left; | 296 | auto left = texcoords.left; |
| 297 | auto right = texcoords.right; | 297 | auto right = texcoords.right; |
| 298 | if (framebuffer_transform_flags != Tegra::FramebufferConfig::TransformFlags::Unset) | 298 | if (framebuffer_transform_flags != Tegra::FramebufferConfig::TransformFlags::Unset) { |
| 299 | if (framebuffer_transform_flags == Tegra::FramebufferConfig::TransformFlags::FlipV) { | 299 | if (framebuffer_transform_flags == Tegra::FramebufferConfig::TransformFlags::FlipV) { |
| 300 | // Flip the framebuffer vertically | 300 | // Flip the framebuffer vertically |
| 301 | left = texcoords.right; | 301 | left = texcoords.right; |
| 302 | right = texcoords.left; | 302 | right = texcoords.left; |
| 303 | } else { | 303 | } else { |
| 304 | // Other transformations are unsupported | 304 | // Other transformations are unsupported |
| 305 | LOG_CRITICAL(Render_OpenGL, "Unsupported framebuffer_transform_flags=%d", | 305 | NGLOG_CRITICAL(Render_OpenGL, "Unsupported framebuffer_transform_flags={}", |
| 306 | framebuffer_transform_flags); | 306 | static_cast<u32>(framebuffer_transform_flags)); |
| 307 | UNIMPLEMENTED(); | 307 | UNIMPLEMENTED(); |
| 308 | } | 308 | } |
| 309 | } | ||
| 309 | 310 | ||
| 310 | std::array<ScreenRectVertex, 4> vertices = {{ | 311 | std::array<ScreenRectVertex, 4> vertices = {{ |
| 311 | ScreenRectVertex(x, y, texcoords.top, left), | 312 | ScreenRectVertex(x, y, texcoords.top, left), |
| @@ -427,9 +428,9 @@ bool RendererOpenGL::Init() { | |||
| 427 | const char* gpu_vendor{reinterpret_cast<char const*>(glGetString(GL_VENDOR))}; | 428 | const char* gpu_vendor{reinterpret_cast<char const*>(glGetString(GL_VENDOR))}; |
| 428 | const char* gpu_model{reinterpret_cast<char const*>(glGetString(GL_RENDERER))}; | 429 | const char* gpu_model{reinterpret_cast<char const*>(glGetString(GL_RENDERER))}; |
| 429 | 430 | ||
| 430 | LOG_INFO(Render_OpenGL, "GL_VERSION: %s", gl_version); | 431 | NGLOG_INFO(Render_OpenGL, "GL_VERSION: {}", gl_version); |
| 431 | LOG_INFO(Render_OpenGL, "GL_VENDOR: %s", gpu_vendor); | 432 | NGLOG_INFO(Render_OpenGL, "GL_VENDOR: {}", gpu_vendor); |
| 432 | LOG_INFO(Render_OpenGL, "GL_RENDERER: %s", gpu_model); | 433 | NGLOG_INFO(Render_OpenGL, "GL_RENDERER: {}", gpu_model); |
| 433 | 434 | ||
| 434 | Core::Telemetry().AddField(Telemetry::FieldType::UserSystem, "GPU_Vendor", gpu_vendor); | 435 | Core::Telemetry().AddField(Telemetry::FieldType::UserSystem, "GPU_Vendor", gpu_vendor); |
| 435 | Core::Telemetry().AddField(Telemetry::FieldType::UserSystem, "GPU_Model", gpu_model); | 436 | Core::Telemetry().AddField(Telemetry::FieldType::UserSystem, "GPU_Model", gpu_model); |
diff --git a/src/video_core/textures/decoders.cpp b/src/video_core/textures/decoders.cpp index e0509f0ce..8b39b2bdf 100644 --- a/src/video_core/textures/decoders.cpp +++ b/src/video_core/textures/decoders.cpp | |||
| @@ -4,6 +4,7 @@ | |||
| 4 | 4 | ||
| 5 | #include <cstring> | 5 | #include <cstring> |
| 6 | #include "common/assert.h" | 6 | #include "common/assert.h" |
| 7 | #include "core/memory.h" | ||
| 7 | #include "video_core/textures/decoders.h" | 8 | #include "video_core/textures/decoders.h" |
| 8 | #include "video_core/textures/texture.h" | 9 | #include "video_core/textures/texture.h" |
| 9 | 10 | ||
| @@ -26,9 +27,8 @@ static u32 GetSwizzleOffset(u32 x, u32 y, u32 image_width, u32 bytes_per_pixel, | |||
| 26 | return address; | 27 | return address; |
| 27 | } | 28 | } |
| 28 | 29 | ||
| 29 | static void CopySwizzledData(u32 width, u32 height, u32 bytes_per_pixel, u32 out_bytes_per_pixel, | 30 | void CopySwizzledData(u32 width, u32 height, u32 bytes_per_pixel, u32 out_bytes_per_pixel, |
| 30 | u8* swizzled_data, u8* unswizzled_data, bool unswizzle, | 31 | u8* swizzled_data, u8* unswizzled_data, bool unswizzle, u32 block_height) { |
| 31 | u32 block_height) { | ||
| 32 | u8* data_ptrs[2]; | 32 | u8* data_ptrs[2]; |
| 33 | for (unsigned y = 0; y < height; ++y) { | 33 | for (unsigned y = 0; y < height; ++y) { |
| 34 | for (unsigned x = 0; x < width; ++x) { | 34 | for (unsigned x = 0; x < width; ++x) { |
diff --git a/src/video_core/textures/decoders.h b/src/video_core/textures/decoders.h index a700911cf..2562c4b06 100644 --- a/src/video_core/textures/decoders.h +++ b/src/video_core/textures/decoders.h | |||
| @@ -17,6 +17,10 @@ namespace Texture { | |||
| 17 | std::vector<u8> UnswizzleTexture(VAddr address, TextureFormat format, u32 width, u32 height, | 17 | std::vector<u8> UnswizzleTexture(VAddr address, TextureFormat format, u32 width, u32 height, |
| 18 | u32 block_height = TICEntry::DefaultBlockHeight); | 18 | u32 block_height = TICEntry::DefaultBlockHeight); |
| 19 | 19 | ||
| 20 | /// Copies texture data from a buffer and performs swizzling/unswizzling as necessary. | ||
| 21 | void CopySwizzledData(u32 width, u32 height, u32 bytes_per_pixel, u32 out_bytes_per_pixel, | ||
| 22 | u8* swizzled_data, u8* unswizzled_data, bool unswizzle, u32 block_height); | ||
| 23 | |||
| 20 | /** | 24 | /** |
| 21 | * Decodes an unswizzled texture into a A8R8G8B8 texture. | 25 | * Decodes an unswizzled texture into a A8R8G8B8 texture. |
| 22 | */ | 26 | */ |
diff --git a/src/video_core/video_core.cpp b/src/video_core/video_core.cpp index 289140f31..89dc8ed1e 100644 --- a/src/video_core/video_core.cpp +++ b/src/video_core/video_core.cpp | |||
| @@ -24,9 +24,9 @@ bool Init(EmuWindow* emu_window) { | |||
| 24 | g_renderer = std::make_unique<RendererOpenGL>(); | 24 | g_renderer = std::make_unique<RendererOpenGL>(); |
| 25 | g_renderer->SetWindow(g_emu_window); | 25 | g_renderer->SetWindow(g_emu_window); |
| 26 | if (g_renderer->Init()) { | 26 | if (g_renderer->Init()) { |
| 27 | LOG_DEBUG(Render, "initialized OK"); | 27 | NGLOG_DEBUG(Render, "initialized OK"); |
| 28 | } else { | 28 | } else { |
| 29 | LOG_CRITICAL(Render, "initialization failed !"); | 29 | NGLOG_CRITICAL(Render, "initialization failed !"); |
| 30 | return false; | 30 | return false; |
| 31 | } | 31 | } |
| 32 | return true; | 32 | return true; |
| @@ -36,7 +36,7 @@ bool Init(EmuWindow* emu_window) { | |||
| 36 | void Shutdown() { | 36 | void Shutdown() { |
| 37 | g_renderer.reset(); | 37 | g_renderer.reset(); |
| 38 | 38 | ||
| 39 | LOG_DEBUG(Render, "shutdown OK"); | 39 | NGLOG_DEBUG(Render, "shutdown OK"); |
| 40 | } | 40 | } |
| 41 | 41 | ||
| 42 | } // namespace VideoCore | 42 | } // namespace VideoCore |
diff --git a/src/yuzu/debugger/graphics/graphics_surface.cpp b/src/yuzu/debugger/graphics/graphics_surface.cpp index 1e4844b57..1fbca8ad0 100644 --- a/src/yuzu/debugger/graphics/graphics_surface.cpp +++ b/src/yuzu/debugger/graphics/graphics_surface.cpp | |||
| @@ -25,6 +25,8 @@ static Tegra::Texture::TextureFormat ConvertToTextureFormat( | |||
| 25 | switch (render_target_format) { | 25 | switch (render_target_format) { |
| 26 | case Tegra::RenderTargetFormat::RGBA8_UNORM: | 26 | case Tegra::RenderTargetFormat::RGBA8_UNORM: |
| 27 | return Tegra::Texture::TextureFormat::A8R8G8B8; | 27 | return Tegra::Texture::TextureFormat::A8R8G8B8; |
| 28 | case Tegra::RenderTargetFormat::RGB10_A2_UNORM: | ||
| 29 | return Tegra::Texture::TextureFormat::A2B10G10R10; | ||
| 28 | default: | 30 | default: |
| 29 | UNIMPLEMENTED_MSG("Unimplemented RT format"); | 31 | UNIMPLEMENTED_MSG("Unimplemented RT format"); |
| 30 | } | 32 | } |
| @@ -376,10 +378,10 @@ void GraphicsSurfaceWidget::OnUpdate() { | |||
| 376 | // TODO: Implement a good way to visualize alpha components! | 378 | // TODO: Implement a good way to visualize alpha components! |
| 377 | 379 | ||
| 378 | QImage decoded_image(surface_width, surface_height, QImage::Format_ARGB32); | 380 | QImage decoded_image(surface_width, surface_height, QImage::Format_ARGB32); |
| 379 | VAddr address = gpu.memory_manager->PhysicalToVirtualAddress(surface_address); | 381 | boost::optional<VAddr> address = gpu.memory_manager->GpuToCpuAddress(surface_address); |
| 380 | 382 | ||
| 381 | auto unswizzled_data = | 383 | auto unswizzled_data = |
| 382 | Tegra::Texture::UnswizzleTexture(address, surface_format, surface_width, surface_height); | 384 | Tegra::Texture::UnswizzleTexture(*address, surface_format, surface_width, surface_height); |
| 383 | 385 | ||
| 384 | auto texture_data = Tegra::Texture::DecodeTexture(unswizzled_data, surface_format, | 386 | auto texture_data = Tegra::Texture::DecodeTexture(unswizzled_data, surface_format, |
| 385 | surface_width, surface_height); | 387 | surface_width, surface_height); |
| @@ -435,9 +437,9 @@ void GraphicsSurfaceWidget::SaveSurface() { | |||
| 435 | pixmap->save(&file, "PNG"); | 437 | pixmap->save(&file, "PNG"); |
| 436 | } else if (selectedFilter == bin_filter) { | 438 | } else if (selectedFilter == bin_filter) { |
| 437 | auto& gpu = Core::System::GetInstance().GPU(); | 439 | auto& gpu = Core::System::GetInstance().GPU(); |
| 438 | VAddr address = gpu.memory_manager->PhysicalToVirtualAddress(surface_address); | 440 | boost::optional<VAddr> address = gpu.memory_manager->GpuToCpuAddress(surface_address); |
| 439 | 441 | ||
| 440 | const u8* buffer = Memory::GetPointer(address); | 442 | const u8* buffer = Memory::GetPointer(*address); |
| 441 | ASSERT_MSG(buffer != nullptr, "Memory not accessible"); | 443 | ASSERT_MSG(buffer != nullptr, "Memory not accessible"); |
| 442 | 444 | ||
| 443 | QFile file(filename); | 445 | QFile file(filename); |
diff --git a/src/yuzu/debugger/wait_tree.cpp b/src/yuzu/debugger/wait_tree.cpp index cae2864e5..acc4c2e0b 100644 --- a/src/yuzu/debugger/wait_tree.cpp +++ b/src/yuzu/debugger/wait_tree.cpp | |||
| @@ -6,8 +6,8 @@ | |||
| 6 | #include "yuzu/util/util.h" | 6 | #include "yuzu/util/util.h" |
| 7 | 7 | ||
| 8 | #include "core/core.h" | 8 | #include "core/core.h" |
| 9 | #include "core/hle/kernel/condition_variable.h" | ||
| 10 | #include "core/hle/kernel/event.h" | 9 | #include "core/hle/kernel/event.h" |
| 10 | #include "core/hle/kernel/handle_table.h" | ||
| 11 | #include "core/hle/kernel/mutex.h" | 11 | #include "core/hle/kernel/mutex.h" |
| 12 | #include "core/hle/kernel/thread.h" | 12 | #include "core/hle/kernel/thread.h" |
| 13 | #include "core/hle/kernel/timer.h" | 13 | #include "core/hle/kernel/timer.h" |
| @@ -67,6 +67,29 @@ QString WaitTreeText::GetText() const { | |||
| 67 | return text; | 67 | return text; |
| 68 | } | 68 | } |
| 69 | 69 | ||
| 70 | WaitTreeMutexInfo::WaitTreeMutexInfo(VAddr mutex_address) : mutex_address(mutex_address) { | ||
| 71 | mutex_value = Memory::Read32(mutex_address); | ||
| 72 | owner_handle = static_cast<Kernel::Handle>(mutex_value & Kernel::Mutex::MutexOwnerMask); | ||
| 73 | owner = Kernel::g_handle_table.Get<Kernel::Thread>(owner_handle); | ||
| 74 | } | ||
| 75 | |||
| 76 | QString WaitTreeMutexInfo::GetText() const { | ||
| 77 | return tr("waiting for mutex 0x%1").arg(mutex_address, 16, 16, QLatin1Char('0')); | ||
| 78 | } | ||
| 79 | |||
| 80 | std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeMutexInfo::GetChildren() const { | ||
| 81 | std::vector<std::unique_ptr<WaitTreeItem>> list; | ||
| 82 | |||
| 83 | bool has_waiters = (mutex_value & Kernel::Mutex::MutexHasWaitersFlag) != 0; | ||
| 84 | |||
| 85 | list.push_back(std::make_unique<WaitTreeText>(tr("has waiters: %1").arg(has_waiters))); | ||
| 86 | list.push_back(std::make_unique<WaitTreeText>( | ||
| 87 | tr("owner handle: 0x%1").arg(owner_handle, 8, 16, QLatin1Char('0')))); | ||
| 88 | if (owner != nullptr) | ||
| 89 | list.push_back(std::make_unique<WaitTreeThread>(*owner)); | ||
| 90 | return list; | ||
| 91 | } | ||
| 92 | |||
| 70 | WaitTreeWaitObject::WaitTreeWaitObject(const Kernel::WaitObject& o) : object(o) {} | 93 | WaitTreeWaitObject::WaitTreeWaitObject(const Kernel::WaitObject& o) : object(o) {} |
| 71 | 94 | ||
| 72 | bool WaitTreeExpandableItem::IsExpandable() const { | 95 | bool WaitTreeExpandableItem::IsExpandable() const { |
| @@ -84,11 +107,6 @@ std::unique_ptr<WaitTreeWaitObject> WaitTreeWaitObject::make(const Kernel::WaitO | |||
| 84 | switch (object.GetHandleType()) { | 107 | switch (object.GetHandleType()) { |
| 85 | case Kernel::HandleType::Event: | 108 | case Kernel::HandleType::Event: |
| 86 | return std::make_unique<WaitTreeEvent>(static_cast<const Kernel::Event&>(object)); | 109 | return std::make_unique<WaitTreeEvent>(static_cast<const Kernel::Event&>(object)); |
| 87 | case Kernel::HandleType::Mutex: | ||
| 88 | return std::make_unique<WaitTreeMutex>(static_cast<const Kernel::Mutex&>(object)); | ||
| 89 | case Kernel::HandleType::ConditionVariable: | ||
| 90 | return std::make_unique<WaitTreeConditionVariable>( | ||
| 91 | static_cast<const Kernel::ConditionVariable&>(object)); | ||
| 92 | case Kernel::HandleType::Timer: | 110 | case Kernel::HandleType::Timer: |
| 93 | return std::make_unique<WaitTreeTimer>(static_cast<const Kernel::Timer&>(object)); | 111 | return std::make_unique<WaitTreeTimer>(static_cast<const Kernel::Timer&>(object)); |
| 94 | case Kernel::HandleType::Thread: | 112 | case Kernel::HandleType::Thread: |
| @@ -160,6 +178,9 @@ QString WaitTreeThread::GetText() const { | |||
| 160 | case THREADSTATUS_WAIT_SYNCH_ANY: | 178 | case THREADSTATUS_WAIT_SYNCH_ANY: |
| 161 | status = tr("waiting for objects"); | 179 | status = tr("waiting for objects"); |
| 162 | break; | 180 | break; |
| 181 | case THREADSTATUS_WAIT_MUTEX: | ||
| 182 | status = tr("waiting for mutex"); | ||
| 183 | break; | ||
| 163 | case THREADSTATUS_DORMANT: | 184 | case THREADSTATUS_DORMANT: |
| 164 | status = tr("dormant"); | 185 | status = tr("dormant"); |
| 165 | break; | 186 | break; |
| @@ -186,6 +207,7 @@ QColor WaitTreeThread::GetColor() const { | |||
| 186 | return QColor(Qt::GlobalColor::darkYellow); | 207 | return QColor(Qt::GlobalColor::darkYellow); |
| 187 | case THREADSTATUS_WAIT_SYNCH_ALL: | 208 | case THREADSTATUS_WAIT_SYNCH_ALL: |
| 188 | case THREADSTATUS_WAIT_SYNCH_ANY: | 209 | case THREADSTATUS_WAIT_SYNCH_ANY: |
| 210 | case THREADSTATUS_WAIT_MUTEX: | ||
| 189 | return QColor(Qt::GlobalColor::red); | 211 | return QColor(Qt::GlobalColor::red); |
| 190 | case THREADSTATUS_DORMANT: | 212 | case THREADSTATUS_DORMANT: |
| 191 | return QColor(Qt::GlobalColor::darkCyan); | 213 | return QColor(Qt::GlobalColor::darkCyan); |
| @@ -225,11 +247,11 @@ std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeThread::GetChildren() const { | |||
| 225 | list.push_back(std::make_unique<WaitTreeText>( | 247 | list.push_back(std::make_unique<WaitTreeText>( |
| 226 | tr("last running ticks = %1").arg(thread.last_running_ticks))); | 248 | tr("last running ticks = %1").arg(thread.last_running_ticks))); |
| 227 | 249 | ||
| 228 | if (thread.held_mutexes.empty()) { | 250 | if (thread.mutex_wait_address != 0) |
| 229 | list.push_back(std::make_unique<WaitTreeText>(tr("not holding mutex"))); | 251 | list.push_back(std::make_unique<WaitTreeMutexInfo>(thread.mutex_wait_address)); |
| 230 | } else { | 252 | else |
| 231 | list.push_back(std::make_unique<WaitTreeMutexList>(thread.held_mutexes)); | 253 | list.push_back(std::make_unique<WaitTreeText>(tr("not waiting for mutex"))); |
| 232 | } | 254 | |
| 233 | if (thread.status == THREADSTATUS_WAIT_SYNCH_ANY || | 255 | if (thread.status == THREADSTATUS_WAIT_SYNCH_ANY || |
| 234 | thread.status == THREADSTATUS_WAIT_SYNCH_ALL) { | 256 | thread.status == THREADSTATUS_WAIT_SYNCH_ALL) { |
| 235 | list.push_back(std::make_unique<WaitTreeObjectList>(thread.wait_objects, | 257 | list.push_back(std::make_unique<WaitTreeObjectList>(thread.wait_objects, |
| @@ -250,33 +272,6 @@ std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeEvent::GetChildren() const { | |||
| 250 | return list; | 272 | return list; |
| 251 | } | 273 | } |
| 252 | 274 | ||
| 253 | WaitTreeMutex::WaitTreeMutex(const Kernel::Mutex& object) : WaitTreeWaitObject(object) {} | ||
| 254 | |||
| 255 | std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeMutex::GetChildren() const { | ||
| 256 | std::vector<std::unique_ptr<WaitTreeItem>> list(WaitTreeWaitObject::GetChildren()); | ||
| 257 | |||
| 258 | const auto& mutex = static_cast<const Kernel::Mutex&>(object); | ||
| 259 | if (mutex.GetHasWaiters()) { | ||
| 260 | list.push_back(std::make_unique<WaitTreeText>(tr("locked by thread:"))); | ||
| 261 | list.push_back(std::make_unique<WaitTreeThread>(*mutex.GetHoldingThread())); | ||
| 262 | } else { | ||
| 263 | list.push_back(std::make_unique<WaitTreeText>(tr("free"))); | ||
| 264 | } | ||
| 265 | return list; | ||
| 266 | } | ||
| 267 | |||
| 268 | WaitTreeConditionVariable::WaitTreeConditionVariable(const Kernel::ConditionVariable& object) | ||
| 269 | : WaitTreeWaitObject(object) {} | ||
| 270 | |||
| 271 | std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeConditionVariable::GetChildren() const { | ||
| 272 | std::vector<std::unique_ptr<WaitTreeItem>> list(WaitTreeWaitObject::GetChildren()); | ||
| 273 | |||
| 274 | const auto& condition_variable = static_cast<const Kernel::ConditionVariable&>(object); | ||
| 275 | list.push_back(std::make_unique<WaitTreeText>( | ||
| 276 | tr("available count = %1").arg(condition_variable.GetAvailableCount()))); | ||
| 277 | return list; | ||
| 278 | } | ||
| 279 | |||
| 280 | WaitTreeTimer::WaitTreeTimer(const Kernel::Timer& object) : WaitTreeWaitObject(object) {} | 275 | WaitTreeTimer::WaitTreeTimer(const Kernel::Timer& object) : WaitTreeWaitObject(object) {} |
| 281 | 276 | ||
| 282 | std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeTimer::GetChildren() const { | 277 | std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeTimer::GetChildren() const { |
| @@ -293,21 +288,6 @@ std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeTimer::GetChildren() const { | |||
| 293 | return list; | 288 | return list; |
| 294 | } | 289 | } |
| 295 | 290 | ||
| 296 | WaitTreeMutexList::WaitTreeMutexList( | ||
| 297 | const boost::container::flat_set<Kernel::SharedPtr<Kernel::Mutex>>& list) | ||
| 298 | : mutex_list(list) {} | ||
| 299 | |||
| 300 | QString WaitTreeMutexList::GetText() const { | ||
| 301 | return tr("holding mutexes"); | ||
| 302 | } | ||
| 303 | |||
| 304 | std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeMutexList::GetChildren() const { | ||
| 305 | std::vector<std::unique_ptr<WaitTreeItem>> list(mutex_list.size()); | ||
| 306 | std::transform(mutex_list.begin(), mutex_list.end(), list.begin(), | ||
| 307 | [](const auto& t) { return std::make_unique<WaitTreeMutex>(*t); }); | ||
| 308 | return list; | ||
| 309 | } | ||
| 310 | |||
| 311 | WaitTreeThreadList::WaitTreeThreadList(const std::vector<Kernel::SharedPtr<Kernel::Thread>>& list) | 291 | WaitTreeThreadList::WaitTreeThreadList(const std::vector<Kernel::SharedPtr<Kernel::Thread>>& list) |
| 312 | : thread_list(list) {} | 292 | : thread_list(list) {} |
| 313 | 293 | ||
diff --git a/src/yuzu/debugger/wait_tree.h b/src/yuzu/debugger/wait_tree.h index e538174eb..300ba9ae4 100644 --- a/src/yuzu/debugger/wait_tree.h +++ b/src/yuzu/debugger/wait_tree.h | |||
| @@ -16,8 +16,6 @@ class EmuThread; | |||
| 16 | namespace Kernel { | 16 | namespace Kernel { |
| 17 | class WaitObject; | 17 | class WaitObject; |
| 18 | class Event; | 18 | class Event; |
| 19 | class Mutex; | ||
| 20 | class ConditionVariable; | ||
| 21 | class Thread; | 19 | class Thread; |
| 22 | class Timer; | 20 | class Timer; |
| 23 | } // namespace Kernel | 21 | } // namespace Kernel |
| @@ -61,6 +59,20 @@ public: | |||
| 61 | bool IsExpandable() const override; | 59 | bool IsExpandable() const override; |
| 62 | }; | 60 | }; |
| 63 | 61 | ||
| 62 | class WaitTreeMutexInfo : public WaitTreeExpandableItem { | ||
| 63 | Q_OBJECT | ||
| 64 | public: | ||
| 65 | explicit WaitTreeMutexInfo(VAddr mutex_address); | ||
| 66 | QString GetText() const override; | ||
| 67 | std::vector<std::unique_ptr<WaitTreeItem>> GetChildren() const override; | ||
| 68 | |||
| 69 | private: | ||
| 70 | VAddr mutex_address; | ||
| 71 | u32 mutex_value; | ||
| 72 | Kernel::Handle owner_handle; | ||
| 73 | Kernel::SharedPtr<Kernel::Thread> owner; | ||
| 74 | }; | ||
| 75 | |||
| 64 | class WaitTreeWaitObject : public WaitTreeExpandableItem { | 76 | class WaitTreeWaitObject : public WaitTreeExpandableItem { |
| 65 | Q_OBJECT | 77 | Q_OBJECT |
| 66 | public: | 78 | public: |
| @@ -104,20 +116,6 @@ public: | |||
| 104 | std::vector<std::unique_ptr<WaitTreeItem>> GetChildren() const override; | 116 | std::vector<std::unique_ptr<WaitTreeItem>> GetChildren() const override; |
| 105 | }; | 117 | }; |
| 106 | 118 | ||
| 107 | class WaitTreeMutex : public WaitTreeWaitObject { | ||
| 108 | Q_OBJECT | ||
| 109 | public: | ||
| 110 | explicit WaitTreeMutex(const Kernel::Mutex& object); | ||
| 111 | std::vector<std::unique_ptr<WaitTreeItem>> GetChildren() const override; | ||
| 112 | }; | ||
| 113 | |||
| 114 | class WaitTreeConditionVariable : public WaitTreeWaitObject { | ||
| 115 | Q_OBJECT | ||
| 116 | public: | ||
| 117 | explicit WaitTreeConditionVariable(const Kernel::ConditionVariable& object); | ||
| 118 | std::vector<std::unique_ptr<WaitTreeItem>> GetChildren() const override; | ||
| 119 | }; | ||
| 120 | |||
| 121 | class WaitTreeTimer : public WaitTreeWaitObject { | 119 | class WaitTreeTimer : public WaitTreeWaitObject { |
| 122 | Q_OBJECT | 120 | Q_OBJECT |
| 123 | public: | 121 | public: |
| @@ -125,19 +123,6 @@ public: | |||
| 125 | std::vector<std::unique_ptr<WaitTreeItem>> GetChildren() const override; | 123 | std::vector<std::unique_ptr<WaitTreeItem>> GetChildren() const override; |
| 126 | }; | 124 | }; |
| 127 | 125 | ||
| 128 | class WaitTreeMutexList : public WaitTreeExpandableItem { | ||
| 129 | Q_OBJECT | ||
| 130 | public: | ||
| 131 | explicit WaitTreeMutexList( | ||
| 132 | const boost::container::flat_set<Kernel::SharedPtr<Kernel::Mutex>>& list); | ||
| 133 | |||
| 134 | QString GetText() const override; | ||
| 135 | std::vector<std::unique_ptr<WaitTreeItem>> GetChildren() const override; | ||
| 136 | |||
| 137 | private: | ||
| 138 | const boost::container::flat_set<Kernel::SharedPtr<Kernel::Mutex>>& mutex_list; | ||
| 139 | }; | ||
| 140 | |||
| 141 | class WaitTreeThreadList : public WaitTreeExpandableItem { | 126 | class WaitTreeThreadList : public WaitTreeExpandableItem { |
| 142 | Q_OBJECT | 127 | Q_OBJECT |
| 143 | public: | 128 | public: |