Compare commits

...

147 Commits

Author SHA1 Message Date
Morph 197d756560 bounded_threadsafe_queue: Refactor Pop
Introduces PopModes to bring waiting logic into Pop, similar to Push.
2023-03-21 22:33:58 -04:00
Morph 8c56481249 bounded_threadsafe_queue: Add producer cv to avoid busy waiting 2023-03-21 22:33:57 -04:00
Morph 407dc917f1 bounded_threadsafe_queue: Deduplicate and add PushModes
Adds the PushModes Try and Wait to allow producers to specify how they want to push their data to the queue if the queue is full.
If the queue is full:
- Try will fail to push to the queue, returning false. Try only returns true if it successfully pushes to the queue. This may result in items not being pushed into the queue.
- Wait will wait until a slot is available to push to the queue, resulting in potential for deadlock if a consumer is not running.
2023-03-21 19:20:21 -04:00
Morph 15d573194c bounded_threadsafe_queue: Add TryPush 2023-03-21 19:17:38 -04:00
Morph f28ca5361f logging: Make use of bounded queue 2023-03-21 19:17:38 -04:00
Morph 306840a580 bounded_threadsafe_queue: Use simplified impl of bounded queue
Provides a simplified SPSC, MPSC, and MPMC bounded queue implementation using mutexes.
2023-03-21 19:17:32 -04:00
bunnei 3d4c113037 Merge pull request #9970 from bunnei/string-util-view
common: string_util: Use std::string_view for UTF16ToUTF8/UTF8ToUTF16W.
2023-03-19 11:10:16 -07:00
bunnei 230d118252 Merge pull request #9972 from liamwhite/ipc-trace
kernel: fix LOG_TRACE in ipc
2023-03-19 11:00:42 -07:00
Liam 43d909949e kernel: fix LOG_TRACE in ipc 2023-03-19 10:02:20 -04:00
bunnei 00d401d639 common: string_util: Use std::string_view for UTF16ToUTF8/UTF8ToUTF16W. 2023-03-18 22:42:25 -07:00
liamwhite 0e7e98e24e Merge pull request #9966 from bunnei/bounded-polyfill
common: bounded_threadsafe_queue: Use polyfill_thread.
2023-03-18 12:39:52 -04:00
bunnei 0eb3fa05e5 common: bounded_threadsafe_queue: Use polyfill_thread. 2023-03-17 23:42:17 -07:00
bunnei 889454f9bf Merge pull request #9778 from behunin/my-box-chevy
gpu_thread: Use bounded queue
2023-03-17 22:14:29 -07:00
bunnei 8bcaa8c2e4 Merge pull request #9953 from german77/amiibo_crc
service: nfp: Actually write correct crc
2023-03-17 22:13:57 -07:00
Narr the Reg 075a3d1172 service: nfp: Replace crc function with boost equivalent 2023-03-16 17:47:32 -06:00
liamwhite 6d76a54d37 Merge pull request #9955 from liamwhite/color-blend-equation
vulkan: disable extendedDynamicState3ColorBlendEquation on radv
2023-03-15 20:19:45 -04:00
liamwhite a04061e6ae Merge pull request #9931 from liamwhite/sched
vk_scheduler: split work queue waits and execution waits
2023-03-15 20:19:35 -04:00
Narr the Reg 7187732454 service: nfp: Close app area and recreate crc 2023-03-15 17:01:06 -06:00
Narr the Reg 5031f5b8b0 service: nfp: Convert mii colors to v3 2023-03-15 17:01:05 -06:00
Liam da83afdeaf vulkan: disable extendedDynamicState3ColorBlendEquation on radv 2023-03-15 15:55:07 -04:00
Narr the Reg 026fe2e4f4 service: nfp: Actually write correct crc 2023-03-14 23:42:41 -06:00
liamwhite 0c7149d222 Merge pull request #9933 from vonchenplus/texture_format
video_core: Update texture format
2023-03-14 11:35:37 -04:00
bunnei 05f26e1337 Merge pull request #9951 from Morph1984/save
configure_audio: Fix output mode setting not saving
2023-03-13 18:49:14 -07:00
Morph 4c678cfbc8 configure_audio: Fix output mode setting not saving 2023-03-13 17:41:30 -04:00
liamwhite 8870fae674 Merge pull request #9939 from german77/vibration
input_common: sdl: Only send last vibration command
2023-03-13 13:45:40 -04:00
liamwhite 8348c41eab Merge pull request #9941 from german77/settings
yuzu: Move audio settings to audio section
2023-03-13 13:45:29 -04:00
liamwhite 638044820d Merge pull request #9943 from vonchenplus/gentleman
video_core: Fix inline_index and draw_texture error
2023-03-13 13:45:17 -04:00
liamwhite 1f952f6ac9 Merge pull request #9936 from liamwhite/m_this
kernel: use consistent style
2023-03-13 09:16:16 -04:00
german77 96b8a3ecac input_common: sdl: Only send last vibration command 2023-03-12 21:30:02 -06:00
Liam c352381ce9 kernel: additional style fixes to KThread, KProcess 2023-03-12 22:10:27 -04:00
Liam 9775a73d1a kernel: fix clang build 2023-03-12 22:10:27 -04:00
Liam 088c434d65 kernel: remove unnecessary finalize calls 2023-03-12 22:10:27 -04:00
Liam 9863db9db4 kernel: convert KProcess to new style 2023-03-12 22:09:27 -04:00
Liam 6bfb4c8f71 kernel: convert KThread to new style 2023-03-12 22:09:09 -04:00
Liam ac6cbb7134 kernel: prefer std::addressof 2023-03-12 22:09:09 -04:00
Liam 641783df8f kernel: convert KResourceLimit 2023-03-12 22:09:09 -04:00
Liam c0b9e93b77 kernel: remove kernel_ 2023-03-12 22:09:09 -04:00
Liam 9368e17a92 kernel: remove gratitutous attribute usage 2023-03-12 22:09:09 -04:00
Liam 91fd4e30f2 kernel/svc: convert to new style 2023-03-12 22:09:08 -04:00
Liam 57f1d8ef8d kernel: convert miscellaneous 2023-03-12 22:06:53 -04:00
Liam d1b53c8d82 kernel: conver KScopedLock, KScopedResourceReservation, KSessionRequest, KSharedMemory, KSpinLock 2023-03-12 22:06:53 -04:00
Liam 7322c99e5f kernel: convert KAbstractSchedulerLock 2023-03-12 22:06:53 -04:00
Liam 467adc1acd kernel: convert KMemoryLayout, KMemoryRegion*, KPageTableSlabHeap, KPriorityQueue 2023-03-12 22:06:53 -04:00
Liam 0483dfae1a kernel: move KMemoryLayout for NX board 2023-03-12 22:06:53 -04:00
Liam 8d1f5bfbd2 kernel: remove KLinkedList 2023-03-12 22:06:53 -04:00
Liam fdf90c6d75 kernel: convert KConditionVariable, KLightConditionVariable, KLightLock 2023-03-12 22:06:53 -04:00
Liam 097c25b164 kernel: convert KPort, KSession 2023-03-12 22:06:53 -04:00
Liam d24ab14126 kernel: convert GlobalSchedulerContext, KAddressArbiter, KScopedSchedulerLockAndSleep, KThreadQueue to new style 2023-03-12 22:06:53 -04:00
liamwhite 54c359d1e3 Merge pull request #9942 from liamwhite/speling
general: use codespell to identify spelling mistakes
2023-03-12 21:59:46 -04:00
Liam 3f261f22c9 vk_scheduler: split work queue waits and execution waits 2023-03-12 17:19:44 -04:00
Liam 600f325d87 general: fix spelling mistakes 2023-03-12 11:33:01 -04:00
FengChen 44f10c8dee video_core: Fix ogl status error when draw_texture 2023-03-12 13:33:31 +08:00
FengChen 4e42ba54e5 video_core: Invalid index_buffer flag when inline_index draw 2023-03-12 13:21:26 +08:00
Liam d155167ea2 general: use codespell to identify spelling mistakes 2023-03-11 22:08:43 -05:00
german77 e090a1c6bd yuzu: Move audio settings to audio section 2023-03-11 20:04:36 -06:00
german77 e8af3f29d2 yuzu: Remove console id setting 2023-03-11 19:33:31 -06:00
Fernando S 49643d8134 Merge pull request #9913 from ameerj/acc-dma-refactor
AccelerateDMA: Refactor Buffer/Image copy code and implement for OGL
2023-03-11 20:04:19 +01:00
liamwhite 92c89312fc Merge pull request #9923 from liamwhite/kht
kernel: add timer pointer to KThreadQueue
2023-03-10 16:19:41 -05:00
liamwhite e0bd27b674 Merge pull request #9928 from german77/super_nfp
service: nfp: Improve implementation
2023-03-10 13:55:28 -05:00
liamwhite 103380134f Merge pull request #9925 from ameerj/gl-sync-signal
OpenGL: Prefer glClientWaitSync for OGLSync objects
2023-03-10 13:55:22 -05:00
liamwhite 021af4fd00 Merge pull request #9917 from Morph1984/the-real-time
native_clock: Re-adjust the RDTSC frequency to its real frequency
2023-03-10 13:55:11 -05:00
Feng Chen c8ad039612 video_core: Update texture format 2023-03-10 21:48:50 +08:00
Narr the Reg 8d5cde6eff service: nfp: Improve implementation 2023-03-09 19:29:28 -06:00
liamwhite ec4e2d1fab Merge pull request #9916 from liamwhite/fpu
kernel: clone fpu status on CreateThread
2023-03-09 09:19:15 -05:00
liamwhite b5c0c1e163 Merge pull request #9822 from ameerj/buffcache-ssbo-addr
buffer_cache: Add logic for non-NVN storage buffer tracking
2023-03-09 09:18:39 -05:00
ameerj 03137086db OpenGL: Prefer glClientWaitSync for OGLSync objects
At least on Nvidia, glClientWaitSync with a timeout of 0 (non-blocking) is faster than glGetSynciv of GL_SYNC_STATUS.
2023-03-08 20:29:25 -05:00
bunnei 4562f7af9a Merge pull request #9906 from german77/metroid2
input_common: Increase mouse sensitivity range
2023-03-08 10:43:38 -08:00
liamwhite f3f57f90fe Merge pull request #9912 from liamwhite/err
hle: rename legacy errors to Results
2023-03-08 09:16:27 -05:00
liamwhite b5d61f214d Merge pull request #9904 from liamwhite/ws
kernel: fix WaitSynchronization
2023-03-08 09:16:17 -05:00
liamwhite 3cf88a4d6c Merge pull request #9896 from Kelebek1/d24s8
Check all swizzle components for red, not just [0]
2023-03-08 09:16:06 -05:00
Morph 67560296c6 perf_stats: Check multicore first
SpeedLimiting is SC only. Since MC is performance oriented we should check for it first to skip checking use_speed_limit.
2023-03-07 23:11:01 -05:00
Morph d72d753b1a Merge pull request #9921 from liamwhite/override
general: fix type inconsistencies
2023-03-07 22:42:40 -05:00
Morph a3ffea6a64 Merge pull request #9918 from liamwhite/fwrapv
kernel: avoid signed overflow UB on MSVC
2023-03-07 22:42:32 -05:00
Morph b014fdacdb Merge pull request #9920 from liamwhite/constexpr-bit-cast
common: make BitCast constexpr
2023-03-07 22:42:19 -05:00
Morph 1073346c7f hid: Use nanosecond timestamps instead of ticks 2023-03-07 21:17:47 -05:00
Morph 3053a62375 core: Promote CPU/GPU threads to time critical
And also demote Audren and CoreTiming to High thread priority.
2023-03-07 21:17:46 -05:00
Morph d718eab351 native_clock: Wait for 10 seconds instead of 30
It was experimentally determined to be sufficient.
2023-03-07 21:17:46 -05:00
Morph c27a626b5b native_clock: Use RealTimeClock instead of SteadyClock
We want to synchronize RDTSC to real time.
2023-03-07 21:17:46 -05:00
Morph 6f9918552c steady_clock: Introduce a real time clock 2023-03-07 21:17:46 -05:00
Morph dcd13a7566 native_clock: Re-adjust the RDTSC frequency
The RDTSC frequency reported by CPUID is not accurate to its true frequency.
We will spawn a separate thread to calculate the true RDTSC frequency after a measurement period of 30 seconds has elapsed.
2023-03-07 21:17:46 -05:00
Narr the Reg 757aafa582 input_common: Minor typo issues (#9922) 2023-03-08 03:15:46 +01:00
Liam 1776448df2 kernel: add timer pointer to KThreadQueue 2023-03-07 20:51:29 -05:00
german77 9a9e5844d3 input_common: Increase mouse sensitivity range 2023-03-07 19:31:52 -06:00
Liam 64dcb40db1 common: make BitCast constexpr 2023-03-07 20:26:56 -05:00
Liam ba4213d956 general: fix type inconsistencies 2023-03-07 20:05:19 -05:00
Liam d45ac00d48 kernel: avoid signed overflow UB on MSVC 2023-03-07 19:46:48 -05:00
Liam 484641003c kernel: clone fpu status on CreateThread 2023-03-07 19:18:06 -05:00
liamwhite a7792e5ff8 Merge pull request #9889 from Morph1984/time-is-ticking
core_timing: Reduce CPU usage on Windows
2023-03-07 10:54:13 -05:00
ameerj 268942c8fe gl_rasterizer: Implement AccelerateDMA DmaBufferImageCopy 2023-03-06 22:57:52 -05:00
ameerj 6b9cc0ed23 Refactor AccelerateDMA code 2023-03-06 22:57:45 -05:00
Liam 1d0fe75e7c hle: rename legacy errors to Results 2023-03-06 20:58:42 -05:00
liamwhite 6d61430311 Merge pull request #9890 from Kelebek1/reverb_fix
Fix a bug with the Reverb command in reading from the pre delay line
2023-03-06 11:23:34 -05:00
liamwhite b210174087 Merge pull request #9910 from jbeich/libc++
kernel: add missing header for libc++
2023-03-06 11:21:51 -05:00
liamwhite e6349fcd3b Merge pull request #9905 from german77/usbssl
Service: USB, SSL, PSC: Update
2023-03-06 11:21:37 -05:00
liamwhite f7e6bda5cd Merge pull request #9907 from german77/joycon
input_common: joycon: Add stick input from passive reports
2023-03-06 11:21:27 -05:00
liamwhite 31f0fa1065 Merge pull request #9908 from german77/pfp
service: acc: Replace default image with a 32x32 image
2023-03-06 11:21:17 -05:00
liamwhite 3bd29fb66b Merge pull request #9909 from eltociear/patch-1
fix typo in settings.h
2023-03-06 11:21:06 -05:00
Jan Beich 859fb469b8 kernel: add missing header for libc++
In file included from src/core/hle/kernel/k_light_lock.cpp:4:
In file included from src/./core/hle/kernel/k_light_lock.h:8:
src/./core/hle/kernel/k_scoped_lock.h:25:51: error: no member named 'addressof' in namespace 'std'
    explicit KScopedLock(T& l) : KScopedLock(std::addressof(l)) {}
                                             ~~~~~^
2023-03-06 11:49:25 +00:00
Ikko Eltociear Ashimine c161e3f433 fix typo in settings.h
Intial -> Initial
2023-03-06 20:28:47 +09:00
Narr the Reg 8a501ff30b service: acc: Replace default image with a 32x32 image 2023-03-05 16:36:19 -06:00
german77 97704b8da9 input_common: joycon: Add stick input from passive reports 2023-03-05 12:50:15 -06:00
Narr the Reg 1f57ae6949 service: psc: Update names 2023-03-05 12:02:10 -06:00
Narr the Reg f01540da6c service: ssl: Add missing properties and update names 2023-03-05 12:02:04 -06:00
Narr the Reg 54711df739 service: usb: Update names 2023-03-05 10:45:24 -06:00
Liam 644ee0043e kernel: fix WaitSynchronization 2023-03-05 10:29:10 -05:00
Fernando S fdae95efaa Merge pull request #9786 from FernandoS27/the-gaia-is-a-lie
YFC - Engines: Implement Accelerate DMA Texture.
2023-03-05 15:30:47 +01:00
Fernando Sahmkow 8a3411b417 Engines: Implement Accelerate DMA Texture. 2023-03-05 12:18:00 +01:00
Morph 376a414f5b native_clock: Round RDTSC frequency to the nearest 1000 2023-03-05 02:36:31 -05:00
Morph 026eaddbee timer_resolution: Set current process to High QoS
Ensures that this process is treated as a high performance process by the Windows scheduler.
2023-03-05 02:36:31 -05:00
Morph 3453beb1e0 general: Target Windows 10 SDK
We no longer support operating systems below Windows 10.
2023-03-05 02:36:31 -05:00
Morph 194cf0b497 hardware_properties: Update BASE_CLOCK_RATE to exactly 1020 MHz 2023-03-05 02:36:31 -05:00
Morph bff1453282 core_timing: Use higher precision sleeps on Windows
The precision of sleep_for and wait_for is limited to 1-1.5ms on Windows.
Using SleepForOneTick() allows us to sleep for exactly one interval of the current timer resolution.
This allows us to take advantage of systems that have a timer resolution of 0.5ms to reduce CPU overhead in the event loop.
2023-03-05 02:36:31 -05:00
Morph 7e353082ac main: (Windows) Set the current timer resolution to the maximum
Increases the precision of thread sleeps on Windows.
2023-03-05 02:36:31 -05:00
Morph 7fffdf83b7 wall_clock: Make use of SteadyClock 2023-03-05 02:36:31 -05:00
Morph 1ed49f92dd common: Implement a method to change the Windows timer resolution
This utilizes undocumented NtDll functions to change the current timer resolution from the default of 1ms.
2023-03-05 01:41:28 -05:00
Morph bd09c82521 common: Implement a high resolution steady clock
This implementation provides a consistent, high performance, and high resolution clock where/when std::chrono::steady_clock does not provide sufficient precision.
2023-03-05 01:41:19 -05:00
Morph ce8f4da638 Merge pull request #9884 from liamwhite/service-cleanup
service: miscellaneous cleanups
2023-03-03 22:51:17 -05:00
Kelebek1 a7fb80e612 Check all swizzle components for red, not just [0], pass float border color rather than int 2023-03-04 02:33:50 +00:00
Behunin 44518b225c gpu_thread: Use bounded queue 2023-03-03 18:20:56 -07:00
bunnei 1f98634371 Merge pull request #9855 from liamwhite/kern-16-support
kernel: support for 16.0.0
2023-03-03 14:42:00 -08:00
Morph b4b3454d9b ci: Actually enable LTO on MSVC (#9887) 2023-03-02 14:47:20 +01:00
Kelebek1 104cb6aa0a Fix a bug with the Reverb command in reading from the pre_delay line. 2023-03-02 06:00:55 +00:00
bunnei 99d763888f Merge pull request #9888 from liamwhite/vids
vulkan_common: disable vertexInputDynamicState on unsupported driver
2023-03-01 21:22:06 -08:00
Liam ec6ee04c64 vulkan_common: disable vertexInputDynamicState on unsupported driver 2023-03-01 22:48:12 -05:00
Liam 97f7f7bad5 kernel: be more careful about kernel address keys 2023-03-01 10:42:45 -05:00
Liam c4ba088a5d kernel: refactor priority inheritance to represent locks as C++ objects 2023-03-01 10:42:45 -05:00
Liam 96bd7ea42d kernel: simplify AddressSpaceInfo, update values 2023-03-01 10:42:45 -05:00
Liam 367e89f984 kernel: barrier memory before condition variable write 2023-03-01 10:42:45 -05:00
Liam 9f9b64cda2 kernel: document previous location of interrupt disables in arbiter/condvar 2023-03-01 10:42:45 -05:00
Liam 4165ac0680 kernel: adjust pool allocations 2023-03-01 10:42:45 -05:00
Liam 62711fec02 kernel: simplify KAbstractSchedulerLock::Lock 2023-03-01 10:42:45 -05:00
Liam 0746a2084e kernel: add InfoType::IoRegionHint 2023-03-01 10:42:45 -05:00
Liam 809148e1a5 nvnflinger: fix name 2023-03-01 10:39:49 -05:00
Liam 65be230fdd service: move hle_ipc from kernel 2023-03-01 10:39:49 -05:00
Liam 4a1aa98598 sm:: remove unused member 2023-03-01 10:39:36 -05:00
liamwhite 97f7a560f3 Merge pull request #9832 from liamwhite/hle-mp
service: HLE multiprocess
2023-03-01 10:38:20 -05:00
liamwhite da11c40849 Merge pull request #9879 from zhaobot/tx-update-20230301024940
Update translations (2023-03-01)
2023-02-28 22:23:52 -05:00
The yuzu Community 6efd335eda Update translations (2023-03-01) 2023-03-01 02:49:50 +00:00
liamwhite 1346b14bef Merge pull request #9877 from abouvier/cmake-boost
cmake: use correct boost imported targets
2023-02-28 18:40:44 -05:00
liamwhite 304d6e9870 Merge pull request #9862 from abouvier/cmake-components
cmake: support components in find modules
2023-02-28 16:36:28 -05:00
Alexandre Bouvier 57fd8b1f45 cmake: use correct boost imported targets 2023-02-28 17:56:01 +01:00
ameerj 2ce5bb9bd6 buffer_cache: Add logic for non-NVN storage buffer tracking 2023-02-25 16:24:21 -05:00
Liam 72e5552409 sm:: fix lingering session initialization issues 2023-02-21 12:19:25 -05:00
Liam 87749d217e cheat_engine: add check for hid initialization 2023-02-21 12:19:25 -05:00
Liam 6e0a33089b sm:: support service registration deferral 2023-02-21 12:19:25 -05:00
Liam a936972614 service: refactor server architecture
Converts services to have their own processes
2023-02-21 12:19:25 -05:00
Liam 23151ff498 core: defer cpu shutdown 2023-02-21 12:19:25 -05:00
579 changed files with 18356 additions and 15656 deletions
+1 -1
View File
@@ -40,7 +40,7 @@ def parse_imports(file_name):
def parse_imports_recursive(file_name, path_list=[]):
q = queue.Queue() # create a FIFO queue
# file_name can be a string or a list for the convience
# file_name can be a string or a list for the convenience
if isinstance(file_name, str):
q.put(file_name)
elif isinstance(file_name, list):
+1 -1
View File
@@ -9,7 +9,7 @@ parameters:
steps:
- script: choco install vulkan-sdk
displayName: 'Install vulkan-sdk'
- script: refreshenv && mkdir build && cd build && cmake -E env CXXFLAGS="/Gw /GA /Gr /Ob2" cmake -G "Visual Studio 17 2022" -A x64 -DCMAKE_POLICY_DEFAULT_CMP0069=NEW -DENABLE_LTO=ON -DYUZU_USE_BUNDLED_QT=1 -DYUZU_USE_BUNDLED_SDL2=1 -DYUZU_USE_QT_WEB_ENGINE=ON -DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON -DYUZU_ENABLE_COMPATIBILITY_REPORTING=${COMPAT} -DYUZU_TESTS=OFF -DUSE_DISCORD_PRESENCE=ON -DENABLE_QT_TRANSLATION=ON -DDISPLAY_VERSION=${{ parameters['version'] }} -DCMAKE_BUILD_TYPE=Release -DYUZU_CRASH_DUMPS=ON .. && cd ..
- script: refreshenv && mkdir build && cd build && cmake -E env CXXFLAGS="/Gw /GA /Gr /Ob2" cmake -G "Visual Studio 17 2022" -A x64 -DCMAKE_POLICY_DEFAULT_CMP0069=NEW -DYUZU_ENABLE_LTO=ON -DYUZU_USE_BUNDLED_QT=1 -DYUZU_USE_BUNDLED_SDL2=1 -DYUZU_USE_QT_WEB_ENGINE=ON -DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON -DYUZU_ENABLE_COMPATIBILITY_REPORTING=${COMPAT} -DYUZU_TESTS=OFF -DUSE_DISCORD_PRESENCE=ON -DENABLE_QT_TRANSLATION=ON -DDISPLAY_VERSION=${{ parameters['version'] }} -DCMAKE_BUILD_TYPE=Release -DYUZU_CRASH_DUMPS=ON .. && cd ..
displayName: 'Configure CMake'
- task: MSBuild@1
displayName: 'Build'
+6
View File
@@ -0,0 +1,6 @@
; SPDX-FileCopyrightText: 2023 yuzu Emulator Project
; SPDX-License-Identifier: GPL-2.0-or-later
[codespell]
skip = ./.git,./build,./dist,./Doxyfile,./externals,./LICENSES
ignore-words-list = aci,allright,ba,deques,froms,hda,inout,lod,masia,nam,nax,nd,pullrequests,pullrequest,te,transfered,unstall,uscaled,zink
+17
View File
@@ -0,0 +1,17 @@
# SPDX-FileCopyrightText: 2023 yuzu Emulator Project
# SPDX-License-Identifier: GPL-2.0-or-later
# GitHub Action to automate the identification of common misspellings in text files.
# https://github.com/codespell-project/actions-codespell
# https://github.com/codespell-project/codespell
name: codespell
on: pull_request
permissions: {}
jobs:
codespell:
name: Check for spelling errors
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
persist-credentials: false
- uses: codespell-project/actions-codespell@master
+6 -30
View File
@@ -210,6 +210,7 @@ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin)
# =======================================================================
# Enforce the search mode of non-required packages for better and shorter failure messages
find_package(Boost 1.73.0 REQUIRED context)
find_package(enet 1.3 MODULE)
find_package(fmt 9 REQUIRED)
find_package(inih 52 MODULE COMPONENTS INIReader)
@@ -253,19 +254,6 @@ if (YUZU_TESTS)
find_package(Catch2 3.0.1 REQUIRED)
endif()
find_package(Boost 1.73.0 COMPONENTS context)
if (Boost_FOUND)
set(Boost_LIBRARIES Boost::boost)
# Conditionally add Boost::context only if the found Boost package provides it
# The old version is missing Boost::context, so we want to avoid adding in that case
# The new version requires adding Boost::context to prevent linking issues
if (TARGET Boost::context)
list(APPEND Boost_LIBRARIES Boost::context)
endif()
else()
message(FATAL_ERROR "Boost 1.73.0 or newer not found")
endif()
# boost:asio has functions that require AcceptEx et al
if (MINGW)
find_library(MSWSOCK_LIBRARY mswsock REQUIRED)
@@ -356,12 +344,12 @@ if(ENABLE_QT)
find_package(PkgConfig REQUIRED)
pkg_check_modules(QT_DEP_GLU QUIET glu>=9.0.0)
if (NOT QT_DEP_GLU_FOUND)
message(FATAL_ERROR "Qt bundled pacakge dependency `glu` not found. \
message(FATAL_ERROR "Qt bundled package dependency `glu` not found. \
Perhaps `libglu1-mesa-dev` needs to be installed?")
endif()
pkg_check_modules(QT_DEP_MESA QUIET dri>=20.0.8)
if (NOT QT_DEP_MESA_FOUND)
message(FATAL_ERROR "Qt bundled pacakge dependency `dri` not found. \
message(FATAL_ERROR "Qt bundled package dependency `dri` not found. \
Perhaps `mesa-common-dev` needs to be installed?")
endif()
@@ -462,14 +450,6 @@ if (ENABLE_SDL2)
endif()
endif()
# Reexport some targets that are named differently when using the upstream CmakeConfig
# In order to ALIAS targets to a new name, they first need to be IMPORTED_GLOBAL
# Dynarmic checks for target `boost` and so we want to make sure it can find it through our system instead of using their external
if (TARGET Boost::boost)
set_target_properties(Boost::boost PROPERTIES IMPORTED_GLOBAL TRUE)
add_library(boost ALIAS Boost::boost)
endif()
# List of all FFmpeg components required
set(FFmpeg_COMPONENTS
avcodec
@@ -497,8 +477,8 @@ if (APPLE)
find_library(COCOA_LIBRARY Cocoa)
set(PLATFORM_LIBRARIES ${COCOA_LIBRARY} ${IOKIT_LIBRARY} ${COREVIDEO_LIBRARY})
elseif (WIN32)
# WSAPoll and SHGetKnownFolderPath (AppData/Roaming) didn't exist before WinNT 6.x (Vista)
add_definitions(-D_WIN32_WINNT=0x0600 -DWINVER=0x0600)
# Target Windows 10
add_definitions(-D_WIN32_WINNT=0x0A00 -DWINVER=0x0A00)
set(PLATFORM_LIBRARIES winmm ws2_32 iphlpapi)
if (MINGW)
# PSAPI is the Process Status API
@@ -585,11 +565,7 @@ function(create_target_directory_groups target_name)
endfunction()
# Prevent boost from linking against libs when building
add_definitions(-DBOOST_ERROR_CODE_HEADER_ONLY
-DBOOST_SYSTEM_NO_LIB
-DBOOST_DATE_TIME_NO_LIB
-DBOOST_REGEX_NO_LIB
)
target_link_libraries(Boost::headers INTERFACE Boost::disable_autolinking)
# Adjustments for MSVC + Ninja
if (MSVC AND CMAKE_GENERATOR STREQUAL "Ninja")
add_compile_options(
+1 -1
View File
@@ -14,7 +14,7 @@
# FFmpeg_LIBRARIES: aggregate all the paths to the libraries
# FFmpeg_FOUND: True if all components have been found
#
# This module defines the following targets, which are prefered over variables:
# This module defines the following targets, which are preferred over variables:
#
# FFmpeg::<component>: Target to use <component> directly, with include path,
# library and dependencies set up. If you are using a static build, you are
+398 -343
View File
File diff suppressed because it is too large Load Diff
+399 -344
View File
File diff suppressed because it is too large Load Diff
+397 -342
View File
File diff suppressed because it is too large Load Diff
+398 -343
View File
File diff suppressed because it is too large Load Diff
+398 -343
View File
File diff suppressed because it is too large Load Diff
+398 -343
View File
File diff suppressed because it is too large Load Diff
+452 -397
View File
File diff suppressed because it is too large Load Diff
+397 -342
View File
File diff suppressed because it is too large Load Diff
+435 -380
View File
File diff suppressed because it is too large Load Diff
+469 -413
View File
File diff suppressed because it is too large Load Diff
+398 -343
View File
File diff suppressed because it is too large Load Diff
+398 -343
View File
File diff suppressed because it is too large Load Diff
+399 -344
View File
File diff suppressed because it is too large Load Diff
+398 -343
View File
File diff suppressed because it is too large Load Diff
+616 -555
View File
File diff suppressed because it is too large Load Diff
+616 -555
View File
File diff suppressed because it is too large Load Diff
+451 -390
View File
File diff suppressed because it is too large Load Diff
+400 -345
View File
File diff suppressed because it is too large Load Diff
+398 -343
View File
File diff suppressed because it is too large Load Diff
+433 -372
View File
File diff suppressed because it is too large Load Diff
+402 -347
View File
File diff suppressed because it is too large Load Diff
+398 -343
View File
File diff suppressed because it is too large Load Diff
-6
View File
@@ -36,12 +36,6 @@ SPDX-License-Identifier: GPL-2.0-or-later
<application>
<!-- Windows 10 -->
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
<!-- Windows 8.1 -->
<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
<!-- Windows 8 -->
<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
<!-- Windows 7 -->
<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
</application>
</compatibility>
<trustInfo
+1 -1
View File
@@ -83,7 +83,7 @@ if (MSVC)
)
if (USE_CCACHE OR YUZU_USE_PRECOMPILED_HEADERS)
# when caching, we need to use /Z7 to downgrade debug info to use an older but more cachable format
# when caching, we need to use /Z7 to downgrade debug info to use an older but more cacheable format
# Precompiled headers are deleted if not using /Z7. See https://github.com/nanoant/CMakePCHCompiler/issues/21
add_compile_options(/Z7)
else()
+1 -1
View File
@@ -20,7 +20,7 @@ Manager::Manager(Core::System& system_) : system{system_} {
Result Manager::AcquireSessionId(size_t& session_id) {
if (num_free_sessions == 0) {
LOG_ERROR(Service_Audio, "All 4 AudioIn sessions are in use, cannot create any more");
return Service::Audio::ERR_MAXIMUM_SESSIONS_REACHED;
return Service::Audio::ResultOutOfSessions;
}
session_id = session_ids[next_session_id];
next_session_id = (next_session_id + 1) % MaxInSessions;
+2 -2
View File
@@ -19,7 +19,7 @@ void AudioManager::Shutdown() {
Result AudioManager::SetOutManager(BufferEventFunc buffer_func) {
if (!running) {
return Service::Audio::ERR_OPERATION_FAILED;
return Service::Audio::ResultOperationFailed;
}
std::scoped_lock l{lock};
@@ -35,7 +35,7 @@ Result AudioManager::SetOutManager(BufferEventFunc buffer_func) {
Result AudioManager::SetInManager(BufferEventFunc buffer_func) {
if (!running) {
return Service::Audio::ERR_OPERATION_FAILED;
return Service::Audio::ResultOperationFailed;
}
std::scoped_lock l{lock};
+1 -1
View File
@@ -19,7 +19,7 @@ Manager::Manager(Core::System& system_) : system{system_} {
Result Manager::AcquireSessionId(size_t& session_id) {
if (num_free_sessions == 0) {
LOG_ERROR(Service_Audio, "All 12 Audio Out sessions are in use, cannot create any more");
return Service::Audio::ERR_MAXIMUM_SESSIONS_REACHED;
return Service::Audio::ResultOutOfSessions;
}
session_id = session_ids[next_session_id];
next_session_id = (next_session_id + 1) % MaxOutSessions;
+1 -1
View File
@@ -58,7 +58,7 @@ public:
/**
* Get a list of audio out device names.
*
* @oaram names - Output container to write names to.
* @param names - Output container to write names to.
* @return Number of names written.
*/
u32 GetAudioOutDeviceNames(
+1 -1
View File
@@ -28,7 +28,7 @@ SystemManager& Manager::GetSystemManager() {
Result Manager::GetWorkBufferSize(const AudioRendererParameterInternal& params,
u64& out_count) const {
if (!CheckValidRevision(params.revision)) {
return Service::Audio::ERR_INVALID_REVISION;
return Service::Audio::ResultInvalidRevision;
}
out_count = System::GetWorkBufferSize(params);
+1 -1
View File
@@ -16,7 +16,7 @@ struct AudioBuffer {
s64 played_timestamp;
/// Game memory address for these samples.
VAddr samples;
/// Unqiue identifier for this buffer.
/// Unique identifier for this buffer.
u64 tag;
/// Size of the samples buffer.
u64 size;
+1 -1
View File
@@ -46,7 +46,7 @@ Result In::AppendBuffer(const AudioInBuffer& buffer, u64 tag) {
if (system.AppendBuffer(buffer, tag)) {
return ResultSuccess;
}
return Service::Audio::ERR_BUFFER_COUNT_EXCEEDED;
return Service::Audio::ResultBufferCountReached;
}
void In::ReleaseAndRegisterBuffers() {
+3 -3
View File
@@ -45,11 +45,11 @@ Result System::IsConfigValid(const std::string_view device_name,
const AudioInParameter& in_params) const {
if ((device_name.size() > 0) &&
(device_name != GetDefaultDeviceName() && device_name != GetDefaultUacDeviceName())) {
return Service::Audio::ERR_INVALID_DEVICE_NAME;
return Service::Audio::ResultNotFound;
}
if (in_params.sample_rate != TargetSampleRate && in_params.sample_rate > 0) {
return Service::Audio::ERR_INVALID_SAMPLE_RATE;
return Service::Audio::ResultInvalidSampleRate;
}
return ResultSuccess;
@@ -80,7 +80,7 @@ Result System::Initialize(std::string device_name, const AudioInParameter& in_pa
Result System::Start() {
if (state != State::Stopped) {
return Service::Audio::ERR_OPERATION_FAILED;
return Service::Audio::ResultOperationFailed;
}
session->Initialize(name, sample_format, channel_count, session_id, handle,
+1 -1
View File
@@ -46,7 +46,7 @@ Result Out::AppendBuffer(const AudioOutBuffer& buffer, const u64 tag) {
if (system.AppendBuffer(buffer, tag)) {
return ResultSuccess;
}
return Service::Audio::ERR_BUFFER_COUNT_EXCEEDED;
return Service::Audio::ResultBufferCountReached;
}
void Out::ReleaseAndRegisterBuffers() {
+4 -4
View File
@@ -33,11 +33,11 @@ std::string_view System::GetDefaultOutputDeviceName() const {
Result System::IsConfigValid(std::string_view device_name,
const AudioOutParameter& in_params) const {
if ((device_name.size() > 0) && (device_name != GetDefaultOutputDeviceName())) {
return Service::Audio::ERR_INVALID_DEVICE_NAME;
return Service::Audio::ResultNotFound;
}
if (in_params.sample_rate != TargetSampleRate && in_params.sample_rate > 0) {
return Service::Audio::ERR_INVALID_SAMPLE_RATE;
return Service::Audio::ResultInvalidSampleRate;
}
if (in_params.channel_count == 0 || in_params.channel_count == 2 ||
@@ -45,7 +45,7 @@ Result System::IsConfigValid(std::string_view device_name,
return ResultSuccess;
}
return Service::Audio::ERR_INVALID_CHANNEL_COUNT;
return Service::Audio::ResultInvalidChannelCount;
}
Result System::Initialize(std::string device_name, const AudioOutParameter& in_params, u32 handle_,
@@ -80,7 +80,7 @@ size_t System::GetSessionId() const {
Result System::Start() {
if (state != State::Stopped) {
return Service::Audio::ERR_OPERATION_FAILED;
return Service::Audio::ResultOperationFailed;
}
session->Initialize(name, sample_format, channel_count, session_id, handle,
@@ -135,7 +135,7 @@ void AudioRenderer::ThreadFunc() {
static constexpr char name[]{"AudioRenderer"};
MicroProfileOnThreadCreate(name);
Common::SetCurrentThreadName(name);
Common::SetCurrentThreadPriority(Common::ThreadPriority::Critical);
Common::SetCurrentThreadPriority(Common::ThreadPriority::High);
if (mailbox->ADSPWaitMessage() != RenderMessage::AudioRenderer_InitializeOK) {
LOG_ERROR(Service_Audio,
"ADSP Audio Renderer -- Failed to receive initialize message from host!");
@@ -165,7 +165,7 @@ void AudioRenderer::ThreadFunc() {
// Check this buffer is valid, as it may not be used.
if (command_buffer.buffer != 0) {
// If there are no remaining commands (from the previous list),
// this is a new command list, initalize it.
// this is a new command list, initialize it.
if (command_buffer.remaining_command_count == 0) {
command_list_processor.Initialize(system, command_buffer.buffer,
command_buffer.size, streams[index]);
+1 -1
View File
@@ -22,7 +22,7 @@ Result Renderer::Initialize(const AudioRendererParameterInternal& params,
if (!manager.AddSystem(system)) {
LOG_ERROR(Service_Audio,
"Both Audio Render sessions are in use, cannot create any more");
return Service::Audio::ERR_MAXIMUM_SESSIONS_REACHED;
return Service::Audio::ResultOutOfSessions;
}
system_registered = true;
}
@@ -155,7 +155,7 @@ public:
/**
* Check if a variadic command buffer is supported.
* As of Rev 5 with the added optional performance metric logging, the command
* buffer can be a variable size, so take that into account for calcualting its size.
* buffer can be a variable size, so take that into account for calculating its size.
*
* @return True if supported, otherwise false.
*/
@@ -48,7 +48,7 @@ Result InfoUpdater::UpdateVoiceChannelResources(VoiceContext& voice_context) {
LOG_ERROR(Service_Audio,
"Consumed an incorrect voice resource size, header size={}, consumed={}",
in_header->voice_resources_size, consumed_input_size);
return Service::Audio::ERR_INVALID_UPDATE_DATA;
return Service::Audio::ResultInvalidUpdateInfo;
}
input += consumed_input_size;
@@ -123,7 +123,7 @@ Result InfoUpdater::UpdateVoices(VoiceContext& voice_context,
if (consumed_input_size != in_header->voices_size) {
LOG_ERROR(Service_Audio, "Consumed an incorrect voices size, header size={}, consumed={}",
in_header->voices_size, consumed_input_size);
return Service::Audio::ERR_INVALID_UPDATE_DATA;
return Service::Audio::ResultInvalidUpdateInfo;
}
out_header->voices_size = consumed_output_size;
@@ -184,7 +184,7 @@ Result InfoUpdater::UpdateEffectsVersion1(EffectContext& effect_context, const b
if (consumed_input_size != in_header->effects_size) {
LOG_ERROR(Service_Audio, "Consumed an incorrect effects size, header size={}, consumed={}",
in_header->effects_size, consumed_input_size);
return Service::Audio::ERR_INVALID_UPDATE_DATA;
return Service::Audio::ResultInvalidUpdateInfo;
}
out_header->effects_size = consumed_output_size;
@@ -239,7 +239,7 @@ Result InfoUpdater::UpdateEffectsVersion2(EffectContext& effect_context, const b
if (consumed_input_size != in_header->effects_size) {
LOG_ERROR(Service_Audio, "Consumed an incorrect effects size, header size={}, consumed={}",
in_header->effects_size, consumed_input_size);
return Service::Audio::ERR_INVALID_UPDATE_DATA;
return Service::Audio::ResultInvalidUpdateInfo;
}
out_header->effects_size = consumed_output_size;
@@ -267,7 +267,7 @@ Result InfoUpdater::UpdateMixes(MixContext& mix_context, const u32 mix_buffer_co
}
if (mix_buffer_count == 0) {
return Service::Audio::ERR_INVALID_UPDATE_DATA;
return Service::Audio::ResultInvalidUpdateInfo;
}
std::span<const MixInfo::InParameter> in_params{
@@ -281,13 +281,13 @@ Result InfoUpdater::UpdateMixes(MixContext& mix_context, const u32 mix_buffer_co
total_buffer_count += params.buffer_count;
if (params.dest_mix_id > static_cast<s32>(mix_context.GetCount()) &&
params.dest_mix_id != UnusedMixId && params.mix_id != FinalMixId) {
return Service::Audio::ERR_INVALID_UPDATE_DATA;
return Service::Audio::ResultInvalidUpdateInfo;
}
}
}
if (total_buffer_count > mix_buffer_count) {
return Service::Audio::ERR_INVALID_UPDATE_DATA;
return Service::Audio::ResultInvalidUpdateInfo;
}
bool mix_dirty{false};
@@ -317,7 +317,7 @@ Result InfoUpdater::UpdateMixes(MixContext& mix_context, const u32 mix_buffer_co
if (mix_dirty) {
if (behaviour.IsSplitterSupported() && splitter_context.UsingSplitter()) {
if (!mix_context.TSortInfo(splitter_context)) {
return Service::Audio::ERR_INVALID_UPDATE_DATA;
return Service::Audio::ResultInvalidUpdateInfo;
}
} else {
mix_context.SortInfo();
@@ -327,7 +327,7 @@ Result InfoUpdater::UpdateMixes(MixContext& mix_context, const u32 mix_buffer_co
if (consumed_input_size != in_header->mix_size) {
LOG_ERROR(Service_Audio, "Consumed an incorrect mixes size, header size={}, consumed={}",
in_header->mix_size, consumed_input_size);
return Service::Audio::ERR_INVALID_UPDATE_DATA;
return Service::Audio::ResultInvalidUpdateInfo;
}
input += mix_count * sizeof(MixInfo::InParameter);
@@ -384,7 +384,7 @@ Result InfoUpdater::UpdateSinks(SinkContext& sink_context, std::span<MemoryPoolI
if (consumed_input_size != in_header->sinks_size) {
LOG_ERROR(Service_Audio, "Consumed an incorrect sinks size, header size={}, consumed={}",
in_header->sinks_size, consumed_input_size);
return Service::Audio::ERR_INVALID_UPDATE_DATA;
return Service::Audio::ResultInvalidUpdateInfo;
}
input += consumed_input_size;
@@ -411,7 +411,7 @@ Result InfoUpdater::UpdateMemoryPools(std::span<MemoryPoolInfo> memory_pools,
state != MemoryPoolInfo::ResultState::MapFailed &&
state != MemoryPoolInfo::ResultState::InUse) {
LOG_WARNING(Service_Audio, "Invalid ResultState from updating memory pools");
return Service::Audio::ERR_INVALID_UPDATE_DATA;
return Service::Audio::ResultInvalidUpdateInfo;
}
}
@@ -423,7 +423,7 @@ Result InfoUpdater::UpdateMemoryPools(std::span<MemoryPoolInfo> memory_pools,
LOG_ERROR(Service_Audio,
"Consumed an incorrect memory pool size, header size={}, consumed={}",
in_header->memory_pool_size, consumed_input_size);
return Service::Audio::ERR_INVALID_UPDATE_DATA;
return Service::Audio::ResultInvalidUpdateInfo;
}
input += consumed_input_size;
@@ -453,7 +453,7 @@ Result InfoUpdater::UpdatePerformanceBuffer(std::span<u8> performance_output,
LOG_ERROR(Service_Audio,
"Consumed an incorrect performance size, header size={}, consumed={}",
in_header->performance_buffer_size, consumed_input_size);
return Service::Audio::ERR_INVALID_UPDATE_DATA;
return Service::Audio::ResultInvalidUpdateInfo;
}
input += consumed_input_size;
@@ -467,18 +467,18 @@ Result InfoUpdater::UpdateBehaviorInfo(BehaviorInfo& behaviour_) {
const auto in_params{reinterpret_cast<const BehaviorInfo::InParameter*>(input)};
if (!CheckValidRevision(in_params->revision)) {
return Service::Audio::ERR_INVALID_UPDATE_DATA;
return Service::Audio::ResultInvalidUpdateInfo;
}
if (in_params->revision != behaviour_.GetUserRevision()) {
return Service::Audio::ERR_INVALID_UPDATE_DATA;
return Service::Audio::ResultInvalidUpdateInfo;
}
behaviour_.ClearError();
behaviour_.UpdateFlags(in_params->flags);
if (in_header->behaviour_size != sizeof(BehaviorInfo::InParameter)) {
return Service::Audio::ERR_INVALID_UPDATE_DATA;
return Service::Audio::ResultInvalidUpdateInfo;
}
input += sizeof(BehaviorInfo::InParameter);
@@ -500,7 +500,7 @@ Result InfoUpdater::UpdateErrorInfo(const BehaviorInfo& behaviour_) {
Result InfoUpdater::UpdateSplitterInfo(SplitterContext& splitter_context) {
u32 consumed_size{0};
if (!splitter_context.Update(input, consumed_size)) {
return Service::Audio::ERR_INVALID_UPDATE_DATA;
return Service::Audio::ResultInvalidUpdateInfo;
}
input += consumed_size;
@@ -529,9 +529,9 @@ Result InfoUpdater::UpdateRendererInfo(const u64 elapsed_frames) {
Result InfoUpdater::CheckConsumedSize() {
if (CpuAddr(input) - CpuAddr(input_origin.data()) != expected_input_size) {
return Service::Audio::ERR_INVALID_UPDATE_DATA;
return Service::Audio::ResultInvalidUpdateInfo;
} else if (CpuAddr(output) - CpuAddr(output_origin.data()) != expected_output_size) {
return Service::Audio::ERR_INVALID_UPDATE_DATA;
return Service::Audio::ResultInvalidUpdateInfo;
}
return ResultSuccess;
}
@@ -308,7 +308,8 @@ static void ApplyReverbEffect(const ReverbInfo::ParameterVersion2& params, Rever
}
Common::FixedPoint<50, 14> pre_delay_sample{
state.pre_delay_line.Read() * Common::FixedPoint<50, 14>::from_base(params.late_gain)};
state.pre_delay_line.TapOut(state.pre_delay_time) *
Common::FixedPoint<50, 14>::from_base(params.late_gain)};
std::array<Common::FixedPoint<50, 14>, ReverbInfo::MaxDelayLines> mix_matrix{
state.prev_feedback_output[2] + state.prev_feedback_output[1] + pre_delay_sample,
@@ -192,7 +192,7 @@ public:
/**
* Get this effect's parameter data.
*
* @return Pointer to the parametter, must be cast to the correct type.
* @return Pointer to the parameter, must be cast to the correct type.
*/
u8* GetParameter() {
return parameter.data();
@@ -201,7 +201,7 @@ public:
/**
* Get this effect's parameter data.
*
* @return Pointer to the parametter, must be cast to the correct type.
* @return Pointer to the parameter, must be cast to the correct type.
*/
u8* GetStateBuffer() {
return state.data();
+2 -1
View File
@@ -104,7 +104,8 @@ public:
}
void Write(const Common::FixedPoint<50, 14> sample) {
*(input++) = sample;
*input = sample;
input++;
if (input >= buffer_end) {
input = buffer.data();
}
+4 -4
View File
@@ -79,12 +79,10 @@ public:
return;
}
sample_count = delay_time;
input = &buffer[(output - buffer.data() + sample_count) % (sample_count_max + 1)];
input = &buffer[0];
}
Common::FixedPoint<50, 14> Tick(const Common::FixedPoint<50, 14> sample) {
Write(sample);
auto out_sample{Read()};
output++;
@@ -92,6 +90,7 @@ public:
output = buffer.data();
}
Write(sample);
return out_sample;
}
@@ -100,7 +99,8 @@ public:
}
void Write(const Common::FixedPoint<50, 14> sample) {
*(input++) = sample;
*input = sample;
input++;
if (input >= buffer_end) {
input = buffer.data();
}
@@ -29,7 +29,7 @@ public:
*/
enum class State {
Invalid,
Aquired,
Acquired,
RequestDetach,
Detached,
RequestAttach,
@@ -92,7 +92,7 @@ bool PoolMapper::TryAttachBuffer(BehaviorInfo::ErrorInfo& error_info, AddressInf
address_info.Setup(address, size);
if (!FillDspAddr(address_info)) {
error_info.error_code = Service::Audio::ERR_POOL_MAPPING_FAILED;
error_info.error_code = Service::Audio::ResultInvalidAddressInfo;
error_info.address = address;
return force_map;
}
+1 -1
View File
@@ -93,7 +93,7 @@ public:
* Splitter sort, traverse the splitter node graph and sort the sorted mixes from results.
*
* @param splitter_context - Splitter context for the sort.
* @return True if the sort was successful, othewise false.
* @return True if the sort was successful, otherwise false.
*/
bool TSortInfo(const SplitterContext& splitter_context);
@@ -33,7 +33,7 @@ struct PerformanceDetailVersion1 {
/* 0x0D */ PerformanceEntryType entry_type;
};
static_assert(sizeof(PerformanceDetailVersion1) == 0x10,
"PerformanceDetailVersion1 has the worng size!");
"PerformanceDetailVersion1 has the wrong size!");
struct PerformanceDetailVersion2 {
/* 0x00 */ u32 node_id;
@@ -45,6 +45,6 @@ struct PerformanceDetailVersion2 {
/* 0x14 */ char unk14[0x4];
};
static_assert(sizeof(PerformanceDetailVersion2) == 0x18,
"PerformanceDetailVersion2 has the worng size!");
"PerformanceDetailVersion2 has the wrong size!");
} // namespace AudioCore::AudioRenderer
@@ -22,7 +22,7 @@ struct PerformanceEntryVersion1 {
/* 0x0C */ PerformanceEntryType entry_type;
};
static_assert(sizeof(PerformanceEntryVersion1) == 0x10,
"PerformanceEntryVersion1 has the worng size!");
"PerformanceEntryVersion1 has the wrong size!");
struct PerformanceEntryVersion2 {
/* 0x00 */ u32 node_id;
@@ -32,6 +32,6 @@ struct PerformanceEntryVersion2 {
/* 0x0D */ char unk0D[0xB];
};
static_assert(sizeof(PerformanceEntryVersion2) == 0x18,
"PerformanceEntryVersion2 has the worng size!");
"PerformanceEntryVersion2 has the wrong size!");
} // namespace AudioCore::AudioRenderer
@@ -16,7 +16,7 @@ struct PerformanceFrameHeaderVersion1 {
/* 0x14 */ u32 frame_index;
};
static_assert(sizeof(PerformanceFrameHeaderVersion1) == 0x18,
"PerformanceFrameHeaderVersion1 has the worng size!");
"PerformanceFrameHeaderVersion1 has the wrong size!");
struct PerformanceFrameHeaderVersion2 {
/* 0x00 */ u32 magic; // "PERF"
@@ -31,6 +31,6 @@ struct PerformanceFrameHeaderVersion2 {
/* 0x25 */ char unk25[0xB];
};
static_assert(sizeof(PerformanceFrameHeaderVersion2) == 0x30,
"PerformanceFrameHeaderVersion2 has the worng size!");
"PerformanceFrameHeaderVersion2 has the wrong size!");
} // namespace AudioCore::AudioRenderer
@@ -55,7 +55,7 @@ public:
/**
* Get the total number of splitter destinations.
*
* @return Number of destiantions.
* @return Number of destinations.
*/
u32 GetDataCount() const;
@@ -87,7 +87,7 @@ public:
/**
* Update this destination.
*
* @param params - Inpout parameters to update the destination.
* @param params - Input parameters to update the destination.
*/
void Update(const InParameter& params);
@@ -126,9 +126,9 @@ private:
std::array<f32, MaxMixBuffers> prev_mix_volumes{0.0f};
/// Next destination in the mix chain
SplitterDestinationData* next{};
/// Is this destiantion in use?
/// Is this destination in use?
bool in_use{};
/// Does this destiantion need its volumes updated?
/// Does this destination need its volumes updated?
bool need_update{};
};
@@ -49,14 +49,14 @@ public:
/**
* Get the number of destinations in this splitter.
*
* @return The number of destiantions.
* @return The number of destinations.
*/
u32 GetDestinationCount() const;
/**
* Set the number of destinations in this splitter.
*
* @param count - The new number of destiantions.
* @param count - The new number of destinations.
*/
void SetDestinationCount(u32 count);
+25 -25
View File
@@ -101,15 +101,15 @@ Result System::Initialize(const AudioRendererParameterInternal& params,
Kernel::KTransferMemory* transfer_memory, u64 transfer_memory_size,
u32 process_handle_, u64 applet_resource_user_id_, s32 session_id_) {
if (!CheckValidRevision(params.revision)) {
return Service::Audio::ERR_INVALID_REVISION;
return Service::Audio::ResultInvalidRevision;
}
if (GetWorkBufferSize(params) > transfer_memory_size) {
return Service::Audio::ERR_INSUFFICIENT_BUFFER_SIZE;
return Service::Audio::ResultInsufficientBuffer;
}
if (process_handle_ == 0) {
return Service::Audio::ERR_INVALID_PROCESS_HANDLE;
return Service::Audio::ResultInvalidHandle;
}
behavior.SetUserLibRevision(params.revision);
@@ -143,19 +143,19 @@ Result System::Initialize(const AudioRendererParameterInternal& params,
samples_workbuffer =
allocator.Allocate<s32>((voice_channels + mix_buffer_count) * sample_count, 0x10);
if (samples_workbuffer.empty()) {
return Service::Audio::ERR_INSUFFICIENT_BUFFER_SIZE;
return Service::Audio::ResultInsufficientBuffer;
}
auto upsampler_workbuffer{allocator.Allocate<s32>(
(voice_channels + mix_buffer_count) * TargetSampleCount * upsampler_count, 0x10)};
if (upsampler_workbuffer.empty()) {
return Service::Audio::ERR_INSUFFICIENT_BUFFER_SIZE;
return Service::Audio::ResultInsufficientBuffer;
}
depop_buffer =
allocator.Allocate<s32>(Common::AlignUp(static_cast<u32>(mix_buffer_count), 0x40), 0x40);
if (depop_buffer.empty()) {
return Service::Audio::ERR_INSUFFICIENT_BUFFER_SIZE;
return Service::Audio::ResultInsufficientBuffer;
}
// invalidate samples_workbuffer DSP cache
@@ -166,12 +166,12 @@ Result System::Initialize(const AudioRendererParameterInternal& params,
}
if (voice_infos.empty()) {
return Service::Audio::ERR_INSUFFICIENT_BUFFER_SIZE;
return Service::Audio::ResultInsufficientBuffer;
}
auto sorted_voice_infos{allocator.Allocate<VoiceInfo*>(params.voices, 0x10)};
if (sorted_voice_infos.empty()) {
return Service::Audio::ERR_INSUFFICIENT_BUFFER_SIZE;
return Service::Audio::ResultInsufficientBuffer;
}
std::memset(sorted_voice_infos.data(), 0, sorted_voice_infos.size_bytes());
@@ -183,12 +183,12 @@ Result System::Initialize(const AudioRendererParameterInternal& params,
}
if (voice_channel_resources.empty()) {
return Service::Audio::ERR_INSUFFICIENT_BUFFER_SIZE;
return Service::Audio::ResultInsufficientBuffer;
}
auto voice_cpu_states{allocator.Allocate<VoiceState>(params.voices, 0x10)};
if (voice_cpu_states.empty()) {
return Service::Audio::ERR_INSUFFICIENT_BUFFER_SIZE;
return Service::Audio::ResultInsufficientBuffer;
}
for (auto& voice_state : voice_cpu_states) {
@@ -198,7 +198,7 @@ Result System::Initialize(const AudioRendererParameterInternal& params,
auto mix_infos{allocator.Allocate<MixInfo>(params.sub_mixes + 1, 0x10)};
if (mix_infos.empty()) {
return Service::Audio::ERR_INSUFFICIENT_BUFFER_SIZE;
return Service::Audio::ResultInsufficientBuffer;
}
u32 effect_process_order_count{0};
@@ -208,7 +208,7 @@ Result System::Initialize(const AudioRendererParameterInternal& params,
effect_process_order_count = params.effects * (params.sub_mixes + 1);
effect_process_order_buffer = allocator.Allocate<s32>(effect_process_order_count, 0x10);
if (effect_process_order_buffer.empty()) {
return Service::Audio::ERR_INSUFFICIENT_BUFFER_SIZE;
return Service::Audio::ResultInsufficientBuffer;
}
}
@@ -222,7 +222,7 @@ Result System::Initialize(const AudioRendererParameterInternal& params,
auto sorted_mix_infos{allocator.Allocate<MixInfo*>(params.sub_mixes + 1, 0x10)};
if (sorted_mix_infos.empty()) {
return Service::Audio::ERR_INSUFFICIENT_BUFFER_SIZE;
return Service::Audio::ResultInsufficientBuffer;
}
std::memset(sorted_mix_infos.data(), 0, sorted_mix_infos.size_bytes());
@@ -235,7 +235,7 @@ Result System::Initialize(const AudioRendererParameterInternal& params,
auto edge_matrix_workbuffer{allocator.Allocate<u8>(edge_matrix_size, 1)};
if (node_states_workbuffer.empty() || edge_matrix_workbuffer.size() == 0) {
return Service::Audio::ERR_INSUFFICIENT_BUFFER_SIZE;
return Service::Audio::ResultInsufficientBuffer;
}
mix_context.Initialize(sorted_mix_infos, mix_infos, params.sub_mixes + 1,
@@ -250,7 +250,7 @@ Result System::Initialize(const AudioRendererParameterInternal& params,
upsampler_manager = allocator.Allocate<UpsamplerManager>(1, 0x10).data();
if (upsampler_manager == nullptr) {
return Service::Audio::ERR_INSUFFICIENT_BUFFER_SIZE;
return Service::Audio::ResultInsufficientBuffer;
}
memory_pool_workbuffer = allocator.Allocate<MemoryPoolInfo>(memory_pool_count, 0x10);
@@ -259,18 +259,18 @@ Result System::Initialize(const AudioRendererParameterInternal& params,
}
if (memory_pool_workbuffer.empty() && memory_pool_count > 0) {
return Service::Audio::ERR_INSUFFICIENT_BUFFER_SIZE;
return Service::Audio::ResultInsufficientBuffer;
}
if (!splitter_context.Initialize(behavior, params, allocator)) {
return Service::Audio::ERR_INSUFFICIENT_BUFFER_SIZE;
return Service::Audio::ResultInsufficientBuffer;
}
std::span<EffectResultState> effect_result_states_cpu{};
if (behavior.IsEffectInfoVersion2Supported() && params.effects > 0) {
effect_result_states_cpu = allocator.Allocate<EffectResultState>(params.effects, 0x10);
if (effect_result_states_cpu.empty()) {
return Service::Audio::ERR_INSUFFICIENT_BUFFER_SIZE;
return Service::Audio::ResultInsufficientBuffer;
}
std::memset(effect_result_states_cpu.data(), 0, effect_result_states_cpu.size_bytes());
}
@@ -289,7 +289,7 @@ Result System::Initialize(const AudioRendererParameterInternal& params,
upsampler_workbuffer);
if (upsampler_infos.empty()) {
return Service::Audio::ERR_INSUFFICIENT_BUFFER_SIZE;
return Service::Audio::ResultInsufficientBuffer;
}
auto effect_infos{allocator.Allocate<EffectInfoBase>(params.effects, 0x40)};
@@ -298,14 +298,14 @@ Result System::Initialize(const AudioRendererParameterInternal& params,
}
if (effect_infos.empty() && params.effects > 0) {
return Service::Audio::ERR_INSUFFICIENT_BUFFER_SIZE;
return Service::Audio::ResultInsufficientBuffer;
}
std::span<EffectResultState> effect_result_states_dsp{};
if (behavior.IsEffectInfoVersion2Supported() && params.effects > 0) {
effect_result_states_dsp = allocator.Allocate<EffectResultState>(params.effects, 0x40);
if (effect_result_states_dsp.empty()) {
return Service::Audio::ERR_INSUFFICIENT_BUFFER_SIZE;
return Service::Audio::ResultInsufficientBuffer;
}
std::memset(effect_result_states_dsp.data(), 0, effect_result_states_dsp.size_bytes());
}
@@ -319,14 +319,14 @@ Result System::Initialize(const AudioRendererParameterInternal& params,
}
if (sinks.empty()) {
return Service::Audio::ERR_INSUFFICIENT_BUFFER_SIZE;
return Service::Audio::ResultInsufficientBuffer;
}
sink_context.Initialize(sinks, params.sinks);
auto voice_dsp_states{allocator.Allocate<VoiceState>(params.voices, 0x40)};
if (voice_dsp_states.empty()) {
return Service::Audio::ERR_INSUFFICIENT_BUFFER_SIZE;
return Service::Audio::ResultInsufficientBuffer;
}
for (auto& voice_state : voice_dsp_states) {
@@ -344,7 +344,7 @@ Result System::Initialize(const AudioRendererParameterInternal& params,
0xC};
performance_workbuffer = allocator.Allocate<u8>(perf_workbuffer_size, 0x40);
if (performance_workbuffer.empty()) {
return Service::Audio::ERR_INSUFFICIENT_BUFFER_SIZE;
return Service::Audio::ResultInsufficientBuffer;
}
std::memset(performance_workbuffer.data(), 0, performance_workbuffer.size_bytes());
performance_manager.Initialize(performance_workbuffer, performance_workbuffer.size_bytes(),
@@ -360,7 +360,7 @@ Result System::Initialize(const AudioRendererParameterInternal& params,
command_workbuffer_size = allocator.GetRemainingSize();
command_workbuffer = allocator.Allocate<u8>(command_workbuffer_size, 0x40);
if (command_workbuffer.empty()) {
return Service::Audio::ERR_INSUFFICIENT_BUFFER_SIZE;
return Service::Audio::ResultInsufficientBuffer;
}
command_buffer_size = 0;
+2 -2
View File
@@ -154,7 +154,7 @@ public:
ExecutionMode GetExecutionMode() const;
/**
* Get the rendering deivce for this system.
* Get the rendering device for this system.
* This is unused.
*
* @return Rendering device for this system.
@@ -241,7 +241,7 @@ private:
std::span<u8> command_workbuffer{};
/// Size of command workbuffer
u64 command_workbuffer_size{};
/// Numebr of commands in the workbuffer
/// Number of commands in the workbuffer
u64 command_buffer_size{};
/// Manager for upsamplers
UpsamplerManager* upsampler_manager{};
+3 -3
View File
@@ -36,7 +36,7 @@ public:
/**
* Initialize the system manager, called when any system is registered.
*
* @return True if sucessfully initialized, otherwise false.
* @return True if successfully initialized, otherwise false.
*/
bool InitializeUnsafe();
@@ -50,7 +50,7 @@ public:
* The manager does not own the system, so do not free it without calling Remove.
*
* @param system - The system to add.
* @return True if succesfully added, otherwise false.
* @return True if successfully added, otherwise false.
*/
bool Add(System& system);
@@ -58,7 +58,7 @@ public:
* Remove an audio render system from the manager.
*
* @param system - The system to remove.
* @return True if succesfully removed, otherwise false.
* @return True if successfully removed, otherwise false.
*/
bool Remove(System& system);
+4 -4
View File
@@ -181,7 +181,7 @@ void VoiceInfo::UpdateWaveBuffer(std::span<BehaviorInfo::ErrorInfo> error_info,
if (wave_buffer_internal.start_offset * byte_size > wave_buffer_internal.size ||
wave_buffer_internal.end_offset * byte_size > wave_buffer_internal.size) {
LOG_ERROR(Service_Audio, "Invalid PCM16 start/end wavebuffer sizes!");
error_info[0].error_code = Service::Audio::ERR_INVALID_UPDATE_DATA;
error_info[0].error_code = Service::Audio::ResultInvalidUpdateInfo;
error_info[0].address = wave_buffer_internal.address;
return;
}
@@ -192,7 +192,7 @@ void VoiceInfo::UpdateWaveBuffer(std::span<BehaviorInfo::ErrorInfo> error_info,
if (wave_buffer_internal.start_offset * byte_size > wave_buffer_internal.size ||
wave_buffer_internal.end_offset * byte_size > wave_buffer_internal.size) {
LOG_ERROR(Service_Audio, "Invalid PCMFloat start/end wavebuffer sizes!");
error_info[0].error_code = Service::Audio::ERR_INVALID_UPDATE_DATA;
error_info[0].error_code = Service::Audio::ResultInvalidUpdateInfo;
error_info[0].address = wave_buffer_internal.address;
return;
}
@@ -216,7 +216,7 @@ void VoiceInfo::UpdateWaveBuffer(std::span<BehaviorInfo::ErrorInfo> error_info,
if (start > static_cast<s64>(wave_buffer_internal.size) ||
end > static_cast<s64>(wave_buffer_internal.size)) {
LOG_ERROR(Service_Audio, "Invalid ADPCM start/end wavebuffer sizes!");
error_info[0].error_code = Service::Audio::ERR_INVALID_UPDATE_DATA;
error_info[0].error_code = Service::Audio::ResultInvalidUpdateInfo;
error_info[0].address = wave_buffer_internal.address;
return;
}
@@ -228,7 +228,7 @@ void VoiceInfo::UpdateWaveBuffer(std::span<BehaviorInfo::ErrorInfo> error_info,
if (wave_buffer_internal.start_offset < 0 || wave_buffer_internal.end_offset < 0) {
LOG_ERROR(Service_Audio, "Invalid input start/end wavebuffer sizes!");
error_info[0].error_code = Service::Audio::ERR_INVALID_UPDATE_DATA;
error_info[0].error_code = Service::Audio::ResultInvalidUpdateInfo;
error_info[0].address = wave_buffer_internal.address;
return;
}
+2 -2
View File
@@ -183,7 +183,7 @@ public:
void Initialize();
/**
* Does this voice ned an update?
* Does this voice need an update?
*
* @param params - Input parameters to check matching.
*
@@ -236,7 +236,7 @@ public:
*
* @param error_info - Output array of errors.
* @param wave_buffer - The wavebuffer to be updated.
* @param wave_buffer_internal - Input parametters to be used for the update.
* @param wave_buffer_internal - Input parameters to be used for the update.
* @param sample_format - Sample format of the wavebuffer.
* @param valid - Is this wavebuffer valid?
* @param pool_mapper - Used to map the wavebuffers.
+12 -1
View File
@@ -91,6 +91,7 @@ add_library(common STATIC
multi_level_page_table.h
nvidia_flags.cpp
nvidia_flags.h
overflow.h
page_table.cpp
page_table.h
param_package.cpp
@@ -113,6 +114,8 @@ add_library(common STATIC
socket_types.h
spin_lock.cpp
spin_lock.h
steady_clock.cpp
steady_clock.h
stream.cpp
stream.h
string_util.cpp
@@ -142,6 +145,14 @@ add_library(common STATIC
zstd_compression.h
)
if (WIN32)
target_sources(common PRIVATE
windows/timer_resolution.cpp
windows/timer_resolution.h
)
target_link_libraries(common PRIVATE ntdll)
endif()
if(ARCHITECTURE_x86_64)
target_sources(common
PRIVATE
@@ -176,7 +187,7 @@ endif()
create_target_directory_groups(common)
target_link_libraries(common PUBLIC ${Boost_LIBRARIES} fmt::fmt microprofile Threads::Threads)
target_link_libraries(common PUBLIC Boost::context Boost::headers fmt::fmt microprofile Threads::Threads)
target_link_libraries(common PRIVATE lz4::lz4 zstd::zstd LLVM::Demangle)
if (YUZU_USE_PRECOMPILED_HEADERS)
+1 -1
View File
@@ -66,7 +66,7 @@ public:
* @param description The room description
* @param port The port of the room
* @param net_version The version of the libNetwork that gets used
* @param has_password True if the room is passowrd protected
* @param has_password True if the room is password protected
* @param preferred_game The preferred game of the room
* @param preferred_game_id The title id of the preferred game
*/
+11 -9
View File
@@ -3,19 +3,21 @@
#pragma once
#include <cstring>
#include <type_traits>
#include <version>
#ifdef __cpp_lib_bit_cast
#include <bit>
#endif
namespace Common {
template <typename To, typename From>
[[nodiscard]] std::enable_if_t<sizeof(To) == sizeof(From) && std::is_trivially_copyable_v<From> &&
std::is_trivially_copyable_v<To>,
To>
BitCast(const From& src) noexcept {
To dst;
std::memcpy(&dst, &src, sizeof(To));
return dst;
constexpr inline To BitCast(const From& from) {
#ifdef __cpp_lib_bit_cast
return std::bit_cast<To>(from);
#else
return __builtin_bit_cast(To, from);
#endif
}
} // namespace Common
+211 -120
View File
@@ -1,158 +1,249 @@
// SPDX-FileCopyrightText: Copyright (c) 2020 Erik Rigtorp <erik@rigtorp.se>
// SPDX-License-Identifier: MIT
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <atomic>
#include <bit>
#include <condition_variable>
#include <memory>
#include <cstddef>
#include <mutex>
#include <new>
#include <stop_token>
#include <type_traits>
#include <utility>
#include "common/polyfill_thread.h"
namespace Common {
#if defined(__cpp_lib_hardware_interference_size)
constexpr size_t hardware_interference_size = std::hardware_destructive_interference_size;
#else
constexpr size_t hardware_interference_size = 64;
#endif
namespace detail {
constexpr size_t DefaultCapacity = 0x1000;
} // namespace detail
template <typename T, size_t Capacity = detail::DefaultCapacity>
class SPSCQueue {
static_assert((Capacity & (Capacity - 1)) == 0, "Capacity must be a power of two.");
template <typename T, size_t capacity = 0x400>
class MPSCQueue {
public:
explicit MPSCQueue() : allocator{std::allocator<Slot<T>>()} {
// Allocate one extra slot to prevent false sharing on the last slot
slots = allocator.allocate(capacity + 1);
// Allocators are not required to honor alignment for over-aligned types
// (see http://eel.is/c++draft/allocator.requirements#10) so we verify
// alignment here
if (reinterpret_cast<uintptr_t>(slots) % alignof(Slot<T>) != 0) {
allocator.deallocate(slots, capacity + 1);
throw std::bad_alloc();
}
for (size_t i = 0; i < capacity; ++i) {
std::construct_at(&slots[i]);
}
static_assert(std::has_single_bit(capacity), "capacity must be an integer power of 2");
static_assert(alignof(Slot<T>) == hardware_interference_size,
"Slot must be aligned to cache line boundary to prevent false sharing");
static_assert(sizeof(Slot<T>) % hardware_interference_size == 0,
"Slot size must be a multiple of cache line size to prevent "
"false sharing between adjacent slots");
static_assert(sizeof(MPSCQueue) % hardware_interference_size == 0,
"Queue size must be a multiple of cache line size to "
"prevent false sharing between adjacent queues");
template <typename... Args>
bool TryEmplace(Args&&... args) {
return Emplace<PushMode::Try>(std::forward<Args>(args)...);
}
~MPSCQueue() noexcept {
for (size_t i = 0; i < capacity; ++i) {
std::destroy_at(&slots[i]);
}
allocator.deallocate(slots, capacity + 1);
template <typename... Args>
void EmplaceWait(Args&&... args) {
Emplace<PushMode::Wait>(std::forward<Args>(args)...);
}
// The queue must be both non-copyable and non-movable
MPSCQueue(const MPSCQueue&) = delete;
MPSCQueue& operator=(const MPSCQueue&) = delete;
MPSCQueue(MPSCQueue&&) = delete;
MPSCQueue& operator=(MPSCQueue&&) = delete;
void Push(const T& v) noexcept {
static_assert(std::is_nothrow_copy_constructible_v<T>,
"T must be nothrow copy constructible");
emplace(v);
bool TryPop(T& t) {
return Pop<PopMode::Try>(t);
}
template <typename P, typename = std::enable_if_t<std::is_nothrow_constructible_v<T, P&&>>>
void Push(P&& v) noexcept {
emplace(std::forward<P>(v));
void PopWait(T& t) {
Pop<PopMode::Wait>(t);
}
void Pop(T& v, std::stop_token stop) noexcept {
auto const tail = tail_.fetch_add(1);
auto& slot = slots[idx(tail)];
if (!slot.turn.test()) {
std::unique_lock lock{cv_mutex};
cv.wait(lock, stop, [&slot] { return slot.turn.test(); });
}
v = slot.move();
slot.destroy();
slot.turn.clear();
slot.turn.notify_one();
void PopWait(T& t, std::stop_token stop_token) {
Pop<PopMode::WaitWithStopToken>(t, stop_token);
}
T PopWait() {
T t;
Pop<PopMode::Wait>(t);
return t;
}
T PopWait(std::stop_token stop_token) {
T t;
Pop<PopMode::WaitWithStopToken>(t, stop_token);
return t;
}
private:
template <typename U = T>
struct Slot {
~Slot() noexcept {
if (turn.test()) {
destroy();
}
}
template <typename... Args>
void construct(Args&&... args) noexcept {
static_assert(std::is_nothrow_constructible_v<U, Args&&...>,
"T must be nothrow constructible with Args&&...");
std::construct_at(reinterpret_cast<U*>(&storage), std::forward<Args>(args)...);
}
void destroy() noexcept {
static_assert(std::is_nothrow_destructible_v<U>, "T must be nothrow destructible");
std::destroy_at(reinterpret_cast<U*>(&storage));
}
U&& move() noexcept {
return reinterpret_cast<U&&>(storage);
}
// Align to avoid false sharing between adjacent slots
alignas(hardware_interference_size) std::atomic_flag turn{};
struct aligned_store {
struct type {
alignas(U) unsigned char data[sizeof(U)];
};
};
typename aligned_store::type storage;
enum class PushMode {
Try,
Wait,
Count,
};
enum class PopMode {
Try,
Wait,
WaitWithStopToken,
Count,
};
template <PushMode Mode, typename... Args>
bool Emplace(Args&&... args) {
const size_t write_index = m_write_index.load(std::memory_order::relaxed);
if constexpr (Mode == PushMode::Try) {
// Check if we have free slots to write to.
if ((write_index - m_read_index.load(std::memory_order::acquire)) == Capacity) {
return false;
}
} else if constexpr (Mode == PushMode::Wait) {
// Wait until we have free slots to write to.
std::unique_lock lock{producer_cv_mutex};
producer_cv.wait(lock, [this, write_index] {
return (write_index - m_read_index.load(std::memory_order::acquire)) < Capacity;
});
} else {
static_assert(Mode < PushMode::Count, "Invalid PushMode.");
}
// Determine the position to write to.
const size_t pos = write_index % Capacity;
// Emplace into the queue.
std::construct_at(std::addressof(m_data[pos]), std::forward<Args>(args)...);
// Increment the write index.
++m_write_index;
// Notify the consumer that we have pushed into the queue.
std::scoped_lock lock{consumer_cv_mutex};
consumer_cv.notify_one();
return true;
}
template <PopMode Mode>
bool Pop(T& t, [[maybe_unused]] std::stop_token stop_token = {}) {
const size_t read_index = m_read_index.load(std::memory_order::relaxed);
if constexpr (Mode == PopMode::Try) {
// Check if the queue is empty.
if (read_index == m_write_index.load(std::memory_order::acquire)) {
return false;
}
} else if constexpr (Mode == PopMode::Wait) {
// Wait until the queue is not empty.
std::unique_lock lock{consumer_cv_mutex};
consumer_cv.wait(lock, [this, read_index] {
return read_index != m_write_index.load(std::memory_order::acquire);
});
} else if constexpr (Mode == PopMode::WaitWithStopToken) {
// Wait until the queue is not empty.
std::unique_lock lock{consumer_cv_mutex};
Common::CondvarWait(consumer_cv, lock, stop_token, [this, read_index] {
return read_index != m_write_index.load(std::memory_order::acquire);
});
if (stop_token.stop_requested()) {
return false;
}
} else {
static_assert(Mode < PopMode::Count, "Invalid PopMode.");
}
// Determine the position to read from.
const size_t pos = read_index % Capacity;
// Pop the data off the queue, moving it.
t = std::move(m_data[pos]);
// Increment the read index.
++m_read_index;
// Notify the producer that we have popped off the queue.
std::scoped_lock lock{producer_cv_mutex};
producer_cv.notify_one();
return true;
}
alignas(128) std::atomic_size_t m_read_index{0};
alignas(128) std::atomic_size_t m_write_index{0};
std::array<T, Capacity> m_data;
std::condition_variable_any producer_cv;
std::mutex producer_cv_mutex;
std::condition_variable_any consumer_cv;
std::mutex consumer_cv_mutex;
};
template <typename T, size_t Capacity = detail::DefaultCapacity>
class MPSCQueue {
public:
template <typename... Args>
void emplace(Args&&... args) noexcept {
static_assert(std::is_nothrow_constructible_v<T, Args&&...>,
"T must be nothrow constructible with Args&&...");
auto const head = head_.fetch_add(1);
auto& slot = slots[idx(head)];
slot.turn.wait(true);
slot.construct(std::forward<Args>(args)...);
slot.turn.test_and_set();
cv.notify_one();
bool TryEmplace(Args&&... args) {
std::scoped_lock lock{write_mutex};
return spsc_queue.TryEmplace(std::forward<Args>(args)...);
}
constexpr size_t idx(size_t i) const noexcept {
return i & mask;
template <typename... Args>
void EmplaceWait(Args&&... args) {
std::scoped_lock lock{write_mutex};
spsc_queue.EmplaceWait(std::forward<Args>(args)...);
}
static constexpr size_t mask = capacity - 1;
bool TryPop(T& t) {
return spsc_queue.TryPop(t);
}
// Align to avoid false sharing between head_ and tail_
alignas(hardware_interference_size) std::atomic<size_t> head_{0};
alignas(hardware_interference_size) std::atomic<size_t> tail_{0};
void PopWait(T& t) {
spsc_queue.PopWait(t);
}
std::mutex cv_mutex;
std::condition_variable_any cv;
void PopWait(T& t, std::stop_token stop_token) {
spsc_queue.PopWait(t, stop_token);
}
Slot<T>* slots;
[[no_unique_address]] std::allocator<Slot<T>> allocator;
T PopWait() {
return spsc_queue.PopWait();
}
static_assert(std::is_nothrow_copy_assignable_v<T> || std::is_nothrow_move_assignable_v<T>,
"T must be nothrow copy or move assignable");
T PopWait(std::stop_token stop_token) {
return spsc_queue.PopWait(stop_token);
}
static_assert(std::is_nothrow_destructible_v<T>, "T must be nothrow destructible");
private:
SPSCQueue<T, Capacity> spsc_queue;
std::mutex write_mutex;
};
template <typename T, size_t Capacity = detail::DefaultCapacity>
class MPMCQueue {
public:
template <typename... Args>
bool TryEmplace(Args&&... args) {
std::scoped_lock lock{write_mutex};
return spsc_queue.TryEmplace(std::forward<Args>(args)...);
}
template <typename... Args>
void EmplaceWait(Args&&... args) {
std::scoped_lock lock{write_mutex};
spsc_queue.EmplaceWait(std::forward<Args>(args)...);
}
bool TryPop(T& t) {
std::scoped_lock lock{read_mutex};
return spsc_queue.TryPop(t);
}
void PopWait(T& t) {
std::scoped_lock lock{read_mutex};
spsc_queue.PopWait(t);
}
void PopWait(T& t, std::stop_token stop_token) {
std::scoped_lock lock{read_mutex};
spsc_queue.PopWait(t, stop_token);
}
T PopWait() {
std::scoped_lock lock{read_mutex};
return spsc_queue.PopWait();
}
T PopWait(std::stop_token stop_token) {
std::scoped_lock lock{read_mutex};
return spsc_queue.PopWait(stop_token);
}
private:
SPSCQueue<T, Capacity> spsc_queue;
std::mutex write_mutex;
std::mutex read_mutex;
};
} // namespace Common
+1 -1
View File
@@ -90,7 +90,7 @@ Fiber::~Fiber() {
}
void Fiber::Exit() {
ASSERT_MSG(impl->is_thread_fiber, "Exitting non main thread fiber");
ASSERT_MSG(impl->is_thread_fiber, "Exiting non main thread fiber");
if (!impl->is_thread_fiber) {
return;
}
+1 -1
View File
@@ -22,7 +22,7 @@ class FixedPoint;
namespace detail {
// helper templates to make magic with types :)
// these allow us to determine resonable types from
// these allow us to determine reasonable types from
// a desired size, they also let us infer the next largest type
// from a type which is nice for the division op
template <size_t T>
+2 -2
View File
@@ -322,7 +322,7 @@ private:
}
/// Return true when a given memory region is a "nieche" and the placeholders don't have to be
/// splitted.
/// split.
bool IsNiechePlaceholder(size_t virtual_offset, size_t length) const {
const auto it = placeholders.upper_bound({virtual_offset, virtual_offset + length});
if (it != placeholders.end() && it->lower() == virtual_offset + length) {
@@ -484,7 +484,7 @@ class HostMemory::Impl {
public:
explicit Impl(size_t /*backing_size */, size_t /* virtual_size */) {
// This is just a place holder.
// Please implement fastmem in a propper way on your platform.
// Please implement fastmem in a proper way on your platform.
throw std::bad_alloc{};
}
+5 -5
View File
@@ -15,7 +15,7 @@
namespace Common::Input {
// Type of data that is expected to recieve or send
// Type of data that is expected to receive or send
enum class InputType {
None,
Battery,
@@ -46,7 +46,7 @@ enum class PollingMode {
// Constant polling of buttons, analogs and motion data
Active,
// Only update on button change, digital analogs
Pasive,
Passive,
// Enable near field communication polling
NFC,
// Enable infrared camera polling
@@ -103,7 +103,7 @@ enum class VibrationAmplificationType {
struct AnalogProperties {
// Anything below this value will be detected as zero
float deadzone{};
// Anyting above this values will be detected as one
// Anything above this values will be detected as one
float range{1.0f};
// Minimum value to be detected as active
float threshold{0.5f};
@@ -209,7 +209,7 @@ struct LedStatus {
bool led_4{};
};
// Raw data fom camera
// Raw data from camera
struct CameraStatus {
CameraFormat format{CameraFormat::None};
std::vector<u8> data{};
@@ -428,7 +428,7 @@ inline void UnregisterOutputFactory(const std::string& name) {
}
/**
* Create an input device from given paramters.
* Create an input device from given parameters.
* @tparam InputDeviceType the type of input devices to create
* @param params a serialized ParamPackage string that contains all parameters for creating the
* device
+8 -8
View File
@@ -28,7 +28,7 @@
#ifdef _WIN32
#include "common/string_util.h"
#endif
#include "common/threadsafe_queue.h"
#include "common/bounded_threadsafe_queue.h"
namespace Common::Log {
@@ -204,11 +204,11 @@ public:
void PushEntry(Class log_class, Level log_level, const char* filename, unsigned int line_num,
const char* function, std::string&& message) {
if (!filter.CheckMessage(log_class, log_level))
if (!filter.CheckMessage(log_class, log_level)) {
return;
const Entry& entry =
CreateEntry(log_class, log_level, filename, line_num, function, std::move(message));
message_queue.Push(entry);
}
message_queue.EmplaceWait(
CreateEntry(log_class, log_level, filename, line_num, function, std::move(message)));
}
private:
@@ -225,7 +225,7 @@ private:
ForEachBackend([&entry](Backend& backend) { backend.Write(entry); });
};
while (!stop_token.stop_requested()) {
entry = message_queue.PopWait(stop_token);
message_queue.PopWait(entry, stop_token);
if (entry.filename != nullptr) {
write_logs();
}
@@ -233,7 +233,7 @@ private:
// Drain the logging queue. Only writes out up to MAX_LOGS_TO_WRITE to prevent a
// case where a system is repeatedly spamming logs even on close.
int max_logs_to_write = filter.IsDebug() ? INT_MAX : 100;
while (max_logs_to_write-- && message_queue.Pop(entry)) {
while (max_logs_to_write-- && message_queue.TryPop(entry)) {
write_logs();
}
});
@@ -273,7 +273,7 @@ private:
ColorConsoleBackend color_console_backend{};
FileBackend file_backend;
MPSCQueue<Entry, true> message_queue{};
MPSCQueue<Entry> message_queue{};
std::chrono::steady_clock::time_point time_origin{std::chrono::steady_clock::now()};
std::jthread backend_thread;
};
+1 -1
View File
@@ -119,7 +119,7 @@ bool ParseFilterRule(Filter& instance, Iterator begin, Iterator end) {
SUB(Service, NPNS) \
SUB(Service, NS) \
SUB(Service, NVDRV) \
SUB(Service, NVFlinger) \
SUB(Service, Nvnflinger) \
SUB(Service, OLSC) \
SUB(Service, PCIE) \
SUB(Service, PCTL) \
+101 -101
View File
@@ -29,107 +29,107 @@ enum class Level : u8 {
* filter.cpp.
*/
enum class Class : u8 {
Log, ///< Messages about the log system itself
Common, ///< Library routines
Common_Filesystem, ///< Filesystem interface library
Common_Memory, ///< Memory mapping and management functions
Core, ///< LLE emulation core
Core_ARM, ///< ARM CPU core
Core_Timing, ///< CoreTiming functions
Config, ///< Emulator configuration (including commandline)
Debug, ///< Debugging tools
Debug_Emulated, ///< Debug messages from the emulated programs
Debug_GPU, ///< GPU debugging tools
Debug_Breakpoint, ///< Logging breakpoints and watchpoints
Debug_GDBStub, ///< GDB Stub
Kernel, ///< The HLE implementation of the CTR kernel
Kernel_SVC, ///< Kernel system calls
Service, ///< HLE implementation of system services. Each major service
///< should have its own subclass.
Service_ACC, ///< The ACC (Accounts) service
Service_AM, ///< The AM (Applet manager) service
Service_AOC, ///< The AOC (AddOn Content) service
Service_APM, ///< The APM (Performance) service
Service_ARP, ///< The ARP service
Service_Audio, ///< The Audio (Audio control) service
Service_BCAT, ///< The BCAT service
Service_BGTC, ///< The BGTC (Background Task Controller) service
Service_BPC, ///< The BPC service
Service_BTDRV, ///< The Bluetooth driver service
Service_BTM, ///< The BTM service
Service_Capture, ///< The capture service
Service_ERPT, ///< The error reporting service
Service_ETicket, ///< The ETicket service
Service_EUPLD, ///< The error upload service
Service_Fatal, ///< The Fatal service
Service_FGM, ///< The FGM service
Service_Friend, ///< The friend service
Service_FS, ///< The FS (Filesystem) service
Service_GRC, ///< The game recording service
Service_HID, ///< The HID (Human interface device) service
Service_IRS, ///< The IRS service
Service_JIT, ///< The JIT service
Service_LBL, ///< The LBL (LCD backlight) service
Service_LDN, ///< The LDN (Local domain network) service
Service_LDR, ///< The loader service
Service_LM, ///< The LM (Logger) service
Service_Migration, ///< The migration service
Service_Mii, ///< The Mii service
Service_MM, ///< The MM (Multimedia) service
Service_MNPP, ///< The MNPP service
Service_NCM, ///< The NCM service
Service_NFC, ///< The NFC (Near-field communication) service
Service_NFP, ///< The NFP service
Service_NGCT, ///< The NGCT (No Good Content for Terra) service
Service_NIFM, ///< The NIFM (Network interface) service
Service_NIM, ///< The NIM service
Service_NOTIF, ///< The NOTIF (Notification) service
Service_NPNS, ///< The NPNS service
Service_NS, ///< The NS services
Service_NVDRV, ///< The NVDRV (Nvidia driver) service
Service_NVFlinger, ///< The NVFlinger service
Service_OLSC, ///< The OLSC service
Service_PCIE, ///< The PCIe service
Service_PCTL, ///< The PCTL (Parental control) service
Service_PCV, ///< The PCV service
Service_PM, ///< The PM service
Service_PREPO, ///< The PREPO (Play report) service
Service_PSC, ///< The PSC service
Service_PTM, ///< The PTM service
Service_SET, ///< The SET (Settings) service
Service_SM, ///< The SM (Service manager) service
Service_SPL, ///< The SPL service
Service_SSL, ///< The SSL service
Service_TCAP, ///< The TCAP service.
Service_Time, ///< The time service
Service_USB, ///< The USB (Universal Serial Bus) service
Service_VI, ///< The VI (Video interface) service
Service_WLAN, ///< The WLAN (Wireless local area network) service
HW, ///< Low-level hardware emulation
HW_Memory, ///< Memory-map and address translation
HW_LCD, ///< LCD register emulation
HW_GPU, ///< GPU control emulation
HW_AES, ///< AES engine emulation
IPC, ///< IPC interface
Frontend, ///< Emulator UI
Render, ///< Emulator video output and hardware acceleration
Render_Software, ///< Software renderer backend
Render_OpenGL, ///< OpenGL backend
Render_Vulkan, ///< Vulkan backend
Shader, ///< Shader recompiler
Shader_SPIRV, ///< Shader SPIR-V code generation
Shader_GLASM, ///< Shader GLASM code generation
Shader_GLSL, ///< Shader GLSL code generation
Audio, ///< Audio emulation
Audio_DSP, ///< The HLE implementation of the DSP
Audio_Sink, ///< Emulator audio output backend
Loader, ///< ROM loader
CheatEngine, ///< Memory manipulation and engine VM functions
Crypto, ///< Cryptographic engine/functions
Input, ///< Input emulation
Network, ///< Network emulation
WebService, ///< Interface to yuzu Web Services
Count ///< Total number of logging classes
Log, ///< Messages about the log system itself
Common, ///< Library routines
Common_Filesystem, ///< Filesystem interface library
Common_Memory, ///< Memory mapping and management functions
Core, ///< LLE emulation core
Core_ARM, ///< ARM CPU core
Core_Timing, ///< CoreTiming functions
Config, ///< Emulator configuration (including commandline)
Debug, ///< Debugging tools
Debug_Emulated, ///< Debug messages from the emulated programs
Debug_GPU, ///< GPU debugging tools
Debug_Breakpoint, ///< Logging breakpoints and watchpoints
Debug_GDBStub, ///< GDB Stub
Kernel, ///< The HLE implementation of the CTR kernel
Kernel_SVC, ///< Kernel system calls
Service, ///< HLE implementation of system services. Each major service
///< should have its own subclass.
Service_ACC, ///< The ACC (Accounts) service
Service_AM, ///< The AM (Applet manager) service
Service_AOC, ///< The AOC (AddOn Content) service
Service_APM, ///< The APM (Performance) service
Service_ARP, ///< The ARP service
Service_Audio, ///< The Audio (Audio control) service
Service_BCAT, ///< The BCAT service
Service_BGTC, ///< The BGTC (Background Task Controller) service
Service_BPC, ///< The BPC service
Service_BTDRV, ///< The Bluetooth driver service
Service_BTM, ///< The BTM service
Service_Capture, ///< The capture service
Service_ERPT, ///< The error reporting service
Service_ETicket, ///< The ETicket service
Service_EUPLD, ///< The error upload service
Service_Fatal, ///< The Fatal service
Service_FGM, ///< The FGM service
Service_Friend, ///< The friend service
Service_FS, ///< The FS (Filesystem) service
Service_GRC, ///< The game recording service
Service_HID, ///< The HID (Human interface device) service
Service_IRS, ///< The IRS service
Service_JIT, ///< The JIT service
Service_LBL, ///< The LBL (LCD backlight) service
Service_LDN, ///< The LDN (Local domain network) service
Service_LDR, ///< The loader service
Service_LM, ///< The LM (Logger) service
Service_Migration, ///< The migration service
Service_Mii, ///< The Mii service
Service_MM, ///< The MM (Multimedia) service
Service_MNPP, ///< The MNPP service
Service_NCM, ///< The NCM service
Service_NFC, ///< The NFC (Near-field communication) service
Service_NFP, ///< The NFP service
Service_NGCT, ///< The NGCT (No Good Content for Terra) service
Service_NIFM, ///< The NIFM (Network interface) service
Service_NIM, ///< The NIM service
Service_NOTIF, ///< The NOTIF (Notification) service
Service_NPNS, ///< The NPNS service
Service_NS, ///< The NS services
Service_NVDRV, ///< The NVDRV (Nvidia driver) service
Service_Nvnflinger, ///< The Nvnflinger service
Service_OLSC, ///< The OLSC service
Service_PCIE, ///< The PCIe service
Service_PCTL, ///< The PCTL (Parental control) service
Service_PCV, ///< The PCV service
Service_PM, ///< The PM service
Service_PREPO, ///< The PREPO (Play report) service
Service_PSC, ///< The PSC service
Service_PTM, ///< The PTM service
Service_SET, ///< The SET (Settings) service
Service_SM, ///< The SM (Service manager) service
Service_SPL, ///< The SPL service
Service_SSL, ///< The SSL service
Service_TCAP, ///< The TCAP service.
Service_Time, ///< The time service
Service_USB, ///< The USB (Universal Serial Bus) service
Service_VI, ///< The VI (Video interface) service
Service_WLAN, ///< The WLAN (Wireless local area network) service
HW, ///< Low-level hardware emulation
HW_Memory, ///< Memory-map and address translation
HW_LCD, ///< LCD register emulation
HW_GPU, ///< GPU control emulation
HW_AES, ///< AES engine emulation
IPC, ///< IPC interface
Frontend, ///< Emulator UI
Render, ///< Emulator video output and hardware acceleration
Render_Software, ///< Software renderer backend
Render_OpenGL, ///< OpenGL backend
Render_Vulkan, ///< Vulkan backend
Shader, ///< Shader recompiler
Shader_SPIRV, ///< Shader SPIR-V code generation
Shader_GLASM, ///< Shader GLASM code generation
Shader_GLSL, ///< Shader GLSL code generation
Audio, ///< Audio emulation
Audio_DSP, ///< The HLE implementation of the DSP
Audio_Sink, ///< Emulator audio output backend
Loader, ///< ROM loader
CheatEngine, ///< Memory manipulation and engine VM functions
Crypto, ///< Cryptographic engine/functions
Input, ///< Input emulation
Network, ///< Network emulation
WebService, ///< Interface to yuzu Web Services
Count ///< Total number of logging classes
};
} // namespace Common::Log
+22
View File
@@ -0,0 +1,22 @@
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <type_traits>
#include "bit_cast.h"
namespace Common {
template <typename T>
requires(std::is_integral_v<T> && std::is_signed_v<T>)
inline T WrappingAdd(T lhs, T rhs) {
using U = std::make_unsigned_t<T>;
U lhs_u = BitCast<U>(lhs);
U rhs_u = BitCast<U>(rhs);
return BitCast<T>(lhs_u + rhs_u);
}
} // namespace Common
+5 -5
View File
@@ -128,7 +128,7 @@ public:
/**
* Sets a default value, label, and setting value.
*
* @param default_val Intial value of the setting, and default value of the setting
* @param default_val Initial value of the setting, and default value of the setting
* @param name Label for the setting
*/
explicit Setting(const Type& default_val, const std::string& name)
@@ -139,7 +139,7 @@ public:
/**
* Sets a default value, minimum value, maximum value, and label.
*
* @param default_val Intial value of the setting, and default value of the setting
* @param default_val Initial value of the setting, and default value of the setting
* @param min_val Sets the minimum allowed value of the setting
* @param max_val Sets the maximum allowed value of the setting
* @param name Label for the setting
@@ -231,7 +231,7 @@ public:
/**
* Sets a default value, label, and setting value.
*
* @param default_val Intial value of the setting, and default value of the setting
* @param default_val Initial value of the setting, and default value of the setting
* @param name Label for the setting
*/
explicit SwitchableSetting(const Type& default_val, const std::string& name)
@@ -242,7 +242,7 @@ public:
/**
* Sets a default value, minimum value, maximum value, and label.
*
* @param default_val Intial value of the setting, and default value of the setting
* @param default_val Initial value of the setting, and default value of the setting
* @param min_val Sets the minimum allowed value of the setting
* @param max_val Sets the maximum allowed value of the setting
* @param name Label for the setting
@@ -503,7 +503,7 @@ struct Values {
Setting<bool> tas_loop{false, "tas_loop"};
Setting<bool> mouse_panning{false, "mouse_panning"};
Setting<u8, true> mouse_panning_sensitivity{10, 1, 100, "mouse_panning_sensitivity"};
Setting<u8, true> mouse_panning_sensitivity{50, 1, 100, "mouse_panning_sensitivity"};
Setting<bool> mouse_enabled{false, "mouse_enabled"};
Setting<bool> emulate_analog_keyboard{false, "emulate_analog_keyboard"};
+81
View File
@@ -0,0 +1,81 @@
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#if defined(_WIN32)
#include <windows.h>
#else
#include <time.h>
#endif
#include "common/steady_clock.h"
namespace Common {
#ifdef _WIN32
static s64 WindowsQueryPerformanceFrequency() {
LARGE_INTEGER frequency;
QueryPerformanceFrequency(&frequency);
return frequency.QuadPart;
}
static s64 WindowsQueryPerformanceCounter() {
LARGE_INTEGER counter;
QueryPerformanceCounter(&counter);
return counter.QuadPart;
}
static s64 GetSystemTimeNS() {
// GetSystemTimePreciseAsFileTime returns the file time in 100ns units.
static constexpr s64 Multiplier = 100;
// Convert Windows epoch to Unix epoch.
static constexpr s64 WindowsEpochToUnixEpochNS = 0x19DB1DED53E8000LL;
FILETIME filetime;
GetSystemTimePreciseAsFileTime(&filetime);
return Multiplier * ((static_cast<s64>(filetime.dwHighDateTime) << 32) +
static_cast<s64>(filetime.dwLowDateTime)) -
WindowsEpochToUnixEpochNS;
}
#endif
SteadyClock::time_point SteadyClock::Now() noexcept {
#if defined(_WIN32)
static const auto freq = WindowsQueryPerformanceFrequency();
const auto counter = WindowsQueryPerformanceCounter();
// 10 MHz is a very common QPC frequency on modern PCs.
// Optimizing for this specific frequency can double the performance of
// this function by avoiding the expensive frequency conversion path.
static constexpr s64 TenMHz = 10'000'000;
if (freq == TenMHz) [[likely]] {
static_assert(period::den % TenMHz == 0);
static constexpr s64 Multiplier = period::den / TenMHz;
return time_point{duration{counter * Multiplier}};
}
const auto whole = (counter / freq) * period::den;
const auto part = (counter % freq) * period::den / freq;
return time_point{duration{whole + part}};
#elif defined(__APPLE__)
return time_point{duration{clock_gettime_nsec_np(CLOCK_MONOTONIC_RAW)}};
#else
timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts);
return time_point{std::chrono::seconds{ts.tv_sec} + std::chrono::nanoseconds{ts.tv_nsec}};
#endif
}
RealTimeClock::time_point RealTimeClock::Now() noexcept {
#if defined(_WIN32)
return time_point{duration{GetSystemTimeNS()}};
#elif defined(__APPLE__)
return time_point{duration{clock_gettime_nsec_np(CLOCK_REALTIME)}};
#else
timespec ts;
clock_gettime(CLOCK_REALTIME, &ts);
return time_point{std::chrono::seconds{ts.tv_sec} + std::chrono::nanoseconds{ts.tv_nsec}};
#endif
}
}; // namespace Common
+34
View File
@@ -0,0 +1,34 @@
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <chrono>
#include "common/common_types.h"
namespace Common {
struct SteadyClock {
using rep = s64;
using period = std::nano;
using duration = std::chrono::nanoseconds;
using time_point = std::chrono::time_point<SteadyClock>;
static constexpr bool is_steady = true;
[[nodiscard]] static time_point Now() noexcept;
};
struct RealTimeClock {
using rep = s64;
using period = std::nano;
using duration = std::chrono::nanoseconds;
using time_point = std::chrono::time_point<RealTimeClock>;
static constexpr bool is_steady = false;
[[nodiscard]] static time_point Now() noexcept;
};
} // namespace Common
+7 -7
View File
@@ -125,18 +125,18 @@ std::string ReplaceAll(std::string result, const std::string& src, const std::st
return result;
}
std::string UTF16ToUTF8(const std::u16string& input) {
std::string UTF16ToUTF8(std::u16string_view input) {
std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> convert;
return convert.to_bytes(input);
return convert.to_bytes(input.data(), input.data() + input.size());
}
std::u16string UTF8ToUTF16(const std::string& input) {
std::u16string UTF8ToUTF16(std::string_view input) {
std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> convert;
return convert.from_bytes(input);
return convert.from_bytes(input.data(), input.data() + input.size());
}
#ifdef _WIN32
static std::wstring CPToUTF16(u32 code_page, const std::string& input) {
static std::wstring CPToUTF16(u32 code_page, std::string_view input) {
const auto size =
MultiByteToWideChar(code_page, 0, input.data(), static_cast<int>(input.size()), nullptr, 0);
@@ -154,7 +154,7 @@ static std::wstring CPToUTF16(u32 code_page, const std::string& input) {
return output;
}
std::string UTF16ToUTF8(const std::wstring& input) {
std::string UTF16ToUTF8(std::wstring_view input) {
const auto size = WideCharToMultiByte(CP_UTF8, 0, input.data(), static_cast<int>(input.size()),
nullptr, 0, nullptr, nullptr);
if (size == 0) {
@@ -172,7 +172,7 @@ std::string UTF16ToUTF8(const std::wstring& input) {
return output;
}
std::wstring UTF8ToUTF16W(const std::string& input) {
std::wstring UTF8ToUTF16W(std::string_view input) {
return CPToUTF16(CP_UTF8, input);
}
+4 -4
View File
@@ -36,12 +36,12 @@ bool SplitPath(const std::string& full_path, std::string* _pPath, std::string* _
[[nodiscard]] std::string ReplaceAll(std::string result, const std::string& src,
const std::string& dest);
[[nodiscard]] std::string UTF16ToUTF8(const std::u16string& input);
[[nodiscard]] std::u16string UTF8ToUTF16(const std::string& input);
[[nodiscard]] std::string UTF16ToUTF8(std::u16string_view input);
[[nodiscard]] std::u16string UTF8ToUTF16(std::string_view input);
#ifdef _WIN32
[[nodiscard]] std::string UTF16ToUTF8(const std::wstring& input);
[[nodiscard]] std::wstring UTF8ToUTF16W(const std::string& str);
[[nodiscard]] std::string UTF16ToUTF8(std::wstring_view input);
[[nodiscard]] std::wstring UTF8ToUTF16W(std::string_view str);
#endif
+6 -6
View File
@@ -229,7 +229,7 @@ public:
value = swap(swap() - 1);
return old;
}
// Comparaison
// Comparison
// v == i
bool operator==(const swapped_t& i) const {
return swap() == i.swap();
@@ -368,7 +368,7 @@ public:
// Member
/** todo **/
// Arithmetics
// Arithmetic
template <typename S, typename T2, typename F2>
friend S operator+(const S& p, const swapped_t v);
@@ -384,7 +384,7 @@ public:
template <typename S, typename T2, typename F2>
friend S operator%(const S& p, const swapped_t v);
// Arithmetics + assignments
// Arithmetic + assignments
template <typename S, typename T2, typename F2>
friend S operator+=(const S& p, const swapped_t v);
@@ -415,7 +415,7 @@ public:
friend bool operator==(const S& p, const swapped_t v);
};
// Arithmetics
// Arithmetic
template <typename S, typename T, typename F>
S operator+(const S& i, const swap_struct_t<T, F> v) {
return i + v.swap();
@@ -441,7 +441,7 @@ S operator%(const S& i, const swap_struct_t<T, F> v) {
return i % v.swap();
}
// Arithmetics + assignments
// Arithmetic + assignments
template <typename S, typename T, typename F>
S& operator+=(S& i, const swap_struct_t<T, F> v) {
i += v.swap();
@@ -465,7 +465,7 @@ S operator&(const swap_struct_t<T, F> v, const S& i) {
return static_cast<S>(v.swap() & i);
}
// Comparaison
// Comparison
template <typename S, typename T, typename F>
bool operator<(const S& p, const swap_struct_t<T, F> v) {
return p < v.swap();
+16 -23
View File
@@ -1,6 +1,7 @@
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include "common/steady_clock.h"
#include "common/uint128.h"
#include "common/wall_clock.h"
@@ -11,45 +12,32 @@
namespace Common {
using base_timer = std::chrono::steady_clock;
using base_time_point = std::chrono::time_point<base_timer>;
class StandardWallClock final : public WallClock {
public:
explicit StandardWallClock(u64 emulated_cpu_frequency_, u64 emulated_clock_frequency_)
: WallClock(emulated_cpu_frequency_, emulated_clock_frequency_, false) {
start_time = base_timer::now();
}
: WallClock{emulated_cpu_frequency_, emulated_clock_frequency_, false},
start_time{SteadyClock::Now()} {}
std::chrono::nanoseconds GetTimeNS() override {
base_time_point current = base_timer::now();
auto elapsed = current - start_time;
return std::chrono::duration_cast<std::chrono::nanoseconds>(elapsed);
return SteadyClock::Now() - start_time;
}
std::chrono::microseconds GetTimeUS() override {
base_time_point current = base_timer::now();
auto elapsed = current - start_time;
return std::chrono::duration_cast<std::chrono::microseconds>(elapsed);
return std::chrono::duration_cast<std::chrono::microseconds>(GetTimeNS());
}
std::chrono::milliseconds GetTimeMS() override {
base_time_point current = base_timer::now();
auto elapsed = current - start_time;
return std::chrono::duration_cast<std::chrono::milliseconds>(elapsed);
return std::chrono::duration_cast<std::chrono::milliseconds>(GetTimeNS());
}
u64 GetClockCycles() override {
std::chrono::nanoseconds time_now = GetTimeNS();
const u128 temporary =
Common::Multiply64Into128(time_now.count(), emulated_clock_frequency);
return Common::Divide128On32(temporary, 1000000000).first;
const u128 temp = Common::Multiply64Into128(GetTimeNS().count(), emulated_clock_frequency);
return Common::Divide128On32(temp, NS_RATIO).first;
}
u64 GetCPUCycles() override {
std::chrono::nanoseconds time_now = GetTimeNS();
const u128 temporary = Common::Multiply64Into128(time_now.count(), emulated_cpu_frequency);
return Common::Divide128On32(temporary, 1000000000).first;
const u128 temp = Common::Multiply64Into128(GetTimeNS().count(), emulated_cpu_frequency);
return Common::Divide128On32(temp, NS_RATIO).first;
}
void Pause([[maybe_unused]] bool is_paused) override {
@@ -57,7 +45,7 @@ public:
}
private:
base_time_point start_time;
SteadyClock::time_point start_time;
};
#ifdef ARCHITECTURE_x86_64
@@ -93,4 +81,9 @@ std::unique_ptr<WallClock> CreateBestMatchingClock(u64 emulated_cpu_frequency,
#endif
std::unique_ptr<WallClock> CreateStandardWallClock(u64 emulated_cpu_frequency,
u64 emulated_clock_frequency) {
return std::make_unique<StandardWallClock>(emulated_cpu_frequency, emulated_clock_frequency);
}
} // namespace Common
+3
View File
@@ -55,4 +55,7 @@ private:
[[nodiscard]] std::unique_ptr<WallClock> CreateBestMatchingClock(u64 emulated_cpu_frequency,
u64 emulated_clock_frequency);
[[nodiscard]] std::unique_ptr<WallClock> CreateStandardWallClock(u64 emulated_cpu_frequency,
u64 emulated_clock_frequency);
} // namespace Common
+109
View File
@@ -0,0 +1,109 @@
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include <windows.h>
#include "common/windows/timer_resolution.h"
extern "C" {
// http://undocumented.ntinternals.net/index.html?page=UserMode%2FUndocumented%20Functions%2FTime%2FNtQueryTimerResolution.html
NTSYSAPI LONG NTAPI NtQueryTimerResolution(PULONG MinimumResolution, PULONG MaximumResolution,
PULONG CurrentResolution);
// http://undocumented.ntinternals.net/index.html?page=UserMode%2FUndocumented%20Functions%2FTime%2FNtSetTimerResolution.html
NTSYSAPI LONG NTAPI NtSetTimerResolution(ULONG DesiredResolution, BOOLEAN SetResolution,
PULONG CurrentResolution);
// http://undocumented.ntinternals.net/index.html?page=UserMode%2FUndocumented%20Functions%2FNT%20Objects%2FThread%2FNtDelayExecution.html
NTSYSAPI LONG NTAPI NtDelayExecution(BOOLEAN Alertable, PLARGE_INTEGER DelayInterval);
}
// Defines for compatibility with older Windows 10 SDKs.
#ifndef PROCESS_POWER_THROTTLING_EXECUTION_SPEED
#define PROCESS_POWER_THROTTLING_EXECUTION_SPEED 0x1
#endif
#ifndef PROCESS_POWER_THROTTLING_IGNORE_TIMER_RESOLUTION
#define PROCESS_POWER_THROTTLING_IGNORE_TIMER_RESOLUTION 0x4
#endif
namespace Common::Windows {
namespace {
using namespace std::chrono;
constexpr nanoseconds ToNS(ULONG hundred_ns) {
return nanoseconds{hundred_ns * 100};
}
constexpr ULONG ToHundredNS(nanoseconds ns) {
return static_cast<ULONG>(ns.count()) / 100;
}
struct TimerResolution {
std::chrono::nanoseconds minimum;
std::chrono::nanoseconds maximum;
std::chrono::nanoseconds current;
};
TimerResolution GetTimerResolution() {
ULONG MinimumTimerResolution;
ULONG MaximumTimerResolution;
ULONG CurrentTimerResolution;
NtQueryTimerResolution(&MinimumTimerResolution, &MaximumTimerResolution,
&CurrentTimerResolution);
return {
.minimum{ToNS(MinimumTimerResolution)},
.maximum{ToNS(MaximumTimerResolution)},
.current{ToNS(CurrentTimerResolution)},
};
}
void SetHighQoS() {
// https://learn.microsoft.com/en-us/windows/win32/procthread/quality-of-service
PROCESS_POWER_THROTTLING_STATE PowerThrottling{
.Version{PROCESS_POWER_THROTTLING_CURRENT_VERSION},
.ControlMask{PROCESS_POWER_THROTTLING_EXECUTION_SPEED |
PROCESS_POWER_THROTTLING_IGNORE_TIMER_RESOLUTION},
.StateMask{},
};
SetProcessInformation(GetCurrentProcess(), ProcessPowerThrottling, &PowerThrottling,
sizeof(PROCESS_POWER_THROTTLING_STATE));
}
} // Anonymous namespace
nanoseconds GetMinimumTimerResolution() {
return GetTimerResolution().minimum;
}
nanoseconds GetMaximumTimerResolution() {
return GetTimerResolution().maximum;
}
nanoseconds GetCurrentTimerResolution() {
return GetTimerResolution().current;
}
nanoseconds SetCurrentTimerResolution(nanoseconds timer_resolution) {
// Set the timer resolution, and return the current timer resolution.
const auto DesiredTimerResolution = ToHundredNS(timer_resolution);
ULONG CurrentTimerResolution;
NtSetTimerResolution(DesiredTimerResolution, TRUE, &CurrentTimerResolution);
return ToNS(CurrentTimerResolution);
}
nanoseconds SetCurrentTimerResolutionToMaximum() {
SetHighQoS();
return SetCurrentTimerResolution(GetMaximumTimerResolution());
}
void SleepForOneTick() {
LARGE_INTEGER DelayInterval{
.QuadPart{-1},
};
NtDelayExecution(FALSE, &DelayInterval);
}
} // namespace Common::Windows
+38
View File
@@ -0,0 +1,38 @@
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <chrono>
namespace Common::Windows {
/// Returns the minimum (least precise) supported timer resolution in nanoseconds.
std::chrono::nanoseconds GetMinimumTimerResolution();
/// Returns the maximum (most precise) supported timer resolution in nanoseconds.
std::chrono::nanoseconds GetMaximumTimerResolution();
/// Returns the current timer resolution in nanoseconds.
std::chrono::nanoseconds GetCurrentTimerResolution();
/**
* Sets the current timer resolution.
*
* @param timer_resolution Timer resolution in nanoseconds.
*
* @returns The current timer resolution.
*/
std::chrono::nanoseconds SetCurrentTimerResolution(std::chrono::nanoseconds timer_resolution);
/**
* Sets the current timer resolution to the maximum supported timer resolution.
*
* @returns The current timer resolution.
*/
std::chrono::nanoseconds SetCurrentTimerResolutionToMaximum();
/// Sleep for one tick of the current timer resolution.
void SleepForOneTick();
} // namespace Common::Windows
+41 -10
View File
@@ -6,6 +6,7 @@
#include <thread>
#include "common/atomic_ops.h"
#include "common/steady_clock.h"
#include "common/uint128.h"
#include "common/x64/native_clock.h"
@@ -39,6 +40,12 @@ static u64 FencedRDTSC() {
}
#endif
template <u64 Nearest>
static u64 RoundToNearest(u64 value) {
const auto mod = value % Nearest;
return mod >= (Nearest / 2) ? (value - mod + Nearest) : (value - mod);
}
u64 EstimateRDTSCFrequency() {
// Discard the first result measuring the rdtsc.
FencedRDTSC();
@@ -46,18 +53,18 @@ u64 EstimateRDTSCFrequency() {
FencedRDTSC();
// Get the current time.
const auto start_time = std::chrono::steady_clock::now();
const auto start_time = Common::RealTimeClock::Now();
const u64 tsc_start = FencedRDTSC();
// Wait for 200 milliseconds.
std::this_thread::sleep_for(std::chrono::milliseconds{200});
const auto end_time = std::chrono::steady_clock::now();
// Wait for 250 milliseconds.
std::this_thread::sleep_for(std::chrono::milliseconds{250});
const auto end_time = Common::RealTimeClock::Now();
const u64 tsc_end = FencedRDTSC();
// Calculate differences.
const u64 timer_diff = static_cast<u64>(
std::chrono::duration_cast<std::chrono::nanoseconds>(end_time - start_time).count());
const u64 tsc_diff = tsc_end - tsc_start;
const u64 tsc_freq = MultiplyAndDivide64(tsc_diff, 1000000000ULL, timer_diff);
return tsc_freq;
return RoundToNearest<1000>(tsc_freq);
}
namespace X64 {
@@ -65,13 +72,29 @@ NativeClock::NativeClock(u64 emulated_cpu_frequency_, u64 emulated_clock_frequen
u64 rtsc_frequency_)
: WallClock(emulated_cpu_frequency_, emulated_clock_frequency_, true), rtsc_frequency{
rtsc_frequency_} {
// Thread to re-adjust the RDTSC frequency after 10 seconds has elapsed.
time_sync_thread = std::jthread{[this](std::stop_token token) {
// Get the current time.
const auto start_time = Common::RealTimeClock::Now();
const u64 tsc_start = FencedRDTSC();
// Wait for 10 seconds.
if (!Common::StoppableTimedWait(token, std::chrono::seconds{10})) {
return;
}
const auto end_time = Common::RealTimeClock::Now();
const u64 tsc_end = FencedRDTSC();
// Calculate differences.
const u64 timer_diff = static_cast<u64>(
std::chrono::duration_cast<std::chrono::nanoseconds>(end_time - start_time).count());
const u64 tsc_diff = tsc_end - tsc_start;
const u64 tsc_freq = MultiplyAndDivide64(tsc_diff, 1000000000ULL, timer_diff);
rtsc_frequency = tsc_freq;
CalculateAndSetFactors();
}};
time_point.inner.last_measure = FencedRDTSC();
time_point.inner.accumulated_ticks = 0U;
ns_rtsc_factor = GetFixedPoint64Factor(NS_RATIO, rtsc_frequency);
us_rtsc_factor = GetFixedPoint64Factor(US_RATIO, rtsc_frequency);
ms_rtsc_factor = GetFixedPoint64Factor(MS_RATIO, rtsc_frequency);
clock_rtsc_factor = GetFixedPoint64Factor(emulated_clock_frequency, rtsc_frequency);
cpu_rtsc_factor = GetFixedPoint64Factor(emulated_cpu_frequency, rtsc_frequency);
CalculateAndSetFactors();
}
u64 NativeClock::GetRTSC() {
@@ -131,6 +154,14 @@ u64 NativeClock::GetCPUCycles() {
return MultiplyHigh(rtsc_value, cpu_rtsc_factor);
}
void NativeClock::CalculateAndSetFactors() {
ns_rtsc_factor = GetFixedPoint64Factor(NS_RATIO, rtsc_frequency);
us_rtsc_factor = GetFixedPoint64Factor(US_RATIO, rtsc_frequency);
ms_rtsc_factor = GetFixedPoint64Factor(MS_RATIO, rtsc_frequency);
clock_rtsc_factor = GetFixedPoint64Factor(emulated_clock_frequency, rtsc_frequency);
cpu_rtsc_factor = GetFixedPoint64Factor(emulated_cpu_frequency, rtsc_frequency);
}
} // namespace X64
} // namespace Common
+5
View File
@@ -3,6 +3,7 @@
#pragma once
#include "common/polyfill_thread.h"
#include "common/wall_clock.h"
namespace Common {
@@ -28,6 +29,8 @@ public:
private:
u64 GetRTSC();
void CalculateAndSetFactors();
union alignas(16) TimePoint {
TimePoint() : pack{} {}
u128 pack{};
@@ -47,6 +50,8 @@ private:
u64 ms_rtsc_factor{};
u64 rtsc_frequency;
std::jthread time_sync_thread;
};
} // namespace X64
+38 -38
View File
@@ -158,7 +158,7 @@ add_library(core STATIC
hid/motion_input.h
hle/api_version.h
hle/ipc.h
hle/ipc_helpers.h
hle/kernel/board/nintendo/nx/k_memory_layout.cpp
hle/kernel/board/nintendo/nx/k_memory_layout.h
hle/kernel/board/nintendo/nx/k_system_control.cpp
hle/kernel/board/nintendo/nx/k_system_control.h
@@ -168,8 +168,6 @@ add_library(core STATIC
hle/kernel/svc_results.h
hle/kernel/global_scheduler_context.cpp
hle/kernel/global_scheduler_context.h
hle/kernel/hle_ipc.cpp
hle/kernel/hle_ipc.h
hle/kernel/init/init_slab_setup.cpp
hle/kernel/init/init_slab_setup.h
hle/kernel/initial_process.h
@@ -214,12 +212,10 @@ add_library(core STATIC
hle/kernel/k_light_condition_variable.h
hle/kernel/k_light_lock.cpp
hle/kernel/k_light_lock.h
hle/kernel/k_linked_list.h
hle/kernel/k_memory_block.h
hle/kernel/k_memory_block_manager.cpp
hle/kernel/k_memory_block_manager.h
hle/kernel/k_memory_layout.cpp
hle/kernel/k_memory_layout.board.nintendo_nx.cpp
hle/kernel/k_memory_layout.h
hle/kernel/k_memory_manager.cpp
hle/kernel/k_memory_manager.h
@@ -293,8 +289,6 @@ add_library(core STATIC
hle/kernel/physical_memory.h
hle/kernel/process_capability.cpp
hle/kernel/process_capability.h
hle/kernel/service_thread.cpp
hle/kernel/service_thread.h
hle/kernel/slab_helpers.h
hle/kernel/svc.cpp
hle/kernel/svc.h
@@ -459,7 +453,6 @@ add_library(core STATIC
hle/service/filesystem/fsp_srv.h
hle/service/fgm/fgm.cpp
hle/service/fgm/fgm.h
hle/service/friend/errors.h
hle/service/friend/friend.cpp
hle/service/friend/friend.h
hle/service/friend/friend_interface.cpp
@@ -631,35 +624,35 @@ add_library(core STATIC
hle/service/nvdrv/nvdrv_interface.h
hle/service/nvdrv/nvmemp.cpp
hle/service/nvdrv/nvmemp.h
hle/service/nvflinger/binder.h
hle/service/nvflinger/buffer_item.h
hle/service/nvflinger/buffer_item_consumer.cpp
hle/service/nvflinger/buffer_item_consumer.h
hle/service/nvflinger/buffer_queue_consumer.cpp
hle/service/nvflinger/buffer_queue_consumer.h
hle/service/nvflinger/buffer_queue_core.cpp
hle/service/nvflinger/buffer_queue_core.h
hle/service/nvflinger/buffer_queue_defs.h
hle/service/nvflinger/buffer_queue_producer.cpp
hle/service/nvflinger/buffer_queue_producer.h
hle/service/nvflinger/buffer_slot.h
hle/service/nvflinger/buffer_transform_flags.h
hle/service/nvflinger/consumer_base.cpp
hle/service/nvflinger/consumer_base.h
hle/service/nvflinger/consumer_listener.h
hle/service/nvflinger/graphic_buffer_producer.cpp
hle/service/nvflinger/graphic_buffer_producer.h
hle/service/nvflinger/hos_binder_driver_server.cpp
hle/service/nvflinger/hos_binder_driver_server.h
hle/service/nvflinger/nvflinger.cpp
hle/service/nvflinger/nvflinger.h
hle/service/nvflinger/parcel.h
hle/service/nvflinger/pixel_format.h
hle/service/nvflinger/producer_listener.h
hle/service/nvflinger/status.h
hle/service/nvflinger/ui/fence.h
hle/service/nvflinger/ui/graphic_buffer.h
hle/service/nvflinger/window.h
hle/service/nvnflinger/binder.h
hle/service/nvnflinger/buffer_item.h
hle/service/nvnflinger/buffer_item_consumer.cpp
hle/service/nvnflinger/buffer_item_consumer.h
hle/service/nvnflinger/buffer_queue_consumer.cpp
hle/service/nvnflinger/buffer_queue_consumer.h
hle/service/nvnflinger/buffer_queue_core.cpp
hle/service/nvnflinger/buffer_queue_core.h
hle/service/nvnflinger/buffer_queue_defs.h
hle/service/nvnflinger/buffer_queue_producer.cpp
hle/service/nvnflinger/buffer_queue_producer.h
hle/service/nvnflinger/buffer_slot.h
hle/service/nvnflinger/buffer_transform_flags.h
hle/service/nvnflinger/consumer_base.cpp
hle/service/nvnflinger/consumer_base.h
hle/service/nvnflinger/consumer_listener.h
hle/service/nvnflinger/graphic_buffer_producer.cpp
hle/service/nvnflinger/graphic_buffer_producer.h
hle/service/nvnflinger/hos_binder_driver_server.cpp
hle/service/nvnflinger/hos_binder_driver_server.h
hle/service/nvnflinger/nvnflinger.cpp
hle/service/nvnflinger/nvnflinger.h
hle/service/nvnflinger/parcel.h
hle/service/nvnflinger/pixel_format.h
hle/service/nvnflinger/producer_listener.h
hle/service/nvnflinger/status.h
hle/service/nvnflinger/ui/fence.h
hle/service/nvnflinger/ui/graphic_buffer.h
hle/service/nvnflinger/window.h
hle/service/olsc/olsc.cpp
hle/service/olsc/olsc.h
hle/service/pcie/pcie.cpp
@@ -682,8 +675,15 @@ add_library(core STATIC
hle/service/ptm/ptm.h
hle/service/ptm/ts.cpp
hle/service/ptm/ts.h
hle/service/hle_ipc.cpp
hle/service/hle_ipc.h
hle/service/ipc_helpers.h
hle/service/kernel_helpers.cpp
hle/service/kernel_helpers.h
hle/service/mutex.cpp
hle/service/mutex.h
hle/service/server_manager.cpp
hle/service/server_manager.h
hle/service/service.cpp
hle/service/service.h
hle/service/set/set.cpp
@@ -832,7 +832,7 @@ endif()
create_target_directory_groups(core)
target_link_libraries(core PUBLIC common PRIVATE audio_core network video_core)
target_link_libraries(core PUBLIC Boost::boost PRIVATE fmt::fmt nlohmann_json::nlohmann_json mbedtls Opus::opus)
target_link_libraries(core PUBLIC Boost::headers PRIVATE fmt::fmt nlohmann_json::nlohmann_json mbedtls Opus::opus)
if (MINGW)
target_link_libraries(core PRIVATE ${MSWSOCK_LIBRARY})
endif()
+19 -8
View File
@@ -4,13 +4,24 @@
#include "core/constants.h"
namespace Core::Constants {
const std::array<u8, 107> ACCOUNT_BACKUP_JPEG{{
0xff, 0xd8, 0xff, 0xdb, 0x00, 0x43, 0x00, 0x03, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x02, 0x02,
0x02, 0x03, 0x03, 0x03, 0x03, 0x04, 0x06, 0x04, 0x04, 0x04, 0x04, 0x04, 0x08, 0x06, 0x06, 0x05,
0x06, 0x09, 0x08, 0x0a, 0x0a, 0x09, 0x08, 0x09, 0x09, 0x0a, 0x0c, 0x0f, 0x0c, 0x0a, 0x0b, 0x0e,
0x0b, 0x09, 0x09, 0x0d, 0x11, 0x0d, 0x0e, 0x0f, 0x10, 0x10, 0x11, 0x10, 0x0a, 0x0c, 0x12, 0x13,
0x12, 0x10, 0x13, 0x0f, 0x10, 0x10, 0x10, 0xff, 0xc9, 0x00, 0x0b, 0x08, 0x00, 0x01, 0x00, 0x01,
0x01, 0x01, 0x11, 0x00, 0xff, 0xcc, 0x00, 0x06, 0x00, 0x10, 0x10, 0x05, 0xff, 0xda, 0x00, 0x08,
0x01, 0x01, 0x00, 0x00, 0x3f, 0x00, 0xd2, 0xcf, 0x20, 0xff, 0xd9,
const std::array<u8, 287> ACCOUNT_BACKUP_JPEG{{
0xff, 0xd8, 0xff, 0xe0, 0x00, 0x10, 0x4a, 0x46, 0x49, 0x46, 0x00, 0x01, 0x01, 0x01, 0x00, 0x48,
0x00, 0x48, 0x00, 0x00, 0xff, 0xdb, 0x00, 0x43, 0x00, 0x06, 0x04, 0x04, 0x04, 0x05, 0x04, 0x06,
0x05, 0x05, 0x06, 0x09, 0x06, 0x05, 0x06, 0x09, 0x0b, 0x08, 0x06, 0x06, 0x08, 0x0b, 0x0c, 0x0a,
0x0a, 0x0b, 0x0a, 0x0a, 0x0c, 0x10, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x10, 0x0c, 0x0e, 0x0f,
0x10, 0x0f, 0x0e, 0x0c, 0x13, 0x13, 0x14, 0x14, 0x13, 0x13, 0x1c, 0x1b, 0x1b, 0x1b, 0x1c, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0xff, 0xdb, 0x00, 0x43, 0x01, 0x07, 0x07,
0x07, 0x0d, 0x0c, 0x0d, 0x18, 0x10, 0x10, 0x18, 0x1a, 0x15, 0x11, 0x15, 0x1a, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0xff, 0xc0,
0x00, 0x11, 0x08, 0x00, 0x20, 0x00, 0x20, 0x03, 0x01, 0x22, 0x00, 0x02, 0x11, 0x01, 0x03, 0x11,
0x01, 0xff, 0xc4, 0x00, 0x14, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xc4, 0x00, 0x14, 0x10, 0x01, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xc4, 0x00,
0x14, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xff, 0xc4, 0x00, 0x14, 0x11, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xda, 0x00, 0x0c, 0x03, 0x01, 0x00,
0x02, 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xd9,
}};
}
+1 -1
View File
@@ -12,6 +12,6 @@
namespace Core::Constants {
// ACC Service - Blank JPEG used as user icon in absentia of real one.
extern const std::array<u8, 107> ACCOUNT_BACKUP_JPEG;
extern const std::array<u8, 287> ACCOUNT_BACKUP_JPEG;
} // namespace Core::Constants
+11 -6
View File
@@ -358,7 +358,7 @@ struct System::Impl {
void ShutdownMainProcess() {
SetShuttingDown(true);
// Log last frame performance stats if game was loded
// Log last frame performance stats if game was loaded
if (perf_stats) {
const auto perf_results = GetAndResetPerfStats();
constexpr auto performance = Common::Telemetry::FieldType::Performance;
@@ -380,9 +380,7 @@ struct System::Impl {
gpu_core->NotifyShutdown();
}
kernel.ShutdownCores();
cpu_manager.Shutdown();
debugger.reset();
kernel.SuspendApplication(true);
if (services) {
services->KillNVNFlinger();
}
@@ -398,6 +396,9 @@ struct System::Impl {
gpu_core.reset();
host1x_core.reset();
perf_stats.reset();
kernel.ShutdownCores();
cpu_manager.Shutdown();
debugger.reset();
kernel.Shutdown();
memory.Reset();
@@ -433,7 +434,7 @@ struct System::Impl {
}
Service::Glue::ApplicationLaunchProperty launch{};
launch.title_id = process.GetProgramID();
launch.title_id = process.GetProgramId();
FileSys::PatchManager pm{launch.title_id, fs_controller, *content_provider};
launch.version = pm.GetGameVersion().value_or(0);
@@ -761,7 +762,7 @@ const Core::SpeedLimiter& System::SpeedLimiter() const {
}
u64 System::GetApplicationProcessProgramID() const {
return impl->kernel.ApplicationProcess()->GetProgramID();
return impl->kernel.ApplicationProcess()->GetProgramId();
}
Loader::ResultStatus System::GetGameName(std::string& out) const {
@@ -938,6 +939,10 @@ const Network::RoomNetwork& System::GetRoomNetwork() const {
return impl->room_network;
}
void System::RunServer(std::unique_ptr<Service::ServerManager>&& server_manager) {
return impl->kernel.RunServer(std::move(server_manager));
}
void System::RegisterExecuteProgramCallback(ExecuteProgramCallback&& callback) {
impl->execute_program_callback = std::move(callback);
}
+6 -1
View File
@@ -61,6 +61,8 @@ namespace Glue {
class ARPManager;
}
class ServerManager;
namespace SM {
class ServiceManager;
} // namespace SM
@@ -144,7 +146,7 @@ public:
/**
* Initializes the system
* This function will initialize core functionaility used for system emulation
* This function will initialize core functionality used for system emulation
*/
void Initialize();
@@ -417,6 +419,9 @@ public:
/// Tells if the system debugger is enabled.
[[nodiscard]] bool DebuggerEnabled() const;
/// Runs a server instance until shutdown.
void RunServer(std::unique_ptr<Service::ServerManager>&& server_manager);
/// Type used for the frontend to designate a callback for System to re-launch the application
/// using a specified program index.
using ExecuteProgramCallback = std::function<void(std::size_t)>;
+34 -23
View File
@@ -6,6 +6,10 @@
#include <string>
#include <tuple>
#ifdef _WIN32
#include "common/windows/timer_resolution.h"
#endif
#include "common/microprofile.h"
#include "core/core_timing.h"
#include "core/core_timing_util.h"
@@ -38,7 +42,8 @@ struct CoreTiming::Event {
};
CoreTiming::CoreTiming()
: clock{Common::CreateBestMatchingClock(Hardware::BASE_CLOCK_RATE, Hardware::CNTFREQ)} {}
: cpu_clock{Common::CreateBestMatchingClock(Hardware::BASE_CLOCK_RATE, Hardware::CNTFREQ)},
event_clock{Common::CreateStandardWallClock(Hardware::BASE_CLOCK_RATE, Hardware::CNTFREQ)} {}
CoreTiming::~CoreTiming() {
Reset();
@@ -48,7 +53,7 @@ void CoreTiming::ThreadEntry(CoreTiming& instance) {
static constexpr char name[] = "HostTiming";
MicroProfileOnThreadCreate(name);
Common::SetCurrentThreadName(name);
Common::SetCurrentThreadPriority(Common::ThreadPriority::Critical);
Common::SetCurrentThreadPriority(Common::ThreadPriority::High);
instance.on_thread_init();
instance.ThreadLoop();
MicroProfileOnThreadExit();
@@ -185,15 +190,15 @@ void CoreTiming::ResetTicks() {
}
u64 CoreTiming::GetCPUTicks() const {
if (is_multicore) {
return clock->GetCPUCycles();
if (is_multicore) [[likely]] {
return cpu_clock->GetCPUCycles();
}
return ticks;
}
u64 CoreTiming::GetClockTicks() const {
if (is_multicore) {
return clock->GetClockCycles();
if (is_multicore) [[likely]] {
return cpu_clock->GetClockCycles();
}
return CpuCyclesToClockCycles(ticks);
}
@@ -252,21 +257,20 @@ void CoreTiming::ThreadLoop() {
const auto next_time = Advance();
if (next_time) {
// There are more events left in the queue, wait until the next event.
const auto wait_time = *next_time - GetGlobalTimeNs().count();
auto wait_time = *next_time - GetGlobalTimeNs().count();
if (wait_time > 0) {
#ifdef _WIN32
// Assume a timer resolution of 1ms.
static constexpr s64 TimerResolutionNS = 1000000;
const auto timer_resolution_ns =
Common::Windows::GetCurrentTimerResolution().count();
// Sleep in discrete intervals of the timer resolution, and spin the rest.
const auto sleep_time = wait_time - (wait_time % TimerResolutionNS);
if (sleep_time > 0) {
event.WaitFor(std::chrono::nanoseconds(sleep_time));
}
while (!paused && !event.IsSet() && wait_time > 0) {
wait_time = *next_time - GetGlobalTimeNs().count();
while (!paused && !event.IsSet() && GetGlobalTimeNs().count() < *next_time) {
// Yield to reduce thread starvation.
std::this_thread::yield();
if (wait_time >= timer_resolution_ns) {
Common::Windows::SleepForOneTick();
} else {
std::this_thread::yield();
}
}
if (event.IsSet()) {
@@ -285,9 +289,9 @@ void CoreTiming::ThreadLoop() {
}
paused_set = true;
clock->Pause(true);
event_clock->Pause(true);
pause_event.Wait();
clock->Pause(false);
event_clock->Pause(false);
}
}
@@ -303,16 +307,23 @@ void CoreTiming::Reset() {
has_started = false;
}
std::chrono::nanoseconds CoreTiming::GetCPUTimeNs() const {
if (is_multicore) [[likely]] {
return cpu_clock->GetTimeNS();
}
return CyclesToNs(ticks);
}
std::chrono::nanoseconds CoreTiming::GetGlobalTimeNs() const {
if (is_multicore) {
return clock->GetTimeNS();
if (is_multicore) [[likely]] {
return event_clock->GetTimeNS();
}
return CyclesToNs(ticks);
}
std::chrono::microseconds CoreTiming::GetGlobalTimeUs() const {
if (is_multicore) {
return clock->GetTimeUS();
if (is_multicore) [[likely]] {
return event_clock->GetTimeUS();
}
return CyclesToUs(ticks);
}
+6 -2
View File
@@ -122,6 +122,9 @@ public:
/// Returns current time in emulated in Clock cycles
u64 GetClockTicks() const;
/// Returns current time in nanoseconds.
std::chrono::nanoseconds GetCPUTimeNs() const;
/// Returns current time in microseconds.
std::chrono::microseconds GetGlobalTimeUs() const;
@@ -139,14 +142,15 @@ private:
void Reset();
std::unique_ptr<Common::WallClock> clock;
std::unique_ptr<Common::WallClock> cpu_clock;
std::unique_ptr<Common::WallClock> event_clock;
s64 global_timer = 0;
// The queue is a min-heap using std::make_heap/push_heap/pop_heap.
// We don't use std::priority_queue because we need to be able to serialize, unserialize and
// erase arbitrary events (RemoveEvent()) regardless of the queue order. These aren't
// accomodated by the standard adaptor class.
// accommodated by the standard adaptor class.
std::vector<Event> event_queue;
u64 event_fifo_id = 0;
+1 -1
View File
@@ -192,7 +192,7 @@ void CpuManager::RunThread(std::stop_token token, std::size_t core) {
}
MicroProfileOnThreadCreate(name.c_str());
Common::SetCurrentThreadName(name.c_str());
Common::SetCurrentThreadPriority(Common::ThreadPriority::High);
Common::SetCurrentThreadPriority(Common::ThreadPriority::Critical);
auto& data = core_data[core];
data.host_context = Common::Fiber::ThreadToFiber();
+1 -1
View File
@@ -11,7 +11,7 @@
namespace Core::Crypto {
// Sits on top of a VirtualFile and provides CTR-mode AES decription.
// Sits on top of a VirtualFile and provides CTR-mode AES description.
class CTREncryptionLayer : public EncryptionLayer {
public:
using IVData = std::array<u8, 16>;
+1 -1
View File
@@ -249,7 +249,7 @@ public:
static bool KeyFileExists(bool title);
// Call before using the sd seed to attempt to derive it if it dosen't exist. Needs system
// Call before using the sd seed to attempt to derive it if it doesn't exist. Needs system
// save 8*43 and the private file to exist.
void DeriveSDSeedLazy();
+1 -1
View File
@@ -9,7 +9,7 @@
namespace Core::Crypto {
// Sits on top of a VirtualFile and provides XTS-mode AES decription.
// Sits on top of a VirtualFile and provides XTS-mode AES description.
class XTSEncryptionLayer : public EncryptionLayer {
public:
XTSEncryptionLayer(FileSys::VirtualFile base, Key256 key);
+4 -3
View File
@@ -16,6 +16,7 @@
#include "core/debugger/debugger_interface.h"
#include "core/debugger/gdbstub.h"
#include "core/hle/kernel/global_scheduler_context.h"
#include "core/hle/kernel/k_process.h"
#include "core/hle/kernel/k_scheduler.h"
template <typename Readable, typename Buffer, typename Callback>
@@ -284,12 +285,12 @@ private:
void UpdateActiveThread() {
const auto& threads{ThreadList()};
if (std::find(threads.begin(), threads.end(), state->active_thread) == threads.end()) {
state->active_thread = threads[0];
state->active_thread = threads.front();
}
}
const std::vector<Kernel::KThread*>& ThreadList() {
return system.GlobalSchedulerContext().GetThreadList();
const std::list<Kernel::KThread*>& ThreadList() {
return system.ApplicationProcess()->GetThreadList();
}
private:
+10 -10
View File
@@ -421,7 +421,7 @@ void GDBStub::HandleBreakpointRemove(std::string_view command) {
static std::optional<std::string> GetNameFromThreadType32(Core::Memory::Memory& memory,
const Kernel::KThread* thread) {
// Read thread type from TLS
const VAddr tls_thread_type{memory.Read32(thread->GetTLSAddress() + 0x1fc)};
const VAddr tls_thread_type{memory.Read32(thread->GetTlsAddress() + 0x1fc)};
const VAddr argument_thread_type{thread->GetArgument()};
if (argument_thread_type && tls_thread_type != argument_thread_type) {
@@ -452,7 +452,7 @@ static std::optional<std::string> GetNameFromThreadType32(Core::Memory::Memory&
static std::optional<std::string> GetNameFromThreadType64(Core::Memory::Memory& memory,
const Kernel::KThread* thread) {
// Read thread type from TLS
const VAddr tls_thread_type{memory.Read64(thread->GetTLSAddress() + 0x1f8)};
const VAddr tls_thread_type{memory.Read64(thread->GetTlsAddress() + 0x1f8)};
const VAddr argument_thread_type{thread->GetArgument()};
if (argument_thread_type && tls_thread_type != argument_thread_type) {
@@ -573,10 +573,10 @@ void GDBStub::HandleQuery(std::string_view command) {
SendReply(PaginateBuffer(buffer, command.substr(21)));
} else if (command.starts_with("fThreadInfo")) {
// beginning of list
const auto& threads = system.GlobalSchedulerContext().GetThreadList();
const auto& threads = system.ApplicationProcess()->GetThreadList();
std::vector<std::string> thread_ids;
for (const auto& thread : threads) {
thread_ids.push_back(fmt::format("{:x}", thread->GetThreadID()));
thread_ids.push_back(fmt::format("{:x}", thread->GetThreadId()));
}
SendReply(fmt::format("m{}", fmt::join(thread_ids, ",")));
} else if (command.starts_with("sThreadInfo")) {
@@ -587,15 +587,15 @@ void GDBStub::HandleQuery(std::string_view command) {
buffer += R"(<?xml version="1.0"?>)";
buffer += "<threads>";
const auto& threads = system.GlobalSchedulerContext().GetThreadList();
const auto& threads = system.ApplicationProcess()->GetThreadList();
for (const auto* thread : threads) {
auto thread_name{GetThreadName(system, thread)};
if (!thread_name) {
thread_name = fmt::format("Thread {:d}", thread->GetThreadID());
thread_name = fmt::format("Thread {:d}", thread->GetThreadId());
}
buffer += fmt::format(R"(<thread id="{:x}" core="{:d}" name="{}">{}</thread>)",
thread->GetThreadID(), thread->GetActiveCore(),
thread->GetThreadId(), thread->GetActiveCore(),
EscapeXML(*thread_name), GetThreadState(thread));
}
@@ -756,7 +756,7 @@ void GDBStub::HandleRcmd(const std::vector<u8>& command) {
reply = fmt::format("Process: {:#x} ({})\n"
"Program Id: {:#018x}\n",
process->GetProcessID(), process->GetName(), process->GetProgramID());
process->GetProcessId(), process->GetName(), process->GetProgramId());
reply +=
fmt::format("Layout:\n"
" Alias: {:#012x} - {:#012x}\n"
@@ -817,9 +817,9 @@ void GDBStub::HandleRcmd(const std::vector<u8>& command) {
}
Kernel::KThread* GDBStub::GetThreadByID(u64 thread_id) {
const auto& threads{system.GlobalSchedulerContext().GetThreadList()};
const auto& threads{system.ApplicationProcess()->GetThreadList()};
for (auto* thread : threads) {
if (thread->GetThreadID() == thread_id) {
if (thread->GetThreadId() == thread_id) {
return thread;
}
}
+2 -2
View File
@@ -259,7 +259,7 @@ void GDBStubA64::WriteRegisters(Kernel::KThread* thread, std::string_view regist
std::string GDBStubA64::ThreadStatus(const Kernel::KThread* thread, u8 signal) const {
return fmt::format("T{:02x}{:02x}:{};{:02x}:{};{:02x}:{};thread:{:x};", signal, PC_REGISTER,
RegRead(thread, PC_REGISTER), SP_REGISTER, RegRead(thread, SP_REGISTER),
LR_REGISTER, RegRead(thread, LR_REGISTER), thread->GetThreadID());
LR_REGISTER, RegRead(thread, LR_REGISTER), thread->GetThreadId());
}
u32 GDBStubA64::BreakpointInstruction() const {
@@ -469,7 +469,7 @@ void GDBStubA32::WriteRegisters(Kernel::KThread* thread, std::string_view regist
std::string GDBStubA32::ThreadStatus(const Kernel::KThread* thread, u8 signal) const {
return fmt::format("T{:02x}{:02x}:{};{:02x}:{};{:02x}:{};thread:{:x};", signal, PC_REGISTER,
RegRead(thread, PC_REGISTER), SP_REGISTER, RegRead(thread, SP_REGISTER),
LR_REGISTER, RegRead(thread, LR_REGISTER), thread->GetThreadID());
LR_REGISTER, RegRead(thread, LR_REGISTER), thread->GetThreadId());
}
u32 GDBStubA32::BreakpointInstruction() const {

Some files were not shown because too many files have changed in this diff Show More