Compare commits

...

244 Commits

Author SHA1 Message Date
Liam cbaf642ffe Initial ARM64 support 2022-11-09 16:58:49 -05:00
Fernando S 3161b34ff6 Merge pull request #9215 from liamwhite/swordfight
Ensure correctness of atomic store ordering
2022-11-09 14:50:49 +01:00
Liam 71c0e20f95 Ensure correctness of atomic store ordering 2022-11-09 08:09:50 -05:00
Mai ad9e5bc5b7 Merge pull request #9199 from liamwhite/service-oops
service_thread: fix deletion
2022-11-09 03:25:53 +00:00
Liam 6a0d8b2aa1 service_thread: fix deletion 2022-11-06 19:50:51 -05:00
Fernando S dc520a487d Merge pull request #9195 from vonchenplus/vmm_kinds_error
video_core:Fix vmm kinds size error
2022-11-06 15:34:24 +01:00
FengChen aa97f39ba8 video_core:Fix vmm kinds size error 2022-11-06 22:31:22 +08:00
Fernando S df38c03a09 Merge pull request #9163 from vonchenplus/draw_error
video_core: Fix drawing trigger mechanism regression
2022-11-06 01:13:59 +01:00
liamwhite 4c198bbf06 Merge pull request #9173 from bunnei/kern-update-15
Kernel: Various updates for FW 15.0.x
2022-11-05 13:25:29 -04:00
Liam cf0f821565 core: hle: kernel: Address review comments. 2022-11-05 12:23:47 -04:00
Morph 8baf036cdc Merge pull request #9189 from vonchenplus/stupid
video_core: Fix scaling graphical regressions for multiple games
2022-11-05 11:57:52 -04:00
FengChen 7283010305 video_core: Fix scaling graphical regressions for multiple games 2022-11-05 17:21:02 +08:00
Mai 6f6be615f3 Merge pull request #9181 from jbeich/freebsd-qt-parity
Qt: enable recent Linux features on BSDs
2022-11-04 17:54:17 +00:00
Mai 862afa8514 Merge pull request #9178 from jbeich/freebsd-include
network: unbreak on BSDs due to missing include
2022-11-04 17:52:01 +00:00
Jan Beich d7d7ae8219 Qt: enable recent Linux features on more Unices
- Prevent sleep via xdg-desktop-portal after fa7abafa5f
- Pause on suspend after b7642cff36
- Exit on SIGINT/SIGTERM after 9479940a1f
- Improve dark themes after b51db12567
2022-11-04 13:01:17 +00:00
Jan Beich 717c8ded82 network: add missing header for SO_* on Unix after f80c7c4cd5
src/core/internal_network/socket_proxy.cpp: In member function 'virtual Network::Errno Network::ProxySocket::Initialize(Network::Domain, Network::Type, Network::Protocol)':
src/core/internal_network/socket_proxy.cpp:51:20: error: 'SO_TYPE' was not declared in this scope
   51 |     SetSockOpt(fd, SO_TYPE, type);
      |                    ^~~~~~~
src/core/internal_network/socket_proxy.cpp: In member function 'virtual Network::Errno Network::ProxySocket::SetLinger(bool, u32)':
src/core/internal_network/socket_proxy.cpp:253:27: error: 'SO_LINGER' was not declared in this scope
  253 |     return SetSockOpt(fd, SO_LINGER, values);
      |                           ^~~~~~~~~
src/core/internal_network/socket_proxy.cpp: In member function 'virtual Network::Errno Network::ProxySocket::SetReuseAddr(bool)':
src/core/internal_network/socket_proxy.cpp:257:32: error: 'SO_REUSEADDR' was not declared in this scope
  257 |     return SetSockOpt<u32>(fd, SO_REUSEADDR, enable ? 1 : 0);
      |                                ^~~~~~~~~~~~
src/core/internal_network/socket_proxy.cpp: In member function 'virtual Network::Errno Network::ProxySocket::SetBroadcast(bool)':
src/core/internal_network/socket_proxy.cpp:262:32: error: 'SO_BROADCAST' was not declared in this scope
  262 |     return SetSockOpt<u32>(fd, SO_BROADCAST, enable ? 1 : 0);
      |                                ^~~~~~~~~~~~
src/core/internal_network/socket_proxy.cpp: In member function 'virtual Network::Errno Network::ProxySocket::SetSndBuf(u32)':
src/core/internal_network/socket_proxy.cpp:266:27: error: 'SO_SNDBUF' was not declared in this scope
  266 |     return SetSockOpt(fd, SO_SNDBUF, value);
      |                           ^~~~~~~~~
src/core/internal_network/socket_proxy.cpp: In member function 'virtual Network::Errno Network::ProxySocket::SetRcvBuf(u32)':
src/core/internal_network/socket_proxy.cpp:274:27: error: 'SO_RCVBUF' was not declared in this scope
  274 |     return SetSockOpt(fd, SO_RCVBUF, value);
      |                           ^~~~~~~~~
src/core/internal_network/socket_proxy.cpp: In member function 'virtual Network::Errno Network::ProxySocket::SetSndTimeo(u32)':
src/core/internal_network/socket_proxy.cpp:279:27: error: 'SO_SNDTIMEO' was not declared in this scope
  279 |     return SetSockOpt(fd, SO_SNDTIMEO, static_cast<int>(value));
      |                           ^~~~~~~~~~~
src/core/internal_network/socket_proxy.cpp: In member function 'virtual Network::Errno Network::ProxySocket::SetRcvTimeo(u32)':
src/core/internal_network/socket_proxy.cpp:284:27: error: 'SO_RCVTIMEO' was not declared in this scope
  284 |     return SetSockOpt(fd, SO_RCVTIMEO, static_cast<int>(value));
      |                           ^~~~~~~~~~~
2022-11-04 07:28:46 +00:00
gidoly 9fc1bcc7b2 Update shader cache version. (#9175) 2022-11-04 03:16:01 -04:00
Feng Chen 75596c07e0 video_core: Fix SNORM texture buffer emulating error (#9001) 2022-11-04 02:39:42 -04:00
Piplup ece22fcbc7 UI: Add options to hide extra columns (#9093)
UI change that allows the user to hide the size and or file types columns
2022-11-04 02:30:39 -04:00
bunnei 38e4382f53 Merge pull request #8858 from vonchenplus/mipmap
video_core: Generate mipmap texture by drawing
2022-11-03 22:21:58 -07:00
bunnei 37de88040c Merge pull request #9135 from liamwhite/service-thread-event
kernel: invert session request handling flow
2022-11-03 21:45:56 -07:00
bunnei 05ae0cab0e core: hle: kernel: k_page_table: Remove unnecessary casts. 2022-11-03 21:17:08 -07:00
bunnei 119315af08 core: hle: kernel: k_page_table: Manually open/close pages for IPC methods. 2022-11-03 21:17:08 -07:00
bunnei 661fe06d9d core: hle: kernel: k_page_table: Implement IPC memory methods. 2022-11-03 21:17:07 -07:00
bunnei ba21ba0c5c core: hle: kernel: k_memory_manager: Refresh. 2022-11-03 21:17:07 -07:00
bunnei 32d7faafa8 core: hle: kernel: Integrate system KSystemResource. 2022-11-03 21:17:07 -07:00
bunnei b7b47f3099 core: hle: kernel: k_dynamic_page_manager: Refresh. 2022-11-03 21:17:07 -07:00
bunnei 6f941121e6 core: hle: kernel: Add KSystemResource. 2022-11-03 21:17:07 -07:00
bunnei 6636b81573 core: hle: kernel: k_handle_table: Refresh. 2022-11-03 21:17:07 -07:00
bunnei 1f21fa866d core: hle: kernel: k_memory_layout: Refresh. 2022-11-03 21:17:07 -07:00
bunnei 84d130f143 core: hle: kernel: k_memory_region_type: Refresh. 2022-11-03 21:17:07 -07:00
bunnei d928ba8e40 core: hle: kernel: slab_helpers: Add KAutoObjectWithSlabHeap. 2022-11-03 21:17:06 -07:00
bunnei 3aab7d4473 core: hle: kernel: k_dynamic_resource_manager: Add KBlockInfoManager, KBlockInfoSlabHeap. 2022-11-03 21:17:06 -07:00
bunnei 6b6c02f541 core: hle: kernel: k_page_bitmap: Refresh. 2022-11-03 21:17:06 -07:00
bunnei 50bfacca88 core: hle: kernel: k_memory_block: Refresh. 2022-11-03 21:17:06 -07:00
bunnei 0cb9bc12fc core: hle: kernel: k_page_heap: Refresh. 2022-11-03 21:17:06 -07:00
bunnei 6257461684 core: hle: kernel: k_page_group: Add KPageBufferSlabHeap. 2022-11-03 21:17:06 -07:00
bunnei d353c45f7d core: hle: kernel: k_system_control: Add SecureAppletMemorySize. 2022-11-03 21:17:06 -07:00
bunnei f76b4417e6 core: hle: kernel: k_page_buffer: Add KPageBufferSlabHeap. 2022-11-03 21:17:06 -07:00
bunnei 0897f4f96c core: hle: kernel: Add KPageTableManager. 2022-11-03 21:17:06 -07:00
bunnei 6d4f411c08 core: hle: kernel: Add KPageTableSlabHeap. 2022-11-03 21:17:06 -07:00
bunnei 37b17252d1 core: hle: kernel: Add KEventInfo. 2022-11-03 21:17:06 -07:00
bunnei ddd3f48736 core: hle: kernel: Add KDebug. 2022-11-03 21:17:06 -07:00
bunnei 46322be735 core: hle: result: Fix code for compilers. 2022-11-03 21:17:06 -07:00
Fernando S 3794851f7f Merge pull request #9154 from liamwhite/new-fb
vk_blit_screen: recreate swapchain images on guest format change
2022-11-04 01:25:34 +01:00
Morph 74275d0968 Merge pull request #9097 from liamwhite/intel-spv-compiler
video_core: don't build ASTC decoder shader unless requested
2022-11-03 19:29:33 -04:00
bunnei ca0d9ef4b8 Merge pull request #9166 from Docteh/tx-update-20221102021425
Manually import Ukrainian language file
2022-11-02 22:23:52 -07:00
bunnei 846b6fba82 Merge pull request #9157 from yuzu-emu/acc-stored-users
core: hle: service: acc: Fix ListOpenContextStoredUsers/StoreOpenContext.
2022-11-02 19:42:04 -07:00
bunnei 75ab52f05b core: hle: service: acc: Fix ListOpenContextStoredUsers/StoreOpenContext.
- These APIs are used to capture the opened users and allow that state to be persisted across processes.
- They are not intended to just return the system opened users, that is what ListOpenUsers is for.
- Fixes the launch hang with Bayonetta 3.
2022-11-02 16:09:30 -07:00
bunnei 83f649240e Merge pull request #9171 from driskiou/fix-menu-separator
remove unnecessary sepator in file menu (main.ui)
2022-11-02 10:17:39 -07:00
Ludovic f325fcb131 remove unnecessary sepator in file menu (main.ui) 2022-11-02 17:33:53 +01:00
Kyle Kienapfel 5e4ab2d42c Manually import Ukrainian language files
I'm not sure if GillianMC and I can claim that yuzu is first emulator translated to Ukrainian until the language files are used in builds.
2022-11-02 02:22:18 -07:00
liamwhite de4afde065 Merge pull request #9143 from K0bin/scheduler-empty
vk_scheduler: Remove recorded_counts
2022-10-31 21:37:46 -04:00
Liam 77b74f5d95 sm:: avoid excessive port recreation 2022-10-31 17:47:39 -04:00
Liam 633411c20f kernel: fix single core for service threads 2022-10-31 17:45:46 -04:00
Liam 2228383322 kernel: fix port tracking 2022-10-31 17:45:46 -04:00
Liam 7aa91c8d9c k_server_session: add SendReplyHLE 2022-10-31 17:45:45 -04:00
Liam 7837185f0a service_thread: convert to map for session management 2022-10-31 17:44:07 -04:00
Liam 983f2b7074 kernel: invert session request handling flow 2022-10-31 17:44:06 -04:00
bunnei 7f0d0dd177 Merge pull request #9159 from liamwhite/kbork
kernel: more complete fix for KPort reference counting
2022-10-31 11:18:17 -07:00
FengChen b42b894785 video_core: Fix drawing trigger mechanism regression 2022-10-31 21:57:38 +08:00
Liam 4e9adae5da kernel: more complete fix for KPort reference counting 2022-10-31 08:23:29 -04:00
bunnei f39d2cf78b Merge pull request #9155 from FernandoS27/goosfraba
Vulkan: Fix regression caused by limiting render area to width/height of render targets.
2022-10-30 17:34:28 -07:00
Fernando S d8ff939edc Merge pull request #9158 from liamwhite/single-bore
k_thread: fix single core
2022-10-31 00:58:07 +01:00
Liam eec3184bb0 k_thread: fix single core 2022-10-30 18:44:29 -04:00
Fernando Sahmkow 67e0d38152 Vulkan: Fix regression caused by limiting render area to width/height of rendef targets. 2022-10-30 21:24:28 +01:00
Liam 808e22984f vk_blit_screen: recreate swapchain images on guest format change 2022-10-30 15:04:16 -04:00
Morph e09756b2df Merge pull request #9151 from liamwhite/dram-size
kernel: reinitialize after dram layout change
2022-10-30 13:23:57 -04:00
Liam 8f00c59462 kernel: reinitialize after dram layout change 2022-10-30 11:01:22 -04:00
liamwhite 1cdd2d5204 Merge pull request #9091 from Docteh/what_compat_list
UI: Add option to hide the compatibility list
2022-10-30 09:17:16 -04:00
bunnei ccfdb7c1af Merge pull request #9149 from german77/volum
service: am: Stub SetRecordVolumeMuted
2022-10-29 23:36:15 -07:00
german77 6f0f7f1547 service: am: Stub SetRecordVolumeMuted
Used by bayonetta 3
2022-10-30 00:34:33 -05:00
bunnei 316a2c1715 Merge pull request #9148 from liamwhite/crab-language-at-home
k_server_session: fix crashes
2022-10-29 21:03:53 -07:00
Liam d867ae5ab6 k_server_session: fix crashes 2022-10-29 23:05:56 -04:00
bunnei c4d91488d9 Merge pull request #9137 from liamwhite/hbmenu
Improved support for nx-hbmenu
2022-10-29 16:11:26 -07:00
bunnei 72bff8ba11 Merge pull request #9140 from vonchenplus/darw_index_bufferx_first_error
video_core: Fix drawing trigger mechanism regression
2022-10-29 16:10:53 -07:00
bunnei 84d15c7f47 Merge pull request #9127 from vonchenplus/vulkan_clear
video_core: Catch vulkan clear op not all channel need clear
2022-10-27 19:19:40 -07:00
Robin Kertels dce242858a vk_scheduler: Remove recorded_counts 2022-10-28 03:42:43 +02:00
liamwhite 8ce6256722 Merge pull request #9138 from liamwhite/hbl-stacktrace
arm_interface: curb infinite recursion in stacktrace generation
2022-10-27 20:07:48 -04:00
Liam 3e6840a74c arm_interface: curb infinite recursion in stacktrace generation 2022-10-27 16:01:05 -04:00
bunnei 25d53e66d1 Merge pull request #9115 from vonchenplus/game_name_by_language
file_sys: Priority display of game titles in the current language
2022-10-27 11:33:02 -07:00
bunnei 20118075c5 Merge pull request #9126 from vonchenplus/revert-8068-shader-if-false
Revert "shader_recompiler/dead_code_elimination: Add DeadBranchElimination pass"
2022-10-27 10:11:02 -07:00
Liam 2cdfbbc07d nvnflinger: release queued handles immediately on disconnection 2022-10-27 08:28:02 -04:00
Liam cdb9fe978f vi: implement CloseDisplay 2022-10-27 08:27:38 -04:00
liamwhite 86a3a0b1b4 Merge pull request #9134 from lioncash/init
audio_in/out_system: Pass Initialize members by value where applicable
2022-10-27 08:10:24 -04:00
FengChen f6e7cae62c video_core: Fix drawing trigger mechanism regression 2022-10-27 13:26:52 +08:00
bunnei 2dd6a2352d Merge pull request #9125 from liamwhite/dummy-scheduler
kernel: refactor dummy thread wakeups
2022-10-26 09:51:44 -07:00
Lioncash e0ec9ffc36 audio_in/out_system: Pass Initialize members by value where applicable
applet_resource_user_id isn't actually modified and is just assigned to
a member variable, so this doesn't need to be a mutable reference.

Similarly, the device name itself isn't modified and is only moved. We
pass by value here, since we can still perform the move, but eliminate a
sneaky set of calls that can unintentionally destroy the original
string. Given how nested the calls are, it's good to get rid of this
potential vector for a use-after-move bug.
2022-10-26 11:21:48 -04:00
Mai 041eb5bf57 Merge pull request #9131 from Morph1984/contiguous
concepts: Use the std::contiguous_iterator concept
2022-10-26 15:12:48 +00:00
Morph 8b4d5aeb4f concepts: Use the std::contiguous_iterator concept
This also covers std::span, which does not have a const iterator.

Also renames IsSTLContainer to IsContiguousContainer to explicitly convey its semantics.
2022-10-26 00:41:54 -04:00
liamwhite d8e3380ea5 Merge pull request #9128 from abouvier/patch-1
tests: fix for -Wall
2022-10-25 12:36:25 -04:00
liamwhite e59bd6c335 Merge pull request #9113 from german77/peer_pressure
service: nfp: Allow amiibos without keys
2022-10-25 12:13:31 -04:00
liamwhite 77803d96be Merge pull request #9107 from german77/gidoly_rules
input_common: cache vibration tests
2022-10-25 12:13:18 -04:00
Alexandre Bouvier fa9b7db76f tests: fix for -Wall
Fix #9123
2022-10-25 15:20:23 +00:00
FengChen 0ec1801bc1 video_core: Catch vulkan clear op not all channel need clear 2022-10-25 22:39:29 +08:00
liamwhite fa913a702f Merge pull request #9112 from vonchenplus/deferred_draw
video_core: Reimplementing the maxwell drawing trigger mechanism
2022-10-25 09:42:59 -04:00
liamwhite 3c38bd7cf0 Merge pull request #9119 from liamwhite/shutdown-barrier
core: barrier service thread shutdown
2022-10-25 06:45:51 -04:00
Feng Chen 165bce3c2d Revert "shader_recompiler/dead_code_elimination: Add DeadBranchElimination pass" 2022-10-25 12:57:25 +08:00
Liam 1a378a7769 kernel: refactor dummy thread wakeups 2022-10-24 19:52:01 -04:00
bunnei cbb6c24215 Merge pull request #8873 from vonchenplus/fix_legacy_location_error
video_core: Fix legacy to generic location unpaired
2022-10-24 10:50:24 -07:00
FengChen 1689e0a71f file_sys: Priority display of game titles in the current language 2022-10-24 21:55:25 +08:00
Fernando S 2e782a154d Merge pull request #9122 from liamwhite/burnt-chicken
nvdrv: fix container destruction order
2022-10-24 12:41:46 +02:00
bunnei 0313ee7793 Merge pull request #9105 from Morph1984/warnings
general: Treat more warnings as errors
2022-10-23 17:25:18 -07:00
Liam 05f2673648 nvdrv: fix container destruction order 2022-10-23 19:25:57 -04:00
Liam 2d90a927c9 core: barrier service thread shutdown 2022-10-23 05:45:45 -04:00
german77 2ccbf5abdd core: hid: Add handheld to nfc devices 2022-10-22 14:05:00 -05:00
Morph 120cd450e5 CMakeLists: Disable -Wbraced-scalar-init on Clang
Clang erroneously emits this warning when using designated initializers.
2022-10-22 15:02:04 -04:00
Morph f51c71e956 yuzu: Resolve -Wpessimizing-move 2022-10-22 15:02:04 -04:00
Morph bb31b0f261 startup_checks: Resolve -Wstringop-truncation
Copies up to sizeof(p_name) - 1 in strncpy and null terminates it at p_name[254]
2022-10-22 15:02:04 -04:00
Morph f86774c1ac startup_checks: Resolve -Wformat 2022-10-22 15:02:04 -04:00
Morph 42c4ef7373 general: Resolve -Wunused-but-set-variable 2022-10-22 15:02:04 -04:00
Morph c7e079a5d4 general: Resolve -Wunused-lambda-capture and C5233 2022-10-22 15:02:04 -04:00
Morph 6908ea2284 general: Resolve -Wclass-memaccess 2022-10-22 15:02:04 -04:00
Morph 347432524c ipc_helpers: Ignore GCC compiler warnings only on GCC
Clang and ICC for whatever reason also defines __GNUC__. Exclude them from this check.
2022-10-22 15:02:04 -04:00
Morph b02c3f2314 CMakeLists: Enforce C5233 on MSVC
This is similar to Clang's -Wunused-lambda-capture
2022-10-22 15:02:04 -04:00
Morph 3822e31323 CMakeLists: Disable C4100 and C4324
Disabling C4100 is similar to -Wno-unused-parameter
2022-10-22 15:02:04 -04:00
Morph cae108404a CMakeLists: Remove redundant warnings
These warnings are already included in /W3.
2022-10-22 15:02:04 -04:00
Morph bad3025951 decoders: Use 2's complement instead of unary -
Resolves C4146 on MSVC
2022-10-22 15:02:04 -04:00
Morph f3c40f4a20 CMakeLists: Treat MSVC warnings as errors 2022-10-22 15:02:04 -04:00
Morph e6ab1f673b general: Enforce C4800 everywhere except in video_core 2022-10-22 15:02:04 -04:00
Morph 93297d14d8 CMakeLists: Remove all redundant warnings
These are already explicitly or implicitly set in src/CMakeLists.txt
2022-10-22 15:02:04 -04:00
Morph 91c410c918 CMakeLists: Consolidate all unused warnings into -Wunused 2022-10-22 15:02:04 -04:00
Morph 496695618a CMakeLists: Treat -Wall and -Wextra as errors 2022-10-22 15:02:04 -04:00
Fernando S 0860fffd78 Merge pull request #9095 from FernandoS27/meat-good-vegetable-bad
Maxwell3D/Puller: Fix regressions and syncing issues.
2022-10-22 13:06:03 +02:00
FengChen 2f90694797 video_core: Implement maxwell inline_index method 2022-10-22 16:58:23 +08:00
Narr the Reg 3e0aaeba98 service: nfp: Allow amiibos without keys 2022-10-21 23:08:07 -05:00
Narr the Reg 82fdfb33ac service: nfp: remove unnecessary include 2022-10-21 21:54:31 -05:00
FengChen 1f54cd4ac7 video_coare: Reimplementing the maxwell drawing trigger mechanism 2022-10-21 17:09:22 +08:00
liamwhite efaedcab31 Merge pull request #9106 from lioncash/copy-err
hid/npad: Fix copy size in GetSupportedNpadIdTypes
2022-10-21 03:47:02 -04:00
liamwhite 49682a0481 Merge pull request #9108 from Morph1984/r32-b24g8
format_lookup_table: Implement R32_B24G8 with D32_FLOAT_S8_UINT
2022-10-21 03:45:49 -04:00
liamwhite aa9e9052a6 Merge pull request #9109 from lioncash/session
k_session_request: Add missing override
2022-10-21 03:44:30 -04:00
Lioncash 93a7058d8e k_session_request: Add missing override specifier 2022-10-21 01:56:14 -04:00
Morph f16db300c6 format_lookup_table: Implement R32_B24G8 with D32_FLOAT_S8_UINT
This format is similar to Z32_FLOAT_X24S8_UINT, which is implemented with D32_FLOAT_S8_UINT.

Used in Persona 5 Royal
2022-10-21 01:54:57 -04:00
Lioncash 969387a79a k_session_request: Turn C-style array into std::array
Makes for stronger typing and allows tooling bounds checks provided by
the standard library for debugging purposes.
2022-10-21 01:54:34 -04:00
Lioncash 3968faec06 k_session_request: Simplify constructor initialization 2022-10-21 01:53:10 -04:00
german77 7f66050f0c input_common: cache vibration tests 2022-10-21 00:24:08 -05:00
Lioncash 0b181eeef4 hid/npad: Fix copy size in GetSupportedNpadIdTypes
Previously this was passing the size of the vector into memcpy rather
than the size in bytes to copy, which would result in a partial read.

Thankfully, this function isn't used yet, so this gets rid of a bug
before it's able to do anything.
2022-10-21 00:09:22 -04:00
bunnei 6b71530fa8 Merge pull request #9088 from Fdawgs/chore/images
general: compress png images
2022-10-20 18:42:26 -07:00
liamwhite a6628e8dba Merge pull request #9078 from liamwhite/session-request
kernel: Session request cleanup
2022-10-20 18:07:30 -04:00
liamwhite 9e16837088 Merge pull request #9099 from Docteh/undocked
Controller Applet had instance of Undocked, make Handheld
2022-10-20 18:05:05 -04:00
bunnei c0b1bdd237 Merge pull request #9096 from Kelebek1/audio_15
[audio_core] Update for firmware 15.0.0
2022-10-20 13:17:26 -07:00
Kyle Kienapfel d4c0b7b437 Controller Applet had instance of Undocked, make Handheld
Remember that time we renamed the Undocked option to Handheld in the
status bar, and then later remembered the Controller Configuration?

Scrolling through Transifex I noticed that we still have one instance of
"Undocked" in the text.
2022-10-20 06:55:23 -07:00
liamwhite 7daf751b8d Merge pull request #9094 from lioncash/fixed
common/fixed_point: Minor interface improvements
2022-10-19 19:00:59 -04:00
Liam 9524e28d20 video_core: don't build ASTC decoder shader unless requested 2022-10-19 18:52:42 -04:00
Liam fca195b4fb kernel: remove most SessionRequestManager handling from KServerSession 2022-10-19 16:31:12 -04:00
Liam 3efb8eb2dc kernel: add KSessionRequest 2022-10-19 16:31:12 -04:00
liamwhite 5ffb8b8039 Merge pull request #9082 from Morph1984/future
savedata_factory: Detect future save data paths
2022-10-19 16:28:42 -04:00
liamwhite 925fb63478 Merge pull request #9083 from liamwhite/take-a-chance-on-me
kernel: fix slab heap ABA
2022-10-19 16:27:59 -04:00
liamwhite 560bca57a2 Merge pull request #9071 from bunnei/mp-mm
Kernel Multiprocess (Part 1) - Persist memory & core timing
2022-10-19 16:27:43 -04:00
bunnei 97879faea4 core: hle: kernel: Migrate ProcessState to enum class. 2022-10-19 14:03:50 -04:00
Kyle Kienapfel 470e89a8ed UI: Add option to hide the compatibility list
Option is added directly below the option for the addons column

Defaulting to hide compatibility list. Changing default works properly.

Co-authored-by: Piplup <piplup55@users.noreply.github.com>
2022-10-19 03:51:51 -07:00
Kelebek1 7bd3930939 Update audio_core for firmware 15.0.0 2022-10-19 06:16:15 +01:00
Fernando S b8a70c9999 Merge pull request #9084 from vonchenplus/dma_copy
video_core: implement 1D copies based on VMM 'kind'
2022-10-19 06:56:00 +02:00
Fernando Sahmkow 3cb4498142 Maxwell3D/Puller: Fix regressions and syncing issues. 2022-10-19 06:21:51 +02:00
bunnei a264b54022 core: Initialize: Add missing braces. 2022-10-18 19:13:35 -07:00
bunnei 638fa6170a core: core_timing: Re-initialize if single/multicore state changes. 2022-10-18 19:13:35 -07:00
bunnei 11f85ea713 core: core_timing: Remove unused IsHostTiming. 2022-10-18 19:13:35 -07:00
bunnei 829e82e264 core: hle: kernel: Use result macros for new/changed code. 2022-10-18 19:13:35 -07:00
bunnei a4d11f4427 core: Partially persist emulation state across game boots. 2022-10-18 19:13:35 -07:00
bunnei 1b787adbd0 core: hle: kernel: Fix InitializePreemption order. 2022-10-18 19:13:35 -07:00
bunnei abcc009dff core: hle: kernel: k_process: Improve management of page table & cleanup. 2022-10-18 19:13:35 -07:00
bunnei 79bcb38321 core: hle: kernel: k_interrupt_manager: HandleInterrupt should not depend on current process. 2022-10-18 19:13:35 -07:00
bunnei 8d4e026d05 core: hle: kernel: Remove junk. 2022-10-18 19:13:35 -07:00
bunnei ff26190d42 core: hle: kernel: k_page_table: Impl. LockForUn/MapDeviceAddressSpace, cleanup. 2022-10-18 19:13:35 -07:00
bunnei d00245d444 video_core: renderer_vulkan: vk_query_cache: Avoid shutdown crash in QueryPool::Reserve. 2022-10-18 19:13:35 -07:00
bunnei 1baedfa12c core: hle: kernel: Integration application memory block slab manager. 2022-10-18 19:13:34 -07:00
bunnei ed591934fb core: hle: kernel: k_page_table: Update, and integrate with new KMemoryBlockManager/SlabManager. 2022-10-18 19:13:34 -07:00
bunnei 58eb6953d1 core: hle: kernel: k_memory_block: Update. 2022-10-18 19:13:34 -07:00
bunnei 2bb41cffca core: hle: kernel: k_memory_block_manager: Update. 2022-10-18 19:13:34 -07:00
bunnei 57a77e9ff4 core: hle: kernel: k_thread: Implement thread termination DPC. 2022-10-18 19:13:34 -07:00
bunnei d02ccfb15d core: hle: kernel: Add KDynamicResourceManager. 2022-10-18 19:13:34 -07:00
bunnei 9ec5f75f43 core: hle: kernel: Add KDynamicSlabHeap. 2022-10-18 19:13:34 -07:00
bunnei 345b9e6a08 core: hle: kernel: Add KDynamicPageManager. 2022-10-18 19:13:34 -07:00
bunnei 25dcaf1eca core: hle: kernel: k_process: Change Status -> State. 2022-10-18 19:13:34 -07:00
bunnei 113a5ed68f core: hle: kernel: svc_types: Add SystemThreadPriorityHighest and ProcessState. 2022-10-18 19:13:34 -07:00
bunnei 47b8160666 core: device_memory: Templatize GetPointer(..). 2022-10-18 19:13:34 -07:00
bunnei cb073f95dc core: hle: result: Add GetInnerValue and Includes methods. 2022-10-18 19:13:34 -07:00
bunnei e63a5459e3 core: hle: kernel: svc_common: Add WaitInfinite & cleanup. 2022-10-18 19:13:34 -07:00
Lioncash 6e1c6297a3 fixed_point: Mark default constructor as constexpr
Ensures that a fixed-point value is always initialized

This likely also fixes several cases of uninitialized values being
operated on, since we have multiple areas in the codebase where the
default constructor is being used like:

Common::FixedPoint<50, 14> current_sample{};

and is then followed up with an arithmetic operation like += or
something else, which operates directly on FixedPoint's internal data
member, which would previously be uninitialized.
2022-10-18 16:06:50 -04:00
Lioncash b6119a55f9 fixed_point: Mark copy/move assignment operators and constructors as constexpr
Given these are just moving a raw value around, these can sensibly be
made constexpr to make the interface more useful.
2022-10-18 16:06:50 -04:00
Lioncash 0cfd90004b fixed_point: Mark std::swap and move constructor as noexcept
These shouldn't throw and can influence how some standard algorithms
will work.
2022-10-18 16:06:50 -04:00
Lioncash 2cc9d94060 fixed_point: Mark relevant member function [[nodiscard]]
Marks member functions as discard, where ignoring the return value would
be indicative of a bug or dead code.
2022-10-18 16:06:50 -04:00
Lioncash 0101ef9fb1 fixed_point: Make to_uint() non-const
This calls round_up(), which is a non-const member function, so if a
fixed-point instantiation ever calls to_uint(), it'll result in a
compiler error.

This allows the member function to work.

While we're at it, we can actually mark to_long_floor() as const, since
it's not modifying any member state.
2022-10-18 16:06:50 -04:00
Lioncash 9393f90ccf fixed_point: Use defaulted comparisons
Collapses all of the comparison functions down to a single line.
2022-10-18 16:06:50 -04:00
Lioncash 5000d814af fixed_point: Use variable templates and concepts where applicable
Makes a few things a little less noisy and removes the need for SFINAE
in quite a few functions.
2022-10-18 16:06:46 -04:00
bunnei 8649c46c74 Merge pull request #9054 from Docteh/just_lz4
CMake: Try add_library "lz4" if "lz4::lz4" is unavailable
2022-10-17 22:51:26 -07:00
bunnei 1deb997eba Merge pull request #9087 from Morph1984/once
general: Add missing pragma once
2022-10-17 22:50:02 -07:00
Liam 282cd3e5fe kernel: fix slab heap ABA 2022-10-17 17:53:32 -04:00
Frazer Smith 40d9107b23 general: compress png images 2022-10-17 15:08:07 +01:00
FengChen 23b6569fc2 video_core: implement 1D copies based on VMM 'kind' 2022-10-17 15:35:12 +08:00
FengChen 99507d0188 video_core: Implement memory manager page kind 2022-10-17 15:33:29 +08:00
Morph 88ccdaf10a fixed_point: Replace CONSTEXPR14 with constexpr
As we require the latest C++ standards to compile yuzu, checking for C++14 constexpr is not needed.
2022-10-17 03:16:54 -04:00
Morph bffbaddb79 general: Add missing pragma once 2022-10-17 03:14:31 -04:00
Morph c75a4bdeaa Merge pull request #9085 from Docteh/TX_TOKEN
Set TX_TOKEN for transifex client
2022-10-17 02:57:07 -04:00
Morph 2f37c7948f Merge pull request #9079 from Morph1984/unknown-unkowns
general: Fix spelling
2022-10-17 02:56:58 -04:00
Morph f107e58fde Merge pull request #9080 from lat9nq/sdl-audio-not-null
sdl2_sink: Avoid loading a null string into a vector
2022-10-17 02:56:38 -04:00
Kyle Kienapfel c70e1d0247 Set TX_TOKEN for transifex client
I did some tests on my own fork, and we're writing to ~/.transifexrc but
the client can't seem to read that file. maybe issue with $HOME or
something.

Workaround is to set TX_TOKEN environment variable and now the pesky
~/.transifexrc file is not needed.
2022-10-16 23:37:25 -07:00
Morph ae453ab6a8 savedata_factory: Detect future save data paths
Enable compatibility for new account/device save paths planned on a future implementation.
2022-10-16 23:49:55 -04:00
FengChen 20139f8a55 Address feedback 2022-10-17 09:40:44 +08:00
lat9nq 4b773b15a6 sdl2_sink: Inline variable init into if condition
Co-authored-by: Mai <mathew1800@gmail.com>
2022-10-16 21:36:40 -04:00
lat9nq 9fe077635e sdl2_sink: Distinguish between capture and non-capture device names
The function prototype appears to care whether we are loading capture
devices or not, and SDL_GetAudioDeviceName has a parameter to use it,
but for some reason it isn't.

This puts `capture` where it goes.
2022-10-16 03:15:54 -04:00
lat9nq 5c7eef3756 sdl2_sink: Check for null string when loading SDL audio devices
Attempting to place a null string into a vector of strings causes an
error that closes the application.

Don't.
2022-10-16 03:14:52 -04:00
Morph ddf5577799 video_core: Fix spelling of "synchronize" 2022-10-16 00:50:53 -04:00
Morph f706b3bd24 general: Fix spelling of "unknown" 2022-10-16 00:46:22 -04:00
bunnei d574bb4610 Merge pull request #9058 from Docteh/new_transifex_cli
New transifex client needs migrating to.
2022-10-15 21:39:03 -07:00
bunnei b0ba1a0b65 Merge pull request #9076 from Docteh/unknown
fix a tiny spelling mistake
2022-10-15 21:37:47 -07:00
Kyle Kienapfel 0ba03d1b3a fix a tiny spelling mistake
Kreato pointed this out over on discord.
2022-10-15 14:58:44 -07:00
Kyle Kienapfel fcebd36cde Translations: new transifex client
Currently we're using the python client which uses an API that they
state will sunset Nov 30, 2022.

`tx push -s` actually appears to work properly, some of the other
commands require tweaking, like instead of suggesting `tx pull -a` in
dist/languages we need to suggest `tx pull -t -a`
2022-10-14 23:12:40 -07:00
liamwhite ae6dd1143c Merge pull request #9061 from liamwhite/writable-event
kernel: remove KWritableEvent
2022-10-14 17:30:38 -04:00
liamwhite 1d38109714 Merge pull request #9055 from liamwhite/hbl
Preliminary support for nx-hbloader
2022-10-14 17:30:11 -04:00
Morph 6a9bbb0128 Merge pull request #9069 from german77/sdl2
audio_core: Revert sink name to sdl2
2022-10-14 13:16:38 -04:00
Narr the Reg d2170075e6 audio_core: Revert sink name to sdl2 2022-10-14 10:59:33 -05:00
Kyle Kienapfel 40af1111c2 CMake: Try add library "LZ4::lz4_shared" if "lz4::lz4" is unavailable
Right now this looks like a distro specific problem, but we'll have to see.

Over on Gentoo: with lz4 1.9.3 there is a lz4::lz4 library target, with 1.9.4 it's no longer
mentioned in the cmake files provided by the  package. (/usr/lib64/cmake/lz4)

arch and openSUSE have lz4 1.9.4 available so I checked there,
they only have .pc files for pkg-config, so asking for "lz4::lz4" works as usual

MSVC does require "lz4::lz4" to be asked for
2022-10-13 17:23:47 -07:00
liamwhite 553be194f6 Merge pull request #9067 from Morph1984/tess-cw
renderer_(opengl/vulkan): Fix tessellation clockwise parameter
2022-10-13 20:12:31 -04:00
liamwhite 048d3e2404 Merge pull request #9039 from Kelebek1/auto_backend
Auto select the SDL audio backend when Cubeb latency is too high
2022-10-13 20:12:22 -04:00
liamwhite 3c925a7282 Merge pull request #9032 from liamwhite/stub-friends
IFriendService: stub CheckFriendListAvailability
2022-10-13 20:12:08 -04:00
Mai e37d00332c Merge pull request #9065 from liamwhite/result-mess
result: enforce reference check specialization
2022-10-13 19:54:10 +00:00
Morph d3114c620d renderer_(opengl/vulkan): Fix tessellation clockwise parameter
This should be assigned CW only on Triangles_CW rather than not Triangles_CCW, making CCW the default winding order rather than CW.
2022-10-13 15:52:56 -04:00
Narr the Reg 26b76d2eaf Merge pull request #9066 from Morph1984/fix-stretch-to-window
settings: Update aspect_ratio range
2022-10-13 13:00:07 -05:00
Morph e2164f3417 settings: Update aspect_ratio range
Since 16:10 was added, the maximum value is now 4.
2022-10-13 12:24:04 -04:00
Liam c0fb5e876d result: enforce reference check specialization 2022-10-13 12:10:39 -04:00
Liam a9ace6856d kernel: remove KWritableEvent 2022-10-12 20:29:29 -04:00
bunnei 64c2ccb0cb Merge pull request #9034 from liamwhite/result-macros
kernel: add expanded result macros
2022-10-12 17:11:07 -07:00
bunnei dbacb31f61 Merge pull request #9027 from yuzu-emu/revert-8987-another-name-for-reinforcement-steel
Revert "vulkan: automatically use larger staging buffer sizes when possible"
2022-10-12 15:36:56 -07:00
bunnei 0b9f2c2f14 Merge pull request #9040 from liamwhite/woe-thirty-two
core_timing: use high-precision sleeps on non-Windows targets
2022-10-12 15:35:06 -07:00
bunnei e158167139 Merge pull request #9024 from liamwhite/async-screenshot
video_core: don't block rendering on screenshots
2022-10-12 13:26:32 -07:00
bunnei 3da4280e81 Merge pull request #9047 from german77/steam-aspect
yuzu: Add 16:10 aspect ratio
2022-10-12 12:54:23 -07:00
bunnei 77177a7e33 Merge pull request #9049 from liamwhite/monkeyhawk
syncpoint_manager: ensure handle is removable before removing
2022-10-12 12:34:22 -07:00
Liam 61a8696510 k_server_session: preliminary support for userspace server sessions 2022-10-11 18:40:40 -04:00
Liam 9b34afa588 Add implementation of svcCreateSession 2022-10-11 18:15:45 -04:00
Liam 6bcd676b61 general: preliminary support for hbl 2022-10-11 18:15:30 -04:00
liamwhite 133a68ee9b Merge pull request #9048 from Kelebek1/regs
[video_core] Fix stencil mask registers
2022-10-11 17:22:40 -04:00
Liam b1cd6cec19 syncpoint_manager: ensure handle is removable before removing 2022-10-10 19:22:26 -04:00
Kelebek1 4496030ea9 Fix stencil func registers, make clip control equivalent to how it was before, but surely wrong. 2022-10-10 20:59:57 +01:00
Narr the Reg eb74ef474b yuzu: Add 16:10 aspect ratio 2022-10-10 13:32:33 -05:00
Kelebek1 8c9e238a7b Choose the SDL audio backend when Cubeb reports too high of a latency 2022-10-09 13:47:59 +01:00
Liam 9632434243 core_timing: use high-precision sleeps on non-Windows targets 2022-10-08 18:27:40 -04:00
Liam 47a2efee73 kernel: add expanded result macros 2022-10-08 12:41:27 -04:00
Liam ddf64e56af IFriendService: stub CheckFriendListAvailability 2022-10-07 22:19:41 -04:00
Liam a5476541f2 video_core: don't block rendering on screenshots 2022-10-07 17:33:59 -04:00
liamwhite 20cf09471a Revert "vulkan: automatically use larger staging buffer sizes when possible" 2022-10-07 04:49:08 -04:00
FengChen d4cb0eac87 video_core: Fix legacy to generic location unpaired 2022-09-20 12:03:31 +08:00
Feng Chen c864cb5772 Merge branch 'master' into mipmap 2022-09-20 11:56:43 +08:00
FengChen 9a95c7fa14 video_core: Generate mipmap texture by drawing 2022-09-20 11:55:43 +08:00
336 changed files with 16650 additions and 3932 deletions
-12
View File
@@ -3,15 +3,6 @@
# SPDX-FileCopyrightText: 2021 yuzu Emulator Project
# SPDX-License-Identifier: GPL-2.0-or-later
# Setup RC file for tx
cat << EOF > ~/.transifexrc
[https://www.transifex.com]
hostname = https://www.transifex.com
username = api
password = $TRANSIFEX_API_TOKEN
EOF
set -x
echo -e "\e[1m\e[33mBuild tools information:\e[0m"
@@ -19,9 +10,6 @@ cmake --version
gcc -v
tx --version
# vcpkg needs these: curl zip unzip tar, have tar
apt-get install -y curl zip unzip
mkdir build && cd build
cmake .. -DENABLE_QT_TRANSLATION=ON -DGENERATE_QT_TRANSLATION=ON -DCMAKE_BUILD_TYPE=Release -DENABLE_SDL2=OFF -DYUZU_TESTS=OFF -DYUZU_USE_BUNDLED_VCPKG=ON
make translation
+2 -2
View File
@@ -19,11 +19,11 @@ jobs:
- uses: actions/checkout@v3
with:
submodules: recursive
fetch-depth: 0
fetch-depth: 0
- name: Update Translation
run: ./.ci/scripts/transifex/docker.sh
env:
TRANSIFEX_API_TOKEN: ${{ secrets.TRANSIFEX_API_TOKEN }}
TX_TOKEN: ${{ secrets.TRANSIFEX_API_TOKEN }}
reuse:
runs-on: ubuntu-latest
+9 -9
View File
@@ -133,13 +133,13 @@ if (NOT ENABLE_GENERIC)
if (MSVC)
detect_architecture("_M_AMD64" x86_64)
detect_architecture("_M_IX86" x86)
detect_architecture("_M_ARM" ARM)
detect_architecture("_M_ARM64" ARM64)
detect_architecture("_M_ARM" arm)
detect_architecture("_M_ARM64" arm64)
else()
detect_architecture("__x86_64__" x86_64)
detect_architecture("__i386__" x86)
detect_architecture("__arm__" ARM)
detect_architecture("__aarch64__" ARM64)
detect_architecture("__arm__" arm)
detect_architecture("__aarch64__" arm64)
endif()
endif()
@@ -218,11 +218,11 @@ if(ENABLE_QT)
set(QT_VERSION 5.15)
# Check for system Qt on Linux, fallback to bundled Qt
if (${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
if (UNIX AND NOT APPLE)
if (NOT YUZU_USE_BUNDLED_QT)
find_package(Qt5 ${QT_VERSION} COMPONENTS Widgets DBus Multimedia)
endif()
if (NOT Qt5_FOUND OR YUZU_USE_BUNDLED_QT)
if (${CMAKE_SYSTEM_NAME} STREQUAL "Linux" AND (NOT Qt5_FOUND OR YUZU_USE_BUNDLED_QT))
# Check for dependencies, then enable bundled Qt download
# Check that the system GLIBCXX version is compatible
@@ -323,7 +323,7 @@ if(ENABLE_QT)
set(YUZU_QT_NO_CMAKE_SYSTEM_PATH "NO_CMAKE_SYSTEM_PATH")
endif()
if ((${CMAKE_SYSTEM_NAME} STREQUAL "Linux") AND YUZU_USE_BUNDLED_QT)
if (UNIX AND NOT APPLE AND YUZU_USE_BUNDLED_QT)
find_package(Qt5 ${QT_VERSION} REQUIRED COMPONENTS Widgets Concurrent Multimedia DBus ${QT_PREFIX_HINT} ${YUZU_QT_NO_CMAKE_SYSTEM_PATH})
else()
find_package(Qt5 ${QT_VERSION} REQUIRED COMPONENTS Widgets Concurrent Multimedia ${QT_PREFIX_HINT} ${YUZU_QT_NO_CMAKE_SYSTEM_PATH})
@@ -541,9 +541,9 @@ add_definitions(-DBOOST_ERROR_CODE_HEADER_ONLY
# Adjustments for MSVC + Ninja
if (MSVC AND CMAKE_GENERATOR STREQUAL "Ninja")
add_compile_options(
/wd4711 # function 'function' selected for automatic inline expansion
/wd4464 # relative include path contains '..'
/wd4820 # 'identifier1': '4' bytes padding added after data member 'identifier2'
/wd4711 # function 'function' selected for automatic inline expansion
/wd4820 # 'bytes' bytes padding added after construct 'member_name'
)
endif()
Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.4 KiB

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.1 KiB

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.4 KiB

After

Width:  |  Height:  |  Size: 2.7 KiB

BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.1 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.1 KiB

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.8 KiB

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.5 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.7 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.3 KiB

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.3 KiB

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.3 KiB

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.6 KiB

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.3 KiB

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.6 KiB

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

+1 -1
View File
@@ -1,7 +1,7 @@
[main]
host = https://www.transifex.com
[yuzu.emulator]
[o:yuzu-emulator:p:yuzu:r:emulator]
file_filter = <lang>.ts
source_file = en.ts
source_lang = en
+3 -1
View File
@@ -1 +1,3 @@
This directory stores translation patches (TS files) for yuzu Qt frontend. This directory is linked with [yuzu project on transifex](https://www.transifex.com/yuzu-emulator/yuzu), so you can update the translation by executing `tx pull -a`. If you want to contribute to the translation, please go the transifex link and submit your translation there. This directory on the main repo will be synchronized with transifex periodically. Do not directly open PRs on github to modify the translation.
This directory stores translation patches (TS files) for yuzu Qt frontend. This directory is linked with [yuzu project on transifex](https://www.transifex.com/yuzu-emulator/yuzu), so you can update the translation by executing `tx pull -t -a`. If you want to contribute to the translation, please go the transifex link and submit your translation there. This directory on the main repo will be synchronized with transifex periodically.
Do not directly open PRs on github to modify the translation.
+7321
View File
File diff suppressed because it is too large Load Diff
Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 528 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.6 KiB

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

+5 -6
View File
@@ -7,15 +7,14 @@ include(DownloadExternals)
# xbyak
if (ARCHITECTURE_x86 OR ARCHITECTURE_x86_64)
add_library(xbyak INTERFACE)
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/xbyak/include)
file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/xbyak/xbyak DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/xbyak/include)
target_include_directories(xbyak SYSTEM INTERFACE ${CMAKE_CURRENT_BINARY_DIR}/xbyak/include)
target_compile_definitions(xbyak INTERFACE XBYAK_NO_OP_NAMES)
add_subdirectory(xbyak)
endif()
# Dynarmic
if (ARCHITECTURE_x86_64)
if (ARCHITECTURE_x86_64 OR ARCHITECTURE_arm64)
if (ARCHITECTURE_arm64)
set(DYNARMIC_FRONTENDS "A32")
endif()
set(DYNARMIC_NO_BUNDLED_FMT ON)
set(DYNARMIC_IGNORE_ASSERTS ON CACHE BOOL "" FORCE)
add_subdirectory(dynarmic)
+14 -19
View File
@@ -58,13 +58,11 @@ if (MSVC)
# Warnings
/W3
/we4018 # 'expression': signed/unsigned mismatch
/WX
/we4062 # Enumerator 'identifier' in a switch of enum 'enumeration' is not handled
/we4101 # 'identifier': unreferenced local variable
/we4189 # 'identifier': local variable is initialized but not referenced
/we4265 # 'class': class has virtual functions, but destructor is not virtual
/we4267 # 'var': conversion from 'size_t' to 'type', possible loss of data
/we4305 # 'context': truncation from 'type1' to 'type2'
/we4388 # 'expression': signed/unsigned mismatch
/we4389 # 'operator': signed/unsigned mismatch
/we4456 # Declaration of 'identifier' hides previous local declaration
@@ -75,10 +73,13 @@ if (MSVC)
/we4547 # 'operator': operator before comma has no effect; expected operator with side-effect
/we4549 # 'operator1': operator before comma has no effect; did you intend 'operator2'?
/we4555 # Expression has no effect; expected expression with side-effect
/we4715 # 'function': not all control paths return a value
/we4834 # Discarding return value of function with 'nodiscard' attribute
/we4826 # Conversion from 'type1' to 'type2' is sign-extended. This may cause unexpected runtime behavior.
/we5038 # data member 'member1' will be initialized after data member 'member2'
/we5233 # explicit lambda capture 'identifier' is not used
/we5245 # 'function': unreferenced function with internal linkage has been removed
/wd4100 # 'identifier': unreferenced formal parameter
/wd4324 # 'struct_name': structure was padded due to __declspec(align())
)
if (USE_CCACHE)
@@ -99,24 +100,18 @@ if (MSVC)
set(CMAKE_EXE_LINKER_FLAGS_RELEASE "/DEBUG /MANIFEST:NO /INCREMENTAL:NO /OPT:REF,ICF" CACHE STRING "" FORCE)
else()
add_compile_options(
-Wall
-Werror=array-bounds
-Werror=implicit-fallthrough
-Werror=all
-Werror=extra
-Werror=missing-declarations
-Werror=missing-field-initializers
-Werror=reorder
-Werror=shadow
-Werror=sign-compare
-Werror=switch
-Werror=uninitialized
-Werror=unused-function
-Werror=unused-result
-Werror=unused-variable
-Wextra
-Wmissing-declarations
-Werror=unused
-Wno-attributes
-Wno-invalid-offsetof
-Wno-unused-parameter
$<$<CXX_COMPILER_ID:Clang>:-Wno-braced-scalar-init>
$<$<CXX_COMPILER_ID:Clang>:-Wno-unused-private-field>
)
if (ARCHITECTURE_x86_64)
+2 -11
View File
@@ -206,27 +206,18 @@ if (MSVC)
/we4244 # 'conversion': conversion from 'type1' to 'type2', possible loss of data
/we4245 # 'conversion': conversion from 'type1' to 'type2', signed/unsigned mismatch
/we4254 # 'operator': conversion from 'type1:field_bits' to 'type2:field_bits', possible loss of data
/we4456 # Declaration of 'identifier' hides previous local declaration
/we4457 # Declaration of 'identifier' hides function parameter
/we4458 # Declaration of 'identifier' hides class member
/we4459 # Declaration of 'identifier' hides global declaration
/we4800 # Implicit conversion from 'type' to bool. Possible information loss
)
else()
target_compile_options(audio_core PRIVATE
-Werror=conversion
-Werror=ignored-qualifiers
-Werror=shadow
-Werror=unused-variable
$<$<CXX_COMPILER_ID:GNU>:-Werror=unused-but-set-parameter>
$<$<CXX_COMPILER_ID:GNU>:-Werror=unused-but-set-variable>
-Wno-sign-conversion
)
endif()
target_link_libraries(audio_core PUBLIC common core)
if (ARCHITECTURE_x86_64)
if (ARCHITECTURE_x86_64 OR ARCHITECTURE_arm64)
target_link_libraries(audio_core PRIVATE dynarmic)
endif()
+4 -4
View File
@@ -23,7 +23,7 @@ System::~System() {
void System::Finalize() {
Stop();
session->Finalize();
buffer_event->GetWritableEvent().Signal();
buffer_event->Signal();
}
void System::StartSession() {
@@ -56,7 +56,7 @@ Result System::IsConfigValid(const std::string_view device_name,
return ResultSuccess;
}
Result System::Initialize(std::string& device_name, const AudioInParameter& in_params,
Result System::Initialize(std::string device_name, const AudioInParameter& in_params,
const u32 handle_, const u64 applet_resource_user_id_) {
auto result{IsConfigValid(device_name, in_params)};
if (result.IsError()) {
@@ -142,7 +142,7 @@ void System::ReleaseBuffers() {
if (signal) {
// Signal if any buffer was released, or if none are registered, we need more.
buffer_event->GetWritableEvent().Signal();
buffer_event->Signal();
}
}
@@ -159,7 +159,7 @@ bool System::FlushAudioInBuffers() {
buffers.FlushBuffers(buffers_released);
if (buffers_released > 0) {
buffer_event->GetWritableEvent().Signal();
buffer_event->Signal();
}
return true;
}
+1 -1
View File
@@ -97,7 +97,7 @@ public:
* @param applet_resource_user_id - Unused.
* @return Result code.
*/
Result Initialize(std::string& device_name, const AudioInParameter& in_params, u32 handle,
Result Initialize(std::string device_name, const AudioInParameter& in_params, u32 handle,
u64 applet_resource_user_id);
/**
+5 -5
View File
@@ -24,7 +24,7 @@ System::~System() {
void System::Finalize() {
Stop();
session->Finalize();
buffer_event->GetWritableEvent().Signal();
buffer_event->Signal();
}
std::string_view System::GetDefaultOutputDeviceName() const {
@@ -49,8 +49,8 @@ Result System::IsConfigValid(std::string_view device_name,
return Service::Audio::ERR_INVALID_CHANNEL_COUNT;
}
Result System::Initialize(std::string& device_name, const AudioOutParameter& in_params, u32 handle_,
u64& applet_resource_user_id_) {
Result System::Initialize(std::string device_name, const AudioOutParameter& in_params, u32 handle_,
u64 applet_resource_user_id_) {
auto result = IsConfigValid(device_name, in_params);
if (result.IsError()) {
return result;
@@ -141,7 +141,7 @@ void System::ReleaseBuffers() {
bool signal{buffers.ReleaseBuffers(system.CoreTiming(), *session)};
if (signal) {
// Signal if any buffer was released, or if none are registered, we need more.
buffer_event->GetWritableEvent().Signal();
buffer_event->Signal();
}
}
@@ -158,7 +158,7 @@ bool System::FlushAudioOutBuffers() {
buffers.FlushBuffers(buffers_released);
if (buffers_released > 0) {
buffer_event->GetWritableEvent().Signal();
buffer_event->Signal();
}
return true;
}
+2 -2
View File
@@ -88,8 +88,8 @@ public:
* @param applet_resource_user_id - Unused.
* @return Result code.
*/
Result Initialize(std::string& device_name, const AudioOutParameter& in_params, u32 handle,
u64& applet_resource_user_id);
Result Initialize(std::string device_name, const AudioOutParameter& in_params, u32 handle,
u64 applet_resource_user_id);
/**
* Start this system.
@@ -91,7 +91,7 @@ Result InfoUpdater::UpdateVoices(VoiceContext& voice_context,
voice_info.Initialize();
for (u32 channel = 0; channel < in_param.channel_count; channel++) {
std::memset(voice_states[channel], 0, sizeof(VoiceState));
*voice_states[channel] = {};
}
}
@@ -94,7 +94,7 @@ void BiquadFilterCommand::Dump([[maybe_unused]] const ADSP::CommandListProcessor
void BiquadFilterCommand::Process(const ADSP::CommandListProcessor& processor) {
auto state_{reinterpret_cast<VoiceState::BiquadFilterState*>(state)};
if (needs_init) {
std::memset(state_, 0, sizeof(VoiceState::BiquadFilterState));
*state_ = {};
}
auto input_buffer{
@@ -30,7 +30,7 @@ void MultiTapBiquadFilterCommand::Process(const ADSP::CommandListProcessor& proc
for (u32 i = 0; i < filter_tap_count; i++) {
auto state{reinterpret_cast<VoiceState::BiquadFilterState*>(states[i])};
if (needs_init[i]) {
std::memset(state, 0, sizeof(VoiceState::BiquadFilterState));
*state = {};
}
ApplyBiquadFilterFloat(output_buffer, input_buffer, biquads[i].b, biquads[i].a, *state,
+56 -33
View File
@@ -98,9 +98,8 @@ System::System(Core::System& core_, Kernel::KEvent* adsp_rendered_event_)
: core{core_}, adsp{core.AudioCore().GetADSP()}, adsp_rendered_event{adsp_rendered_event_} {}
Result System::Initialize(const AudioRendererParameterInternal& params,
Kernel::KTransferMemory* transfer_memory, const u64 transfer_memory_size,
const u32 process_handle_, const u64 applet_resource_user_id_,
const s32 session_id_) {
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;
}
@@ -354,6 +353,8 @@ Result System::Initialize(const AudioRendererParameterInternal& params,
render_time_limit_percent = 100;
drop_voice = params.voice_drop_enabled && params.execution_mode == ExecutionMode::Auto;
drop_voice_param = 1.0f;
num_voices_dropped = 0;
allocator.Align(0x40);
command_workbuffer_size = allocator.GetRemainingSize();
@@ -534,7 +535,7 @@ Result System::Update(std::span<const u8> input, std::span<u8> performance, std:
return result;
}
adsp_rendered_event->GetWritableEvent().Clear();
adsp_rendered_event->Clear();
num_times_updated++;
const auto end_time{core.CoreTiming().GetClockTicks()};
@@ -547,7 +548,7 @@ u32 System::GetRenderingTimeLimit() const {
return render_time_limit_percent;
}
void System::SetRenderingTimeLimit(const u32 limit) {
void System::SetRenderingTimeLimit(u32 limit) {
render_time_limit_percent = limit;
}
@@ -625,7 +626,7 @@ void System::SendCommandToDsp() {
reset_command_buffers = false;
command_buffer_size = command_size;
if (remaining_command_count == 0) {
adsp_rendered_event->GetWritableEvent().Signal();
adsp_rendered_event->Signal();
}
} else {
adsp.ClearRemainCount(session_id);
@@ -635,7 +636,7 @@ void System::SendCommandToDsp() {
}
u64 System::GenerateCommand(std::span<u8> in_command_buffer,
[[maybe_unused]] const u64 command_buffer_size_) {
[[maybe_unused]] u64 command_buffer_size_) {
PoolMapper::ClearUseState(memory_pool_workbuffer, memory_pool_count);
const auto start_time{core.CoreTiming().GetClockTicks()};
@@ -693,7 +694,8 @@ u64 System::GenerateCommand(std::span<u8> in_command_buffer,
voice_context.SortInfo();
const auto start_estimated_time{command_buffer.estimated_process_time};
const auto start_estimated_time{drop_voice_param *
static_cast<f32>(command_buffer.estimated_process_time)};
command_generator.GenerateVoiceCommands();
command_generator.GenerateSubMixCommands();
@@ -712,11 +714,16 @@ u64 System::GenerateCommand(std::span<u8> in_command_buffer,
render_context.behavior->IsAudioRendererProcessingTimeLimit70PercentSupported();
time_limit_percent = 70.0f;
}
const auto end_estimated_time{drop_voice_param *
static_cast<f32>(command_buffer.estimated_process_time)};
const auto estimated_time{start_estimated_time - end_estimated_time};
const auto time_limit{static_cast<u32>(
static_cast<f32>(start_estimated_time - command_buffer.estimated_process_time) +
(((time_limit_percent / 100.0f) * 2'880'000.0) *
(static_cast<f32>(render_time_limit_percent) / 100.0f)))};
num_voices_dropped = DropVoices(command_buffer, start_estimated_time, time_limit);
estimated_time + (((time_limit_percent / 100.0f) * 2'880'000.0) *
(static_cast<f32>(render_time_limit_percent) / 100.0f)))};
num_voices_dropped =
DropVoices(command_buffer, static_cast<u32>(start_estimated_time), time_limit);
}
command_list_header->buffer_size = command_buffer.size;
@@ -737,24 +744,33 @@ u64 System::GenerateCommand(std::span<u8> in_command_buffer,
return command_buffer.size;
}
u32 System::DropVoices(CommandBuffer& command_buffer, const u32 estimated_process_time,
const u32 time_limit) {
f32 System::GetVoiceDropParameter() const {
return drop_voice_param;
}
void System::SetVoiceDropParameter(f32 voice_drop_) {
drop_voice_param = voice_drop_;
}
u32 System::DropVoices(CommandBuffer& command_buffer, u32 estimated_process_time, u32 time_limit) {
u32 i{0};
auto command_list{command_buffer.command_list.data() + sizeof(CommandListHeader)};
ICommand* cmd{};
ICommand* cmd{nullptr};
for (; i < command_buffer.count; i++) {
// Find a first valid voice to drop
while (i < command_buffer.count) {
cmd = reinterpret_cast<ICommand*>(command_list);
if (cmd->type != CommandId::Performance &&
cmd->type != CommandId::DataSourcePcmInt16Version1 &&
cmd->type != CommandId::DataSourcePcmInt16Version2 &&
cmd->type != CommandId::DataSourcePcmFloatVersion1 &&
cmd->type != CommandId::DataSourcePcmFloatVersion2 &&
cmd->type != CommandId::DataSourceAdpcmVersion1 &&
cmd->type != CommandId::DataSourceAdpcmVersion2) {
if (cmd->type == CommandId::Performance ||
cmd->type == CommandId::DataSourcePcmInt16Version1 ||
cmd->type == CommandId::DataSourcePcmInt16Version2 ||
cmd->type == CommandId::DataSourcePcmFloatVersion1 ||
cmd->type == CommandId::DataSourcePcmFloatVersion2 ||
cmd->type == CommandId::DataSourceAdpcmVersion1 ||
cmd->type == CommandId::DataSourceAdpcmVersion2) {
break;
}
command_list += cmd->size;
i++;
}
if (cmd == nullptr || command_buffer.count == 0 || i >= command_buffer.count) {
@@ -767,6 +783,7 @@ u32 System::DropVoices(CommandBuffer& command_buffer, const u32 estimated_proces
const auto node_id_type{cmd->node_id >> 28};
const auto node_id_base{cmd->node_id & 0xFFF};
// If the new estimated process time falls below the limit, we're done dropping.
if (estimated_process_time <= time_limit) {
break;
}
@@ -775,6 +792,7 @@ u32 System::DropVoices(CommandBuffer& command_buffer, const u32 estimated_proces
break;
}
// Don't drop voices marked with the highest priority.
auto& voice_info{voice_context.GetInfo(node_id_base)};
if (voice_info.priority == HighestVoicePriority) {
break;
@@ -783,18 +801,23 @@ u32 System::DropVoices(CommandBuffer& command_buffer, const u32 estimated_proces
voices_dropped++;
voice_info.voice_dropped = true;
if (i < command_buffer.count) {
while (cmd->node_id == node_id) {
if (cmd->type == CommandId::DepopPrepare) {
cmd->enabled = true;
} else if (cmd->type == CommandId::Performance || !cmd->enabled) {
cmd->enabled = false;
}
i++;
command_list += cmd->size;
cmd = reinterpret_cast<ICommand*>(command_list);
// First iteration should drop the voice, and then iterate through all of the commands tied
// to the voice. We don't need reverb on a voice which we've just removed, for example.
// Depops can't be removed otherwise we'll introduce audio popping, and we don't
// remove perf commands. Lower the estimated time for each command dropped.
while (i < command_buffer.count && cmd->node_id == node_id) {
if (cmd->type == CommandId::DepopPrepare) {
cmd->enabled = true;
} else if (cmd->enabled && cmd->type != CommandId::Performance) {
cmd->enabled = false;
estimated_process_time -= static_cast<u32>(
drop_voice_param * static_cast<f32>(cmd->estimated_process_time));
}
command_list += cmd->size;
cmd = reinterpret_cast<ICommand*>(command_list);
i++;
}
i++;
}
return voices_dropped;
}
+16
View File
@@ -196,6 +196,20 @@ public:
*/
u32 DropVoices(CommandBuffer& command_buffer, u32 estimated_process_time, u32 time_limit);
/**
* Get the current voice drop parameter.
*
* @return The current voice drop.
*/
f32 GetVoiceDropParameter() const;
/**
* Set the voice drop parameter.
*
* @param The new voice drop.
*/
void SetVoiceDropParameter(f32 voice_drop);
private:
/// Core system
Core::System& core;
@@ -301,6 +315,8 @@ private:
u32 num_voices_dropped{};
/// Tick that rendering started
u64 render_start_tick{};
/// Parameter to control the threshold for dropping voices if the audio graph gets too large
f32 drop_voice_param{1.0f};
};
} // namespace AudioRenderer
@@ -74,8 +74,8 @@ void VoiceContext::SortInfo() {
}
std::ranges::sort(sorted_voice_info, [](const VoiceInfo* a, const VoiceInfo* b) {
return a->priority != b->priority ? a->priority < b->priority
: a->sort_order < b->sort_order;
return a->priority != b->priority ? a->priority > b->priority
: a->sort_order > b->sort_order;
});
}
+29 -2
View File
@@ -66,10 +66,10 @@ public:
const auto latency_error = cubeb_get_min_latency(ctx, &params, &minimum_latency);
if (latency_error != CUBEB_OK) {
LOG_CRITICAL(Audio_Sink, "Error getting minimum latency, error: {}", latency_error);
minimum_latency = 256U;
minimum_latency = TargetSampleCount * 2;
}
minimum_latency = std::max(minimum_latency, 256u);
minimum_latency = std::max(minimum_latency, TargetSampleCount * 2);
LOG_INFO(Service_Audio,
"Opening cubeb stream {} type {} with: rate {} channels {} (system channels {}) "
@@ -326,4 +326,31 @@ std::vector<std::string> ListCubebSinkDevices(bool capture) {
return device_list;
}
u32 GetCubebLatency() {
cubeb* ctx;
if (cubeb_init(&ctx, "yuzu Latency Getter", nullptr) != CUBEB_OK) {
LOG_CRITICAL(Audio_Sink, "cubeb_init failed");
// Return a large latency so we choose SDL instead.
return 10000u;
}
cubeb_stream_params params{};
params.rate = TargetSampleRate;
params.channels = 2;
params.format = CUBEB_SAMPLE_S16LE;
params.prefs = CUBEB_STREAM_PREF_NONE;
params.layout = CUBEB_LAYOUT_STEREO;
u32 latency{0};
const auto latency_error = cubeb_get_min_latency(ctx, &params, &latency);
if (latency_error != CUBEB_OK) {
LOG_CRITICAL(Audio_Sink, "Error getting minimum latency, error: {}", latency_error);
latency = TargetSampleCount * 2;
}
latency = std::max(latency, TargetSampleCount * 2);
cubeb_destroy(ctx);
return latency;
}
} // namespace AudioCore::Sink
+7
View File
@@ -96,4 +96,11 @@ private:
*/
std::vector<std::string> ListCubebSinkDevices(bool capture);
/**
* Get the reported latency for this sink.
*
* @return Minimum latency for this sink.
*/
u32 GetCubebLatency();
} // namespace AudioCore::Sink
+8 -6
View File
@@ -47,11 +47,7 @@ public:
spec.freq = TargetSampleRate;
spec.channels = static_cast<u8>(device_channels);
spec.format = AUDIO_S16SYS;
if (type == StreamType::Render) {
spec.samples = TargetSampleCount;
} else {
spec.samples = 1024;
}
spec.samples = TargetSampleCount * 2;
spec.callback = &SDLSinkStream::DataCallback;
spec.userdata = this;
@@ -234,10 +230,16 @@ std::vector<std::string> ListSDLSinkDevices(bool capture) {
const int device_count = SDL_GetNumAudioDevices(capture);
for (int i = 0; i < device_count; ++i) {
device_list.emplace_back(SDL_GetAudioDeviceName(i, 0));
if (const char* name = SDL_GetAudioDeviceName(i, capture)) {
device_list.emplace_back(name);
}
}
return device_list;
}
u32 GetSDLLatency() {
return TargetSampleCount * 2;
}
} // namespace AudioCore::Sink
+7
View File
@@ -87,4 +87,11 @@ private:
*/
std::vector<std::string> ListSDLSinkDevices(bool capture);
/**
* Get the reported latency for this sink.
*
* @return Minimum latency for this sink.
*/
u32 GetSDLLatency();
} // namespace AudioCore::Sink
+44 -22
View File
@@ -21,58 +21,80 @@ namespace {
struct SinkDetails {
using FactoryFn = std::unique_ptr<Sink> (*)(std::string_view);
using ListDevicesFn = std::vector<std::string> (*)(bool);
using LatencyFn = u32 (*)();
/// Name for this sink.
const char* id;
std::string_view id;
/// A method to call to construct an instance of this type of sink.
FactoryFn factory;
/// A method to call to list available devices.
ListDevicesFn list_devices;
/// Method to get the latency of this backend.
LatencyFn latency;
};
// sink_details is ordered in terms of desirability, with the best choice at the top.
constexpr SinkDetails sink_details[] = {
#ifdef HAVE_CUBEB
SinkDetails{"cubeb",
[](std::string_view device_id) -> std::unique_ptr<Sink> {
return std::make_unique<CubebSink>(device_id);
},
&ListCubebSinkDevices},
SinkDetails{
"cubeb",
[](std::string_view device_id) -> std::unique_ptr<Sink> {
return std::make_unique<CubebSink>(device_id);
},
&ListCubebSinkDevices,
&GetCubebLatency,
},
#endif
#ifdef HAVE_SDL2
SinkDetails{"sdl2",
[](std::string_view device_id) -> std::unique_ptr<Sink> {
return std::make_unique<SDLSink>(device_id);
},
&ListSDLSinkDevices},
SinkDetails{
"sdl2",
[](std::string_view device_id) -> std::unique_ptr<Sink> {
return std::make_unique<SDLSink>(device_id);
},
&ListSDLSinkDevices,
&GetSDLLatency,
},
#endif
SinkDetails{"null",
[](std::string_view device_id) -> std::unique_ptr<Sink> {
return std::make_unique<NullSink>(device_id);
},
[](bool capture) { return std::vector<std::string>{"null"}; }},
[](bool capture) { return std::vector<std::string>{"null"}; }, []() { return 0u; }},
};
const SinkDetails& GetOutputSinkDetails(std::string_view sink_id) {
auto iter =
std::find_if(std::begin(sink_details), std::end(sink_details),
[sink_id](const auto& sink_detail) { return sink_detail.id == sink_id; });
const auto find_backend{[](std::string_view id) {
return std::find_if(std::begin(sink_details), std::end(sink_details),
[&id](const auto& sink_detail) { return sink_detail.id == id; });
}};
if (sink_id == "auto" || iter == std::end(sink_details)) {
if (sink_id != "auto") {
LOG_ERROR(Audio, "Invalid sink_id {}", sink_id);
auto iter = find_backend(sink_id);
if (sink_id == "auto") {
// Auto-select a backend. Prefer CubeB, but it may report a large minimum latency which
// causes audio issues, in that case go with SDL.
#if defined(HAVE_CUBEB) && defined(HAVE_SDL2)
iter = find_backend("cubeb");
if (iter->latency() > TargetSampleCount * 3) {
iter = find_backend("sdl2");
}
// Auto-select.
// sink_details is ordered in terms of desirability, with the best choice at the front.
#else
iter = std::begin(sink_details);
#endif
LOG_INFO(Service_Audio, "Auto-selecting the {} backend", iter->id);
}
if (iter == std::end(sink_details)) {
LOG_ERROR(Audio, "Invalid sink_id {}", sink_id);
iter = find_backend("null");
}
return *iter;
}
} // Anonymous namespace
std::vector<const char*> GetSinkIDs() {
std::vector<const char*> sink_ids(std::size(sink_details));
std::vector<std::string_view> GetSinkIDs() {
std::vector<std::string_view> sink_ids(std::size(sink_details));
std::transform(std::begin(sink_details), std::end(sink_details), std::begin(sink_ids),
[](const auto& sink) { return sink.id; });
+1 -1
View File
@@ -19,7 +19,7 @@ class Sink;
*
* @return Vector of available sink names.
*/
std::vector<const char*> GetSinkIDs();
std::vector<std::string_view> GetSinkIDs();
/**
* Gets the list of devices for a particular sink identified by the given ID.
+9 -4
View File
@@ -156,12 +156,13 @@ if (MSVC)
)
target_compile_options(common PRIVATE
/W4
/WX
/we4242 # 'identifier': conversion from 'type1' to 'type2', possible loss of data
/we4254 # 'operator': conversion from 'type1:field_bits' to 'type2:field_bits', possible loss of data
/we4800 # Implicit conversion from 'type' to bool. Possible information loss
)
else()
target_compile_options(common PRIVATE
-Werror
$<$<CXX_COMPILER_ID:Clang>:-fsized-deallocation>
)
endif()
@@ -169,7 +170,11 @@ endif()
create_target_directory_groups(common)
target_link_libraries(common PUBLIC ${Boost_LIBRARIES} fmt::fmt microprofile Threads::Threads)
target_link_libraries(common PRIVATE lz4::lz4)
if (TARGET lz4::lz4)
target_link_libraries(common PRIVATE lz4::lz4)
else()
target_link_libraries(common PRIVATE LZ4::lz4_shared)
endif()
if (TARGET zstd::zstd)
target_link_libraries(common PRIVATE zstd::zstd)
else()
+11 -4
View File
@@ -141,10 +141,6 @@ public:
constexpr BitField(BitField&&) noexcept = default;
constexpr BitField& operator=(BitField&&) noexcept = default;
[[nodiscard]] constexpr operator T() const {
return Value();
}
constexpr void Assign(const T& value) {
#ifdef _MSC_VER
storage = static_cast<StorageType>((storage & ~mask) | FormatValue(value));
@@ -162,6 +158,17 @@ public:
return ExtractValue(storage);
}
template <typename ConvertedToType>
[[nodiscard]] constexpr ConvertedToType As() const {
static_assert(!std::is_same_v<T, ConvertedToType>,
"Unnecessary cast. Use Value() instead.");
return static_cast<ConvertedToType>(Value());
}
[[nodiscard]] constexpr operator T() const {
return Value();
}
[[nodiscard]] constexpr explicit operator bool() const {
return Value() != 0;
}
-9
View File
@@ -21,11 +21,6 @@ constexpr size_t hardware_interference_size = std::hardware_destructive_interfer
constexpr size_t hardware_interference_size = 64;
#endif
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable : 4324)
#endif
template <typename T, size_t capacity = 0x400>
class MPSCQueue {
public:
@@ -160,8 +155,4 @@ private:
static_assert(std::is_nothrow_destructible_v<T>, "T must be nothrow destructible");
};
#ifdef _MSC_VER
#pragma warning(pop)
#endif
} // namespace Common
+3 -1
View File
@@ -31,8 +31,10 @@
#ifndef _MSC_VER
#ifdef ARCHITECTURE_x86_64
#if defined(ARCHITECTURE_x86_64)
#define Crash() __asm__ __volatile__("int $3")
#elif defined(ARCHITECTURE_arm64)
#define Crash() __asm__ __volatile__("brk #0")
#else
#define Crash() exit(1)
#endif
+11 -13
View File
@@ -3,24 +3,14 @@
#pragma once
#include <iterator>
#include <type_traits>
namespace Common {
// Check if type is like an STL container
// Check if type satisfies the ContiguousContainer named requirement.
template <typename T>
concept IsSTLContainer = requires(T t) {
typename T::value_type;
typename T::iterator;
typename T::const_iterator;
// TODO(ogniK): Replace below is std::same_as<void> when MSVC supports it.
t.begin();
t.end();
t.cbegin();
t.cend();
t.data();
t.size();
};
concept IsContiguousContainer = std::contiguous_iterator<typename T::iterator>;
// TODO: Replace with std::derived_from when the <concepts> header
// is available on all supported platforms.
@@ -34,4 +24,12 @@ concept DerivedFrom = requires {
template <typename From, typename To>
concept ConvertibleTo = std::is_convertible_v<From, To>;
// No equivalents in the stdlib
template <typename T>
concept IsArithmetic = std::is_arithmetic_v<T>;
template <typename T>
concept IsIntegral = std::is_integral_v<T>;
} // namespace Common
+110 -164
View File
@@ -4,14 +4,7 @@
// From: https://github.com/eteran/cpp-utilities/blob/master/fixed/include/cpp-utilities/fixed.h
// See also: http://stackoverflow.com/questions/79677/whats-the-best-way-to-do-fixed-point-math
#ifndef FIXED_H_
#define FIXED_H_
#if __cplusplus >= 201402L
#define CONSTEXPR14 constexpr
#else
#define CONSTEXPR14
#endif
#pragma once
#include <cstddef> // for size_t
#include <cstdint>
@@ -19,6 +12,8 @@
#include <ostream>
#include <type_traits>
#include <common/concepts.h>
namespace Common {
template <size_t I, size_t F>
@@ -57,8 +52,8 @@ struct type_from_size<64> {
static constexpr size_t size = 64;
using value_type = int64_t;
using unsigned_type = std::make_unsigned<value_type>::type;
using signed_type = std::make_signed<value_type>::type;
using unsigned_type = std::make_unsigned_t<value_type>;
using signed_type = std::make_signed_t<value_type>;
using next_size = type_from_size<128>;
};
@@ -68,8 +63,8 @@ struct type_from_size<32> {
static constexpr size_t size = 32;
using value_type = int32_t;
using unsigned_type = std::make_unsigned<value_type>::type;
using signed_type = std::make_signed<value_type>::type;
using unsigned_type = std::make_unsigned_t<value_type>;
using signed_type = std::make_signed_t<value_type>;
using next_size = type_from_size<64>;
};
@@ -79,8 +74,8 @@ struct type_from_size<16> {
static constexpr size_t size = 16;
using value_type = int16_t;
using unsigned_type = std::make_unsigned<value_type>::type;
using signed_type = std::make_signed<value_type>::type;
using unsigned_type = std::make_unsigned_t<value_type>;
using signed_type = std::make_signed_t<value_type>;
using next_size = type_from_size<32>;
};
@@ -90,8 +85,8 @@ struct type_from_size<8> {
static constexpr size_t size = 8;
using value_type = int8_t;
using unsigned_type = std::make_unsigned<value_type>::type;
using signed_type = std::make_signed<value_type>::type;
using unsigned_type = std::make_unsigned_t<value_type>;
using signed_type = std::make_signed_t<value_type>;
using next_size = type_from_size<16>;
};
@@ -106,9 +101,9 @@ constexpr B next_to_base(N rhs) {
struct divide_by_zero : std::exception {};
template <size_t I, size_t F>
CONSTEXPR14 FixedPoint<I, F> divide(
constexpr FixedPoint<I, F> divide(
FixedPoint<I, F> numerator, FixedPoint<I, F> denominator, FixedPoint<I, F>& remainder,
typename std::enable_if<type_from_size<I + F>::next_size::is_specialized>::type* = nullptr) {
std::enable_if_t<type_from_size<I + F>::next_size::is_specialized>* = nullptr) {
using next_type = typename FixedPoint<I, F>::next_type;
using base_type = typename FixedPoint<I, F>::base_type;
@@ -126,9 +121,9 @@ CONSTEXPR14 FixedPoint<I, F> divide(
}
template <size_t I, size_t F>
CONSTEXPR14 FixedPoint<I, F> divide(
constexpr FixedPoint<I, F> divide(
FixedPoint<I, F> numerator, FixedPoint<I, F> denominator, FixedPoint<I, F>& remainder,
typename std::enable_if<!type_from_size<I + F>::next_size::is_specialized>::type* = nullptr) {
std::enable_if_t<!type_from_size<I + F>::next_size::is_specialized>* = nullptr) {
using unsigned_type = typename FixedPoint<I, F>::unsigned_type;
@@ -196,9 +191,9 @@ CONSTEXPR14 FixedPoint<I, F> divide(
// this is the usual implementation of multiplication
template <size_t I, size_t F>
CONSTEXPR14 FixedPoint<I, F> multiply(
constexpr FixedPoint<I, F> multiply(
FixedPoint<I, F> lhs, FixedPoint<I, F> rhs,
typename std::enable_if<type_from_size<I + F>::next_size::is_specialized>::type* = nullptr) {
std::enable_if_t<type_from_size<I + F>::next_size::is_specialized>* = nullptr) {
using next_type = typename FixedPoint<I, F>::next_type;
using base_type = typename FixedPoint<I, F>::base_type;
@@ -215,9 +210,9 @@ CONSTEXPR14 FixedPoint<I, F> multiply(
// it is slightly slower, but is more robust since it doesn't
// require and upgraded type
template <size_t I, size_t F>
CONSTEXPR14 FixedPoint<I, F> multiply(
constexpr FixedPoint<I, F> multiply(
FixedPoint<I, F> lhs, FixedPoint<I, F> rhs,
typename std::enable_if<!type_from_size<I + F>::next_size::is_specialized>::type* = nullptr) {
std::enable_if_t<!type_from_size<I + F>::next_size::is_specialized>* = nullptr) {
using base_type = typename FixedPoint<I, F>::base_type;
@@ -272,19 +267,20 @@ public:
static constexpr base_type one = base_type(1) << fractional_bits;
public: // constructors
FixedPoint() = default;
FixedPoint(const FixedPoint&) = default;
FixedPoint(FixedPoint&&) = default;
FixedPoint& operator=(const FixedPoint&) = default;
constexpr FixedPoint() = default;
template <class Number>
constexpr FixedPoint(
Number n, typename std::enable_if<std::is_arithmetic<Number>::value>::type* = nullptr)
: data_(static_cast<base_type>(n * one)) {}
constexpr FixedPoint(const FixedPoint&) = default;
constexpr FixedPoint& operator=(const FixedPoint&) = default;
constexpr FixedPoint(FixedPoint&&) noexcept = default;
constexpr FixedPoint& operator=(FixedPoint&&) noexcept = default;
template <IsArithmetic Number>
constexpr FixedPoint(Number n) : data_(static_cast<base_type>(n * one)) {}
public: // conversion
template <size_t I2, size_t F2>
CONSTEXPR14 explicit FixedPoint(FixedPoint<I2, F2> other) {
constexpr explicit FixedPoint(FixedPoint<I2, F2> other) {
static_assert(I2 <= I && F2 <= F, "Scaling conversion can only upgrade types");
using T = FixedPoint<I2, F2>;
@@ -308,36 +304,14 @@ public:
}
public: // comparison operators
constexpr bool operator==(FixedPoint rhs) const {
return data_ == rhs.data_;
}
constexpr bool operator!=(FixedPoint rhs) const {
return data_ != rhs.data_;
}
constexpr bool operator<(FixedPoint rhs) const {
return data_ < rhs.data_;
}
constexpr bool operator>(FixedPoint rhs) const {
return data_ > rhs.data_;
}
constexpr bool operator<=(FixedPoint rhs) const {
return data_ <= rhs.data_;
}
constexpr bool operator>=(FixedPoint rhs) const {
return data_ >= rhs.data_;
}
friend constexpr auto operator<=>(FixedPoint lhs, FixedPoint rhs) = default;
public: // unary operators
constexpr bool operator!() const {
[[nodiscard]] constexpr bool operator!() const {
return !data_;
}
constexpr FixedPoint operator~() const {
[[nodiscard]] constexpr FixedPoint operator~() const {
// NOTE(eteran): this will often appear to "just negate" the value
// that is not an error, it is because -x == (~x+1)
// and that "+1" is adding an infinitesimally small fraction to the
@@ -345,89 +319,87 @@ public: // unary operators
return FixedPoint::from_base(~data_);
}
constexpr FixedPoint operator-() const {
[[nodiscard]] constexpr FixedPoint operator-() const {
return FixedPoint::from_base(-data_);
}
constexpr FixedPoint operator+() const {
[[nodiscard]] constexpr FixedPoint operator+() const {
return FixedPoint::from_base(+data_);
}
CONSTEXPR14 FixedPoint& operator++() {
constexpr FixedPoint& operator++() {
data_ += one;
return *this;
}
CONSTEXPR14 FixedPoint& operator--() {
constexpr FixedPoint& operator--() {
data_ -= one;
return *this;
}
CONSTEXPR14 FixedPoint operator++(int) {
constexpr FixedPoint operator++(int) {
FixedPoint tmp(*this);
data_ += one;
return tmp;
}
CONSTEXPR14 FixedPoint operator--(int) {
constexpr FixedPoint operator--(int) {
FixedPoint tmp(*this);
data_ -= one;
return tmp;
}
public: // basic math operators
CONSTEXPR14 FixedPoint& operator+=(FixedPoint n) {
constexpr FixedPoint& operator+=(FixedPoint n) {
data_ += n.data_;
return *this;
}
CONSTEXPR14 FixedPoint& operator-=(FixedPoint n) {
constexpr FixedPoint& operator-=(FixedPoint n) {
data_ -= n.data_;
return *this;
}
CONSTEXPR14 FixedPoint& operator*=(FixedPoint n) {
constexpr FixedPoint& operator*=(FixedPoint n) {
return assign(detail::multiply(*this, n));
}
CONSTEXPR14 FixedPoint& operator/=(FixedPoint n) {
constexpr FixedPoint& operator/=(FixedPoint n) {
FixedPoint temp;
return assign(detail::divide(*this, n, temp));
}
private:
CONSTEXPR14 FixedPoint& assign(FixedPoint rhs) {
constexpr FixedPoint& assign(FixedPoint rhs) {
data_ = rhs.data_;
return *this;
}
public: // binary math operators, effects underlying bit pattern since these
// don't really typically make sense for non-integer values
CONSTEXPR14 FixedPoint& operator&=(FixedPoint n) {
constexpr FixedPoint& operator&=(FixedPoint n) {
data_ &= n.data_;
return *this;
}
CONSTEXPR14 FixedPoint& operator|=(FixedPoint n) {
constexpr FixedPoint& operator|=(FixedPoint n) {
data_ |= n.data_;
return *this;
}
CONSTEXPR14 FixedPoint& operator^=(FixedPoint n) {
constexpr FixedPoint& operator^=(FixedPoint n) {
data_ ^= n.data_;
return *this;
}
template <class Integer,
class = typename std::enable_if<std::is_integral<Integer>::value>::type>
CONSTEXPR14 FixedPoint& operator>>=(Integer n) {
template <IsIntegral Integer>
constexpr FixedPoint& operator>>=(Integer n) {
data_ >>= n;
return *this;
}
template <class Integer,
class = typename std::enable_if<std::is_integral<Integer>::value>::type>
CONSTEXPR14 FixedPoint& operator<<=(Integer n) {
template <IsIntegral Integer>
constexpr FixedPoint& operator<<=(Integer n) {
data_ <<= n;
return *this;
}
@@ -437,42 +409,42 @@ public: // conversion to basic types
data_ += (data_ & fractional_mask) >> 1;
}
constexpr int to_int() {
[[nodiscard]] constexpr int to_int() {
round_up();
return static_cast<int>((data_ & integer_mask) >> fractional_bits);
}
constexpr unsigned int to_uint() const {
[[nodiscard]] constexpr unsigned int to_uint() {
round_up();
return static_cast<unsigned int>((data_ & integer_mask) >> fractional_bits);
}
constexpr int64_t to_long() {
[[nodiscard]] constexpr int64_t to_long() {
round_up();
return static_cast<int64_t>((data_ & integer_mask) >> fractional_bits);
}
constexpr int to_int_floor() const {
[[nodiscard]] constexpr int to_int_floor() const {
return static_cast<int>((data_ & integer_mask) >> fractional_bits);
}
constexpr int64_t to_long_floor() {
[[nodiscard]] constexpr int64_t to_long_floor() const {
return static_cast<int64_t>((data_ & integer_mask) >> fractional_bits);
}
constexpr unsigned int to_uint_floor() const {
[[nodiscard]] constexpr unsigned int to_uint_floor() const {
return static_cast<unsigned int>((data_ & integer_mask) >> fractional_bits);
}
constexpr float to_float() const {
[[nodiscard]] constexpr float to_float() const {
return static_cast<float>(data_) / FixedPoint::one;
}
constexpr double to_double() const {
[[nodiscard]] constexpr double to_double() const {
return static_cast<double>(data_) / FixedPoint::one;
}
constexpr base_type to_raw() const {
[[nodiscard]] constexpr base_type to_raw() const {
return data_;
}
@@ -480,27 +452,27 @@ public: // conversion to basic types
data_ &= fractional_mask;
}
constexpr base_type get_frac() const {
[[nodiscard]] constexpr base_type get_frac() const {
return data_ & fractional_mask;
}
public:
CONSTEXPR14 void swap(FixedPoint& rhs) {
constexpr void swap(FixedPoint& rhs) noexcept {
using std::swap;
swap(data_, rhs.data_);
}
public:
base_type data_;
base_type data_{};
};
// if we have the same fractional portion, but differing integer portions, we trivially upgrade the
// smaller type
template <size_t I1, size_t I2, size_t F>
CONSTEXPR14 typename std::conditional<I1 >= I2, FixedPoint<I1, F>, FixedPoint<I2, F>>::type
operator+(FixedPoint<I1, F> lhs, FixedPoint<I2, F> rhs) {
constexpr std::conditional_t<I1 >= I2, FixedPoint<I1, F>, FixedPoint<I2, F>> operator+(
FixedPoint<I1, F> lhs, FixedPoint<I2, F> rhs) {
using T = typename std::conditional<I1 >= I2, FixedPoint<I1, F>, FixedPoint<I2, F>>::type;
using T = std::conditional_t<I1 >= I2, FixedPoint<I1, F>, FixedPoint<I2, F>>;
const T l = T::from_base(lhs.to_raw());
const T r = T::from_base(rhs.to_raw());
@@ -508,10 +480,10 @@ operator+(FixedPoint<I1, F> lhs, FixedPoint<I2, F> rhs) {
}
template <size_t I1, size_t I2, size_t F>
CONSTEXPR14 typename std::conditional<I1 >= I2, FixedPoint<I1, F>, FixedPoint<I2, F>>::type
operator-(FixedPoint<I1, F> lhs, FixedPoint<I2, F> rhs) {
constexpr std::conditional_t<I1 >= I2, FixedPoint<I1, F>, FixedPoint<I2, F>> operator-(
FixedPoint<I1, F> lhs, FixedPoint<I2, F> rhs) {
using T = typename std::conditional<I1 >= I2, FixedPoint<I1, F>, FixedPoint<I2, F>>::type;
using T = std::conditional_t<I1 >= I2, FixedPoint<I1, F>, FixedPoint<I2, F>>;
const T l = T::from_base(lhs.to_raw());
const T r = T::from_base(rhs.to_raw());
@@ -519,10 +491,10 @@ operator-(FixedPoint<I1, F> lhs, FixedPoint<I2, F> rhs) {
}
template <size_t I1, size_t I2, size_t F>
CONSTEXPR14 typename std::conditional<I1 >= I2, FixedPoint<I1, F>, FixedPoint<I2, F>>::type
operator*(FixedPoint<I1, F> lhs, FixedPoint<I2, F> rhs) {
constexpr std::conditional_t<I1 >= I2, FixedPoint<I1, F>, FixedPoint<I2, F>> operator*(
FixedPoint<I1, F> lhs, FixedPoint<I2, F> rhs) {
using T = typename std::conditional<I1 >= I2, FixedPoint<I1, F>, FixedPoint<I2, F>>::type;
using T = std::conditional_t<I1 >= I2, FixedPoint<I1, F>, FixedPoint<I2, F>>;
const T l = T::from_base(lhs.to_raw());
const T r = T::from_base(rhs.to_raw());
@@ -530,10 +502,10 @@ operator*(FixedPoint<I1, F> lhs, FixedPoint<I2, F> rhs) {
}
template <size_t I1, size_t I2, size_t F>
CONSTEXPR14 typename std::conditional<I1 >= I2, FixedPoint<I1, F>, FixedPoint<I2, F>>::type
operator/(FixedPoint<I1, F> lhs, FixedPoint<I2, F> rhs) {
constexpr std::conditional_t<I1 >= I2, FixedPoint<I1, F>, FixedPoint<I2, F>> operator/(
FixedPoint<I1, F> lhs, FixedPoint<I2, F> rhs) {
using T = typename std::conditional<I1 >= I2, FixedPoint<I1, F>, FixedPoint<I2, F>>::type;
using T = std::conditional_t<I1 >= I2, FixedPoint<I1, F>, FixedPoint<I2, F>>;
const T l = T::from_base(lhs.to_raw());
const T r = T::from_base(rhs.to_raw());
@@ -548,159 +520,133 @@ std::ostream& operator<<(std::ostream& os, FixedPoint<I, F> f) {
// basic math operators
template <size_t I, size_t F>
CONSTEXPR14 FixedPoint<I, F> operator+(FixedPoint<I, F> lhs, FixedPoint<I, F> rhs) {
constexpr FixedPoint<I, F> operator+(FixedPoint<I, F> lhs, FixedPoint<I, F> rhs) {
lhs += rhs;
return lhs;
}
template <size_t I, size_t F>
CONSTEXPR14 FixedPoint<I, F> operator-(FixedPoint<I, F> lhs, FixedPoint<I, F> rhs) {
constexpr FixedPoint<I, F> operator-(FixedPoint<I, F> lhs, FixedPoint<I, F> rhs) {
lhs -= rhs;
return lhs;
}
template <size_t I, size_t F>
CONSTEXPR14 FixedPoint<I, F> operator*(FixedPoint<I, F> lhs, FixedPoint<I, F> rhs) {
constexpr FixedPoint<I, F> operator*(FixedPoint<I, F> lhs, FixedPoint<I, F> rhs) {
lhs *= rhs;
return lhs;
}
template <size_t I, size_t F>
CONSTEXPR14 FixedPoint<I, F> operator/(FixedPoint<I, F> lhs, FixedPoint<I, F> rhs) {
constexpr FixedPoint<I, F> operator/(FixedPoint<I, F> lhs, FixedPoint<I, F> rhs) {
lhs /= rhs;
return lhs;
}
template <size_t I, size_t F, class Number,
class = typename std::enable_if<std::is_arithmetic<Number>::value>::type>
CONSTEXPR14 FixedPoint<I, F> operator+(FixedPoint<I, F> lhs, Number rhs) {
template <size_t I, size_t F, IsArithmetic Number>
constexpr FixedPoint<I, F> operator+(FixedPoint<I, F> lhs, Number rhs) {
lhs += FixedPoint<I, F>(rhs);
return lhs;
}
template <size_t I, size_t F, class Number,
class = typename std::enable_if<std::is_arithmetic<Number>::value>::type>
CONSTEXPR14 FixedPoint<I, F> operator-(FixedPoint<I, F> lhs, Number rhs) {
template <size_t I, size_t F, IsArithmetic Number>
constexpr FixedPoint<I, F> operator-(FixedPoint<I, F> lhs, Number rhs) {
lhs -= FixedPoint<I, F>(rhs);
return lhs;
}
template <size_t I, size_t F, class Number,
class = typename std::enable_if<std::is_arithmetic<Number>::value>::type>
CONSTEXPR14 FixedPoint<I, F> operator*(FixedPoint<I, F> lhs, Number rhs) {
template <size_t I, size_t F, IsArithmetic Number>
constexpr FixedPoint<I, F> operator*(FixedPoint<I, F> lhs, Number rhs) {
lhs *= FixedPoint<I, F>(rhs);
return lhs;
}
template <size_t I, size_t F, class Number,
class = typename std::enable_if<std::is_arithmetic<Number>::value>::type>
CONSTEXPR14 FixedPoint<I, F> operator/(FixedPoint<I, F> lhs, Number rhs) {
template <size_t I, size_t F, IsArithmetic Number>
constexpr FixedPoint<I, F> operator/(FixedPoint<I, F> lhs, Number rhs) {
lhs /= FixedPoint<I, F>(rhs);
return lhs;
}
template <size_t I, size_t F, class Number,
class = typename std::enable_if<std::is_arithmetic<Number>::value>::type>
CONSTEXPR14 FixedPoint<I, F> operator+(Number lhs, FixedPoint<I, F> rhs) {
template <size_t I, size_t F, IsArithmetic Number>
constexpr FixedPoint<I, F> operator+(Number lhs, FixedPoint<I, F> rhs) {
FixedPoint<I, F> tmp(lhs);
tmp += rhs;
return tmp;
}
template <size_t I, size_t F, class Number,
class = typename std::enable_if<std::is_arithmetic<Number>::value>::type>
CONSTEXPR14 FixedPoint<I, F> operator-(Number lhs, FixedPoint<I, F> rhs) {
template <size_t I, size_t F, IsArithmetic Number>
constexpr FixedPoint<I, F> operator-(Number lhs, FixedPoint<I, F> rhs) {
FixedPoint<I, F> tmp(lhs);
tmp -= rhs;
return tmp;
}
template <size_t I, size_t F, class Number,
class = typename std::enable_if<std::is_arithmetic<Number>::value>::type>
CONSTEXPR14 FixedPoint<I, F> operator*(Number lhs, FixedPoint<I, F> rhs) {
template <size_t I, size_t F, IsArithmetic Number>
constexpr FixedPoint<I, F> operator*(Number lhs, FixedPoint<I, F> rhs) {
FixedPoint<I, F> tmp(lhs);
tmp *= rhs;
return tmp;
}
template <size_t I, size_t F, class Number,
class = typename std::enable_if<std::is_arithmetic<Number>::value>::type>
CONSTEXPR14 FixedPoint<I, F> operator/(Number lhs, FixedPoint<I, F> rhs) {
template <size_t I, size_t F, IsArithmetic Number>
constexpr FixedPoint<I, F> operator/(Number lhs, FixedPoint<I, F> rhs) {
FixedPoint<I, F> tmp(lhs);
tmp /= rhs;
return tmp;
}
// shift operators
template <size_t I, size_t F, class Integer,
class = typename std::enable_if<std::is_integral<Integer>::value>::type>
CONSTEXPR14 FixedPoint<I, F> operator<<(FixedPoint<I, F> lhs, Integer rhs) {
template <size_t I, size_t F, IsIntegral Integer>
constexpr FixedPoint<I, F> operator<<(FixedPoint<I, F> lhs, Integer rhs) {
lhs <<= rhs;
return lhs;
}
template <size_t I, size_t F, class Integer,
class = typename std::enable_if<std::is_integral<Integer>::value>::type>
CONSTEXPR14 FixedPoint<I, F> operator>>(FixedPoint<I, F> lhs, Integer rhs) {
template <size_t I, size_t F, IsIntegral Integer>
constexpr FixedPoint<I, F> operator>>(FixedPoint<I, F> lhs, Integer rhs) {
lhs >>= rhs;
return lhs;
}
// comparison operators
template <size_t I, size_t F, class Number,
class = typename std::enable_if<std::is_arithmetic<Number>::value>::type>
template <size_t I, size_t F, IsArithmetic Number>
constexpr bool operator>(FixedPoint<I, F> lhs, Number rhs) {
return lhs > FixedPoint<I, F>(rhs);
}
template <size_t I, size_t F, class Number,
class = typename std::enable_if<std::is_arithmetic<Number>::value>::type>
template <size_t I, size_t F, IsArithmetic Number>
constexpr bool operator<(FixedPoint<I, F> lhs, Number rhs) {
return lhs < FixedPoint<I, F>(rhs);
}
template <size_t I, size_t F, class Number,
class = typename std::enable_if<std::is_arithmetic<Number>::value>::type>
template <size_t I, size_t F, IsArithmetic Number>
constexpr bool operator>=(FixedPoint<I, F> lhs, Number rhs) {
return lhs >= FixedPoint<I, F>(rhs);
}
template <size_t I, size_t F, class Number,
class = typename std::enable_if<std::is_arithmetic<Number>::value>::type>
template <size_t I, size_t F, IsArithmetic Number>
constexpr bool operator<=(FixedPoint<I, F> lhs, Number rhs) {
return lhs <= FixedPoint<I, F>(rhs);
}
template <size_t I, size_t F, class Number,
class = typename std::enable_if<std::is_arithmetic<Number>::value>::type>
template <size_t I, size_t F, IsArithmetic Number>
constexpr bool operator==(FixedPoint<I, F> lhs, Number rhs) {
return lhs == FixedPoint<I, F>(rhs);
}
template <size_t I, size_t F, class Number,
class = typename std::enable_if<std::is_arithmetic<Number>::value>::type>
template <size_t I, size_t F, IsArithmetic Number>
constexpr bool operator!=(FixedPoint<I, F> lhs, Number rhs) {
return lhs != FixedPoint<I, F>(rhs);
}
template <size_t I, size_t F, class Number,
class = typename std::enable_if<std::is_arithmetic<Number>::value>::type>
template <size_t I, size_t F, IsArithmetic Number>
constexpr bool operator>(Number lhs, FixedPoint<I, F> rhs) {
return FixedPoint<I, F>(lhs) > rhs;
}
template <size_t I, size_t F, class Number,
class = typename std::enable_if<std::is_arithmetic<Number>::value>::type>
template <size_t I, size_t F, IsArithmetic Number>
constexpr bool operator<(Number lhs, FixedPoint<I, F> rhs) {
return FixedPoint<I, F>(lhs) < rhs;
}
template <size_t I, size_t F, class Number,
class = typename std::enable_if<std::is_arithmetic<Number>::value>::type>
template <size_t I, size_t F, IsArithmetic Number>
constexpr bool operator>=(Number lhs, FixedPoint<I, F> rhs) {
return FixedPoint<I, F>(lhs) >= rhs;
}
template <size_t I, size_t F, class Number,
class = typename std::enable_if<std::is_arithmetic<Number>::value>::type>
template <size_t I, size_t F, IsArithmetic Number>
constexpr bool operator<=(Number lhs, FixedPoint<I, F> rhs) {
return FixedPoint<I, F>(lhs) <= rhs;
}
template <size_t I, size_t F, class Number,
class = typename std::enable_if<std::is_arithmetic<Number>::value>::type>
template <size_t I, size_t F, IsArithmetic Number>
constexpr bool operator==(Number lhs, FixedPoint<I, F> rhs) {
return FixedPoint<I, F>(lhs) == rhs;
}
template <size_t I, size_t F, class Number,
class = typename std::enable_if<std::is_arithmetic<Number>::value>::type>
template <size_t I, size_t F, IsArithmetic Number>
constexpr bool operator!=(Number lhs, FixedPoint<I, F> rhs) {
return FixedPoint<I, F>(lhs) != rhs;
}
} // namespace Common
#undef CONSTEXPR14
#endif
+6 -6
View File
@@ -209,8 +209,8 @@ public:
/**
* Helper function which deduces the value type of a contiguous STL container used in ReadSpan.
* If T is not a contiguous STL container as defined by the concept IsSTLContainer, this calls
* ReadObject and T must be a trivially copyable object.
* If T is not a contiguous container as defined by the concept IsContiguousContainer, this
* calls ReadObject and T must be a trivially copyable object.
*
* See ReadSpan for more details if T is a contiguous container.
* See ReadObject for more details if T is a trivially copyable object.
@@ -223,7 +223,7 @@ public:
*/
template <typename T>
[[nodiscard]] size_t Read(T& data) const {
if constexpr (IsSTLContainer<T>) {
if constexpr (IsContiguousContainer<T>) {
using ContiguousType = typename T::value_type;
static_assert(std::is_trivially_copyable_v<ContiguousType>,
"Data type must be trivially copyable.");
@@ -235,8 +235,8 @@ public:
/**
* Helper function which deduces the value type of a contiguous STL container used in WriteSpan.
* If T is not a contiguous STL container as defined by the concept IsSTLContainer, this calls
* WriteObject and T must be a trivially copyable object.
* If T is not a contiguous STL container as defined by the concept IsContiguousContainer, this
* calls WriteObject and T must be a trivially copyable object.
*
* See WriteSpan for more details if T is a contiguous container.
* See WriteObject for more details if T is a trivially copyable object.
@@ -249,7 +249,7 @@ public:
*/
template <typename T>
[[nodiscard]] size_t Write(const T& data) const {
if constexpr (IsSTLContainer<T>) {
if constexpr (IsContiguousContainer<T>) {
using ContiguousType = typename T::value_type;
static_assert(std::is_trivially_copyable_v<ContiguousType>,
"Data type must be trivially copyable.");
+6
View File
@@ -359,6 +359,12 @@ public:
}
});
long page_size = sysconf(_SC_PAGESIZE);
if (page_size != 0x1000) {
LOG_CRITICAL(HW_Memory, "page size {:#x} is incompatible with 4K paging", page_size);
throw std::bad_alloc{};
}
// Backing memory initialization
#if defined(__FreeBSD__) && __FreeBSD__ < 13
// XXX Drop after FreeBSD 12.* reaches EOL on 2024-06-30
+4 -1
View File
@@ -100,7 +100,6 @@ enum class CameraError {
enum class VibrationAmplificationType {
Linear,
Exponential,
Test,
};
// Analog properties for calibration
@@ -325,6 +324,10 @@ public:
return VibrationError::NotSupported;
}
virtual bool IsVibrationEnabled() {
return false;
}
virtual PollingError SetPollingMode([[maybe_unused]] PollingMode polling_mode) {
return PollingError::NotSupported;
}
+1 -1
View File
@@ -431,7 +431,7 @@ struct Values {
FullscreenMode::Exclusive,
#endif
FullscreenMode::Borderless, FullscreenMode::Exclusive, "fullscreen_mode"};
SwitchableSetting<int, true> aspect_ratio{0, 0, 3, "aspect_ratio"};
SwitchableSetting<int, true> aspect_ratio{0, 0, 4, "aspect_ratio"};
SwitchableSetting<int, true> max_anisotropy{0, 0, 5, "max_anisotropy"};
SwitchableSetting<bool> use_speed_limit{true, "use_speed_limit"};
SwitchableSetting<u16, true> speed_limit{100, 0, 9999, "speed_limit"};
+21 -16
View File
@@ -190,8 +190,13 @@ add_library(core STATIC
hle/kernel/k_code_memory.h
hle/kernel/k_condition_variable.cpp
hle/kernel/k_condition_variable.h
hle/kernel/k_debug.h
hle/kernel/k_dynamic_page_manager.h
hle/kernel/k_dynamic_resource_manager.h
hle/kernel/k_dynamic_slab_heap.h
hle/kernel/k_event.cpp
hle/kernel/k_event.h
hle/kernel/k_event_info.h
hle/kernel/k_handle_table.cpp
hle/kernel/k_handle_table.h
hle/kernel/k_interrupt_manager.cpp
@@ -219,6 +224,8 @@ add_library(core STATIC
hle/kernel/k_page_group.h
hle/kernel/k_page_table.cpp
hle/kernel/k_page_table.h
hle/kernel/k_page_table_manager.h
hle/kernel/k_page_table_slab_heap.h
hle/kernel/k_port.cpp
hle/kernel/k_port.h
hle/kernel/k_priority_queue.h
@@ -240,6 +247,8 @@ add_library(core STATIC
hle/kernel/k_server_session.h
hle/kernel/k_session.cpp
hle/kernel/k_session.h
hle/kernel/k_session_request.cpp
hle/kernel/k_session_request.h
hle/kernel/k_shared_memory.cpp
hle/kernel/k_shared_memory.h
hle/kernel/k_shared_memory_info.h
@@ -249,6 +258,8 @@ add_library(core STATIC
hle/kernel/k_synchronization_object.cpp
hle/kernel/k_synchronization_object.h
hle/kernel/k_system_control.h
hle/kernel/k_system_resource.cpp
hle/kernel/k_system_resource.h
hle/kernel/k_thread.cpp
hle/kernel/k_thread.h
hle/kernel/k_thread_local_page.cpp
@@ -261,8 +272,6 @@ add_library(core STATIC
hle/kernel/k_worker_task.h
hle/kernel/k_worker_task_manager.cpp
hle/kernel/k_worker_task_manager.h
hle/kernel/k_writable_event.cpp
hle/kernel/k_writable_event.h
hle/kernel/kernel.cpp
hle/kernel/kernel.h
hle/kernel/memory_types.h
@@ -488,10 +497,6 @@ add_library(core STATIC
hle/service/hid/irsensor/processor_base.h
hle/service/hid/irsensor/tera_plugin_processor.cpp
hle/service/hid/irsensor/tera_plugin_processor.h
hle/service/jit/jit_context.cpp
hle/service/jit/jit_context.h
hle/service/jit/jit.cpp
hle/service/jit/jit.h
hle/service/lbl/lbl.cpp
hle/service/lbl/lbl.h
hle/service/ldn/lan_discovery.cpp
@@ -771,19 +776,15 @@ if (MSVC)
/we4244 # 'conversion': conversion from 'type1' to 'type2', possible loss of data
/we4245 # 'conversion': conversion from 'type1' to 'type2', signed/unsigned mismatch
/we4254 # 'operator': conversion from 'type1:field_bits' to 'type2:field_bits', possible loss of data
/we4800 # Implicit conversion from 'type' to bool. Possible information loss
)
else()
target_compile_options(core PRIVATE
-Werror=conversion
-Werror=ignored-qualifiers
$<$<CXX_COMPILER_ID:GNU>:-Werror=class-memaccess>
$<$<CXX_COMPILER_ID:GNU>:-Werror=unused-but-set-parameter>
$<$<CXX_COMPILER_ID:GNU>:-Werror=unused-but-set-variable>
$<$<CXX_COMPILER_ID:Clang>:-fsized-deallocation>
-Wno-sign-conversion
$<$<CXX_COMPILER_ID:Clang>:-fsized-deallocation>
)
endif()
@@ -800,14 +801,18 @@ if (ENABLE_WEB_SERVICE)
target_link_libraries(core PRIVATE web_service)
endif()
if (ARCHITECTURE_x86_64)
if (ARCHITECTURE_x86_64 OR ARCHITECTURE_arm64)
target_sources(core PRIVATE
arm/dynarmic/arm_dynarmic_32.cpp
arm/dynarmic/arm_dynarmic_32.h
arm/dynarmic/arm_dynarmic_64.cpp
arm/dynarmic/arm_dynarmic_64.h
arm/dynarmic/arm_dynarmic_32.cpp
arm/dynarmic/arm_dynarmic_32.h
arm/dynarmic/arm_dynarmic_cp15.cpp
arm/dynarmic/arm_dynarmic_cp15.h
hle/service/jit/jit_context.cpp
hle/service/jit/jit_context.h
hle/service/jit/jit.cpp
hle/service/jit/jit.h
)
target_link_libraries(core PRIVATE dynarmic)
endif()
+8
View File
@@ -134,6 +134,14 @@ void ARM_Interface::Run() {
}
system.ExitDynarmicProfile();
// If the thread is scheduled for termination, exit the thread.
if (current_thread->HasDpc()) {
if (current_thread->IsTerminationRequested()) {
current_thread->Exit();
UNREACHABLE();
}
}
// Notify the debugger and go to sleep if a breakpoint was hit,
// or if the thread is unable to continue for any reason.
if (Has(hr, breakpoint) || Has(hr, no_execute)) {
+6 -1
View File
@@ -301,6 +301,11 @@ std::shared_ptr<Dynarmic::A32::Jit> ARM_Dynarmic_32::MakeJit(Common::PageTable*
}
}
#ifdef ARCHITECTURE_arm64
// TODO: remove when fixed in dynarmic
config.optimizations &= ~Dynarmic::OptimizationFlag::BlockLinking;
#endif
return std::make_unique<Dynarmic::A32::Jit>(config);
}
@@ -450,7 +455,7 @@ std::vector<ARM_Interface::BacktraceEntry> ARM_Dynarmic_32::GetBacktrace(Core::S
// Frame records are two words long:
// fp+0 : pointer to previous frame record
// fp+4 : value of lr for frame
while (true) {
for (size_t i = 0; i < 256; i++) {
out.push_back({"", 0, lr, 0, ""});
if (!fp || (fp % 4 != 0) || !memory.IsValidVirtualAddressRange(fp, 8)) {
break;
+2 -1
View File
@@ -111,6 +111,7 @@ public:
LOG_ERROR(Core_ARM,
"Unimplemented instruction @ 0x{:X} for {} instructions (instr = {:08X})", pc,
num_instructions, memory.Read32(pc));
ReturnException(pc, ARM_Interface::no_execute);
}
void InstructionCacheOperationRaised(Dynarmic::A64::InstructionCacheOperation op,
@@ -516,7 +517,7 @@ std::vector<ARM_Interface::BacktraceEntry> ARM_Dynarmic_64::GetBacktrace(Core::S
// Frame records are two words long:
// fp+0 : pointer to previous frame record
// fp+8 : value of lr for frame
while (true) {
for (size_t i = 0; i < 256; i++) {
out.push_back({"", 0, lr, 0, ""});
if (!fp || (fp % 4 != 0) || !memory.IsValidVirtualAddressRange(fp, 16)) {
break;
+15 -7
View File
@@ -52,12 +52,16 @@ CallbackOrAccessOneWord DynarmicCP15::CompileSendOneWord(bool two, unsigned opc1
case 4:
// CP15_DATA_SYNC_BARRIER
return Callback{
[](Dynarmic::A32::Jit*, void*, std::uint32_t, std::uint32_t) -> std::uint64_t {
#ifdef _MSC_VER
[](void*, std::uint32_t, std::uint32_t) -> std::uint64_t {
#if defined(_MSC_VER) && defined(ARCHITECTURE_x86_64)
_mm_mfence();
_mm_lfence();
#else
#elif defined(ARCHITECTURE_x86_64)
asm volatile("mfence\n\tlfence\n\t" : : : "memory");
#elif defined(ARCHITECTURE_arm64)
asm volatile("dsb sy\n\t" : : : "memory");
#else
#error Unsupported architecture
#endif
return 0;
},
@@ -66,11 +70,15 @@ CallbackOrAccessOneWord DynarmicCP15::CompileSendOneWord(bool two, unsigned opc1
case 5:
// CP15_DATA_MEMORY_BARRIER
return Callback{
[](Dynarmic::A32::Jit*, void*, std::uint32_t, std::uint32_t) -> std::uint64_t {
#ifdef _MSC_VER
[](void*, std::uint32_t, std::uint32_t) -> std::uint64_t {
#if defined(_MSC_VER) && defined(ARCHITECTURE_x86_64)
_mm_mfence();
#else
#elif defined(ARCHITECTURE_x86_64)
asm volatile("mfence\n\t" : : : "memory");
#elif defined(ARCHITECTURE_arm64)
asm volatile("dmb sy\n\t" : : : "memory");
#else
#error Unsupported architecture
#endif
return 0;
},
@@ -115,7 +123,7 @@ CallbackOrAccessOneWord DynarmicCP15::CompileGetOneWord(bool two, unsigned opc1,
CallbackOrAccessTwoWords DynarmicCP15::CompileGetTwoWords(bool two, unsigned opc, CoprocReg CRm) {
if (!two && opc == 0 && CRm == CoprocReg::C14) {
// CNTPCT
const auto callback = [](Dynarmic::A32::Jit*, void* arg, u32, u32) -> u64 {
const auto callback = [](void* arg, u32, u32) -> u64 {
const auto& parent_arg = *static_cast<ARM_Dynarmic_32*>(arg);
return parent_arg.system.CoreTiming().GetClockTicks();
};
+2 -2
View File
@@ -1,7 +1,7 @@
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#ifdef ARCHITECTURE_x86_64
#if defined(ARCHITECTURE_x86_64) || defined(ARCHITECTURE_arm64)
#include "core/arm/dynarmic/arm_exclusive_monitor.h"
#endif
#include "core/arm/exclusive_monitor.h"
@@ -13,7 +13,7 @@ ExclusiveMonitor::~ExclusiveMonitor() = default;
std::unique_ptr<Core::ExclusiveMonitor> MakeExclusiveMonitor(Memory::Memory& memory,
std::size_t num_cores) {
#ifdef ARCHITECTURE_x86_64
#if defined(ARCHITECTURE_x86_64) || defined(ARCHITECTURE_arm64)
return std::make_unique<Core::DynarmicExclusiveMonitor>(memory, num_cores);
#else
// TODO(merry): Passthrough exclusive monitor
+66 -34
View File
@@ -133,6 +133,56 @@ struct System::Impl {
: kernel{system}, fs_controller{system}, memory{system}, hid_core{}, room_network{},
cpu_manager{system}, reporter{system}, applet_manager{system}, time_manager{system} {}
void Initialize(System& system) {
device_memory = std::make_unique<Core::DeviceMemory>();
is_multicore = Settings::values.use_multi_core.GetValue();
extended_memory_layout = Settings::values.use_extended_memory_layout.GetValue();
core_timing.SetMulticore(is_multicore);
core_timing.Initialize([&system]() { system.RegisterHostThread(); });
const auto posix_time = std::chrono::system_clock::now().time_since_epoch();
const auto current_time =
std::chrono::duration_cast<std::chrono::seconds>(posix_time).count();
Settings::values.custom_rtc_differential =
Settings::values.custom_rtc.value_or(current_time) - current_time;
// Create a default fs if one doesn't already exist.
if (virtual_filesystem == nullptr) {
virtual_filesystem = std::make_shared<FileSys::RealVfsFilesystem>();
}
if (content_provider == nullptr) {
content_provider = std::make_unique<FileSys::ContentProviderUnion>();
}
// Create default implementations of applets if one is not provided.
applet_manager.SetDefaultAppletsIfMissing();
is_async_gpu = Settings::values.use_asynchronous_gpu_emulation.GetValue();
kernel.SetMulticore(is_multicore);
cpu_manager.SetMulticore(is_multicore);
cpu_manager.SetAsyncGpu(is_async_gpu);
}
void ReinitializeIfNecessary(System& system) {
const bool must_reinitialize =
is_multicore != Settings::values.use_multi_core.GetValue() ||
extended_memory_layout != Settings::values.use_extended_memory_layout.GetValue();
if (!must_reinitialize) {
return;
}
LOG_DEBUG(Kernel, "Re-initializing");
is_multicore = Settings::values.use_multi_core.GetValue();
extended_memory_layout = Settings::values.use_extended_memory_layout.GetValue();
Initialize(system);
}
SystemResultStatus Run() {
std::unique_lock<std::mutex> lk(suspend_guard);
status = SystemResultStatus::Success;
@@ -178,37 +228,14 @@ struct System::Impl {
debugger = std::make_unique<Debugger>(system, port);
}
SystemResultStatus Init(System& system, Frontend::EmuWindow& emu_window) {
SystemResultStatus SetupForMainProcess(System& system, Frontend::EmuWindow& emu_window) {
LOG_DEBUG(Core, "initialized OK");
device_memory = std::make_unique<Core::DeviceMemory>();
is_multicore = Settings::values.use_multi_core.GetValue();
is_async_gpu = Settings::values.use_asynchronous_gpu_emulation.GetValue();
kernel.SetMulticore(is_multicore);
cpu_manager.SetMulticore(is_multicore);
cpu_manager.SetAsyncGpu(is_async_gpu);
core_timing.SetMulticore(is_multicore);
// Setting changes may require a full system reinitialization (e.g., disabling multicore).
ReinitializeIfNecessary(system);
kernel.Initialize();
cpu_manager.Initialize();
core_timing.Initialize([&system]() { system.RegisterHostThread(); });
const auto posix_time = std::chrono::system_clock::now().time_since_epoch();
const auto current_time =
std::chrono::duration_cast<std::chrono::seconds>(posix_time).count();
Settings::values.custom_rtc_differential =
Settings::values.custom_rtc.value_or(current_time) - current_time;
// Create a default fs if one doesn't already exist.
if (virtual_filesystem == nullptr)
virtual_filesystem = std::make_shared<FileSys::RealVfsFilesystem>();
if (content_provider == nullptr)
content_provider = std::make_unique<FileSys::ContentProviderUnion>();
/// Create default implementations of applets if one is not provided.
applet_manager.SetDefaultAppletsIfMissing();
/// Reset all glue registrations
arp_manager.ResetAll();
@@ -253,11 +280,11 @@ struct System::Impl {
return SystemResultStatus::ErrorGetLoader;
}
SystemResultStatus init_result{Init(system, emu_window)};
SystemResultStatus init_result{SetupForMainProcess(system, emu_window)};
if (init_result != SystemResultStatus::Success) {
LOG_CRITICAL(Core, "Failed to initialize system (Error {})!",
static_cast<int>(init_result));
Shutdown();
ShutdownMainProcess();
return init_result;
}
@@ -276,7 +303,7 @@ struct System::Impl {
const auto [load_result, load_parameters] = app_loader->Load(*main_process, system);
if (load_result != Loader::ResultStatus::Success) {
LOG_CRITICAL(Core, "Failed to load ROM (Error {})!", load_result);
Shutdown();
ShutdownMainProcess();
return static_cast<SystemResultStatus>(
static_cast<u32>(SystemResultStatus::ErrorLoader) + static_cast<u32>(load_result));
@@ -335,7 +362,7 @@ struct System::Impl {
return status;
}
void Shutdown() {
void ShutdownMainProcess() {
SetShuttingDown(true);
// Log last frame performance stats if game was loded
@@ -363,13 +390,14 @@ struct System::Impl {
kernel.ShutdownCores();
cpu_manager.Shutdown();
debugger.reset();
services->KillNVNFlinger();
kernel.CloseServices();
services.reset();
service_manager.reset();
cheat_engine.reset();
telemetry_session.reset();
time_manager.Shutdown();
core_timing.Shutdown();
core_timing.ClearPendingEvents();
app_loader.reset();
audio_core.reset();
gpu_core.reset();
@@ -377,7 +405,6 @@ struct System::Impl {
perf_stats.reset();
kernel.Shutdown();
memory.Reset();
applet_manager.ClearAll();
if (auto room_member = room_network.GetRoomMember().lock()) {
Network::GameInfo game_info{};
@@ -500,6 +527,7 @@ struct System::Impl {
bool is_multicore{};
bool is_async_gpu{};
bool extended_memory_layout{};
ExecuteProgramCallback execute_program_callback;
ExitCallback exit_callback;
@@ -520,6 +548,10 @@ const CpuManager& System::GetCpuManager() const {
return impl->cpu_manager;
}
void System::Initialize() {
impl->Initialize(*this);
}
SystemResultStatus System::Run() {
return impl->Run();
}
@@ -540,8 +572,8 @@ void System::InvalidateCpuInstructionCacheRange(VAddr addr, std::size_t size) {
impl->kernel.InvalidateCpuInstructionCacheRange(addr, size);
}
void System::Shutdown() {
impl->Shutdown();
void System::ShutdownMainProcess() {
impl->ShutdownMainProcess();
}
bool System::IsShuttingDown() const {
+8 -2
View File
@@ -142,6 +142,12 @@ public:
System(System&&) = delete;
System& operator=(System&&) = delete;
/**
* Initializes the system
* This function will initialize core functionaility used for system emulation
*/
void Initialize();
/**
* Run the OS and Application
* This function will start emulation and run the relevant devices
@@ -166,8 +172,8 @@ public:
void InvalidateCpuInstructionCacheRange(VAddr addr, std::size_t size);
/// Shutdown the emulated system.
void Shutdown();
/// Shutdown the main emulated process.
void ShutdownMainProcess();
/// Check if the core is shutting down.
[[nodiscard]] bool IsShuttingDown() const;
+22 -16
View File
@@ -40,7 +40,9 @@ struct CoreTiming::Event {
CoreTiming::CoreTiming()
: clock{Common::CreateBestMatchingClock(Hardware::BASE_CLOCK_RATE, Hardware::CNTFREQ)} {}
CoreTiming::~CoreTiming() = default;
CoreTiming::~CoreTiming() {
Reset();
}
void CoreTiming::ThreadEntry(CoreTiming& instance) {
constexpr char name[] = "HostTiming";
@@ -53,6 +55,7 @@ void CoreTiming::ThreadEntry(CoreTiming& instance) {
}
void CoreTiming::Initialize(std::function<void()>&& on_thread_init_) {
Reset();
on_thread_init = std::move(on_thread_init_);
event_fifo_id = 0;
shutting_down = false;
@@ -65,17 +68,8 @@ void CoreTiming::Initialize(std::function<void()>&& on_thread_init_) {
}
}
void CoreTiming::Shutdown() {
paused = true;
shutting_down = true;
pause_event.Set();
event.Set();
if (timer_thread) {
timer_thread->join();
}
ClearPendingEvents();
timer_thread.reset();
has_started = false;
void CoreTiming::ClearPendingEvents() {
event_queue.clear();
}
void CoreTiming::Pause(bool is_paused) {
@@ -196,10 +190,6 @@ u64 CoreTiming::GetClockTicks() const {
return CpuCyclesToClockCycles(ticks);
}
void CoreTiming::ClearPendingEvents() {
event_queue.clear();
}
void CoreTiming::RemoveEvent(const std::shared_ptr<EventType>& event_type) {
std::scoped_lock lock{basic_lock};
@@ -270,6 +260,7 @@ void CoreTiming::ThreadLoop() {
// There are more events left in the queue, wait until the next event.
const auto wait_time = *next_time - GetGlobalTimeNs().count();
if (wait_time > 0) {
#ifdef _WIN32
// Assume a timer resolution of 1ms.
static constexpr s64 TimerResolutionNS = 1000000;
@@ -287,6 +278,9 @@ void CoreTiming::ThreadLoop() {
if (event.IsSet()) {
event.Reset();
}
#else
event.WaitFor(std::chrono::nanoseconds(wait_time));
#endif
}
} else {
// Queue is empty, wait until another event is scheduled and signals us to continue.
@@ -303,6 +297,18 @@ void CoreTiming::ThreadLoop() {
}
}
void CoreTiming::Reset() {
paused = true;
shutting_down = true;
pause_event.Set();
event.Set();
if (timer_thread) {
timer_thread->join();
}
timer_thread.reset();
has_started = false;
}
std::chrono::nanoseconds CoreTiming::GetGlobalTimeNs() const {
if (is_multicore) {
return clock->GetTimeNS();
+4 -10
View File
@@ -61,19 +61,14 @@ public:
/// required to end slice - 1 and start slice 0 before the first cycle of code is executed.
void Initialize(std::function<void()>&& on_thread_init_);
/// Tears down all timing related functionality.
void Shutdown();
/// Clear all pending events. This should ONLY be done on exit.
void ClearPendingEvents();
/// Sets if emulation is multicore or single core, must be set before Initialize
void SetMulticore(bool is_multicore_) {
is_multicore = is_multicore_;
}
/// Check if it's using host timing.
bool IsHostTiming() const {
return is_multicore;
}
/// Pauses/Unpauses the execution of the timer thread.
void Pause(bool is_paused);
@@ -136,12 +131,11 @@ public:
private:
struct Event;
/// Clear all pending events. This should ONLY be done on exit.
void ClearPendingEvents();
static void ThreadEntry(CoreTiming& instance);
void ThreadLoop();
void Reset();
std::unique_ptr<Common::WallClock> clock;
s64 global_timer = 0;
+6 -4
View File
@@ -31,12 +31,14 @@ public:
DramMemoryMap::Base;
}
u8* GetPointer(PAddr addr) {
return buffer.BackingBasePointer() + (addr - DramMemoryMap::Base);
template <typename T>
T* GetPointer(PAddr addr) {
return reinterpret_cast<T*>(buffer.BackingBasePointer() + (addr - DramMemoryMap::Base));
}
const u8* GetPointer(PAddr addr) const {
return buffer.BackingBasePointer() + (addr - DramMemoryMap::Base);
template <typename T>
const T* GetPointer(PAddr addr) const {
return reinterpret_cast<T*>(buffer.BackingBasePointer() + (addr - DramMemoryMap::Base));
}
Common::HostMemory buffer;
+2 -2
View File
@@ -232,8 +232,8 @@ const std::vector<std::shared_ptr<NCA>>& XCI::GetNCAs() const {
std::shared_ptr<NCA> XCI::GetNCAByType(NCAContentType type) const {
const auto program_id = secure_partition->GetProgramTitleID();
const auto iter = std::find_if(
ncas.begin(), ncas.end(), [this, type, program_id](const std::shared_ptr<NCA>& nca) {
const auto iter =
std::find_if(ncas.begin(), ncas.end(), [type, program_id](const std::shared_ptr<NCA>& nca) {
return nca->GetType() == type && nca->GetTitleId() == program_id;
});
return iter == ncas.end() ? nullptr : *iter;
+34 -9
View File
@@ -1,6 +1,7 @@
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include "common/settings.h"
#include "common/string_util.h"
#include "common/swap.h"
#include "core/file_sys/control_metadata.h"
@@ -37,6 +38,27 @@ std::string LanguageEntry::GetDeveloperName() const {
developer_name.size());
}
constexpr std::array<Language, 18> language_to_codes = {{
Language::Japanese,
Language::AmericanEnglish,
Language::French,
Language::German,
Language::Italian,
Language::Spanish,
Language::Chinese,
Language::Korean,
Language::Dutch,
Language::Portuguese,
Language::Russian,
Language::Taiwanese,
Language::BritishEnglish,
Language::CanadianFrench,
Language::LatinAmericanSpanish,
Language::Chinese,
Language::Taiwanese,
Language::BrazilianPortuguese,
}};
NACP::NACP() = default;
NACP::NACP(VirtualFile file) {
@@ -45,9 +67,13 @@ NACP::NACP(VirtualFile file) {
NACP::~NACP() = default;
const LanguageEntry& NACP::GetLanguageEntry(Language language) const {
if (language != Language::Default) {
return raw.language_entries.at(static_cast<u8>(language));
const LanguageEntry& NACP::GetLanguageEntry() const {
Language language = language_to_codes[Settings::values.language_index.GetValue()];
{
const auto& language_entry = raw.language_entries.at(static_cast<u8>(language));
if (!language_entry.GetApplicationName().empty())
return language_entry;
}
for (const auto& language_entry : raw.language_entries) {
@@ -55,16 +81,15 @@ const LanguageEntry& NACP::GetLanguageEntry(Language language) const {
return language_entry;
}
// Fallback to English
return GetLanguageEntry(Language::AmericanEnglish);
return raw.language_entries.at(static_cast<u8>(Language::AmericanEnglish));
}
std::string NACP::GetApplicationName(Language language) const {
return GetLanguageEntry(language).GetApplicationName();
std::string NACP::GetApplicationName() const {
return GetLanguageEntry().GetApplicationName();
}
std::string NACP::GetDeveloperName(Language language) const {
return GetLanguageEntry(language).GetDeveloperName();
std::string NACP::GetDeveloperName() const {
return GetLanguageEntry().GetDeveloperName();
}
u64 NACP::GetTitleId() const {
+3 -3
View File
@@ -101,9 +101,9 @@ public:
explicit NACP(VirtualFile file);
~NACP();
const LanguageEntry& GetLanguageEntry(Language language = Language::Default) const;
std::string GetApplicationName(Language language = Language::Default) const;
std::string GetDeveloperName(Language language = Language::Default) const;
const LanguageEntry& GetLanguageEntry() const;
std::string GetApplicationName() const;
std::string GetDeveloperName() const;
u64 GetTitleId() const;
u64 GetDLCBaseTitleId() const;
std::string GetVersionString() const;
+1 -1
View File
@@ -127,7 +127,7 @@ void ProgramMetadata::LoadManual(bool is_64_bit, ProgramAddressSpaceType address
}
bool ProgramMetadata::Is64BitProgram() const {
return npdm_header.has_64_bit_instructions;
return npdm_header.has_64_bit_instructions.As<bool>();
}
ProgramAddressSpaceType ProgramMetadata::GetAddressSpaceType() const {
+51 -7
View File
@@ -5,6 +5,7 @@
#include "common/assert.h"
#include "common/common_types.h"
#include "common/logging/log.h"
#include "common/uuid.h"
#include "core/core.h"
#include "core/file_sys/savedata_factory.h"
#include "core/file_sys/vfs.h"
@@ -59,6 +60,36 @@ bool ShouldSaveDataBeAutomaticallyCreated(SaveDataSpaceId space, const SaveDataA
attr.title_id == 0 && attr.save_id == 0);
}
std::string GetFutureSaveDataPath(SaveDataSpaceId space_id, SaveDataType type, u64 title_id,
u128 user_id) {
// Only detect nand user saves.
const auto space_id_path = [space_id]() -> std::string_view {
switch (space_id) {
case SaveDataSpaceId::NandUser:
return "/user/save";
default:
return "";
}
}();
if (space_id_path.empty()) {
return "";
}
Common::UUID uuid;
std::memcpy(uuid.uuid.data(), user_id.data(), sizeof(Common::UUID));
// Only detect account/device saves from the future location.
switch (type) {
case SaveDataType::SaveData:
return fmt::format("{}/account/{}/{:016X}/1", space_id_path, uuid.RawString(), title_id);
case SaveDataType::DeviceSaveData:
return fmt::format("{}/device/{:016X}/1", space_id_path, title_id);
default:
return "";
}
}
} // Anonymous namespace
std::string SaveDataAttribute::DebugInfo() const {
@@ -82,7 +113,7 @@ ResultVal<VirtualDir> SaveDataFactory::Create(SaveDataSpaceId space,
PrintSaveDataAttributeWarnings(meta);
const auto save_directory =
GetFullPath(system, space, meta.type, meta.title_id, meta.user_id, meta.save_id);
GetFullPath(system, dir, space, meta.type, meta.title_id, meta.user_id, meta.save_id);
auto out = dir->CreateDirectoryRelative(save_directory);
@@ -99,7 +130,7 @@ ResultVal<VirtualDir> SaveDataFactory::Open(SaveDataSpaceId space,
const SaveDataAttribute& meta) const {
const auto save_directory =
GetFullPath(system, space, meta.type, meta.title_id, meta.user_id, meta.save_id);
GetFullPath(system, dir, space, meta.type, meta.title_id, meta.user_id, meta.save_id);
auto out = dir->GetDirectoryRelative(save_directory);
@@ -134,9 +165,9 @@ std::string SaveDataFactory::GetSaveDataSpaceIdPath(SaveDataSpaceId space) {
}
}
std::string SaveDataFactory::GetFullPath(Core::System& system, SaveDataSpaceId space,
SaveDataType type, u64 title_id, u128 user_id,
u64 save_id) {
std::string SaveDataFactory::GetFullPath(Core::System& system, VirtualDir dir,
SaveDataSpaceId space, SaveDataType type, u64 title_id,
u128 user_id, u64 save_id) {
// According to switchbrew, if a save is of type SaveData and the title id field is 0, it should
// be interpreted as the title id of the current process.
if (type == SaveDataType::SaveData || type == SaveDataType::DeviceSaveData) {
@@ -145,6 +176,17 @@ std::string SaveDataFactory::GetFullPath(Core::System& system, SaveDataSpaceId s
}
}
// For compat with a future impl.
if (std::string future_path =
GetFutureSaveDataPath(space, type, title_id & ~(0xFFULL), user_id);
!future_path.empty()) {
// Check if this location exists, and prefer it over the old.
if (const auto future_dir = dir->GetDirectoryRelative(future_path); future_dir != nullptr) {
LOG_INFO(Service_FS, "Using save at new location: {}", future_path);
return future_path;
}
}
std::string out = GetSaveDataSpaceIdPath(space);
switch (type) {
@@ -167,7 +209,8 @@ std::string SaveDataFactory::GetFullPath(Core::System& system, SaveDataSpaceId s
SaveDataSize SaveDataFactory::ReadSaveDataSize(SaveDataType type, u64 title_id,
u128 user_id) const {
const auto path = GetFullPath(system, SaveDataSpaceId::NandUser, type, title_id, user_id, 0);
const auto path =
GetFullPath(system, dir, SaveDataSpaceId::NandUser, type, title_id, user_id, 0);
const auto relative_dir = GetOrCreateDirectoryRelative(dir, path);
const auto size_file = relative_dir->GetFile(SAVE_DATA_SIZE_FILENAME);
@@ -185,7 +228,8 @@ SaveDataSize SaveDataFactory::ReadSaveDataSize(SaveDataType type, u64 title_id,
void SaveDataFactory::WriteSaveDataSize(SaveDataType type, u64 title_id, u128 user_id,
SaveDataSize new_value) const {
const auto path = GetFullPath(system, SaveDataSpaceId::NandUser, type, title_id, user_id, 0);
const auto path =
GetFullPath(system, dir, SaveDataSpaceId::NandUser, type, title_id, user_id, 0);
const auto relative_dir = GetOrCreateDirectoryRelative(dir, path);
const auto size_file = relative_dir->CreateFile(SAVE_DATA_SIZE_FILENAME);
+2 -2
View File
@@ -95,8 +95,8 @@ public:
VirtualDir GetSaveDataSpaceDirectory(SaveDataSpaceId space) const;
static std::string GetSaveDataSpaceIdPath(SaveDataSpaceId space);
static std::string GetFullPath(Core::System& system, SaveDataSpaceId space, SaveDataType type,
u64 title_id, u128 user_id, u64 save_id);
static std::string GetFullPath(Core::System& system, VirtualDir dir, SaveDataSpaceId space,
SaveDataType type, u64 title_id, u128 user_id, u64 save_id);
SaveDataSize ReadSaveDataSize(SaveDataType type, u64 title_id, u128 user_id) const;
void WriteSaveDataSize(SaveDataType type, u64 title_id, u128 user_id,
+2
View File
@@ -67,6 +67,8 @@ float EmulationAspectRatio(AspectRatio aspect, float window_aspect_ratio) {
return 3.0f / 4.0f;
case AspectRatio::R21_9:
return 9.0f / 21.0f;
case AspectRatio::R16_10:
return 10.0f / 16.0f;
case AspectRatio::StretchToWindow:
return window_aspect_ratio;
default:
+1
View File
@@ -27,6 +27,7 @@ enum class AspectRatio {
Default,
R4_3,
R21_9,
R16_10,
StretchToWindow,
};
+20 -48
View File
@@ -970,14 +970,7 @@ bool EmulatedController::SetVibration(std::size_t device_index, VibrationValue v
Common::Input::VibrationError::None;
}
bool EmulatedController::TestVibration(std::size_t device_index) {
if (device_index >= output_devices.size()) {
return false;
}
if (!output_devices[device_index]) {
return false;
}
bool EmulatedController::IsVibrationEnabled(std::size_t device_index) {
const auto player_index = NpadIdTypeToIndex(npad_id_type);
const auto& player = Settings::values.players.GetValue()[player_index];
@@ -985,31 +978,15 @@ bool EmulatedController::TestVibration(std::size_t device_index) {
return false;
}
const Common::Input::VibrationStatus test_vibration = {
.low_amplitude = 0.001f,
.low_frequency = DEFAULT_VIBRATION_VALUE.low_frequency,
.high_amplitude = 0.001f,
.high_frequency = DEFAULT_VIBRATION_VALUE.high_frequency,
.type = Common::Input::VibrationAmplificationType::Test,
};
if (device_index >= output_devices.size()) {
return false;
}
const Common::Input::VibrationStatus zero_vibration = {
.low_amplitude = DEFAULT_VIBRATION_VALUE.low_amplitude,
.low_frequency = DEFAULT_VIBRATION_VALUE.low_frequency,
.high_amplitude = DEFAULT_VIBRATION_VALUE.high_amplitude,
.high_frequency = DEFAULT_VIBRATION_VALUE.high_frequency,
.type = Common::Input::VibrationAmplificationType::Test,
};
if (!output_devices[device_index]) {
return false;
}
// Send a slight vibration to test for rumble support
output_devices[device_index]->SetVibration(test_vibration);
// Wait for about 15ms to ensure the controller is ready for the stop command
std::this_thread::sleep_for(std::chrono::milliseconds(15));
// Stop any vibration and return the result
return output_devices[device_index]->SetVibration(zero_vibration) ==
Common::Input::VibrationError::None;
return output_devices[device_index]->IsVibrationEnabled();
}
bool EmulatedController::SetPollingMode(Common::Input::PollingMode polling_mode) {
@@ -1048,6 +1025,7 @@ bool EmulatedController::HasNfc() const {
case NpadStyleIndex::JoyconRight:
case NpadStyleIndex::JoyconDual:
case NpadStyleIndex::ProController:
case NpadStyleIndex::Handheld:
break;
default:
return false;
@@ -1158,27 +1136,27 @@ bool EmulatedController::IsControllerSupported(bool use_temporary_value) const {
const auto type = is_configuring && use_temporary_value ? tmp_npad_type : npad_type;
switch (type) {
case NpadStyleIndex::ProController:
return supported_style_tag.fullkey;
return supported_style_tag.fullkey.As<bool>();
case NpadStyleIndex::Handheld:
return supported_style_tag.handheld;
return supported_style_tag.handheld.As<bool>();
case NpadStyleIndex::JoyconDual:
return supported_style_tag.joycon_dual;
return supported_style_tag.joycon_dual.As<bool>();
case NpadStyleIndex::JoyconLeft:
return supported_style_tag.joycon_left;
return supported_style_tag.joycon_left.As<bool>();
case NpadStyleIndex::JoyconRight:
return supported_style_tag.joycon_right;
return supported_style_tag.joycon_right.As<bool>();
case NpadStyleIndex::GameCube:
return supported_style_tag.gamecube;
return supported_style_tag.gamecube.As<bool>();
case NpadStyleIndex::Pokeball:
return supported_style_tag.palma;
return supported_style_tag.palma.As<bool>();
case NpadStyleIndex::NES:
return supported_style_tag.lark;
return supported_style_tag.lark.As<bool>();
case NpadStyleIndex::SNES:
return supported_style_tag.lucia;
return supported_style_tag.lucia.As<bool>();
case NpadStyleIndex::N64:
return supported_style_tag.lagoon;
return supported_style_tag.lagoon.As<bool>();
case NpadStyleIndex::SegaGenesis:
return supported_style_tag.lager;
return supported_style_tag.lager.As<bool>();
default:
return false;
}
@@ -1234,12 +1212,6 @@ bool EmulatedController::IsConnected(bool get_temporary_value) const {
return is_connected;
}
bool EmulatedController::IsVibrationEnabled() const {
const auto player_index = NpadIdTypeToIndex(npad_id_type);
const auto& player = Settings::values.players.GetValue()[player_index];
return player.vibration_enabled;
}
NpadIdType EmulatedController::GetNpadIdType() const {
std::scoped_lock lock{mutex};
return npad_id_type;
+1 -4
View File
@@ -206,9 +206,6 @@ public:
*/
bool IsConnected(bool get_temporary_value = false) const;
/// Returns true if vibration is enabled
bool IsVibrationEnabled() const;
/// Removes all callbacks created from input devices
void UnloadInput();
@@ -339,7 +336,7 @@ public:
* Sends a small vibration to the output device
* @return true if SetVibration was successfull
*/
bool TestVibration(std::size_t device_index);
bool IsVibrationEnabled(std::size_t device_index);
/**
* Sets the desired data to be polled from a controller
+10 -10
View File
@@ -14,7 +14,7 @@ enum class CameraAmbientNoiseLevel : u32 {
Low,
Medium,
High,
Unkown3, // This level can't be reached
Unknown3, // This level can't be reached
};
// This is nn::irsensor::CameraLightTarget
@@ -75,9 +75,9 @@ enum class IrCameraStatus : u32 {
enum class IrCameraInternalStatus : u32 {
Stopped,
FirmwareUpdateNeeded,
Unkown2,
Unkown3,
Unkown4,
Unknown2,
Unknown3,
Unknown4,
FirmwareVersionRequested,
FirmwareVersionIsInvalid,
Ready,
@@ -121,20 +121,20 @@ enum class IrSensorFunctionLevel : u8 {
// This is nn::irsensor::MomentProcessorPreprocess
enum class MomentProcessorPreprocess : u32 {
Unkown0,
Unkown1,
Unknown0,
Unknown1,
};
// This is nn::irsensor::PackedMomentProcessorPreprocess
enum class PackedMomentProcessorPreprocess : u8 {
Unkown0,
Unkown1,
Unknown0,
Unknown1,
};
// This is nn::irsensor::PointingStatus
enum class PointingStatus : u32 {
Unkown0,
Unkown1,
Unknown0,
Unknown1,
};
struct IrsRect {
+9 -8
View File
@@ -86,13 +86,13 @@ public:
u32 num_domain_objects{};
const bool always_move_handles{
(static_cast<u32>(flags) & static_cast<u32>(Flags::AlwaysMoveHandles)) != 0};
if (!ctx.Session()->IsDomain() || always_move_handles) {
if (!ctx.GetManager()->IsDomain() || always_move_handles) {
num_handles_to_move = num_objects_to_move;
} else {
num_domain_objects = num_objects_to_move;
}
if (ctx.Session()->IsDomain()) {
if (ctx.GetManager()->IsDomain()) {
raw_data_size +=
static_cast<u32>(sizeof(DomainMessageHeader) / sizeof(u32) + num_domain_objects);
ctx.write_size += num_domain_objects;
@@ -125,7 +125,7 @@ public:
if (!ctx.IsTipc()) {
AlignWithPadding();
if (ctx.Session()->IsDomain() && ctx.HasDomainMessageHeader()) {
if (ctx.GetManager()->IsDomain() && ctx.HasDomainMessageHeader()) {
IPC::DomainMessageHeader domain_header{};
domain_header.num_objects = num_domain_objects;
PushRaw(domain_header);
@@ -145,7 +145,7 @@ public:
template <class T>
void PushIpcInterface(std::shared_ptr<T> iface) {
if (context->Session()->IsDomain()) {
if (context->GetManager()->IsDomain()) {
context->AddDomainObject(std::move(iface));
} else {
kernel.CurrentProcess()->GetResourceLimit()->Reserve(
@@ -153,9 +153,10 @@ public:
auto* session = Kernel::KSession::Create(kernel);
session->Initialize(nullptr, iface->GetServiceName());
iface->RegisterSession(&session->GetServerSession(),
std::make_shared<Kernel::SessionRequestManager>(kernel));
context->AddMoveObject(&session->GetClientSession());
iface->ClientConnected(&session->GetServerSession());
}
}
@@ -385,7 +386,7 @@ public:
template <class T>
std::weak_ptr<T> PopIpcInterface() {
ASSERT(context->Session()->IsDomain());
ASSERT(context->GetManager()->IsDomain());
ASSERT(context->GetDomainMessageHeader().input_object_count > 0);
return context->GetDomainHandler<T>(Pop<u32>() - 1);
}
@@ -404,7 +405,7 @@ inline s32 RequestParser::Pop() {
}
// Ignore the -Wclass-memaccess warning on memcpy for non-trivially default constructible objects.
#if defined(__GNUC__)
#if defined(__GNUC__) && !defined(__clang__) && !defined(__INTEL_COMPILER)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wclass-memaccess"
#endif
@@ -415,7 +416,7 @@ void RequestParser::PopRaw(T& value) {
std::memcpy(&value, cmdbuf + index, sizeof(T));
index += (sizeof(T) + 3) / 4; // round up to word length
}
#if defined(__GNUC__)
#if defined(__GNUC__) && !defined(__clang__) && !defined(__INTEL_COMPILER)
#pragma GCC diagnostic pop
#endif
@@ -8,6 +8,10 @@
namespace Kernel::Board::Nintendo::Nx {
class KSystemControl {
public:
// This can be overridden as needed.
static constexpr size_t SecureAppletMemorySize = 4 * 1024 * 1024; // 4_MB
public:
class Init {
public:
@@ -49,4 +49,26 @@ bool GlobalSchedulerContext::IsLocked() const {
return scheduler_lock.IsLockedByCurrentThread();
}
void GlobalSchedulerContext::RegisterDummyThreadForWakeup(KThread* thread) {
ASSERT(IsLocked());
woken_dummy_threads.insert(thread);
}
void GlobalSchedulerContext::UnregisterDummyThreadForWakeup(KThread* thread) {
ASSERT(IsLocked());
woken_dummy_threads.erase(thread);
}
void GlobalSchedulerContext::WakeupWaitingDummyThreads() {
ASSERT(IsLocked());
for (auto* thread : woken_dummy_threads) {
thread->DummyThreadEndWait();
}
woken_dummy_threads.clear();
}
} // namespace Kernel
@@ -4,6 +4,7 @@
#pragma once
#include <atomic>
#include <set>
#include <vector>
#include "common/common_types.h"
@@ -58,6 +59,10 @@ public:
/// Returns true if the global scheduler lock is acquired
bool IsLocked() const;
void UnregisterDummyThreadForWakeup(KThread* thread);
void RegisterDummyThreadForWakeup(KThread* thread);
void WakeupWaitingDummyThreads();
[[nodiscard]] LockType& SchedulerLock() {
return scheduler_lock;
}
@@ -76,6 +81,9 @@ private:
KSchedulerPriorityQueue priority_queue;
LockType scheduler_lock;
/// Lists dummy threads pending wakeup on lock release
std::set<KThread*> woken_dummy_threads;
/// Lists all thread ids that aren't deleted/etc.
std::vector<KThread*> thread_list;
std::mutex global_list_guard;
+93 -20
View File
@@ -16,27 +16,39 @@
#include "core/hle/kernel/k_auto_object.h"
#include "core/hle/kernel/k_handle_table.h"
#include "core/hle/kernel/k_process.h"
#include "core/hle/kernel/k_server_port.h"
#include "core/hle/kernel/k_server_session.h"
#include "core/hle/kernel/k_thread.h"
#include "core/hle/kernel/kernel.h"
#include "core/hle/kernel/service_thread.h"
#include "core/memory.h"
namespace Kernel {
SessionRequestHandler::SessionRequestHandler(KernelCore& kernel_, const char* service_name_,
ServiceThreadType thread_type)
: kernel{kernel_} {
if (thread_type == ServiceThreadType::CreateNew) {
service_thread = kernel.CreateServiceThread(service_name_);
} else {
service_thread = kernel.GetDefaultServiceThread();
}
}
: kernel{kernel_}, service_thread{thread_type == ServiceThreadType::CreateNew
? kernel.CreateServiceThread(service_name_)
: kernel.GetDefaultServiceThread()} {}
SessionRequestHandler::~SessionRequestHandler() {
kernel.ReleaseServiceThread(service_thread);
}
void SessionRequestHandler::AcceptSession(KServerPort* server_port) {
auto* server_session = server_port->AcceptSession();
ASSERT(server_session != nullptr);
RegisterSession(server_session, std::make_shared<SessionRequestManager>(kernel));
}
void SessionRequestHandler::RegisterSession(KServerSession* server_session,
std::shared_ptr<SessionRequestManager> manager) {
manager->SetSessionHandler(shared_from_this());
service_thread.RegisterServerSession(server_session, manager);
server_session->Close();
}
SessionRequestManager::SessionRequestManager(KernelCore& kernel_) : kernel{kernel_} {}
SessionRequestManager::~SessionRequestManager() = default;
@@ -56,15 +68,77 @@ bool SessionRequestManager::HasSessionRequestHandler(const HLERequestContext& co
}
}
void SessionRequestHandler::ClientConnected(KServerSession* session) {
session->ClientConnected(shared_from_this());
Result SessionRequestManager::CompleteSyncRequest(KServerSession* server_session,
HLERequestContext& context) {
Result result = ResultSuccess;
// Ensure our server session is tracked globally.
kernel.RegisterServerObject(session);
// If the session has been converted to a domain, handle the domain request
if (this->HasSessionRequestHandler(context)) {
if (IsDomain() && context.HasDomainMessageHeader()) {
result = HandleDomainSyncRequest(server_session, context);
// If there is no domain header, the regular session handler is used
} else if (this->HasSessionHandler()) {
// If this manager has an associated HLE handler, forward the request to it.
result = this->SessionHandler().HandleSyncRequest(*server_session, context);
}
} else {
ASSERT_MSG(false, "Session handler is invalid, stubbing response!");
IPC::ResponseBuilder rb(context, 2);
rb.Push(ResultSuccess);
}
if (convert_to_domain) {
ASSERT_MSG(!IsDomain(), "ServerSession is already a domain instance.");
this->ConvertToDomain();
convert_to_domain = false;
}
return result;
}
void SessionRequestHandler::ClientDisconnected(KServerSession* session) {
session->ClientDisconnected();
Result SessionRequestManager::HandleDomainSyncRequest(KServerSession* server_session,
HLERequestContext& context) {
if (!context.HasDomainMessageHeader()) {
return ResultSuccess;
}
// Set domain handlers in HLE context, used for domain objects (IPC interfaces) as inputs
ASSERT(context.GetManager().get() == this);
// If there is a DomainMessageHeader, then this is CommandType "Request"
const auto& domain_message_header = context.GetDomainMessageHeader();
const u32 object_id{domain_message_header.object_id};
switch (domain_message_header.command) {
case IPC::DomainMessageHeader::CommandType::SendMessage:
if (object_id > this->DomainHandlerCount()) {
LOG_CRITICAL(IPC,
"object_id {} is too big! This probably means a recent service call "
"needed to return a new interface!",
object_id);
ASSERT(false);
return ResultSuccess; // Ignore error if asserts are off
}
if (auto strong_ptr = this->DomainHandler(object_id - 1).lock()) {
return strong_ptr->HandleSyncRequest(*server_session, context);
} else {
ASSERT(false);
return ResultSuccess;
}
case IPC::DomainMessageHeader::CommandType::CloseVirtualHandle: {
LOG_DEBUG(IPC, "CloseVirtualHandle, object_id=0x{:08X}", object_id);
this->CloseDomainHandler(object_id - 1);
IPC::ResponseBuilder rb{context, 2};
rb.Push(ResultSuccess);
return ResultSuccess;
}
}
LOG_CRITICAL(IPC, "Unknown domain command={}", domain_message_header.command.Value());
ASSERT(false);
return ResultSuccess;
}
HLERequestContext::HLERequestContext(KernelCore& kernel_, Core::Memory::Memory& memory_,
@@ -126,7 +200,7 @@ void HLERequestContext::ParseCommandBuffer(const KHandleTable& handle_table, u32
// Padding to align to 16 bytes
rp.AlignWithPadding();
if (Session()->IsDomain() &&
if (GetManager()->IsDomain() &&
((command_header->type == IPC::CommandType::Request ||
command_header->type == IPC::CommandType::RequestWithContext) ||
!incoming)) {
@@ -135,7 +209,7 @@ void HLERequestContext::ParseCommandBuffer(const KHandleTable& handle_table, u32
if (incoming || domain_message_header) {
domain_message_header = rp.PopRaw<IPC::DomainMessageHeader>();
} else {
if (Session()->IsDomain()) {
if (GetManager()->IsDomain()) {
LOG_WARNING(IPC, "Domain request has no DomainMessageHeader!");
}
}
@@ -228,12 +302,11 @@ Result HLERequestContext::WriteToOutgoingCommandBuffer(KThread& requesting_threa
// Write the domain objects to the command buffer, these go after the raw untranslated data.
// TODO(Subv): This completely ignores C buffers.
if (Session()->IsDomain()) {
if (GetManager()->IsDomain()) {
current_offset = domain_offset - static_cast<u32>(outgoing_domain_objects.size());
for (const auto& object : outgoing_domain_objects) {
server_session->AppendDomainHandler(object);
cmd_buf[current_offset++] =
static_cast<u32_le>(server_session->NumDomainRequestHandlers());
for (auto& object : outgoing_domain_objects) {
GetManager()->AppendDomainHandler(std::move(object));
cmd_buf[current_offset++] = static_cast<u32_le>(GetManager()->DomainHandlerCount());
}
}
+25 -21
View File
@@ -43,13 +43,15 @@ class Domain;
class HLERequestContext;
class KAutoObject;
class KernelCore;
class KEvent;
class KHandleTable;
class KServerPort;
class KProcess;
class KServerSession;
class KThread;
class KReadableEvent;
class KSession;
class KWritableEvent;
class SessionRequestManager;
class ServiceThread;
enum class ThreadWakeupReason;
@@ -76,27 +78,17 @@ public:
virtual Result HandleSyncRequest(Kernel::KServerSession& session,
Kernel::HLERequestContext& context) = 0;
/**
* Signals that a client has just connected to this HLE handler and keeps the
* associated ServerSession alive for the duration of the connection.
* @param server_session Owning pointer to the ServerSession associated with the connection.
*/
void ClientConnected(KServerSession* session);
void AcceptSession(KServerPort* server_port);
void RegisterSession(KServerSession* server_session,
std::shared_ptr<SessionRequestManager> manager);
/**
* Signals that a client has just disconnected from this HLE handler and releases the
* associated ServerSession.
* @param server_session ServerSession associated with the connection.
*/
void ClientDisconnected(KServerSession* session);
std::weak_ptr<ServiceThread> GetServiceThread() const {
ServiceThread& GetServiceThread() const {
return service_thread;
}
protected:
KernelCore& kernel;
std::weak_ptr<ServiceThread> service_thread;
ServiceThread& service_thread;
};
using SessionRequestHandlerWeakPtr = std::weak_ptr<SessionRequestHandler>;
@@ -121,6 +113,10 @@ public:
is_domain = true;
}
void ConvertToDomainOnRequestEnd() {
convert_to_domain = true;
}
std::size_t DomainHandlerCount() const {
return domain_handlers.size();
}
@@ -158,13 +154,17 @@ public:
session_handler = std::move(handler);
}
std::weak_ptr<ServiceThread> GetServiceThread() const {
ServiceThread& GetServiceThread() const {
return session_handler->GetServiceThread();
}
bool HasSessionRequestHandler(const HLERequestContext& context) const;
Result HandleDomainSyncRequest(KServerSession* server_session, HLERequestContext& context);
Result CompleteSyncRequest(KServerSession* server_session, HLERequestContext& context);
private:
bool convert_to_domain{};
bool is_domain{};
SessionRequestHandlerPtr session_handler;
std::vector<SessionRequestHandlerPtr> domain_handlers;
@@ -295,7 +295,7 @@ public:
*/
template <typename T, typename = std::enable_if_t<!std::is_pointer_v<T>>>
std::size_t WriteBuffer(const T& data, std::size_t buffer_index = 0) const {
if constexpr (Common::IsSTLContainer<T>) {
if constexpr (Common::IsContiguousContainer<T>) {
using ContiguousType = typename T::value_type;
static_assert(std::is_trivially_copyable_v<ContiguousType>,
"Container to WriteBuffer must contain trivially copyable objects");
@@ -341,11 +341,11 @@ public:
template <typename T>
std::shared_ptr<T> GetDomainHandler(std::size_t index) const {
return std::static_pointer_cast<T>(manager.lock()->DomainHandler(index).lock());
return std::static_pointer_cast<T>(GetManager()->DomainHandler(index).lock());
}
void SetSessionRequestManager(std::weak_ptr<SessionRequestManager> manager_) {
manager = std::move(manager_);
manager = manager_;
}
std::string Description() const;
@@ -354,6 +354,10 @@ public:
return *thread;
}
std::shared_ptr<SessionRequestManager> GetManager() const {
return manager.lock();
}
private:
friend class IPC::ResponseBuilder;
@@ -387,7 +391,7 @@ private:
u32 handles_offset{};
u32 domain_offset{};
std::weak_ptr<SessionRequestManager> manager;
std::weak_ptr<SessionRequestManager> manager{};
KernelCore& kernel;
Core::Memory::Memory& memory;
+52 -28
View File
@@ -10,7 +10,9 @@
#include "core/hardware_properties.h"
#include "core/hle/kernel/init/init_slab_setup.h"
#include "core/hle/kernel/k_code_memory.h"
#include "core/hle/kernel/k_debug.h"
#include "core/hle/kernel/k_event.h"
#include "core/hle/kernel/k_event_info.h"
#include "core/hle/kernel/k_memory_layout.h"
#include "core/hle/kernel/k_memory_manager.h"
#include "core/hle/kernel/k_page_buffer.h"
@@ -18,9 +20,11 @@
#include "core/hle/kernel/k_process.h"
#include "core/hle/kernel/k_resource_limit.h"
#include "core/hle/kernel/k_session.h"
#include "core/hle/kernel/k_session_request.h"
#include "core/hle/kernel/k_shared_memory.h"
#include "core/hle/kernel/k_shared_memory_info.h"
#include "core/hle/kernel/k_system_control.h"
#include "core/hle/kernel/k_system_resource.h"
#include "core/hle/kernel/k_thread.h"
#include "core/hle/kernel/k_thread_local_page.h"
#include "core/hle/kernel/k_transfer_memory.h"
@@ -34,6 +38,7 @@ namespace Kernel::Init {
HANDLER(KThread, (SLAB_COUNT(KThread)), ##__VA_ARGS__) \
HANDLER(KEvent, (SLAB_COUNT(KEvent)), ##__VA_ARGS__) \
HANDLER(KPort, (SLAB_COUNT(KPort)), ##__VA_ARGS__) \
HANDLER(KSessionRequest, (SLAB_COUNT(KSession) * 2), ##__VA_ARGS__) \
HANDLER(KSharedMemory, (SLAB_COUNT(KSharedMemory)), ##__VA_ARGS__) \
HANDLER(KSharedMemoryInfo, (SLAB_COUNT(KSharedMemory) * 8), ##__VA_ARGS__) \
HANDLER(KTransferMemory, (SLAB_COUNT(KTransferMemory)), ##__VA_ARGS__) \
@@ -42,7 +47,10 @@ namespace Kernel::Init {
HANDLER(KThreadLocalPage, \
(SLAB_COUNT(KProcess) + (SLAB_COUNT(KProcess) + SLAB_COUNT(KThread)) / 8), \
##__VA_ARGS__) \
HANDLER(KResourceLimit, (SLAB_COUNT(KResourceLimit)), ##__VA_ARGS__)
HANDLER(KResourceLimit, (SLAB_COUNT(KResourceLimit)), ##__VA_ARGS__) \
HANDLER(KEventInfo, (SLAB_COUNT(KThread) + SLAB_COUNT(KDebug)), ##__VA_ARGS__) \
HANDLER(KDebug, (SLAB_COUNT(KDebug)), ##__VA_ARGS__) \
HANDLER(KSecureSystemResource, (SLAB_COUNT(KProcess)), ##__VA_ARGS__)
namespace {
@@ -71,8 +79,20 @@ constexpr size_t SlabCountKResourceLimit = 5;
constexpr size_t SlabCountKDebug = Core::Hardware::NUM_CPU_CORES;
constexpr size_t SlabCountKIoPool = 1;
constexpr size_t SlabCountKIoRegion = 6;
constexpr size_t SlabcountKSessionRequestMappings = 40;
constexpr size_t SlabCountExtraKThread = 160;
constexpr size_t SlabCountExtraKThread = (1024 + 256 + 256) - SlabCountKThread;
namespace test {
static_assert(KernelPageBufferHeapSize ==
2 * PageSize + (SlabCountKProcess + SlabCountKThread +
(SlabCountKProcess + SlabCountKThread) / 8) *
PageSize);
static_assert(KernelPageBufferAdditionalSize ==
(SlabCountExtraKThread + (SlabCountExtraKThread / 8)) * PageSize);
} // namespace test
/// Helper function to translate from the slab virtual address to the reserved location in physical
/// memory.
@@ -94,8 +114,8 @@ VAddr InitializeSlabHeap(Core::System& system, KMemoryLayout& memory_layout, VAd
// TODO(bunnei): Fix this once we support the kernel virtual memory layout.
if (size > 0) {
void* backing_kernel_memory{
system.DeviceMemory().GetPointer(TranslateSlabAddrToPhysical(memory_layout, start))};
void* backing_kernel_memory{system.DeviceMemory().GetPointer<void>(
TranslateSlabAddrToPhysical(memory_layout, start))};
const KMemoryRegion* region = memory_layout.FindVirtual(start + size - 1);
ASSERT(region != nullptr);
@@ -107,7 +127,7 @@ VAddr InitializeSlabHeap(Core::System& system, KMemoryLayout& memory_layout, VAd
}
size_t CalculateSlabHeapGapSize() {
constexpr size_t KernelSlabHeapGapSize = 2_MiB - 296_KiB;
constexpr size_t KernelSlabHeapGapSize = 2_MiB - 320_KiB;
static_assert(KernelSlabHeapGapSize <= KernelSlabHeapGapsSizeMax);
return KernelSlabHeapGapSize;
}
@@ -132,6 +152,7 @@ KSlabResourceCounts KSlabResourceCounts::CreateDefault() {
.num_KDebug = SlabCountKDebug,
.num_KIoPool = SlabCountKIoPool,
.num_KIoRegion = SlabCountKIoRegion,
.num_KSessionRequestMappings = SlabcountKSessionRequestMappings,
};
}
@@ -162,29 +183,6 @@ size_t CalculateTotalSlabHeapSize(const KernelCore& kernel) {
return size;
}
void InitializeKPageBufferSlabHeap(Core::System& system) {
auto& kernel = system.Kernel();
const auto& counts = kernel.SlabResourceCounts();
const size_t num_pages =
counts.num_KProcess + counts.num_KThread + (counts.num_KProcess + counts.num_KThread) / 8;
const size_t slab_size = num_pages * PageSize;
// Reserve memory from the system resource limit.
ASSERT(kernel.GetSystemResourceLimit()->Reserve(LimitableResource::PhysicalMemory, slab_size));
// Allocate memory for the slab.
constexpr auto AllocateOption = KMemoryManager::EncodeOption(
KMemoryManager::Pool::System, KMemoryManager::Direction::FromFront);
const PAddr slab_address =
kernel.MemoryManager().AllocateAndOpenContinuous(num_pages, 1, AllocateOption);
ASSERT(slab_address != 0);
// Initialize the slabheap.
KPageBuffer::InitializeSlabHeap(kernel, system.DeviceMemory().GetPointer(slab_address),
slab_size);
}
void InitializeSlabHeaps(Core::System& system, KMemoryLayout& memory_layout) {
auto& kernel = system.Kernel();
@@ -256,3 +254,29 @@ void InitializeSlabHeaps(Core::System& system, KMemoryLayout& memory_layout) {
}
} // namespace Kernel::Init
namespace Kernel {
void KPageBufferSlabHeap::Initialize(Core::System& system) {
auto& kernel = system.Kernel();
const auto& counts = kernel.SlabResourceCounts();
const size_t num_pages =
counts.num_KProcess + counts.num_KThread + (counts.num_KProcess + counts.num_KThread) / 8;
const size_t slab_size = num_pages * PageSize;
// Reserve memory from the system resource limit.
ASSERT(kernel.GetSystemResourceLimit()->Reserve(LimitableResource::PhysicalMemory, slab_size));
// Allocate memory for the slab.
constexpr auto AllocateOption = KMemoryManager::EncodeOption(
KMemoryManager::Pool::System, KMemoryManager::Direction::FromFront);
const PAddr slab_address =
kernel.MemoryManager().AllocateAndOpenContinuous(num_pages, 1, AllocateOption);
ASSERT(slab_address != 0);
// Initialize the slabheap.
KPageBuffer::InitializeSlabHeap(kernel, system.DeviceMemory().GetPointer<void>(slab_address),
slab_size);
}
} // namespace Kernel
+1 -1
View File
@@ -33,11 +33,11 @@ struct KSlabResourceCounts {
size_t num_KDebug;
size_t num_KIoPool;
size_t num_KIoRegion;
size_t num_KSessionRequestMappings;
};
void InitializeSlabResourceCounts(KernelCore& kernel);
size_t CalculateTotalSlabHeapSize(const KernelCore& kernel);
void InitializeKPageBufferSlabHeap(Core::System& system);
void InitializeSlabHeaps(Core::System& system, KMemoryLayout& memory_layout);
} // namespace Kernel::Init
+7 -8
View File
@@ -16,9 +16,9 @@
#include "core/hle/kernel/k_session.h"
#include "core/hle/kernel/k_shared_memory.h"
#include "core/hle/kernel/k_synchronization_object.h"
#include "core/hle/kernel/k_system_resource.h"
#include "core/hle/kernel/k_thread.h"
#include "core/hle/kernel/k_transfer_memory.h"
#include "core/hle/kernel/k_writable_event.h"
namespace Kernel {
@@ -42,13 +42,12 @@ static_assert(ClassToken<KPort> == 0b10000101'00000000);
static_assert(ClassToken<KSession> == 0b00011001'00000000);
static_assert(ClassToken<KSharedMemory> == 0b00101001'00000000);
static_assert(ClassToken<KEvent> == 0b01001001'00000000);
static_assert(ClassToken<KWritableEvent> == 0b10001001'00000000);
// static_assert(ClassToken<KLightClientSession> == 0b00110001'00000000);
// static_assert(ClassToken<KLightServerSession> == 0b01010001'00000000);
static_assert(ClassToken<KTransferMemory> == 0b10010001'00000000);
static_assert(ClassToken<KTransferMemory> == 0b01010001'00000000);
// static_assert(ClassToken<KDeviceAddressSpace> == 0b01100001'00000000);
// static_assert(ClassToken<KSessionRequest> == 0b10100001'00000000);
static_assert(ClassToken<KCodeMemory> == 0b11000001'00000000);
static_assert(ClassToken<KCodeMemory> == 0b10100001'00000000);
// Ensure that the token hierarchy is correct.
@@ -73,13 +72,12 @@ static_assert(ClassToken<KPort> == ((0b10000101 << 8) | ClassToken<KAutoObject>)
static_assert(ClassToken<KSession> == ((0b00011001 << 8) | ClassToken<KAutoObject>));
static_assert(ClassToken<KSharedMemory> == ((0b00101001 << 8) | ClassToken<KAutoObject>));
static_assert(ClassToken<KEvent> == ((0b01001001 << 8) | ClassToken<KAutoObject>));
static_assert(ClassToken<KWritableEvent> == ((0b10001001 << 8) | ClassToken<KAutoObject>));
// static_assert(ClassToken<KLightClientSession> == ((0b00110001 << 8) | ClassToken<KAutoObject>));
// static_assert(ClassToken<KLightServerSession> == ((0b01010001 << 8) | ClassToken<KAutoObject>));
static_assert(ClassToken<KTransferMemory> == ((0b10010001 << 8) | ClassToken<KAutoObject>));
static_assert(ClassToken<KTransferMemory> == ((0b01010001 << 8) | ClassToken<KAutoObject>));
// static_assert(ClassToken<KDeviceAddressSpace> == ((0b01100001 << 8) | ClassToken<KAutoObject>));
// static_assert(ClassToken<KSessionRequest> == ((0b10100001 << 8) | ClassToken<KAutoObject>));
static_assert(ClassToken<KCodeMemory> == ((0b11000001 << 8) | ClassToken<KAutoObject>));
static_assert(ClassToken<KCodeMemory> == ((0b10100001 << 8) | ClassToken<KAutoObject>));
// Ensure that the token hierarchy reflects the class hierarchy.
@@ -110,7 +108,6 @@ static_assert(std::is_final_v<KPort> && std::is_base_of_v<KAutoObject, KPort>);
static_assert(std::is_final_v<KSession> && std::is_base_of_v<KAutoObject, KSession>);
static_assert(std::is_final_v<KSharedMemory> && std::is_base_of_v<KAutoObject, KSharedMemory>);
static_assert(std::is_final_v<KEvent> && std::is_base_of_v<KAutoObject, KEvent>);
static_assert(std::is_final_v<KWritableEvent> && std::is_base_of_v<KAutoObject, KWritableEvent>);
// static_assert(std::is_final_v<KLightClientSession> &&
// std::is_base_of_v<KAutoObject, KLightClientSession>);
// static_assert(std::is_final_v<KLightServerSession> &&
@@ -123,4 +120,6 @@ static_assert(std::is_final_v<KTransferMemory> && std::is_base_of_v<KAutoObject,
// static_assert(std::is_final_v<KCodeMemory> &&
// std::is_base_of_v<KAutoObject, KCodeMemory>);
static_assert(std::is_base_of_v<KAutoObject, KSystemResource>);
} // namespace Kernel
+5 -2
View File
@@ -10,6 +10,8 @@ namespace Kernel {
class KAutoObject;
class KSystemResource;
class KClassTokenGenerator {
public:
using TokenBaseType = u16;
@@ -58,7 +60,7 @@ private:
if constexpr (std::is_same<T, KAutoObject>::value) {
static_assert(T::ObjectType == ObjectType::KAutoObject);
return 0;
} else if constexpr (!std::is_final<T>::value) {
} else if constexpr (!std::is_final<T>::value && !std::same_as<T, KSystemResource>) {
static_assert(ObjectType::BaseClassesStart <= T::ObjectType &&
T::ObjectType < ObjectType::BaseClassesEnd);
constexpr auto ClassIndex = static_cast<TokenBaseType>(T::ObjectType) -
@@ -101,7 +103,6 @@ public:
KSession,
KSharedMemory,
KEvent,
KWritableEvent,
KLightClientSession,
KLightServerSession,
KTransferMemory,
@@ -109,6 +110,8 @@ public:
KSessionRequest,
KCodeMemory,
KSystemResource,
// NOTE: True order for these has not been determined yet.
KAlpha,
KBeta,
+2 -3
View File
@@ -58,8 +58,7 @@ bool KClientPort::IsSignaled() const {
return num_sessions < max_sessions;
}
Result KClientPort::CreateSession(KClientSession** out,
std::shared_ptr<SessionRequestManager> session_manager) {
Result KClientPort::CreateSession(KClientSession** out) {
// Reserve a new session from the resource limit.
KScopedResourceReservation session_reservation(kernel.CurrentProcess()->GetResourceLimit(),
LimitableResource::Sessions);
@@ -104,7 +103,7 @@ Result KClientPort::CreateSession(KClientSession** out,
}
// Initialize the session.
session->Initialize(this, parent->GetName(), session_manager);
session->Initialize(this, parent->GetName());
// Commit the session reservation.
session_reservation.Commit();
+1 -2
View File
@@ -52,8 +52,7 @@ public:
void Destroy() override;
bool IsSignaled() const override;
Result CreateSession(KClientSession** out,
std::shared_ptr<SessionRequestManager> session_manager = nullptr);
Result CreateSession(KClientSession** out);
private:
std::atomic<s32> num_sessions{};
+14 -4
View File
@@ -1,6 +1,7 @@
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include "common/scope_exit.h"
#include "core/hle/kernel/hle_ipc.h"
#include "core/hle/kernel/k_client_session.h"
#include "core/hle/kernel/k_server_session.h"
@@ -10,6 +11,8 @@
namespace Kernel {
static constexpr u32 MessageBufferSize = 0x100;
KClientSession::KClientSession(KernelCore& kernel_)
: KAutoObjectWithSlabHeapAndContainer{kernel_} {}
KClientSession::~KClientSession() = default;
@@ -21,10 +24,17 @@ void KClientSession::Destroy() {
void KClientSession::OnServerClosed() {}
Result KClientSession::SendSyncRequest(KThread* thread, Core::Memory::Memory& memory,
Core::Timing::CoreTiming& core_timing) {
// Signal the server session that new data is available
return parent->GetServerSession().HandleSyncRequest(thread, memory, core_timing);
Result KClientSession::SendSyncRequest() {
// Create a session request.
KSessionRequest* request = KSessionRequest::Create(kernel);
R_UNLESS(request != nullptr, ResultOutOfResource);
SCOPE_EXIT({ request->Close(); });
// Initialize the request.
request->Initialize(nullptr, GetCurrentThread(kernel).GetTLSAddress(), MessageBufferSize);
// Send the request.
return parent->GetServerSession().OnRequest(request);
}
} // namespace Kernel
+1 -2
View File
@@ -46,8 +46,7 @@ public:
return parent;
}
Result SendSyncRequest(KThread* thread, Core::Memory::Memory& memory,
Core::Timing::CoreTiming& core_timing);
Result SendSyncRequest();
void OnServerClosed();
+1 -1
View File
@@ -34,7 +34,7 @@ Result KCodeMemory::Initialize(Core::DeviceMemory& device_memory, VAddr addr, si
// Clear the memory.
for (const auto& block : m_page_group.Nodes()) {
std::memset(device_memory.GetPointer(block.GetAddress()), 0xFF, block.GetSize());
std::memset(device_memory.GetPointer<void>(block.GetAddress()), 0xFF, block.GetSize());
}
// Set remaining tracking members.
+20
View File
@@ -0,0 +1,20 @@
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include "core/hle/kernel/k_auto_object.h"
#include "core/hle/kernel/slab_helpers.h"
namespace Kernel {
class KDebug final : public KAutoObjectWithSlabHeapAndContainer<KDebug, KAutoObjectWithList> {
KERNEL_AUTOOBJECT_TRAITS(KDebug, KAutoObject);
public:
explicit KDebug(KernelCore& kernel_) : KAutoObjectWithSlabHeapAndContainer{kernel_} {}
static void PostDestroy([[maybe_unused]] uintptr_t arg) {}
};
} // namespace Kernel

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