Commit Graph

7428 Commits

Author SHA1 Message Date
lizzie 7b556f8d02 exclude more stuff from vulkan 2026-08-18 22:17:31 +00:00
lizzie 251d041ae5 exclude from vulkan surface selection 2026-08-18 22:17:31 +00:00
CamilleLaVey 2000fdfb7b [vulkan, android] Initial implementation of LSFG-VK (#4263)
Pretty much self explanatory, own implementation based on LSFG-VK available with some additional reverse engineer work for the actual use of shaders inside Lossless.dll, we don't store/ bundle any tools that bypass security and self ownership: to use this feature is required to own your own copy of Lossless Scaling and I encourage to support developers behind this work.

Special thanks:

1.- THS - Original developer behind Lossless Scaling
2.- PancakeTAS - Developer behind LSFG-VK
3.- The Big Smolio The Sleeper (@gidoly)

Co-authored-by: lizzie <lizzie@eden-emu.dev>
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/4263
2026-08-17 00:30:19 +02:00
crueter 8648c27cbb [cmake] Simplify DetectPlatform and normalize platform names (#4183)
Since 3.25 introduced `LINUX` and `BSD`, use them, and standardize other platforms to that style

Signed-off-by: crueter <crueter@eden-emu.dev>
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/4183
Reviewed-by: Samuel <lizzie@eden-emu.dev>
Reviewed-by: CamilleLaVey <camillelavey99@gmail.com>
2026-08-10 04:57:38 +02:00
lizzie c4ab2f6b9e [cmake] Add ENABLE_WERROR option (#4080)
Should warnings be errors? that's a philosophical debate which I can only answer with "no, but if you think otherwise here is an option for you"

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

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/4080
Reviewed-by: crueter <crueter@eden-emu.dev>
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
2026-08-09 02:56:28 +02:00
crueter a3d32a18b8 [meta] Discourage profanity usage (#4239)
I'm not into millennial humor, personally.

Proactively removed as much profanity as I could grep.

Signed-off-by: crueter <crueter@eden-emu.dev>
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/4239
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
Reviewed-by: Samuel <lizzie@eden-emu.dev>
2026-08-09 02:53:16 +02:00
CamilleLaVey 3f52bf4b4b [core, gpu, threads] Multithreading refactor (#4254)
This insufferable work tries to cover some holes on previous threading implementation from yuzu's team, starting with Windows and Linux reordering of priorities (NICE), reworks previous Android's threading and cpu affinity with adpf, adjust emulated clocks/gpu for better "accuracy" with their work, bumps android minSDK for all flavors, legacy will now work with AP 29 to cover A10 - A12, standard will reach A13 as base and finally the optimized build will come with API 35, mostly targeted on devices with A15 support and newer, NDK and AGP wasn't upgraded yet. The performance cost efficiency have been improved based on device power configuration; preventing overheating if certain devices tended to fall into NICE0 (not allocated threads priority, all task ran with higher priority, 11 tasks running within the limited 2 - 7 threads available on the most common configuration 1x3x4 or 1x4x3).

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/4254
2026-08-08 04:39:47 +02:00
CamilleLaVey 49a0ca6d5d [vulkan] Initial implementation on Bindless Buffer/Descriptors (#4251)
Adds a VK_EXT_descriptor_buffer, VK_KHR_device_buffer_address path alongside push descriptors and descriptor sets. The ring is chunked and sized from the device limits, so drivers with a small sampler range (QCOM reports 128 KiB) get more, chunks per frame instead of losing the feature. A pipeline uses one path or the other, never both, since some drivers do not support bufferless push descriptors. The chunk binding is only re-emitted when it changes, and a draw that repeats the previous payload reuses its allocation instead of rewriting it. This whole change will help to reduce the constant use of descriptors on the slower path, improves the "slow implementation" on QCOM drivers (A7xx and older) for push descriptors, improves latency when compiling pipelines. The implementation on indexing descriptors was also refined.

_Special Thanks_

1.- Meowly The Bindless Smol (@Gidoly)

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/4251
2026-08-05 16:58:43 +02:00
CamilleLaVey 5e1d5e82dc [vulkan] Re-adjusting ASTC resolve (#4250)
This is an adjustment made due to problems caused by my ASTC changes some pr's earlier; added sanity to decoded blocks, removes the inconditional storage view for ASTC formats (verified against MaxwellToVk logic), added support to VK_EXT_astc_decode_mode which will ensure a better way to resolve RGFA16/RGFA32 on tilers, simplified ASTC HDR decoding into LDR valid formats.

This fixes some issues with SteamDeck, Fire Emblem: Engage washed colors and other problems related to ASTC.

_Special Thanks_

1.- Meowly The Smol (@Gidoly)
2.- @simply0001 for the actual idea on the redundant storage views on the transcoded ASTC path.

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/4250
2026-08-05 09:24:35 +02:00
simply0001 54046ac60e [video_core/macro] check HLE hashes before compiling (#4236)
- [x] I have read and followed the [Contribution Guidelines](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/CONTRIBUTING.md#code-contributions).
- [x] I have read and followed the [AI Policy](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/policies/AI.md)
- [x] I have read and followed the [Coding Guidelines](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/policies/Coding.md) to the best of my ability.

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

Known HLE macros are identified by a hash, but MacroEngine compiled them first and and afterwards it threw the compiled program away when the hash matched. This fix makes it so it checks the hash first and caches the HLE implementation directly, so it only compiles when the hash is unknown or if HLE is disabled.

Cached macros were also constantly checking the hash again and walking through each `std::get_if` until their variant matched. So I dispatched them through `std::visit` instead, and keep one resolved code span for hashing, compiling, and dumping so mid-method uploads use the right range.

Continues the macro hot path work from [#4067](https://git.eden-emu.dev/eden-emu/eden/pulls/4067)

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/4236
Reviewed-by: Shinmegumi <shinmegumi@eden-emu.dev>
Reviewed-by: Lizzie <lizzie@eden-emu.dev>
2026-07-30 06:25:43 +02:00
PavelBARABANOV e69415c07b [android] disable VP8 MediaCodec decoder due to crashes in Diablo II (#4231)
Hotfix, in the future an improved handling on VP8 will be introduced for Android.

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/4231
Reviewed-by: CamilleLaVey <camillelavey99@gmail.com>
2026-07-26 04:24:04 +02:00
lizzie 58dee53305 [fmt] use {#:x} instead of 0x{:#x} (#4170)
continuation of #309 but applying to even more files than before :)
also makes them lowercase because `0xfafafa` is better as `0XFAFAFA`

Signed-off-by: lizzie <lizzie@eden-emu.dev>
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/4170
Reviewed-by: CamilleLaVey <camillelavey99@gmail.com>
Reviewed-by: Maufeat <sahyno1996@gmail.com>
2026-07-25 21:47:07 +02:00
xbzk b85f289048 [nce, fs] tico support, fix FS bug that would nuke entire 'switch' folder (#4086)
Contains the minimal set of functionalities to allow tico installer succeed, and tico work normally EXCEPT for game launching (which me or someone else will investigate later)

First three commits are from PR 4012.

The other six, kinda dizzy to explain each one. All were implemented based on tico source, switchbrew and libnx.
Hopefully the commit messages will do.

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/4086
Reviewed-by: Lizzie <lizzie@eden-emu.dev>
Reviewed-by: Maufeat <sahyno1996@gmail.com>
2026-07-23 21:59:55 +02:00
lizzie 89004124a5 [video_core] use bool params for read/writes and cascade them thru the calltree (#4001)
should make codegen a tad bit better and reduce icache pressure for what is otherwise a glorified memcpy

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

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/4001
Reviewed-by: Maufeat <sahyno1996@gmail.com>
Reviewed-by: CamilleLaVey <camillelavey99@gmail.com>
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
2026-07-18 21:01:58 +02:00
CamilleLaVey eb9280dedf [vulkan] 4th Vulkan Global Maintenance (#4212)
The approach on this PR moves around refactoring/ updating residual work; main issue was the whole logic behind msaa upload/download images with the constant image copy per pass required; which was gated via shaderStorageImageMultisample, which is not available on all the platforms supported including Android, making them to rely into a more heavier approach to convert msaa image copy into a non msaa image copy, not only losing precision in the conversion, but also creating bugs around the resolve of the image itself, if the supported path had to copy 2 times the same image to be actually presentable, when the fallback was enabled 3 copies were performed, not only decreasing the performance but also increasing race conditions due to the certain capabilities processed in this chain (storage_views). In order to resolve them more naturally, the constant copies were removed from the now "common" path along establishing a proper color resolve for Android and actually making them more direct.

Yet this opened a new pack of outdated handling on our current backend; since we now pass msaa images more directly (whenever a game request a msaa type of image/ which seems to be not common + each fragment resolves images on how it's actually required, adding missing depth/stencil), how we often load and store them becomes a critical issue, since our current configuration renderpass/framebuffer forces to always load and load clear whenever a new attachment it's passing through the renderpass, making this really heavier on memory bandwidth limited devices as SteamDeck and others that doesn't rely on the inmediate rendering mode (Tilers vs iGPU); to prevent over allocating data, I had to re-structure part of the current renderpass and framebuffer to actually reuse part of the data/ attachments called, with flags as DON'T_CARE, simplifying partially on how we actually call attachments including their barriers and conditions (occlusion, etc), the DON'T_CARE it's specifically useful to not only prevent calling new loads (which is a flush and heavier on tiler devices) and not only reusing the actual data store, which works on the future time, this saves memory bandwidth and gives space to actually avoid the constant pressure on SYSMEM/GMEM shader resolver path.

This maintenance also improved the current removal features logic on QCOM drivers, closing gaps between implementations on descriptors (VK_EXT_indexing_descriptor), adjusting the whole WMEL to avoid being so stricter if certain capabilities are missing to actually use this feature, leading to test and play more on how QCOM drivers are actually behaving; meanwhile the main objective is to open path for a robust and bigger implementation in the future, the changes made here also contains small bug fixes on SPIR-V logic, adding missing cases to resolve shaders (FP64 -> FP16), adding more robustness on how narrow features are actually being used and how to wired them whenever they're not available, meanwhile there are still some issues in regards on how Tegra vs Adreno can preserve unorms at FP32 and FP16, leaving better understanding on base for what VK_EXT_shader_float_controls is actually doing most of the times (flushes NaN's and Denorms equally).

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/4212
2026-07-16 20:56:00 +02:00
MaranBr defb8bf2e2 [video_core] Fix crash using RenderDoc (#4188)
This fixes a crash issue when RenderDoc is attached.

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/4188
Reviewed-by: CamilleLaVey <camillelavey99@gmail.com>
2026-07-12 20:25:36 +02:00
MaranBr a27d35463e [video_core] Improve synchronization and refactor buffer cache timing logic (#4182)
This simplifies the GPU accuracy setting by removing the intermediate Balanced mode and setting High as the default on desktop platforms.

It introduces a dedicated setting for GPU fence behavior, allowing the synchronization policy to be configured independently of GPU accuracy.

The Vulkan buffer cache now tracks GPU recording timeline ticks and waits only when necessary, reducing unnecessary synchronization while maintaining correctness for hard-to-trace graphical bugs.

GPU buffer readback has also been refined to synchronize only the affected upload regions when needed, and default DMA behavior has been updated to align with the new GPU accuracy model.

### TL;DR

The fix for particles freezing and unfreezing in mid-air in `Super Mario Odyssey` has been improved, resulting in less of a performance hit.
This game requires the new `Enable GPU Buffer Readback` option to be enabled to fix this issue.

The vertex explosions that occurred in `Super Mario Bros. Wonder`, especially in World 4, have been completely eliminated. You can now enjoy a smooth experience without graphical glitches exploding across the screen.
This game requires the new `GPU Fence Behavior` option to be set to `Strict` to fully fix this issue.

The flickering issue inside certain Shrines in `The Legend of Zelda: Tears of the Kingdom` has also been fixed.
For now, this game requires the new `GPU Fence Behavior` option to be set to `Accurate` to fully fix this issue.

These options are intended to fix graphical bugs in games that require better synchronization behavior between CPU and GPU, so other games may be affected as well.

Co-authored-by: xbzk <xbzk@eden-emu.dev>
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/4182
Reviewed-by: Lizzie <lizzie@eden-emu.dev>
2026-07-10 05:25:12 +02:00
John 5606edd1a6 [Vulkan] Regression Fix - Return BindVertexBuffer2EXT old path (#4199)
Fixes Triangle SMO Smoke Regression

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/4199
2026-07-10 05:00:49 +02:00
lizzie 3fd6eeaf9f Revert #3970 #4177 (#4187)
3970 revert fixes crash caused by scheduler
4177 fix mario galaxy and metroid prime 4 not booting

Co-authored-by: CamilleLaVey <camillelavey99@gmail.com>
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/4187
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
2026-07-09 19:02:26 +02:00
CamilleLaVey 372bdfccbc [vulkan, android] Mediacodec implementation + Vulkan fixes (#4191)
This is the first step into the conversion on full GPU video decoding for Android; currently due to the VIC structure, I couldn't set it on surface mode to prevent the latency when sending video decoded (which is processed by GPU now), because currently we convert YUV420 into the Nvidia's format each frame constantly on CPU, aside the requirements from other extensions to work + VIC rewrite, which is a work currently not planned to happen on this PR; the actual configuration for video decoding is ByteBuffer, using GPU to decode NVDEC data (all codecs supported, h264, vp8 and vp9) and send it to CPU for display purposes, which is more faster than relying purely on CPU for any drawing task, saving devices resources/ heating, the downside on this will be the slight latency when a new frame is displayed, which is gonna be a black frame for less than a second, nothing major to harm the experience rather than actually trying our best to take advantage on hardware accelerated.

Aside this, I also added a bunch of minor Vulkan fixes to grant drivers less thinkering when receiving spir-v instructions, meaning this has new bans for extensions on QCOM (following reported issues on other projects working around Adreno driver behavior), this more than providing performance aims to enhance the stability on the driver, performance it's gonna likely to be hit based on the UBO's (StorageBufferAccess) operations and SSBO (uniformStorageBufferAccess), there was an already existing path for the emulation which forces to wide them into 32bit packed operations. I also included some smaller changes/ bugs + VUID's fixes from earlier changes on my work.

Special Thanks:

-> Mr. Smoly Gidolard (@gidoly)

Sources:

1.- https://github.com/microsoft/DirectXShaderCompiler/issues/2842
2.- https://github.com/mlc-ai/web-llm/issues/836
3.- https://github.com/ggml-org/llama.cpp/issues/5186
4.- https://github.com/encounter/aurora/pull/202

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/4191
2026-07-09 06:55:54 +02:00
CamilleLaVey 3a6ac6e418 [video_core] Implementation on ASTC HDR formats + Vulkan fixes (#4190)
Based on the register of the ASTC implementation from Ameerj (yuzu), currently our conversion from ASTC on Desktop tends to duplicates the unpacking of ASTC converted textures, leading to bad performance; since there are some graphical effects that actually access on the band of 32bits (RGAF32) than the common 16bits (RGAF16) from our ASTC path decoding method, which commonly uses ARGB8 (degradation -> LDR) transformation to reduce the memory cost per conversion; meanwhile it could actually provide initially better performance; the engine tended to get stalled when this writted stage effect got skipped; mostly because CPU tends to look for an unimplemented texture/ format query (from which doesn't exist on our MaxwellToVK); unlike what's commonly believed HDR was a format to write enviroment effects even before their appearance on video output (since Switch doesn't have HDR, only SDR on certain engines).

The test result on this PR showed games like Astral Chain and other heavy reliant on ASTC decoding improved their performance and stability by around 15%; meanwhile could it be tied to a hardware gain, it's clearly a gain for direct access on what's required on most games. This PR also contains few Vulkan bug fix I encountered along this implementation.

Special Thanks:

-> Mr. Smoly Gidolard (@gidoly)

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/4190
2026-07-09 05:29:50 +02:00
CamilleLaVey 8225151a44 [vulkan] 3rd Vulkan Global Maintenance (#4189)
Following the philosophy on the previous Vulkan maintenance PR's, this one is reviewing the video_core to resolve VUID's related to the missing handling/ safechecks (UBO's case on missing StorageBufferAccess 8/16 bits on QCOM drivers, resulting on bad compute pipeline compiled), wiring topology representative to EDS2 configuration (following #4117), refactored the sampled image access via new memeber function for type "typeless" which adds a handling on the integer mistmatch (uint to sint, float to uint) + fixing bugs on current texture sampling (int) including the depth/stencil path resolve, maintenance to previous changes on query cache (resolving bugs from #3853), reduced the amount of binding BindVertexBufferEXT2 when a new tick/ frame is presented (with this being a reason for performance reduction on games where vertex polutes the stage, like BOTW/TOTK where grass is draw with vertex); implemented color border swizzle and color write enable for future improvements on EDS3, added initial implementation on Synchronization2 starting a path to ensure an access to VK 1.3 features safely and other smaller fixes along the road.

Special Thanks:

-> Mr. Smolio Gidolard (@gidoly)

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/4189
2026-07-09 04:22:43 +02:00
lizzie 41762940d6 [common] rework BitField and BitUtil, use concepts whenever possible (#4076)
test no regressions especially on Liiinux

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

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/4076
Reviewed-by: CamilleLaVey <camillelavey99@gmail.com>
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
2026-07-09 03:47:04 +02:00
lizzie f423471cc0 [*, docs] remove UTF8 and make docs ASCII only (#4166)
except for the AI policy doc which uses output for demonstrative purposes

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

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/4166
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
Reviewed-by: CamilleLaVey <camillelavey99@gmail.com>
2026-07-07 20:01:11 +02:00
lizzie 1643d8766f [vk] invalidate shader cache automatically if !=driverId or !=driverVersion (#4174)
this integrates neatly into the existing GraphicsPipelineKey system
no need for extra funcs :)

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

Co-authored-by: CamilleLaVey <camillelavey99@gmail.com>
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/4174
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
Reviewed-by: CamilleLaVey <camillelavey99@gmail.com>
2026-07-07 19:57:45 +02:00
lizzie a769505a45 [vk, ogl] Remove dedicated precomputed swizzle table; use shorter inline table in block_linear swizzle shaders (#4146)
old table = 64 * 8 * sizeof(u32) = 512 * 4 = 4096 bytes
new table = 8 * sizeof(u32) = 8 * 4 = 32 bytes

the expression
```glsl
    return ((pos & 0x0180) >> 1)
         | ((pos & 0x0040) >> 2)
         | ((pos & 0x0020) << 3)
         | ((pos & 0x0010) << 1)
         | ((pos & 0x000f) << 0);
```
is equivalent for generating the table but idk if we'd want that

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

Co-authored-by: CamilleLaVey <camillelavey99@gmail.com>
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/4146
Reviewed-by: CamilleLaVey <camillelavey99@gmail.com>
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
2026-07-02 19:24:07 +02:00
xbzk 54c3d10b86 [vk, renderdoc] (VUID-02997) avoid vk_image_view as VK_NULL_HANDLE when feature nullDescriptor is unavailable (#4056)
This minor change in src\video_core\renderer_vulkan\pipeline_helper.h allows renderdoc capture on mhr sunbreak.
Maybe it sanitizes some crashes on old vulkan GPUs.

Device log (nvidia kepler gpu vulkan 1.1.117):
[  17.605262] Render.Vulkan <Info> video_core\vulkan_common\vulkan_device.cpp:1041:GetSuitability: Device doesn't support feature nullDescriptor

VUID-VkWriteDescriptorSet-descriptorType-02997
For sampled/combined/storage image descriptors, Khronos says imageView must be valid or VK_NULL_HANDLE
(https://docs.vulkan.org/refpages/latest/refpages/source/VkPhysicalDeviceRobustness2FeaturesKHR.html)

but then it says: if nullDescriptor is not enabled, imageView must not be VK_NULL_HANDLE.
(https://docs.vulkan.org/spec/latest/chapters/descriptorsets.html)
nullDescriptor is exactly the feature that allows descriptors to be written with null handles.

The fix relies on conditionally replacing the null sampled view with Eden’s dummy null-image-view object (ImageView constructor checks HasNullDescriptor which checks features.robustness2.nullDescriptor. cheap checks, and only for null handles, so no notable cost).

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/4056
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
Reviewed-by: CamilleLaVey <camillelavey99@gmail.com>
2026-07-02 03:23:08 +02:00
xbzk bdf60d79a0 [video_core] gate Mesa EXIT terminator detection behind non-proprietary driver (#4151)
FIXES A REGRESSION FROM 4012.

TryFindSize's Mesa fallback matched the unconditional @PT EXIT (0xE30000000007000F) that nv50_ir emits at program end.
That exact word is also emitted by NVN mid-program for unconditional early-outs, so on retail titles (e.g. Super Mario 3D World) the scan truncated at the first early EXIT and dropped the rest of the shader, making textures vanish.

Mesa's terminal EXIT and NVN's mid-program EXIT are bit-identical, so no mask can separate them. Gate the heuristic on !is_proprietary_driver:

NVN binaries (bindless cbuf slot 2) keep self-branch-only sizing, while nouveau/Mesa homebrew (single terminal EXIT, no self-branch trailer) still uses the EXIT terminator. nv50_ir emits exactly one EXIT (early returns lower to BRA-to-exit, discard to DISCARD), so a single terminal match is correct for that path.

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/4151
Reviewed-by: Lizzie <lizzie@eden-emu.dev>
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
2026-07-01 13:06:00 +02:00
lizzie 2068b5d452 [vk] Clamp dynamic descriptors based on device limits (#4115)
Should fix this specific crash
```
* thread #82, name = 'GPU', stop reason = Exception 0xc0000005 encountered at address 0x7ff7e5193e89: Access violation reading location 0x00000098
  * frame #0: 0x00007ff7e5193e89 eden.exe`std::unique_ptr<Vulkan::Scheduler::CommandChunk,std::default_delete<Vulkan::Scheduler::CommandChunk> >::operator->(this=<unavailable>) at memory:3453 [inlined]
    frame #1: 0x00007ff7e5193e81 eden.exe`void Vulkan::Scheduler::DispatchWork(this=0x0000000000000000) at vk_scheduler.cpp:146
    frame #2: 0x00007ff7e5193d8f eden.exe`void Vulkan::Scheduler::WaitWorker(this=<unavailable>) at vk_scheduler.cpp:133
    frame #3: 0x00007ff7e54f472e eden.exe`void Vulkan::UpdateDescriptorQueue::Acquire(this=0x0000026c77cfb4b8) at vk_update_descriptor.cpp:41
    frame #4: 0x00007ff7e5537a43 eden.exe`void Vulkan::ASTCDecoderPass::Assemble(this=0x0000026c794fba10, image=0x0000026cfb794850, map=0x00000025e28fcb30, swizzles=<unavailable>) at vk_compute_pass.cpp:603
    frame #5: 0x00007ff7e55043e1 eden.exe`void Vulkan::TextureCacheRuntime::AccelerateImageUpload(this=<unavailable>, image=0x0000026cfb794850, map=0x00000025e28fcb30, swizzles=size=10, z_start=0, z_count=0) at vk_texture_cache.cpp:2482
    frame #6: 0x00007ff7e5516592 eden.exe`void VideoCommon::TextureCache<struct Vulkan::TextureCacheParams>::UploadImageContents<struct Vulkan::StagingBufferRef>(this=<unavailable>, image=0x0000026cfb794850, staging=0x00000025e28fcb30) at texture_cache.h:1147
    frame #7: 0x00007ff7e551523d eden.exe`void VideoCommon::TextureCache<struct Vulkan::TextureCacheParams>::RefreshContents(this=0x0000026c794fd800, image=0x0000026cfb794850, image_id=(index = 3801072224)) at texture_cache.h:1133
    frame #8: 0x00007ff7e5517b50 eden.exe`struct Common::SlotId VideoCommon::TextureCache<struct Vulkan::TextureCacheParams>::JoinImages(this=0x0000026c794fd800, info=<unavailable>, gpu_addr=25374426112, cpu_addr=2254181376) at texture_cache.h:1644
    frame #9: 0x00007ff7e5516ff6 eden.exe`struct Common::SlotId VideoCommon::TextureCache<struct Vulkan::TextureCacheParams>::InsertImage(this=0x0000026c794fd800, info=0x00000025e28fd270, gpu_addr=25374426112, options=0x0) at texture_cache.h:1513
    frame #10: 0x00007ff7e5516a60 eden.exe`struct Common::SlotId VideoCommon::TextureCache<struct Vulkan::TextureCacheParams>::FindOrInsertImage(this=0x0000026c794fd800, info=0x00000025e28fd270, gpu_addr=25374426112, options=0x0) at texture_cache.h:1194
    frame #11: 0x00007ff7e5515a13 eden.exe`struct Common::SlotId VideoCommon::TextureCache<struct Vulkan::TextureCacheParams>::CreateImageView(this=0x0000026c794fd800, config=0x00000025e28fd370) at texture_cache.h:1173
    frame #12: 0x00007ff7e550cd64 eden.exe`struct Common::SlotId VideoCommon::TextureCache<struct Vulkan::TextureCacheParams>::VisitImageView(this=0x0000026c794fd800, index=4586, compute=<unavailable>) at texture_cache.h:554
    frame #13: 0x00007ff7e550d181 eden.exe`void VideoCommon::TextureCache<struct Vulkan::TextureCacheParams>::FillImageViews(this=0x0000026c794fd800, views=size=5, compute=<unavailable>, blacklist=<unavailable>) at texture_cache.h:227
    frame #14: 0x00007ff7e58896e4 eden.exe`Vulkan::GraphicsPipeline::ConfigureImpl<Vulkan::(anonymous namespace)::SimpleStorageSpec>(this=0x0000026f865c1a60, is_indexed=<unavailable>) at vk_graphics_pipeline.cpp:415
    frame #15: 0x00007ff7e5889479 eden.exe`<lambda_1>::operator(pl=<unavailable>, is_indexed=<unavailable>) at vk_graphics_pipeline.h:123 [inlined]
    frame #16: 0x00007ff7e5889474 eden.exe`<lambda_1>::__invoke(pl=<unavailable>, is_indexed=<unavailable>) at vk_graphics_pipeline.h:123
    frame #17: 0x00007ff7e519d2a8 eden.exe`Vulkan::GraphicsPipeline::Configure(this=0x0000026f865c1a60, is_indexed=<unavailable>) at vk_graphics_pipeline.h:105 [inlined]
    frame #18: 0x00007ff7e519d29d eden.exe`Vulkan::RasterizerVulkan::PrepareDraw<`lambda at D:\a\g\g\eden-source\src\video_core\renderer_vulkan\vk_rasterizer.cpp:256:29'>(this=0x0000026c764f9368, is_indexed=<unavailable>, draw_func=0x00000025e28fdb80) at vk_rasterizer.cpp:244
    frame #19: 0x00007ff7e519d1db eden.exe`void Vulkan::RasterizerVulkan::Draw(this=<unavailable>, is_indexed=<unavailable>, instance_count=<unavailable>) at vk_rasterizer.cpp:256
    frame #20: 0x00007ff7e50d9025 eden.exe`void Tegra::HLE_DrawIndexedIndirect::Fallback(this=0x0000026f2af85118, maxwell3d=0x0000026ccbf9eb00, parameters=size=6) at macro.cpp:178
    frame #21: 0x00007ff7e50d8f21 eden.exe`void Tegra::HLE_DrawIndexedIndirect::Execute(this=0x0000026f2af85118, maxwell3d=0x0000026ccbf9eb00, parameters=size=6) at macro.cpp:129
    frame #22: 0x00007ff7e50db607 eden.exe`Tegra::MacroEngine::Execute::<lambda_0>::operator(this=0x00000025e28fde70, acm= Active Type = Tegra::HLE_DrawIndexedIndirect ) at macro.cpp:1362
    frame #23: 0x00007ff7e50dada0 eden.exe`void Tegra::MacroEngine::Execute(this=0x0000026ccbfaa020, maxwell3d=0x0000026ccbf9eb00, method=418, parameters=<unavailable>) at macro.cpp:1392
    frame #24: 0x00007ff7e4ef062b eden.exe`void Tegra::Engines::Maxwell3D::CallMacroMethod(this=0x0000026ccbf9eb00, method=<unavailable>, parameters=<unavailable>) at maxwell_3d.cpp:390
    frame #25: 0x00007ff7e4ef04be eden.exe`void Tegra::Engines::Maxwell3D::ProcessMacro(this=0x0000026ccbf9eb00, method=<unavailable>, base_start=<unavailable>, amount=5, is_last_call=<unavailable>) at maxwell_3d.cpp:223
    frame #26: 0x00007ff7e4ef1673 eden.exe`void Tegra::Engines::Maxwell3D::CallMultiMethod(this=<unavailable>, method=<unavailable>, base_start=0x000001ea398e22f4, amount=<unavailable>, methods_pending=5) at maxwell_3d.cpp:419
    frame #27: 0x00007ff7e4ef535a eden.exe`void Tegra::DmaPusher::CallMultiMethod(this=<unavailable>, base_start=0x000001ea398e22f4, num_methods=<unavailable>) const at dma_pusher.cpp:201
    frame #28: 0x00007ff7e4ef5023 eden.exe`void Tegra::DmaPusher::ProcessCommands(this=0x0000026ccbfba698, commands=size=36) at dma_pusher.cpp:120
    frame #29: 0x00007ff7e4ef4ced eden.exe`bool Tegra::DmaPusher::Step(this=0x0000026ccbfba698) at dma_pusher.cpp:88
    frame #30: 0x00007ff7e4ef49f8 eden.exe`void Tegra::DmaPusher::DispatchCalls(this=0x0000026ccbfba698) at dma_pusher.cpp:40
    frame #31: 0x00007ff7e4ede797 eden.exe`void Tegra::Control::Scheduler::Push(this=<unavailable>, channel=-493895072, entries=0x00000025e28fe2e0) at scheduler.cpp:31
    frame #32: 0x00007ff7e4eedc7b eden.exe`VideoCommon::GPUThread::ThreadManager::StartThread::<lambda_0>::operator(this=<unavailable>, stop_token=stop_token @ 0x00000025e28ffb40) at gpu_thread.cpp:42 [inlined]
    frame #33: 0x00007ff7e4eedae8 eden.exe`std::invoke(_Obj=<unavailable>, _Arg1=0x0000026ccb3edef0) at type_traits:1680 [inlined]
    frame #34: 0x00007ff7e4eedac1 eden.exe`std::thread::_Invoke<std::tuple<`lambda at D:\a\g\g\eden-source\src\video_core\gpu_thread.cpp:29:27',std::stop_token>,0,1>(_RawVals=0x0000026ccb3edef0) at thread:60
    frame #35: 0x00007ff8e87a37b0 ucrtbase.dll`wcsrchr + 336
    ```

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

Co-authored-by: CamilleLaVey <camillelavey99@gmail.com>
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/4115
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
Reviewed-by: CamilleLaVey <camillelavey99@gmail.com>
2026-06-30 04:33:30 +02:00
wildcard 6c16440996 [vulkan] Fix EDS 0-2 (#4117)
EDS3 states were dynamic just because the driver supports them. But in EDS0-EDS2, we does not actually emit the EDS3 dynamic commands for them. So the pipeline builder skipped baking some fixed graphics state into the Vulkan pipeline, but the runtime also did not set that state dynamically. That leaves wrong Vulkan state during rendering causing rendering glitches in XC2.

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/4117
Reviewed-by: CamilleLaVey <camillelavey99@gmail.com>
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
2026-06-28 15:07:54 +02:00
lizzie 894add43f3 [vk] fix PR5R black screen on qcom driver (#4120)
Different approach proposed by gido.

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

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/4120
Reviewed-by: CamilleLaVey <camillelavey99@gmail.com>
2026-06-28 04:29:28 +02:00
MaranBr b4b41ee62c [buffer_cache] Add option to control GPU buffer readback (#4126)
Added an option to control the GPU buffer readback, as it causes issues if the hardware cannot keep up with the additional workload.

Some games require this to render certain effects properly.

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/4126
2026-06-27 08:38:04 +02:00
simply0001 0d6a2158f0 [maxwell_3d] append inline index draw streams in bulk (#4083)
Inline index draws arrive as a batch but were processed one word at a time, so each index ran through the full per-method path and got appended a byte at a time.
Handle the whole batch in one pass instead, updating state once and appending all the indices together. Replay shadow control still goes word by word since it has to reload each one.

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/4083
Reviewed-by: Lizzie <lizzie@eden-emu.dev>
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
2026-06-27 02:52:59 +02:00
xbzk 09b6b3b71e xbzk/gpu-logging_qt-controls_android-fix (#4018)
5af7771f83-Bugfix: Made gpu_log_level global-only (was per-game switchable). Fixed Android non-determinism where a per-game profile silently overrode the global to Off and trapped GPULogger::Initialize() in a dead state, making shader dumps fail invisibly. Android per-game UI now hides the whole GPU logging block; Qt UI is untouched (global-only anyway).

bf4aabe8ab-Refactor/Cleanup: Removed gpu_logging_enabled master toggle as redundant with gpu_log_level == Off. Introduced GPU::Logging::IsActive() helper, replaced 14 call sites across vk_*.cpp. Refactored LogShaderCompilation() to be text-only and extracted SPIR-V dumping into a standalone GPU::Logging::DumpSpirvShader() free function. No singleton dependency, gated only by gpu_log_shader_dumps. Now gpu_log_level and gpu_log_shader_dumps are fully orthogonal. Cleaned up Android (BooleanSetting, SettingsItem, presenter, 7 locale string files).

865a1c5027-Refactor: Renamed dump_shaders → dump_guest_shaders to disambiguate from gpu_log_shader_dumps. Updated Qt label to "Dump Guest (Maxwell) Shaders" and rewrote the tooltip to mention .ash, the DumpDir/shaders/ location, and nvdisasm.

7cab456fdf-Feature: Added Qt UI control for GPU log level in the Logging session. Added gpu_log_shader_dumps checkbox to the Graphics column right below dump_guest_shaders.

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/4018
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
2026-06-27 02:52:13 +02:00
simply0001 629ebf1bde [video_core/maxwell3d] compute macro param address on demand (#4067)
GetMacroAddress only reads a couple of indices per macro, but ProcessMacro was
then building a full std::vector GPUVAddr> with one push_back per parameter word
every submission. macro_segments already holds base, count per chunk, so
GetMacroAddress can just walk it instead, drops the per-word loop, a
.clear(), and a vector member.

Also makes it so it returns on the first match in the macro dispatch instead of running every
std::get_if check.

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/4067
Reviewed-by: Lizzie <lizzie@eden-emu.dev>
Reviewed-by: CamilleLaVey <camillelavey99@gmail.com>
2026-06-26 04:15:31 +02:00
lizzie 3aa0d46259 [video_core, hle] remove redundant parent references in system structs (#3908)
reworked a bit to remove references of parent objects and instead pass as arguments to methods to prevent useless reloads

Signed-off-by: lizzie <lizzie@eden-emu.dev>
Co-authored-by: maufeat <sahyno1996@gmail.com>
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3908
Reviewed-by: Maufeat <sahyno1996@gmail.com>
Reviewed-by: crueter <crueter@eden-emu.dev>
2026-06-23 06:31:25 +02:00
lizzie f8facda35f [vk] Prevent OOM due to increased staging buffer on *nix (#4116)
*nix drivers for NVIDIA doesn't seem to like the increased size.
Windows is fine with it however.

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

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/4116
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
2026-06-23 01:48:11 +02:00
MaranBr 68aaea6085 [buffer_cache] Refactor buffer synchronization to use bounding-box download region (#4094)
Implement bounding-box buffer synchronization to minimize downloads and preserve GPU-modified regions during uploads.

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/4094
Reviewed-by: Lizzie <lizzie@eden-emu.dev>
Reviewed-by: Shinmegumi <shinmegumi@eden-emu.dev>
2026-06-22 17:05:59 +02:00
MaranBr ba608d2b57 [video_core] Add in-flight flush throttling to prevent CPU/GPU desync (#4085)
Prevent the CPU from getting too far ahead of the GPU by limiting pending flushes.

This fixes graphical issues in games that rely on better CPU and GPU synchronization in the Scheduler, such as the flickering bug inside shrines in The Legend of Zelda: Tears of the Kingdom.

This is enabled when the GPU is in Accurate mode.

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/4085
Reviewed-by: crueter <crueter@eden-emu.dev>
Reviewed-by: Shinmegumi <shinmegumi@eden-emu.dev>
2026-06-22 17:05:18 +02:00
MaranBr c22f57bc4e [video_core] Improve StagingBufferPool stream allocation (#4101)
This fixes (I really hope so) the random graphical corruption issue that can occur in Mario Kart 8 Deluxe and possibly other games as well.

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/4101
Reviewed-by: crueter <crueter@eden-emu.dev>
Reviewed-by: Shinmegumi <shinmegumi@eden-emu.dev>
2026-06-22 17:04:52 +02:00
lizzie c8c61a12c3 [dynarmic, MacroHLE] Fix crashes on W^X systems (#4090)
should fix crashes on:
- NetBSD
- SELinux
- OpenBSD
- other W^X systems
- some person trying to be funny with W^X on their system even if they dont have to

perf impact should be minimal

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

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/4090
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
Reviewed-by: Maufeat <sahyno1996@gmail.com>
2026-06-15 22:06:14 +02:00
lizzie 62ef8b15fd [video_core] correct not-quite-correct PTE_kind enumeration (#4077)
should now be more align with actual values/enums :)
trivial change

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

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/4077
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
Reviewed-by: Maufeat <sahyno1996@gmail.com>
2026-06-15 22:05:18 +02:00
BoiledElectricity 5ebb5b8772 [opengl] query GL_MAX_CLIP_DISTANCES instead of hardcoding 8 (#4095)
The GL shader profile hardcoded max_user_clip_distances to 8. Query the
device limit like the Vulkan path already does (it reads
maxClipDistances), so we use what the host actually reports.

Clamp to Maxwell's NumClipDistances (8) since the guest never produces
more than that and the SPIR-V output array is sized for at most 8. So a
host reporting fewer than 8 is respected, and one reporting more can't
overrun anything.

Fixes #3910
https://git.eden-emu.dev/eden-emu/eden/issues/3910

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/4095
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
Reviewed-by: Lizzie <lizzie@eden-emu.dev>
2026-06-15 04:30:40 +02:00
xbzk 73918d23d5 [video_core, maxwell] fixes for homebrew games that use MESA compiler (#4012)
two main issues:

shader_environment.cpp

Support Mesa nv50_ir-compiled homebrew fragment shaders
Mesa nv50_ir (used by NZP-Switch via libdrm_nouveau) emits Maxwell SASS that differs from NVN in two ways our shader pipeline didn't account for, causing "infinite" loops during shader scanning.

How?  TryFindSize() previously detected end-of-shader only via NVN's "BRA $-1" self-branch trailer (SELF_BRANCH_A/B). Mesa-compiled shaders end with an unconditional @PT EXIT and emit no trailer, so scanning ran past the shader and looped to MAXIMUM_SIZE.

Fix: Added a secondary match against @PT EXIT T (opcode 0xE30, predicate PT, flow T) as a fallback terminator. The mask is estrictive enough to reject predicated EXITs, conditional-flow EXITs, and sched control words, so well-formed NVN shaders see no ehavior change (their single @PT EXIT immediately precedes BRA $-1, and both detections return the same size).

load_store_attribute.cpp + attribute.h

IPA's is_perspective check only applied the ×position_w correction for IR::IsGeneric() attributes, and used a per-component SPH lookup. Two failure modes followed:

1. Mesa fragment shaders read varyings via legacy attribute slots
(ColorFrontDiffuse, FixedFncTexture, FogCoordinate) which are
remapped to generic varyings later by ConvertLegacyToGeneric. At
IPA-translation time they're still legacy, so IsGeneric() was
false and the inject was skipped — but the resulting GLSL/SPIR-V
varying was Smooth (perspective-correct), and the SASS still
issued its manual perspective dance via MUFU.RCP(ATTR_W)+FMUL,
compounding an extra ×clip_w factor. NZP fog (eye_z distance
varying) ended up as eye_z⁴×density² instead of eye_z²×density²,
saturating fog to white everywhere.

2. Even for legacy attrs that should inject, Mesa stores them in two formats selected by the IPA's interpolation_mode field:
Pass/Multiply/Constant → attr/w (perspective); inject ×position_w
Sc (ScreenLinear)      → raw attr; do NOT inject
Unconditionally injecting for Sc dims vertex colors by 1/clip_w because there's no SASS multiplier to round-trip it back.

Fix: extend the IPA correction path to also fire on IsLegacyAttribute(), gated on interpolation_mode != Sc. While here, the generic-path check is widened from per-component to vector-level (first non-Unused PixelImap, with all-Unused fallthrough treated as Perspective) so it matches the GLSL interpolation qualifier picked by CollectInterpolationInfo — this fixes the same all-zeroed-imap case Mesa exposes for explicit generics. IsLegacyAttribute moved from translate_program.cpp's anonymous namespace into attribute.h next to IsGeneric so IPA can reach it.

Tested on NaziZombies:Portable (Switch homebrew): fog now matches real
hardware, vertex-colored geometry (hand, gun, decals) renders correctly.

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/4012
Reviewed-by: Lizzie <lizzie@eden-emu.dev>
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
2026-06-15 03:05:11 +02:00
BoiledElectricity ef4113aeaa [video_core] fix TOCTOU in Vulkan instance extension enumeration (#4072)
So CreateInstance was enumerating instance extensions twice, and that could race if the driver returned a different list the second time. On some AMD iGPU drivers, we could enable an extension from the first list, then fail the second check with VK_ERROR_EXTENSION_NOT_PRESENT.

Fix this by enumerating once and passing that same snapshot into RequiredExtensions.

Fixes: https://github.com/eden-emulator/Issue-Reports/issues/414
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/4072
Reviewed-by: Lizzie <lizzie@eden-emu.dev>
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
2026-06-15 03:02:53 +02:00
xbzk 026974211e [vk, homebrew] ETC2 format list added (#4061)
Liz' command. ETC2 format list added. Used mainly in homebrew, NZ:P for example.

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/4061
Reviewed-by: Lizzie <lizzie@eden-emu.dev>
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
2026-06-15 03:00:58 +02:00
lizzie 60e1032771 [qt] fix various crashes due to invalid/corrupted/outdated settings (#4070)
lots of "out of index" errors :)

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

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/4070
Reviewed-by: crueter <crueter@eden-emu.dev>
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
2026-06-14 20:48:24 +02:00
MaranBr eb8086a011 [buffer_cache] Fix Xenoblade Chronicles series (#4066)
This fixes a bug introduced in the Xenoblade Chronicles series where some small elements would occasionally flicker on the screen.

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/4066
Reviewed-by: crueter <crueter@eden-emu.dev>
Reviewed-by: Lizzie <lizzie@eden-emu.dev>
2026-06-13 01:06:57 +02:00
lizzie 89199f4d27 [*] basic in-house cpp linting (#4039)
- add `#pragma once` to remainder files
- "correcter" defines (ANDROID), see https://groups.google.com/g/android-ndk/c/cf9_f1SLXls
- extra miscelly fixups

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

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/4039
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
Reviewed-by: crueter <crueter@eden-emu.dev>
2026-06-04 05:49:07 +02:00
lizzie 978d9d935d [vk/vma] force ANV to have HOST_CACHED stream buffers (#3792)
Signed-off-by: lizzie <lizzie@eden-emu.dev>
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3792
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
Reviewed-by: crueter <crueter@eden-emu.dev>
2026-06-04 05:48:41 +02:00