| Commit message (Collapse) | Author | Age | Files | Lines |
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
cce6d44af2 executes each command list entry from a copy of its words taken
at submit. Games submit command lists before writing them: the lists wait
behind a semaphore acquire, and the game writes their commands just before
it releases the acquire (Mario Kart World after present). The copies of
those lists were stale. Pokopia stopped after its first frame on macOS: its
GPU never reached the fence the game spun on (EDEN_NX2_PB_SNAPSHOT=0 made it
run again).
Count each channel's suspensions on an acquire and the resumes after them,
and record the count with each copy. A list copied while its channel was
suspended, or whose channel suspended since, reads guest memory instead.
Lists submitted and run without a wait in between keep the copy.
EDEN_NX2_PB_SNAPSHOT=0 still disables it altogether.
Assisted-by: Claude Sonnet 5.5 (first version); Claude Opus 5.5 (bisect, suspension count, testing and commit message)
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The trees fix (#52) drains the split and flushes for every command list
on a GPU-written page: in a Mario Kart World race ~13,500 lists and ~400
GPU round trips a second, during which the back has nothing to do. The
replay ran at ~40 fps instead of ~45.
The front now marks the pages those lists are on. The buffer cache notes
writes to them; after a compute dispatch or DMA copy that writes one it
copies the page into host memory and submits. The front waits for the
back only up to the last compute or copy work it sent (not everything
queued), then reads the copy once the GPU is done with it.
Pages the GPU wrote once, long before, and the CPU now writes lists to
have no copy: their first list drains and flushes the whole page, which
is then read from guest memory until GPU work writes it again. CPU
writes and inline uploads reach guest memory, so they keep such a page
synced but make a copy stale. A page a draw writes always drains.
Mario Kart World time-trial replay, Radeon 780M: ~40 -> ~45 fps, trees
drawn, no list drains left.
|
| |
|
|
| |
(add IsGpuWrittenCommands method to check GPU-written entries)
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
| |
With the present waiting for the previous frame's fence, the game
refills command memory it already submitted while the GPU thread is
still running that frame, so some frames rendered into the wrong image.
Copy each entry's words at submit and execute the copy. Resumed entries
and ranges the GPU has newer words for still read memory.
EDEN_NX2_PB_SNAPSHOT=0 executes from memory.
Ported from Wael3rd/Eglantine-MKW (bd3119a86f).
Assisted-by: Claude Sonnet 5.5 (porting the fix)
(cherry picked from commit 408bb84d06ae0729697ef9bed2c2ba76ce6dff42)
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Mario Kart World runs small command lists (20-byte entries) that its
culling dispatches fill in each frame. Accurate GPU mode reads every
command list through the caches; Fast mode reads guest memory directly
(on the split's front thread too), where those entries were still the
words of an older frame, so the draws behind them were left out: the
trees around the courses vanished in Fast mode only.
The buffer cache now also marks the device pages the GPU writes (shader
stores, copies of GPU-written data) in a bitmap the split's front can
read. A command list on such a page waits for the back to run what was
queued before it and is flushed when its words are still only in host
buffers. In a race that is ~5% of command lists (13,500 a second of
262,000) and ~400 flushes a second.
|
| |
|
|
|
|
|
|
|
|
| |
split
The split starts only with unsafe command reads, decided once at start-up. Switching to
accurate afterwards made the front thread flush caches the back thread owns, which raced on
Scheduler::chunk and crashed. MaybeStart now re-checks the settings between commands: it
drains and stops the split when they no longer allow it and starts it again when they do.
DmaPusher keeps unsafe reads while the split is active to cover the gap until then.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The GPU thread (front) takes the CPU's commands, parses command lists
and runs the puller; engine method calls and everything behind them
(registers, draws, dispatches, the rasterizer and its caches) run in
order on a second thread (back), fed through a single-producer
single-consumer ring (gpu_split.h). Work the front did on back-owned
state (end of command list flushes, channel binds, semaphore releases,
syncpoint increments, flush/invalidate requests, presentation) is
deferred into the same ring; the front waits for the back only where it
needs a result from that state: semaphore acquires and MME DMA reads.
EDEN_NX2_SPLIT=1 runs macros on the back. EDEN_NX2_SPLIT=2 runs the 3D
and compute macros on the front against copies of the registers they
read (Maxwell3D/KeplerCompute Front*), drops state writes that keep a
register's value there, and sends the rest. EDEN_NX2_SPLIT_VERIFY=1
compares the copies with the back's registers every 4096 macro calls
(0 differences in 40,193 checks in title 1); EDEN_NX2_SPLIT_CHECK=1
logs the stack of any other thread using the Vulkan scheduler while the
back runs. Switch 2 titles, Vulkan, non-accurate GPU only.
Title 1, 3D attract loop: ~44,000 draws a second on one thread, ~47,400
with EDEN_NX2_SPLIT=1, 50,000-66,500 with EDEN_NX2_SPLIT=2.
|
| |
|
|
|
|
|
| |
EDEN_NX2_GPU_PROFILE now times engine method calls (the work a split GPU thread's back half
would run) and counts semaphore acquires and those that wait. Title 1: method calls ~343 ms
a second (6.9 million), front-half work (command parsing, macros) ~333 ms, acquires ~2,700 a
second of which ~220 wait. Notes 140 (macro compiler) and 141 (draw setup).
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
off the hot path
- AMD CPUs have no CPUID leaf 0x15, so the TSC frequency stayed 0 and
every guest CNTPCT read went through QueryPerformanceCounter (~10% of
the game's main core in title 1). Measure it like Intel CPUs without
a crystal frequency.
- A rejected native shader was rethrown (two C++ throws) every time it
was bound; return false instead (~1-2% of the GPU thread).
- The semaphore watch, pushbuffer entry hashing, first-write trace and
per-macro debug logs ran on every command word or macro call; they
now cost a flag check unless their environment variable is set
(~4% of the GPU thread). Also starts the macro engine's profile zone.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
| |
Title 4 calls a 3D macro with a 6-word IncreaseOnce header, ends the main
GPFIFO entry after the first word and supplies the other five in a 5-word
subroutine entry. The split-method parking (an entry elsewhere was treated
as a call with a clean method state) fed those parameters to the parser as
headers: the macro ran with garbage, later draws read megabytes of unmapped
memory and the host driver timed out at the loading screen after the dock
scene. As on the hardware, the method state now simply continues; the old
guess stays behind EDEN_NX2_PARK_SPLIT_METHODS.
Debug aids: splits are logged at debug level with the words around them,
and a 3D write that interrupts a macro's parameters dumps the last 48 writes.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
- MME: implement MME_DMA_READ / MME_DMA_READ_FIFOED (Turing macros read query
results into their load FIFO; the conditional-render macro at 0x142 needs it).
- vi2 present waits up to 4 s for the frame fence (was 250 ms) so shader
compile stalls don't let the game lap its equal-value gate semaphores.
- Native QMD: fire the third release slot at word 52, which NVN2 patches for
queue-to-queue syncs (compute queue releasing a gate the 3D queue waits on).
- Compute class SET_REPORT_SEMAPHORE (0x6c0-0x6c3) releases.
- Ampere lowering: AOFFI, any LOP3 truth table, STG RZ, LDG 0x981, IABS,
I2FP rounding, IMAD negated addend, SHFL 0x989 (all 77 title-4 shaders lower).
- Debug: EDEN_NX2_SEM_WATCH=<addr> traces acquires, releases, method
arguments and compute macro emits for one semaphore block;
EDEN_NX2_KEY_SCRIPT scripted key presses; per-submit logs moved to TRACE.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
- gpu 214 creates GPU-only memory the graphics server backs itself (title 4
renders everything into six 300 MB regions at 0x81_0000_0000). Back each
with application-pool pages mapped into the alias code region and map that
for the GPU. This is what made title 4's frames appear.
- vi2 229 waits (bounded) for the presented frame's GPU fence: the reply
reports every buffer free, so without this the game laps Eden's GPU thread
and rewrites command memory it has not read yet.
- Split methods: keep several parked methods keyed by resume address (NVN
interleaves command buffers) and drop them when the submission ends.
- hid 214 (per-frame vibration send) answered quietly.
- Debug aids: EDEN_NX2_WINDOW_TRACE / EDEN_NX2_RT_TRACE (render targets,
clears, textures), EDEN_NX2_AUDIO_LEVEL (output peak), EDEN_NX2_PB_DUMP
(command list for offline replay), parsed-entry change check.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
NVN2 gates command buffers with semaphores the CPU releases after writing
them. Eden read past unmet SEMAPHORED acquires, so it executed stale commands
and desynchronised. Channels now suspend on an unmet acquire and resume from
the same word once it is met (scheduler keeps the waiting channels, the GPU
thread polls them), as in changes.patch.
Also: methods split across GPFIFO entries around a called command buffer are
set aside and resumed; subchannel 2 defaults to inline-to-memory; unbound
subchannels and out-of-range compute/DMA methods are dropped instead of
crashing; 4-byte semaphore releases no longer write 16 bytes; Ampere
SEM_PAYLOAD_HI/SEM_EXECUTE no longer spin as Kepler acquires; unmapped GPU
reads log instead of asserting. Debug aids: EDEN_NX2_PB_CHECK (pushbuffer
changed after submit), EDEN_NX2_QUERY_TRACE, a one-time pushbuffer dump.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
fixes (#4473)
- [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.
-------------------
Aimed to fix two known UE5 crashes: Kepler uploads and Maxwell macros, both caused by CPU/GPU races due dirty tracking issues.
Kepler ComputeInline: preserved dirty tracking across dma continuations and async readback.
Maxwell macros: preserved gpu owned subranges during page granular cpu uploads.
DiscardWrite: stopped clearing neighboring macro arguments by rounding up ranges.
DMA Step: improved continuation aware dirty sampling.
To the Ender Magnolia crew (maybe 1 or 2 persons): This will fix the dash crash, and the random / shackled beast vaper crashes.
There are some more UE5 issues to go next.
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/4473
Reviewed-by: lizzie <lizzie@eden-emu.dev>
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
(#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>
|
| |
|
|
|
|
|
|
|
|
| |
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>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
| |
format estimate (#4006)
u8 may have been 0xff, (aka. 255), but bitset was only 255 elements, so doing bitset[255] is technically OOB
additionally the max size estimate for index formats was not correct, there can be up to 256 elements with a u8 format index, not just 255
Signed-off-by: lizzie <lizzie@eden-emu.dev>
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/4006
Reviewed-by: crueter <crueter@eden-emu.dev>
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
|
| |
|
|
|
|
|
|
|
| |
state (#3987)
This fixes a deadlock issue that prevents any game using OpenGL + GPU Accurate from booting when Sync Memory Operations is enabled.
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3987
Reviewed-by: Lizzie <lizzie@eden-emu.dev>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
pipeline through multiple targeted optimizations (#3296)
- Scheduler: Reduced lock scope to allow parallel command preparation across channels
- DmaPusher: Added command prefetching (16-command lookahead) to improve cache hit rate
- Maxwell3D: Pre-allocated macro parameter vectors to eliminate dynamic allocations and unrolls dirty register tracking loop for better cache locality
- MacroEngine: Added last-executed macro cache to skip hash table lookups on hot path
Co-authored-by: lizzie <lizzie@eden-emu.dev>
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3296
Reviewed-by: Maufeat <sahyno1996@gmail.com>
Reviewed-by: DraVee <dravee@eden-emu.dev>
Co-authored-by: CamilleLaVey <camillelavey99@gmail.com>
Co-committed-by: CamilleLaVey <camillelavey99@gmail.com>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
for core stuff:
just remove unique ptrs that dont need any pointer stability at all (afterall its an allocation within an allocation so yeah)
for fibers:
Main reasoning behind this is because virtualBuffer<> is stupidly fucking expensive and it also clutters my fstat view
ALSO mmap is a syscall, syscalls are bad for performance or whatever
ALSO std::vector<> is better suited for handling this kind of "fixed size thing where its like big but not THAT big" (512 KiB isn't going to kill your memory usage for each fiber...)
for core.cpp stuff
- inlines stuff into std::optional<> as opposed to std::unique_ptr<> (because yknow, we are making the Impl from an unique_ptr, allocating within an allocation is unnecessary)
- reorganizes the structures a bit so padding doesnt screw us up (it's not perfect but eh saves a measly 44 bytes)
- removes unused/dead code
- uses std::vector<> instead of std::deque<>
no perf impact expected, maybe some initialisation boost but very minimal impact nonethless
lto gets rid of most calls anyways - the heavy issue is with shared_ptr and the cache coherency from the atomics... but i clumped them together because well, they kinda do not suffer from cache coherency - hopefully not a mistake
this balloons the size of Impl to about 1.67 MB - which is fine because we throw it in the stack anyways
REST OF INTERFACES: most of them ballooned in size as well, but overhead is ok since its an allocation within an alloc, no stack is used (when it comes to storing these i mean)
Signed-off-by: lizzie lizzie@eden-emu.dev
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3306
Reviewed-by: CamilleLaVey <camillelavey99@gmail.com>
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
Co-authored-by: lizzie <lizzie@eden-emu.dev>
Co-committed-by: lizzie <lizzie@eden-emu.dev>
|
| |
|
|
|
|
|
|
|
|
| |
operations (#3179)
This reworks the logic to improve performance in many games that heavily rely on DMA. It can help all platforms, but on desktop the performance boost can be noticeable, especially on dedicated GPUs. The option Sync Memory Operations must be enabled.
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3179
Co-authored-by: MaranBr <maranbr@outlook.com>
Co-committed-by: MaranBr <maranbr@outlook.com>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
toggle (#3129)
The GPU Accuracy level is now divided into Performance, Balanced and Accurate.
1. Performance prioritizes speed at all costs. It's faster, but it can be unstable and may have some bugs (which is expected).
2. Balanced maintains excellent performance and is safer against bugs and shader corruption.
3. Accurate is the most precise and the most expensive in terms of hardware. Only a few games still need this level to work properly.
The Release Early Fences toggle has also been removed by @PavelBARABANOV, as it's not needed anymore.
Co-authored-by: PavelBARABANOV <pavelbarabanov94@gmail.com>
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3129
Reviewed-by: Caio Oliveira <caiooliveirafarias0@gmail.com>
Reviewed-by: Maufeat <sahyno1996@gmail.com>
Co-authored-by: MaranBr <maranbr@outlook.com>
Co-committed-by: MaranBr <maranbr@outlook.com>
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
Mainly because - while we can just give out an AppImage and call it a day - building natively should be an option for all major distros.
And "base" stable debian doesn't provide a new enough g++/clang++ so... we need to make some "fixups".
Signed-off-by: lizzie <lizzie@eden-emu.dev>
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/2763
Reviewed-by: crueter <crueter@eden-emu.dev>
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
Co-authored-by: lizzie <lizzie@eden-emu.dev>
Co-committed-by: lizzie <lizzie@eden-emu.dev>
|
| |
|
|
|
|
|
|
|
|
|
| |
This simplifies DMA options in a clearer and more objective way.
Co-authored-by: PavelBARABANOV <pavelbarabanov94@gmail.com>
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/525
Reviewed-by: crueter <crueter@eden-emu.dev>
Reviewed-by: Shinmegumi <shinmegumi@eden-emu.dev>
Co-authored-by: MaranBr <maranbr@outlook.com>
Co-committed-by: MaranBr <maranbr@outlook.com>
|
| |
|
|
|
|
|
|
|
|
|
| |
This adds an option to control the DMA precision level at runtime.
Co-authored-by: crueter <crueter@eden-emu.dev>
Co-authored-by: PavelBARABANOV <pavelbarabanov94@gmail.com>
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/304
Reviewed-by: crueter <crueter@eden-emu.dev>
Co-authored-by: MaranBr <maranbr@outlook.com>
Co-committed-by: MaranBr <maranbr@outlook.com>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
(#276)
This improves DMA logic and add an option to sync memory operations.
Thanks to Higgs for the new DMA logic.
Co-authored-by: PavelBARABANOV <pavelbarabanov94@gmail.com>
Co-authored-by: crueter <crueter@eden-emu.dev>
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/276
Reviewed-by: crueter <crueter@eden-emu.dev>
Co-authored-by: MaranBr <maranbr@outlook.com>
Co-committed-by: MaranBr <maranbr@outlook.com>
|
| |
|
|
|
|
| |
Signed-off-by: crueter <crueter@eden-emu.dev>
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/185
Reviewed-by: Lizzie <lizzie@eden-emu.dev>
|
| | |
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
- Modify DmaPusher to use safe memory reads when handling compute
operations at High GPU accuracy
- Prevent potential memory corruption issues that could lead to
invalid dispatch parameters
- Previously, unsafe reads could result in corrupted launch_description
data in KeplerCompute::ProcessLaunch, causing invalid vkCmdDispatch
calls
- By enforcing safe reads specifically for compute operations, we
maintain performance for other GPU tasks while ensuring compute
dispatch stability
This change requires >= High GPU accuracy level to take effect.
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| |
|
|
|
| |
resize keeps previous data intact when the buffer grows
resize_destructive destroys the previous data when the buffer grows
|
| |
|
|
| |
Uses ScratchBuffer and avoids overwriting the command_headers buffer with the prefetch_command_list
|
| | |
|
| | |
|
| |
|
|
|
| |
This formats all copyright comments according to SPDX formatting guidelines.
Additionally, this resolves the remaining GPLv2 only licensed files by relicensing them to GPLv2.0-or-later.
|
| | |
|
| | |
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Reimplement the buffer cache using cached bindings and page level
granularity for modification tracking. This also drops the usage of
shared pointers and virtual functions from the cache.
- Bindings are cached, allowing to skip work when the game changes few
bits between draws.
- OpenGL Assembly shaders no longer copy when a region has been modified
from the GPU to emulate constant buffers, instead GL_EXT_memory_object
is used to alias sub-buffers within the same allocation.
- OpenGL Assembly shaders stream constant buffer data using
glProgramBufferParametersIuivNV, from NV_parameter_buffer_object. In
theory this should save one hash table resolve inside the driver
compared to glBufferSubData.
- A new OpenGL stream buffer is implemented based on fences for drivers
that are not Nvidia's proprietary, due to their low performance on
partial glBufferSubData calls synchronized with 3D rendering (that
some games use a lot).
- Most optimizations are shared between APIs now, allowing Vulkan to
cache more bindings than before, skipping unnecesarry work.
This commit adds the necessary infrastructure to use Vulkan object from
OpenGL. Overall, it improves performance and fixes some bugs present on
the old cache. There are still some edge cases hit by some games that
harm performance on some vendors, this are planned to be fixed in later
commits.
|
| |
|
|
|
|
| |
Resolves variable shadowing scenarios up to the end of the OpenGL code
to make it nicer to review. The rest will be resolved in a following
commit.
|
| |
|
|
| |
- This seems to cause softlocks in Breath of the Wild.
|