Compare commits

..

23 Commits

Author SHA1 Message Date
lizzie 1fa72e7bc5 fx 2026-04-26 06:05:22 +00:00
lizzie 666593a3b2 WIP: stuff for fun 2
Signed-off-by: lizzie <lizzie@eden-emu.dev>
2026-04-26 05:30:16 +00:00
crueter 91058d7383 [desktop] Fix 2 mod manager bugs (#3884)
- Multi-import would show duplicates of a mod if it had both exefs and
  romfs
- Import from folder would crash on some single mods

Signed-off-by: crueter <crueter@eden-emu.dev>
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3884
Reviewed-by: Lizzie <lizzie@eden-emu.dev>
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
2026-04-26 03:26:04 +02:00
crueter 048d02e5b4 [android] Remove unused SPIRV strings and make strings check run on PRs (#3885)
I reorganized my runners so it shouldn't be an issue anymore

Signed-off-by: crueter <crueter@eden-emu.dev>
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3885
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
Reviewed-by: CamilleLaVey <camillelavey99@gmail.com>
2026-04-25 23:32:20 +02:00
lizzie 17e2be173c [spirv] nuke spirv-opt (#3877)
lots of AGILEism in spirv-opt
theres BETTER alternatives like https://github.com/renderbag/re-spirv (im not gonna bother for now, it probably has shitty build system)
it sucks

the IR already resolves most of the shader code to just constant load/stores
Spirv-opt passes do not seem to make such a big difference
only introduce extra latency
like for example cbuf pass in IR already removes a lot of code, that spirv_opt would otherwise miss due to the fact it doesn't have cbuf information

Signed-off-by: lizzie <lizzie@eden-emu.dev>

Co-authored-by: crueter <crueter@eden-emu.dev>
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3877
Reviewed-by: CamilleLaVey <camillelavey99@gmail.com>
Reviewed-by: crueter <crueter@eden-emu.dev>
2026-04-25 21:54:27 +02:00
crueter bd6dd7ecec [maxwell] Fix Flow::Block comp error (#3882)
Signed-off-by: crueter <crueter@eden-emu.dev>
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3882
Reviewed-by: Lizzie <lizzie@eden-emu.dev>
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
2026-04-25 20:50:11 +02:00
crueter 72ae613176 [dist, android] Update translations from Transifex (#3881)
Signed-off-by: Eden CI <ci@eden-emu.dev>
Co-authored-by: Eden CI <ci@eden-emu.dev>
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3881
2026-04-25 18:07:47 +02:00
crueter 26ce96297c [frontend] Change update checker to use new endpoints (#3879)
Related: [RFC3870](https://git.eden-emu.dev/eden-emu/eden/issues/3870)

Nightly and stable releases are now served through
`nightly.eden-emu.dev` and `stable.eden-emu.dev`, respectively. These
are stored using Backblaze, and served and cached through the Cloudflare
CDN. Ideally this will reduce costs, though I'll have to wait for my
first invoice to be certain.

These will serve as the new download locations going forward. Since we
have full control over this API, we can make any adjustments we want as
needed. For now, all it does is provide `tag_name`, `name`, and `body`,
the latter of which will be used for the upcoming updater PR.

Signed-off-by: crueter <crueter@eden-emu.dev>
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3879
Reviewed-by: CamilleLaVey <camillelavey99@gmail.com>
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
2026-04-24 18:40:49 +02:00
CamilleLaVey b3cc8723c1 [vulkan] 2nd Vulkan Global Maintenance (#3853)
This pr is a sequel to the one merged some days ago (#3839); which aims to improve stability, graphical accuracy and better Vulkan implementation and coherency among all platforms, contains the next changes:

-> Removal of VK_EXT_unified_image_layouts: The removal of this ext was for cleaning purposes since the only part of this extension implemented was the activator; meanwhile a proper structure of use for this extension was not implemented, currently it's not viable to keep following an idea of a proper implementation due to complexity of this feature and the state of buffer cache and texture cache, which it's task that we must do near in the future, when this happens a better oportunity will arise to properly set layouts along a proper implementation of VK_EXT_descriptors_indexing, practically this feature was dead code.

-> Adjustment of VK_EXT_custom_border_color: The implementation of this feature was handled poorly and worsened during the first tries of making ExtendedDynamicState stable, by gating it's use to the slider of EDS (dyna_state) if the counter was at least in 1, even tho this entered in a bug with the RemoveUnsuitableExtension, when is not a requirement for enabling in Vulkan's documentation and was my mistake, some time later in ExtendedDynamicState refactor (#3074) I tried to make the implementation more robust in comparison the Yuzu's implementation which had bans on vendor drivers, the new handling was requesting if extension was available and what kind of support feature it had, enabling what it was available and wiring an adequate path for said available feature; which leads us to today's change, after reading carefully how certain paths weren't triggered or caused mostly issues on how extension should work I did the next changes:

    - I removed the forced disabling with ExtendedDynamicState setting
    - Resolved the bug with RemoveUnsuitableExtension + dyna_state
    - Removed comments of explanation + log_debug warning
    - Set extension to be disabled if customBorderColorWithoutFormat is not available
    - Helps to solidify the removal of bans in vendor drivers

This changes fixes the VUID 04015 for the handling with undefined format and made the usage of the extension more near to what Vulkan specification expects, yet there is still cases where we can't emulate properly samplers and some translucid black boxes will still appear, yet, now alleviated by allowing extension choose the proper custom available in Vulkan or degrade into a fallaback of solid colors.

-> Adjustment of VK_EXT/KHR_robustness2: This feature was introduced in ExtendedDynamicState refactor (#3074), as safety measure for descriptors during the Write of buffers, providing robustness with an upgraded access to image, buffers and proper discard of null data in descriptors, however, despite the configuration the logs during debug sessions never stopped to bring the next VUID-VkWriteDescriptorSet-descriptorType-00324 and VUID-VkWriteDescriptorSet-descriptorType-00325, being the first one, the most constant issue plaguing logs; the approach was not only ensuring device can access between each of the version of this feature, whether is an EXT or KHR (drivers can report one of them or both, yet, if we call the one of them and it's not the version supported, driver would not load the feature, there's a priority to the KHR version) with a simplified configuration of the extension to use only nullDescritor to deflect properly buffers and other trash data outside of descriptors bound; ensuring to wire the path when it's and not available and also with BindVertexBuffers2EXT when it's or not available; fixing both VUID's. This changes helps to save some CPU resources and memory on binding routes.

      - Fixes VUID-VkWriteDescriptorSet-descriptorType-00324
      - Fixes VUID-VkWriteDescriptorSet-descriptorType-00325
      - Fixes VUID-vkCmdBindVertexBuffers-pBuffers-00621 (alongisde a latter adjustment for pStrides)

-> Adjustment VK_EXT_image_robustness: As other features, this was implemented during the ExtendedDynamicState refactor (#3074), currently this change it's just to ensure more drivers are accessing this feature by changing the modality from extension to an explicit feature, some other redundant code was cleaned within this change.

-> Restored gating flush operation on removed gpu accuracy: An issue report from an user called CaptFaraday in https://github.com/eden-emulator/Issue-Reports/issues/425, posted a behavior appearing after the rework of gpu accuracy levels (#3129), which broke the rendering in Paper Mario - The-Thousand-Year Door where some graphical issues such as black flash and missing rendering from many animations through the game thanks to the removal of the flush inside FlushAndInvalidateRegion gated with IsGPULevelExtreme and suggested a possible fix with resting the missing gating and flush; which I did and properly restoring the complete behavior of this functionality + wiring to the new IsGPULevelHigh for a better semantic correctness, the change was tested and didn't affected Yoshi's Crafted World graphical problems and main reason behind the deletion of this function, fixed in fcfcee7247.

      - Solves https://github.com/eden-emulator/Issue-Reports/issues/266
      - Solves https://github.com/eden-emulator/Issue-Reports/issues/425
      - Fixes Paper Mario - The-Thousand-Year Door
      - Keeps Yoshi's Crafted World issue still fixed

-> Adjustment VK_EXT_conditional_rendering: Yuzu inherited us in their Vulkan backend multiple flaws which got worsened with the time as game and drivers changed, aside that, with the time studying this source code and especially the Vulkan-side of Eden, I started to learn and recognize some extensions that required a wide and robust modification to ensure the logic of the extension works as intended; currently ConditionalRendering had a lot of minimal modification:

    - Reordering the functions from "_NotifySegment_" to avoid a masive ram leak coming from query_cache (@weakboson) (#131)
    - Removing a function "_NotifySegment_" from rasterizer to ensure Metroid Prime 4 stopped crashing due to serious ram leaks in query_cache (@Maufeat) (#3142)

And other intents to make ConditionalRendering fully working, such as happened in ExtendedDynamicState refactor (#3074) but only patched an horrible situation with how the extension was truly working, after spending more than 3 months studying how this and other sub-sequential and essential extensions touched in this PR worked in Vulkan, I dived once again to make it work properly; one of the first changes was to fix an invalid reference lookup of queries, which fixed the removal of "NotifySegment" inside rasterizer and start to adjusting other parts of the implementation of ConditionalRendering minimally and switching with heavy tests to ensure not a single game gets broken among the changes; yet the initial benefits from fixing the indirection in the lookups to query cache, was to reduce the amount of time of GPU was spending in the constant state of queries, which proved to reduce flickering in Pokémon ZA among others, with also an small increase of performance but more noticeable stability, starting to reduce stutering bit by bit.

This advances allowed me to fix one of the the functions of IsGPULevelHigh, where existed a bypass to accelerate conditional rendering without the proper checks if the extension was truly supported, freeing QCOM from the flag of a fixated presync workaround; which also improved the usage of QCOM driver for 8 Elite devices and Unreal Engine 4 - 5 games, such as Dragon Ball Z - Sparking Zero; but that's not the only benefit from the current tries to make ConditionalRendering implementation more robust and accurate to specifications, but also started to show key points of where VK_EXT_transform_feedback was also failing to work properly.

-> Adjustment VK_EXT_transform_feedback: Like many other features in this PR, this one was also adjusted minimally in ExtendedDynamicState refactor (#3074), with the ConditionalRendering refactor going on, the solutions for the usage of this extensions started by ensuring each key function is properly gated by a getter which would only be enabled if the extension was already being loaded in the virtual device, if wasn't the case I was making sure to wire the fallback correctly, which wasn't in place and didn't had a robust handling since ever, this way games started to not only improve graphical accuracy, like some games such as Zelda - Echoes Of Wisdom where the lightning and dark border moves/ reacts dynamically.

Besides that, this change brought the possibility to finally get rid of the indirection of the buffers synchronization which often take a non-synchornization path to ensure a faster reply but with higher possibilities to cause graphical issues in among several games; aside that, also helped to ensure "_query_cache.CounterEnable(VideoCommon::QueryType::StreamingByteCount, false)_;" function is properly allocated and reset in a different place than where this was placed.

   - Maintain Metroid Prime 4 fixes even after returning the lines that caused the game to be unplayable, whether was an instant crash
     or crash after some minutes of gameplay, fixes that were introduced in other work (#3142).

Within the first step in the refactor of this extension, this work was reviewed by @wildcard which made me notice of an issue of handling inside buffers, there existed a mismatch on the tracking of feedback buffers and since we're treating them as buffer_slot, counterstream was still tracking and consuming stream_buffers and not where data was really passing through; derivating the counter selection of counterBufferCount by stream indexes and not by slot, which could cause cases of _Stream =! slot_, a solution proposed for me was to add stream mapper function where the stream slot were located + updating UpdateBuffers() to calculate buffer counts per slot and not stream, allowing to fully map the map funtion of stream mapper; along other changes on the WriteBuffers + ProduceBufferCounter to avoid any misaligment.

-> Other minimal adjustments: Alongside these important adjustment, others were also made to ensure logical coherency to this recent changes, such as ensuring FullSynchronization of buffers path, since GPU has mostly a syncing issue with certain type of textures and vertex calculations, the original behavior of jumping into a non-synchronize path of buffers let GPU ran without proper awareness of the textures being loaded, ensuring more performance if all the textures reached properly inside GPU, but with no safety provided for buffers, even we added a cases were dummies and mostly buffer trash data gets discarded by nullDescriptors, this won't ensure graphical artifacts or a bad calculation on the range of lightning/ gfx could appear. I dare to think this was thought to be implemented due to the original heavy costs on Yuzu's time, this along the removal of QCOM's drivers from Query's Presync funtions.

A small adjustment to the mutable functions inside the CreateImageView structure to add the extended usage:

"Because Switch's GPU creates incompatible views (sRGB and UNORM) on the same image. A sRGB image can't be used as storage but it is in a UNORM view. Which is exactly the use case of these flags." - @weakboson

During all of this changes inside queries, we started to get in some devices "Device Loss" warning from Vulkan along 2 specific warnings:

    - [ 102.384895] Render.Vulkan <Critical> video_core/vulkan_common/vulkan_debug_callback.cpp:69:DebugUtilCallback: vkDeviceWaitIdle(): THREADING ERROR : object of type VkQueue is simultaneously used in current thread 517024609280 and thread 517864567808
    - [ 114.003530] Render.Vulkan <Critical> video_core/vulkan_common/vulkan_debug_callback.cpp:69:DebugUtilCallback: vkCmdBeginQuery(): VkQueryPool 0x15e400000015e4 and query 172: query not reset. After query pool creation, each query must be reset (with vkCmdResetQueryPool or vkResetQueryPool) before it is used. Queries must also be reset between uses.

Since before all of this adjustments, original GPU thread often take it's time to stop and look for a moment to synchronize with CPU (non-TimelineSemaphore), the whole flow data was improved that we were producing more data stale than we could really take due to the lack of a Reset to avoid pools being filled with old data, in order to get rid of this, another try to implement ResetQueryPool's appeared which was intented to be implemented some months ago and got removed in #3270, this time aligning the vkDeviceWaitIdle + ResetQueryPool was proved to be effective than first implementation and didn't caused major issues, now GPU can Vulkan can reset staling data, which can catalogued as old once they were used and displayed in frame, keeping a more fluid exchance and discard of data.

    - Fixes VUID-vkCmdBeginQuery-None-00807
    - Fixes multithreading error with vkDeviceWaitIdle and data allocation

We have some other changes to the coherency of ExtendedDynamicState2 and the feature of restart primitives, which now patches topologies once are processed if they pass through ExtendedDynamicState2 enabled and get reset before every draw to prevent another topology VUID; also I ensured refresh, reset, clamp and overall improve the math inside the Viewport/ Scissor feature operations inside DynamicState and later upgrades.

---------------------------
UPDATE (23/04/2026): After passing a heavy testing phase, an issue was encountered with AMD drivers on Windows which based on the commit:  c07dfa6fb4, Super Mario Odissey started to show vertex glitches on the the waterfall + water fog being rendered incorrectly, if VertexInputDynamicState was disabled caused black screen on ExtendedDynamicState (1 - 3) and hard crash if ExtendedDynamicState it was disabled; this situation was caused to the vertex input dynamic tied to ExtendedDynamicState1, AMD driver didn't allowed fast access to BindVertexBuffers2EXT without binding strides first, which caused a syncing problem between the binded vertex and the missing buffer in the same chain, this got fixed by removing the conditions for vertex input dynamic.

Aside that; another pair of issues were addressed in the meantime of refining this PR, one of them was to solve the failing BGR565 formats to swizzle into RGBA5 which allows to swap between red and blue; solving the inverse situation of blue icons on Mario Kart 8 Deluxe for older QCOM drivers and SoC's, such as Snapdragon 855 - 870; which will also help some Exynos processors to render properly. This solution was converted into a toggle/hack because it's use it's very conditional on older hardware; newer SoC's such as 8 Elite won't longer require this handling to convert properly BGR565 texture even if the support for the format is not available.

---------------------------

Here an small preview of what this pr has been fixed so far, but our testing range may be more limited than what this can actually do:

- Allow to display new effect on games

1. Jump Force: New particle on stages and main menu.
2. The Legend Of Zelda - Echoes of Wisdom: darkness post processing effect on screen filter such as game intro and smokes on houses (8 Elite).
3. Reduce texture flickering on games such as EoW, Monster Hunter Rise.
4. Improved performance stability on various games with Android.
5. Improved Xenoblade games rendering with QCOM stock drivers by improve viewpoint handling (8 Elite).
6. Fixes vertex explosion on Xenoblade 3 with AMD GPU with extended dynamic state enabled.
7. Fixed Mario Kart 8 Deluxe rendering with VK_EXT_vertex_input_dynamic_state enabled.
8. Fixes certain angle of Pokemon Legend Z-A would look mono color with vertex input dynamic state.
9. Fixed graphical issue with VK_EXT_vertex_input_dynamic_state on mobile drivers.
10. Fixed vertex explosion with Turnip (8 Elite) on The Legend Of Zelda- Breath Of The Wild during loading screen.
11. Fixed issue of vertex on Pokémon Legends ZA with VK_EXT_vertex_input_dynamic_state enabled.
12. Improved rendering and stability of Inmortal Fenyx Rising, including QCOM drivers being able to reach into gameplay.
13. Fixes Paper Mario - The-Thousand-Year Door missing rendering on animations through the whole game.
14. Fixed Mario Kart 8 Deluxe blue tint icon on Snapdragon 855 - 870 (by enabling Emulated BGR565 hack toggle).
15. Fixed Naruto Ultimate Ninja Storm issue rendering on characters like Naruto being blue on older QCOM SoC's and Exynos (by enabling Emulated BGR565 hack toggle)
16. Fixed Dangaronpa Killing Harmony v3 issue rendering on characters with blue tint on older QCOM SoC's.
---------------------------

_**Special Thanks - Credits**_

-> @Gidoly for being able to keep track of the intensive testing phase this pr required and the will to keep helping in development, you're a good friend and very useful.
-> @CaptFaraday for the suggestion of the fix for Paper Mario.
-> @wildcard for the review during the refactor of VK_EXT_transform_feedback, without this comment I would probably ran into many untrackable issues.
-> @weakboson for the suggestion into the solution for sRGB's and UNORM's in the incompatible views.

Co-authored-by: lizzie <lizzie@eden-emu.dev>
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3853
Reviewed-by: crueter <crueter@eden-emu.dev>
2026-04-24 16:37:18 +02:00
lizzie 417ed904f0 [dynarmic] fix MWAIT push/pop not being handled properly on xbyak (#3875)
push %edx is not what i wanted, nor what anybody wants, xbyak silently accepting this before was not intended
now that xbyak is updated this is an issue

the issue was simply:
a) ptr being overwritten (if it happened to be EDX/EBX/EAX) due to changed WAITPKG logic (oops)
b) xbyak not reporting wrong r32 pop/push on older versions thus missing it and now it throws an exception

Signed-off-by: lizzie <lizzie@eden-emu.dev>
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3875
Reviewed-by: crueter <crueter@eden-emu.dev>
Reviewed-by: CamilleLaVey <camillelavey99@gmail.com>
2026-04-23 05:06:33 +02:00
wildcard 838cc926f6 keyboard fixes (#3865)
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3865
Reviewed-by: CamilleLaVey <camillelavey99@gmail.com>
2026-04-23 03:43:54 +02:00
coolone 860acb4faf [android] Fix crash on start any games for many handhelds (Ayaneo, Retroid etc) (#3647)
## Summary
This change hardens Android Picture-in-Picture handling to avoid runtime crashes on devices/ROMs where PiP APIs are unavailable or behave inconsistently.

## What changed
- Added a feature gate for PiP support using `FEATURE_PICTURE_IN_PICTURE`.
- Early-returned from PiP flows when unsupported.
- Wrapped PiP API calls (`enterPictureInPictureMode`, `setPictureInPictureParams`) in guarded handlers that catch `IllegalStateException` and `UnsupportedOperationException`.
- Logged one warning per failed PiP action to avoid log spam.

## Why
On some Android devices, calling PiP APIs can throw at runtime even when the app is otherwise functioning normally. This patch prevents those calls from crashing/interrupting emulation and keeps behavior unchanged on supported devices.

## Notes
- No behavior changes for fully PiP-capable devices.
- Safe no-op on unsupported devices.

Co-authored-by: Nikolai Trukhin <coolone.official@gmail.com>
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3647
Reviewed-by: DraVee <chimera@dravee.dev>
Reviewed-by: Lizzie <lizzie@eden-emu.dev>
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
2026-04-22 05:32:52 +02:00
Eden CI a0bb6324c0 [dist, android] Update translations from Transifex for Apr 21 (#3871)
Automatic translation update for Apr 21

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3871
2026-04-21 16:02:40 +02:00
MaranBr 3a823de605 [dynarmic] Remove Ignore Global Monitor from CPU Accuracy Auto (#3846)
This fixes a flickering issue in some games, such as The Legend of Zelda: Echoes of Wisdom.

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3846
Reviewed-by: crueter <crueter@eden-emu.dev>
Reviewed-by: Lizzie <lizzie@eden-emu.dev>
2026-04-21 05:03:43 +02:00
crueter 0257a8d491 [desktop] Change data manager to use tabs instead of a list (#3856)
Signed-off-by: crueter <crueter@eden-emu.dev>
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3856
Reviewed-by: CamilleLaVey <camillelavey99@gmail.com>
Reviewed-by: Lizzie <lizzie@eden-emu.dev>
2026-04-21 04:01:39 +02:00
PavelBARABANOV 6c76908ddb [android] Allow manual overlay toggle even with controller connected + move async GPU options to hacks (#3862)
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3862
Co-authored-by: PavelBARABANOV <pavelbarabanov94@gmail.com>
Co-committed-by: PavelBARABANOV <pavelbarabanov94@gmail.com>
2026-04-17 20:29:45 +02:00
omardotdev e6ad51e3d5 [settings] remove duplicate settings (#3847)
this removes the duplicate serial knob, battery/unit serial shown on the settings tab and uses the debugging tab instead
(this used to be a pr to fix breeze compatibility issues where the text/input fields would look wrong when the theme was set to breeze but since the settings was moved its not really needed to change the window size)

Co-authored-by: Omar <180954465+omardotdev@users.noreply.github.com>
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3847
Reviewed-by: crueter <crueter@eden-emu.dev>
Reviewed-by: Lizzie <lizzie@eden-emu.dev>
Co-authored-by: omardotdev <omardotdev@eden-emu.dev>
Co-committed-by: omardotdev <omardotdev@eden-emu.dev>
2026-04-17 06:58:40 +02:00
Eden CI f11b69d6b7 [dist, android] Update translations from Transifex for Apr 14 (#3859)
Automatic translation update for Apr 14

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3859
Co-authored-by: Eden CI <ci@eden-emu.dev>
Co-committed-by: Eden CI <ci@eden-emu.dev>
2026-04-14 18:14:01 +02:00
xbzk 27cadb24f3 [android, intent] Run restoreContentForGame for shortcut launching + Improve custom settings context for shortcut launching (based on normal launch) (#3854)
intended to fix two bugs identified by Pavel upon android shortcut launching (and prolly all FEs since the rely on intent launching too):
1. external content not loading: fixed by running restoreContentForGame  for per game mount in content path.
2. custom settings no loading: that was proven to be user side, but adjustments were made to match normal launch.
should be harmless for normal usage. once validated can be merged.

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3854
Reviewed-by: CamilleLaVey <camillelavey99@gmail.com>
Co-authored-by: xbzk <xbzk@eden-emu.dev>
Co-committed-by: xbzk <xbzk@eden-emu.dev>
2026-04-14 00:21:51 +02:00
John a7ef19e028 [settings] Exposes the Hidden GPU Async Setting on other Platforms (#3833)
Disabling it may:
- Alleviates and Fixes flickering in Pokemon LZA, Kirby, Jamboree, XCDE, etc.
- Audio improvements in Metroid Prime 4

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3833
Reviewed-by: crueter <crueter@eden-emu.dev>
Co-authored-by: John <john@eden-emu.dev>
Co-committed-by: John <john@eden-emu.dev>
2026-04-13 00:28:12 +02:00
Eden CI 2c1eff2e60 [dist, android] Update translations from Transifex for Apr 11 (#3850)
Automatic translation update for Apr 11

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3850
Co-authored-by: Eden CI <ci@eden-emu.dev>
Co-committed-by: Eden CI <ci@eden-emu.dev>
2026-04-11 18:37:13 +02:00
xbzk abb616c357 [vk,swapchain] vsync: Changed Immediate fallback from (FIFO) to (Mailbox, then FIFO) (#3746)
Just discovered that stock adreno drivers on a730 had no Immediate VSync mode available, and it was falling back to FIFO, which causes a lot of response delay in Unity games.

But if someone chose Immediate, it prefers low latency above buffering, so Mailbox is his friend, and FIFO is his nemesis.

So i just changed Immediate to fall back to Mailbox first, and only if Mailbox is not available either it falls back to FIFO:

Immediate -> Mailbox -> FIFO;
Mailbox -> FIFO;
FIFO Relaxed -> FIFO.

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3746
Reviewed-by: crueter <crueter@eden-emu.dev>
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
Co-authored-by: xbzk <xbzk@eden-emu.dev>
Co-committed-by: xbzk <xbzk@eden-emu.dev>
2026-04-11 02:49:55 +02:00
lizzie c95cb8f8ec [hle] improved flusher that uses jthread (#3837)
not happy with this impl, but I made this a bit quickly to demostrate it can be done better :)

Signed-off-by: lizzie <lizzie@eden-emu.dev>

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3837
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
Reviewed-by: CamilleLaVey <camillelavey99@gmail.com>
Co-authored-by: lizzie <lizzie@eden-emu.dev>
Co-committed-by: lizzie <lizzie@eden-emu.dev>
2026-04-09 23:46:38 +02:00
168 changed files with 11658 additions and 10514 deletions
+3 -1
View File
@@ -3,6 +3,8 @@ name: Check Strings
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
jobs:
check-strings:
@@ -10,7 +12,7 @@ jobs:
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
fetch-depth: 1
- name: Find Unused Strings
run: ./tools/unused-strings.sh
-14
View File
@@ -1,14 +0,0 @@
diff --git a/external/CMakeLists.txt b/external/CMakeLists.txt
index eb4e69e..3155805 100644
--- a/external/CMakeLists.txt
+++ b/external/CMakeLists.txt
@@ -72,7 +72,8 @@ if (SPIRV_TOOLS_USE_MIMALLOC)
pop_variable(MI_BUILD_TESTS)
endif()
-if (DEFINED SPIRV-Headers_SOURCE_DIR)
+# NetBSD doesn't have SPIRV-Headers readily available on system
+if (DEFINED SPIRV-Headers_SOURCE_DIR AND NOT ${CMAKE_SYSTEM_NAME} STREQUAL "NetBSD")
# This allows flexible position of the SPIRV-Headers repo.
set(SPIRV_HEADER_DIR ${SPIRV-Headers_SOURCE_DIR})
else()
@@ -1,287 +0,0 @@
From 67bf3d1381b1faf59e87001d6156ba4e21cada14 Mon Sep 17 00:00:00 2001
From: crueter <crueter@eden-emu.dev>
Date: Mon, 29 Dec 2025 21:22:36 -0500
Subject: [PATCH] [cmake] refactor: shared/static handling
This significantly redoes the way shared and static libraries are
handled. Now, it's controlled by two options: `SPIRV_TOOLS_BUILD_STATIC`
and `SPIRV_TOOLS_BUILD_SHARED`.
The default configuration (no `BUILD_SHARED_LIBS` set, options left at
default) is to build shared ONLY if this is the master project, or
static ONLY if this is a subproject (e.g. FetchContent, CPM.cmake). Also
I should note that static-only (i.e. no shared) is now a supported
target, this is done because projects including it as a submodule e.g.
on Android or Windows may prefer this.
Now the shared/static handling:
- static ON, shared OFF: Only generates `.a` libraries.
- static ON, shared ON: Generates `.a` libraries, but also
`libSPIRV-Tools.so`
- static OFF, shared ON: Only generates `.so` libraries.
Notable TODOs:
- SPIRV-Tools-shared.pc seems redundant--how should we handle which one
to use in the case of distributions that distribute both types (MSYS2
for instance)?
* *Note: pkgconfig sucks at this and usually just leaves it up to the
user, so the optimal solution may indeed be doing absolutely
nothing.* CMake is unaffected :)
- use namespaces in the CMake config files pleaaaaase
This is going to change things a good bit for package maintainers, but
cest la vie. It's for the greater good, I promise.
Signed-off-by: crueter <crueter@eden-emu.dev>
---
CMakeLists.txt | 108 +++++++++++++++++++++++++-----------------
source/CMakeLists.txt | 62 ++++++++++++------------
2 files changed, 94 insertions(+), 76 deletions(-)
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 4d843b4d2f..07201f690f 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -14,6 +14,15 @@
cmake_minimum_required(VERSION 3.22.1)
+# master project detection--useful for FetchContent/submodule inclusion
+set(master_project OFF)
+set(subproject ON)
+
+if (NOT DEFINED PROJECT_NAME)
+ set(master_project ON)
+ set(subproject OFF)
+endif()
+
project(spirv-tools)
# Avoid a bug in CMake 3.22.1. By default it will set -std=c++11 for
@@ -135,46 +144,49 @@ if (DEFINED SPIRV_TOOLS_EXTRA_DEFINITIONS)
add_definitions(${SPIRV_TOOLS_EXTRA_DEFINITIONS})
endif()
-# Library build setting definitions:
-#
-# * SPIRV_TOOLS_BUILD_STATIC - ON or OFF - Defaults to ON.
-# If enabled the following targets will be created:
-# ${SPIRV_TOOLS}-static - STATIC library.
-# Has full public symbol visibility.
-# ${SPIRV_TOOLS}-shared - SHARED library.
-# Has default-hidden symbol visibility.
-# ${SPIRV_TOOLS} - will alias to one of above, based on BUILD_SHARED_LIBS.
-# If disabled the following targets will be created:
-# ${SPIRV_TOOLS} - either STATIC or SHARED based on SPIRV_TOOLS_LIBRARY_TYPE.
-# Has full public symbol visibility.
-# ${SPIRV_TOOLS}-shared - SHARED library.
-# Has default-hidden symbol visibility.
-#
-# * SPIRV_TOOLS_LIBRARY_TYPE - SHARED or STATIC.
-# Specifies the library type used for building SPIRV-Tools libraries.
-# Defaults to SHARED when BUILD_SHARED_LIBS=1, otherwise STATIC.
-#
-# * SPIRV_TOOLS_FULL_VISIBILITY - "${SPIRV_TOOLS}-static" or "${SPIRV_TOOLS}"
-# Evaluates to the SPIRV_TOOLS target library name that has no hidden symbols.
-# This is used by internal targets for accessing symbols that are non-public.
-# Note this target provides no API stability guarantees.
-#
-# Ideally, all of these will go away - see https://github.com/KhronosGroup/SPIRV-Tools/issues/3909.
-option(ENABLE_EXCEPTIONS_ON_MSVC "Build SPIRV-TOOLS with c++ exceptions enabled in MSVC" ON)
-option(SPIRV_TOOLS_BUILD_STATIC "Build ${SPIRV_TOOLS}-static target. ${SPIRV_TOOLS} will alias to ${SPIRV_TOOLS}-static or ${SPIRV_TOOLS}-shared based on BUILD_SHARED_LIBS" ON)
-if(SPIRV_TOOLS_BUILD_STATIC)
- set(SPIRV_TOOLS_FULL_VISIBILITY ${SPIRV_TOOLS}-static)
+# If BUILD_SHARED_LIBS is undefined, set it based on whether we are
+# the master project or a subproject
+if (NOT DEFINED BUILD_SHARED_LIBS)
+ set(BUILD_SHARED_LIBS ${master_project})
+endif()
+
+if (BUILD_SHARED_LIBS)
+ set(static_default OFF)
+else()
+ set(static_default ON)
+endif()
+
+option(SPIRV_TOOLS_BUILD_SHARED "Build ${SPIRV_TOOLS} as a shared library"
+ ${BUILD_SHARED_LIBS})
+option(SPIRV_TOOLS_BUILD_STATIC "Build ${SPIRV_TOOLS} as a static library"
+ ${static_default})
+
+# Avoid conflict between the dll import library and
+# the static library (thanks microsoft)
+if(CMAKE_STATIC_LIBRARY_PREFIX STREQUAL "" AND
+ CMAKE_STATIC_LIBRARY_SUFFIX STREQUAL ".lib")
+ set(SPIRV_TOOLS_STATIC_LIBNAME "${SPIRV_TOOLS}-static")
+else()
+ set(SPIRV_TOOLS_STATIC_LIBNAME "${SPIRV_TOOLS}")
+endif()
+
+if (SPIRV_TOOLS_BUILD_STATIC)
+ # If building a static library at all, always build other libraries as static,
+ # and link to the static SPIRV-Tools library.
set(SPIRV_TOOLS_LIBRARY_TYPE "STATIC")
-else(SPIRV_TOOLS_BUILD_STATIC)
- set(SPIRV_TOOLS_FULL_VISIBILITY ${SPIRV_TOOLS})
- if (NOT DEFINED SPIRV_TOOLS_LIBRARY_TYPE)
- if(BUILD_SHARED_LIBS)
- set(SPIRV_TOOLS_LIBRARY_TYPE "SHARED")
- else()
- set(SPIRV_TOOLS_LIBRARY_TYPE "STATIC")
- endif()
- endif()
-endif(SPIRV_TOOLS_BUILD_STATIC)
+ set(SPIRV_TOOLS_FULL_VISIBILITY ${SPIRV_TOOLS}-static)
+elseif (SPIRV_TOOLS_BUILD_SHARED)
+ # If only building a shared library, link other libraries to the
+ # shared library. Also, other libraries should be shared
+ set(SPIRV_TOOLS_LIBRARY_TYPE "SHARED")
+ set(SPIRV_TOOLS_FULL_VISIBILITY ${SPIRV_TOOLS}-shared)
+else()
+ message(FATAL_ERROR "You must set one of "
+ "SPIRV_TOOLS_BUILD_STATIC or SPIRV_TOOLS_BUILD_SHARED!")
+endif()
+
+option(ENABLE_EXCEPTIONS_ON_MSVC
+ "Build SPIRV-TOOLS with C++ exceptions enabled in MSVC" ON)
function(spvtools_default_compile_options TARGET)
target_compile_options(${TARGET} PRIVATE ${SPIRV_WARNINGS})
@@ -372,7 +384,7 @@ if (NOT "${SPIRV_SKIP_TESTS}")
endif()
set(SPIRV_LIBRARIES "-lSPIRV-Tools-opt -lSPIRV-Tools -lSPIRV-Tools-link")
-set(SPIRV_SHARED_LIBRARIES "-lSPIRV-Tools-shared")
+set(SPIRV_SHARED_LIBRARIES "-lSPIRV-Tools")
# Build pkg-config file
# Use a first-class target so it's regenerated when relevant files are updated.
@@ -388,7 +400,12 @@ add_custom_command(
-DSPIRV_LIBRARIES=${SPIRV_LIBRARIES}
-P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/write_pkg_config.cmake
DEPENDS "CHANGES" "${CMAKE_CURRENT_SOURCE_DIR}/cmake/SPIRV-Tools.pc.in" "${CMAKE_CURRENT_SOURCE_DIR}/cmake/write_pkg_config.cmake")
-add_custom_command(
+
+set(pc_files ${CMAKE_CURRENT_BINARY_DIR}/SPIRV-Tools.pc)
+
+# TODO(crueter): remove?
+if (SPIRV_TOOLS_BUILD_SHARED)
+ add_custom_command(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/SPIRV-Tools-shared.pc
COMMAND ${CMAKE_COMMAND}
-DCHANGES_FILE=${CMAKE_CURRENT_SOURCE_DIR}/CHANGES
@@ -400,9 +417,12 @@ add_custom_command(
-DSPIRV_SHARED_LIBRARIES=${SPIRV_SHARED_LIBRARIES}
-P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/write_pkg_config.cmake
DEPENDS "CHANGES" "${CMAKE_CURRENT_SOURCE_DIR}/cmake/SPIRV-Tools-shared.pc.in" "${CMAKE_CURRENT_SOURCE_DIR}/cmake/write_pkg_config.cmake")
-add_custom_target(spirv-tools-pkg-config
- ALL
- DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/SPIRV-Tools-shared.pc ${CMAKE_CURRENT_BINARY_DIR}/SPIRV-Tools.pc)
+ set(pc_files ${pc_files} ${CMAKE_CURRENT_BINARY_DIR}/SPIRV-Tools-shared.pc)
+endif()
+
+add_custom_target(spirv-tools-pkg-config
+ ALL
+ DEPENDS ${pc_files})
# Install pkg-config file
if (ENABLE_SPIRV_TOOLS_INSTALL)
diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt
index bfa1e661bc..fd3712c70c 100644
--- a/source/CMakeLists.txt
+++ b/source/CMakeLists.txt
@@ -337,49 +337,44 @@ function(spirv_tools_default_target_options target)
)
set_property(TARGET ${target} PROPERTY FOLDER "SPIRV-Tools libraries")
spvtools_check_symbol_exports(${target})
- add_dependencies(${target} spirv-tools-build-version core_tables extinst_tables)
+ add_dependencies(${target}
+ spirv-tools-build-version core_tables extinst_tables)
endfunction()
-# Always build ${SPIRV_TOOLS}-shared. This is expected distro packages, and
-# unlike the other SPIRV_TOOLS target, defaults to hidden symbol visibility.
-add_library(${SPIRV_TOOLS}-shared SHARED ${SPIRV_SOURCES})
-if (SPIRV_TOOLS_USE_MIMALLOC)
- target_link_libraries(${SPIRV_TOOLS}-shared PRIVATE mimalloc-static)
+if (SPIRV_TOOLS_BUILD_SHARED)
+ add_library(${SPIRV_TOOLS}-shared SHARED ${SPIRV_SOURCES})
+ if (SPIRV_TOOLS_USE_MIMALLOC)
+ target_link_libraries(${SPIRV_TOOLS}-shared PRIVATE mimalloc-static)
+ endif()
+
+ set_target_properties(${SPIRV_TOOLS}-shared PROPERTIES
+ OUTPUT_NAME "${SPIRV_TOOLS}")
+ spirv_tools_default_target_options(${SPIRV_TOOLS}-shared)
+
+ target_compile_definitions(${SPIRV_TOOLS}-shared
+ PRIVATE SPIRV_TOOLS_IMPLEMENTATION
+ PUBLIC SPIRV_TOOLS_SHAREDLIB)
+
+ list(APPEND SPIRV_TOOLS_TARGETS ${SPIRV_TOOLS}-shared)
endif()
-spirv_tools_default_target_options(${SPIRV_TOOLS}-shared)
-set_target_properties(${SPIRV_TOOLS}-shared PROPERTIES CXX_VISIBILITY_PRESET hidden)
-target_compile_definitions(${SPIRV_TOOLS}-shared
- PRIVATE SPIRV_TOOLS_IMPLEMENTATION
- PUBLIC SPIRV_TOOLS_SHAREDLIB
-)
if(SPIRV_TOOLS_BUILD_STATIC)
add_library(${SPIRV_TOOLS}-static STATIC ${SPIRV_SOURCES})
if (SPIRV_TOOLS_USE_MIMALLOC AND SPIRV_TOOLS_USE_MIMALLOC_IN_STATIC_BUILD)
target_link_libraries(${SPIRV_TOOLS}-shared PRIVATE mimalloc-static)
endif()
+
spirv_tools_default_target_options(${SPIRV_TOOLS}-static)
- # The static target does not have the '-static' suffix.
- set_target_properties(${SPIRV_TOOLS}-static PROPERTIES OUTPUT_NAME "${SPIRV_TOOLS}")
-
- # Create the "${SPIRV_TOOLS}" target as an alias to either "${SPIRV_TOOLS}-static"
- # or "${SPIRV_TOOLS}-shared" depending on the value of BUILD_SHARED_LIBS.
- if(BUILD_SHARED_LIBS)
- add_library(${SPIRV_TOOLS} ALIAS ${SPIRV_TOOLS}-shared)
- else()
- add_library(${SPIRV_TOOLS} ALIAS ${SPIRV_TOOLS}-static)
- endif()
+ set_target_properties(${SPIRV_TOOLS}-static PROPERTIES
+ OUTPUT_NAME "${SPIRV_TOOLS_STATIC_LIBNAME}")
- set(SPIRV_TOOLS_TARGETS ${SPIRV_TOOLS}-static ${SPIRV_TOOLS}-shared)
-else()
- add_library(${SPIRV_TOOLS} ${SPIRV_TOOLS_LIBRARY_TYPE} ${SPIRV_SOURCES})
- if (SPIRV_TOOLS_USE_MIMALLOC)
- target_link_libraries(${SPIRV_TOOLS} PRIVATE mimalloc-static)
- endif()
- spirv_tools_default_target_options(${SPIRV_TOOLS})
- set(SPIRV_TOOLS_TARGETS ${SPIRV_TOOLS} ${SPIRV_TOOLS}-shared)
+ list(APPEND SPIRV_TOOLS_TARGETS ${SPIRV_TOOLS}-static)
endif()
+# Create the "SPIRV-Tools" target as an alias to either "SPIRV-Tools-static"
+# or "SPIRV-Tools-shared" depending on the value of SPIRV_TOOLS_BUILD_SHARED.
+add_library(${SPIRV_TOOLS} ALIAS ${SPIRV_TOOLS_FULL_VISIBILITY})
+
if("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux")
find_library(LIBRT rt)
if(LIBRT)
@@ -390,14 +385,17 @@ if("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux")
endif()
if(ENABLE_SPIRV_TOOLS_INSTALL)
- if (SPIRV_TOOLS_USE_MIMALLOC AND (NOT SPIRV_TOOLS_BUILD_STATIC OR SPIRV_TOOLS_USE_MIMALLOC_IN_STATIC_BUILD))
+ if (SPIRV_TOOLS_USE_MIMALLOC AND
+ (NOT SPIRV_TOOLS_BUILD_STATIC OR SPIRV_TOOLS_USE_MIMALLOC_IN_STATIC_BUILD))
list(APPEND SPIRV_TOOLS_TARGETS mimalloc-static)
endif()
install(TARGETS ${SPIRV_TOOLS_TARGETS} EXPORT ${SPIRV_TOOLS}Targets)
export(EXPORT ${SPIRV_TOOLS}Targets FILE ${SPIRV_TOOLS}Target.cmake)
spvtools_config_package_dir(${SPIRV_TOOLS} PACKAGE_DIR)
- install(EXPORT ${SPIRV_TOOLS}Targets FILE ${SPIRV_TOOLS}Target.cmake DESTINATION ${PACKAGE_DIR})
+ install(EXPORT ${SPIRV_TOOLS}Targets
+ FILE ${SPIRV_TOOLS}Target.cmake
+ DESTINATION ${PACKAGE_DIR})
# Special config file for root library compared to other libs.
file(WRITE ${CMAKE_BINARY_DIR}/${SPIRV_TOOLS}Config.cmake
-2
View File
@@ -130,7 +130,6 @@ if (YUZU_STATIC_BUILD)
# these libs do not properly provide static libs/let you do it with cmake
set(fmt_FORCE_BUNDLED ON)
set(SPIRV-Tools_FORCE_BUNDLED ON)
set(SPIRV-Headers_FORCE_BUNDLED ON)
set(zstd_FORCE_BUNDLED ON)
endif()
@@ -523,7 +522,6 @@ if (NOT YUZU_STATIC_ROOM)
find_package(VulkanMemoryAllocator)
find_package(VulkanUtilityLibraries)
find_package(SimpleIni)
find_package(SPIRV-Tools)
find_package(sirit)
find_package(gamemode)
find_package(frozen)
-26
View File
@@ -1,26 +0,0 @@
# SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
# SPDX-License-Identifier: GPL-3.0-or-later
# SPDX-FileCopyrightText: 2022 yuzu Emulator Project
# SPDX-License-Identifier: GPL-2.0-or-later
include(FindPackageHandleStandardArgs)
find_package(PkgConfig QUIET)
pkg_search_module(SPIRV-Tools QUIET IMPORTED_TARGET SPIRV-Tools)
find_package_handle_standard_args(SPIRV-Tools
REQUIRED_VARS SPIRV-Tools_LINK_LIBRARIES
VERSION_VAR SPIRV-Tools_VERSION
)
if (PLATFORM_MSYS)
FixMsysPath(PkgConfig::SPIRV-Tools)
endif()
if (SPIRV-Tools_FOUND AND NOT TARGET SPIRV-Tools::SPIRV-Tools)
if (TARGET SPIRV-Tools)
add_library(SPIRV-Tools::SPIRV-Tools ALIAS SPIRV-Tools)
else()
add_library(SPIRV-Tools::SPIRV-Tools ALIAS PkgConfig::SPIRV-Tools)
endif()
endif()
+5 -5
View File
@@ -35,17 +35,17 @@ set(GIT_DESC ${BUILD_VERSION})
# Generate cpp with Git revision from template
# Also if this is a CI build, add the build name (ie: Nightly, Canary) to the scm_rev file as well
# Auto-updater metadata! Must somewhat mirror GitHub API endpoint
# Auto-updater metadata! Must somewhat mirror GitHub/Forgejo API endpoint
set(BUILD_AUTO_UPDATE_API_PATH "/latest/release.json")
if (NIGHTLY_BUILD)
set(BUILD_AUTO_UPDATE_WEBSITE "https://git.eden-emu.dev")
set(BUILD_AUTO_UPDATE_API "git.eden-emu.dev")
set(BUILD_AUTO_UPDATE_API_PATH "/api/v1/repos/")
set(BUILD_AUTO_UPDATE_API "nightly.eden-emu.dev")
set(BUILD_AUTO_UPDATE_REPO "eden-ci/nightly")
set(REPO_NAME "Eden Nightly")
else()
set(BUILD_AUTO_UPDATE_WEBSITE "https://git.eden-emu.dev")
set(BUILD_AUTO_UPDATE_API "git.eden-emu.dev")
set(BUILD_AUTO_UPDATE_API_PATH "/api/v1/repos/")
set(BUILD_AUTO_UPDATE_API "stable.eden-emu.dev")
set(BUILD_AUTO_UPDATE_REPO "eden-emu/eden")
set(REPO_NAME "Eden")
endif()
+334 -337
View File
File diff suppressed because it is too large Load Diff
+302 -306
View File
File diff suppressed because it is too large Load Diff
+302 -306
View File
File diff suppressed because it is too large Load Diff
+302 -306
View File
File diff suppressed because it is too large Load Diff
+302 -306
View File
File diff suppressed because it is too large Load Diff
+302 -306
View File
File diff suppressed because it is too large Load Diff
+334 -337
View File
File diff suppressed because it is too large Load Diff
+302 -306
View File
File diff suppressed because it is too large Load Diff
+304 -308
View File
File diff suppressed because it is too large Load Diff
+302 -306
View File
File diff suppressed because it is too large Load Diff
+364 -367
View File
File diff suppressed because it is too large Load Diff
+304 -308
View File
File diff suppressed because it is too large Load Diff
+302 -306
View File
File diff suppressed because it is too large Load Diff
+302 -306
View File
File diff suppressed because it is too large Load Diff
+303 -307
View File
File diff suppressed because it is too large Load Diff
+302 -306
View File
File diff suppressed because it is too large Load Diff
+304 -308
View File
File diff suppressed because it is too large Load Diff
+496 -472
View File
File diff suppressed because it is too large Load Diff
+302 -306
View File
File diff suppressed because it is too large Load Diff
+984 -981
View File
File diff suppressed because it is too large Load Diff
+305 -308
View File
File diff suppressed because it is too large Load Diff
+304 -308
View File
File diff suppressed because it is too large Load Diff
+305 -308
View File
File diff suppressed because it is too large Load Diff
+302 -306
View File
File diff suppressed because it is too large Load Diff
+302 -306
View File
File diff suppressed because it is too large Load Diff
+304 -308
View File
File diff suppressed because it is too large Load Diff
+302 -306
View File
File diff suppressed because it is too large Load Diff
-8
View File
@@ -192,14 +192,6 @@ else()
endif()
endif()
# SPIRV Tools
AddJsonPackage(spirv-tools)
if (SPIRV-Tools_ADDED)
add_library(SPIRV-Tools::SPIRV-Tools ALIAS SPIRV-Tools-static)
target_link_libraries(SPIRV-Tools-static PRIVATE SPIRV-Tools-opt SPIRV-Tools-link)
endif()
# Catch2
if (YUZU_TESTS OR DYNARMIC_TESTS)
AddJsonPackage(catch2)
-14
View File
@@ -102,20 +102,6 @@
"git_version": "1.3.18",
"find_args": "MODULE"
},
"spirv-tools": {
"package": "SPIRV-Tools",
"repo": "KhronosGroup/SPIRV-Tools",
"sha": "0a7e28689a",
"hash": "eadfcceb82f4b414528d99962335e4f806101168474028f3cf7691ac40c37f323decf2a42c525e2d5bfa6f14ff132d6c5cf9b87c151490efad01f5e13ade1520",
"git_version": "2025.4",
"options": [
"SPIRV_SKIP_EXECUTABLES ON"
],
"patches": [
"0001-netbsd-fix.patch",
"0002-allow-static-only.patch"
]
},
"spirv-headers": {
"package": "SPIRV-Headers",
"repo": "KhronosGroup/SPIRV-Headers",
+2 -2
View File
@@ -1,4 +1,4 @@
# SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
# SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
# SPDX-License-Identifier: GPL-3.0-or-later
# SPDX-FileCopyrightText: 2021 yuzu Emulator Project
@@ -254,7 +254,7 @@ else()
OUTPUT
${FFmpeg_BUILD_LIBRARIES}
COMMAND
make ${FFmpeg_MAKE_ARGS}
gmake ${FFmpeg_MAKE_ARGS}
WORKING_DIRECTORY
${FFmpeg_BUILD_DIR}
)
@@ -15,6 +15,7 @@ import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.content.pm.PackageManager
import android.content.res.Configuration
import android.graphics.Rect
import android.graphics.drawable.Icon
@@ -100,6 +101,7 @@ class EmulationActivity : AppCompatActivity(), SensorEventListener, InputManager
private var romSwapGeneration = 0
private var hasEmulationSession = processHasEmulationSession
private val romSwapStopTimeoutRunnable = Runnable { onRomSwapStopTimeout() }
private val pictureInPictureFailureActions: MutableSet<String> = mutableSetOf()
private fun onRomSwapStopTimeout() {
if (!isWaitingForRomSwapStop) {
@@ -266,12 +268,18 @@ class EmulationActivity : AppCompatActivity(), SensorEventListener, InputManager
}
override fun onUserLeaveHint() {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) {
if (BooleanSetting.PICTURE_IN_PICTURE.getBoolean() && !isInPictureInPictureMode) {
val pictureInPictureParamsBuilder = PictureInPictureParams.Builder()
.getPictureInPictureActionsBuilder().getPictureInPictureAspectBuilder()
enterPictureInPictureMode(pictureInPictureParamsBuilder.build())
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S ||
!isPictureInPictureSupported() ||
!BooleanSetting.PICTURE_IN_PICTURE.getBoolean() ||
isInPictureInPictureMode
) {
return
}
val pictureInPictureParamsBuilder = PictureInPictureParams.Builder()
.getPictureInPictureActionsBuilder().getPictureInPictureAspectBuilder()
runPictureInPictureAction("enter picture-in-picture mode") {
enterPictureInPictureMode(pictureInPictureParamsBuilder.build())
}
}
@@ -651,7 +659,29 @@ class EmulationActivity : AppCompatActivity(), SensorEventListener, InputManager
return this.apply { setActions(pictureInPictureActions) }
}
private fun isPictureInPictureSupported() =
Build.VERSION.SDK_INT >= Build.VERSION_CODES.O &&
packageManager.hasSystemFeature(PackageManager.FEATURE_PICTURE_IN_PICTURE)
private fun runPictureInPictureAction(actionName: String, action: () -> Unit) {
try {
action()
} catch (e: IllegalStateException) {
if (pictureInPictureFailureActions.add(actionName)) {
Log.warning("[PiP] Failed to $actionName: ${e.message}")
}
} catch (e: UnsupportedOperationException) {
if (pictureInPictureFailureActions.add(actionName)) {
Log.warning("[PiP] Failed to $actionName: ${e.message}")
}
}
}
fun buildPictureInPictureParams() {
if (!isPictureInPictureSupported()) {
return
}
val pictureInPictureParamsBuilder = PictureInPictureParams.Builder()
.getPictureInPictureActionsBuilder().getPictureInPictureAspectBuilder()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
@@ -661,7 +691,9 @@ class EmulationActivity : AppCompatActivity(), SensorEventListener, InputManager
BooleanSetting.PICTURE_IN_PICTURE.getBoolean() && isEmulationActive
)
}
setPictureInPictureParams(pictureInPictureParamsBuilder.build())
runPictureInPictureAction("set picture-in-picture params") {
setPictureInPictureParams(pictureInPictureParamsBuilder.build())
}
}
fun displayMultiplayerDialog() {
@@ -1,3 +1,7 @@
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
@@ -33,8 +37,10 @@ object SoftwareKeyboard {
val emulationActivity = NativeLibrary.sEmulationActivity.get()
val overlayView = emulationActivity!!.findViewById<View>(R.id.surface_input_overlay)
overlayView.requestFocus()
val im =
overlayView.context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
im.restartInput(overlayView)
im.showSoftInput(overlayView, InputMethodManager.SHOW_FORCED)
// There isn't a good way to know that the IMM is dismissed, so poll every 500ms to submit inline keyboard result.
@@ -17,6 +17,7 @@ enum class BooleanSetting(override val key: String) : AbstractBooleanSetting {
USE_CUSTOM_CPU_TICKS("use_custom_cpu_ticks"),
SKIP_CPU_INNER_INVALIDATION("skip_cpu_inner_invalidation"),
FIX_BLOOM_EFFECTS("fix_bloom_effects"),
EMULATE_BGR565("emulate_bgr565"),
CPUOPT_UNSAFE_HOST_MMU("cpuopt_unsafe_host_mmu"),
USE_DOCKED_MODE("use_docked_mode"),
USE_AUTO_STUB("use_auto_stub"),
@@ -33,6 +34,10 @@ enum class BooleanSetting(override val key: String) : AbstractBooleanSetting {
RENDERER_DEBUG("debug"),
RENDERER_PATCH_OLD_QCOM_DRIVERS("patch_old_qcom_drivers"),
RENDERER_VERTEX_INPUT_DYNAMIC_STATE("vertex_input_dynamic_state"),
FORCE_IDENTITY_SWIZZLE("force_identity_swizzle"),
FORCE_LDR_TO_SRGB("force_ldr_to_srgb"),
RENDERER_PROVOKING_VERTEX("provoking_vertex"),
RENDERER_DESCRIPTOR_INDEXING("descriptor_indexing"),
RENDERER_SAMPLE_SHADING("sample_shading"),
GPU_UNSWIZZLE_ENABLED("gpu_unswizzle_enabled"),
PICTURE_IN_PICTURE("picture_in_picture"),
@@ -17,6 +17,8 @@ enum class IntSetting(override val key: String) : AbstractIntSetting {
RENDERER_VRAM_USAGE_MODE("vram_usage_mode"),
RENDERER_NVDEC_EMULATION("nvdec_emulation"),
RENDERER_ASTC_DECODE_METHOD("accelerate_astc"),
RENDERER_ASTC_RECOMPRESSION("astc_recompression"),
RENDERER_FORMAT_REINTERPRETATION("format_reinterpretation"),
RENDERER_ACCURACY("gpu_accuracy"),
RENDERER_RESOLUTION("resolution_setup"),
RENDERER_VSYNC("use_vsync"),
@@ -24,7 +26,6 @@ enum class IntSetting(override val key: String) : AbstractIntSetting {
RENDERER_ANTI_ALIASING("anti_aliasing"),
RENDERER_SCREEN_LAYOUT("screen_layout"),
RENDERER_ASPECT_RATIO("aspect_ratio"),
RENDERER_OPTIMIZE_SPIRV_OUTPUT("optimize_spirv_output"),
RENDERER_DYNA_STATE("dyna_state"),
DMA_ACCURACY("dma_accuracy"),
@@ -148,6 +148,34 @@ abstract class SettingsItem(
descriptionId = R.string.vertex_input_dynamic_state_description
)
)
put(
SwitchSetting(
BooleanSetting.FORCE_IDENTITY_SWIZZLE,
titleId = R.string.force_identity_swizzle,
descriptionId = R.string.force_identity_swizzle_description
)
)
put(
SwitchSetting(
BooleanSetting.FORCE_LDR_TO_SRGB,
titleId = R.string.force_ldr_to_srgb,
descriptionId = R.string.force_ldr_to_srgb_description
)
)
put(
SwitchSetting(
BooleanSetting.RENDERER_DESCRIPTOR_INDEXING,
titleId = R.string.descriptor_indexing,
descriptionId = R.string.descriptor_indexing_description
)
)
put(
SwitchSetting(
BooleanSetting.RENDERER_SAMPLE_SHADING,
titleId = R.string.sample_shading,
descriptionId = R.string.sample_shading_description
)
)
put(
SliderSetting(
IntSetting.RENDERER_SAMPLE_SHADING,
@@ -335,6 +363,23 @@ abstract class SettingsItem(
valuesId = R.array.astcDecodingMethodValues
)
)
put(
SingleChoiceSetting(
IntSetting.RENDERER_ASTC_RECOMPRESSION,
titleId = R.string.astc_recompression,
descriptionId = R.string.astc_recompression_description,
choicesId = R.array.astcRecompressionMethodNames,
valuesId = R.array.astcRecompressionMethodValues
)
)
put(
SingleChoiceSetting(
IntSetting.RENDERER_FORMAT_REINTERPRETATION,
titleId = R.string.format_reinterpretation,
choicesId = R.array.formatReinterpretationNames,
valuesId = R.array.formatReinterpretationValues
)
)
put(
SingleChoiceSetting(
IntSetting.RENDERER_VRAM_USAGE_MODE,
@@ -643,15 +688,6 @@ abstract class SettingsItem(
descriptionId = R.string.renderer_async_presentation_description
)
)
put(
SingleChoiceSetting(
IntSetting.RENDERER_OPTIMIZE_SPIRV_OUTPUT,
titleId = R.string.renderer_optimize_spirv_output,
descriptionId = R.string.renderer_optimize_spirv_output_description,
choicesId = R.array.optimizeSpirvOutputEntries,
valuesId = R.array.optimizeSpirvOutputValues
)
)
put(
SingleChoiceSetting(
IntSetting.DMA_ACCURACY,
@@ -756,6 +792,13 @@ abstract class SettingsItem(
descriptionId = R.string.fix_bloom_effects_description
)
)
put(
SwitchSetting(
BooleanSetting.EMULATE_BGR565,
titleId = R.string.emulate_bgr565,
descriptionId = R.string.emulate_bgr565_description
)
)
put(
SwitchSetting(
BooleanSetting.CPUOPT_UNSAFE_HOST_MMU,
@@ -271,7 +271,6 @@ class SettingsFragmentPresenter(
add(IntSetting.FSR_SHARPENING_SLIDER.key)
}
add(IntSetting.RENDERER_ANTI_ALIASING.key)
add(IntSetting.RENDERER_OPTIMIZE_SPIRV_OUTPUT.key)
add(HeaderSetting(R.string.advanced))
@@ -284,8 +283,6 @@ class SettingsFragmentPresenter(
add(BooleanSetting.SYNC_MEMORY_OPERATIONS.key)
add(BooleanSetting.RENDERER_USE_DISK_SHADER_CACHE.key)
add(BooleanSetting.RENDERER_FORCE_MAX_CLOCK.key)
add(BooleanSetting.RENDERER_ASYNCHRONOUS_GPU_EMULATION.key)
add(BooleanSetting.RENDERER_ASYNC_PRESENTATION.key)
add(BooleanSetting.RENDERER_REACTIVE_FLUSHING.key)
add(BooleanSetting.ENABLE_BUFFER_HISTORY.key)
add(BooleanSetting.USE_OPTIMIZED_VERTEX_BUFFERS.key)
@@ -295,7 +292,10 @@ class SettingsFragmentPresenter(
add(IntSetting.FAST_GPU_TIME.key)
add(BooleanSetting.SKIP_CPU_INNER_INVALIDATION.key)
add(BooleanSetting.FIX_BLOOM_EFFECTS.key)
add(BooleanSetting.EMULATE_BGR565.key)
add(BooleanSetting.RENDERER_ASYNCHRONOUS_SHADERS.key)
add(BooleanSetting.RENDERER_ASYNCHRONOUS_GPU_EMULATION.key)
add(BooleanSetting.RENDERER_ASYNC_PRESENTATION.key)
add(SettingsItem.GPU_UNSWIZZLE_COMBINED)
add(HeaderSetting(R.string.extensions))
@@ -291,13 +291,23 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
// Game launched via intent (check for existing custom config)
intentGame != null -> {
game?.let { gameInstance ->
runCatching { GameHelper.restoreContentForGame(gameInstance) }
.onFailure {
Log.warning(
"[EmulationFragment] Failed to restore content for intent launch: ${it.message}"
)
}
val customConfigFile = SettingsFile.getCustomSettingsFile(gameInstance)
if (customConfigFile.exists()) {
shouldUseCustom = true
Log.info(
"[EmulationFragment] Found existing custom settings for ${gameInstance.title}, loading them"
)
SettingsFile.loadCustomConfig(gameInstance)
NativeConfig.unloadPerGameConfig()
} else {
shouldUseCustom = false
Log.info(
"[EmulationFragment] No custom settings found for ${gameInstance.title}, using global settings"
)
@@ -871,7 +881,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
if (drawerView == binding.quickSettingsSheet) {
isQuickSettingsMenuOpen = true
if (shouldUseCustom) {
SettingsFile.loadCustomConfig(args.game!!)
SettingsFile.loadCustomConfig(game!!)
}
}
}
@@ -2499,7 +2509,6 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
fun toggleOverlay(enable: Boolean) {
if (!isAdded || _binding == null) return
if (enable && hasPhysicalControllerConnected && !args.overlayGamelessEditMode) return
if (enable == !BooleanSetting.SHOW_INPUT_OVERLAY.getBoolean()) {
// Reset controller input flag so controller can hide overlay again
if (!enable) {
@@ -2537,7 +2546,8 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
if (binding.surfaceInputOverlay.isGamelessMode()) return
if (hasConnectedControllers) {
if (BooleanSetting.SHOW_INPUT_OVERLAY.getBoolean()) {
if (BooleanSetting.SHOW_INPUT_OVERLAY.getBoolean() &&
BooleanSetting.HIDE_OVERLAY_ON_CONTROLLER_INPUT.getBoolean()) {
overlayHiddenByPhysicalController = true
toggleOverlay(false)
}
@@ -17,16 +17,23 @@ import android.graphics.drawable.VectorDrawable
import android.os.Build
import android.os.Handler
import android.os.Looper
import android.text.Editable
import android.text.InputType
import android.util.AttributeSet
import android.view.HapticFeedbackConstants
import android.view.KeyEvent
import android.view.MotionEvent
import android.view.View
import android.view.View.OnTouchListener
import android.view.WindowInsets
import android.view.inputmethod.BaseInputConnection
import android.view.inputmethod.EditorInfo
import android.view.inputmethod.InputConnection
import androidx.core.content.ContextCompat
import androidx.window.layout.WindowMetricsCalculator
import kotlin.math.max
import kotlin.math.min
import org.yuzu.yuzu_emu.NativeLibrary
import org.yuzu.yuzu_emu.features.input.NativeInput
import org.yuzu.yuzu_emu.R
import org.yuzu.yuzu_emu.features.input.model.NativeAnalog
@@ -49,6 +56,7 @@ class InputOverlay(context: Context, attrs: AttributeSet?) :
private val overlayButtons: MutableSet<InputOverlayDrawableButton> = HashSet()
private val overlayDpads: MutableSet<InputOverlayDrawableDpad> = HashSet()
private val overlayJoysticks: MutableSet<InputOverlayDrawableJoystick> = HashSet()
private val imeEditable = Editable.Factory.getInstance().newEditable("")
private var inEditMode = false
private var gamelessMode = false
@@ -75,6 +83,63 @@ class InputOverlay(context: Context, attrs: AttributeSet?) :
// External listener for EmulationFragment joypad overlay auto-hide
var touchEventListener: ((MotionEvent) -> Unit)? = null
override fun onCheckIsTextEditor(): Boolean = true
override fun onCreateInputConnection(outAttrs: EditorInfo): InputConnection {
imeEditable.clear()
outAttrs.inputType =
InputType.TYPE_CLASS_TEXT or
InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS or
InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD
outAttrs.imeOptions = EditorInfo.IME_FLAG_NO_EXTRACT_UI or EditorInfo.IME_ACTION_DONE
outAttrs.initialSelStart = 0
outAttrs.initialSelEnd = 0
return object : BaseInputConnection(this, true) {
override fun getEditable(): Editable = imeEditable
override fun commitText(text: CharSequence?, newCursorPosition: Int): Boolean {
if (!text.isNullOrEmpty()) {
forwardCommittedText(text)
}
return super.commitText(text, newCursorPosition)
}
override fun deleteSurroundingText(beforeLength: Int, afterLength: Int): Boolean {
repeat(beforeLength.coerceAtLeast(0)) {
NativeLibrary.submitInlineKeyboardInput(KeyEvent.KEYCODE_DEL)
}
return super.deleteSurroundingText(beforeLength, afterLength)
}
override fun sendKeyEvent(event: KeyEvent): Boolean {
if (event.action != KeyEvent.ACTION_DOWN) {
return true
}
when (event.keyCode) {
KeyEvent.KEYCODE_BACK,
KeyEvent.KEYCODE_DEL,
KeyEvent.KEYCODE_ENTER -> {
NativeLibrary.submitInlineKeyboardInput(event.keyCode)
}
else -> {
val textChar = event.unicodeChar
if (textChar != 0) {
NativeLibrary.submitInlineKeyboardText(textChar.toChar().toString())
}
}
}
return true
}
override fun performEditorAction(actionCode: Int): Boolean {
NativeLibrary.submitInlineKeyboardInput(KeyEvent.KEYCODE_ENTER)
return true
}
}
}
override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) {
super.onLayout(changed, left, top, right, bottom)
@@ -119,6 +184,25 @@ class InputOverlay(context: Context, attrs: AttributeSet?) :
}
}
private fun forwardCommittedText(text: CharSequence) {
val builder = StringBuilder()
text.forEach { character ->
when (character) {
'\n' -> {
if (builder.isNotEmpty()) {
NativeLibrary.submitInlineKeyboardText(builder.toString())
builder.clear()
}
NativeLibrary.submitInlineKeyboardInput(KeyEvent.KEYCODE_ENTER)
}
else -> builder.append(character)
}
}
if (builder.isNotEmpty()) {
NativeLibrary.submitInlineKeyboardText(builder.toString())
}
}
private fun drawGrid(canvas: Canvas) {
val gridSize = IntSetting.OVERLAY_GRID_SIZE.getInt()
val width = canvas.width
@@ -95,7 +95,7 @@ namespace AndroidSettings {
Settings::Setting<u32> input_overlay_auto_hide{linkage, 5, "input_overlay_auto_hide",
Settings::Category::Overlay,
Settings::Specialization::Default, true, true, &enable_input_overlay_auto_hide};
Settings::Setting<bool> hide_overlay_on_controller_input{linkage, false,
Settings::Setting<bool> hide_overlay_on_controller_input{linkage, true,
"hide_overlay_on_controller_input",
Settings::Category::Overlay,
Settings::Specialization::Default, true,
+6 -8
View File
@@ -1726,9 +1726,8 @@ JNIEXPORT jstring JNICALL Java_org_yuzu_yuzu_1emu_NativeLibrary_getUpdateUrl(
jobject obj,
jstring version) {
const char* version_str = env->GetStringUTFChars(version, nullptr);
const std::string url = fmt::format("{}/{}/releases/tag/{}",
std::string{Common::g_build_auto_update_website},
std::string{Common::g_build_auto_update_repo},
const std::string url = fmt::format("{}/{}",
std::string{Common::g_build_auto_update_api},
version_str);
env->ReleaseStringUTFChars(version, version_str);
return env->NewStringUTF(url.c_str());
@@ -1760,11 +1759,10 @@ JNIEXPORT jstring JNICALL Java_org_yuzu_yuzu_1emu_NativeLibrary_getUpdateApkUrl(
}
const std::string apk_filename = fmt::format("Eden-Android-{}-{}.apk", artifact_str, variant);
const std::string url = fmt::format("{}/{}/releases/download/{}/{}",
std::string{Common::g_build_auto_update_website},
std::string{Common::g_build_auto_update_repo},
version_str,
apk_filename);
const std::string url = fmt::format("{}/{}/{}",
std::string{Common::g_build_auto_update_api},
version_str, apk_filename);
env->ReleaseStringUTFChars(tag, version_str);
env->ReleaseStringUTFChars(artifact, artifact_str);
@@ -32,7 +32,7 @@
<string name="hide_overlay_on_controller_input">إخفاء الطبقة عند إدخال ذراع التحكم</string>
<string name="hide_overlay_on_controller_input_description">إخفاء تلقائي لطبقة عناصر التحكم باللمس عند استخدام ذراع تحكم فعلية. تظهر الطبقة مرة أخرى عند فصل ذراع التحكم.</string>
<string name="invert_confirm_back_controller_buttons">عكس أزرار التأكيد/الرجوع في وحدة التحكم</string>
<string name="invert_confirm_back_controller_buttons_description">قم بتبديل طريقة عمل زري التأكيد والرجوع في نظام Android لتتوافق مع أنماط Switch و Xbox أثناء استخدام واجهة المستخدم الخاصة بالتطبيق.</string>
<string name="invert_confirm_back_controller_buttons_description">تبديل طريقة التعامل مع زري «تأكيد» و«رجوع» في نظام Android لتتوافق مع أنماط أجهزة Switch وXbox أثناء استخدام واجهة المستخدم الخاصة بالتطبيق.</string>
<string name="input_overlay_options">طبقة الإدخال</string>
<string name="input_overlay_options_description">ضبط ذراع التحكم على الشاشة</string>
@@ -268,7 +268,7 @@
<string name="product">المنتج</string>
<string name="android_version">إصدار Android</string>
<string name="android_security_patch">تصحيح الأمان</string>
<string name="build_id">معرف البناء</string>
<string name="build_id">معرف الإصدار</string>
<string name="general_information">معلومات عامة</string>
<string name="hardware">الأجهزة</string>
<string name="supported_abis">واجهات برمجة التطبيقات المدعومة</string>
@@ -287,7 +287,7 @@
<string name="install_amiibo_keys">تثبيت مفاتيح أميبو</string>
<string name="install_amiibo_keys_description">مطلوب لاستخدام أميبو في اللعبة</string>
<string name="gpu_driver_fetcher">أداة جلب برامج تشغيل وحدة المعالجة الرسومية</string>
<string name="gpu_driver_manager">مدير برامج تشغيل وحدة معالجة الرسومات</string>
<string name="gpu_driver_manager">إدارة برامج تشغيل وحدة معالجة الرسومات</string>
<string name="install_gpu_driver_description">تثبيت برامج تشغيل بديلة لأداء أو دقة أفضل</string>
<string name="advanced_settings">الإعدادات المتقدمة</string>
<string name="settings_description">ضبط إعدادات المحاكي</string>
@@ -403,7 +403,7 @@
<string name="contributors">المساهمين</string>
<string name="contributors_description">الأشخاص الذين جعلوا تطبيق Eden لنظام Android ممكنًا</string>
<string name="licenses_description">المشاريع التي تجعل Eden لأجهزة Android ممكنة</string>
<string name="build">البناء</string>
<string name="build">الإصدار</string>
<string name="user_data">بيانات المستخدم</string>
<string name="user_data_description">استيراد/تصدير جميع بيانات التطبيق.\nعند استيراد بيانات المستخدم، سيتم حذف جميع بيانات المستخدم الموجودة!\nقد يُسبب استيراد البيانات من Citron بعض المشاكل. يُنصح باستيراد جميع البيانات المطلوبة يدويًا.</string>
<string name="exporting_user_data">جارٍ تصدير بيانات المستخدم...</string>
@@ -463,8 +463,6 @@
<string name="fsr_sharpness">حدة FSR</string>
<string name="fsr_sharpness_description">يحدد مدى وضوح الصورة عند استخدام التباين الديناميكي لـ FSR</string>
<string name="renderer_anti_aliasing">طريقة مضاد التعرج</string>
<string name="renderer_optimize_spirv_output">تحسين مخرجات SPIRV</string>
<string name="renderer_optimize_spirv_output_description">يعمل على تحسين أداء برامج التظليل المجمعة لتحسين كفاءة وحدة معالجة الرسومات، ولكنه قد يؤدي إلى زيادة وقت التحميل وإبطاء السرعة في البداية.</string>
<string name="advanced">متقدم</string>
@@ -486,12 +484,16 @@
<string name="use_disk_shader_cache_description">يقلل من التأتأة عن طريق تخزين وتحميل التظليلات التي تم إنشاؤها محليًا.</string>
<string name="renderer_force_max_clock">إجبار السرعة القصوى (لأجهزة Adreno فقط)</string>
<string name="renderer_force_max_clock_description">يجبر وحدة معالجة الرسومات على العمل بأقصى سرعة ممكنة (سيظل يتم تطبيق القيود الحرارية).</string>
<string name="renderer_asynchronous_gpu_emulation">محاكاة غير متزامنة لوحدة معالجة الرسومات</string>
<string name="renderer_asynchronous_gpu_emulation_description">يُشغّل هذا الخيار محاكاة وحدة معالجة الرسومات بشكل غير متزامن لتقليل توقف وحدة المعالجة المركزية وتحسين الإنتاجية. عطّل هذا الخيار فقط في حال واجهت مشاكل متعلقة بالتوقيت.</string>
<string name="renderer_async_presentation">عرض غير متزامن</string>
<string name="renderer_async_presentation_description">يحسّن الأداء بشكل طفيف عن طريق نقل عملية العرض إلى خيط معالجة منفصل لوحدة المعالجة المركزية.</string>
<string name="renderer_reactive_flushing">استخدم التنظيف التفاعلي</string>
<string name="renderer_reactive_flushing_description">يحسن دقة العرض في بعض الألعاب على حساب الأداء.</string>
<string name="enable_buffer_history">تمكين سجل التخزين المؤقت</string>
<string name="enable_buffer_history_description">يُتيح هذا الخيار الوصول إلى حالات التخزين المؤقت السابقة. وقد يُحسّن جودة العرض وثبات الأداء في بعض الألعاب.</string>
<string name="use_optimized_vertex_buffers">مخازن الرؤوس المُحسّنة</string>
<string name="use_optimized_vertex_buffers_description">يُتيح ربطًا مُحسَّنًا لمخازن الرؤوس لتحسين الأداء. يتطلب برامج تشغيل Turnip من Mesa 26.0 أو أحدث. قد يتعطل على برامج التشغيل الأقدم.</string>
<string name="use_optimized_vertex_buffers_description">يتيح ربط مخزن الرؤوس المُحسّن لتحسين الأداء. يتطلب برامج تشغيل Turnip/QCOM من إصدار Mesa 26.0 أو أحدث. سيؤدي إلى تعطل النظام عند استخدام برامج تشغيل Turnip الأقدم.</string>
<string name="hacks">اختراقات</string>
@@ -500,7 +502,9 @@
<string name="skip_cpu_inner_invalidation">تخطي إبطال صلاحية وحدة المعالجة المركزية الداخلية</string>
<string name="skip_cpu_inner_invalidation_description">يتخطى بعض عمليات إبطال ذاكرة التخزين المؤقتة من جانب وحدة المعالجة المركزية أثناء تحديثات الذاكرة، مما يقلل من استخدام وحدة المعالجة المركزية ويحسن أداءها. قد يتسبب ذلك في حدوث أعطال أو تعطل في بعض الألعاب.</string>
<string name="fix_bloom_effects">إصلاح تأثيرات التوهج</string>
<string name="fix_bloom_effects_description">يقلل من ضبابية التوهج في LA/EOW (Adreno 700)، ويزيل التوهج في Burnout. تحذير: قد يسبب ظهور خلل رسومي في ألعاب أخرى.</string>
<string name="fix_bloom_effects_description">يقلل من ضبابية التوهج في LA/EOW (Adreno A6XX - A7XX/ Turnip)، ويزيل التوهج في Burnout. تحذير: قد يسبب تشوهات رسومية في ألعاب أخرى.</string>
<string name="emulate_bgr565">محاكاة BGR565</string>
<string name="emulate_bgr565_description">يُصلح مشاكل انعكاس الألوان في الألعاب أو ظهور تشوهات غريبة أو ظلال غريبة.</string>
<string name="renderer_asynchronous_shaders">استخدم تظليل غير متزامن</string>
<string name="renderer_asynchronous_shaders_description">يقوم بتجميع التظليل بشكل غير متزامن. قد يقلل ذلك من التقطعات ولكنه قد يؤدي أيضًا إلى حدوث أخطاء.</string>
<string name="gpu_unswizzle_settings">إعدادات إلغاء ترتيب بيانات وحدة معالجة الرسومات</string>
@@ -627,10 +631,10 @@
<string name="gamecube_controller">ذراع تحكم GameCube</string>
<string name="invert_axis">عكس المحور</string>
<string name="invert_button">عكس الزر</string>
<string name="toggle_button">زر التبديل</string>
<string name="toggle_button">زر تشغيل/إيقاف</string>
<string name="turbo_button">زر التوربو</string>
<string name="set_threshold">تعيين الحد الفاصل</string>
<string name="toggle_axis">تبديل المحور</string>
<string name="toggle_axis">تشغيل/إيقاف المحور</string>
<string name="connected">متصل</string>
<string name="use_system_vibrator">استخدم هزاز النظام</string>
<string name="input_overlay">طبقة الإدخال</string>
@@ -656,7 +660,7 @@
<!-- Miscellaneous -->
<string name="slider_default">افتراضي</string>
<string name="default_string">الافتراضي</string>
<string name="default_string">افتراضي</string>
<string name="loading">جارٍ التحميل…</string>
<string name="shutting_down">جارٍ إيقاف التشغيل...</string>
<string name="reset_setting_confirmation">هل تريد إعادة تعيين هذا الإعداد إلى قيمته الافتراضية؟</string>
@@ -682,8 +686,8 @@
<string name="import_success">تم الاستيراد بنجاح</string>
<string name="export_success">تم التصدير بنجاح</string>
<string name="start">بدء</string>
<string name="global">المتغيرات العامة</string>
<string name="custom">مخصص</string>
<string name="global">الإعدادات العامة</string>
<string name="custom">الإعدادات المخصصة للعبة</string>
<string name="import_complete">اكتمل الاستيراد</string>
<string name="use_global_setting">استخدام الإعداد العام</string>
<string name="operation_completed_successfully">اكتملت العملية بنجاح</string>
@@ -762,7 +766,7 @@
<string name="info_description">معرف العنوان، المطور، الإصدار</string>
<string name="per_game_settings">الإعدادات الخاصة للعبة</string>
<string name="per_game_settings_description">تعديل الإعدادات الخاصة بهذه اللعبة</string>
<string name="launch_options">تشغيل الإعدادات</string>
<string name="launch_options">إعدادات التشغيل</string>
<string name="path">المسار</string>
<string name="program_id">معرف العنوان</string>
<string name="developer">المطور</string>
@@ -874,13 +878,13 @@
<!-- Emulation Menu -->
<string name="emulation_exit">خروج من المحاكاة</string>
<string name="emulation_done">إنهاء</string>
<string name="emulation_toggle_controls">تبديل أزرار التحكم</string>
<string name="emulation_toggle_controls">تشغيل/إيقاف أزرار التحكم</string>
<string name="emulation_rel_stick_center">مركز العصا النسبي</string>
<string name="emulation_dpad_slide">انزلاق الأسهم</string>
<string name="emulation_haptics">الاهتزازات الديناميكية</string>
<string name="emulation_show_overlay">عرض ذراع التحكم</string>
<string name="emulation_hide_overlay">إخفاء ذراع التحكم</string>
<string name="emulation_toggle_all">تبديل الكل</string>
<string name="emulation_toggle_all">تشغيل/إيقاف الكل</string>
<string name="emulation_control_adjust">ضبط الطبقة</string>
<string name="emulation_control_scale">الحجم</string>
<string name="emulation_control_opacity">الشفافية</string>
@@ -1122,7 +1126,7 @@
<string name="enable_overlay_description">تمكين التطبيق الصغير المدمج في Horizon. اضغط مع الاستمرار على زر الشاشة الرئيسية لمدة 1 ثانية لإظهاره.</string>
<!-- Profile Management -->
<string name="profile_manager">مدير الملف الشخصي</string>
<string name="profile_manager">إدارة ملف التعريف</string>
<string name="profile_manager_description">إدارة ملفات تعريف المستخدمين</string>
<string name="profile_add_user">إضافة مستخدم</string>
<string name="profile_new_user">مستخدم جديد</string>
@@ -332,7 +332,6 @@
<string name="fsr_sharpness">تیژی FSR</string>
<string name="fsr_sharpness_description">دیاریکردنی تیژی وێنە لە کاتی بەکارهێنانی FSR</string>
<string name="renderer_anti_aliasing">شێوازی دژە-خاوڕۆیی</string>
<string name="renderer_optimize_spirv_output_description">شێیدەرە کۆمپایلکراوەکان باش دەکات بۆ باشترکردنی کارایی GPU.</string>
<string name="dma_accuracy">وردیی DMA</string>
@@ -442,8 +442,6 @@
<string name="fsr_sharpness">Ostrost FSR</string>
<string name="fsr_sharpness_description">Určuje jak ostře bude obraz vypadat při použití dynamického kontrastu FSR.</string>
<string name="renderer_anti_aliasing">Metoda anti-aliasingu</string>
<string name="renderer_optimize_spirv_output">Optimalizovat výstup SPIRV</string>
<string name="renderer_optimize_spirv_output_description">Optimalizuje kompilované shadery pro zlepšení efektivity GPU, ale mohou se objevit delší nahrávací časy a zpomalení v úvodu.</string>
<string name="advanced">Pokročilé</string>
@@ -442,8 +442,6 @@ Wird der Handheld-Modus verwendet, verringert es die Auflösung und erhöht die
<string name="fsr_sharpness">FSR-Schärfe</string>
<string name="fsr_sharpness_description">Bestimmt die Schärfe bei FSR-Nutzung.</string>
<string name="renderer_anti_aliasing">Kantenglättung</string>
<string name="renderer_optimize_spirv_output">Optimiere SPIRV-Ausgabe</string>
<string name="renderer_optimize_spirv_output_description">Optimiert den kompilierten Shader, um die GPU-Effizienz zu verbessern.</string>
<string name="advanced">Erweitert</string>
@@ -351,7 +351,7 @@
<item quantity="other">%d archivos de guardado importados con éxito.</item>
</plurals>
<string name="no_save_data_found">No se encontraron datos de guardado</string>
<string name="verify_installed_content">Verificar contenido instalado</string>
<string name="verify_installed_content">Verificar los contenidos instalados</string>
<string name="verify_installed_content_description">Comprueba todo el contenido instalado por si hubiese alguno corrupto</string>
<string name="keys_missing">Faltan las claves de encriptación</string>
@@ -457,8 +457,6 @@
<string name="fsr_sharpness">Nitidez FSR</string>
<string name="fsr_sharpness_description">Ajusta la intensidad del filtro de enfoque al usar el contraste dinámico de FSR.</string>
<string name="renderer_anti_aliasing">Método de suavizado de bordes</string>
<string name="renderer_optimize_spirv_output">Optimizar la salida de SPIRV</string>
<string name="renderer_optimize_spirv_output_description">Optimiza los sombreadores compilados para mejorar la eficiencia de la GPU.</string>
<string name="advanced">Avanzado</string>
@@ -480,12 +478,16 @@
<string name="use_disk_shader_cache_description">Reduce los tirones almacenando y cargando los sombreadores generados.</string>
<string name="renderer_force_max_clock">Forzar velocidad al máximo (solo Adreno)</string>
<string name="renderer_force_max_clock_description">Fuerza a la GPU a ejecutarse a la velocidad máxima de reloj posible (se seguirán aplicando restricciones térmicas).</string>
<string name="renderer_asynchronous_gpu_emulation">Emulación de GPU asíncrona</string>
<string name="renderer_asynchronous_gpu_emulation_description">Ejecuta la emulación de la GPU de forma asíncrona para reducir los bloqueos de la CPU y mejorar el rendimiento. Desactiva esta opción solo si experimentas problemas de sincronización.</string>
<string name="renderer_async_presentation">Presentación asíncrona</string>
<string name="renderer_async_presentation_description">Mejora ligeramente el rendimiento al mover la presentación a un hilo independiente de la CPU.</string>
<string name="renderer_reactive_flushing">Usar limpieza reactiva</string>
<string name="renderer_reactive_flushing_description">Mejora la precisión de renderizado en algunos juegos, pero reduce el rendimiento.</string>
<string name="enable_buffer_history">Activar el historial del búfer</string>
<string name="enable_buffer_history_description">Permite el acceso al estado del búfer anterior. Esta opción puede mejorar la calidad de renderizado y la consistencia en el rendimiento de algunos juegos.</string>
<string name="use_optimized_vertex_buffers">Búferes de vértices optimizados</string>
<string name="use_optimized_vertex_buffers_description">Permite la vinculación optimizada del búfer de vértices para un mejor rendimiento. Requiere controladores de Mesa 26.0+ Turnip. Se producin fallos en controladores más antiguos.</string>
<string name="use_optimized_vertex_buffers_description">Permite la optimización del enlace del búfer de vértices para un mejor rendimiento. Requiere controladores Mesa 26.0+ Turnip/ controladores QCOM. Causará fallos con controladores Turnip más antiguos.</string>
<string name="hacks">Hacks</string>
@@ -494,7 +496,9 @@
<string name="skip_cpu_inner_invalidation">Omitir invalidación interna de la CPU</string>
<string name="skip_cpu_inner_invalidation_description">Omite ciertas invalidaciones de caché de la CPU durante las actualizaciones de memoria, lo que reduce el uso de la CPU y mejora su rendimiento. Esto puede causar fallos o bloqueos en algunos juegos.</string>
<string name="fix_bloom_effects">Arreglar los efectos de resplandor</string>
<string name="fix_bloom_effects_description">Reduce el efecto de resplandor en LA/EOW (Adreno 700), elimina el resplandor en Burnout. Advertencia: puede causar artefactos gráficos en otros juegos.</string>
<string name="fix_bloom_effects_description">Reduce el efecto de resplandor en LA/EOW (Adreno A6XX - A7XX/ Turnip), elimina el resplandor en Burnout. Advertencia: puede causar artefactos gráficos en otros juegos.</string>
<string name="emulate_bgr565">Emular BGR565</string>
<string name="emulate_bgr565_description">Soluciona problemas con colores invertidos en juegos, artefactos o sombras extrañas.</string>
<string name="renderer_asynchronous_shaders">Usar sombreadores asíncronos</string>
<string name="renderer_asynchronous_shaders_description">Compila los sombreadores de forma asíncrona. Esto puede reducir los tirones, pero también puede introducir errores gráficos.</string>
<string name="gpu_unswizzle_settings">Ajustes de desentrelazado de la GPU</string>
@@ -125,8 +125,6 @@
<string name="nvdec_emulation_none">هیچ‌کدام</string>
<!-- Optimize Spir-V output -->
<string name="renderer_optimize_spirv_output">بهینه‌سازی خروجی Spir-V</string>
<string name="renderer_optimize_spirv_output_description">شیدر کامپایل شده را برای بهبود کارایی GPU بهینه‌سازی می‌کند.</string>
<string name="never">هرگز</string>
<string name="on_load">در هنگام بارگذاری</string>
<string name="always">همیشه</string>
@@ -455,7 +455,6 @@
<string name="fsr_sharpness">Netteté FSR</string>
<string name="fsr_sharpness_description">Détermine à quel point l\'image sera affinée lors de l\'utilisation du contraste dynamique FSR.</string>
<string name="renderer_anti_aliasing">Méthode d\'anticrénelage</string>
<string name="renderer_optimize_spirv_output_description">Optimise le shader compilé pour améliorer l\'efficacité du GPU.</string>
<string name="dma_accuracy">Précision DMA</string>
@@ -362,7 +362,6 @@
<string name="fsr_sharpness">חדות FSR</string>
<string name="fsr_sharpness_description">קובע את מידת החדות בעת שימוש ב-FSR.</string>
<string name="renderer_anti_aliasing">שיטת Anti-aliasing</string>
<string name="renderer_optimize_spirv_output_description">משפר את השאדר המהודר כדי להגביר את יעילות ה-GPU.</string>
<string name="dma_accuracy">דיוק DMA</string>
@@ -351,7 +351,6 @@
<string name="fsr_sharpness">FSR élesség</string>
<string name="fsr_sharpness_description">Meghatározza, milyen éles lesz a kép az FSR dinamikus kontraszt használata közben.</string>
<string name="renderer_anti_aliasing">Élsimítási módszer</string>
<string name="renderer_optimize_spirv_output_description">Optimalizálja a lefordított shadert a GPU hatékonyságának javításáért.</string>
<string name="dma_accuracy">DMA pontosság</string>
@@ -383,7 +383,6 @@
<string name="fsr_sharpness">Ketajaman FSR</string>
<string name="fsr_sharpness_description">Menentukan seberapa tajam gambar akan terlihat saat menggunakan kontras dinamis FSR</string>
<string name="renderer_anti_aliasing">Metode anti-aliasing</string>
<string name="renderer_optimize_spirv_output_description">Mengoptimalkan shader yang dikompilasi untuk meningkatkan efisiensi GPU.</string>
<string name="dma_accuracy">Akurasi DMA</string>
@@ -390,7 +390,6 @@
<string name="fsr_sharpness">Nitidezza FSR</string>
<string name="fsr_sharpness_description">Determina quanto sarà nitida l\'immagine utilizzando il contrasto dinamico di FSR</string>
<string name="renderer_anti_aliasing">Metodo di anti-aliasing</string>
<string name="renderer_optimize_spirv_output_description">Ottimizza lo shader compilato per migliorare l\'efficienza della GPU.</string>
<string name="dma_accuracy">Precisione DMA</string>
@@ -349,7 +349,6 @@
<string name="renderer_vsync">垂直同期モード</string>
<string name="renderer_scaling_filter">ウィンドウ適応フィルター</string>
<string name="renderer_anti_aliasing">アンチエイリアス方式</string>
<string name="renderer_optimize_spirv_output_description">コンパイル済みシェーダーを最適化し、GPUの効率を向上させます。</string>
<string name="dma_accuracy">DMA精度</string>
@@ -349,7 +349,6 @@
<string name="renderer_vsync">수직동기화 모드</string>
<string name="renderer_scaling_filter">윈도우 적응 필터</string>
<string name="renderer_anti_aliasing">안티에일리어싱 방법</string>
<string name="renderer_optimize_spirv_output_description">컴파일된 셰이더를 최적화하여 GPU 효율성을 향상시킵니다.</string>
<string name="dma_accuracy">DMA 정확도</string>
@@ -332,7 +332,6 @@
<string name="fsr_sharpness">FSR-skarphet</string>
<string name="fsr_sharpness_description">Bestemmer bildekvalitet med FSR</string>
<string name="renderer_anti_aliasing">Anti-aliasing-metode</string>
<string name="renderer_optimize_spirv_output_description">Optimaliserer den kompilerte shaderen for å forbedre GPU-effektiviteten.</string>
<string name="dma_accuracy">DMA-nøyaktighet</string>
@@ -442,8 +442,6 @@
<string name="fsr_sharpness">Ostrość FSR</string>
<string name="fsr_sharpness_description">Kontroluje ostrość obrazu w FSR.</string>
<string name="renderer_anti_aliasing">Metoda wygładzania krawędzi</string>
<string name="renderer_optimize_spirv_output">Optymalizuj wyjście SPIRV</string>
<string name="renderer_optimize_spirv_output_description">Optymalizuje skompilowany shader w celu poprawy wydajności GPU.</string>
<string name="advanced">Zaawansowane</string>
@@ -433,7 +433,6 @@
<string name="fsr_sharpness">Nitidez do FSR</string>
<string name="fsr_sharpness_description">Determina a nitidez da imagem ao utilizar o contraste dinâmico do FSR</string>
<string name="renderer_anti_aliasing">Método de Anti-aliasing</string>
<string name="renderer_optimize_spirv_output_description">Otimiza o shader compilado para melhorar a eficiência da GPU.</string>
<string name="advanced">Avançado</string>
@@ -355,7 +355,6 @@
<string name="fsr_sharpness">Nitidez do FSR</string>
<string name="fsr_sharpness_description">Determina a nitidez da imagem ao usar contraste dinâmico do FSR</string>
<string name="renderer_anti_aliasing">Método de Anti-Serrilhado</string>
<string name="renderer_optimize_spirv_output_description">Otimiza o shader compilado para melhorar a eficiência da GPU.</string>
<string name="dma_accuracy">Precisão da DMA</string>
@@ -459,8 +459,6 @@
<string name="fsr_sharpness">Резкость FSR</string>
<string name="fsr_sharpness_description">Определяет, насколько чётким будет изображение при использовании динамического контраста FSR.</string>
<string name="renderer_anti_aliasing">Метод сглаживания</string>
<string name="renderer_optimize_spirv_output">Оптимизация вывода SPIRV</string>
<string name="renderer_optimize_spirv_output_description">Оптимизирует скомпилированный шейдер для повышения эффективности ГПУ.</string>
<string name="advanced">Расширенные</string>
@@ -482,13 +480,15 @@
<string name="use_disk_shader_cache_description">Уменьшение зависаний за счет хранения и загрузки сгенерированных шейдеров.</string>
<string name="renderer_force_max_clock">Принудительная максимальная тактовая частота (только для Adreno)</string>
<string name="renderer_force_max_clock_description">Заставляет ГПУ работать на максимально возможных тактовых частотах (тепловые ограничения все равно будут применяться).</string>
<string name="renderer_asynchronous_gpu_emulation">Асинхронная эмуляция ГПУ</string>
<string name="renderer_asynchronous_gpu_emulation_description">Выполняет эмуляцию ГПУ асинхронно для снижения задержек ЦП и увеличения производительности. Отключайте только при возникновении проблем с таймингами.</string>
<string name="renderer_async_presentation">Асинхронная презентация</string>
<string name="renderer_async_presentation_description">Немного улучшает производительность, перемещая презентацию в отдельный поток ЦП.</string>
<string name="renderer_reactive_flushing">Реактивная очистка</string>
<string name="renderer_reactive_flushing_description">Повышение точности рендеринга в некоторых играх за счет снижения производительности.</string>
<string name="enable_buffer_history">Включить историю буфера</string>
<string name="enable_buffer_history_description">Позволяет обращаться к предыдущим состояниям буфера. Эта опция может повысить качество рендеринга и стабильность производительности в некоторых играх.</string>
<string name="use_optimized_vertex_buffers">Оптимизированные вершинные буферы</string>
<string name="use_optimized_vertex_buffers_description">Активирует оптимизированную привязку вершинных буферов для улучшения производительности. Требуются Mesa Turnip драйвера версией не ниже 26.0, на более старых драйверах будут происходить сбои и краши</string>
<string name="hacks">Хаки</string>
<string name="fast_gpu_time">Быстрое время ГПУ</string>
@@ -496,7 +496,6 @@
<string name="skip_cpu_inner_invalidation">Пропустить внутреннюю инвалидацию ЦП</string>
<string name="skip_cpu_inner_invalidation_description">Пропускает некоторые инвалидации кэша на стороне ЦП при обновлениях памяти, уменьшая нагрузку на процессор и повышая производительность. Может вызывать сбои в некоторых играх.</string>
<string name="fix_bloom_effects">Исправить эффекты размытия</string>
<string name="fix_bloom_effects_description">Частично убирает размытие в LA/EOW (Adreno 700), полностью отключает его в Burnout. Внимание: может вызывать графические артефакты в других играх.</string>
<string name="renderer_asynchronous_shaders">Использовать асинхронные шейдеры</string>
<string name="renderer_asynchronous_shaders_description">Компилирует шейдеры асинхронно. Это может уменьшить подтормаживания, но также может вызвать графические артефакты.</string>
<string name="gpu_unswizzle_settings">Настройки распаковки текстур (Unswizzle)</string>
@@ -1080,6 +1079,7 @@
<string name="app_language_system">Следовать системе</string>
<!-- Static Themes -->
<string name="static_theme_color">Цвет темы</string>
<string name="eden_theme">Eden</string>
<string name="violet">Фиолетовый </string>
<string name="blue">Синий</string>
<string name="cyan">Циановый</string>
@@ -354,7 +354,6 @@
<string name="fsr_sharpness">ФСР оштрина</string>
<string name="fsr_sharpness_description">Одређује колико ће се слика наоштрен трајати док користи \"ФСР\" динамички контраст</string>
<string name="renderer_anti_aliasing">Метода против алиасирања</string>
<string name="renderer_optimize_spirv_output_description">Оптимизира састављена схадер за побољшање ефикасности ГПУ-а.</string>
<string name="dma_accuracy">DMA тачност</string>
@@ -459,8 +459,6 @@
<string name="fsr_sharpness">Різкість FSR</string>
<string name="fsr_sharpness_description">Визначає різкість зображення при використанні FSR.</string>
<string name="renderer_anti_aliasing">Згладжування</string>
<string name="renderer_optimize_spirv_output">Оптимізовувати виведення SPIRV</string>
<string name="renderer_optimize_spirv_output_description">Оптимізує скомпільований шейдер для покращення ефективності GPU.</string>
<string name="advanced">Додаткові</string>
@@ -482,12 +480,16 @@
<string name="use_disk_shader_cache_description">Зменшує затримки шляхом збереження шейдерів.</string>
<string name="renderer_force_max_clock">Максимальна тактова частота (тільки Adreno)</string>
<string name="renderer_force_max_clock_description">Змушує GPU працювати на максимальній тактовій частоті.</string>
<string name="renderer_asynchronous_gpu_emulation">Асинхронна емуляція ГП</string>
<string name="renderer_asynchronous_gpu_emulation_description">Емуляція ГП виконується асинхронно для зменшення затримок ЦП й покращення пропускної здатності. Вимкніть лише у випадку виникнення проблем із таймінгами.</string>
<string name="renderer_async_presentation">Асинхронне подання</string>
<string name="renderer_async_presentation_description">Трохи покращує продуктивність завдяки переміщенню подання на окремий потік ЦП.</string>
<string name="renderer_reactive_flushing">Реактивне очищення</string>
<string name="renderer_reactive_flushing_description">Покращує точність рендерингу в деяких іграх.</string>
<string name="enable_buffer_history">Увімкнути історію буфера</string>
<string name="enable_buffer_history_description">Вмикає доступ до попередніх станів буфера. Цей параметр може покращити якість візуалізації та стабільну продуктивність у деяких іграх.</string>
<string name="use_optimized_vertex_buffers">Оптимізовані буфери вершин</string>
<string name="use_optimized_vertex_buffers_description">Застосовує оптимізований буфер вершин, щоб покращити продуктивність. Потребує драйверів Mesa 26.0+ Turnip. На старіших драйверах виникатиме збій.</string>
<string name="use_optimized_vertex_buffers_description">Застосовує оптимізований буфер вершин, щоб покращити продуктивність. Потребує драйверів Mesa 26.0+ Turnip / QCOM. На старіших драйверах Turnip виникатиме збій.</string>
<string name="hacks">Обхідні рішення</string>
@@ -496,7 +498,9 @@
<string name="skip_cpu_inner_invalidation">Пропустити внутрішнє інвалідування CPU</string>
<string name="skip_cpu_inner_invalidation_description">Пропускає деякі інвалідації кешу на стороні CPU під час оновлення пам\'яті, зменшуючи навантаження на процесор і покращуючи продуктивність. Може спричинити збої в деяких іграх.</string>
<string name="fix_bloom_effects">Виправити ефекти світіння</string>
<string name="fix_bloom_effects_description">Зменшує розмиття світіння в LA/EOW (Adreno 700), прибирає світіння в Burnout. Увага: може спричинити графічні артефакти в інших іграх.</string>
<string name="fix_bloom_effects_description">Зменшує розмиття світіння в LA/EOW (Adreno A6XXA7XX / Turnip), прибирає світіння в Burnout. Увага: може спричинити графічні артефакти в інших іграх.</string>
<string name="emulate_bgr565">Емулювати BGR565</string>
<string name="emulate_bgr565_description">Виправляє проблеми з інвертованими кольорами в іграх або дивними артефактами чи тінями.</string>
<string name="renderer_asynchronous_shaders">Асинхронні шейдери</string>
<string name="renderer_asynchronous_shaders_description">Компілює шейдери асинхронно. Це може зменшити затримки, але також може спричинити графічні баги.</string>
<string name="gpu_unswizzle_settings">Налаштування розпакування за допомогою ГП</string>
@@ -330,7 +330,6 @@
<string name="fsr_sharpness">Độ sắc nét FSR</string>
<string name="fsr_sharpness_description">Độ sắc nét khi dùng FSR</string>
<string name="renderer_anti_aliasing">Phương pháp khử răng cưa</string>
<string name="renderer_optimize_spirv_output_description">Tối ưu hóa shader đã biên dịch để cải thiện hiệu suất GPU.</string>
<string name="dma_accuracy">Độ chính xác DMA</string>
@@ -55,7 +55,7 @@
<string name="stats_overlay_options_description">配置性能统计叠加层中显示的信息</string>
<string name="show_fps">显示帧率</string>
<string name="show_fps_description">显示当前帧率</string>
<string name="show_frametime">显示帧时间</string>
<string name="show_frametime">显示 Frametime</string>
<string name="show_app_ram_usage">显示应用内存使用情况</string>
<string name="show_app_ram_usage_description">显示模拟器内存用量</string>
<string name="show_system_ram_usage">显示系统内存使用情况</string>
@@ -453,8 +453,6 @@
<string name="fsr_sharpness">FSR 锐化度</string>
<string name="fsr_sharpness_description">指定使用 FSR 时图像的锐化程度</string>
<string name="renderer_anti_aliasing">抗锯齿方式</string>
<string name="renderer_optimize_spirv_output">优化 SPIRV 输出</string>
<string name="renderer_optimize_spirv_output_description">优化编译后的着色器以提高GPU效率。</string>
<string name="advanced">高级</string>
@@ -476,21 +474,22 @@
<string name="use_disk_shader_cache_description">将生成的着色器缓存于磁盘中并进行读取,以减少卡顿。</string>
<string name="renderer_force_max_clock">强制最大时钟 (仅限 Adreno)</string>
<string name="renderer_force_max_clock_description">强制 GPU 以最大时钟运行 (仍被温控限制)。</string>
<string name="renderer_asynchronous_gpu_emulation">GPU 异步模拟</string>
<string name="renderer_asynchronous_gpu_emulation_description">异步运行 GPU 模拟,以减少 CPU 停顿并提高吞吐量。仅当遇到与时序相关的问题时才应禁用此功能。</string>
<string name="renderer_async_presentation">异步呈现</string>
<string name="renderer_async_presentation_description">通过将呈现操作移至单独的 CPU 线程来略微提升性能。</string>
<string name="renderer_reactive_flushing">启用反应性刷新</string>
<string name="renderer_reactive_flushing_description">牺牲性能提高某些游戏的渲染精度。</string>
<string name="renderer_reactive_flushing_description">通过牺牲性能提高某些游戏的渲染精度。</string>
<string name="enable_buffer_history">启用缓冲区历史</string>
<string name="enable_buffer_history_description">允许访问之前的缓冲状态。\n这个选项可能会提升某些游戏渲染质量性能一致性。</string>
<string name="enable_buffer_history_description">启用对先前缓冲状态的访问。此选项可在某些游戏中提升渲染质量并保持性能一致性。</string>
<string name="use_optimized_vertex_buffers">优化顶点缓冲区</string>
<string name="use_optimized_vertex_buffers_description">实现优化顶点缓冲区绑定以提升性能。需要 Mesa 26.0+ Turnip 驱动。老驱动会崩溃。</string>
<string name="hacks">Hacks</string>
<string name="fast_gpu_time">GPU 超频频率</string>
<string name="fast_gpu_time_description">强制大多数游戏以其最高原生分辨率运行。使用 256 获得最性能,使用 512 获得最大图形保真度。</string>
<string name="fast_gpu_time_description">强制大多数游戏以其最高原生分辨率运行。设置为 256 获得最性能,设置为 512 获得最佳画面保真度。</string>
<string name="skip_cpu_inner_invalidation">跳过CPU内部无效化</string>
<string name="skip_cpu_inner_invalidation_description">在内存更新期间跳过某些CPU端缓存无效化,减少CPU使用率并提高其性能。可能会导致某些游戏出现故障或崩溃。</string>
<string name="fix_bloom_effects">修复泛光效果</string>
<string name="fix_bloom_effects_description">减少《塞尔达传说:智慧的再现》(LA/EOW) 在 Adreno 700 系列 GPU 上的模糊感,并移除《横冲直撞》(Burnout) 中的模糊特效。警告:可能会导致其他游戏出现画面花屏或异常。</string>
<string name="fix_bloom_effects">修复 Bloom 效果</string>
<string name="renderer_asynchronous_shaders">使用异步着色器</string>
<string name="renderer_asynchronous_shaders_description">异步编译着色器。这可能会减少卡顿,但也可能会导致图形错误。</string>
<string name="gpu_unswizzle_settings">GPU 还原设置</string>
@@ -440,7 +440,6 @@
<string name="fsr_sharpness">FSR 銳化度</string>
<string name="fsr_sharpness_description">使用 FSR 時圖片的銳化程度</string>
<string name="renderer_anti_aliasing">抗鋸齒</string>
<string name="renderer_optimize_spirv_output_description">最佳化編譯後的著色器以提高GPU效率。</string>
<string name="dma_accuracy">DMA 準確度</string>
@@ -469,8 +469,6 @@
<string name="fsr_sharpness">FSR sharpness</string>
<string name="fsr_sharpness_description">Determines how sharpened the image will look while using FSR\'s dynamic contrast</string>
<string name="renderer_anti_aliasing">Anti-aliasing method</string>
<string name="renderer_optimize_spirv_output">Optimize SPIRV output</string>
<string name="renderer_optimize_spirv_output_description">Optimizes compiled shaders to improve GPU efficiency, but may introduce longer loading times and initial slowdowns.</string>
<string name="advanced">Advanced</string>
@@ -501,7 +499,7 @@
<string name="enable_buffer_history">Enable buffer history</string>
<string name="enable_buffer_history_description">Enables access to previous buffer states. This option may improve rendering quality and performance consistency in some games.</string>
<string name="use_optimized_vertex_buffers">Optimized Vertex Buffers</string>
<string name="use_optimized_vertex_buffers_description">Enables optimized vertex buffer binding for improved performance. Requires Mesa 26.0+ Turnip drivers. Will crash on older drivers.</string>
<string name="use_optimized_vertex_buffers_description">Enables optimized vertex buffer binding for improved performance. Requires Mesa 26.0+ Turnip drivers/ QCOM drivers. Will crash on older Turnip drivers.</string>
<string name="hacks">Hacks</string>
@@ -510,7 +508,9 @@
<string name="skip_cpu_inner_invalidation">Skip CPU Inner Invalidation</string>
<string name="skip_cpu_inner_invalidation_description">Skips certain CPU-side cache invalidations during memory updates, reducing CPU usage and improving it\'s performance. This may cause glitches or crashes on some games.</string>
<string name="fix_bloom_effects">Fix Bloom Effects</string>
<string name="fix_bloom_effects_description">Reduces bloom blur in LA/EOW (Adreno 700), removes bloom in Burnout. Warning: may cause graphical artifacts in other games.</string>
<string name="fix_bloom_effects_description">Reduces bloom blur in LA/EOW (Adreno A6XX - A7XX/ Turnip), removes bloom in Burnout. Warning: may cause graphical artifacts in other games.</string>
<string name="emulate_bgr565">Emulate BGR565</string>
<string name="emulate_bgr565_description">Fixes problems with inverted colors in games or strange artifacts or strange shadows.</string>
<string name="renderer_asynchronous_shaders">Use asynchronous shaders</string>
<string name="renderer_asynchronous_shaders_description">Compiles shaders asynchronously. This may reduce stutters but may also introduce glitches.</string>
<string name="gpu_unswizzle_settings">GPU Unswizzle Settings</string>
@@ -243,6 +243,9 @@ void AndroidKeyboard::SubmitInlineKeyboardInput(int key_code) {
static_cast<s32>(m_current_text.size()));
break;
case KEYCODE_DEL:
if (m_current_text.empty()) {
return;
}
m_current_text.pop_back();
submit_inline_callback(Service::AM::Frontend::SwkbdReplyType::ChangedString, m_current_text,
static_cast<int>(m_current_text.size()));
+9 -3
View File
@@ -693,7 +693,9 @@ void HostMemory::Map(size_t virtual_offset, size_t host_offset, size_t length,
ASSERT(virtual_offset % PageAlignment == 0);
ASSERT(host_offset % PageAlignment == 0);
ASSERT(length % PageAlignment == 0);
ASSERT(virtual_offset + length <= virtual_size);
if (impl && virtual_base) {
ASSERT(virtual_offset + length <= virtual_size);
}
ASSERT(host_offset + length <= backing_size);
if (length == 0 || !virtual_base || !impl) {
return;
@@ -704,7 +706,9 @@ void HostMemory::Map(size_t virtual_offset, size_t host_offset, size_t length,
void HostMemory::Unmap(size_t virtual_offset, size_t length, bool separate_heap) {
ASSERT(virtual_offset % PageAlignment == 0);
ASSERT(length % PageAlignment == 0);
ASSERT(virtual_offset + length <= virtual_size);
if (impl && virtual_base) {
ASSERT(virtual_offset + length <= virtual_size);
}
if (length == 0 || !virtual_base || !impl) {
return;
}
@@ -714,7 +718,9 @@ void HostMemory::Unmap(size_t virtual_offset, size_t length, bool separate_heap)
void HostMemory::Protect(size_t virtual_offset, size_t length, MemoryPermission perm) {
ASSERT(virtual_offset % PageAlignment == 0);
ASSERT(length % PageAlignment == 0);
ASSERT(virtual_offset + length <= virtual_size);
if (impl && virtual_base) {
ASSERT(virtual_offset + length <= virtual_size);
}
if (length == 0 || !virtual_base || !impl) {
return;
}
+139
View File
@@ -0,0 +1,139 @@
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <deque>
#include <memory>
#include <type_traits>
#include "common/common_types.h"
namespace Common {
template <class Traits>
class LeastRecentlyUsedCache {
using ObjectType = typename Traits::ObjectType;
using TickType = typename Traits::TickType;
struct Item {
ObjectType obj;
TickType tick;
Item* next{};
Item* prev{};
};
public:
LeastRecentlyUsedCache() : first_item{}, last_item{} {}
~LeastRecentlyUsedCache() = default;
size_t Insert(ObjectType obj, TickType tick) {
const auto new_id = Build();
auto& item = item_pool[new_id];
item.obj = obj;
item.tick = tick;
Attach(item);
return new_id;
}
void Touch(size_t id, TickType tick) {
auto& item = item_pool[id];
if (item.tick >= tick) {
return;
}
item.tick = tick;
if (&item == last_item) {
return;
}
Detach(item);
Attach(item);
}
void Free(size_t id) {
auto& item = item_pool[id];
Detach(item);
item.prev = nullptr;
item.next = nullptr;
free_items.push_back(id);
}
template <typename Func>
void ForEachItemBelow(TickType tick, Func&& func) {
static constexpr bool RETURNS_BOOL =
std::is_same_v<std::invoke_result<Func, ObjectType>, bool>;
Item* iterator = first_item;
while (iterator) {
if (static_cast<s64>(tick) - static_cast<s64>(iterator->tick) < 0) {
return;
}
Item* next = iterator->next;
if constexpr (RETURNS_BOOL) {
if (func(iterator->obj)) {
return;
}
} else {
func(iterator->obj);
}
iterator = next;
}
}
private:
size_t Build() {
if (free_items.empty()) {
const size_t item_id = item_pool.size();
auto& item = item_pool.emplace_back();
item.next = nullptr;
item.prev = nullptr;
return item_id;
}
const size_t item_id = free_items.front();
free_items.pop_front();
auto& item = item_pool[item_id];
item.next = nullptr;
item.prev = nullptr;
return item_id;
}
void Attach(Item& item) {
if (!first_item) {
first_item = &item;
}
if (!last_item) {
last_item = &item;
} else {
item.prev = last_item;
last_item->next = &item;
item.next = nullptr;
last_item = &item;
}
}
void Detach(Item& item) {
if (item.prev) {
item.prev->next = item.next;
}
if (item.next) {
item.next->prev = item.prev;
}
if (&item == first_item) {
first_item = item.next;
if (first_item) {
first_item->prev = nullptr;
}
}
if (&item == last_item) {
last_item = item.prev;
if (last_item) {
last_item->next = nullptr;
}
}
}
std::deque<Item> item_pool;
std::deque<size_t> free_items;
Item* first_item{};
Item* last_item{};
};
} // namespace Common
+1
View File
@@ -52,6 +52,7 @@ SWITCHABLE(AstcRecompression, true);
SWITCHABLE(AudioMode, true);
SWITCHABLE(CpuBackend, true);
SWITCHABLE(CpuAccuracy, true);
SWITCHABLE(FormatReinterpretation, true);
SWITCHABLE(FullscreenMode, true);
SWITCHABLE(GpuAccuracy, true);
SWITCHABLE(GpuLogLevel, true);
+70 -9
View File
@@ -69,6 +69,7 @@ SWITCHABLE(AstcRecompression, true);
SWITCHABLE(AudioMode, true);
SWITCHABLE(CpuBackend, true);
SWITCHABLE(CpuAccuracy, true);
SWITCHABLE(FormatReinterpretation, true);
SWITCHABLE(FullscreenMode, true);
SWITCHABLE(GpuAccuracy, true);
SWITCHABLE(Language, true);
@@ -388,10 +389,6 @@ struct Values {
true,
true};
SwitchableSetting<SpirvOptimizeMode, true> optimize_spirv_output{linkage,
SpirvOptimizeMode::Never,
"optimize_spirv_output",
Category::Renderer};
SwitchableSetting<bool> use_asynchronous_gpu_emulation{
linkage, true, "use_asynchronous_gpu_emulation", Category::Renderer};
// *nix platforms may have issues with the borderless windowed fullscreen mode.
@@ -473,7 +470,11 @@ struct Values {
"astc_recompression",
Category::RendererAdvanced};
SwitchableSetting<FormatReinterpretation, true> format_reinterpretation{
linkage,
FormatReinterpretation::Disabled,
"format_reinterpretation",
Category::RendererAdvanced};
SwitchableSetting<bool> sync_memory_operations{linkage,
false,
"sync_memory_operations",
@@ -482,6 +483,9 @@ struct Values {
true,
true};
SwitchableSetting<bool> force_identity_swizzle{linkage, false, "force_identity_swizzle",
Category::RendererAdvanced};
SwitchableSetting<bool> renderer_force_max_clock{linkage, false, "force_max_clock",
Category::RendererAdvanced};
@@ -555,6 +559,9 @@ struct Values {
SwitchableSetting<bool> fix_bloom_effects{linkage, false, "fix_bloom_effects",
Category::RendererHacks};
SwitchableSetting<bool> emulate_bgr565{linkage, false, "emulate_bgr565",
Category::RendererHacks};
SwitchableSetting<bool> rescale_hack{linkage, false, "rescale_hack",
Category::RendererHacks};
@@ -584,7 +591,7 @@ struct Values {
SwitchableSetting<ExtendedDynamicState> dyna_state{linkage,
#if defined(ANDROID)
ExtendedDynamicState::EDS1,
ExtendedDynamicState::Disabled,
#elif defined(__APPLE__)
ExtendedDynamicState::Disabled,
#else
@@ -609,6 +616,60 @@ struct Values {
#endif
"vertex_input_dynamic_state", Category::RendererExtensions};
#ifdef ANDROID
// Shader Float Controls (Android only) - Eden Veil / Extensions
// Force enable VK_KHR_shader_float_controls even if driver has known issues
// Allows fine-tuning float behavior to match Switch/Maxwell or optimize performance
SwitchableSetting<bool> shader_float_controls_force_enable{linkage,
false,
"shader_float_controls_force_enable",
Category::RendererExtensions,
Specialization::Paired};
// Individual float behavior controls (visible only when force_enable is true)
// Multiple can be active simultaneously EXCEPT FTZ and DenormPreserve (mutually exclusive)
//
// Recommended configurations:
// Switch-native: FTZ=ON, RTE=ON, SignedZero=ON (matches Maxwell behavior)
// Performance: FTZ=ON only (fastest)
// Accuracy: DenormPreserve=ON, RTE=ON, SignedZero=ON (slowest, highest precision)
SwitchableSetting<bool> shader_float_ftz{linkage,
false,
"shader_float_ftz",
Category::RendererExtensions,
Specialization::Default,
true,
false,
&shader_float_controls_force_enable};
SwitchableSetting<bool> shader_float_denorm_preserve{linkage,
false,
"shader_float_denorm_preserve",
Category::RendererExtensions,
Specialization::Default,
true,
false,
&shader_float_controls_force_enable};
SwitchableSetting<bool> shader_float_rte{linkage,
false,
"shader_float_rte",
Category::RendererExtensions,
Specialization::Default,
true,
false,
&shader_float_controls_force_enable};
SwitchableSetting<bool> shader_float_signed_zero_inf_nan{linkage,
false,
"shader_float_signed_zero_inf_nan",
Category::RendererExtensions,
Specialization::Default,
true,
false,
&shader_float_controls_force_enable};
#endif
Setting<bool> renderer_debug{linkage, false, "debug", Category::RendererDebug};
Setting<bool> renderer_shader_feedback{linkage, false, "shader_feedback",
Category::RendererDebug};
@@ -636,8 +697,8 @@ struct Values {
Category::System};
SwitchableSetting<Region, true> region_index{linkage, Region::Usa, "region_index", Category::System};
SwitchableSetting<TimeZone, true> time_zone_index{linkage, TimeZone::Auto, "time_zone_index", Category::System};
Setting<u32> serial_battery{linkage, 0, "serial_battery", Category::System};
Setting<u32> serial_unit{linkage, 0, "serial_unit", Category::System};
Setting<u32> serial_battery{linkage, 0, "serial_battery", Category::Debugging};
Setting<u32> serial_unit{linkage, 0, "serial_unit", Category::Debugging};
// Measured in seconds since epoch
SwitchableSetting<bool> custom_rtc_enabled{linkage, false, "custom_rtc_enabled", Category::System, Specialization::Paired, true, true};
SwitchableSetting<s64> custom_rtc{
@@ -807,7 +868,7 @@ struct Values {
0,
65535,
"debug_knobs",
Category::Core,
Category::Debugging,
Specialization::Countable,
true,
true};
+11
View File
@@ -158,6 +158,17 @@ ENUM(ExtendedDynamicState, Disabled, EDS1, EDS2, EDS3);
ENUM(GpuLogLevel, Off, Errors, Standard, Verbose, All)
ENUM(GameListMode, TreeView, GridView);
ENUM(SpeedMode, Standard, Turbo, Slow);
ENUM(FormatReinterpretation, Disabled, R32UintToR32Sfloat, R32SintToR32Uint, R32SfloatToR32Sint)
// Shader Float Controls behavior modes
// These control how floating-point denormals and special values are handled in shaders
ENUM(ShaderFloatBehavior,
DriverDefault, // Let driver choose (safest, may not match Switch behavior)
SwitchNative, // Emulate Switch/Maxwell behavior (FTZ + RTE + SignedZero)
FlushToZero, // FTZ only - flush denorms to zero (fastest, some precision loss)
PreserveDenorms, // Preserve denorms (slowest, highest precision)
RoundToEven, // RTE rounding mode (IEEE 754 compliant)
SignedZeroInfNan); // Preserve signed zero, inf, nan (accuracy for edge cases)
template <typename Type>
inline std::string_view CanonicalizeEnum(Type id) {
@@ -289,7 +289,6 @@ void ArmDynarmic32::MakeJit(Common::PageTable* page_table) {
config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_UnfuseFMA;
config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_IgnoreStandardFPCRValue;
config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_InaccurateNaN;
config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_IgnoreGlobalMonitor;
break;
// Paranoia mode for debugging optimizations
case Settings::CpuAccuracy::Paranoid:
@@ -340,7 +340,6 @@ void ArmDynarmic64::MakeJit(Common::PageTable* page_table, std::size_t address_s
config.unsafe_optimizations = true;
config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_UnfuseFMA;
config.fastmem_address_space_bits = 64;
config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_IgnoreGlobalMonitor;
break;
// Paranoia mode for debugging optimizations
case Settings::CpuAccuracy::Paranoid:
+43 -59
View File
@@ -6,6 +6,8 @@
#include <condition_variable>
#include <mutex>
#include <optional>
#include <stop_token>
#include <thread>
#include "core/core.h"
@@ -18,59 +20,53 @@ namespace Kernel::Svc {
constexpr auto MAX_MSG_TIME = std::chrono::milliseconds(250);
const auto MAX_MSG_SIZE = 0x1000;
static std::string msg_buffer;
static std::mutex msg_mutex;
static std::condition_variable msg_cv;
static std::chrono::steady_clock::time_point last_msg_time;
static bool worker_running = true;
static std::unique_ptr<std::thread> flush_thread;
static std::once_flag start_flag;
static void FlushDbgLoop() {
while (true) {
std::unique_lock lock(msg_mutex);
msg_cv.wait(lock, [] { return !msg_buffer.empty() || !worker_running; });
if (!worker_running && msg_buffer.empty()) break;
auto timeout = last_msg_time + MAX_MSG_TIME;
bool woke_early = msg_cv.wait_until(lock, timeout, [] {
return msg_buffer.size() >= MAX_MSG_SIZE || !worker_running;
});
if (!woke_early || msg_buffer.size() >= MAX_MSG_SIZE || !worker_running) {
if (!msg_buffer.empty()) {
// Remove trailing newline as LOG_INFO adds that anyways
if (msg_buffer.back() == '\n')
msg_buffer.pop_back();
LOG_INFO(Debug_Emulated, "\n{}", msg_buffer);
msg_buffer.clear();
}
if (!worker_running) break;
}
}
}
/// Used to output a message on a debug hardware unit - does nothing on a retail unit
Result OutputDebugString(Core::System& system, u64 address, u64 len) {
static struct DebugFlusher {
std::string msg_buffer;
std::mutex msg_mutex;
std::condition_variable msg_cv;
std::chrono::steady_clock::time_point last_msg_time;
std::optional<std::jthread> thread;
} flusher_data;
R_SUCCEED_IF(len == 0);
// Only start the thread the very first time this function is called
std::call_once(start_flag, [] {
flush_thread = std::make_unique<std::thread>(FlushDbgLoop);
});
if (!flusher_data.thread) {
flusher_data.thread.emplace([](std::stop_token stop_token) {
while (!stop_token.stop_requested()) {
std::unique_lock lock(flusher_data.msg_mutex);
flusher_data.msg_cv.wait(lock, [&stop_token] {
return !flusher_data.msg_buffer.empty() || stop_token.stop_requested();
});
if (stop_token.stop_requested() && flusher_data.msg_buffer.empty())
break;
auto timeout = flusher_data.last_msg_time + MAX_MSG_TIME;
bool woke_early = flusher_data.msg_cv.wait_until(lock, timeout, [&stop_token] {
return flusher_data.msg_buffer.size() >= MAX_MSG_SIZE || stop_token.stop_requested();
});
if (!woke_early || flusher_data.msg_buffer.size() >= MAX_MSG_SIZE || stop_token.stop_requested()) {
if (!flusher_data.msg_buffer.empty()) {
// Remove trailing newline as LOG_INFO adds that anyways
if (flusher_data.msg_buffer.back() == '\n')
flusher_data.msg_buffer.pop_back();
{
std::lock_guard lock(msg_mutex);
const auto old_size = msg_buffer.size();
msg_buffer.resize(old_size + len);
GetCurrentMemory(system.Kernel()).ReadBlock(address, msg_buffer.data() + old_size, len);
last_msg_time = std::chrono::steady_clock::now();
LOG_INFO(Debug_Emulated, "\n{}", flusher_data.msg_buffer);
flusher_data.msg_buffer.clear();
}
if (stop_token.stop_requested()) break;
}
}
flusher_data.msg_cv.notify_all();
});
}
msg_cv.notify_one();
{
std::lock_guard lock(flusher_data.msg_mutex);
const auto old_size = flusher_data.msg_buffer.size();
flusher_data.msg_buffer.resize(old_size + len);
GetCurrentMemory(system.Kernel()).ReadBlock(address, flusher_data.msg_buffer.data() + old_size, len);
flusher_data.last_msg_time = std::chrono::steady_clock::now();
}
flusher_data.msg_cv.notify_one();
R_SUCCEED();
}
@@ -82,16 +78,4 @@ Result OutputDebugString64From32(Core::System& system, uint32_t debug_str, uint3
R_RETURN(OutputDebugString(system, debug_str, len));
}
struct BufferAutoFlush {
~BufferAutoFlush() {
{
std::lock_guard lock(msg_mutex);
worker_running = false;
}
msg_cv.notify_all();
if (flush_thread && flush_thread->joinable()) flush_thread->join();
}
};
static BufferAutoFlush auto_flusher;
} // namespace Kernel::Svc
+18
View File
@@ -396,6 +396,24 @@ std::size_t HLERequestContext::WriteBuffer(const void* buffer, std::size_t size,
const bool is_buffer_b{BufferDescriptorB().size() > buffer_index &&
BufferDescriptorB()[buffer_index].Size()};
const std::size_t buffer_size{GetWriteBufferSize(buffer_index)};
// Defensive check: if client didn't provide output buffer, log detailed error but don't crash
if (buffer_size == 0) {
LOG_ERROR(Core,
"WriteBuffer called but client provided NO output buffer! "
"Requested size: 0x{:X}, buffer_index: {}, is_buffer_b: {}, "
"BufferB count: {}, BufferC count: {}",
size, buffer_index, is_buffer_b, BufferDescriptorB().size(),
BufferDescriptorC().size());
// Log command context for debugging
LOG_ERROR(Core, "IPC Command: 0x{:X}, Type: {}", GetCommand(),
static_cast<u32>(GetCommandType()));
// Return 0 instead of crashing - let service handle error
return 0;
}
if (size > buffer_size) {
LOG_CRITICAL(Core, "size ({:016X}) is greater than buffer_size ({:016X})", size,
buffer_size);
@@ -23,16 +23,14 @@ static const auto default_cg_mode = nullptr; //Allow RWE
namespace Dynarmic {
void EmitSpinLockLock(Xbyak::CodeGenerator& code, Xbyak::Reg64 ptr, Xbyak::Reg32 tmp, bool waitpkg) {
// TODO: this is because we lack regalloc - so better to be safe :(
if (waitpkg) {
code.push(Xbyak::util::eax);
code.push(Xbyak::util::ebx);
code.push(Xbyak::util::edx);
}
Xbyak::Label start, loop;
code.jmp(start, code.T_NEAR);
code.L(loop);
if (waitpkg) {
// TODO: this is because we lack regalloc - so better to be safe :(
code.push(Xbyak::util::rax);
code.push(Xbyak::util::rbx);
code.push(Xbyak::util::rdx);
// TODO: This clobbers EAX and EDX did we tell the regalloc?
// ARM ptr for address-monitoring
code.umonitor(ptr);
@@ -49,6 +47,9 @@ void EmitSpinLockLock(Xbyak::CodeGenerator& code, Xbyak::Reg64 ptr, Xbyak::Reg32
code.umwait(Xbyak::util::ebx);
// CF == 1 if we hit the OS-timeout in IA32_UMWAIT_CONTROL without a write
// CF == 0 if we exited the wait for any other reason
code.pop(Xbyak::util::rdx);
code.pop(Xbyak::util::rbx);
code.pop(Xbyak::util::rax);
} else {
code.pause();
}
@@ -57,11 +58,6 @@ void EmitSpinLockLock(Xbyak::CodeGenerator& code, Xbyak::Reg64 ptr, Xbyak::Reg32
/*code.lock();*/ code.xchg(code.dword[ptr], tmp);
code.test(tmp, tmp);
code.jnz(loop, code.T_NEAR);
if (waitpkg) {
code.pop(Xbyak::util::edx);
code.pop(Xbyak::util::ebx);
code.pop(Xbyak::util::eax);
}
}
void EmitSpinLockUnlock(Xbyak::CodeGenerator& code, Xbyak::Reg64 ptr, Xbyak::Reg32 tmp) {
+5 -1
View File
@@ -3,6 +3,7 @@
#include <algorithm>
#include <filesystem>
#include <iostream>
#include <fmt/format.h>
#include "common/fs/fs.h"
#include "common/fs/fs_types.h"
@@ -25,7 +26,10 @@ std::vector<std::filesystem::path> GetModFolder(const std::string& root) {
"romfslite"};
if (std::ranges::find(valid_names, name) != valid_names.end()) {
paths.emplace_back(entry.path().parent_path());
const auto parent = entry.path().parent_path();
if (std::ranges::find(paths, parent) == paths.end()) {
paths.emplace_back(parent);
}
}
return true;
+9 -44
View File
@@ -80,55 +80,24 @@ std::optional<std::string> UpdateChecker::GetResponse(std::string url, std::stri
}
}
std::optional<UpdateChecker::Update> UpdateChecker::GetLatestRelease(bool include_prereleases) {
std::optional<UpdateChecker::Update> UpdateChecker::GetLatestRelease() {
#ifdef YUZU_BUNDLED_OPENSSL
const auto update_check_url = fmt::format("https://{}", Common::g_build_auto_update_api);
#else
const auto update_check_url = std::string{Common::g_build_auto_update_api};
#endif
auto update_check_path = fmt::format("{}{}", std::string{Common::g_build_auto_update_api_path},
std::string{Common::g_build_auto_update_repo});
auto update_check_path = std::string{Common::g_build_auto_update_api_path};
try {
if (include_prereleases) { // This can return either a prerelease or a stable release,
// whichever is more recent.
const auto update_check_tags_path = update_check_path + "/tags";
const auto update_check_releases_path = update_check_path + "/releases";
const auto response = UpdateChecker::GetResponse(update_check_url, update_check_path);
const auto tags_response = UpdateChecker::GetResponse(update_check_url, update_check_tags_path);
const auto releases_response = UpdateChecker::GetResponse(update_check_url, update_check_releases_path);
if (!response)
return {};
if (!tags_response || !releases_response)
return {};
const std::string latest_tag
= nlohmann::json::parse(tags_response.value()).at(0).at("name");
const std::string latest_name =
nlohmann::json::parse(releases_response.value()).at(0).at("name");
const bool latest_tag_has_release = releases_response.value().find(
fmt::format("\"{}\"", latest_tag))
!= std::string::npos;
// If there is a newer tag, but that tag has no associated release, don't prompt the
// user to update.
if (!latest_tag_has_release)
return {};
return Update{latest_tag, latest_name};
} else { // This is a stable release, only check for other stable releases.
update_check_path += "/releases/latest";
const auto response = UpdateChecker::GetResponse(update_check_url, update_check_path);
if (!response)
return {};
const std::string latest_tag = nlohmann::json::parse(response.value()).at("tag_name");
const std::string latest_name = nlohmann::json::parse(response.value()).at("name");
return Update{latest_tag, latest_name};
}
const std::string latest_tag = nlohmann::json::parse(response.value()).at("tag_name");
const std::string latest_name = nlohmann::json::parse(response.value()).at("name");
return Update{latest_tag, latest_name};
} catch (nlohmann::detail::out_of_range&) {
LOG_ERROR(Frontend,
"Parsing JSON response from {}{} failed during update check: "
@@ -147,12 +116,8 @@ std::optional<UpdateChecker::Update> UpdateChecker::GetLatestRelease(bool includ
}
std::optional<UpdateChecker::Update> UpdateChecker::GetUpdate() {
const bool is_prerelease = ((strstr(Common::g_build_version, "pre-alpha") != NULL) ||
(strstr(Common::g_build_version, "alpha") != NULL) ||
(strstr(Common::g_build_version, "beta") != NULL) ||
(strstr(Common::g_build_version, "rc") != NULL));
const std::optional<UpdateChecker::Update> latest_release_tag =
UpdateChecker::GetLatestRelease(is_prerelease);
UpdateChecker::GetLatestRelease();
if (!latest_release_tag)
goto empty;
+1 -1
View File
@@ -18,6 +18,6 @@ typedef struct {
} Update;
std::optional<std::string> GetResponse(std::string url, std::string path);
std::optional<Update> GetLatestRelease(bool include_prereleases);
std::optional<Update> GetLatestRelease();
std::optional<Update> GetUpdate();
} // namespace UpdateChecker
+22 -8
View File
@@ -162,13 +162,23 @@ std::unique_ptr<TranslationMap> InitializeTranslations(QObject* parent) {
tr("Stretches the renderer to fit the specified aspect ratio.\nMost games only support "
"16:9, so modifications are required to get other ratios.\nAlso controls the "
"aspect ratio of captured screenshots."));
INSERT(Settings, use_disk_shader_cache, tr("Use persistent pipeline cache"),
INSERT(Settings,
format_reinterpretation,
tr("Format Reinterpretation:"),
tr("Reinterprets certain texture formats for accuracy rendering.\nMay cause "
"graphical issues in some games."));
INSERT(Settings,
force_identity_swizzle,
tr("Force Identity Swizzle"),
tr("Forces identity component swizzle for storage and input attachment images. "
"Required by Vulkan spec. Disable only for debugging driver issues."));
INSERT(Settings,
use_disk_shader_cache,
tr("Use persistent pipeline cache"),
tr("Allows saving shaders to storage for faster loading on following game "
"boots.\nDisabling it is only intended for debugging."));
INSERT(Settings, optimize_spirv_output, tr("Optimize SPIRV output"),
tr("Runs an additional optimization pass over generated SPIRV shaders.\n"
"Will increase time required for shader compilation.\nMay slightly improve "
"performance.\nThis feature is experimental."));
INSERT(Settings, use_asynchronous_gpu_emulation, tr("Use asynchronous GPU emulation"),
tr("Uses an extra CPU thread for rendering.\nThis option should always remain enabled."));
INSERT(Settings, nvdec_emulation, tr("NVDEC emulation:"),
tr("Specifies how videos should be decoded.\nIt can either use the CPU or the GPU for "
"decoding, or perform no decoding at all (black screen on videos).\n"
@@ -315,9 +325,6 @@ std::unique_ptr<TranslationMap> InitializeTranslations(QObject* parent) {
"their resolution, details and supported controllers and depending on this setting.\n"
"Setting to Handheld can help improve performance for low end systems."));
INSERT(Settings, current_user, QString(), QString());
INSERT(Settings, serial_unit, tr("Unit Serial"), QString());
INSERT(Settings, serial_battery, tr("Battery Serial"), QString());
INSERT(Settings, debug_knobs, tr("Debug knobs"), QString());
// Controls
@@ -685,6 +692,13 @@ std::unique_ptr<ComboboxTranslationMap> ComboboxEnumeration(QObject* parent) {
PAIR(GameListMode, TreeView, tr("Tree View")),
PAIR(GameListMode, GridView, tr("Grid View")),
}});
translations->insert({Settings::EnumMetadata<Settings::FormatReinterpretation>::Index(),
{
PAIR(FormatReinterpretation, Disabled, tr("Disabled")),
PAIR(FormatReinterpretation, R32UintToR32Sfloat, tr("R32 Uint to R32 Float")),
PAIR(FormatReinterpretation, R32SintToR32Uint, tr("R32 Sint to R32 Uint")),
PAIR(FormatReinterpretation, R32SfloatToR32Sint, tr("R32 Float to R32 Sint")),
}});
#undef PAIR
#undef CTX_PAIR
+11
View File
@@ -55,6 +55,17 @@ static const std::map<Settings::ScalingFilter, QString> scaling_filter_texts_map
{Settings::ScalingFilter::Mmpx, QStringLiteral(QT_TRANSLATE_NOOP("MainWindow", "MMPX"))},
};
static const std::map<Settings::FormatReinterpretation, QString> format_reinterpretation_texts_map = {
{Settings::FormatReinterpretation::Disabled,
QStringLiteral(QT_TRANSLATE_NOOP("MainWindow", "Disabled"))},
{Settings::FormatReinterpretation::R32UintToR32Sfloat,
QStringLiteral(QT_TRANSLATE_NOOP("MainWindow", "R32 Uint to R32 Float"))},
{Settings::FormatReinterpretation::R32SintToR32Uint,
QStringLiteral(QT_TRANSLATE_NOOP("MainWindow", "R32 Sint to R32 Uint"))},
{Settings::FormatReinterpretation::R32SfloatToR32Sint,
QStringLiteral(QT_TRANSLATE_NOOP("MainWindow", "R32 Float to R32 Sint"))},
};
static const std::map<Settings::ConsoleMode, QString> use_docked_mode_texts_map = {
{Settings::ConsoleMode::Docked, QStringLiteral(QT_TRANSLATE_NOOP("MainWindow", "Docked"))},
{Settings::ConsoleMode::Handheld, QStringLiteral(QT_TRANSLATE_NOOP("MainWindow", "Handheld"))},
+4 -2
View File
@@ -101,8 +101,10 @@ QStringList GetModFolders(const QString& root, const QString& fallbackName) {
} else {
// Rename the existing mod folder.
const auto new_path = std_path.parent_path() / name.toStdString();
fs::remove_all(new_path);
fs::rename(std_path, new_path);
if (new_path != std_path) {
fs::remove_all(new_path);
fs::rename(std_path, new_path);
}
std_path = new_path;
}
+1 -1
View File
@@ -243,7 +243,7 @@ add_library(shader_recompiler STATIC
)
target_link_libraries(shader_recompiler PUBLIC common fmt::fmt sirit::sirit SPIRV-Tools::SPIRV-Tools)
target_link_libraries(shader_recompiler PUBLIC common fmt::fmt sirit::sirit)
if (MSVC)
target_compile_options(shader_recompiler PRIVATE
@@ -382,13 +382,14 @@ void EmitContext::SetupExtensions() {
if (info.uses_int64 && profile.support_int64) {
header += "#extension GL_ARB_gpu_shader_int64 : enable\n";
}
if (info.uses_int64_bit_atomics) {
if (info.uses_int64_bit_atomics && profile.support_gl_shader_atomic_int64) {
header += "#extension GL_NV_shader_atomic_int64 : enable\n";
}
if (info.uses_atomic_f32_add) {
if (info.uses_atomic_f32_add && profile.support_gl_shader_atomic_float) {
header += "#extension GL_NV_shader_atomic_float : enable\n";
}
if (info.uses_atomic_f16x2_add || info.uses_atomic_f16x2_min || info.uses_atomic_f16x2_max) {
if ((info.uses_atomic_f16x2_add || info.uses_atomic_f16x2_min || info.uses_atomic_f16x2_max) &&
profile.support_gl_shader_atomic_fp16_vector) {
header += "#extension GL_NV_shader_atomic_fp16_vector : enable\n";
}
if (info.uses_fp16) {
@@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
@@ -9,7 +9,6 @@
#include <type_traits>
#include <utility>
#include <vector>
#include <spirv-tools/optimizer.hpp>
#include "common/settings.h"
#include "shader_recompiler/backend/spirv/emit_spirv.h"
@@ -22,15 +21,7 @@ namespace Shader::Backend::SPIRV {
namespace {
template <class Func>
struct FuncTraits {};
thread_local std::unique_ptr<spvtools::Optimizer> thread_optimizer;
spvtools::Optimizer& GetThreadOptimizer() {
if (!thread_optimizer) {
thread_optimizer = std::make_unique<spvtools::Optimizer>(SPV_ENV_VULKAN_1_3);
thread_optimizer->RegisterPerformancePasses();
}
return *thread_optimizer;
}
template <class ReturnType_, class... Args>
struct FuncTraits<ReturnType_ (*)(Args...)> {
using ReturnType = ReturnType_;
@@ -341,19 +332,35 @@ void DefineEntryPoint(const IR::Program& program, EmitContext& ctx, Id main) {
void SetupDenormControl(const Profile& profile, const IR::Program& program, EmitContext& ctx,
Id main_func) {
const Info& info{program.info};
// User-forced behavior overrides (Android Eden Veil/Extensions)
// When force flags are active, they take precedence over shader-declared behavior
const bool force_flush = profile.force_fp32_denorm_flush;
const bool force_preserve = profile.force_fp32_denorm_preserve;
if (force_flush && force_preserve) {
LOG_WARNING(Shader_SPIRV, "Both FTZ and Preserve forced simultaneously - FTZ takes precedence");
}
if (info.uses_fp32_denorms_flush && info.uses_fp32_denorms_preserve) {
LOG_DEBUG(Shader_SPIRV, "Fp32 denorm flush and preserve on the same shader");
} else if (info.uses_fp32_denorms_flush) {
} else if (force_flush || info.uses_fp32_denorms_flush) {
if (profile.support_fp32_denorm_flush) {
ctx.AddCapability(spv::Capability::DenormFlushToZero);
ctx.AddExecutionMode(main_func, spv::ExecutionMode::DenormFlushToZero, 32U);
if (force_flush) {
LOG_DEBUG(Shader_SPIRV, "Fp32 DenormFlushToZero FORCED by user setting");
}
} else {
// Drivers will most likely flush denorms by default, no need to warn
}
} else if (info.uses_fp32_denorms_preserve) {
} else if (force_preserve || info.uses_fp32_denorms_preserve) {
if (profile.support_fp32_denorm_preserve) {
ctx.AddCapability(spv::Capability::DenormPreserve);
ctx.AddExecutionMode(main_func, spv::ExecutionMode::DenormPreserve, 32U);
if (force_preserve) {
LOG_DEBUG(Shader_SPIRV, "Fp32 DenormPreserve FORCED by user setting");
}
} else {
LOG_DEBUG(Shader_SPIRV, "Fp32 denorm preserve used in shader without host support");
}
@@ -386,13 +393,24 @@ void SetupSignedNanCapabilities(const Profile& profile, const IR::Program& progr
if (profile.has_broken_fp16_float_controls && program.info.uses_fp16) {
return;
}
// User-forced behavior (Android Eden Veil/Extensions)
const bool force_signed_zero_inf_nan = profile.force_fp32_signed_zero_inf_nan;
if (program.info.uses_fp16 && profile.support_fp16_signed_zero_nan_preserve) {
ctx.AddCapability(spv::Capability::SignedZeroInfNanPreserve);
ctx.AddExecutionMode(main_func, spv::ExecutionMode::SignedZeroInfNanPreserve, 16U);
}
if (profile.support_fp32_signed_zero_nan_preserve) {
ctx.AddCapability(spv::Capability::SignedZeroInfNanPreserve);
ctx.AddExecutionMode(main_func, spv::ExecutionMode::SignedZeroInfNanPreserve, 32U);
if (force_signed_zero_inf_nan || profile.support_fp32_signed_zero_nan_preserve) {
if (profile.support_fp32_signed_zero_nan_preserve) {
ctx.AddCapability(spv::Capability::SignedZeroInfNanPreserve);
ctx.AddExecutionMode(main_func, spv::ExecutionMode::SignedZeroInfNanPreserve, 32U);
if (force_signed_zero_inf_nan) {
LOG_DEBUG(Shader_SPIRV, "Fp32 SignedZeroInfNanPreserve FORCED by user setting");
}
} else if (force_signed_zero_inf_nan) {
LOG_WARNING(Shader_SPIRV, "SignedZeroInfNanPreserve forced but driver doesn't support it");
}
}
if (program.info.uses_fp64 && profile.support_fp64_signed_zero_nan_preserve) {
ctx.AddCapability(spv::Capability::SignedZeroInfNanPreserve);
@@ -501,8 +519,7 @@ void PatchPhiNodes(IR::Program& program, EmitContext& ctx) {
}
} // Anonymous namespace
std::vector<u32> EmitSPIRV(const Profile& profile, const RuntimeInfo& runtime_info,
IR::Program& program, Bindings& bindings, bool optimize) {
std::vector<u32> EmitSPIRV(const Profile& profile, const RuntimeInfo& runtime_info, IR::Program& program, Bindings& bindings) {
EmitContext ctx{profile, runtime_info, program, bindings};
const Id main{DefineMain(ctx, program)};
DefineEntryPoint(program, ctx, main);
@@ -514,29 +531,7 @@ std::vector<u32> EmitSPIRV(const Profile& profile, const RuntimeInfo& runtime_in
SetupCapabilities(profile, program.info, ctx);
SetupTransformFeedbackCapabilities(ctx, main);
PatchPhiNodes(program, ctx);
if (!optimize) {
return ctx.Assemble();
} else {
std::vector<u32> spirv = ctx.Assemble();
// Use thread-local optimizer instead of creating a new one
auto& spv_opt = GetThreadOptimizer();
spv_opt.SetMessageConsumer([](spv_message_level_t, const char*, const spv_position_t&, const char* m) {
LOG_ERROR(HW_GPU, "spirv-opt: {}", m);
});
spvtools::OptimizerOptions opt_options;
opt_options.set_run_validator(false);
std::vector<u32> result;
if (!spv_opt.Run(spirv.data(), spirv.size(), &result, opt_options)) {
LOG_ERROR(HW_GPU,
"Failed to optimize SPIRV shader output, continuing without optimization");
result = std::move(spirv);
}
return result;
}
return ctx.Assemble();
}
Id EmitPhi(EmitContext& ctx, IR::Inst* inst) {
@@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
@@ -33,13 +33,10 @@ constexpr u32 RESCALING_LAYOUT_WORDS_OFFSET = offsetof(RescalingLayout, rescalin
constexpr u32 RESCALING_LAYOUT_DOWN_FACTOR_OFFSET = offsetof(RescalingLayout, down_factor);
constexpr u32 RENDERAREA_LAYOUT_OFFSET = offsetof(RenderAreaLayout, render_area);
[[nodiscard]] std::vector<u32> EmitSPIRV(const Profile& profile, const RuntimeInfo& runtime_info,
IR::Program& program, Bindings& bindings, bool optimize);
[[nodiscard]] inline std::vector<u32> EmitSPIRV(const Profile& profile, IR::Program& program,
bool optimize) {
[[nodiscard]] std::vector<u32> EmitSPIRV(const Profile& profile, const RuntimeInfo& runtime_info, IR::Program& program, Bindings& bindings);
[[nodiscard]] inline std::vector<u32> EmitSPIRV(const Profile& profile, IR::Program& program) {
Bindings binding;
return EmitSPIRV(profile, {}, program, binding, optimize);
return EmitSPIRV(profile, {}, program, binding);
}
} // namespace Shader::Backend::SPIRV
@@ -332,13 +332,23 @@ void AddOffsetToCoordinates(EmitContext& ctx, const IR::TextureInstInfo& info, I
return;
}
// Mobile GPUs: 1D textures emulated as 2D with height=1
const bool emulate_1d = ctx.profile.needs_1d_texture_emulation;
Id result_type{};
switch (info.type) {
case TextureType::Buffer:
case TextureType::Color1D: {
result_type = ctx.U32[1];
break;
}
case TextureType::Color1D:
if (emulate_1d) {
// Treat as 2D: offset needs Y component
offset = ctx.OpCompositeConstruct(ctx.U32[2], offset, ctx.u32_zero_value);
result_type = ctx.U32[2];
} else {
result_type = ctx.U32[1];
}
break;
case TextureType::ColorArray1D:
offset = ctx.OpCompositeConstruct(ctx.U32[2], offset, ctx.u32_zero_value);
[[fallthrough]];
@@ -362,6 +372,40 @@ void AddOffsetToCoordinates(EmitContext& ctx, const IR::TextureInstInfo& info, I
}
coords = ctx.OpIAdd(result_type, coords, offset);
}
// Helper: Convert 1D coordinates to 2D when emulating 1D textures on mobile GPUs
[[nodiscard]] Id AdjustCoordinatesForEmulation(EmitContext& ctx, const IR::TextureInstInfo& info,
Id coords) {
if (!ctx.profile.needs_1d_texture_emulation) {
return coords;
}
switch (info.type) {
case TextureType::Color1D: {
// Convert scalar → vec2(x, 0.0)
return ctx.OpCompositeConstruct(ctx.F32[2], coords, ctx.f32_zero_value);
}
case TextureType::ColorArray1D: {
// Convert vec2(x, layer) → vec3(x, 0.0, layer)
// ColorArray1D coords are always vec2 in IR
const Id x = ctx.OpCompositeExtract(ctx.F32[1], coords, 0);
const Id layer = ctx.OpCompositeExtract(ctx.F32[1], coords, 1);
return ctx.OpCompositeConstruct(ctx.F32[3], x, ctx.f32_zero_value, layer);
}
case TextureType::Color2D:
case TextureType::ColorArray2D:
case TextureType::Color3D:
case TextureType::ColorCube:
case TextureType::ColorArrayCube:
case TextureType::Buffer:
case TextureType::Color2DRect:
// No adjustment needed for non-1D textures
return coords;
}
return coords; // Unreachable, but silences -Werror=return-type
}
} // Anonymous namespace
Id EmitBindlessImageSampleImplicitLod(EmitContext&) {
@@ -463,6 +507,7 @@ Id EmitBoundImageWrite(EmitContext&) {
Id EmitImageSampleImplicitLod(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords,
Id bias_lc, const IR::Value& offset) {
const auto info{inst->Flags<IR::TextureInstInfo>()};
coords = AdjustCoordinatesForEmulation(ctx, info, coords);
if (ctx.stage == Stage::Fragment) {
const ImageOperands operands(ctx, info.has_bias != 0, false, info.has_lod_clamp != 0,
bias_lc, offset);
@@ -484,6 +529,7 @@ Id EmitImageSampleImplicitLod(EmitContext& ctx, IR::Inst* inst, const IR::Value&
Id EmitImageSampleExplicitLod(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords,
Id lod, const IR::Value& offset) {
const auto info{inst->Flags<IR::TextureInstInfo>()};
coords = AdjustCoordinatesForEmulation(ctx, info, coords);
const ImageOperands operands(ctx, false, true, false, lod, offset);
Id result = Emit(&EmitContext::OpImageSparseSampleExplicitLod,
@@ -500,6 +546,7 @@ Id EmitImageSampleExplicitLod(EmitContext& ctx, IR::Inst* inst, const IR::Value&
Id EmitImageSampleDrefImplicitLod(EmitContext& ctx, IR::Inst* inst, const IR::Value& index,
Id coords, Id dref, Id bias_lc, const IR::Value& offset) {
const auto info{inst->Flags<IR::TextureInstInfo>()};
coords = AdjustCoordinatesForEmulation(ctx, info, coords);
if (ctx.stage == Stage::Fragment) {
const ImageOperands operands(ctx, info.has_bias != 0, false, info.has_lod_clamp != 0,
bias_lc, offset);
@@ -521,6 +568,7 @@ Id EmitImageSampleDrefImplicitLod(EmitContext& ctx, IR::Inst* inst, const IR::Va
Id EmitImageSampleDrefExplicitLod(EmitContext& ctx, IR::Inst* inst, const IR::Value& index,
Id coords, Id dref, Id lod, const IR::Value& offset) {
const auto info{inst->Flags<IR::TextureInstInfo>()};
coords = AdjustCoordinatesForEmulation(ctx, info, coords);
const ImageOperands operands(ctx, false, true, false, lod, offset);
return Emit(&EmitContext::OpImageSparseSampleDrefExplicitLod,
&EmitContext::OpImageSampleDrefExplicitLod, ctx, inst, ctx.F32[1],
@@ -530,6 +578,7 @@ Id EmitImageSampleDrefExplicitLod(EmitContext& ctx, IR::Inst* inst, const IR::Va
Id EmitImageGather(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords,
const IR::Value& offset, const IR::Value& offset2) {
const auto info{inst->Flags<IR::TextureInstInfo>()};
coords = AdjustCoordinatesForEmulation(ctx, info, coords);
const ImageOperands operands(ctx, offset, offset2);
if (ctx.profile.need_gather_subpixel_offset) {
coords = ImageGatherSubpixelOffset(ctx, info, TextureImage(ctx, info, index), coords);
@@ -542,6 +591,7 @@ Id EmitImageGather(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id
Id EmitImageGatherDref(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords,
const IR::Value& offset, const IR::Value& offset2, Id dref) {
const auto info{inst->Flags<IR::TextureInstInfo>()};
coords = AdjustCoordinatesForEmulation(ctx, info, coords);
const ImageOperands operands(ctx, offset, offset2);
if (ctx.profile.need_gather_subpixel_offset) {
coords = ImageGatherSubpixelOffset(ctx, info, TextureImage(ctx, info, index), coords);
@@ -554,6 +604,7 @@ Id EmitImageGatherDref(EmitContext& ctx, IR::Inst* inst, const IR::Value& index,
Id EmitImageFetch(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords, Id offset,
Id lod, Id ms) {
const auto info{inst->Flags<IR::TextureInstInfo>()};
coords = AdjustCoordinatesForEmulation(ctx, info, coords);
AddOffsetToCoordinates(ctx, info, coords, offset);
if (info.type == TextureType::Buffer) {
lod = Id{};
@@ -580,9 +631,20 @@ Id EmitImageQueryDimensions(EmitContext& ctx, IR::Inst* inst, const IR::Value& i
return uses_lod ? ctx.OpImageQuerySizeLod(type, image, lod)
: ctx.OpImageQuerySize(type, image);
}};
// Mobile GPUs: 1D textures emulated as 2D, query returns vec2 instead of scalar
const bool emulate_1d = ctx.profile.needs_1d_texture_emulation;
switch (info.type) {
case TextureType::Color1D:
return ctx.OpCompositeConstruct(ctx.U32[4], query(ctx.U32[1]), zero, zero, mips());
if (emulate_1d) {
// Query as 2D, extract only X component for 1D size
const Id size_2d = query(ctx.U32[2]);
const Id width = ctx.OpCompositeExtract(ctx.U32[1], size_2d, 0);
return ctx.OpCompositeConstruct(ctx.U32[4], width, zero, zero, mips());
} else {
return ctx.OpCompositeConstruct(ctx.U32[4], query(ctx.U32[1]), zero, zero, mips());
}
case TextureType::ColorArray1D:
case TextureType::Color2D:
case TextureType::ColorCube:
@@ -600,6 +662,7 @@ Id EmitImageQueryDimensions(EmitContext& ctx, IR::Inst* inst, const IR::Value& i
Id EmitImageQueryLod(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords) {
const auto info{inst->Flags<IR::TextureInstInfo>()};
coords = AdjustCoordinatesForEmulation(ctx, info, coords);
const Id zero{ctx.f32_zero_value};
const Id sampler{Texture(ctx, info, index)};
return ctx.OpCompositeConstruct(ctx.F32[4], ctx.OpImageQueryLod(ctx.F32[2], sampler, coords),
@@ -609,6 +672,7 @@ Id EmitImageQueryLod(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, I
Id EmitImageGradient(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords,
Id derivatives, const IR::Value& offset, Id lod_clamp) {
const auto info{inst->Flags<IR::TextureInstInfo>()};
coords = AdjustCoordinatesForEmulation(ctx, info, coords);
const auto operands = info.num_derivatives == 3
? ImageOperands(ctx, info.has_lod_clamp != 0, derivatives,
ctx.Def(offset), {}, lod_clamp)
@@ -621,6 +685,7 @@ Id EmitImageGradient(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, I
Id EmitImageRead(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords) {
const auto info{inst->Flags<IR::TextureInstInfo>()};
coords = AdjustCoordinatesForEmulation(ctx, info, coords);
if (info.image_format == ImageFormat::Typeless && !ctx.profile.support_typeless_image_loads) {
LOG_WARNING(Shader_SPIRV, "Typeless image read not supported by host");
return ctx.ConstantNull(ctx.U32[4]);
@@ -637,6 +702,7 @@ Id EmitImageRead(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id co
void EmitImageWrite(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords, Id color) {
const auto info{inst->Flags<IR::TextureInstInfo>()};
coords = AdjustCoordinatesForEmulation(ctx, info, coords);
const auto [image, is_integer] = Image(ctx, index, info);
if (!is_integer) {
color = ctx.OpBitcast(ctx.F32[4], color);
@@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
@@ -33,11 +33,24 @@ Id ImageType(EmitContext& ctx, const TextureDescriptor& desc) {
const Id type{ctx.F32[1]};
const bool depth{desc.is_depth};
const bool ms{desc.is_multisample};
// Mobile GPUs lack Sampled1D SPIR-V capability - emulate 1D as 2D with array layer
const bool emulate_1d = ctx.profile.needs_1d_texture_emulation;
// Debug log for 1D emulation
if (desc.type == TextureType::Color1D || desc.type == TextureType::ColorArray1D) {
LOG_WARNING(Shader_SPIRV, "ImageType(texture): Creating {} texture, emulate_1d={}",
desc.type == TextureType::Color1D ? "Color1D" : "ColorArray1D",
emulate_1d);
}
switch (desc.type) {
case TextureType::Color1D:
return ctx.TypeImage(type, spv::Dim::Dim1D, depth, false, false, 1, format);
return emulate_1d ? ctx.TypeImage(type, spv::Dim::Dim2D, depth, false, false, 1, format)
: ctx.TypeImage(type, spv::Dim::Dim1D, depth, false, false, 1, format);
case TextureType::ColorArray1D:
return ctx.TypeImage(type, spv::Dim::Dim1D, depth, true, false, 1, format);
return emulate_1d ? ctx.TypeImage(type, spv::Dim::Dim2D, depth, true, false, 1, format)
: ctx.TypeImage(type, spv::Dim::Dim1D, depth, true, false, 1, format);
case TextureType::Color2D:
case TextureType::Color2DRect:
return ctx.TypeImage(type, spv::Dim::Dim2D, depth, false, ms, 1, format);
@@ -79,11 +92,22 @@ spv::ImageFormat GetImageFormat(ImageFormat format) {
Id ImageType(EmitContext& ctx, const ImageDescriptor& desc, Id sampled_type) {
const spv::ImageFormat format{GetImageFormat(desc.format)};
const bool emulate_1d = ctx.profile.needs_1d_texture_emulation;
// Debug log for 1D emulation
if (desc.type == TextureType::Color1D || desc.type == TextureType::ColorArray1D) {
LOG_WARNING(Shader_SPIRV, "ImageType: Creating {} image, emulate_1d={}",
desc.type == TextureType::Color1D ? "Color1D" : "ColorArray1D",
emulate_1d);
}
switch (desc.type) {
case TextureType::Color1D:
return ctx.TypeImage(sampled_type, spv::Dim::Dim1D, false, false, false, 2, format);
return emulate_1d ? ctx.TypeImage(sampled_type, spv::Dim::Dim2D, false, false, false, 2, format)
: ctx.TypeImage(sampled_type, spv::Dim::Dim1D, false, false, false, 2, format);
case TextureType::ColorArray1D:
return ctx.TypeImage(sampled_type, spv::Dim::Dim1D, false, true, false, 2, format);
return emulate_1d ? ctx.TypeImage(sampled_type, spv::Dim::Dim2D, false, true, false, 2, format)
: ctx.TypeImage(sampled_type, spv::Dim::Dim1D, false, true, false, 2, format);
case TextureType::Color2D:
return ctx.TypeImage(sampled_type, spv::Dim::Dim2D, false, false, false, 2, format);
case TextureType::ColorArray2D:
@@ -178,6 +202,9 @@ void DefineGenericOutput(EmitContext& ctx, size_t index, std::optional<u32> invo
ctx.Decorate(id, spv::Decoration::XfbBuffer, xfb_varying->buffer);
ctx.Decorate(id, spv::Decoration::XfbStride, xfb_varying->stride);
ctx.Decorate(id, spv::Decoration::Offset, xfb_varying->offset);
if (ctx.stage == Stage::Geometry && xfb_varying->stream != 0) {
ctx.Decorate(id, spv::Decoration::Stream, xfb_varying->stream);
}
}
if (num_components < 4 || element > 0) {
const std::string_view subswizzle{swizzle.substr(element, num_components)};
@@ -1441,6 +1468,8 @@ void EmitContext::DefineInputs(const IR::Program& program) {
subgroup_mask_le = DefineInput(*this, U32[4], false, spv::BuiltIn::SubgroupLeMaskKHR);
subgroup_mask_gt = DefineInput(*this, U32[4], false, spv::BuiltIn::SubgroupGtMaskKHR);
subgroup_mask_ge = DefineInput(*this, U32[4], false, spv::BuiltIn::SubgroupGeMaskKHR);
// Vulkan spec: Fragment shader Input variables with integer/float type must have Flat decoration
if (stage == Stage::Fragment) {
Decorate(subgroup_mask_eq, spv::Decoration::Flat);
Decorate(subgroup_mask_lt, spv::Decoration::Flat);
@@ -979,7 +979,7 @@ private:
Environment& env;
IR::AbstractSyntaxList& syntax_list;
bool uses_demote_to_helper{};
const Flow::Block dummy_flow_block;
const Flow::Block dummy_flow_block{};
};
} // Anonymous namespace
@@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
@@ -293,6 +296,14 @@ std::optional<LowAddrInfo> TrackLowAddress(IR::Inst* inst) {
}
// This address is expected to either be a PackUint2x32, a IAdd64, or a CompositeConstructU32x2
IR::Inst* addr_inst{addr.InstRecursive()};
// Unwrap Identity ops introduced by lowerings (e.g., PackUint2x32 -> Identity)
while (addr_inst->GetOpcode() == IR::Opcode::Identity) {
const IR::Value id_arg{addr_inst->Arg(0)};
if (id_arg.IsImmediate()) {
return std::nullopt;
}
addr_inst = id_arg.InstRecursive();
}
s32 imm_offset{0};
if (addr_inst->GetOpcode() == IR::Opcode::IAdd64) {
// If it's an IAdd64, get the immediate offset it is applying and grab the address
@@ -308,6 +319,14 @@ std::optional<LowAddrInfo> TrackLowAddress(IR::Inst* inst) {
return std::nullopt;
}
addr_inst = iadd_addr.InstRecursive();
// Unwrap Identity again if present after folding IAdd64
while (addr_inst->GetOpcode() == IR::Opcode::Identity) {
const IR::Value id_arg{addr_inst->Arg(0)};
if (id_arg.IsImmediate()) {
return std::nullopt;
}
addr_inst = id_arg.InstRecursive();
}
}
// With IAdd64 handled, now PackUint2x32 is expected
if (addr_inst->GetOpcode() == IR::Opcode::PackUint2x32) {
@@ -317,6 +336,14 @@ std::optional<LowAddrInfo> TrackLowAddress(IR::Inst* inst) {
return std::nullopt;
}
addr_inst = vector.InstRecursive();
// Unwrap Identity that may replace PackUint2x32
while (addr_inst->GetOpcode() == IR::Opcode::Identity) {
const IR::Value id_arg{addr_inst->Arg(0)};
if (id_arg.IsImmediate()) {
return std::nullopt;
}
addr_inst = id_arg.InstRecursive();
}
}
// The vector is expected to be a CompositeConstructU32x2
if (addr_inst->GetOpcode() != IR::Opcode::CompositeConstructU32x2) {
+16
View File
@@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
@@ -25,6 +28,14 @@ struct Profile {
bool support_fp16_signed_zero_nan_preserve{};
bool support_fp32_signed_zero_nan_preserve{};
bool support_fp64_signed_zero_nan_preserve{};
// User-forced float behavior overrides (Android Eden Veil/Extensions)
// When shader_float_controls_force_enable is true, these override shader-declared behavior
bool force_fp32_denorm_flush{}; // Force FTZ for all FP32 ops
bool force_fp32_denorm_preserve{}; // Force denorm preservation for all FP32 ops
bool force_fp32_rte_rounding{}; // Force Round-To-Even for all FP32 ops
bool force_fp32_signed_zero_inf_nan{}; // Force signed zero/inf/nan preservation
bool support_explicit_workgroup_layout{};
bool support_vote{};
bool support_viewport_index_layer_non_geometry{};
@@ -38,6 +49,9 @@ struct Profile {
bool support_gl_nv_gpu_shader_5{};
bool support_gl_amd_gpu_shader_half_float{};
bool support_gl_texture_shadow_lod{};
bool support_gl_shader_atomic_float{};
bool support_gl_shader_atomic_fp16_vector{};
bool support_gl_shader_atomic_int64{};
bool support_gl_warp_intrinsics{};
bool support_gl_variable_aoffi{};
bool support_gl_sparse_textures{};
@@ -81,6 +95,8 @@ struct Profile {
bool ignore_nan_fp_comparisons{};
/// Some drivers have broken support for OpVectorExtractDynamic on subgroup mask inputs
bool has_broken_spirv_subgroup_mask_vector_extract_dynamic{};
/// Mobile GPUs lack Sampled1D capability - need to emulate 1D textures as 2D with height=1
bool needs_1d_texture_emulation{};
u32 gl_max_compute_smem_size{};
+1
View File
@@ -76,6 +76,7 @@ enum class TessSpacing {
struct TransformFeedbackVarying {
u32 buffer{};
u32 stream{};
u32 stride{};
u32 offset{};
u32 components{};
+1 -1
View File
@@ -133,7 +133,7 @@ enum class TexturePixelFormat {
ASTC_2D_8X6_SRGB,
ASTC_2D_6X5_UNORM,
ASTC_2D_6X5_SRGB,
E5B9G9R9_FLOAT,
D32_FLOAT,
D16_UNORM,
X8_D24_UNORM,
+5 -5
View File
@@ -109,12 +109,12 @@ public:
return static_cast<u32>(other_cpu_addr - cpu_addr);
}
u64 GetFrameTick() const noexcept {
return frame_tick;
size_t getLRUID() const noexcept {
return lru_id;
}
void SetFrameTick(u64 tick) noexcept {
frame_tick = tick;
void setLRUID(size_t lru_id_) {
lru_id = lru_id_;
}
size_t SizeBytes() const {
@@ -125,7 +125,7 @@ private:
VAddr cpu_addr = 0;
BufferFlagBits flags{};
int stream_score = 0;
u64 frame_tick = 0;
size_t lru_id = SIZE_MAX;
size_t size_bytes = 0;
};

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