Compare commits

..

336 Commits

Author SHA1 Message Date
Kelebek1 1d3bc0a08f Use ScratchBuffer to reduce memory allocations in audio_core 2023-02-10 22:22:29 +00:00
liamwhite c5743d5499 Merge pull request #9736 from Kelebek1/dynamic_vertex_attribs
Remove fake vertex bindings when dynamic state is enabled
2023-02-09 22:14:55 -05:00
liamwhite cbb289fbee Merge pull request #9750 from ameerj/glsl-sample-id-mask
glsl_emit_context: Remove redeclarations of gl_SampleID and gl_SampleMask
2023-02-09 22:14:47 -05:00
liamwhite c0b36c2d26 Merge pull request #9758 from german77/multi_audio
audio: cubeb: Fix yuzu crashing when it test for latency
2023-02-09 22:14:33 -05:00
Narr the Reg 7c0dcea96c audio: cubeb: Fix yuzu crashing when it test for latency 2023-02-09 19:38:03 -06:00
Matías Locatti 7bad3a7e5e Merge pull request #9749 from ameerj/pr9559-partial-revert
buffer_base: Partially revert changes from #9559
2023-02-09 17:53:45 -03:00
ameerj eb9f16dce4 buffer_base: Partially revert changes from #9559
This fixes a regression where Yoshi's Crafted World (and potentially other titles) would enter an infinite loop when GPU Accuracy was set to "Normal"
2023-02-08 19:37:23 -05:00
ameerj 04139cb3ed glsl_emit_context: Remove redeclarations of gl_SampleID and gl_SampleMask
These built-ins seem to be available without needing to be declared for fragment shaders, similar i.e. to gl_FragDepth
2023-02-08 19:34:39 -05:00
liamwhite f6477b91f9 Merge pull request #9747 from german77/SetSupportedNpadIdTypes
service: hid: Return error if arguments of SetSupportedNpadIdType is invalid
2023-02-08 10:09:26 -05:00
Narr the Reg c27006e99d service: hid: Return error if arguments of SetSupportedNpadIdType is invalid 2023-02-07 21:11:39 -06:00
Mai f3b532d091 Merge pull request #9739 from liamwhite/old-gcc-fix
kernel: fix compilation with older gcc
2023-02-07 22:10:35 -05:00
liamwhite 1f3e8d633a Merge pull request #4949 from Morph1984/hidpi-temp-fix
main: Enable High DPI fixes for Qt >= 5.14
2023-02-06 23:20:49 -05:00
bunnei ecbf74b87a Merge pull request #9644 from SaiKai/volume_quicksetting
add volume quicksetting with volume slider
2023-02-06 17:10:44 -08:00
bunnei 01cb49973a Merge pull request #9735 from merryhime/dynarmic-6.4.5
dynarmic: Update to 6.4.5
2023-02-06 17:09:17 -08:00
Liam 82c2a3da9f kernel: fix compilation with older gcc 2023-02-06 13:14:27 -05:00
liamwhite 72f78a48e3 Merge pull request #9737 from goldenx86/yuzu_cmd
Update yuzu_cmd's default_ini.h
2023-02-06 09:08:27 -05:00
Matías Locatti 69eaad18a5 Update yuzu_cmd's default_ini.h
Rename FSR, add missing resolution multipliers, and SMAA
2023-02-06 06:01:51 -03:00
Kelebek1 8ae2a664d2 Remove fake vertex bindings when dynamic state is enabled 2023-02-05 22:28:03 +00:00
Merry 3f852c61d1 dynarmic: Update to 6.4.5 2023-02-05 21:49:32 +00:00
Mai 0373000143 Merge pull request #9731 from liamwhite/svc-move-only
kernel/svc: Split implementations into separate files
2023-02-05 02:26:52 -05:00
Liam 92eb091ddb kernel/svc: Split implementations into separate files 2023-02-04 22:37:43 -05:00
bunnei a64fc3ee77 Merge pull request #9720 from SoRadGaming/discordPresenceUpdate
Game Image with Discord RPC
2023-02-04 18:37:21 -08:00
Sorab 923c17f1ae Add Game Icon for Discord RPC
Connected to Yuzu Compatibility Page
2023-02-05 12:40:57 +11:00
liamwhite f5ed51bdf3 Merge pull request #9730 from german77/cmd_arg
yuzu_cmd: Order arguments alphabetically and port arguments from Qt
2023-02-04 15:01:17 -05:00
liamwhite 236b54376d Merge pull request #9729 from german77/sdl_input
yuzu_cmd: Fix touch and controller input
2023-02-04 15:01:07 -05:00
liamwhite 7f56b0c49f Merge pull request #9728 from ameerj/s32-value
shader_recompiler/value.h: Remove lingering references to S32
2023-02-04 15:00:54 -05:00
german77 3cd0b816cc yuzu_cmd: Order arguments alphabetically and port arguments from Qt 2023-02-04 11:33:29 -06:00
german77 ebca59b8e9 yuzu_cmd: Fix mismatching controller input 2023-02-04 11:05:57 -06:00
german77 424643f9af yuzu_cmd: Fix touch input 2023-02-04 10:31:12 -06:00
ameerj 4678f53463 shader_recompiler/value.h: Remove lingering references to S32 2023-02-04 00:13:47 -05:00
bunnei 5aca9386cf Merge pull request #9717 from german77/less_is_better
input_common: Simplify stick from button
2023-02-03 16:09:29 -08:00
bunnei 193b513bf5 Merge pull request #9719 from ameerj/hle-ipc-span-copy
Revert #9718, Copy HLE Read Buffer for OutputAccessLogToSdCard
2023-02-03 15:42:18 -08:00
Jonas Gutenschwager 2a491f7aaa remove disambiguation argument from mute text
Co-authored-by: Morph <39850852+Morph1984@users.noreply.github.com>
2023-02-04 00:00:20 +01:00
ameerj 979e4d9950 fsp_srv: Copy HLE Read Buffer for OutputAccessLogToSdCard 2023-02-03 00:12:16 -05:00
ameerj 2d2522693e Revert "Merge pull request #9718 from yuzu-emu/revert-9508-hle-ipc-buffer-span"
This reverts commit 25fc5c0e11, reversing
changes made to af20e25081.
2023-02-03 00:08:45 -05:00
Mai 9083ad816f Merge pull request #9713 from unfamiliarplace/master
Added 'Hide empty rooms' toggle to lobby
2023-02-02 23:54:48 -05:00
bunnei 25fc5c0e11 Merge pull request #9718 from yuzu-emu/revert-9508-hle-ipc-buffer-span
Revert "hle_ipc: Use std::span to avoid heap allocations/copies when calling ReadBuffer"
2023-02-02 19:04:50 -08:00
bunnei af20e25081 Merge pull request #9704 from liamwhite/das
kernel: add KDeviceAddressSpace
2023-02-02 19:00:23 -08:00
Luke Sawczak 54ab154696 added 'Hide empty rooms' toggle to lobby
fixed typo

fixed typo

fixed typo

clang
2023-02-02 18:46:28 -06:00
liamwhite b01698775b Revert "hle_ipc: Use std::span to avoid heap allocations/copies when calling ReadBuffer" 2023-02-02 15:53:28 -05:00
Narr the Reg 2f2e88c3fb input_common: Simplify stick from button 2023-02-02 10:13:27 -06:00
liamwhite 8a33f8bd30 Merge pull request #9708 from ameerj/gl-context-flush
gl_shader_cache: Force context flush when loading disk shader cache
2023-02-01 22:38:13 -05:00
liamwhite a9a860a4f7 Merge pull request #9703 from ameerj/txq-ms
shaders: Fix TXQ with MSAA textures
2023-02-01 22:38:00 -05:00
Liam 7d1c3a3f59 kernel: add KDeviceAddressSpace 2023-02-01 17:18:21 -05:00
bunnei 92c5ab33b7 Merge pull request #9696 from german77/please_forgive_me_for_this_sin
input_common: Implement turbo buttons
2023-02-01 12:08:34 -08:00
german77 ce1895497d yuzu: config: Draw turbo buttons with a different color 2023-02-01 12:42:06 -06:00
german77 75e81885b0 input_common: Implement turbo buttons 2023-02-01 12:42:05 -06:00
Mai c4aa833d61 Merge pull request #9711 from zhaobot/tx-update-20230201062139
Update translations (2023-02-01)
2023-02-01 01:26:51 -05:00
The yuzu Community 6ef4bee98e Update translations (2023-02-01) 2023-02-01 06:21:50 +00:00
bunnei de28cd0c2d Merge pull request #9697 from liamwhite/kcap
kernel: add KCapabilities
2023-01-31 10:51:10 -08:00
bunnei ed4a88bd93 Merge pull request #9508 from ameerj/hle-ipc-buffer-span
hle_ipc: Use std::span to avoid heap allocations/copies when calling ReadBuffer
2023-01-30 12:17:09 -08:00
liamwhite e74660673b Merge pull request #9701 from german77/common_protocol
input_common: joycon: Remove Magic numbers from common protocol
2023-01-30 09:02:12 -05:00
liamwhite 9de88cb5a7 Merge pull request #9631 from vonchenplus/vulkan_clear
video_core: Implement vulkan clear specified channel
2023-01-30 09:01:55 -05:00
Liam 67a8740af6 kernel: add KCapabilities 2023-01-29 22:08:28 -05:00
ameerj 720ff38097 gl_compute_pipeline: Force context flush when loading shader cache 2023-01-29 21:32:12 -05:00
Narr the Reg c318a4c80b input_common: joycon: Remove Magic numbers from common protocol 2023-01-29 20:12:58 -06:00
Morph 4069c3ac8b Merge pull request #9707 from german77/clang15
cmake: Download clang format 15
2023-01-29 21:00:55 -05:00
german77 fb425159b1 cmake: Download clang format 15 2023-01-29 19:57:40 -06:00
ameerj 01eeda74a6 gl_graphics_pipeline: Force context flush when loading shader cache 2023-01-29 20:26:49 -05:00
Narr the Reg 11fea5deea input_common: joycon: Fill missing enum data 2023-01-29 19:11:46 -06:00
Morph 07cefe9062 Merge pull request #9706 from Morph1984/github-tagged-merge
ci: Abort on failure to query Github's API
2023-01-29 20:09:29 -05:00
Morph e711188be7 apply-patches-by-label: Remove unused variables and imports 2023-01-29 19:53:14 -05:00
Morph 0f04cabf84 apply-patches-by-label: Use python f-strings 2023-01-29 19:53:14 -05:00
Morph 8532e17243 ci: Abort on failure to query Github's API
This raises an exception if the GET request to Github's API returns anything other than 200 OK, ensuring we always have successful merges of tagged PRs.
Also, reduces the number of queried pages from 29 to 9 to reduce the number of requests.
2023-01-29 19:53:14 -05:00
Morph 5f4647df7d Merge pull request #9705 from behunin/patch-1
Move to Clang Format 15
2023-01-29 19:52:38 -05:00
Levi Behunin d5fc56db4b Move to Clang Format 15
Depends on https://github.com/yuzu-emu/build-environments/pull/69

clang-15 primary run
2023-01-29 17:49:42 -07:00
ameerj a63e17566a spirv: Fix TXQ with MSAA textures 2023-01-29 13:47:30 -05:00
ameerj a1d8306bfd emit_glasm_image: Fix TXQ with MSAA textures 2023-01-29 13:42:34 -05:00
ameerj 08feba2b56 emit_glsl_image: Implement TXQ with MSAA textures
Also fixes for texture buffers, which do not have mips eithers.
2023-01-29 13:31:47 -05:00
liamwhite 3aab574521 Merge pull request #9699 from ameerj/texture-pass-desc
texture_pass: Fix texture descriptors comparisons
2023-01-29 12:27:41 -05:00
liamwhite 149271923c Merge pull request #9698 from ameerj/texture-pass-handle
texture_pass: Refactor texture handle retrieval
2023-01-29 12:27:33 -05:00
liamwhite 208e635f37 Merge pull request #9694 from ameerj/txq-mips
shader_recompiler: TXQ: Skip QueryLevels when possible
2023-01-29 12:27:26 -05:00
liamwhite d960723dc9 Merge pull request #9684 from liamwhite/read-the-spec
polyfill_thread: satisfy execution ordering requirements of stop_callback
2023-01-29 09:35:42 -05:00
bunnei 9170387e71 Merge pull request #9689 from german77/joycon-calibration
input_common: joycon: Remove magic numbers from calibration protocol
2023-01-29 02:43:14 -08:00
bunnei a3aedcce65 Merge pull request #9691 from ameerj/msaa-texcache
texture_cache: Fix tracking of MSAA image views
2023-01-28 23:47:45 -08:00
liamwhite 236f591bde Merge pull request #9690 from german77/whoops
yuzu: config: Avoid reading deleted object
2023-01-28 22:28:38 -05:00
ameerj 0d820f2dab texture_pass: Fix texture descriptors comparisons 2023-01-28 21:23:52 -05:00
ameerj 9bb429999e texture_pass: Refactor texture handle retrieval 2023-01-28 21:11:38 -05:00
bunnei 40e7d78179 Merge pull request #9687 from ameerj/ogl-shader-ms
glasm, glsl: Implement multisampled Image Fetch
2023-01-28 16:32:11 -08:00
bunnei 159aab9a97 Merge pull request #9682 from ameerj/shader-s32
shader_recompiler: Remove S32 IR type
2023-01-28 14:00:11 -08:00
ameerj 2c2e019a44 shader_recompiler: TXQ: Skip QueryLevels when possible 2023-01-28 16:25:18 -05:00
ameerj c0cedbae94 emit_glsl_image: Fix ImageFetch for MSAA textures 2023-01-28 14:39:27 -05:00
Narr the Reg e84a441d75 yuzu: config: Avoid reading deleted object 2023-01-28 12:50:27 -06:00
liamwhite cd138540e2 Merge pull request #9661 from SoRadGaming/LDNhostnameSupport
LDN hostname support in direct connect
2023-01-28 12:09:57 -05:00
SoRadGaming ad712926d6 LDN Hostname Support in Direct Connect
- Added IPv6 & Namespace support in direct connection Regex
- Updated Tooltip for Direct Connect UI
- Removed Dropdown Connection Type in Direct Connect
2023-01-28 18:33:21 +11:00
ameerj c2fb7b64ce texture_cache: Adjust image view sizes by MSAA samples 2023-01-28 00:15:29 -05:00
FengChen 818631a412 video_core: Implement vulkan clear specified channel 2023-01-28 12:53:05 +08:00
Liam 619c0e70f0 polyfill_thread: satisfy execution ordering requirements of stop_callback 2023-01-27 21:34:49 -05:00
bunnei 2efe42fc93 Merge pull request #9677 from Morph1984/sleep-one
polyfill_thread: Implement StoppableTimedWait
2023-01-27 18:28:03 -08:00
Narr the Reg 4e29afefc4 input_common: joycon: Replace ReadSPI vector with span 2023-01-27 18:45:25 -06:00
liamwhite 6fa86989f1 Merge pull request #9539 from Wollnashorn/opengl-fsr
video_core/opengl: Added FSR upscaling filter to the OpenGL renderer
2023-01-27 19:28:35 -05:00
Narr the Reg 8647c72778 input_common: joycon: Remove magic numbers from calibration protocol 2023-01-27 17:12:04 -06:00
bunnei 32b2a72e7b Merge pull request #9666 from liamwhite/wait-for-me
kernel: fix incorrect locking order in suspension
2023-01-27 15:06:09 -08:00
ameerj 0f795603fc glasm: Add MS sampler types 2023-01-27 02:09:18 -05:00
ameerj 5710e90150 glsl: Add MS sampler types 2023-01-27 02:09:17 -05:00
Mai e54d08fc1f Merge pull request #9685 from liamwhite/minmax
kernel: unbreak min/max template deduction on Apple Clang
2023-01-27 00:07:50 +00:00
Liam e9e1e7aa3a kernel: unbreak min/max template deduction on Apple Clang 2023-01-26 17:43:37 -05:00
Wollnashorn c4a49eb1dd video_core/opengl: Add FSR upscaling filter to the OpenGL renderer 2023-01-26 21:43:33 +01:00
bunnei 7d0a77a825 Merge pull request #9683 from german77/high_power_joycon
input_common: Implement SetLowPowerMode and TriggersElapsed
2023-01-26 10:56:31 -08:00
Narr the Reg 49707916db input_common: Implement SetLowPowerMode and TriggersElapsed for the joycon driver 2023-01-26 11:21:04 -06:00
bunnei 5669692b4e Merge pull request #9670 from merryhime/revert-af5ecb0b15d4449f58434e70eed835cf71fc5527
Revert "MemoryManager: use fastmem directly."
2023-01-25 22:28:55 -08:00
bunnei 58ba508e9a Merge pull request #9652 from liamwhite/ms
spirv: fix multisampled image fetch
2023-01-25 22:28:18 -08:00
bunnei 2158ccda3b Merge pull request #9604 from liamwhite/pt
kernel: KPageTable: update
2023-01-25 22:27:48 -08:00
ameerj 93cc6e4d99 shader_recompiler: Remove S32 IR type
The frontend IR opcodes do not distinguish between signed and unsigned integer types.

Fixes broken shaders when IR validation/graphics debugging is enabled for shaders that used BitCastS32F32
2023-01-25 22:03:15 -05:00
Morph ad6cec71ec main: Convert to device independent coordinates for scaling
devicePixelRatioF() returns the scaling ratio when high dpi scaling is enabled.
When high dpi scaling is enabled, the raw screen coordinate system is scaled to device independent coordinates.
2023-01-25 21:16:05 -05:00
Morph 5be85c556e main: Use passthrough scaling for non-windows OSes
They should be better than windows when handling fractional scaling ratios.
2023-01-25 21:16:04 -05:00
Morph 6a1b089a50 main: Enable High DPI fixes for Qt >= 5.14
This uses Qt's new high DPI application attributes for scaling the current window.
However, these aren't perfect as scaling with non integer scales will cause artifacts in UI, icons and other elements.
Therefore, we use a heuristic to select an appropriate integer scale value depending on the current screen resolution and applies this to the application.
2023-01-25 21:16:04 -05:00
Morph 0a7cdc1981 Merge pull request #9681 from Morph1984/nice-one-qt6
main: Only set AA_DisableWindowContextHelpButton below Qt6
2023-01-25 20:46:51 -05:00
Morph b6e5a6bda8 main: Only set AA_DisableWindowContextHelpButton below Qt6
This is fortunately disabled by default on Qt6, so we just have to check whether we are compiling with Qt6 or not.
2023-01-25 18:45:22 -05:00
liamwhite 0d1a9a12c9 Merge pull request #9675 from Morph1984/ini-concat
default_ini: Split and concatenate the config string literal
2023-01-25 17:57:09 -05:00
liamwhite 4ec50dfd4f Merge pull request #9668 from Morph1984/qt-why-is-this-not-the-default
main: Globally disable the "?" button on dialogs
2023-01-25 17:56:58 -05:00
liamwhite abda68f3a4 Merge pull request #9676 from german77/revert-stick-range
Revert #9617 and fix it on input_common
2023-01-25 17:56:47 -05:00
Morph c55147b24a input_common: Make use of StoppableTimedWait 2023-01-25 16:43:04 -05:00
Morph 9b0563fa87 polyfill_thread: Implement StoppableTimedWait
StoppableTimedWait allows for a timed wait to be stopped immediately after a stop is requested.
This is useful in cases where long duration thread sleeps are needed and allows for immediate joining of waiting threads after a stop is requested.

Co-Authored-By: liamwhite <liamwhite@users.noreply.github.com>
2023-01-25 16:43:04 -05:00
Narr the Reg b82a098968 Merge pull request #9679 from jbeich/libc++
input_common: unbreak build with libc++ (missing std::ranges::find_if)
2023-01-25 15:21:59 -06:00
Jan Beich 20c7084892 input_common: add missing header for libc++ after 340f15d1fa
src/input_common/drivers/joycon.cpp:187:26: error: no member named 'find_if' in namespace 'std::ranges'
            std::ranges::find_if(left_joycons, [](auto& device) { return !device->IsConnected(); });
            ~~~~~~~~~~~~~^
src/input_common/drivers/joycon.cpp:193:54: error: no member named 'find_if' in namespace 'std::ranges'
        const auto unconnected_device = std::ranges::find_if(
                                        ~~~~~~~~~~~~~^
src/input_common/drivers/joycon.cpp:393:51: error: no member named 'find_if' in namespace 'std::ranges'
        const auto matching_device = std::ranges::find_if(
                                     ~~~~~~~~~~~~~^
src/input_common/drivers/joycon.cpp:402:51: error: no member named 'find_if' in namespace 'std::ranges'
        const auto matching_device = std::ranges::find_if(
                                     ~~~~~~~~~~~~~^
2023-01-25 19:52:56 +00:00
Narr the Reg cc821bfae1 Revert 9617 and fix it on input_common 2023-01-25 13:52:50 -06:00
Morph 4cdf69c378 default_ini: Split and concatenate the config string literal
We are dangerously close to MSVC's 16384 character limit for string literals. Breaking this string up and concatenating will allow for more settings to be added in the future.
2023-01-25 14:06:06 -05:00
Merry dc7ab4c5d6 Revert "MemoryManager: use fastmem directly."
This reverts commit af5ecb0b15.
2023-01-25 10:12:04 +00:00
Morph cdfb3795af main: Globally disable the "?" button on dialogs
Sets the AA_DisableWindowContextHelpButton attribute to disable this useless button globally.
2023-01-25 01:12:50 -05:00
bunnei 44b981fd3e Merge pull request #9662 from abouvier/cmake-llvm
cmake: prefer system llvm library
2023-01-24 11:03:14 -08:00
liamwhite a68af583ea Merge pull request #9492 from german77/joycon_release
Input_common: Implement custom joycon driver v2
2023-01-24 09:29:37 -05:00
Liam 693cad8e9b kernel: split SetAddressKey into user and kernel variants 2023-01-23 20:31:03 -05:00
Liam 5086380a63 kernel: fix incorrect locking order in suspension 2023-01-23 17:14:41 -05:00
Liam 76a4356e55 spirv: fix multisampled image fetch 2023-01-23 12:03:19 -05:00
Alexandre Bouvier 34b1ea9c19 cmake: prefer system llvm library 2023-01-23 06:23:00 +01:00
liamwhite f99f618d45 Merge pull request #9555 from abouvier/catch2-update
tests: update catch2 to 3.0.1
2023-01-22 18:22:47 -05:00
Liam 31e54c4573 kernel: KPageTable: update 2023-01-22 13:17:29 -05:00
liamwhite 78df1ddce8 Merge pull request #9660 from german77/koreaToTaiwan
yuzu: Fix language comobox crash
2023-01-22 13:14:38 -05:00
liamwhite 9184b6ed2b Merge pull request #9656 from liamwhite/nsight
nsight_aftermath_tracker: update for latest Aftermath SDK
2023-01-22 13:14:28 -05:00
liamwhite ff2bbc8205 Merge pull request #9637 from SaiKai/repeat_shortcuts
allow volume up/down hotkeys to be repeated
2023-01-22 13:14:19 -05:00
liamwhite 02ac593257 Merge pull request #9617 from german77/off_by_one
core: hid: Fix stick minimum range
2023-01-22 13:14:10 -05:00
liamwhite 9705094a57 Merge pull request #9613 from Kelebek1/demangle
Add stacktrace symbol demangling
2023-01-22 13:13:58 -05:00
german77 a436467152 yuzu: Fix language comobox crash 2023-01-22 10:42:59 -06:00
Liam c6eab71d5c nsight_aftermath_tracker: update for latest Aftermath SDK 2023-01-21 13:01:19 -05:00
Kelebek1 31229dd245 Change licenses 2023-01-21 06:19:43 +00:00
bunnei 380dcde154 Merge pull request #9642 from Tachi107/appstream-metadata-fix
fix(dist): wrap screenshots in <image> tags
2023-01-20 21:02:38 -08:00
bunnei f78068d7bf Merge pull request #9611 from liamwhite/patch-1
debugger: add host fastmem pointer fetch command
2023-01-20 10:00:33 -08:00
Narr the Reg d9ee7c3297 core: hid: Make use of SCOPE_EXIT and SCOPE_GUARD where applicable 2023-01-20 00:51:46 -06:00
german77 fafa92cfb8 input_common: Fix joycon mappings 2023-01-20 00:51:46 -06:00
german77 340f15d1fa input_common: Address byte review 2023-01-20 00:51:45 -06:00
bunnei 7d77798f0e Merge pull request #9640 from german77/why_sdl
input_common: reset sdl motion if data is invalid
2023-01-19 18:47:21 -08:00
Narr the Reg 4a307a7b3a core: hid: Only set the polling mode to the correct side 2023-01-19 18:05:23 -06:00
german77 b40aefb39e input_common: Drop Pro controller support from custom driver 2023-01-19 18:05:22 -06:00
german77 d05ea2f3eb input_common: Fix issue where ring and irs are enabled at the same time 2023-01-19 18:05:22 -06:00
Narr the Reg 459fb2b213 input_common: Implement joycon ir camera 2023-01-19 18:05:22 -06:00
german77 5cb437703f yuzu: Add ring controller test button 2023-01-19 18:05:22 -06:00
german77 527dad7097 input_common: Use DriverResult on all engines 2023-01-19 18:05:22 -06:00
german77 e1a3bda4d9 Address review comments 2023-01-19 18:05:22 -06:00
Narr the Reg 1c08d532e0 core: hid: Fix input regressions 2023-01-19 18:05:22 -06:00
german77 6d6b7bdbc3 input_common: Implement joycon nfc 2023-01-19 18:05:21 -06:00
Narr the Reg 6e33731f29 input_common: Add dual joycon support 2023-01-19 18:05:21 -06:00
Narr the Reg 751d36e739 input_common: Add support for joycon ring controller 2023-01-19 18:05:21 -06:00
Narr the Reg f09a023292 input_common: Add support for joycon input reports 2023-01-19 18:05:21 -06:00
Narr the Reg 5676c2e17f input_common: Use calibration from joycon 2023-01-19 18:05:21 -06:00
Narr the Reg 594b2ade6d input_common: Add support for joycon generic functions 2023-01-19 18:05:21 -06:00
Narr the Reg 6aa6301acd input_common: Add joycon low level functions 2023-01-19 18:05:21 -06:00
Narr the Reg 36d5e0a411 service: hid: Set led pattern and fix color detection 2023-01-19 18:05:20 -06:00
Narr the Reg ed5fa10e97 core: hid: Enable pulling color data from controllers 2023-01-19 18:05:20 -06:00
Narr the Reg a4074001fe core: hid: Migrate ring from emulated devices to emulated controller 2023-01-19 18:05:20 -06:00
Narr the Reg 18c9f8eeed yuzu: Update controller colors and button names 2023-01-19 18:05:20 -06:00
Narr the Reg 2d802893e7 input_common: Disable SDL driver with switch controllers 2023-01-19 18:05:20 -06:00
Narr the Reg d80e6c399b input_common: Initial skeleton for custom joycon driver 2023-01-19 18:05:20 -06:00
liamwhite 475370c8f8 Merge pull request #9556 from vonchenplus/draw_texture
video_core: Implement maxwell3d draw texture method
2023-01-19 14:58:53 -05:00
bunnei 9ca3a4758a Merge pull request #9623 from liamwhite/wp-oops
memory: fix watchpoint use when fastmem is enabled
2023-01-19 10:50:21 -08:00
Jonas Gutenschwager 4653effad8 add volume quicksetting with volume slider 2023-01-19 15:13:23 +01:00
Andrea Pappacoda 9f08b3c3c9 fix(dist): wrap screenshots in <image> tags
The [appstream] spec says that <screenshot/> tags must be wrapped in
either <image/> or <video/> tags, so this patch does just that.

[appstream]: https://freedesktop.org/software/appstream/docs/chap-Metadata.html#tag-screenshots
2023-01-19 10:13:30 +01:00
Narr the Reg 67c3c65f7b Merge pull request #9638 from Kelebek1/firmware4
Demote maxwell3d Firmware4 call log to debug
2023-01-18 23:15:22 -06:00
bunnei 413df0811d Merge pull request #9619 from liamwhite/timing-spaghetti
timing: wait for completion on unregister
2023-01-18 15:13:38 -08:00
german77 db6cb9cc0a input_common: reset sdl motion if data is invalid 2023-01-18 10:05:55 -06:00
Jonas Gutenschwager 887ed5c0e2 fix format 2023-01-18 15:49:47 +01:00
bunnei 82e2ac6026 Merge pull request #9615 from merryhime/upsample-ob1
audio_core: Corrective fixes to upsampler
2023-01-17 23:34:12 -08:00
bunnei 1551f97950 Merge pull request #9608 from liamwhite/fps
nvnflinger: correct swap interval handling
2023-01-17 23:13:47 -08:00
Kelebek1 5a106cf11e Demote maxwell3d Firmware4 call log to debug 2023-01-18 01:59:11 +00:00
Jonas Gutenschwager 83754e4789 allow volume up/down hotkeys to be repeated 2023-01-18 00:39:31 +01:00
bunnei 28fde29924 Merge pull request #9612 from goldenx86/1.5xScaler
1.5X, 7X, 8X resolution scaler options
2023-01-16 17:49:06 -08:00
bunnei 58a10ed5d0 Merge pull request #9622 from merryhime/dynarmic
externals: Update dynarmic to 6.4.4
2023-01-15 23:22:54 -08:00
Feng Chen 9fc7ca1731 Address feedback 2023-01-16 10:27:57 +08:00
Liam f1a0ce0e70 memory: fix watchpoint use when fastmem is enabled 2023-01-15 10:24:31 -05:00
Merry 2817af0961 externals: Update dynarmic to 6.4.4 2023-01-15 02:31:00 +00:00
Liam 0953cdd271 timing: wait for completion on unregister 2023-01-14 15:48:01 -05:00
Kelebek1 42b16bb33a Be careful of mangled out of bounds read 2023-01-14 19:53:55 +00:00
german77 50c86b3c2a core: hid: Fix stick minimum range 2023-01-14 11:53:43 -06:00
Merry a0e8e5b22e upsample: Fix coefficient format 2023-01-14 17:09:03 +00:00
Merry 122a8faa38 audio_core: Fix off-by-one error in upsampler 2023-01-14 15:19:11 +00:00
Kelebek1 ce0b8d618d Move demangle impl to cpp 2023-01-14 05:12:41 +00:00
Kelebek1 80a55c1663 Add stacktrace symbol demangling 2023-01-14 04:43:21 +00:00
Matías Locatti d7dbd8e774 Update settings.h 2023-01-13 04:56:25 -03:00
Matías Locatti 4294429a07 CPP 2023-01-13 04:55:26 -03:00
Matías Locatti bb2aec00a2 UI change 2023-01-13 04:54:29 -03:00
Matías Locatti 3ba53f2511 1.5X resolution scaler option 2023-01-13 02:34:24 -03:00
Liam e9c3d16f6f debugger: add host fastmem pointer fetch command 2023-01-12 18:35:14 -05:00
Liam 2f2ef5b147 nvnflinger: correct swap interval handling 2023-01-11 22:05:08 -05:00
bunnei 0e8f98a441 Merge pull request #9605 from german77/mouse_mapping
yuzu: Read mouse scroll
2023-01-10 17:32:58 -08:00
Narr the Reg 87b02f78e1 yuzu: Read mouse wheel input 2023-01-10 18:20:58 -06:00
Morph c277dad25f Merge pull request #9596 from liamwhite/mvk
MoltenVK: restrict number of vertex attributes/bindings to 16
2023-01-10 18:11:44 -05:00
liamwhite cbcf210c19 Merge pull request #9582 from yuzu-emu/revert-9518-revert-9504-pg2
Revert "Revert "k_page_group: synchronize""
2023-01-10 15:27:33 -05:00
liamwhite 0eae0b6803 Merge pull request #9601 from liamwhite/it-never-ends
qt: unlock during signal emission
2023-01-10 15:27:12 -05:00
liamwhite 74404261d2 Merge pull request #9598 from liamwhite/indirect
vulkan_common: fix indirect draw with count
2023-01-10 15:27:02 -05:00
liamwhite e2c68edd35 Merge pull request #9595 from liamwhite/per-game
qt: fix configuration weirdness on turbo
2023-01-10 15:26:49 -05:00
liamwhite 9f974ea818 Merge pull request #9565 from MonsterDruide1/tas-multiplayer-lengths
TAS: Show all script lengths for multiplayer
2023-01-10 15:26:36 -05:00
Liam 385ddef8c3 qt: unlock during signal emission 2023-01-10 12:46:01 -05:00
Liam fa8581e900 vulkan_common: fix indirect draw with count 2023-01-10 09:43:36 -05:00
TellowKrinkle eaf425bd32 MoltenVK: restrict number of vertex attributes/bindings to 16 2023-01-09 19:01:09 -05:00
Liam 1caa84e652 qt: fix configuration weirdness on turbo 2023-01-09 17:54:49 -05:00
UltraHDR fda0e7e989 macOS: Make Yuzu show up in the Launchpad Games folder (#9594)
https://developer.apple.com/documentation/bundleresources/information_property_list/lsapplicationcategorytype
This makes it show up in the Launchpad Games folder
2023-01-09 16:43:45 -05:00
Morph 6bf1436f5c Merge pull request #9589 from liamwhite/default
renderer_vulkan: disable turbo by default
2023-01-09 16:23:24 -05:00
Morph ffb12f4f9f Merge pull request #9581 from liamwhite/turbo2
renderer_vulkan: pause turbo submissions on inactive queue
2023-01-09 16:23:16 -05:00
Morph a4cd747122 Merge pull request #9530 from liamwhite/vk-feature-init
vulkan_device: refactor feature testing
2023-01-09 16:23:04 -05:00
Morph 3be8312120 Merge pull request #9569 from liamwhite/shutdown-wars
qt: additional fixes for reentrant shutdown
2023-01-09 16:21:27 -05:00
Liam 279005448a vulkan_device: refactor feature testing 2023-01-09 16:12:16 -05:00
Fernando S 948ac976d1 Merge pull request #9583 from FernandoS27/fuck-ogl-already
VideoCore: Fix OGL cache invalidation.
2023-01-08 14:05:29 -05:00
Liam 0df43e4e07 renderer_vulkan: disable turbo by default 2023-01-08 11:38:30 -05:00
Fernando Sahmkow efbb6fe288 VideoCore: Fix OGL cache invalidation. 2023-01-07 21:56:17 -05:00
bunnei a5693afa03 Revert "Revert "k_page_group: synchronize"" 2023-01-07 15:32:10 -08:00
bunnei 66e4a48b75 Merge pull request #9563 from german77/crash_not_allowed
input_common: Create an update engine
2023-01-07 13:41:27 -08:00
MonsterDruide1 115bf20448 TAS: Show all script lengths for multiplayer 2023-01-07 21:15:37 +01:00
liamwhite 926438b68d Merge pull request #9578 from bylaws/patch-2
Avoid OOB array access reading passthrough attr mask
2023-01-07 15:14:08 -05:00
Liam c19c8ac92c renderer_vulkan: pause turbo submissions on inactive queue 2023-01-07 14:35:11 -05:00
Billy Laws d34275a260 Avoid OOB array access reading passthrough attr mask
YFC 1.5 extended the size of the varying mask used to hold passthrough attrs without considering this
2023-01-07 18:38:21 +00:00
Narr the Reg 432d48d9c8 Merge pull request #9570 from liamwhite/less-clock-boost
renderer_vulkan: disable clock boost on unvalidated devices
2023-01-07 10:41:37 -06:00
Narr the Reg cc92b7fd94 Merge pull request #9573 from liamwhite/optional
vulkan_device: avoid attempt to access empty optional
2023-01-07 10:40:21 -06:00
Liam 444b25bae1 vulkan_device: avoid attempt to access empty optional 2023-01-06 21:23:21 -05:00
Liam 2e4dde12c7 renderer_vulkan: disable clock boost on unvalidated devices 2023-01-06 19:07:47 -05:00
Liam 9ed4c13758 qt: additional fixes for reentrant shutdown 2023-01-06 18:50:01 -05:00
liamwhite c0f17e1b27 Merge pull request #9567 from german77/antialias
opengl: Sanitize antialiasing config
2023-01-06 15:20:23 -05:00
Narr the Reg 4bda2b475f opengl: Sanitize antialiasing config 2023-01-06 13:42:20 -06:00
Fernando S 7ef897a277 Merge pull request #9566 from Wollnashorn/vulkan-cache-header-fix
video_core/vulkan: Fixed loading of Vulkan driver pipeline cache
2023-01-06 11:58:36 -05:00
Wollnashorn 457826a83b video_core/vulkan: Fixed loading of Vulkan driver pipeline cache
The header size of the Vulkan driver pipeline cache files was incorrectly in PipelineCache::LoadVulkanPipelineCache, for which the pipeline cache wasn't read correctly and got invalidated on each load.
2023-01-06 16:52:41 +01:00
Fernando S 8b251fc3f6 Merge pull request #9535 from bylaws/master
Port over several shader-compiler fixes from skyline
2023-01-06 10:06:45 -05:00
liamwhite 3c05988df2 Merge pull request #9561 from liamwhite/update-dynarmic
externals: update dynarmic, xbyak
2023-01-06 10:00:18 -05:00
liamwhite 6d74490139 Merge pull request #9558 from MonsterDruide1/network-timeout-noerror
net: Silently translate ETIMEDOUT network error
2023-01-06 10:00:09 -05:00
liamwhite 020dbcdbc7 Merge pull request #9552 from liamwhite/turbo
vulkan: implement 'turbo mode' clock booster
2023-01-06 09:59:59 -05:00
Fernando S 5bcbb8de45 Merge pull request #9559 from FernandoS27/cached-writes
VideoCore: Implement Cached Writes, use fastmem for reading GPU memory and eliminate old stuffs
2023-01-06 07:31:39 -05:00
liamwhite 990fe2b3fc Merge pull request #9564 from FernandoS27/oops-i-did-it-again
MacroHLE: eliminate 2 rushed macros.
2023-01-05 22:14:27 -05:00
Fernando Sahmkow f6245dc40a MacroHLE: eliminate 2 rushed macros. 2023-01-05 20:53:31 -05:00
Narr the Reg 8042ce7e19 input_common: Create an update engine 2023-01-05 19:24:29 -06:00
liamwhite eaca61e073 Merge pull request #9528 from liamwhite/mvk-nulldesc
renderer_vulkan: implement fallback path for null buffer descriptors
2023-01-05 18:31:55 -05:00
liamwhite 3e33a878dc Merge pull request #9536 from liamwhite/debug-utils
vulkan_common: unify VK_EXT_debug_utils and selection of validation layer
2023-01-05 18:31:45 -05:00
Liam 1ee0540f82 externals: update dynarmic, xbyak 2023-01-05 18:06:06 -05:00
Billy Laws 58fec43768 Run clang-format 2023-01-05 22:18:10 +00:00
Billy Laws 12b4c9c04c externals: Update sirit 2023-01-05 22:13:07 +00:00
Billy Laws 68ed60cee4 shader_recompiler: Fix shuffle partitioning for >64 invoc-per-subgroup GPUs
The existing implementation only supports 64 invoc-per-subgroup GPUs, and misbehaves on adreno when invocations need to be split into 4 emulated subgroups.
2023-01-05 22:13:07 +00:00
Billy Laws 6c812a0c84 Vulkan, OpenGL: Hook up geometry shader passthrough emulation 2023-01-05 22:13:07 +00:00
Billy Laws 625a4af73a shader_recompiler: Add support for lowering geometry passthrough
Reuses most of the existing code for generating the gl_Layer passthrough. Fixes geometry in Nier: Automata on GPUs without HW passthrough support.
2023-01-05 22:13:07 +00:00
Billy Laws 9e2997c4b6 Vulkan, OpenGL: Hook up storage buffer alignment code 2023-01-05 22:13:07 +00:00
Billy Laws 8804a4eb23 shader_recompiler: Align SSBO offsets to meet host requirements
We can take advantage of SSBO addresses being passed in a constant bufer to account for the extra alignment requirements in the shader itself.
2023-01-05 22:13:07 +00:00
Billy Laws 3f0985c7b0 shader_recompiler: SPIRV: Only enable int64 feature when supported 2023-01-05 22:13:07 +00:00
Billy Laws c1cc99584c shader_recompiler: Add comparison operators to descriptor types 2023-01-05 22:13:07 +00:00
Billy Laws bbfad79c89 Vulkan: Add a workaround for input_position on Adreno drivers
Adreno drivers will crash compiling geometry shaders if the input position is not wrapped in a gl_in struct.
2023-01-05 22:13:07 +00:00
Fernando S 1428451722 Merge pull request #9527 from Wollnashorn/amd-cache-fix
video_core/vulkan: Implemented `VkPipelineCache` to store Vulkan pipelines
2023-01-05 16:38:07 -05:00
Wollnashorn e07976a22b video_core/vulkan: Vulkan driver pipelines now contain cache version
So that old cache can get deleted when the cache version changes and does not grow infinitely
2023-01-05 21:03:01 +01:00
Wollnashorn 9c9008ac81 video_core/vulkan: Driver pipeline cache will now be deleted with the shader cache 2023-01-05 21:03:01 +01:00
Wollnashorn 8945fafcc0 config: Set the Vulkan driver pipeline cache option to be global 2023-01-05 21:03:01 +01:00
Wollnashorn f2aa816679 video_core/vulkan: Added check if Vulkan pipeline path has been set 2023-01-05 21:03:01 +01:00
Wollnashorn f4626512ff config: Better wording for VK pipeline cache option and enable by default 2023-01-05 21:03:01 +01:00
Wollnashorn 67d4f190f7 yuzu-cmd: Removed use_vulkan_driver_pipeline_cache from default_ini.h
The addition of the use_vulkan_driver_pipeline_cache option into the default ini string literal caused the 16,384-byte limit of the MSVC compiler to be exceeded.
2023-01-05 21:03:01 +01:00
Wollnashorn 16809c1fa7 video_core/vulkan: Added VkPipelineCache to store Vulkan pipelines
As an optional feature which can be enabled in the advanced graphics configuration, all pipelines that get built at the initial shader loading are stored in a VkPipelineCache object and are dumped to the disk.

These vendor specific pipeline cache files are located at `/shader/GAME_ID/vulkan_pipelines.bin`. This feature was mainly added because of an issue with the AMD driver (see yuzu-emu#8507) causing invalidation of the cache files the driver builds automatically.
2023-01-05 21:02:44 +01:00
Fernando Sahmkow b56ad93bbc BufferBase: Don't ignore GPU pages. 2023-01-05 14:00:10 -05:00
Fernando Sahmkow 2d0c4f2b1d Fermi2D: sync cache flushes 2023-01-05 06:43:28 -05:00
Fernando Sahmkow af5ecb0b15 MemoryManager: use fastmem directly. 2023-01-05 06:06:33 -05:00
MonsterDruide1 688a9fbfa6 net: Silently translate ETIMEDOUT network error 2023-01-05 11:54:36 +01:00
Fernando Sahmkow 6c7eb81f7d video_core: Cache GPU internal writes. 2023-01-05 05:23:39 -05:00
liamwhite e82e3e06be Merge pull request #9557 from FernandoS27/ooops-i-killed-the-shitty-drivers
Vulkan: Fix drivers that don't support dynamic_state_2 up
2023-01-05 00:14:01 -05:00
Fernando Sahmkow 4d9af4a9d2 Vulkan: Fix drivers that don't support dynamic_state_2 up 2023-01-05 00:11:16 -05:00
Feng Chen 013b689153 video_core: Implement opengl/vulkan draw_texture 2023-01-05 12:41:33 +08:00
Feng Chen 1e8cee2ddf video_core: Implement maxwell3d draw texture method 2023-01-05 12:41:28 +08:00
Alexandre Bouvier 7a2bd13f5b cmake: support the standard cmake testing option 2023-01-05 05:03:34 +01:00
Alexandre Bouvier d0fe27708e tests: update catch2 to 3.0.1 2023-01-05 04:58:31 +01:00
Liam a4269c285a common: add setting for renderer clock workaround 2023-01-04 22:22:01 -05:00
Liam 301e9bbc03 vulkan: implement 'turbo mode' clock booster 2023-01-04 22:22:01 -05:00
Liam 66ae79de13 renderer_vulkan: implement fallback path for null descriptors 2023-01-04 22:14:01 -05:00
liamwhite b78328f19a Merge pull request #9501 from FernandoS27/yfc-rel-2
Yuzu Fried Chicken Part 1.5: MacroHLE Rework and Dynamic State
2023-01-04 21:20:00 -05:00
Fernando Sahmkow 3ecc03ec1b yuzu-ui: Add setting for disabling macro HLE 2023-01-04 14:56:52 -05:00
Fernando Sahmkow a0c697124c Video_core: Address feedback 2023-01-04 14:39:42 -05:00
Fernando Sahmkow 03ccd8bf43 Texture Cache: Implement async texture downloads. 2023-01-03 22:52:15 -05:00
liamwhite bbeb6e460c Merge pull request #9518 from gidoly/revert-9504-pg2
Revert "k_page_group: synchronize"
2023-01-03 21:40:57 -05:00
Fernando Sahmkow ddbf851ef6 Vulkan: Update blacklisting to latest driver versions. 2023-01-03 21:16:43 -05:00
Fernando Sahmkow a045e860dd ShaderCompiler: Inline driver specific constants. 2023-01-03 16:29:25 -05:00
Fernando Sahmkow b62ffb612d Vulkan: rework stencil tracking. 2023-01-03 16:29:16 -05:00
liamwhite 6f031f08fe Merge pull request #9547 from MonsterDruide1/tas-doesnt-flap
TAS: Immediately switch stick to TAS on input
2023-01-03 15:03:58 -05:00
MonsterDruide1 04cb05fce0 TAS: Immediately switch stick to TAS on input
Co-Authored-By: Narr the Reg <5944268+german77@users.noreply.github.com>
2023-01-03 20:08:25 +01:00
liamwhite a7e610403d Merge pull request #9542 from abouvier/cmake-module-path
cmake: move find-modules to root cmake dir
2023-01-02 13:45:36 -05:00
Alexandre Bouvier eceee8c3d9 cmake: move find-modules to root cmake dir 2023-01-02 18:22:07 +01:00
liamwhite 2b110d61e7 Merge pull request #9541 from abouvier/cmake-option
cmake: allow options shadowing with normal variables
2023-01-02 11:29:32 -05:00
liamwhite 6804a43f49 Merge pull request #9540 from MonsterDruide1/tas-sanitized-record
TAS: Record sanitized instead of raw stick inputs
2023-01-02 09:51:29 -05:00
bunnei 48bcb91a2e Merge pull request #9537 from abouvier/cmake-almost-quiet
cmake: improve find_package failure messages
2023-01-02 01:08:20 -08:00
bunnei 09c9be3703 Merge pull request #9543 from german77/nifm
service: nifm: Initialize request state
2023-01-01 21:38:43 -08:00
german77 80bcc18788 service: nifm: Initialize request state 2023-01-01 20:58:08 -06:00
german77 ebd811b535 service: nifm: Match documentation names 2023-01-01 20:58:01 -06:00
Alexandre Bouvier 306c791e67 cmake: allow options shadowing with normal variables 2023-01-02 02:43:38 +01:00
Alexandre Bouvier 1dfcf19c36 cmake: improve find_package failure messages 2023-01-02 02:27:25 +01:00
Liam f9c6d39a6c vulkan_common: blacklist radv from extended_dynamic_state2 on drivers before 22.3.1 2023-01-01 16:43:58 -05:00
Liam 4814d87385 video_core: fix build 2023-01-01 16:43:58 -05:00
Fernando Sahmkow d09aa0182f MacroHLE: Final cleanup and fixes. 2023-01-01 16:43:58 -05:00
Fernando Sahmkow 581a7d785b Rasterizer: Setup skeleton for Host Conditional rendering 2023-01-01 16:43:58 -05:00
Fernando Sahmkow 3630bfaef3 RasterizerMemory: Add filtering for flushing/invalidation operations. 2023-01-01 16:43:58 -05:00
Fernando Sahmkow 2793304117 Vulkan: Allow stagging buffer deferrals. 2023-01-01 16:43:58 -05:00
Fernando Sahmkow 8d694701bc MacroHLE: Add OpenGL Support 2023-01-01 16:43:58 -05:00
Fernando Sahmkow 4c82e47edd Vulkan: Add other additional pipeline specs 2023-01-01 16:43:58 -05:00
Fernando Sahmkow d33251db93 Vulkan: Implement Dynamic State 3 2023-01-01 16:43:58 -05:00
Fernando Sahmkow f800e485c9 Vulkan Implement Dynamic State 2 LogicOp and PatchVertices 2023-01-01 16:43:58 -05:00
Fernando Sahmkow c897c55e3c Vulkan: Implement Dynamic States 2 2023-01-01 16:43:57 -05:00
Fernando Sahmkow cb1497d0d7 DMAPusher: Improve collection of non executing methods 2023-01-01 16:43:57 -05:00
Fernando Sahmkow ce448ce770 Revert Buffer cache changes and setup additional macros. 2023-01-01 16:43:57 -05:00
Fernando Sahmkow 18637766ef MacroHLE: Reduce massive calculations on sizing estimation. 2023-01-01 16:43:57 -05:00
Fernando Sahmkow aad0cbf024 MacroHLE: Add HLE replacement for base vertex and base instance. 2023-01-01 16:43:57 -05:00
Fernando Sahmkow 93ac5a6a6d MacroHLE: Add Index Buffer size estimation. 2023-01-01 16:43:57 -05:00
Fernando Sahmkow c541559767 MacroHLE: Refactor MacroHLE system. 2023-01-01 16:43:57 -05:00
Fernando Sahmkow 0f89828073 MacroHLE: Implement DrawIndexedIndirect & DrawArraysIndirect. 2023-01-01 16:43:57 -05:00
Fernando Sahmkow a5a94f52ff MacroHLE: Add MultidrawIndirect HLE Macro. 2023-01-01 16:43:57 -05:00
MonsterDruide1 d46c9c4659 TAS: Record sanitized instead of raw stick inputs
Co-Authored-By: Narr the Reg <5944268+german77@users.noreply.github.com>
2023-01-01 22:39:18 +01:00
Mai a12a4f2a13 Merge pull request #9538 from merryhime/char-concat
vfs: Replace cstr concat with char concat
2023-01-01 20:00:46 +00:00
Merry bee395d2f0 vfs: Replace cstr concat with char concat 2023-01-01 18:52:02 +00:00
Liam aa13ee5c4a vulkan_common: unify VK_EXT_debug_utils and selection of validation layer 2023-01-01 11:59:47 -05:00
liamwhite 92103d4ff3 Merge pull request #9533 from merryhime/overcommit
host_memory: mmap changes for virtual_base
2023-01-01 10:24:07 -05:00
liamwhite b2d8bbe0e0 Merge pull request #9532 from zhaobot/tx-update-20230101024213
Update translations (2023-01-01)
2023-01-01 10:23:55 -05:00
liamwhite 0b228fde15 Merge pull request #9514 from ColinKinloch/en_gb
settings: warn on invalid regon/language combinations
2023-01-01 10:23:46 -05:00
The yuzu Community 72722986d0 Update translations (2023-01-01) 2023-01-01 02:42:48 +00:00
liamwhite 88f5d38b93 Merge pull request #9526 from ColinKinloch/choose_clang_format
ci: Allow setting clang-format binary
2022-12-30 15:20:20 -05:00
Colin Kinloch 5d36d4b143 ci: Allow setting clang-format binary 2022-12-30 14:29:41 +00:00
Colin Kinloch 28cfc2146f settings: comment language blocklist columns 2022-12-30 13:51:35 +00:00
bunnei 0ac34bd058 Merge pull request #9524 from bunnei/touch-button-crash-fix
core: hid: emulated_console: Avoid a crash if frontend does not configure touch_from_button_maps.
2022-12-30 03:26:41 -05:00
Colin Kinloch 8594f287b8 settings: added regon/language warning bounds check 2022-12-29 15:55:24 +00:00
gidoly 10eaf31af3 Revert "k_page_group: synchronize" 2022-12-29 17:39:42 +09:00
ameerj b0722591c9 hle_ipc: Use thread_local ReadBuffer 2022-12-28 18:46:54 -05:00
ameerj a1490d77ac hle_ipc: Rename ReadBufferSpan to ReadBuffer 2022-12-28 18:46:54 -05:00
ameerj 59c0f85407 hle_ipc: Rename ReadBuffer to ReadBufferCopy
Indicates explicitly that a copy is occurring
2022-12-28 18:46:54 -05:00
ameerj 7c1bf68bb4 bsd: Use std::span for read payloads
Allows the use of HLERequestContext::ReadBufferSpan
2022-12-28 18:46:54 -05:00
ameerj f517f82416 nvdrv: Use std::span for inputs
Allows the use of HLERequestContext::ReadBufferSpan
2022-12-28 18:46:53 -05:00
ameerj e7032d9e64 hidbus: Use ReadBufferSpan 2022-12-28 18:46:53 -05:00
Colin Kinloch 2ccf175324 settings: warn on invalid regon/language combinations 2022-12-28 20:34:28 +00:00
ameerj 32d01a39b0 nvflinger: Split Parcel class into InputParcel and OutputParcel
The usages of the Parcel class were already unique to either Read or Write operations.
Avoids needing a vector of the input payload for the InputParcel use-case, instead it can remain as a span.
2022-12-25 17:19:10 -05:00
ameerj 7ffd624248 service: Use ReadBufferSpan where it is trivial to do so 2022-12-25 17:04:02 -05:00
ameerj fbc375f0de fsp_srv: Use ReadBufferSpan 2022-12-25 13:21:15 -05:00
ameerj 9349f06963 hle_ipc: Add ReadBufferSpan function
Returns a std::span to the buffer address, rather than create a copy of the memory into a std::vector
2022-12-25 13:20:59 -05:00
490 changed files with 52260 additions and 26819 deletions
Regular → Executable
+1 -1
View File
@@ -10,7 +10,7 @@ if grep -nrI '\s$' src *.yml *.txt *.md Doxyfile .gitignore .gitmodules .ci* dis
fi
# Default clang-format points to default 3.5 version one
CLANG_FORMAT=clang-format-12
CLANG_FORMAT=${CLANG_FORMAT:-clang-format-15}
$CLANG_FORMAT --version
if [ "$TRAVIS_EVENT_TYPE" = "pull_request" ]; then
+9 -11
View File
@@ -2,15 +2,12 @@
# SPDX-License-Identifier: GPL-2.0-or-later
# Download all pull requests as patches that match a specific label
# Usage: python download-patches-by-label.py <Label to Match> <Root Path Folder to DL to>
# Usage: python apply-patches-by-label.py <Label to Match>
import requests, sys, json, urllib3.request, shutil, subprocess, os, traceback
import json, requests, subprocess, sys, traceback
tagline = sys.argv[2]
http = urllib3.PoolManager()
dl_list = {}
def check_individual(labels):
for label in labels:
if (label["name"] == sys.argv[1]):
@@ -18,8 +15,9 @@ def check_individual(labels):
return False
def do_page(page):
url = 'https://api.github.com/repos/yuzu-emu/yuzu/pulls?page=%s' % page
url = f"https://api.github.com/repos/yuzu-emu/yuzu/pulls?page={page}"
response = requests.get(url)
response.raise_for_status()
if (response.ok):
j = json.loads(response.content)
if j == []:
@@ -27,13 +25,13 @@ def do_page(page):
for pr in j:
if (check_individual(pr["labels"])):
pn = pr["number"]
print("Matched PR# %s" % pn)
print(subprocess.check_output(["git", "fetch", "https://github.com/yuzu-emu/yuzu.git", "pull/%s/head:pr-%s" % (pn, pn), "-f", "--no-recurse-submodules"]))
print(subprocess.check_output(["git", "merge", "--squash", "pr-%s" % pn]))
print(subprocess.check_output(["git", "commit", "-m\"Merge %s PR %s\"" % (tagline, pn)]))
print(f"Matched PR# {pn}")
print(subprocess.check_output(["git", "fetch", "https://github.com/yuzu-emu/yuzu.git", f"pull/{pn}/head:pr-{pn}", "-f", "--no-recurse-submodules"]))
print(subprocess.check_output(["git", "merge", "--squash", f"pr-{pn}"]))
print(subprocess.check_output(["git", "commit", f"-m\"Merge {tagline} PR {pn}\""]))
try:
for i in range(1,30):
for i in range(1,10):
do_page(i)
except:
traceback.print_exc(file=sys.stdout)
+19 -21
View File
@@ -3,17 +3,14 @@
cmake_minimum_required(VERSION 3.22)
# Dynarmic has cmake_minimum_required(3.12) and we may want to override
# some of its variables, which is only possible in 3.13+
set(CMAKE_POLICY_DEFAULT_CMP0077 NEW)
project(yuzu)
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMakeModules")
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/externals/cmake-modules")
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/externals/find-modules")
include(DownloadExternals)
include(CMakeDependentOption)
project(yuzu)
include(CTest)
# Set bundled sdl2/qt as dependent options.
# OFF by default, but if ENABLE_SDL2 and MSVC are true then ON
@@ -47,7 +44,7 @@ option(ENABLE_CUBEB "Enables the cubeb audio backend" ON)
option(USE_DISCORD_PRESENCE "Enables Discord Rich Presence" OFF)
option(YUZU_TESTS "Compile tests" ON)
option(YUZU_TESTS "Compile tests" "${BUILD_TESTING}")
option(YUZU_USE_PRECOMPILED_HEADERS "Use precompiled headers" ON)
@@ -207,46 +204,48 @@ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin)
# System imported libraries
# =======================================================================
find_package(enet 1.3)
# Enforce the search mode of non-required packages for better and shorter failure messages
find_package(enet 1.3 MODULE)
find_package(fmt 9 REQUIRED)
find_package(inih)
find_package(inih MODULE)
find_package(LLVM MODULE)
find_package(lz4 REQUIRED)
find_package(nlohmann_json 3.8 REQUIRED)
find_package(Opus 1.3)
find_package(Opus 1.3 MODULE)
find_package(ZLIB 1.2 REQUIRED)
find_package(zstd 1.5 REQUIRED)
if (NOT YUZU_USE_EXTERNAL_VULKAN_HEADERS)
find_package(Vulkan 1.3.238)
find_package(Vulkan 1.3.238 REQUIRED)
endif()
if (ENABLE_LIBUSB)
find_package(libusb 1.0.24)
find_package(libusb 1.0.24 MODULE)
endif()
if (ARCHITECTURE_x86 OR ARCHITECTURE_x86_64)
find_package(xbyak 6 QUIET)
find_package(xbyak 6 CONFIG)
endif()
if (ARCHITECTURE_x86_64 OR ARCHITECTURE_arm64)
find_package(dynarmic 6.4.0 QUIET)
find_package(dynarmic 6.4.0 CONFIG)
endif()
if (ENABLE_CUBEB)
find_package(cubeb QUIET)
find_package(cubeb CONFIG)
endif()
if (USE_DISCORD_PRESENCE)
find_package(DiscordRPC QUIET)
find_package(DiscordRPC MODULE)
endif()
if (ENABLE_WEB_SERVICE)
find_package(cpp-jwt 1.4 QUIET)
find_package(httplib 0.11 QUIET)
find_package(cpp-jwt 1.4 CONFIG)
find_package(httplib 0.11 MODULE)
endif()
if (YUZU_TESTS)
find_package(Catch2 2.13.7 REQUIRED)
find_package(Catch2 3.0.1 REQUIRED)
endif()
find_package(Boost 1.73.0 COMPONENTS context)
@@ -515,7 +514,7 @@ endif()
# against all the src files. This should be used before making a pull request.
# =======================================================================
set(CLANG_FORMAT_POSTFIX "-12")
set(CLANG_FORMAT_POSTFIX "-15")
find_program(CLANG_FORMAT
NAMES clang-format${CLANG_FORMAT_POSTFIX}
clang-format
@@ -610,7 +609,6 @@ if (YUZU_USE_FASTER_LD AND CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
endif()
endif()
enable_testing()
add_subdirectory(externals)
add_subdirectory(src)
+16
View File
@@ -0,0 +1,16 @@
# SPDX-FileCopyrightText: 2023 Alexandre Bouvier <contact@amb.tf>
#
# SPDX-License-Identifier: GPL-3.0-or-later
find_package(LLVM QUIET CONFIG)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(LLVM CONFIG_MODE)
if (LLVM_FOUND AND NOT TARGET LLVM::Demangle)
add_library(LLVM::Demangle INTERFACE IMPORTED)
llvm_map_components_to_libnames(LLVM_LIBRARIES demangle)
target_compile_definitions(LLVM::Demangle INTERFACE ${LLVM_DEFINITIONS})
target_include_directories(LLVM::Demangle INTERFACE ${LLVM_INCLUDE_DIRS})
target_link_libraries(LLVM::Demangle INTERFACE ${LLVM_LIBRARIES})
endif()
@@ -5,7 +5,7 @@
include(FindPackageHandleStandardArgs)
find_package(httplib QUIET CONFIG)
if (httplib_FOUND)
if (httplib_CONSIDERED_CONFIGS)
find_package_handle_standard_args(httplib CONFIG_MODE)
else()
find_package(PkgConfig QUIET)
@@ -4,7 +4,7 @@
include(FindPackageHandleStandardArgs)
find_package(lz4 QUIET CONFIG)
if (lz4_FOUND)
if (lz4_CONSIDERED_CONFIGS)
find_package_handle_standard_args(lz4 CONFIG_MODE)
else()
find_package(PkgConfig QUIET)
@@ -4,7 +4,7 @@
include(FindPackageHandleStandardArgs)
find_package(zstd QUIET CONFIG)
if (zstd_FOUND)
if (zstd_CONSIDERED_CONFIGS)
find_package_handle_standard_args(zstd CONFIG_MODE)
else()
find_package(PkgConfig QUIET)
+15
View File
@@ -0,0 +1,15 @@
---- LLVM Exceptions to the Apache 2.0 License ----
As an exception, if, as a result of your compiling your source code, portions
of this Software are embedded into an Object form of such source code, you
may redistribute such embedded portions in such Object form without complying
with the conditions of Sections 4(a), 4(b) and 4(d) of the License.
In addition, if you combine or link compiled forms of this Software with
software that is licensed under the GPLv2 ("Combined Software") and if a
court of competent jurisdiction determines that the patent provision (Section
3), the indemnity provision (Section 9) or other Section of the License
conflicts with the conditions of the GPLv2, you may retroactively and
prospectively choose to deem waived or otherwise exclude such Section(s) of
the License, but only in their entirety and only with respect to the Combined
Software.
+1125 -827
View File
File diff suppressed because it is too large Load Diff
+1127 -829
View File
File diff suppressed because it is too large Load Diff
+1123 -825
View File
File diff suppressed because it is too large Load Diff
+1167 -869
View File
File diff suppressed because it is too large Load Diff
+1126 -828
View File
File diff suppressed because it is too large Load Diff
+1158 -857
View File
File diff suppressed because it is too large Load Diff
+1133 -832
View File
File diff suppressed because it is too large Load Diff
+1125 -827
View File
File diff suppressed because it is too large Load Diff
+1180 -883
View File
File diff suppressed because it is too large Load Diff
+1127 -829
View File
File diff suppressed because it is too large Load Diff
+1130 -829
View File
File diff suppressed because it is too large Load Diff
+1125 -827
View File
File diff suppressed because it is too large Load Diff
+1133 -835
View File
File diff suppressed because it is too large Load Diff
+1295 -983
View File
File diff suppressed because it is too large Load Diff
+1154 -856
View File
File diff suppressed because it is too large Load Diff
+1137 -839
View File
File diff suppressed because it is too large Load Diff
+1221 -920
View File
File diff suppressed because it is too large Load Diff
+1133 -835
View File
File diff suppressed because it is too large Load Diff
+1135 -833
View File
File diff suppressed because it is too large Load Diff
+1204 -903
View File
File diff suppressed because it is too large Load Diff
+733 -599
View File
File diff suppressed because it is too large Load Diff
+733 -599
View File
File diff suppressed because it is too large Load Diff
+1164 -863
View File
File diff suppressed because it is too large Load Diff
+1132 -831
View File
File diff suppressed because it is too large Load Diff
+5 -5
View File
@@ -53,10 +53,10 @@ SPDX-License-Identifier: CC0-1.0
<developer_name>yuzu Emulator Team</developer_name>
<content_rating type="oars-1.0"/>
<screenshots>
<screenshot type="default">https://raw.githubusercontent.com/yuzu-emu/yuzu-emu.github.io/master/images/screenshots/001-Super%20Mario%20Odyssey%20.png</screenshot>
<screenshot>https://raw.githubusercontent.com/yuzu-emu/yuzu-emu.github.io/master/images/screenshots/004-The%20Legend%20of%20Zelda%20Skyward%20Sword%20HD.png</screenshot>
<screenshot>https://raw.githubusercontent.com/yuzu-emu/yuzu-emu.github.io/master/images/screenshots/007-Pokemon%20Sword.png</screenshot>
<screenshot>https://raw.githubusercontent.com/yuzu-emu/yuzu-emu.github.io/master/images/screenshots/010-Hyrule%20Warriors%20Age%20of%20Calamity.png</screenshot>
<screenshot>https://raw.githubusercontent.com/yuzu-emu/yuzu-emu.github.io/master/images/screenshots/039-Pok%C3%A9mon%20Mystery%20Dungeon%20Rescue%20Team%20DX.png.png.png</screenshot>
<screenshot type="default"><image>https://raw.githubusercontent.com/yuzu-emu/yuzu-emu.github.io/master/images/screenshots/001-Super%20Mario%20Odyssey%20.png</image></screenshot>
<screenshot><image>https://raw.githubusercontent.com/yuzu-emu/yuzu-emu.github.io/master/images/screenshots/004-The%20Legend%20of%20Zelda%20Skyward%20Sword%20HD.png</image></screenshot>
<screenshot><image>https://raw.githubusercontent.com/yuzu-emu/yuzu-emu.github.io/master/images/screenshots/007-Pokemon%20Sword.png</image></screenshot>
<screenshot><image>https://raw.githubusercontent.com/yuzu-emu/yuzu-emu.github.io/master/images/screenshots/010-Hyrule%20Warriors%20Age%20of%20Calamity.png</image></screenshot>
<screenshot><image>https://raw.githubusercontent.com/yuzu-emu/yuzu-emu.github.io/master/images/screenshots/039-Pok%C3%A9mon%20Mystery%20Dungeon%20Rescue%20Team%20DX.png.png.png</image></screenshot>
</screenshots>
</component>
+19 -10
View File
@@ -1,9 +1,12 @@
# SPDX-FileCopyrightText: 2016 Citra Emulator Project
# SPDX-License-Identifier: GPL-2.0-or-later
list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/CMakeModules")
list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/externals/find-modules")
include(DownloadExternals)
# Dynarmic has cmake_minimum_required(3.12) and we may want to override
# some of its variables, which is only possible in 3.13+
set(CMAKE_POLICY_DEFAULT_CMP0077 NEW)
# Disable tests in all externals supporting the standard option name
set(BUILD_TESTING OFF)
# xbyak
if ((ARCHITECTURE_x86 OR ARCHITECTURE_x86_64) AND NOT TARGET xbyak::xbyak)
@@ -12,8 +15,7 @@ endif()
# Dynarmic
if ((ARCHITECTURE_x86_64 OR ARCHITECTURE_arm64) AND NOT TARGET dynarmic::dynarmic)
set(DYNARMIC_NO_BUNDLED_FMT ON)
set(DYNARMIC_IGNORE_ASSERTS ON CACHE BOOL "" FORCE)
set(DYNARMIC_IGNORE_ASSERTS ON)
add_subdirectory(dynarmic EXCLUDE_FROM_ALL)
add_library(dynarmic::dynarmic ALIAS dynarmic)
endif()
@@ -60,10 +62,10 @@ if (YUZU_USE_EXTERNAL_SDL2)
Locale Power Render)
foreach(_SUB ${SDL_UNUSED_SUBSYSTEMS})
string(TOUPPER ${_SUB} _OPT)
option(SDL_${_OPT} "" OFF)
set(SDL_${_OPT} OFF)
endforeach()
option(HIDAPI "" ON)
set(HIDAPI ON)
endif()
set(SDL_STATIC ON)
set(SDL_SHARED OFF)
@@ -83,7 +85,7 @@ endif()
# Cubeb
if (ENABLE_CUBEB AND NOT TARGET cubeb::cubeb)
set(BUILD_TESTS OFF CACHE BOOL "")
set(BUILD_TESTS OFF)
add_subdirectory(cubeb EXCLUDE_FROM_ALL)
add_library(cubeb::cubeb ALIAS cubeb)
endif()
@@ -98,6 +100,7 @@ endif()
# Sirit
add_subdirectory(sirit EXCLUDE_FROM_ALL)
# httplib
if (ENABLE_WEB_SERVICE AND NOT TARGET httplib::httplib)
if (NOT WIN32)
find_package(OpenSSL 1.1)
@@ -108,7 +111,7 @@ if (ENABLE_WEB_SERVICE AND NOT TARGET httplib::httplib)
if (WIN32 OR NOT OPENSSL_FOUND)
# LibreSSL
set(LIBRESSL_SKIP_INSTALL ON CACHE BOOL "")
set(LIBRESSL_SKIP_INSTALL ON)
set(OPENSSLDIR "/etc/ssl/")
add_subdirectory(libressl EXCLUDE_FROM_ALL)
target_include_directories(ssl INTERFACE ./libressl/include)
@@ -118,7 +121,6 @@ if (ENABLE_WEB_SERVICE AND NOT TARGET httplib::httplib)
DEFINITION OPENSSL_LIBS)
endif()
# httplib
add_library(httplib INTERFACE)
target_include_directories(httplib INTERFACE ./cpp-httplib)
target_compile_definitions(httplib INTERFACE -DCPPHTTPLIB_OPENSSL_SUPPORT)
@@ -155,3 +157,10 @@ endif()
if (YUZU_USE_EXTERNAL_VULKAN_HEADERS)
add_subdirectory(Vulkan-Headers EXCLUDE_FROM_ALL)
endif()
if (NOT TARGET LLVM::Demangle)
add_library(demangle STATIC)
target_include_directories(demangle PUBLIC ./demangle)
target_sources(demangle PRIVATE demangle/ItaniumDemangle.cpp)
add_library(LLVM::Demangle ALIAS demangle)
endif()
+588
View File
@@ -0,0 +1,588 @@
//===------------------------- ItaniumDemangle.cpp ------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-FileCopyrightText: Part of the LLVM Project
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
// FIXME: (possibly) incomplete list of features that clang mangles that this
// file does not yet support:
// - C++ modules TS
#include "llvm/Demangle/Demangle.h"
#include "llvm/Demangle/ItaniumDemangle.h"
#include <cassert>
#include <cctype>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <functional>
#include <numeric>
#include <utility>
#include <vector>
using namespace llvm;
using namespace llvm::itanium_demangle;
constexpr const char *itanium_demangle::FloatData<float>::spec;
constexpr const char *itanium_demangle::FloatData<double>::spec;
constexpr const char *itanium_demangle::FloatData<long double>::spec;
// <discriminator> := _ <non-negative number> # when number < 10
// := __ <non-negative number> _ # when number >= 10
// extension := decimal-digit+ # at the end of string
const char *itanium_demangle::parse_discriminator(const char *first,
const char *last) {
// parse but ignore discriminator
if (first != last) {
if (*first == '_') {
const char *t1 = first + 1;
if (t1 != last) {
if (std::isdigit(*t1))
first = t1 + 1;
else if (*t1 == '_') {
for (++t1; t1 != last && std::isdigit(*t1); ++t1)
;
if (t1 != last && *t1 == '_')
first = t1 + 1;
}
}
} else if (std::isdigit(*first)) {
const char *t1 = first + 1;
for (; t1 != last && std::isdigit(*t1); ++t1)
;
if (t1 == last)
first = last;
}
}
return first;
}
#ifndef NDEBUG
namespace {
struct DumpVisitor {
unsigned Depth = 0;
bool PendingNewline = false;
template<typename NodeT> static constexpr bool wantsNewline(const NodeT *) {
return true;
}
static bool wantsNewline(NodeArray A) { return !A.empty(); }
static constexpr bool wantsNewline(...) { return false; }
template<typename ...Ts> static bool anyWantNewline(Ts ...Vs) {
for (bool B : {wantsNewline(Vs)...})
if (B)
return true;
return false;
}
void printStr(const char *S) { fprintf(stderr, "%s", S); }
void print(StringView SV) {
fprintf(stderr, "\"%.*s\"", (int)SV.size(), SV.begin());
}
void print(const Node *N) {
if (N)
N->visit(std::ref(*this));
else
printStr("<null>");
}
void print(NodeOrString NS) {
if (NS.isNode())
print(NS.asNode());
else if (NS.isString())
print(NS.asString());
else
printStr("NodeOrString()");
}
void print(NodeArray A) {
++Depth;
printStr("{");
bool First = true;
for (const Node *N : A) {
if (First)
print(N);
else
printWithComma(N);
First = false;
}
printStr("}");
--Depth;
}
// Overload used when T is exactly 'bool', not merely convertible to 'bool'.
void print(bool B) { printStr(B ? "true" : "false"); }
template <class T>
typename std::enable_if<std::is_unsigned<T>::value>::type print(T N) {
fprintf(stderr, "%llu", (unsigned long long)N);
}
template <class T>
typename std::enable_if<std::is_signed<T>::value>::type print(T N) {
fprintf(stderr, "%lld", (long long)N);
}
void print(ReferenceKind RK) {
switch (RK) {
case ReferenceKind::LValue:
return printStr("ReferenceKind::LValue");
case ReferenceKind::RValue:
return printStr("ReferenceKind::RValue");
}
}
void print(FunctionRefQual RQ) {
switch (RQ) {
case FunctionRefQual::FrefQualNone:
return printStr("FunctionRefQual::FrefQualNone");
case FunctionRefQual::FrefQualLValue:
return printStr("FunctionRefQual::FrefQualLValue");
case FunctionRefQual::FrefQualRValue:
return printStr("FunctionRefQual::FrefQualRValue");
}
}
void print(Qualifiers Qs) {
if (!Qs) return printStr("QualNone");
struct QualName { Qualifiers Q; const char *Name; } Names[] = {
{QualConst, "QualConst"},
{QualVolatile, "QualVolatile"},
{QualRestrict, "QualRestrict"},
};
for (QualName Name : Names) {
if (Qs & Name.Q) {
printStr(Name.Name);
Qs = Qualifiers(Qs & ~Name.Q);
if (Qs) printStr(" | ");
}
}
}
void print(SpecialSubKind SSK) {
switch (SSK) {
case SpecialSubKind::allocator:
return printStr("SpecialSubKind::allocator");
case SpecialSubKind::basic_string:
return printStr("SpecialSubKind::basic_string");
case SpecialSubKind::string:
return printStr("SpecialSubKind::string");
case SpecialSubKind::istream:
return printStr("SpecialSubKind::istream");
case SpecialSubKind::ostream:
return printStr("SpecialSubKind::ostream");
case SpecialSubKind::iostream:
return printStr("SpecialSubKind::iostream");
}
}
void print(TemplateParamKind TPK) {
switch (TPK) {
case TemplateParamKind::Type:
return printStr("TemplateParamKind::Type");
case TemplateParamKind::NonType:
return printStr("TemplateParamKind::NonType");
case TemplateParamKind::Template:
return printStr("TemplateParamKind::Template");
}
}
void newLine() {
printStr("\n");
for (unsigned I = 0; I != Depth; ++I)
printStr(" ");
PendingNewline = false;
}
template<typename T> void printWithPendingNewline(T V) {
print(V);
if (wantsNewline(V))
PendingNewline = true;
}
template<typename T> void printWithComma(T V) {
if (PendingNewline || wantsNewline(V)) {
printStr(",");
newLine();
} else {
printStr(", ");
}
printWithPendingNewline(V);
}
struct CtorArgPrinter {
DumpVisitor &Visitor;
template<typename T, typename ...Rest> void operator()(T V, Rest ...Vs) {
if (Visitor.anyWantNewline(V, Vs...))
Visitor.newLine();
Visitor.printWithPendingNewline(V);
int PrintInOrder[] = { (Visitor.printWithComma(Vs), 0)..., 0 };
(void)PrintInOrder;
}
};
template<typename NodeT> void operator()(const NodeT *Node) {
Depth += 2;
fprintf(stderr, "%s(", itanium_demangle::NodeKind<NodeT>::name());
Node->match(CtorArgPrinter{*this});
fprintf(stderr, ")");
Depth -= 2;
}
void operator()(const ForwardTemplateReference *Node) {
Depth += 2;
fprintf(stderr, "ForwardTemplateReference(");
if (Node->Ref && !Node->Printing) {
Node->Printing = true;
CtorArgPrinter{*this}(Node->Ref);
Node->Printing = false;
} else {
CtorArgPrinter{*this}(Node->Index);
}
fprintf(stderr, ")");
Depth -= 2;
}
};
}
void itanium_demangle::Node::dump() const {
DumpVisitor V;
visit(std::ref(V));
V.newLine();
}
#endif
namespace {
class BumpPointerAllocator {
struct BlockMeta {
BlockMeta* Next;
size_t Current;
};
static constexpr size_t AllocSize = 4096;
static constexpr size_t UsableAllocSize = AllocSize - sizeof(BlockMeta);
alignas(long double) char InitialBuffer[AllocSize];
BlockMeta* BlockList = nullptr;
void grow() {
char* NewMeta = static_cast<char *>(std::malloc(AllocSize));
if (NewMeta == nullptr)
std::terminate();
BlockList = new (NewMeta) BlockMeta{BlockList, 0};
}
void* allocateMassive(size_t NBytes) {
NBytes += sizeof(BlockMeta);
BlockMeta* NewMeta = reinterpret_cast<BlockMeta*>(std::malloc(NBytes));
if (NewMeta == nullptr)
std::terminate();
BlockList->Next = new (NewMeta) BlockMeta{BlockList->Next, 0};
return static_cast<void*>(NewMeta + 1);
}
public:
BumpPointerAllocator()
: BlockList(new (InitialBuffer) BlockMeta{nullptr, 0}) {}
void* allocate(size_t N) {
N = (N + 15u) & ~15u;
if (N + BlockList->Current >= UsableAllocSize) {
if (N > UsableAllocSize)
return allocateMassive(N);
grow();
}
BlockList->Current += N;
return static_cast<void*>(reinterpret_cast<char*>(BlockList + 1) +
BlockList->Current - N);
}
void reset() {
while (BlockList) {
BlockMeta* Tmp = BlockList;
BlockList = BlockList->Next;
if (reinterpret_cast<char*>(Tmp) != InitialBuffer)
std::free(Tmp);
}
BlockList = new (InitialBuffer) BlockMeta{nullptr, 0};
}
~BumpPointerAllocator() { reset(); }
};
class DefaultAllocator {
BumpPointerAllocator Alloc;
public:
void reset() { Alloc.reset(); }
template<typename T, typename ...Args> T *makeNode(Args &&...args) {
return new (Alloc.allocate(sizeof(T)))
T(std::forward<Args>(args)...);
}
void *allocateNodeArray(size_t sz) {
return Alloc.allocate(sizeof(Node *) * sz);
}
};
} // unnamed namespace
//===----------------------------------------------------------------------===//
// Code beyond this point should not be synchronized with libc++abi.
//===----------------------------------------------------------------------===//
using Demangler = itanium_demangle::ManglingParser<DefaultAllocator>;
char *llvm::itaniumDemangle(const char *MangledName, char *Buf,
size_t *N, int *Status) {
if (MangledName == nullptr || (Buf != nullptr && N == nullptr)) {
if (Status)
*Status = demangle_invalid_args;
return nullptr;
}
int InternalStatus = demangle_success;
Demangler Parser(MangledName, MangledName + std::strlen(MangledName));
OutputStream S;
Node *AST = Parser.parse();
if (AST == nullptr)
InternalStatus = demangle_invalid_mangled_name;
else if (!initializeOutputStream(Buf, N, S, 1024))
InternalStatus = demangle_memory_alloc_failure;
else {
assert(Parser.ForwardTemplateRefs.empty());
AST->print(S);
S += '\0';
if (N != nullptr)
*N = S.getCurrentPosition();
Buf = S.getBuffer();
}
if (Status)
*Status = InternalStatus;
return InternalStatus == demangle_success ? Buf : nullptr;
}
ItaniumPartialDemangler::ItaniumPartialDemangler()
: RootNode(nullptr), Context(new Demangler{nullptr, nullptr}) {}
ItaniumPartialDemangler::~ItaniumPartialDemangler() {
delete static_cast<Demangler *>(Context);
}
ItaniumPartialDemangler::ItaniumPartialDemangler(
ItaniumPartialDemangler &&Other)
: RootNode(Other.RootNode), Context(Other.Context) {
Other.Context = Other.RootNode = nullptr;
}
ItaniumPartialDemangler &ItaniumPartialDemangler::
operator=(ItaniumPartialDemangler &&Other) {
std::swap(RootNode, Other.RootNode);
std::swap(Context, Other.Context);
return *this;
}
// Demangle MangledName into an AST, storing it into this->RootNode.
bool ItaniumPartialDemangler::partialDemangle(const char *MangledName) {
Demangler *Parser = static_cast<Demangler *>(Context);
size_t Len = std::strlen(MangledName);
Parser->reset(MangledName, MangledName + Len);
RootNode = Parser->parse();
return RootNode == nullptr;
}
static char *printNode(const Node *RootNode, char *Buf, size_t *N) {
OutputStream S;
if (!initializeOutputStream(Buf, N, S, 128))
return nullptr;
RootNode->print(S);
S += '\0';
if (N != nullptr)
*N = S.getCurrentPosition();
return S.getBuffer();
}
char *ItaniumPartialDemangler::getFunctionBaseName(char *Buf, size_t *N) const {
if (!isFunction())
return nullptr;
const Node *Name = static_cast<const FunctionEncoding *>(RootNode)->getName();
while (true) {
switch (Name->getKind()) {
case Node::KAbiTagAttr:
Name = static_cast<const AbiTagAttr *>(Name)->Base;
continue;
case Node::KStdQualifiedName:
Name = static_cast<const StdQualifiedName *>(Name)->Child;
continue;
case Node::KNestedName:
Name = static_cast<const NestedName *>(Name)->Name;
continue;
case Node::KLocalName:
Name = static_cast<const LocalName *>(Name)->Entity;
continue;
case Node::KNameWithTemplateArgs:
Name = static_cast<const NameWithTemplateArgs *>(Name)->Name;
continue;
default:
return printNode(Name, Buf, N);
}
}
}
char *ItaniumPartialDemangler::getFunctionDeclContextName(char *Buf,
size_t *N) const {
if (!isFunction())
return nullptr;
const Node *Name = static_cast<const FunctionEncoding *>(RootNode)->getName();
OutputStream S;
if (!initializeOutputStream(Buf, N, S, 128))
return nullptr;
KeepGoingLocalFunction:
while (true) {
if (Name->getKind() == Node::KAbiTagAttr) {
Name = static_cast<const AbiTagAttr *>(Name)->Base;
continue;
}
if (Name->getKind() == Node::KNameWithTemplateArgs) {
Name = static_cast<const NameWithTemplateArgs *>(Name)->Name;
continue;
}
break;
}
switch (Name->getKind()) {
case Node::KStdQualifiedName:
S += "std";
break;
case Node::KNestedName:
static_cast<const NestedName *>(Name)->Qual->print(S);
break;
case Node::KLocalName: {
auto *LN = static_cast<const LocalName *>(Name);
LN->Encoding->print(S);
S += "::";
Name = LN->Entity;
goto KeepGoingLocalFunction;
}
default:
break;
}
S += '\0';
if (N != nullptr)
*N = S.getCurrentPosition();
return S.getBuffer();
}
char *ItaniumPartialDemangler::getFunctionName(char *Buf, size_t *N) const {
if (!isFunction())
return nullptr;
auto *Name = static_cast<FunctionEncoding *>(RootNode)->getName();
return printNode(Name, Buf, N);
}
char *ItaniumPartialDemangler::getFunctionParameters(char *Buf,
size_t *N) const {
if (!isFunction())
return nullptr;
NodeArray Params = static_cast<FunctionEncoding *>(RootNode)->getParams();
OutputStream S;
if (!initializeOutputStream(Buf, N, S, 128))
return nullptr;
S += '(';
Params.printWithComma(S);
S += ')';
S += '\0';
if (N != nullptr)
*N = S.getCurrentPosition();
return S.getBuffer();
}
char *ItaniumPartialDemangler::getFunctionReturnType(
char *Buf, size_t *N) const {
if (!isFunction())
return nullptr;
OutputStream S;
if (!initializeOutputStream(Buf, N, S, 128))
return nullptr;
if (const Node *Ret =
static_cast<const FunctionEncoding *>(RootNode)->getReturnType())
Ret->print(S);
S += '\0';
if (N != nullptr)
*N = S.getCurrentPosition();
return S.getBuffer();
}
char *ItaniumPartialDemangler::finishDemangle(char *Buf, size_t *N) const {
assert(RootNode != nullptr && "must call partialDemangle()");
return printNode(static_cast<Node *>(RootNode), Buf, N);
}
bool ItaniumPartialDemangler::hasFunctionQualifiers() const {
assert(RootNode != nullptr && "must call partialDemangle()");
if (!isFunction())
return false;
auto *E = static_cast<const FunctionEncoding *>(RootNode);
return E->getCVQuals() != QualNone || E->getRefQual() != FrefQualNone;
}
bool ItaniumPartialDemangler::isCtorOrDtor() const {
const Node *N = static_cast<const Node *>(RootNode);
while (N) {
switch (N->getKind()) {
default:
return false;
case Node::KCtorDtorName:
return true;
case Node::KAbiTagAttr:
N = static_cast<const AbiTagAttr *>(N)->Base;
break;
case Node::KFunctionEncoding:
N = static_cast<const FunctionEncoding *>(N)->getName();
break;
case Node::KLocalName:
N = static_cast<const LocalName *>(N)->Entity;
break;
case Node::KNameWithTemplateArgs:
N = static_cast<const NameWithTemplateArgs *>(N)->Name;
break;
case Node::KNestedName:
N = static_cast<const NestedName *>(N)->Name;
break;
case Node::KStdQualifiedName:
N = static_cast<const StdQualifiedName *>(N)->Child;
break;
}
}
return false;
}
bool ItaniumPartialDemangler::isFunction() const {
assert(RootNode != nullptr && "must call partialDemangle()");
return static_cast<const Node *>(RootNode)->getKind() ==
Node::KFunctionEncoding;
}
bool ItaniumPartialDemangler::isSpecialName() const {
assert(RootNode != nullptr && "must call partialDemangle()");
auto K = static_cast<const Node *>(RootNode)->getKind();
return K == Node::KSpecialName || K == Node::KCtorVtableSpecialName;
}
bool ItaniumPartialDemangler::isData() const {
return !isFunction() && !isSpecialName();
}
+104
View File
@@ -0,0 +1,104 @@
//===--- Demangle.h ---------------------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-FileCopyrightText: Part of the LLVM Project
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_DEMANGLE_DEMANGLE_H
#define LLVM_DEMANGLE_DEMANGLE_H
#include <cstddef>
#include <string>
namespace llvm {
/// This is a llvm local version of __cxa_demangle. Other than the name and
/// being in the llvm namespace it is identical.
///
/// The mangled_name is demangled into buf and returned. If the buffer is not
/// large enough, realloc is used to expand it.
///
/// The *status will be set to a value from the following enumeration
enum : int {
demangle_unknown_error = -4,
demangle_invalid_args = -3,
demangle_invalid_mangled_name = -2,
demangle_memory_alloc_failure = -1,
demangle_success = 0,
};
char *itaniumDemangle(const char *mangled_name, char *buf, size_t *n,
int *status);
enum MSDemangleFlags {
MSDF_None = 0,
MSDF_DumpBackrefs = 1 << 0,
MSDF_NoAccessSpecifier = 1 << 1,
MSDF_NoCallingConvention = 1 << 2,
MSDF_NoReturnType = 1 << 3,
MSDF_NoMemberType = 1 << 4,
};
char *microsoftDemangle(const char *mangled_name, char *buf, size_t *n,
int *status, MSDemangleFlags Flags = MSDF_None);
/// "Partial" demangler. This supports demangling a string into an AST
/// (typically an intermediate stage in itaniumDemangle) and querying certain
/// properties or partially printing the demangled name.
struct ItaniumPartialDemangler {
ItaniumPartialDemangler();
ItaniumPartialDemangler(ItaniumPartialDemangler &&Other);
ItaniumPartialDemangler &operator=(ItaniumPartialDemangler &&Other);
/// Demangle into an AST. Subsequent calls to the rest of the member functions
/// implicitly operate on the AST this produces.
/// \return true on error, false otherwise
bool partialDemangle(const char *MangledName);
/// Just print the entire mangled name into Buf. Buf and N behave like the
/// second and third parameters to itaniumDemangle.
char *finishDemangle(char *Buf, size_t *N) const;
/// Get the base name of a function. This doesn't include trailing template
/// arguments, ie for "a::b<int>" this function returns "b".
char *getFunctionBaseName(char *Buf, size_t *N) const;
/// Get the context name for a function. For "a::b::c", this function returns
/// "a::b".
char *getFunctionDeclContextName(char *Buf, size_t *N) const;
/// Get the entire name of this function.
char *getFunctionName(char *Buf, size_t *N) const;
/// Get the parameters for this function.
char *getFunctionParameters(char *Buf, size_t *N) const;
char *getFunctionReturnType(char *Buf, size_t *N) const;
/// If this function has any any cv or reference qualifiers. These imply that
/// the function is a non-static member function.
bool hasFunctionQualifiers() const;
/// If this symbol describes a constructor or destructor.
bool isCtorOrDtor() const;
/// If this symbol describes a function.
bool isFunction() const;
/// If this symbol describes a variable.
bool isData() const;
/// If this symbol is a <special-name>. These are generally implicitly
/// generated by the implementation, such as vtables and typeinfo names.
bool isSpecialName() const;
~ItaniumPartialDemangler();
private:
void *RootNode;
void *Context;
};
} // namespace llvm
#endif
+93
View File
@@ -0,0 +1,93 @@
//===--- DemangleConfig.h ---------------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-FileCopyrightText: Part of the LLVM Project
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file contains a variety of feature test macros copied from
// include/llvm/Support/Compiler.h so that LLVMDemangle does not need to take
// a dependency on LLVMSupport.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_DEMANGLE_COMPILER_H
#define LLVM_DEMANGLE_COMPILER_H
#ifndef __has_feature
#define __has_feature(x) 0
#endif
#ifndef __has_cpp_attribute
#define __has_cpp_attribute(x) 0
#endif
#ifndef __has_attribute
#define __has_attribute(x) 0
#endif
#ifndef __has_builtin
#define __has_builtin(x) 0
#endif
#ifndef DEMANGLE_GNUC_PREREQ
#if defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__GNUC_PATCHLEVEL__)
#define DEMANGLE_GNUC_PREREQ(maj, min, patch) \
((__GNUC__ << 20) + (__GNUC_MINOR__ << 10) + __GNUC_PATCHLEVEL__ >= \
((maj) << 20) + ((min) << 10) + (patch))
#elif defined(__GNUC__) && defined(__GNUC_MINOR__)
#define DEMANGLE_GNUC_PREREQ(maj, min, patch) \
((__GNUC__ << 20) + (__GNUC_MINOR__ << 10) >= ((maj) << 20) + ((min) << 10))
#else
#define DEMANGLE_GNUC_PREREQ(maj, min, patch) 0
#endif
#endif
#if __has_attribute(used) || DEMANGLE_GNUC_PREREQ(3, 1, 0)
#define DEMANGLE_ATTRIBUTE_USED __attribute__((__used__))
#else
#define DEMANGLE_ATTRIBUTE_USED
#endif
#if __has_builtin(__builtin_unreachable) || DEMANGLE_GNUC_PREREQ(4, 5, 0)
#define DEMANGLE_UNREACHABLE __builtin_unreachable()
#elif defined(_MSC_VER)
#define DEMANGLE_UNREACHABLE __assume(false)
#else
#define DEMANGLE_UNREACHABLE
#endif
#if __has_attribute(noinline) || DEMANGLE_GNUC_PREREQ(3, 4, 0)
#define DEMANGLE_ATTRIBUTE_NOINLINE __attribute__((noinline))
#elif defined(_MSC_VER)
#define DEMANGLE_ATTRIBUTE_NOINLINE __declspec(noinline)
#else
#define DEMANGLE_ATTRIBUTE_NOINLINE
#endif
#if !defined(NDEBUG)
#define DEMANGLE_DUMP_METHOD DEMANGLE_ATTRIBUTE_NOINLINE DEMANGLE_ATTRIBUTE_USED
#else
#define DEMANGLE_DUMP_METHOD DEMANGLE_ATTRIBUTE_NOINLINE
#endif
#if __cplusplus > 201402L && __has_cpp_attribute(fallthrough)
#define DEMANGLE_FALLTHROUGH [[fallthrough]]
#elif __has_cpp_attribute(gnu::fallthrough)
#define DEMANGLE_FALLTHROUGH [[gnu::fallthrough]]
#elif !__cplusplus
// Workaround for llvm.org/PR23435, since clang 3.6 and below emit a spurious
// error when __has_cpp_attribute is given a scoped attribute in C mode.
#define DEMANGLE_FALLTHROUGH
#elif __has_cpp_attribute(clang::fallthrough)
#define DEMANGLE_FALLTHROUGH [[clang::fallthrough]]
#else
#define DEMANGLE_FALLTHROUGH
#endif
#define DEMANGLE_NAMESPACE_BEGIN namespace llvm { namespace itanium_demangle {
#define DEMANGLE_NAMESPACE_END } }
#endif
File diff suppressed because it is too large Load Diff
+127
View File
@@ -0,0 +1,127 @@
//===--- StringView.h -------------------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-FileCopyrightText: Part of the LLVM Project
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// FIXME: Use std::string_view instead when we support C++17.
//
//===----------------------------------------------------------------------===//
#ifndef DEMANGLE_STRINGVIEW_H
#define DEMANGLE_STRINGVIEW_H
#include "DemangleConfig.h"
#include <algorithm>
#include <cassert>
#include <cstring>
DEMANGLE_NAMESPACE_BEGIN
class StringView {
const char *First;
const char *Last;
public:
static const size_t npos = ~size_t(0);
template <size_t N>
StringView(const char (&Str)[N]) : First(Str), Last(Str + N - 1) {}
StringView(const char *First_, const char *Last_)
: First(First_), Last(Last_) {}
StringView(const char *First_, size_t Len)
: First(First_), Last(First_ + Len) {}
StringView(const char *Str) : First(Str), Last(Str + std::strlen(Str)) {}
StringView() : First(nullptr), Last(nullptr) {}
StringView substr(size_t From) const {
return StringView(begin() + From, size() - From);
}
size_t find(char C, size_t From = 0) const {
size_t FindBegin = std::min(From, size());
// Avoid calling memchr with nullptr.
if (FindBegin < size()) {
// Just forward to memchr, which is faster than a hand-rolled loop.
if (const void *P = ::memchr(First + FindBegin, C, size() - FindBegin))
return size_t(static_cast<const char *>(P) - First);
}
return npos;
}
StringView substr(size_t From, size_t To) const {
if (To >= size())
To = size() - 1;
if (From >= size())
From = size() - 1;
return StringView(First + From, First + To);
}
StringView dropFront(size_t N = 1) const {
if (N >= size())
N = size();
return StringView(First + N, Last);
}
StringView dropBack(size_t N = 1) const {
if (N >= size())
N = size();
return StringView(First, Last - N);
}
char front() const {
assert(!empty());
return *begin();
}
char back() const {
assert(!empty());
return *(end() - 1);
}
char popFront() {
assert(!empty());
return *First++;
}
bool consumeFront(char C) {
if (!startsWith(C))
return false;
*this = dropFront(1);
return true;
}
bool consumeFront(StringView S) {
if (!startsWith(S))
return false;
*this = dropFront(S.size());
return true;
}
bool startsWith(char C) const { return !empty() && *begin() == C; }
bool startsWith(StringView Str) const {
if (Str.size() > size())
return false;
return std::equal(Str.begin(), Str.end(), begin());
}
const char &operator[](size_t Idx) const { return *(begin() + Idx); }
const char *begin() const { return First; }
const char *end() const { return Last; }
size_t size() const { return static_cast<size_t>(Last - First); }
bool empty() const { return First == Last; }
};
inline bool operator==(const StringView &LHS, const StringView &RHS) {
return LHS.size() == RHS.size() &&
std::equal(LHS.begin(), LHS.end(), RHS.begin());
}
DEMANGLE_NAMESPACE_END
#endif
+192
View File
@@ -0,0 +1,192 @@
//===--- Utility.h ----------------------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-FileCopyrightText: Part of the LLVM Project
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// Provide some utility classes for use in the demangler(s).
//
//===----------------------------------------------------------------------===//
#ifndef DEMANGLE_UTILITY_H
#define DEMANGLE_UTILITY_H
#include "StringView.h"
#include <cstdint>
#include <cstdlib>
#include <cstring>
#include <iterator>
#include <limits>
DEMANGLE_NAMESPACE_BEGIN
// Stream that AST nodes write their string representation into after the AST
// has been parsed.
class OutputStream {
char *Buffer;
size_t CurrentPosition;
size_t BufferCapacity;
// Ensure there is at least n more positions in buffer.
void grow(size_t N) {
if (N + CurrentPosition >= BufferCapacity) {
BufferCapacity *= 2;
if (BufferCapacity < N + CurrentPosition)
BufferCapacity = N + CurrentPosition;
Buffer = static_cast<char *>(std::realloc(Buffer, BufferCapacity));
if (Buffer == nullptr)
std::terminate();
}
}
void writeUnsigned(uint64_t N, bool isNeg = false) {
// Handle special case...
if (N == 0) {
*this << '0';
return;
}
char Temp[21];
char *TempPtr = std::end(Temp);
while (N) {
*--TempPtr = '0' + char(N % 10);
N /= 10;
}
// Add negative sign...
if (isNeg)
*--TempPtr = '-';
this->operator<<(StringView(TempPtr, std::end(Temp)));
}
public:
OutputStream(char *StartBuf, size_t Size)
: Buffer(StartBuf), CurrentPosition(0), BufferCapacity(Size) {}
OutputStream() = default;
void reset(char *Buffer_, size_t BufferCapacity_) {
CurrentPosition = 0;
Buffer = Buffer_;
BufferCapacity = BufferCapacity_;
}
/// If a ParameterPackExpansion (or similar type) is encountered, the offset
/// into the pack that we're currently printing.
unsigned CurrentPackIndex = std::numeric_limits<unsigned>::max();
unsigned CurrentPackMax = std::numeric_limits<unsigned>::max();
OutputStream &operator+=(StringView R) {
size_t Size = R.size();
if (Size == 0)
return *this;
grow(Size);
std::memmove(Buffer + CurrentPosition, R.begin(), Size);
CurrentPosition += Size;
return *this;
}
OutputStream &operator+=(char C) {
grow(1);
Buffer[CurrentPosition++] = C;
return *this;
}
OutputStream &operator<<(StringView R) { return (*this += R); }
OutputStream &operator<<(char C) { return (*this += C); }
OutputStream &operator<<(long long N) {
if (N < 0)
writeUnsigned(static_cast<unsigned long long>(-N), true);
else
writeUnsigned(static_cast<unsigned long long>(N));
return *this;
}
OutputStream &operator<<(unsigned long long N) {
writeUnsigned(N, false);
return *this;
}
OutputStream &operator<<(long N) {
return this->operator<<(static_cast<long long>(N));
}
OutputStream &operator<<(unsigned long N) {
return this->operator<<(static_cast<unsigned long long>(N));
}
OutputStream &operator<<(int N) {
return this->operator<<(static_cast<long long>(N));
}
OutputStream &operator<<(unsigned int N) {
return this->operator<<(static_cast<unsigned long long>(N));
}
size_t getCurrentPosition() const { return CurrentPosition; }
void setCurrentPosition(size_t NewPos) { CurrentPosition = NewPos; }
char back() const {
return CurrentPosition ? Buffer[CurrentPosition - 1] : '\0';
}
bool empty() const { return CurrentPosition == 0; }
char *getBuffer() { return Buffer; }
char *getBufferEnd() { return Buffer + CurrentPosition - 1; }
size_t getBufferCapacity() { return BufferCapacity; }
};
template <class T> class SwapAndRestore {
T &Restore;
T OriginalValue;
bool ShouldRestore = true;
public:
SwapAndRestore(T &Restore_) : SwapAndRestore(Restore_, Restore_) {}
SwapAndRestore(T &Restore_, T NewVal)
: Restore(Restore_), OriginalValue(Restore) {
Restore = std::move(NewVal);
}
~SwapAndRestore() {
if (ShouldRestore)
Restore = std::move(OriginalValue);
}
void shouldRestore(bool ShouldRestore_) { ShouldRestore = ShouldRestore_; }
void restoreNow(bool Force) {
if (!Force && !ShouldRestore)
return;
Restore = std::move(OriginalValue);
ShouldRestore = false;
}
SwapAndRestore(const SwapAndRestore &) = delete;
SwapAndRestore &operator=(const SwapAndRestore &) = delete;
};
inline bool initializeOutputStream(char *Buf, size_t *N, OutputStream &S,
size_t InitSize) {
size_t BufferSize;
if (Buf == nullptr) {
Buf = static_cast<char *>(std::malloc(InitSize));
if (Buf == nullptr)
return false;
BufferSize = InitSize;
} else
BufferSize = *N;
S.reset(Buf, BufferSize);
return true;
}
DEMANGLE_NAMESPACE_END
#endif
+11 -9
View File
@@ -48,7 +48,7 @@ public:
*
* @param out_buffers - The buffers which were registered.
*/
void RegisterBuffers(std::vector<AudioBuffer>& out_buffers) {
void RegisterBuffers(std::span<AudioBuffer> out_buffers, u32& out_size) {
std::scoped_lock l{lock};
const s32 to_register{std::min(std::min(appended_count, BufferAppendLimit),
BufferAppendLimit - registered_count)};
@@ -59,7 +59,7 @@ public:
index += N;
}
out_buffers.push_back(buffers[index]);
out_buffers[out_size++] = buffers[index];
registered_count++;
registered_index = (registered_index + 1) % append_limit;
@@ -162,7 +162,7 @@ public:
* @param max_buffers - Maximum number of buffers to released.
* @return The number of buffers released.
*/
u32 GetRegisteredAppendedBuffers(std::vector<AudioBuffer>& buffers_flushed, u32 max_buffers) {
u32 GetRegisteredAppendedBuffers(std::span<AudioBuffer> out_buffers, u32 max_buffers) {
std::scoped_lock l{lock};
if (registered_count + appended_count == 0) {
return 0;
@@ -174,19 +174,20 @@ public:
return 0;
}
u32 buffers_flushed{0};
while (registered_count > 0) {
auto index{registered_index - registered_count};
if (index < 0) {
index += N;
}
buffers_flushed.push_back(buffers[index]);
out_buffers[buffers_flushed++] = buffers[index];
registered_count--;
released_count++;
released_index = (released_index + 1) % append_limit;
if (buffers_flushed.size() >= buffers_to_flush) {
if (buffers_flushed >= buffers_to_flush) {
break;
}
}
@@ -197,18 +198,18 @@ public:
index += N;
}
buffers_flushed.push_back(buffers[index]);
out_buffers[buffers_flushed++] = buffers[index];
appended_count--;
released_count++;
released_index = (released_index + 1) % append_limit;
if (buffers_flushed.size() >= buffers_to_flush) {
if (buffers_flushed >= buffers_to_flush) {
break;
}
}
return static_cast<u32>(buffers_flushed.size());
return buffers_flushed;
}
/**
@@ -270,8 +271,9 @@ public:
*/
bool FlushBuffers(u32& buffers_released) {
std::scoped_lock l{lock};
std::vector<AudioBuffer> buffers_flushed{};
static Common::ScratchBuffer<AudioBuffer> buffers_flushed{};
buffers_flushed.resize_destructive(append_limit);
buffers_released = GetRegisteredAppendedBuffers(buffers_flushed, append_limit);
if (registered_count > 0) {
+9 -7
View File
@@ -6,6 +6,7 @@
#include "audio_core/device/audio_buffer.h"
#include "audio_core/device/device_session.h"
#include "audio_core/sink/sink_stream.h"
#include "common/scratch_buffer.h"
#include "core/core.h"
#include "core/core_timing.h"
#include "core/memory.h"
@@ -79,21 +80,22 @@ void DeviceSession::ClearBuffers() {
}
}
void DeviceSession::AppendBuffers(std::span<const AudioBuffer> buffers) const {
for (const auto& buffer : buffers) {
void DeviceSession::AppendBuffers(std::span<const AudioBuffer> buffers, u32 out_size) const {
static Common::ScratchBuffer<s16> samples{};
for (u32 i = 0; i < out_size; i++) {
Sink::SinkBuffer new_buffer{
.frames = buffer.size / (channel_count * sizeof(s16)),
.frames = buffers[i].size / (channel_count * sizeof(s16)),
.frames_played = 0,
.tag = buffer.tag,
.tag = buffers[i].tag,
.consumed = false,
};
if (type == Sink::StreamType::In) {
std::vector<s16> samples{};
stream->AppendBuffer(new_buffer, samples);
} else {
std::vector<s16> samples(buffer.size / sizeof(s16));
system.Memory().ReadBlockUnsafe(buffer.samples, samples.data(), buffer.size);
samples.resize_destructive(buffers[i].size / sizeof(s16));
system.Memory().ReadBlockUnsafe(buffers[i].samples, samples.data(), buffers[i].size);
stream->AppendBuffer(new_buffer, samples);
}
}
+1 -1
View File
@@ -62,7 +62,7 @@ public:
*
* @param buffers - The buffers to play.
*/
void AppendBuffers(std::span<const AudioBuffer> buffers) const;
void AppendBuffers(std::span<const AudioBuffer> buffers, u32 out_size) const;
/**
* (Audio In only) Pop samples from the backend, and write them back to this buffer's address.
+8 -6
View File
@@ -89,9 +89,10 @@ Result System::Start() {
session->Start();
state = State::Started;
std::vector<AudioBuffer> buffers_to_flush{};
buffers.RegisterBuffers(buffers_to_flush);
session->AppendBuffers(buffers_to_flush);
std::array<AudioBuffer, BufferAppendLimit> buffers_to_flush{};
u32 out_size{0};
buffers.RegisterBuffers(buffers_to_flush, out_size);
session->AppendBuffers(buffers_to_flush, out_size);
session->SetRingSize(static_cast<u32>(buffers_to_flush.size()));
return ResultSuccess;
@@ -134,9 +135,10 @@ bool System::AppendBuffer(const AudioInBuffer& buffer, const u64 tag) {
void System::RegisterBuffers() {
if (state == State::Started) {
std::vector<AudioBuffer> registered_buffers{};
buffers.RegisterBuffers(registered_buffers);
session->AppendBuffers(registered_buffers);
std::array<AudioBuffer, BufferAppendLimit> registered_buffers{};
u32 out_size{0};
buffers.RegisterBuffers(registered_buffers, out_size);
session->AppendBuffers(registered_buffers, out_size);
}
}
+8 -6
View File
@@ -89,9 +89,10 @@ Result System::Start() {
session->Start();
state = State::Started;
std::vector<AudioBuffer> buffers_to_flush{};
buffers.RegisterBuffers(buffers_to_flush);
session->AppendBuffers(buffers_to_flush);
std::array<AudioBuffer, BufferAppendLimit> buffers_to_flush{};
u32 out_size{0};
buffers.RegisterBuffers(buffers_to_flush, out_size);
session->AppendBuffers(buffers_to_flush, out_size);
session->SetRingSize(static_cast<u32>(buffers_to_flush.size()));
return ResultSuccess;
@@ -134,9 +135,10 @@ bool System::AppendBuffer(const AudioOutBuffer& buffer, u64 tag) {
void System::RegisterBuffers() {
if (state == State::Started) {
std::vector<AudioBuffer> registered_buffers{};
buffers.RegisterBuffers(registered_buffers);
session->AppendBuffers(registered_buffers);
std::array<AudioBuffer, BufferAppendLimit> registered_buffers{};
u32 out_size{0};
buffers.RegisterBuffers(registered_buffers, out_size);
session->AppendBuffers(registered_buffers, out_size);
}
}
@@ -8,6 +8,7 @@
#include "audio_core/renderer/command/resample/resample.h"
#include "common/fixed_point.h"
#include "common/logging/log.h"
#include "common/scratch_buffer.h"
#include "core/memory.h"
namespace AudioCore::AudioRenderer {
@@ -29,6 +30,7 @@ static u32 DecodePcm(Core::Memory::Memory& memory, std::span<s16> out_buffer,
const DecodeArg& req) {
constexpr s32 min{std::numeric_limits<s16>::min()};
constexpr s32 max{std::numeric_limits<s16>::max()};
static Common::ScratchBuffer<T> samples;
if (req.buffer == 0 || req.buffer_size == 0) {
return 0;
@@ -49,7 +51,7 @@ static u32 DecodePcm(Core::Memory::Memory& memory, std::span<s16> out_buffer,
const u64 size{channel_count * samples_to_decode};
const u64 size_bytes{size * sizeof(T)};
std::vector<T> samples(size);
samples.resize_destructive(size);
memory.ReadBlockUnsafe(source, samples.data(), size_bytes);
if constexpr (std::is_floating_point_v<T>) {
@@ -73,7 +75,7 @@ static u32 DecodePcm(Core::Memory::Memory& memory, std::span<s16> out_buffer,
}
const VAddr source{req.buffer + ((req.start_offset + req.offset) * sizeof(T))};
std::vector<T> samples(samples_to_decode);
samples.resize_destructive(samples_to_decode);
memory.ReadBlockUnsafe(source, samples.data(), samples_to_decode * sizeof(T));
if constexpr (std::is_floating_point_v<T>) {
@@ -103,6 +105,7 @@ static u32 DecodeAdpcm(Core::Memory::Memory& memory, std::span<s16> out_buffer,
const DecodeArg& req) {
constexpr u32 SamplesPerFrame{14};
constexpr u32 NibblesPerFrame{16};
static Common::ScratchBuffer<u8> wavebuffer;
if (req.buffer == 0 || req.buffer_size == 0) {
return 0;
@@ -138,7 +141,7 @@ static u32 DecodeAdpcm(Core::Memory::Memory& memory, std::span<s16> out_buffer,
}
const auto size{std::max((samples_to_process / 8U) * SamplesPerFrame, 8U)};
std::vector<u8> wavebuffer(size);
wavebuffer.resize_destructive(size);
memory.ReadBlockUnsafe(req.buffer + position_in_frame / 2, wavebuffer.data(),
wavebuffer.size());
@@ -227,6 +230,8 @@ static u32 DecodeAdpcm(Core::Memory::Memory& memory, std::span<s16> out_buffer,
* @param args - The wavebuffer data, and information for how to decode it.
*/
void DecodeFromWaveBuffers(Core::Memory::Memory& memory, const DecodeFromWaveBuffersArgs& args) {
Common::ScratchBuffer<s16> temp_buffer(TempBufferSize);
auto& voice_state{*args.voice_state};
auto remaining_sample_count{args.sample_count};
auto fraction{voice_state.fraction};
@@ -256,9 +261,8 @@ void DecodeFromWaveBuffers(Core::Memory::Memory& memory, const DecodeFromWaveBuf
bool is_buffer_starved{false};
u32 offset{voice_state.offset};
std::memset(temp_buffer.data(), 0, temp_buffer.size() * sizeof(s16));
auto output_buffer{args.output};
std::vector<s16> temp_buffer(TempBufferSize, 0);
while (remaining_sample_count > 0) {
const auto samples_to_write{std::min(remaining_sample_count, max_remaining_sample_count)};
@@ -8,6 +8,7 @@
#include "audio_core/renderer/adsp/command_list_processor.h"
#include "audio_core/renderer/command/effect/compressor.h"
#include "audio_core/renderer/effect/compressor.h"
#include "common/scratch_buffer.h"
namespace AudioCore::AudioRenderer {
@@ -44,8 +45,8 @@ static void InitializeCompressorEffect(const CompressorInfo::ParameterVersion2&
static void ApplyCompressorEffect(const CompressorInfo::ParameterVersion2& params,
CompressorInfo::State& state, bool enabled,
std::vector<std::span<const s32>> input_buffers,
std::vector<std::span<s32>> output_buffers, u32 sample_count) {
std::span<std::span<const s32>> input_buffers,
std::span<std::span<s32>> output_buffers, u32 sample_count) {
if (enabled) {
auto state_00{state.unk_00};
auto state_04{state.unk_04};
@@ -124,8 +125,10 @@ void CompressorCommand::Dump([[maybe_unused]] const ADSP::CommandListProcessor&
}
void CompressorCommand::Process(const ADSP::CommandListProcessor& processor) {
std::vector<std::span<const s32>> input_buffers(parameter.channel_count);
std::vector<std::span<s32>> output_buffers(parameter.channel_count);
static Common::ScratchBuffer<std::span<const s32>> input_buffers{};
static Common::ScratchBuffer<std::span<s32>> output_buffers{};
input_buffers.resize_destructive(parameter.channel_count);
output_buffers.resize_destructive(parameter.channel_count);
for (s16 i = 0; i < parameter.channel_count; i++) {
input_buffers[i] = processor.mix_buffers.subspan(inputs[i] * processor.sample_count,
@@ -3,6 +3,7 @@
#include "audio_core/renderer/adsp/command_list_processor.h"
#include "audio_core/renderer/command/effect/delay.h"
#include "common/scratch_buffer.h"
namespace AudioCore::AudioRenderer {
/**
@@ -74,8 +75,8 @@ static void InitializeDelayEffect(const DelayInfo::ParameterVersion1& params,
*/
template <size_t NumChannels>
static void ApplyDelay(const DelayInfo::ParameterVersion1& params, DelayInfo::State& state,
std::vector<std::span<const s32>>& inputs,
std::vector<std::span<s32>>& outputs, const u32 sample_count) {
std::span<std::span<const s32>> inputs, std::span<std::span<s32>> outputs,
const u32 sample_count) {
for (u32 sample_index = 0; sample_index < sample_count; sample_index++) {
std::array<Common::FixedPoint<50, 14>, NumChannels> input_samples{};
for (u32 channel = 0; channel < NumChannels; channel++) {
@@ -153,8 +154,8 @@ static void ApplyDelay(const DelayInfo::ParameterVersion1& params, DelayInfo::St
* @param sample_count - Number of samples to process.
*/
static void ApplyDelayEffect(const DelayInfo::ParameterVersion1& params, DelayInfo::State& state,
const bool enabled, std::vector<std::span<const s32>>& inputs,
std::vector<std::span<s32>>& outputs, const u32 sample_count) {
const bool enabled, std::span<std::span<const s32>> inputs,
std::span<std::span<s32>> outputs, const u32 sample_count) {
if (!IsChannelCountValid(params.channel_count)) {
LOG_ERROR(Service_Audio, "Invalid delay channels {}", params.channel_count);
@@ -208,8 +209,10 @@ void DelayCommand::Dump([[maybe_unused]] const ADSP::CommandListProcessor& proce
}
void DelayCommand::Process(const ADSP::CommandListProcessor& processor) {
std::vector<std::span<const s32>> input_buffers(parameter.channel_count);
std::vector<std::span<s32>> output_buffers(parameter.channel_count);
static Common::ScratchBuffer<std::span<const s32>> input_buffers{};
static Common::ScratchBuffer<std::span<s32>> output_buffers{};
input_buffers.resize_destructive(parameter.channel_count);
output_buffers.resize_destructive(parameter.channel_count);
for (s16 i = 0; i < parameter.channel_count; i++) {
input_buffers[i] = processor.mix_buffers.subspan(inputs[i] * processor.sample_count,
@@ -6,6 +6,7 @@
#include "audio_core/renderer/adsp/command_list_processor.h"
#include "audio_core/renderer/command/effect/i3dl2_reverb.h"
#include "common/polyfill_ranges.h"
#include "common/scratch_buffer.h"
namespace AudioCore::AudioRenderer {
@@ -408,8 +409,10 @@ void I3dl2ReverbCommand::Dump([[maybe_unused]] const ADSP::CommandListProcessor&
}
void I3dl2ReverbCommand::Process(const ADSP::CommandListProcessor& processor) {
std::vector<std::span<const s32>> input_buffers(parameter.channel_count);
std::vector<std::span<s32>> output_buffers(parameter.channel_count);
static Common::ScratchBuffer<std::span<const s32>> input_buffers{};
static Common::ScratchBuffer<std::span<s32>> output_buffers{};
input_buffers.resize_destructive(parameter.channel_count);
output_buffers.resize_destructive(parameter.channel_count);
for (u32 i = 0; i < parameter.channel_count; i++) {
input_buffers[i] = processor.mix_buffers.subspan(inputs[i] * processor.sample_count,
@@ -3,6 +3,7 @@
#include "audio_core/renderer/adsp/command_list_processor.h"
#include "audio_core/renderer/command/effect/light_limiter.h"
#include "common/scratch_buffer.h"
namespace AudioCore::AudioRenderer {
/**
@@ -47,8 +48,8 @@ static void InitializeLightLimiterEffect(const LightLimiterInfo::ParameterVersio
*/
static void ApplyLightLimiterEffect(const LightLimiterInfo::ParameterVersion2& params,
LightLimiterInfo::State& state, const bool enabled,
std::vector<std::span<const s32>>& inputs,
std::vector<std::span<s32>>& outputs, const u32 sample_count,
std::span<std::span<const s32>> inputs,
std::span<std::span<s32>> outputs, const u32 sample_count,
LightLimiterInfo::StatisticsInternal* statistics) {
constexpr s64 min{std::numeric_limits<s32>::min()};
constexpr s64 max{std::numeric_limits<s32>::max()};
@@ -147,8 +148,10 @@ void LightLimiterVersion1Command::Dump([[maybe_unused]] const ADSP::CommandListP
}
void LightLimiterVersion1Command::Process(const ADSP::CommandListProcessor& processor) {
std::vector<std::span<const s32>> input_buffers(parameter.channel_count);
std::vector<std::span<s32>> output_buffers(parameter.channel_count);
static Common::ScratchBuffer<std::span<const s32>> input_buffers{};
static Common::ScratchBuffer<std::span<s32>> output_buffers{};
input_buffers.resize_destructive(parameter.channel_count);
output_buffers.resize_destructive(parameter.channel_count);
for (u32 i = 0; i < parameter.channel_count; i++) {
input_buffers[i] = processor.mix_buffers.subspan(inputs[i] * processor.sample_count,
@@ -190,8 +193,10 @@ void LightLimiterVersion2Command::Dump([[maybe_unused]] const ADSP::CommandListP
}
void LightLimiterVersion2Command::Process(const ADSP::CommandListProcessor& processor) {
std::vector<std::span<const s32>> input_buffers(parameter.channel_count);
std::vector<std::span<s32>> output_buffers(parameter.channel_count);
static Common::ScratchBuffer<std::span<const s32>> input_buffers{};
static Common::ScratchBuffer<std::span<s32>> output_buffers{};
input_buffers.resize_destructive(parameter.channel_count);
output_buffers.resize_destructive(parameter.channel_count);
for (u32 i = 0; i < parameter.channel_count; i++) {
input_buffers[i] = processor.mix_buffers.subspan(inputs[i] * processor.sample_count,
@@ -7,6 +7,7 @@
#include "audio_core/renderer/adsp/command_list_processor.h"
#include "audio_core/renderer/command/effect/reverb.h"
#include "common/polyfill_ranges.h"
#include "common/scratch_buffer.h"
namespace AudioCore::AudioRenderer {
@@ -250,8 +251,8 @@ static Common::FixedPoint<50, 14> Axfx2AllPassTick(ReverbInfo::ReverbDelayLine&
*/
template <size_t NumChannels>
static void ApplyReverbEffect(const ReverbInfo::ParameterVersion2& params, ReverbInfo::State& state,
std::vector<std::span<const s32>>& inputs,
std::vector<std::span<s32>>& outputs, const u32 sample_count) {
std::span<std::span<const s32>> inputs,
std::span<std::span<s32>> outputs, const u32 sample_count) {
constexpr std::array<u8, ReverbInfo::MaxDelayTaps> OutTapIndexes1Ch{
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
};
@@ -368,8 +369,8 @@ static void ApplyReverbEffect(const ReverbInfo::ParameterVersion2& params, Rever
* @param sample_count - Number of samples to process.
*/
static void ApplyReverbEffect(const ReverbInfo::ParameterVersion2& params, ReverbInfo::State& state,
const bool enabled, std::vector<std::span<const s32>>& inputs,
std::vector<std::span<s32>>& outputs, const u32 sample_count) {
const bool enabled, std::span<std::span<const s32>> inputs,
std::span<std::span<s32>> outputs, const u32 sample_count) {
if (enabled) {
switch (params.channel_count) {
case 0:
@@ -411,8 +412,10 @@ void ReverbCommand::Dump([[maybe_unused]] const ADSP::CommandListProcessor& proc
}
void ReverbCommand::Process(const ADSP::CommandListProcessor& processor) {
std::vector<std::span<const s32>> input_buffers(parameter.channel_count);
std::vector<std::span<s32>> output_buffers(parameter.channel_count);
static Common::ScratchBuffer<std::span<const s32>> input_buffers{};
static Common::ScratchBuffer<std::span<s32>> output_buffers{};
input_buffers.resize_destructive(parameter.channel_count);
output_buffers.resize_destructive(parameter.channel_count);
for (u32 i = 0; i < parameter.channel_count; i++) {
input_buffers[i] = processor.mix_buffers.subspan(inputs[i] * processor.sample_count,
@@ -20,25 +20,25 @@ static void SrcProcessFrame(std::span<s32> output, std::span<const s32> input,
const u32 target_sample_count, const u32 source_sample_count,
UpsamplerState* state) {
constexpr u32 WindowSize = 10;
constexpr std::array<Common::FixedPoint<24, 8>, WindowSize> SincWindow1{
51.93359375f, -18.80078125f, 9.73046875f, -5.33203125f, 2.84375f,
-1.41015625f, 0.62109375f, -0.2265625f, 0.0625f, -0.00390625f,
constexpr std::array<Common::FixedPoint<17, 15>, WindowSize> WindowedSinc1{
0.95376587f, -0.12872314f, 0.060028076f, -0.032470703f, 0.017669678f,
-0.009124756f, 0.004272461f, -0.001739502f, 0.000579834f, -0.000091552734f,
};
constexpr std::array<Common::FixedPoint<24, 8>, WindowSize> SincWindow2{
105.35546875f, -24.52734375f, 11.9609375f, -6.515625f, 3.52734375f,
-1.796875f, 0.828125f, -0.32421875f, 0.1015625f, -0.015625f,
constexpr std::array<Common::FixedPoint<17, 15>, WindowSize> WindowedSinc2{
0.8230896f, -0.19161987f, 0.093444824f, -0.05090332f, 0.027557373f,
-0.014038086f, 0.0064697266f, -0.002532959f, 0.00079345703f, -0.00012207031f,
};
constexpr std::array<Common::FixedPoint<24, 8>, WindowSize> SincWindow3{
122.08203125f, -16.47656250f, 7.68359375f, -4.15625000f, 2.26171875f,
-1.16796875f, 0.54687500f, -0.22265625f, 0.07421875f, -0.01171875f,
constexpr std::array<Common::FixedPoint<17, 15>, WindowSize> WindowedSinc3{
0.6298828f, -0.19274902f, 0.09725952f, -0.05319214f, 0.028625488f,
-0.014373779f, 0.006500244f, -0.0024719238f, 0.0007324219f, -0.000091552734f,
};
constexpr std::array<Common::FixedPoint<24, 8>, WindowSize> SincWindow4{
23.73437500f, -9.62109375f, 5.07812500f, -2.78125000f, 1.46875000f,
-0.71484375f, 0.30859375f, -0.10546875f, 0.02734375f, 0.00000000f,
constexpr std::array<Common::FixedPoint<17, 15>, WindowSize> WindowedSinc4{
0.4057312f, -0.1468811f, 0.07601929f, -0.041656494f, 0.022216797f,
-0.011016846f, 0.004852295f, -0.0017700195f, 0.00048828125f, -0.000030517578f,
};
constexpr std::array<Common::FixedPoint<24, 8>, WindowSize> SincWindow5{
80.62500000f, -24.67187500f, 12.44921875f, -6.80859375f, 3.66406250f,
-1.83984375f, 0.83203125f, -0.31640625f, 0.09375000f, -0.01171875f,
constexpr std::array<Common::FixedPoint<17, 15>, WindowSize> WindowedSinc5{
0.1854248f, -0.075164795f, 0.03967285f, -0.021728516f, 0.011474609f,
-0.005584717f, 0.0024108887f, -0.0008239746f, 0.00021362305f, 0.0f,
};
if (!state->initialized) {
@@ -91,52 +91,31 @@ static void SrcProcessFrame(std::span<s32> output, std::span<const s32> input,
static_cast<u16>((state->history_output_index + 1) % UpsamplerState::HistorySize);
};
auto calculate_sample = [&state](std::span<const Common::FixedPoint<24, 8>> coeffs1,
std::span<const Common::FixedPoint<24, 8>> coeffs2) -> s32 {
auto calculate_sample = [&state](std::span<const Common::FixedPoint<17, 15>> coeffs1,
std::span<const Common::FixedPoint<17, 15>> coeffs2) -> s32 {
auto output_index{state->history_output_index};
auto start_pos{output_index - state->history_start_index + 1U};
auto end_pos{10U};
u64 result{0};
if (start_pos < 10) {
end_pos = start_pos;
}
for (u32 coeff_index = 0; coeff_index < 10; coeff_index++) {
result += static_cast<u64>(state->history[output_index].to_raw()) *
coeffs1[coeff_index].to_raw();
u64 prev_contrib{0};
u32 coeff_index{0};
for (; coeff_index < end_pos; coeff_index++, output_index--) {
prev_contrib += static_cast<u64>(state->history[output_index].to_raw()) *
coeffs1[coeff_index].to_raw();
}
auto end_index{state->history_end_index};
for (; start_pos < 9; start_pos++, coeff_index++, end_index--) {
prev_contrib += static_cast<u64>(state->history[end_index].to_raw()) *
coeffs1[coeff_index].to_raw();
output_index = output_index == state->history_start_index ? state->history_end_index
: output_index - 1;
}
output_index =
static_cast<u16>((state->history_output_index + 1) % UpsamplerState::HistorySize);
start_pos = state->history_end_index - output_index + 1U;
end_pos = 10U;
if (start_pos < 10) {
end_pos = start_pos;
for (u32 coeff_index = 0; coeff_index < 10; coeff_index++) {
result += static_cast<u64>(state->history[output_index].to_raw()) *
coeffs2[coeff_index].to_raw();
output_index = output_index == state->history_end_index ? state->history_start_index
: output_index + 1;
}
u64 next_contrib{0};
coeff_index = 0;
for (; coeff_index < end_pos; coeff_index++, output_index++) {
next_contrib += static_cast<u64>(state->history[output_index].to_raw()) *
coeffs2[coeff_index].to_raw();
}
auto start_index{state->history_start_index};
for (; start_pos < 9; start_pos++, start_index++, coeff_index++) {
next_contrib += static_cast<u64>(state->history[start_index].to_raw()) *
coeffs2[coeff_index].to_raw();
}
return static_cast<s32>(((prev_contrib >> 15) + (next_contrib >> 15)) >> 8);
return static_cast<s32>(result >> (8 + 15));
};
switch (state->ratio.to_int_floor()) {
@@ -150,23 +129,23 @@ static void SrcProcessFrame(std::span<s32> output, std::span<const s32> input,
break;
case 1:
output[write_index] = calculate_sample(SincWindow3, SincWindow4);
output[write_index] = calculate_sample(WindowedSinc1, WindowedSinc5);
break;
case 2:
output[write_index] = calculate_sample(SincWindow2, SincWindow1);
output[write_index] = calculate_sample(WindowedSinc2, WindowedSinc4);
break;
case 3:
output[write_index] = calculate_sample(SincWindow5, SincWindow5);
output[write_index] = calculate_sample(WindowedSinc3, WindowedSinc3);
break;
case 4:
output[write_index] = calculate_sample(SincWindow1, SincWindow2);
output[write_index] = calculate_sample(WindowedSinc4, WindowedSinc2);
break;
case 5:
output[write_index] = calculate_sample(SincWindow4, SincWindow3);
output[write_index] = calculate_sample(WindowedSinc5, WindowedSinc1);
break;
}
state->sample_index = static_cast<u8>((state->sample_index + 1) % 6);
@@ -183,11 +162,11 @@ static void SrcProcessFrame(std::span<s32> output, std::span<const s32> input,
break;
case 1:
output[write_index] = calculate_sample(SincWindow2, SincWindow1);
output[write_index] = calculate_sample(WindowedSinc2, WindowedSinc4);
break;
case 2:
output[write_index] = calculate_sample(SincWindow1, SincWindow2);
output[write_index] = calculate_sample(WindowedSinc4, WindowedSinc2);
break;
}
state->sample_index = static_cast<u8>((state->sample_index + 1) % 3);
@@ -204,12 +183,12 @@ static void SrcProcessFrame(std::span<s32> output, std::span<const s32> input,
break;
case 1:
output[write_index] = calculate_sample(SincWindow1, SincWindow2);
output[write_index] = calculate_sample(WindowedSinc4, WindowedSinc2);
break;
case 2:
increment();
output[write_index] = calculate_sample(SincWindow2, SincWindow1);
output[write_index] = calculate_sample(WindowedSinc2, WindowedSinc4);
break;
}
state->sample_index = static_cast<u8>((state->sample_index + 1) % 3);
@@ -5,6 +5,7 @@
#include "audio_core/renderer/adsp/command_list_processor.h"
#include "audio_core/renderer/command/sink/circular_buffer.h"
#include "common/scratch_buffer.h"
#include "core/memory.h"
namespace AudioCore::AudioRenderer {
@@ -24,7 +25,9 @@ void CircularBufferSinkCommand::Process(const ADSP::CommandListProcessor& proces
constexpr s32 min{std::numeric_limits<s16>::min()};
constexpr s32 max{std::numeric_limits<s16>::max()};
std::vector<s16> output(processor.sample_count);
static Common::ScratchBuffer<s16> output{};
output.resize_destructive(processor.sample_count);
for (u32 channel = 0; channel < input_count; channel++) {
auto input{processor.mix_buffers.subspan(inputs[channel] * processor.sample_count,
processor.sample_count)};
@@ -33,7 +33,8 @@ void DeviceSinkCommand::Process(const ADSP::CommandListProcessor& processor) {
.consumed{false},
};
std::vector<s16> samples(out_buffer.frames * input_count);
static Common::ScratchBuffer<s16> samples{};
samples.resize_destructive(out_buffer.frames * input_count);
for (u32 channel = 0; channel < input_count; channel++) {
const auto offset{inputs[channel] * out_buffer.frames};
+20
View File
@@ -302,11 +302,21 @@ std::vector<std::string> ListCubebSinkDevices(bool capture) {
std::vector<std::string> device_list;
cubeb* ctx;
#ifdef _WIN32
auto com_init_result = CoInitializeEx(nullptr, COINIT_MULTITHREADED);
#endif
if (cubeb_init(&ctx, "yuzu Device Enumerator", nullptr) != CUBEB_OK) {
LOG_CRITICAL(Audio_Sink, "cubeb_init failed");
return {};
}
#ifdef _WIN32
if (SUCCEEDED(com_init_result)) {
CoUninitialize();
}
#endif
auto type{capture ? CUBEB_DEVICE_TYPE_INPUT : CUBEB_DEVICE_TYPE_OUTPUT};
cubeb_device_collection collection;
if (cubeb_enumerate_devices(ctx, type, &collection) != CUBEB_OK) {
@@ -329,12 +339,22 @@ std::vector<std::string> ListCubebSinkDevices(bool capture) {
u32 GetCubebLatency() {
cubeb* ctx;
#ifdef _WIN32
auto com_init_result = CoInitializeEx(nullptr, COINIT_MULTITHREADED);
#endif
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;
}
#ifdef _WIN32
if (SUCCEEDED(com_init_result)) {
CoUninitialize();
}
#endif
cubeb_stream_params params{};
params.rate = TargetSampleRate;
params.channels = 2;
+2 -1
View File
@@ -9,6 +9,7 @@
#include "audio_core/sink/sink.h"
#include "audio_core/sink/sink_stream.h"
#include "common/scratch_buffer.h"
namespace Core {
class System;
@@ -20,7 +21,7 @@ public:
explicit NullSinkStreamImpl(Core::System& system_, StreamType type_)
: SinkStream{system_, type_} {}
~NullSinkStreamImpl() override {}
void AppendBuffer(SinkBuffer&, std::vector<s16>&) override {}
void AppendBuffer(SinkBuffer&, Common::ScratchBuffer<s16>&) override {}
std::vector<s16> ReleaseBuffer(u64) override {
return {};
}
+5 -3
View File
@@ -17,7 +17,7 @@
namespace AudioCore::Sink {
void SinkStream::AppendBuffer(SinkBuffer& buffer, std::vector<s16>& samples) {
void SinkStream::AppendBuffer(SinkBuffer& buffer, Common::ScratchBuffer<s16>& samples) {
if (type == StreamType::In) {
queue.enqueue(buffer);
queued_buffers++;
@@ -71,7 +71,9 @@ void SinkStream::AppendBuffer(SinkBuffer& buffer, std::vector<s16>& samples) {
// We need moar samples! Not all games will provide 6 channel audio.
// TODO: Implement some upmixing here. Currently just passthrough, with other
// channels left as silence.
std::vector<s16> new_samples(samples.size() / system_channels * device_channels, 0);
static Common::ScratchBuffer<s16> new_samples{};
new_samples.resize_destructive(samples.size() / system_channels * device_channels);
std::memset(new_samples.data(), 0, new_samples.size() * sizeof(s16));
for (u32 read_index = 0, write_index = 0; read_index < samples.size();
read_index += system_channels, write_index += device_channels) {
@@ -100,7 +102,7 @@ void SinkStream::AppendBuffer(SinkBuffer& buffer, std::vector<s16>& samples) {
}
}
samples_buffer.Push(samples);
samples_buffer.Push(samples.data(), samples.size());
queue.enqueue(buffer);
queued_buffers++;
}
+2 -1
View File
@@ -14,6 +14,7 @@
#include "common/common_types.h"
#include "common/reader_writer_queue.h"
#include "common/ring_buffer.h"
#include "common/scratch_buffer.h"
namespace Core {
class System;
@@ -169,7 +170,7 @@ public:
* @param buffer - Audio buffer information to be queued.
* @param samples - The s16 samples to be queue for playback.
*/
virtual void AppendBuffer(SinkBuffer& buffer, std::vector<s16>& samples);
virtual void AppendBuffer(SinkBuffer& buffer, Common::ScratchBuffer<s16>& samples);
/**
* Release a buffer. Audio In only, will fill a buffer with recorded samples.
+4 -1
View File
@@ -38,6 +38,8 @@ add_library(common STATIC
common_precompiled_headers.h
common_types.h
concepts.h
demangle.cpp
demangle.h
div_ceil.h
dynamic_library.cpp
dynamic_library.h
@@ -97,6 +99,7 @@ add_library(common STATIC
point.h
precompiled_headers.h
quaternion.h
range_map.h
reader_writer_queue.h
ring_buffer.h
${CMAKE_CURRENT_BINARY_DIR}/scm_rev.cpp
@@ -174,7 +177,7 @@ 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 zstd::zstd)
target_link_libraries(common PRIVATE lz4::lz4 zstd::zstd LLVM::Demangle)
if (YUZU_USE_PRECOMPILED_HEADERS)
target_precompile_headers(common PRIVATE precompiled_headers.h)
+4 -3
View File
@@ -12,7 +12,8 @@
namespace Common {
template <typename VaType, size_t AddressSpaceBits>
concept AddressSpaceValid = std::is_unsigned_v<VaType> && sizeof(VaType) * 8 >= AddressSpaceBits;
concept AddressSpaceValid = std::is_unsigned_v<VaType> && sizeof(VaType) * 8 >=
AddressSpaceBits;
struct EmptyStruct {};
@@ -21,7 +22,7 @@ struct EmptyStruct {};
*/
template <typename VaType, VaType UnmappedVa, typename PaType, PaType UnmappedPa,
bool PaContigSplit, size_t AddressSpaceBits, typename ExtraBlockInfo = EmptyStruct>
requires AddressSpaceValid<VaType, AddressSpaceBits>
requires AddressSpaceValid<VaType, AddressSpaceBits>
class FlatAddressSpaceMap {
public:
/// The maximum VA that this AS can technically reach
@@ -109,7 +110,7 @@ private:
* initial, fast linear pass and a subsequent slower pass that iterates until it finds a free block
*/
template <typename VaType, VaType UnmappedVa, size_t AddressSpaceBits>
requires AddressSpaceValid<VaType, AddressSpaceBits>
requires AddressSpaceValid<VaType, AddressSpaceBits>
class FlatAllocator
: public FlatAddressSpaceMap<VaType, UnmappedVa, bool, false, false, AddressSpaceBits> {
private:
+9 -9
View File
@@ -10,7 +10,7 @@
namespace Common {
template <typename T>
requires std::is_unsigned_v<T>
requires std::is_unsigned_v<T>
[[nodiscard]] constexpr T AlignUp(T value, size_t size) {
auto mod{static_cast<T>(value % size)};
value -= mod;
@@ -18,31 +18,31 @@ requires std::is_unsigned_v<T>
}
template <typename T>
requires std::is_unsigned_v<T>
requires std::is_unsigned_v<T>
[[nodiscard]] constexpr T AlignUpLog2(T value, size_t align_log2) {
return static_cast<T>((value + ((1ULL << align_log2) - 1)) >> align_log2 << align_log2);
}
template <typename T>
requires std::is_unsigned_v<T>
requires std::is_unsigned_v<T>
[[nodiscard]] constexpr T AlignDown(T value, size_t size) {
return static_cast<T>(value - value % size);
}
template <typename T>
requires std::is_unsigned_v<T>
requires std::is_unsigned_v<T>
[[nodiscard]] constexpr bool Is4KBAligned(T value) {
return (value & 0xFFF) == 0;
}
template <typename T>
requires std::is_unsigned_v<T>
requires std::is_unsigned_v<T>
[[nodiscard]] constexpr bool IsWordAligned(T value) {
return (value & 0b11) == 0;
}
template <typename T>
requires std::is_integral_v<T>
requires std::is_integral_v<T>
[[nodiscard]] constexpr bool IsAligned(T value, size_t alignment) {
using U = typename std::make_unsigned_t<T>;
const U mask = static_cast<U>(alignment - 1);
@@ -50,7 +50,7 @@ requires std::is_integral_v<T>
}
template <typename T, typename U>
requires std::is_integral_v<T>
requires std::is_integral_v<T>
[[nodiscard]] constexpr T DivideUp(T x, U y) {
return (x + (y - 1)) / y;
}
@@ -73,11 +73,11 @@ public:
constexpr AlignmentAllocator(const AlignmentAllocator<T2, Align>&) noexcept {}
[[nodiscard]] T* allocate(size_type n) {
return static_cast<T*>(::operator new (n * sizeof(T), std::align_val_t{Align}));
return static_cast<T*>(::operator new(n * sizeof(T), std::align_val_t{Align}));
}
void deallocate(T* p, size_type n) {
::operator delete (p, n * sizeof(T), std::align_val_t{Align});
::operator delete(p, n * sizeof(T), std::align_val_t{Align});
}
template <typename T2>
+1 -1
View File
@@ -75,7 +75,7 @@ extern "C" void AnnotateHappensAfter(const char*, int, void*);
#if defined(AE_VCPP) || defined(AE_ICC)
#define AE_FORCEINLINE __forceinline
#elif defined(AE_GCC)
//#define AE_FORCEINLINE __attribute__((always_inline))
// #define AE_FORCEINLINE __attribute__((always_inline))
#define AE_FORCEINLINE inline
#else
#define AE_FORCEINLINE inline
+3 -3
View File
@@ -45,19 +45,19 @@ template <typename T>
}
template <typename T>
requires std::is_unsigned_v<T>
requires std::is_unsigned_v<T>
[[nodiscard]] constexpr bool IsPow2(T value) {
return std::has_single_bit(value);
}
template <typename T>
requires std::is_integral_v<T>
requires std::is_integral_v<T>
[[nodiscard]] T NextPow2(T value) {
return static_cast<T>(1ULL << ((8U * sizeof(T)) - std::countl_zero(value - 1U)));
}
template <size_t bit_index, typename T>
requires std::is_integral_v<T>
requires std::is_integral_v<T>
[[nodiscard]] constexpr bool Bit(const T value) {
static_assert(bit_index < BitSize<T>(), "bit_index must be smaller than size of T");
return ((value >> bit_index) & T(1)) == T(1);
+3 -3
View File
@@ -16,9 +16,9 @@ concept IsContiguousContainer = std::contiguous_iterator<typename T::iterator>;
// is available on all supported platforms.
template <typename Derived, typename Base>
concept DerivedFrom = requires {
std::is_base_of_v<Base, Derived>;
std::is_convertible_v<const volatile Derived*, const volatile Base*>;
};
std::is_base_of_v<Base, Derived>;
std::is_convertible_v<const volatile Derived*, const volatile Base*>;
};
// TODO: Replace with std::convertible_to when libc++ implements it.
template <typename From, typename To>
+35
View File
@@ -0,0 +1,35 @@
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include <llvm/Demangle/Demangle.h>
#include "common/demangle.h"
#include "common/scope_exit.h"
namespace Common {
std::string DemangleSymbol(const std::string& mangled) {
auto is_itanium = [](const std::string& name) -> bool {
// A valid Itanium encoding requires 1-4 leading underscores, followed by 'Z'.
auto pos = name.find_first_not_of('_');
return pos > 0 && pos <= 4 && pos < name.size() && name[pos] == 'Z';
};
if (mangled.empty()) {
return mangled;
}
char* demangled = nullptr;
SCOPE_EXIT({ std::free(demangled); });
if (is_itanium(mangled)) {
demangled = llvm::itaniumDemangle(mangled.c_str(), nullptr, nullptr, nullptr);
}
if (!demangled) {
return mangled;
}
return demangled;
}
} // namespace Common
+12
View File
@@ -0,0 +1,12 @@
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <string>
namespace Common {
std::string DemangleSymbol(const std::string& mangled);
} // namespace Common
+2 -2
View File
@@ -10,14 +10,14 @@ namespace Common {
/// Ceiled integer division.
template <typename N, typename D>
requires std::is_integral_v<N> && std::is_unsigned_v<D>
requires std::is_integral_v<N> && std::is_unsigned_v<D>
[[nodiscard]] constexpr N DivCeil(N number, D divisor) {
return static_cast<N>((static_cast<D>(number) + divisor - 1) / divisor);
}
/// Ceiled integer division with logarithmic divisor in base 2
template <typename N, typename D>
requires std::is_integral_v<N> && std::is_unsigned_v<D>
requires std::is_integral_v<N> && std::is_unsigned_v<D>
[[nodiscard]] constexpr N DivCeilLog2(N value, D alignment_log2) {
return static_cast<N>((static_cast<D>(value) + (D(1) << alignment_log2) - 1) >> alignment_log2);
}
+30 -30
View File
@@ -64,7 +64,7 @@ struct no_init_t {
* Additionally, this requires E to be trivially destructible
*/
template <typename T, typename E, bool = std::is_trivially_destructible_v<T>>
requires std::is_trivially_destructible_v<E>
requires std::is_trivially_destructible_v<E>
struct expected_storage_base {
constexpr expected_storage_base() : m_val{T{}}, m_has_val{true} {}
@@ -111,7 +111,7 @@ struct expected_storage_base {
* Additionally, this requires E to be trivially destructible
*/
template <typename T, typename E>
requires std::is_trivially_destructible_v<E>
requires std::is_trivially_destructible_v<E>
struct expected_storage_base<T, E, true> {
constexpr expected_storage_base() : m_val{T{}}, m_has_val{true} {}
@@ -251,7 +251,7 @@ struct expected_operations_base : expected_storage_base<T, E> {
* Additionally, this requires E to be trivially copy constructible
*/
template <typename T, typename E, bool = std::is_trivially_copy_constructible_v<T>>
requires std::is_trivially_copy_constructible_v<E>
requires std::is_trivially_copy_constructible_v<E>
struct expected_copy_base : expected_operations_base<T, E> {
using expected_operations_base<T, E>::expected_operations_base;
};
@@ -261,7 +261,7 @@ struct expected_copy_base : expected_operations_base<T, E> {
* Additionally, this requires E to be trivially copy constructible
*/
template <typename T, typename E>
requires std::is_trivially_copy_constructible_v<E>
requires std::is_trivially_copy_constructible_v<E>
struct expected_copy_base<T, E, false> : expected_operations_base<T, E> {
using expected_operations_base<T, E>::expected_operations_base;
@@ -289,7 +289,7 @@ struct expected_copy_base<T, E, false> : expected_operations_base<T, E> {
* Additionally, this requires E to be trivially move constructible
*/
template <typename T, typename E, bool = std::is_trivially_move_constructible_v<T>>
requires std::is_trivially_move_constructible_v<E>
requires std::is_trivially_move_constructible_v<E>
struct expected_move_base : expected_copy_base<T, E> {
using expected_copy_base<T, E>::expected_copy_base;
};
@@ -299,7 +299,7 @@ struct expected_move_base : expected_copy_base<T, E> {
* Additionally, this requires E to be trivially move constructible
*/
template <typename T, typename E>
requires std::is_trivially_move_constructible_v<E>
requires std::is_trivially_move_constructible_v<E>
struct expected_move_base<T, E, false> : expected_copy_base<T, E> {
using expected_copy_base<T, E>::expected_copy_base;
@@ -330,9 +330,9 @@ template <typename T, typename E,
bool = std::conjunction_v<std::is_trivially_copy_assignable<T>,
std::is_trivially_copy_constructible<T>,
std::is_trivially_destructible<T>>>
requires std::conjunction_v<std::is_trivially_copy_assignable<E>,
std::is_trivially_copy_constructible<E>,
std::is_trivially_destructible<E>>
requires std::conjunction_v<std::is_trivially_copy_assignable<E>,
std::is_trivially_copy_constructible<E>,
std::is_trivially_destructible<E>>
struct expected_copy_assign_base : expected_move_base<T, E> {
using expected_move_base<T, E>::expected_move_base;
};
@@ -342,9 +342,9 @@ struct expected_copy_assign_base : expected_move_base<T, E> {
* Additionally, this requires E to be trivially copy assignable
*/
template <typename T, typename E>
requires std::conjunction_v<std::is_trivially_copy_assignable<E>,
std::is_trivially_copy_constructible<E>,
std::is_trivially_destructible<E>>
requires std::conjunction_v<std::is_trivially_copy_assignable<E>,
std::is_trivially_copy_constructible<E>,
std::is_trivially_destructible<E>>
struct expected_copy_assign_base<T, E, false> : expected_move_base<T, E> {
using expected_move_base<T, E>::expected_move_base;
@@ -371,9 +371,9 @@ template <typename T, typename E,
bool = std::conjunction_v<std::is_trivially_move_assignable<T>,
std::is_trivially_move_constructible<T>,
std::is_trivially_destructible<T>>>
requires std::conjunction_v<std::is_trivially_move_assignable<E>,
std::is_trivially_move_constructible<E>,
std::is_trivially_destructible<E>>
requires std::conjunction_v<std::is_trivially_move_assignable<E>,
std::is_trivially_move_constructible<E>,
std::is_trivially_destructible<E>>
struct expected_move_assign_base : expected_copy_assign_base<T, E> {
using expected_copy_assign_base<T, E>::expected_copy_assign_base;
};
@@ -383,9 +383,9 @@ struct expected_move_assign_base : expected_copy_assign_base<T, E> {
* Additionally, this requires E to be trivially move assignable
*/
template <typename T, typename E>
requires std::conjunction_v<std::is_trivially_move_assignable<E>,
std::is_trivially_move_constructible<E>,
std::is_trivially_destructible<E>>
requires std::conjunction_v<std::is_trivially_move_assignable<E>,
std::is_trivially_move_constructible<E>,
std::is_trivially_destructible<E>>
struct expected_move_assign_base<T, E, false> : expected_copy_assign_base<T, E> {
using expected_copy_assign_base<T, E>::expected_copy_assign_base;
@@ -412,7 +412,7 @@ struct expected_move_assign_base<T, E, false> : expected_copy_assign_base<T, E>
*/
template <typename T, typename E, bool EnableCopy = std::is_copy_constructible_v<T>,
bool EnableMove = std::is_move_constructible_v<T>>
requires std::conjunction_v<std::is_copy_constructible<E>, std::is_move_constructible<E>>
requires std::conjunction_v<std::is_copy_constructible<E>, std::is_move_constructible<E>>
struct expected_delete_ctor_base {
expected_delete_ctor_base() = default;
expected_delete_ctor_base(const expected_delete_ctor_base&) = default;
@@ -422,7 +422,7 @@ struct expected_delete_ctor_base {
};
template <typename T, typename E>
requires std::conjunction_v<std::is_copy_constructible<E>, std::is_move_constructible<E>>
requires std::conjunction_v<std::is_copy_constructible<E>, std::is_move_constructible<E>>
struct expected_delete_ctor_base<T, E, true, false> {
expected_delete_ctor_base() = default;
expected_delete_ctor_base(const expected_delete_ctor_base&) = default;
@@ -432,7 +432,7 @@ struct expected_delete_ctor_base<T, E, true, false> {
};
template <typename T, typename E>
requires std::conjunction_v<std::is_copy_constructible<E>, std::is_move_constructible<E>>
requires std::conjunction_v<std::is_copy_constructible<E>, std::is_move_constructible<E>>
struct expected_delete_ctor_base<T, E, false, true> {
expected_delete_ctor_base() = default;
expected_delete_ctor_base(const expected_delete_ctor_base&) = delete;
@@ -442,7 +442,7 @@ struct expected_delete_ctor_base<T, E, false, true> {
};
template <typename T, typename E>
requires std::conjunction_v<std::is_copy_constructible<E>, std::is_move_constructible<E>>
requires std::conjunction_v<std::is_copy_constructible<E>, std::is_move_constructible<E>>
struct expected_delete_ctor_base<T, E, false, false> {
expected_delete_ctor_base() = default;
expected_delete_ctor_base(const expected_delete_ctor_base&) = delete;
@@ -460,8 +460,8 @@ template <
typename T, typename E,
bool EnableCopy = std::conjunction_v<std::is_copy_constructible<T>, std::is_copy_assignable<T>>,
bool EnableMove = std::conjunction_v<std::is_move_constructible<T>, std::is_move_assignable<T>>>
requires std::conjunction_v<std::is_copy_constructible<E>, std::is_move_constructible<E>,
std::is_copy_assignable<E>, std::is_move_assignable<E>>
requires std::conjunction_v<std::is_copy_constructible<E>, std::is_move_constructible<E>,
std::is_copy_assignable<E>, std::is_move_assignable<E>>
struct expected_delete_assign_base {
expected_delete_assign_base() = default;
expected_delete_assign_base(const expected_delete_assign_base&) = default;
@@ -471,8 +471,8 @@ struct expected_delete_assign_base {
};
template <typename T, typename E>
requires std::conjunction_v<std::is_copy_constructible<E>, std::is_move_constructible<E>,
std::is_copy_assignable<E>, std::is_move_assignable<E>>
requires std::conjunction_v<std::is_copy_constructible<E>, std::is_move_constructible<E>,
std::is_copy_assignable<E>, std::is_move_assignable<E>>
struct expected_delete_assign_base<T, E, true, false> {
expected_delete_assign_base() = default;
expected_delete_assign_base(const expected_delete_assign_base&) = default;
@@ -482,8 +482,8 @@ struct expected_delete_assign_base<T, E, true, false> {
};
template <typename T, typename E>
requires std::conjunction_v<std::is_copy_constructible<E>, std::is_move_constructible<E>,
std::is_copy_assignable<E>, std::is_move_assignable<E>>
requires std::conjunction_v<std::is_copy_constructible<E>, std::is_move_constructible<E>,
std::is_copy_assignable<E>, std::is_move_assignable<E>>
struct expected_delete_assign_base<T, E, false, true> {
expected_delete_assign_base() = default;
expected_delete_assign_base(const expected_delete_assign_base&) = default;
@@ -493,8 +493,8 @@ struct expected_delete_assign_base<T, E, false, true> {
};
template <typename T, typename E>
requires std::conjunction_v<std::is_copy_constructible<E>, std::is_move_constructible<E>,
std::is_copy_assignable<E>, std::is_move_assignable<E>>
requires std::conjunction_v<std::is_copy_constructible<E>, std::is_move_constructible<E>,
std::is_copy_assignable<E>, std::is_move_assignable<E>>
struct expected_delete_assign_base<T, E, false, false> {
expected_delete_assign_base() = default;
expected_delete_assign_base(const expected_delete_assign_base&) = default;
+43 -30
View File
@@ -51,6 +51,8 @@ enum class PollingMode {
NFC,
// Enable infrared camera polling
IR,
// Enable ring controller polling
Ring,
};
enum class CameraFormat {
@@ -62,21 +64,22 @@ enum class CameraFormat {
None,
};
// Vibration reply from the controller
enum class VibrationError {
None,
// Different results that can happen from a device request
enum class DriverResult {
Success,
WrongReply,
Timeout,
UnsupportedControllerType,
HandleInUse,
ErrorReadingData,
ErrorWritingData,
NoDeviceDetected,
InvalidHandle,
NotSupported,
Disabled,
Unknown,
};
// Polling mode reply from the controller
enum class PollingError {
None,
NotSupported,
Unknown,
};
// Nfc reply from the controller
enum class NfcState {
Success,
@@ -90,13 +93,6 @@ enum class NfcState {
Unknown,
};
// Ir camera reply from the controller
enum class CameraError {
None,
NotSupported,
Unknown,
};
// Hint for amplification curve to be used
enum class VibrationAmplificationType {
Linear,
@@ -134,6 +130,8 @@ struct ButtonStatus {
bool inverted{};
// Press once to activate, press again to release
bool toggle{};
// Spams the button when active
bool turbo{};
// Internal lock for the toggle status
bool locked{};
};
@@ -190,6 +188,8 @@ struct TouchStatus {
struct BodyColorStatus {
u32 body{};
u32 buttons{};
u32 left_grip{};
u32 right_grip{};
};
// HD rumble data
@@ -228,17 +228,31 @@ enum class ButtonNames {
Engine,
// This will display the button by value instead of the button name
Value,
// Joycon button names
ButtonLeft,
ButtonRight,
ButtonDown,
ButtonUp,
TriggerZ,
TriggerR,
TriggerL,
ButtonA,
ButtonB,
ButtonX,
ButtonY,
ButtonPlus,
ButtonMinus,
ButtonHome,
ButtonCapture,
ButtonStickL,
ButtonStickR,
TriggerL,
TriggerZL,
TriggerSL,
TriggerR,
TriggerZR,
TriggerSR,
// GC button names
TriggerZ,
ButtonStart,
// DS4 button names
@@ -292,9 +306,6 @@ class InputDevice {
public:
virtual ~InputDevice() = default;
// Request input device to update if necessary
virtual void SoftUpdate() {}
// Force input device to update data regardless of the current state
virtual void ForceUpdate() {}
@@ -319,22 +330,24 @@ class OutputDevice {
public:
virtual ~OutputDevice() = default;
virtual void SetLED([[maybe_unused]] const LedStatus& led_status) {}
virtual DriverResult SetLED([[maybe_unused]] const LedStatus& led_status) {
return DriverResult::NotSupported;
}
virtual VibrationError SetVibration([[maybe_unused]] const VibrationStatus& vibration_status) {
return VibrationError::NotSupported;
virtual DriverResult SetVibration([[maybe_unused]] const VibrationStatus& vibration_status) {
return DriverResult::NotSupported;
}
virtual bool IsVibrationEnabled() {
return false;
}
virtual PollingError SetPollingMode([[maybe_unused]] PollingMode polling_mode) {
return PollingError::NotSupported;
virtual DriverResult SetPollingMode([[maybe_unused]] PollingMode polling_mode) {
return DriverResult::NotSupported;
}
virtual CameraError SetCameraFormat([[maybe_unused]] CameraFormat camera_format) {
return CameraError::NotSupported;
virtual DriverResult SetCameraFormat([[maybe_unused]] CameraFormat camera_format) {
return DriverResult::NotSupported;
}
virtual NfcState SupportsNfc() const {
+11 -9
View File
@@ -242,19 +242,21 @@ public:
template <typename T>
concept HasRedBlackKeyType = requires {
{ std::is_same<typename T::RedBlackKeyType, void>::value } -> std::convertible_to<bool>;
};
{
std::is_same<typename T::RedBlackKeyType, void>::value
} -> std::convertible_to<bool>;
};
namespace impl {
template <typename T, typename Default>
consteval auto* GetRedBlackKeyType() {
if constexpr (HasRedBlackKeyType<T>) {
return static_cast<typename T::RedBlackKeyType*>(nullptr);
} else {
return static_cast<Default*>(nullptr);
}
template <typename T, typename Default>
consteval auto* GetRedBlackKeyType() {
if constexpr (HasRedBlackKeyType<T>) {
return static_cast<typename T::RedBlackKeyType*>(nullptr);
} else {
return static_cast<Default*>(nullptr);
}
}
} // namespace impl
+5 -3
View File
@@ -9,17 +9,19 @@
namespace Common {
template <class T>
requires(!std::is_array_v<T>) std::unique_ptr<T> make_unique_for_overwrite() {
requires(!std::is_array_v<T>)
std::unique_ptr<T> make_unique_for_overwrite() {
return std::unique_ptr<T>(new T);
}
template <class T>
requires std::is_unbounded_array_v<T> std::unique_ptr<T> make_unique_for_overwrite(std::size_t n) {
requires std::is_unbounded_array_v<T>
std::unique_ptr<T> make_unique_for_overwrite(std::size_t n) {
return std::unique_ptr<T>(new std::remove_extent_t<T>[n]);
}
template <class T, class... Args>
requires std::is_bounded_array_v<T>
requires std::is_bounded_array_v<T>
void make_unique_for_overwrite(Args&&...) = delete;
} // namespace Common
+4 -4
View File
@@ -18,9 +18,9 @@ namespace ranges {
template <typename T>
concept range = requires(T& t) {
begin(t);
end(t);
};
begin(t);
end(t);
};
template <typename T>
concept input_range = range<T>;
@@ -421,7 +421,7 @@ struct generate_fn {
}
template <typename R, std::copy_constructible F>
requires std::invocable<F&> && ranges::output_range<R>
requires std::invocable<F&> && ranges::output_range<R>
constexpr ranges::iterator_t<R> operator()(R&& r, F gen) const {
return operator()(ranges::begin(r), ranges::end(r), std::move(gen));
}
+86 -41
View File
@@ -11,6 +11,8 @@
#ifdef __cpp_lib_jthread
#include <chrono>
#include <condition_variable>
#include <stop_token>
#include <thread>
@@ -21,23 +23,36 @@ void CondvarWait(Condvar& cv, Lock& lock, std::stop_token token, Pred&& pred) {
cv.wait(lock, token, std::move(pred));
}
template <typename Rep, typename Period>
bool StoppableTimedWait(std::stop_token token, const std::chrono::duration<Rep, Period>& rel_time) {
std::condition_variable_any cv;
std::mutex m;
// Perform the timed wait.
std::unique_lock lk{m};
return !cv.wait_for(lk, token, rel_time, [&] { return token.stop_requested(); });
}
} // namespace Common
#else
#include <atomic>
#include <chrono>
#include <condition_variable>
#include <functional>
#include <list>
#include <map>
#include <memory>
#include <mutex>
#include <optional>
#include <thread>
#include <type_traits>
#include <utility>
namespace std {
namespace polyfill {
using stop_state_callbacks = list<function<void()>>;
using stop_state_callback = size_t;
class stop_state {
public:
@@ -45,61 +60,69 @@ public:
~stop_state() = default;
bool request_stop() {
stop_state_callbacks callbacks;
unique_lock lk{m_lock};
{
scoped_lock lk{m_lock};
if (m_stop_requested.load()) {
// Already set, nothing to do
return false;
}
// Set as requested
m_stop_requested = true;
// Copy callback list
callbacks = m_callbacks;
if (m_stop_requested) {
// Already set, nothing to do.
return false;
}
for (auto callback : callbacks) {
callback();
// Mark stop requested.
m_stop_requested = true;
while (!m_callbacks.empty()) {
// Get an iterator to the first element.
const auto it = m_callbacks.begin();
// Move the callback function out of the map.
function<void()> f;
swap(it->second, f);
// Erase the now-empty map element.
m_callbacks.erase(it);
// Run the callback.
if (f) {
f();
}
}
return true;
}
bool stop_requested() const {
return m_stop_requested.load();
unique_lock lk{m_lock};
return m_stop_requested;
}
stop_state_callbacks::const_iterator insert_callback(function<void()> f) {
stop_state_callbacks::const_iterator ret{};
bool should_run{};
stop_state_callback insert_callback(function<void()> f) {
unique_lock lk{m_lock};
{
scoped_lock lk{m_lock};
should_run = m_stop_requested.load();
m_callbacks.push_front(f);
ret = m_callbacks.begin();
}
if (should_run) {
f();
if (m_stop_requested) {
// Stop already requested. Don't insert anything,
// just run the callback synchronously.
if (f) {
f();
}
return 0;
}
// Insert the callback.
stop_state_callback ret = ++m_next_callback;
m_callbacks.emplace(ret, move(f));
return ret;
}
void remove_callback(stop_state_callbacks::const_iterator it) {
scoped_lock lk{m_lock};
m_callbacks.erase(it);
void remove_callback(stop_state_callback cb) {
unique_lock lk{m_lock};
m_callbacks.erase(cb);
}
private:
mutex m_lock;
atomic<bool> m_stop_requested;
stop_state_callbacks m_callbacks;
mutable recursive_mutex m_lock;
map<stop_state_callback, function<void()>> m_callbacks;
stop_state_callback m_next_callback{0};
bool m_stop_requested{false};
};
} // namespace polyfill
@@ -190,7 +213,7 @@ public:
using callback_type = Callback;
template <typename C>
requires constructible_from<Callback, C>
requires constructible_from<Callback, C>
explicit stop_callback(const stop_token& st,
C&& cb) noexcept(is_nothrow_constructible_v<Callback, C>)
: m_stop_state(st.m_stop_state) {
@@ -199,7 +222,7 @@ public:
}
}
template <typename C>
requires constructible_from<Callback, C>
requires constructible_from<Callback, C>
explicit stop_callback(stop_token&& st,
C&& cb) noexcept(is_nothrow_constructible_v<Callback, C>)
: m_stop_state(move(st.m_stop_state)) {
@@ -209,7 +232,7 @@ public:
}
~stop_callback() {
if (m_stop_state && m_callback) {
m_stop_state->remove_callback(*m_callback);
m_stop_state->remove_callback(m_callback);
}
}
@@ -220,7 +243,7 @@ public:
private:
shared_ptr<polyfill::stop_state> m_stop_state;
optional<polyfill::stop_state_callbacks::const_iterator> m_callback;
polyfill::stop_state_callback m_callback;
};
template <typename Callback>
@@ -318,6 +341,28 @@ void CondvarWait(Condvar& cv, Lock& lock, std::stop_token token, Pred pred) {
cv.wait(lock, [&] { return pred() || token.stop_requested(); });
}
template <typename Rep, typename Period>
bool StoppableTimedWait(std::stop_token token, const std::chrono::duration<Rep, Period>& rel_time) {
if (token.stop_requested()) {
return false;
}
bool stop_requested = false;
std::condition_variable cv;
std::mutex m;
std::stop_callback cb(token, [&] {
// Wake up the waiting thread.
std::unique_lock lk{m};
stop_requested = true;
cv.notify_one();
});
// Perform the timed wait.
std::unique_lock lk{m};
return !cv.wait_for(lk, rel_time, [&] { return stop_requested; });
}
} // namespace Common
#endif
+139
View File
@@ -0,0 +1,139 @@
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
#pragma once
#include <map>
#include <type_traits>
#include "common/common_types.h"
namespace Common {
template <typename KeyTBase, typename ValueT>
class RangeMap {
private:
using KeyT =
std::conditional_t<std::is_signed_v<KeyTBase>, KeyTBase, std::make_signed_t<KeyTBase>>;
public:
explicit RangeMap(ValueT null_value_) : null_value{null_value_} {
container.emplace(std::numeric_limits<KeyT>::min(), null_value);
};
~RangeMap() = default;
void Map(KeyTBase address, KeyTBase address_end, ValueT value) {
KeyT new_address = static_cast<KeyT>(address);
KeyT new_address_end = static_cast<KeyT>(address_end);
if (new_address < 0) {
new_address = 0;
}
if (new_address_end < 0) {
new_address_end = 0;
}
InternalMap(new_address, new_address_end, value);
}
void Unmap(KeyTBase address, KeyTBase address_end) {
Map(address, address_end, null_value);
}
[[nodiscard]] size_t GetContinousSizeFrom(KeyTBase address) const {
const KeyT new_address = static_cast<KeyT>(address);
if (new_address < 0) {
return 0;
}
return ContinousSizeInternal(new_address);
}
[[nodiscard]] ValueT GetValueAt(KeyT address) const {
const KeyT new_address = static_cast<KeyT>(address);
if (new_address < 0) {
return null_value;
}
return GetValueInternal(new_address);
}
private:
using MapType = std::map<KeyT, ValueT>;
using IteratorType = typename MapType::iterator;
using ConstIteratorType = typename MapType::const_iterator;
size_t ContinousSizeInternal(KeyT address) const {
const auto it = GetFirstElementBeforeOrOn(address);
if (it == container.end() || it->second == null_value) {
return 0;
}
const auto it_end = std::next(it);
if (it_end == container.end()) {
return std::numeric_limits<KeyT>::max() - address;
}
return it_end->first - address;
}
ValueT GetValueInternal(KeyT address) const {
const auto it = GetFirstElementBeforeOrOn(address);
if (it == container.end()) {
return null_value;
}
return it->second;
}
ConstIteratorType GetFirstElementBeforeOrOn(KeyT address) const {
auto it = container.lower_bound(address);
if (it == container.begin()) {
return it;
}
if (it != container.end() && (it->first == address)) {
return it;
}
--it;
return it;
}
ValueT GetFirstValueWithin(KeyT address) {
auto it = container.lower_bound(address);
if (it == container.begin()) {
return it->second;
}
if (it == container.end()) [[unlikely]] { // this would be a bug
return null_value;
}
--it;
return it->second;
}
ValueT GetLastValueWithin(KeyT address) {
auto it = container.upper_bound(address);
if (it == container.end()) {
return null_value;
}
if (it == container.begin()) [[unlikely]] { // this would be a bug
return it->second;
}
--it;
return it->second;
}
void InternalMap(KeyT address, KeyT address_end, ValueT value) {
const bool must_add_start = GetFirstValueWithin(address) != value;
const ValueT last_value = GetLastValueWithin(address_end);
const bool must_add_end = last_value != value;
auto it = container.lower_bound(address);
const auto it_end = container.upper_bound(address_end);
while (it != it_end) {
it = container.erase(it);
}
if (must_add_start) {
container.emplace(address, value);
}
if (must_add_end) {
container.emplace(address_end, last_value);
}
}
ValueT null_value;
MapType container;
};
} // namespace Common
+18
View File
@@ -24,6 +24,24 @@ public:
~ScratchBuffer() = default;
ScratchBuffer(ScratchBuffer&& rhs) {
last_requested_size = rhs.last_requested_size;
buffer_capacity = rhs.buffer_capacity;
buffer = std::move(rhs.buffer);
rhs.last_requested_size = 0;
rhs.buffer_capacity = 0;
}
void operator=(ScratchBuffer&& rhs) {
last_requested_size = rhs.last_requested_size;
buffer_capacity = rhs.buffer_capacity;
buffer = std::move(rhs.buffer);
rhs.last_requested_size = 0;
rhs.buffer_capacity = 0;
}
/// This will only grow the buffer's capacity if size is greater than the current capacity.
/// The previously held data will remain intact.
void resize(size_t size) {
+14
View File
@@ -129,6 +129,10 @@ void UpdateRescalingInfo() {
info.up_scale = 1;
info.down_shift = 0;
break;
case ResolutionSetup::Res3_2X:
info.up_scale = 3;
info.down_shift = 1;
break;
case ResolutionSetup::Res2X:
info.up_scale = 2;
info.down_shift = 0;
@@ -149,6 +153,14 @@ void UpdateRescalingInfo() {
info.up_scale = 6;
info.down_shift = 0;
break;
case ResolutionSetup::Res7X:
info.up_scale = 7;
info.down_shift = 0;
break;
case ResolutionSetup::Res8X:
info.up_scale = 8;
info.down_shift = 0;
break;
default:
ASSERT(false);
info.up_scale = 1;
@@ -185,6 +197,7 @@ void RestoreGlobalState(bool is_powered_on) {
// Renderer
values.fsr_sharpening_slider.SetGlobal(true);
values.renderer_backend.SetGlobal(true);
values.renderer_force_max_clock.SetGlobal(true);
values.vulkan_device.SetGlobal(true);
values.aspect_ratio.SetGlobal(true);
values.max_anisotropy.SetGlobal(true);
@@ -200,6 +213,7 @@ void RestoreGlobalState(bool is_powered_on) {
values.use_asynchronous_shaders.SetGlobal(true);
values.use_fast_gpu_time.SetGlobal(true);
values.use_pessimistic_flushes.SetGlobal(true);
values.use_vulkan_driver_pipeline_cache.SetGlobal(true);
values.bg_red.SetGlobal(true);
values.bg_green.SetGlobal(true);
values.bg_blue.SetGlobal(true);
+21 -9
View File
@@ -56,11 +56,14 @@ enum class ResolutionSetup : u32 {
Res1_2X = 0,
Res3_4X = 1,
Res1X = 2,
Res2X = 3,
Res3X = 4,
Res4X = 5,
Res5X = 6,
Res6X = 7,
Res3_2X = 3,
Res2X = 4,
Res3X = 5,
Res4X = 6,
Res5X = 7,
Res6X = 8,
Res7X = 9,
Res8X = 10,
};
enum class ScalingFilter : u32 {
@@ -128,7 +131,8 @@ public:
* @param default_val Intial value of the setting, and default value of the setting
* @param name Label for the setting
*/
explicit Setting(const Type& default_val, const std::string& name) requires(!ranged)
explicit Setting(const Type& default_val, const std::string& name)
requires(!ranged)
: value{default_val}, default_value{default_val}, label{name} {}
virtual ~Setting() = default;
@@ -141,7 +145,8 @@ public:
* @param name Label for the setting
*/
explicit Setting(const Type& default_val, const Type& min_val, const Type& max_val,
const std::string& name) requires(ranged)
const std::string& name)
requires(ranged)
: value{default_val},
default_value{default_val}, maximum{max_val}, minimum{min_val}, label{name} {}
@@ -229,7 +234,8 @@ public:
* @param default_val Intial value of the setting, and default value of the setting
* @param name Label for the setting
*/
explicit SwitchableSetting(const Type& default_val, const std::string& name) requires(!ranged)
explicit SwitchableSetting(const Type& default_val, const std::string& name)
requires(!ranged)
: Setting<Type>{default_val, name} {}
virtual ~SwitchableSetting() = default;
@@ -242,7 +248,8 @@ public:
* @param name Label for the setting
*/
explicit SwitchableSetting(const Type& default_val, const Type& min_val, const Type& max_val,
const std::string& name) requires(ranged)
const std::string& name)
requires(ranged)
: Setting<Type, true>{default_val, min_val, max_val, name} {}
/**
@@ -415,6 +422,7 @@ struct Values {
// Renderer
SwitchableSetting<RendererBackend, true> renderer_backend{
RendererBackend::Vulkan, RendererBackend::OpenGL, RendererBackend::Null, "backend"};
SwitchableSetting<bool> renderer_force_max_clock{false, "force_max_clock"};
Setting<bool> renderer_debug{false, "debug"};
Setting<bool> renderer_shader_feedback{false, "shader_feedback"};
Setting<bool> enable_nsight_aftermath{false, "nsight_aftermath"};
@@ -451,6 +459,8 @@ struct Values {
SwitchableSetting<bool> use_asynchronous_shaders{false, "use_asynchronous_shaders"};
SwitchableSetting<bool> use_fast_gpu_time{true, "use_fast_gpu_time"};
SwitchableSetting<bool> use_pessimistic_flushes{false, "use_pessimistic_flushes"};
SwitchableSetting<bool> use_vulkan_driver_pipeline_cache{true,
"use_vulkan_driver_pipeline_cache"};
SwitchableSetting<u8> bg_red{0, "bg_red"};
SwitchableSetting<u8> bg_green{0, "bg_green"};
@@ -477,6 +487,7 @@ struct Values {
Setting<bool> enable_raw_input{false, "enable_raw_input"};
Setting<bool> controller_navigation{true, "controller_navigation"};
Setting<bool> enable_joycon_driver{true, "enable_joycon_driver"};
SwitchableSetting<bool> vibration_enabled{true, "vibration_enabled"};
SwitchableSetting<bool> enable_accurate_vibrations{false, "enable_accurate_vibrations"};
@@ -531,6 +542,7 @@ struct Values {
Setting<bool> reporting_services{false, "reporting_services"};
Setting<bool> quest_flag{false, "quest_flag"};
Setting<bool> disable_macro_jit{false, "disable_macro_jit"};
Setting<bool> disable_macro_hle{false, "disable_macro_hle"};
Setting<bool> extended_logging{false, "extended_logging"};
Setting<bool> use_debug_asserts{false, "use_debug_asserts"};
Setting<bool> use_auto_stub{false, "use_auto_stub"};
+1 -1
View File
@@ -30,7 +30,7 @@ std::string ToUpper(std::string str) {
return str;
}
std::string StringFromBuffer(const std::vector<u8>& data) {
std::string StringFromBuffer(std::span<const u8> data) {
return std::string(data.begin(), std::find(data.begin(), data.end(), '\0'));
}
+2 -1
View File
@@ -5,6 +5,7 @@
#pragma once
#include <cstddef>
#include <span>
#include <string>
#include <vector>
#include "common/common_types.h"
@@ -17,7 +18,7 @@ namespace Common {
/// Make a string uppercase
[[nodiscard]] std::string ToUpper(std::string str);
[[nodiscard]] std::string StringFromBuffer(const std::vector<u8>& data);
[[nodiscard]] std::string StringFromBuffer(std::span<const u8> data);
[[nodiscard]] std::string StripSpaces(const std::string& s);
[[nodiscard]] std::string StripQuotes(const std::string& s);
+37 -37
View File
@@ -103,12 +103,12 @@ concept IsRBEntry = CheckRBEntry<T>::value;
template <typename T>
concept HasRBEntry = requires(T& t, const T& ct) {
{ t.GetRBEntry() } -> std::same_as<RBEntry<T>&>;
{ ct.GetRBEntry() } -> std::same_as<const RBEntry<T>&>;
};
{ t.GetRBEntry() } -> std::same_as<RBEntry<T>&>;
{ ct.GetRBEntry() } -> std::same_as<const RBEntry<T>&>;
};
template <typename T>
requires HasRBEntry<T>
requires HasRBEntry<T>
class RBHead {
private:
T* m_rbh_root = nullptr;
@@ -130,90 +130,90 @@ public:
};
template <typename T>
requires HasRBEntry<T>
requires HasRBEntry<T>
[[nodiscard]] constexpr RBEntry<T>& RB_ENTRY(T* t) {
return t->GetRBEntry();
}
template <typename T>
requires HasRBEntry<T>
requires HasRBEntry<T>
[[nodiscard]] constexpr const RBEntry<T>& RB_ENTRY(const T* t) {
return t->GetRBEntry();
}
template <typename T>
requires HasRBEntry<T>
requires HasRBEntry<T>
[[nodiscard]] constexpr T* RB_LEFT(T* t) {
return RB_ENTRY(t).Left();
}
template <typename T>
requires HasRBEntry<T>
requires HasRBEntry<T>
[[nodiscard]] constexpr const T* RB_LEFT(const T* t) {
return RB_ENTRY(t).Left();
}
template <typename T>
requires HasRBEntry<T>
requires HasRBEntry<T>
[[nodiscard]] constexpr T* RB_RIGHT(T* t) {
return RB_ENTRY(t).Right();
}
template <typename T>
requires HasRBEntry<T>
requires HasRBEntry<T>
[[nodiscard]] constexpr const T* RB_RIGHT(const T* t) {
return RB_ENTRY(t).Right();
}
template <typename T>
requires HasRBEntry<T>
requires HasRBEntry<T>
[[nodiscard]] constexpr T* RB_PARENT(T* t) {
return RB_ENTRY(t).Parent();
}
template <typename T>
requires HasRBEntry<T>
requires HasRBEntry<T>
[[nodiscard]] constexpr const T* RB_PARENT(const T* t) {
return RB_ENTRY(t).Parent();
}
template <typename T>
requires HasRBEntry<T>
requires HasRBEntry<T>
constexpr void RB_SET_LEFT(T* t, T* e) {
RB_ENTRY(t).SetLeft(e);
}
template <typename T>
requires HasRBEntry<T>
requires HasRBEntry<T>
constexpr void RB_SET_RIGHT(T* t, T* e) {
RB_ENTRY(t).SetRight(e);
}
template <typename T>
requires HasRBEntry<T>
requires HasRBEntry<T>
constexpr void RB_SET_PARENT(T* t, T* e) {
RB_ENTRY(t).SetParent(e);
}
template <typename T>
requires HasRBEntry<T>
requires HasRBEntry<T>
[[nodiscard]] constexpr bool RB_IS_BLACK(const T* t) {
return RB_ENTRY(t).IsBlack();
}
template <typename T>
requires HasRBEntry<T>
requires HasRBEntry<T>
[[nodiscard]] constexpr bool RB_IS_RED(const T* t) {
return RB_ENTRY(t).IsRed();
}
template <typename T>
requires HasRBEntry<T>
requires HasRBEntry<T>
[[nodiscard]] constexpr RBColor RB_COLOR(const T* t) {
return RB_ENTRY(t).Color();
}
template <typename T>
requires HasRBEntry<T>
requires HasRBEntry<T>
constexpr void RB_SET_COLOR(T* t, RBColor c) {
RB_ENTRY(t).SetColor(c);
}
template <typename T>
requires HasRBEntry<T>
requires HasRBEntry<T>
constexpr void RB_SET(T* elm, T* parent) {
auto& rb_entry = RB_ENTRY(elm);
rb_entry.SetParent(parent);
@@ -223,14 +223,14 @@ constexpr void RB_SET(T* elm, T* parent) {
}
template <typename T>
requires HasRBEntry<T>
requires HasRBEntry<T>
constexpr void RB_SET_BLACKRED(T* black, T* red) {
RB_SET_COLOR(black, RBColor::RB_BLACK);
RB_SET_COLOR(red, RBColor::RB_RED);
}
template <typename T>
requires HasRBEntry<T>
requires HasRBEntry<T>
constexpr void RB_ROTATE_LEFT(RBHead<T>& head, T* elm, T*& tmp) {
tmp = RB_RIGHT(elm);
if (RB_SET_RIGHT(elm, RB_LEFT(tmp)); RB_RIGHT(elm) != nullptr) {
@@ -252,7 +252,7 @@ constexpr void RB_ROTATE_LEFT(RBHead<T>& head, T* elm, T*& tmp) {
}
template <typename T>
requires HasRBEntry<T>
requires HasRBEntry<T>
constexpr void RB_ROTATE_RIGHT(RBHead<T>& head, T* elm, T*& tmp) {
tmp = RB_LEFT(elm);
if (RB_SET_LEFT(elm, RB_RIGHT(tmp)); RB_LEFT(elm) != nullptr) {
@@ -274,7 +274,7 @@ constexpr void RB_ROTATE_RIGHT(RBHead<T>& head, T* elm, T*& tmp) {
}
template <typename T>
requires HasRBEntry<T>
requires HasRBEntry<T>
constexpr void RB_REMOVE_COLOR(RBHead<T>& head, T* parent, T* elm) {
T* tmp;
while ((elm == nullptr || RB_IS_BLACK(elm)) && elm != head.Root()) {
@@ -358,7 +358,7 @@ constexpr void RB_REMOVE_COLOR(RBHead<T>& head, T* parent, T* elm) {
}
template <typename T>
requires HasRBEntry<T>
requires HasRBEntry<T>
constexpr T* RB_REMOVE(RBHead<T>& head, T* elm) {
T* child = nullptr;
T* parent = nullptr;
@@ -451,7 +451,7 @@ constexpr T* RB_REMOVE(RBHead<T>& head, T* elm) {
}
template <typename T>
requires HasRBEntry<T>
requires HasRBEntry<T>
constexpr void RB_INSERT_COLOR(RBHead<T>& head, T* elm) {
T *parent = nullptr, *tmp = nullptr;
while ((parent = RB_PARENT(elm)) != nullptr && RB_IS_RED(parent)) {
@@ -499,7 +499,7 @@ constexpr void RB_INSERT_COLOR(RBHead<T>& head, T* elm) {
}
template <typename T, typename Compare>
requires HasRBEntry<T>
requires HasRBEntry<T>
constexpr T* RB_INSERT(RBHead<T>& head, T* elm, Compare cmp) {
T* parent = nullptr;
T* tmp = head.Root();
@@ -534,7 +534,7 @@ constexpr T* RB_INSERT(RBHead<T>& head, T* elm, Compare cmp) {
}
template <typename T, typename Compare>
requires HasRBEntry<T>
requires HasRBEntry<T>
constexpr T* RB_FIND(RBHead<T>& head, T* elm, Compare cmp) {
T* tmp = head.Root();
@@ -553,7 +553,7 @@ constexpr T* RB_FIND(RBHead<T>& head, T* elm, Compare cmp) {
}
template <typename T, typename Compare>
requires HasRBEntry<T>
requires HasRBEntry<T>
constexpr T* RB_NFIND(RBHead<T>& head, T* elm, Compare cmp) {
T* tmp = head.Root();
T* res = nullptr;
@@ -574,7 +574,7 @@ constexpr T* RB_NFIND(RBHead<T>& head, T* elm, Compare cmp) {
}
template <typename T, typename U, typename Compare>
requires HasRBEntry<T>
requires HasRBEntry<T>
constexpr T* RB_FIND_KEY(RBHead<T>& head, const U& key, Compare cmp) {
T* tmp = head.Root();
@@ -593,7 +593,7 @@ constexpr T* RB_FIND_KEY(RBHead<T>& head, const U& key, Compare cmp) {
}
template <typename T, typename U, typename Compare>
requires HasRBEntry<T>
requires HasRBEntry<T>
constexpr T* RB_NFIND_KEY(RBHead<T>& head, const U& key, Compare cmp) {
T* tmp = head.Root();
T* res = nullptr;
@@ -614,7 +614,7 @@ constexpr T* RB_NFIND_KEY(RBHead<T>& head, const U& key, Compare cmp) {
}
template <typename T, typename Compare>
requires HasRBEntry<T>
requires HasRBEntry<T>
constexpr T* RB_FIND_EXISTING(RBHead<T>& head, T* elm, Compare cmp) {
T* tmp = head.Root();
@@ -631,7 +631,7 @@ constexpr T* RB_FIND_EXISTING(RBHead<T>& head, T* elm, Compare cmp) {
}
template <typename T, typename U, typename Compare>
requires HasRBEntry<T>
requires HasRBEntry<T>
constexpr T* RB_FIND_EXISTING_KEY(RBHead<T>& head, const U& key, Compare cmp) {
T* tmp = head.Root();
@@ -648,7 +648,7 @@ constexpr T* RB_FIND_EXISTING_KEY(RBHead<T>& head, const U& key, Compare cmp) {
}
template <typename T>
requires HasRBEntry<T>
requires HasRBEntry<T>
constexpr T* RB_NEXT(T* elm) {
if (RB_RIGHT(elm)) {
elm = RB_RIGHT(elm);
@@ -669,7 +669,7 @@ constexpr T* RB_NEXT(T* elm) {
}
template <typename T>
requires HasRBEntry<T>
requires HasRBEntry<T>
constexpr T* RB_PREV(T* elm) {
if (RB_LEFT(elm)) {
elm = RB_LEFT(elm);
@@ -690,7 +690,7 @@ constexpr T* RB_PREV(T* elm) {
}
template <typename T>
requires HasRBEntry<T>
requires HasRBEntry<T>
constexpr T* RB_MIN(RBHead<T>& head) {
T* tmp = head.Root();
T* parent = nullptr;
@@ -704,7 +704,7 @@ constexpr T* RB_MIN(RBHead<T>& head) {
}
template <typename T>
requires HasRBEntry<T>
requires HasRBEntry<T>
constexpr T* RB_MAX(RBHead<T>& head) {
T* tmp = head.Root();
T* parent = nullptr;
+5 -11
View File
@@ -348,9 +348,7 @@ public:
// _DEFINE_SWIZZLER2 defines a single such function, DEFINE_SWIZZLER2 defines all of them for all
// component names (x<->r) and permutations (xy<->yx)
#define _DEFINE_SWIZZLER2(a, b, name) \
[[nodiscard]] constexpr Vec2<T> name() const { \
return Vec2<T>(a, b); \
}
[[nodiscard]] constexpr Vec2<T> name() const { return Vec2<T>(a, b); }
#define DEFINE_SWIZZLER2(a, b, a2, b2, a3, b3, a4, b4) \
_DEFINE_SWIZZLER2(a, b, a##b); \
_DEFINE_SWIZZLER2(a, b, a2##b2); \
@@ -543,9 +541,7 @@ public:
// DEFINE_SWIZZLER2_COMP2 defines two component functions for all component names (x<->r) and
// permutations (xy<->yx)
#define _DEFINE_SWIZZLER2(a, b, name) \
[[nodiscard]] constexpr Vec2<T> name() const { \
return Vec2<T>(a, b); \
}
[[nodiscard]] constexpr Vec2<T> name() const { return Vec2<T>(a, b); }
#define DEFINE_SWIZZLER2_COMP1(a, a2) \
_DEFINE_SWIZZLER2(a, a, a##a); \
_DEFINE_SWIZZLER2(a, a, a2##a2)
@@ -570,9 +566,7 @@ public:
#undef _DEFINE_SWIZZLER2
#define _DEFINE_SWIZZLER3(a, b, c, name) \
[[nodiscard]] constexpr Vec3<T> name() const { \
return Vec3<T>(a, b, c); \
}
[[nodiscard]] constexpr Vec3<T> name() const { return Vec3<T>(a, b, c); }
#define DEFINE_SWIZZLER3_COMP1(a, a2) \
_DEFINE_SWIZZLER3(a, a, a, a##a##a); \
_DEFINE_SWIZZLER3(a, a, a, a2##a2##a2)
@@ -641,8 +635,8 @@ template <typename T>
// linear interpolation via float: 0.0=begin, 1.0=end
template <typename X>
[[nodiscard]] constexpr decltype(X{} * float{} + X{} * float{})
Lerp(const X& begin, const X& end, const float t) {
[[nodiscard]] constexpr decltype(X{} * float{} + X{} * float{}) Lerp(const X& begin, const X& end,
const float t) {
return begin * (1.f - t) + end * t;
}
+40 -1
View File
@@ -182,6 +182,8 @@ add_library(core STATIC
hle/kernel/k_auto_object_container.cpp
hle/kernel/k_auto_object_container.h
hle/kernel/k_affinity_mask.h
hle/kernel/k_capabilities.cpp
hle/kernel/k_capabilities.h
hle/kernel/k_class_token.cpp
hle/kernel/k_class_token.h
hle/kernel/k_client_port.cpp
@@ -193,6 +195,8 @@ add_library(core STATIC
hle/kernel/k_condition_variable.cpp
hle/kernel/k_condition_variable.h
hle/kernel/k_debug.h
hle/kernel/k_device_address_space.cpp
hle/kernel/k_device_address_space.h
hle/kernel/k_dynamic_page_manager.h
hle/kernel/k_dynamic_resource_manager.h
hle/kernel/k_dynamic_slab_heap.h
@@ -294,7 +298,42 @@ add_library(core STATIC
hle/kernel/svc.h
hle/kernel/svc_common.h
hle/kernel/svc_types.h
hle/kernel/svc_wrap.h
hle/kernel/svc/svc_activity.cpp
hle/kernel/svc/svc_address_arbiter.cpp
hle/kernel/svc/svc_address_translation.cpp
hle/kernel/svc/svc_cache.cpp
hle/kernel/svc/svc_code_memory.cpp
hle/kernel/svc/svc_condition_variable.cpp
hle/kernel/svc/svc_debug.cpp
hle/kernel/svc/svc_debug_string.cpp
hle/kernel/svc/svc_device_address_space.cpp
hle/kernel/svc/svc_event.cpp
hle/kernel/svc/svc_exception.cpp
hle/kernel/svc/svc_info.cpp
hle/kernel/svc/svc_interrupt_event.cpp
hle/kernel/svc/svc_io_pool.cpp
hle/kernel/svc/svc_ipc.cpp
hle/kernel/svc/svc_kernel_debug.cpp
hle/kernel/svc/svc_light_ipc.cpp
hle/kernel/svc/svc_lock.cpp
hle/kernel/svc/svc_memory.cpp
hle/kernel/svc/svc_physical_memory.cpp
hle/kernel/svc/svc_port.cpp
hle/kernel/svc/svc_power_management.cpp
hle/kernel/svc/svc_process.cpp
hle/kernel/svc/svc_process_memory.cpp
hle/kernel/svc/svc_processor.cpp
hle/kernel/svc/svc_query_memory.cpp
hle/kernel/svc/svc_register.cpp
hle/kernel/svc/svc_resource_limit.cpp
hle/kernel/svc/svc_secure_monitor_call.cpp
hle/kernel/svc/svc_session.cpp
hle/kernel/svc/svc_shared_memory.cpp
hle/kernel/svc/svc_synchronization.cpp
hle/kernel/svc/svc_thread.cpp
hle/kernel/svc/svc_thread_profiler.cpp
hle/kernel/svc/svc_tick.cpp
hle/kernel/svc/svc_transfer_memory.cpp
hle/result.h
hle/service/acc/acc.cpp
hle/service/acc/acc.h
+4 -18
View File
@@ -1,14 +1,12 @@
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#ifndef _MSC_VER
#include <cxxabi.h>
#endif
#include <map>
#include <optional>
#include "common/bit_field.h"
#include "common/common_types.h"
#include "common/demangle.h"
#include "common/logging/log.h"
#include "core/arm/arm_interface.h"
#include "core/arm/symbols.h"
@@ -71,20 +69,8 @@ void ARM_Interface::SymbolicateBacktrace(Core::System& system, std::vector<Backt
const auto symbol_set = symbols.find(entry.module);
if (symbol_set != symbols.end()) {
const auto symbol = Symbols::GetSymbolName(symbol_set->second, entry.offset);
if (symbol.has_value()) {
#ifdef _MSC_VER
// TODO(DarkLordZach): Add demangling of symbol names.
entry.name = *symbol;
#else
int status{-1};
char* demangled{abi::__cxa_demangle(symbol->c_str(), nullptr, nullptr, &status)};
if (status == 0 && demangled != nullptr) {
entry.name = demangled;
std::free(demangled);
} else {
entry.name = *symbol;
}
#endif
if (symbol) {
entry.name = Common::DemangleSymbol(*symbol);
}
}
}
@@ -229,7 +229,11 @@ std::shared_ptr<Dynarmic::A32::Jit> ARM_Dynarmic_32::MakeJit(Common::PageTable*
config.enable_cycle_counting = true;
// Code cache size
#ifdef ARCHITECTURE_arm64
config.code_cache_size = 128_MiB;
#else
config.code_cache_size = 512_MiB;
#endif
// Allow memory fault handling to work
if (system.DebuggerEnabled()) {
@@ -288,7 +288,11 @@ std::shared_ptr<Dynarmic::A64::Jit> ARM_Dynarmic_64::MakeJit(Common::PageTable*
config.enable_cycle_counting = true;
// Code cache size
#ifdef ARCHITECTURE_arm64
config.code_cache_size = 128_MiB;
#else
config.code_cache_size = 512_MiB;
#endif
// Allow memory fault handling to work
if (system.DebuggerEnabled()) {
+17 -23
View File
@@ -142,16 +142,24 @@ void CoreTiming::ScheduleLoopingEvent(std::chrono::nanoseconds start_time,
}
void CoreTiming::UnscheduleEvent(const std::shared_ptr<EventType>& event_type,
std::uintptr_t user_data) {
std::scoped_lock scope{basic_lock};
const auto itr = std::remove_if(event_queue.begin(), event_queue.end(), [&](const Event& e) {
return e.type.lock().get() == event_type.get() && e.user_data == user_data;
});
std::uintptr_t user_data, bool wait) {
{
std::scoped_lock lk{basic_lock};
const auto itr =
std::remove_if(event_queue.begin(), event_queue.end(), [&](const Event& e) {
return e.type.lock().get() == event_type.get() && e.user_data == user_data;
});
// Removing random items breaks the invariant so we have to re-establish it.
if (itr != event_queue.end()) {
event_queue.erase(itr, event_queue.end());
std::make_heap(event_queue.begin(), event_queue.end(), std::greater<>());
// Removing random items breaks the invariant so we have to re-establish it.
if (itr != event_queue.end()) {
event_queue.erase(itr, event_queue.end());
std::make_heap(event_queue.begin(), event_queue.end(), std::greater<>());
}
}
// Force any in-progress events to finish
if (wait) {
std::scoped_lock lk{advance_lock};
}
}
@@ -190,20 +198,6 @@ u64 CoreTiming::GetClockTicks() const {
return CpuCyclesToClockCycles(ticks);
}
void CoreTiming::RemoveEvent(const std::shared_ptr<EventType>& event_type) {
std::scoped_lock lock{basic_lock};
const auto itr = std::remove_if(event_queue.begin(), event_queue.end(), [&](const Event& e) {
return e.type.lock().get() == event_type.get();
});
// Removing random items breaks the invariant so we have to re-establish it.
if (itr != event_queue.end()) {
event_queue.erase(itr, event_queue.end());
std::make_heap(event_queue.begin(), event_queue.end(), std::greater<>());
}
}
std::optional<s64> CoreTiming::Advance() {
std::scoped_lock lock{advance_lock, basic_lock};
global_timer = GetGlobalTimeNs().count();
+6 -3
View File
@@ -98,10 +98,13 @@ public:
const std::shared_ptr<EventType>& event_type,
std::uintptr_t user_data = 0, bool absolute_time = false);
void UnscheduleEvent(const std::shared_ptr<EventType>& event_type, std::uintptr_t user_data);
void UnscheduleEvent(const std::shared_ptr<EventType>& event_type, std::uintptr_t user_data,
bool wait = true);
/// We only permit one event of each type in the queue at a time.
void RemoveEvent(const std::shared_ptr<EventType>& event_type);
void UnscheduleEventWithoutWait(const std::shared_ptr<EventType>& event_type,
std::uintptr_t user_data) {
UnscheduleEvent(event_type, user_data, false);
}
void AddTicks(u64 ticks_to_add);
+23 -3
View File
@@ -11,6 +11,7 @@
#include "common/hex_util.h"
#include "common/logging/log.h"
#include "common/scope_exit.h"
#include "common/settings.h"
#include "core/arm/arm_interface.h"
#include "core/core.h"
#include "core/debugger/gdbstub.h"
@@ -731,7 +732,25 @@ void GDBStub::HandleRcmd(const std::vector<u8>& command) {
auto* process = system.CurrentProcess();
auto& page_table = process->PageTable();
if (command_str == "get info") {
const char* commands = "Commands:\n"
" get fastmem\n"
" get info\n"
" get mappings\n";
if (command_str == "get fastmem") {
if (Settings::IsFastmemEnabled()) {
const auto& impl = page_table.PageTableImpl();
const auto region = reinterpret_cast<uintptr_t>(impl.fastmem_arena);
const auto region_bits = impl.current_address_space_width_in_bits;
const auto region_size = 1ULL << region_bits;
reply = fmt::format("Region bits: {}\n"
"Host address: {:#x} - {:#x}\n",
region_bits, region, region + region_size - 1);
} else {
reply = "Fastmem is not enabled.\n";
}
} else if (command_str == "get info") {
Loader::AppLoader::Modules modules;
system.GetAppLoader().ReadNSOModules(modules);
@@ -787,9 +806,10 @@ void GDBStub::HandleRcmd(const std::vector<u8>& command) {
cur_addr = next_address;
}
} else if (command_str == "help") {
reply = "Commands:\n get info\n get mappings\n";
reply = commands;
} else {
reply = "Unknown command.\nCommands:\n get info\n get mappings\n";
reply = "Unknown command.\n";
reply += commands;
}
std::span<const u8> reply_span{reinterpret_cast<u8*>(&reply.front()), reply.size()};
+3 -3
View File
@@ -194,9 +194,9 @@ std::size_t VfsFile::WriteBytes(const std::vector<u8>& data, std::size_t offset)
std::string VfsFile::GetFullPath() const {
if (GetContainingDirectory() == nullptr)
return "/" + GetName();
return '/' + GetName();
return GetContainingDirectory()->GetFullPath() + "/" + GetName();
return GetContainingDirectory()->GetFullPath() + '/' + GetName();
}
VirtualFile VfsDirectory::GetFileRelative(std::string_view path) const {
@@ -435,7 +435,7 @@ std::string VfsDirectory::GetFullPath() const {
if (IsRoot())
return GetName();
return GetParentDirectory()->GetFullPath() + "/" + GetName();
return GetParentDirectory()->GetFullPath() + '/' + GetName();
}
bool ReadOnlyVfsDirectory::IsWritable() const {
+20
View File
@@ -25,6 +25,26 @@ constexpr std::array<s32, Common::BitSize<u64>()> VirtualToPhysicalCoreMap{
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
};
static constexpr inline size_t NumVirtualCores = Common::BitSize<u64>();
static constexpr inline u64 VirtualCoreMask = [] {
u64 mask = 0;
for (size_t i = 0; i < NumVirtualCores; ++i) {
mask |= (UINT64_C(1) << i);
}
return mask;
}();
static constexpr inline u64 ConvertVirtualCoreMaskToPhysical(u64 v_core_mask) {
u64 p_core_mask = 0;
while (v_core_mask != 0) {
const u64 next = std::countr_zero(v_core_mask);
v_core_mask &= ~(static_cast<u64>(1) << next);
p_core_mask |= (static_cast<u64>(1) << VirtualToPhysicalCoreMap[next]);
}
return p_core_mask;
}
// Cortex-A57 supports 4 memory watchpoints
constexpr u64 NUM_WATCHPOINTS = 4;

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