Skip to content

Releases: Djihads80/Eglantine

Eglantine nx2 build 117 (be71c42)

Pre-release

Choose a tag to compare

@github-actions github-actions released this 02 Nov 02:35
be71c42

Automatic build of nx2 at be71c42.

Windows: extract the zip and run eglantine.exe, or eden-cli.exe from a terminal.
Linux (AppImage): make it executable (chmod +x) and run it; it bundles its libraries and needs glibc 2.39 or newer (Ubuntu 24.04, Fedora 40, Debian 13, Arch).
Linux (tar.gz): extract it and run ./eglantine or ./eden-cli; it uses your system libraries, so Qt 6 and the usual libraries must be installed.
macOS: Apple Silicon and macOS 15 or newer. Unzip and move eglantine.app to Applications; eden-cli is inside it, in Contents/MacOS. The app is not notarized, so the first time right-click it and choose Open (or run xattr -dr com.apple.quarantine eglantine.app).
The -pgo builds are the same programs compiled with profile-guided optimization (clang plus Eden's profile); prefer them when your CPU supports it. The Windows PGO build is a MinGW build, so it carries its own DLLs and needs no Visual C++ redistributable.

Performance Update with AMD Fixes enabled (nx2-experimental)

Choose a tag to compare

@github-actions github-actions released this 02 Nov 00:29

What's new in this build

This is build 116 of nx2-experimental (6612817). Against build 109 — the last nx2-experimental build that is still published, since build 113 was up for about 45 minutes and has been removed — it adds eight fixes and the .nup loader that build 110 shipped on nx2. Everything build 109 had is still here, including the task/mesh shader work and the EDEN_NX2_* switches. Nothing needs configuring.

Fewer deaths when VRAM runs out (AMD)

  • A session on a full card no longer kills the process. The texture cache measures its own usage, but the driver also counts the unused tail of the allocator's blocks, which the cache could not see. On an RX 7800 XT that tail was 1.06 GiB — the entire safety margin — so the heap sat at its budget for a minute while the cache still believed there was room, then images stopped fitting and the process died. The block slack is now reserved on top of the margin.
  • Images that do not fit go to host memory instead of being left with nothing bound. An image with no memory behind it crashes AMD's drivers the moment it is sampled (an RX 6600 died mid-flood; an RX 7800 XT created 211 of them, 8x8 ones included). Such images are now backed in host memory — slower, but valid — and each occurrence makes the cache keep more room free until the pressure stops. Images too large to back at all still use the sparse fallback.
  • Sparse images no longer divide by a block size AMD reports as zero. The sparse layer setup used the driver's imageGranularity, which AMD returns as 0 and which crashed. It now uses Vulkan's standard 64 KiB 2D block shape when the device promises it, and skips sparse layers with a warning when it does not.
  • The three margins now log as Memory margins: base … MiB, out of memory … MiB, block slack … MiB, and a miss logs Out of device memory: keeping … MiB more free, so a report can say which one is doing the work.

Mario Kart World: frames in the right image, and the trees stay

The present returns before the GPU thread reaches that frame's work, and the game refills command memory it has already submitted, so the end of a frame could run with the next frame's present image as its target — frames landed in the wrong image and an image three frames old could be shown. Command lists are now copied when they are submitted and the copy is what gets executed; EDEN_NX2_PB_SNAPSHOT=0 goes back to executing from guest memory.

That copy has one exception: command lists the GPU itself fills — the small culling lists the game rebuilds every frame — have to be read at execution time, because their words at submit time belong to an older frame. Entries on GPU-written pages always take the flushing read, which is what keeps the trees from vanishing.

Splatoon Raiders: fog is back

Three of its pixel shaders were rejected and their draws skipped, which is why the fog was missing: TXD refused word 2 bit 90, a bit its own emit already forwards as NODEP. It is accepted now, so those shaders compile and their draws run.

GameChat: no more log flood from nx2:camera

GameChat polls nx2:camera command 29 every frame and each call was logged as an unimplemented function — a Critical and a Warning line, 40,000 of them in one session. Commands 3, 21 and 29 now answer with an empty success and are logged once each.

Cheaper native shader capture

A Switch 2 shader used to be captured and lowered when its ShaderInfo was made and again for every environment built for its pipelines; the lowered code now lives in the ShaderInfo and the environments adopt it. The capture also reads guest memory a 4 KiB page at a time instead of flushing the GPU caches for every 16-byte instruction. This is CPU work removed from first encounters with a program, not a measured frame-time change.

.nup packages (from build 110)

.nup containers now load as games: the base program with the newest update inside the container layered over it, title/icon/version read from the container's metadata, add-on content recognised but not yet mounted. Same behaviour and caveats as build 110.

Coming from build 110?

Build 110 was an nx2 build without the nx2-experimental batch. This build is 109's batch plus 110's .nup loader plus the eight fixes above, so nothing 110 had is missing here.

How it works, for the technically curious

  • Device::GetDeviceMemorySlack() reports statistics.blockBytes - allocationBytes from VMA's main heap; the texture cache keeps it as a third margin (capped at 1.5 GiB, taken at once when it grows and released 16 MiB at a time), and critical_memory/expected_memory are now budget - (margin + pressure_margin + slack_margin) and one margin below that.
  • MemoryAllocator::CreateImage retries an out-of-device-memory image with VMA_MEMORY_USAGE_AUTO_PREFER_HOST before the sparse fallback, and counts both cases in MemoryPressureEvents(); the cache turns each new event into +512 MiB of pressure_margin (max 3 GiB) and releases 128 MiB every 600 quiet frames.
  • InitSparseLayers falls back to StandardSparseBlockShape() (256x256 texels for 1-byte blocks down to 64x64 for 16-byte) when imageGranularity is zero and residencyStandard2DBlockShape is set.
  • nvhost_gpu::SubmitGPFIFOImpl snapshots each entry's words with ReadBlockUnsafe into CommandList::submitted_words, and DmaPusher::Step executes that span unless the entry is resumed, the GPU wrote newer words over it (IsMemoryDirty under safe reads), or it lies on GPU-written pages — DmaPusher::IsGpuWrittenCommands (the check FlushGpuWrittenCommands used, now shared) keeps those on the flushing read. EDEN_NX2_PB_SNAPSHOT=0 disables the snapshot.
  • ShaderInfo carries std::shared_ptr<const LoweredNativeCode> filled by GenericEnvironment::LoweredNative(); GraphicsEnvironment/ComputeEnvironment take it as a constructor argument and InitializeNativeCode skips LowerNativeCode when it is present. NativeInstructionReader loads 4 KiB pages with ReadBlockUnsafe and falls back to a single checked ReadBlockUnsafe for instructions outside a fully mapped page.
  • INx2CameraSession replaces the auto stub for the nx2:camera session that nx2:gsv 602 returns, answering TIPC 3/21/29 with an empty success and one warning per command.
  • TXD's predicate now masks bit 90 out of word 2 (it is forwarded below as NODEP).

Automatic build of nx2-experimental at 6612817.

Windows: extract the zip and run eglantine.exe, or eden-cli.exe from a terminal.
Linux (AppImage): make it executable (chmod +x) and run it; it bundles its libraries and needs glibc 2.39 or newer (Ubuntu 24.04, Fedora 40, Debian 13, Arch).
Linux (tar.gz): extract it and run ./eglantine or ./eden-cli; it uses your system libraries, so Qt 6 and the usual libraries must be installed.
macOS: Apple Silicon and macOS 15 or newer. Unzip and move eglantine.app to Applications; eden-cli is inside it, in Contents/MacOS. The app is not notarized, so the first time right-click it and choose Open (or run xattr -dr com.apple.quarantine eglantine.app).
The -pgo builds are the same programs compiled with profile-guided optimization (clang plus Eden's profile); prefer them when your CPU supports it. The Windows PGO build is a MinGW build, so it carries its own DLLs and needs no Visual C++ redistributable.

AMD Experimental Build 77-2 (a42b4d4)

Pre-release

Choose a tag to compare

@github-actions github-actions released this 01 Nov 13:45

Experimental AMD build — not the regular nx2 build. This is the second build from hotfix/amd-sparse-lazy-crash (build 94 was the first), at a42b4d4. It exists to test AMD driver crash fixes on Switch 2 titles. The branch is still a parallel line, not a superset: it has everything build 94 had plus the three changes below, and it is missing the regular build's newer fixes, which are listed further down. If you are not on an AMD GPU, use build 98 instead.

What's changed since build 94

Crashes and memory

  • Running out of VRAM no longer leaves textures with nothing behind them. When device memory ran out, any image that failed to allocate was turned into a sparse image with nothing bound to it, and AMD's drivers crash when one of those gets sampled: an RX 6600 went down mid-flood, and an RX 7800 XT ended up with 211 of them, 8x8 ones included. Images that don't fit now go to host memory instead — slower, but real memory the GPU can read — and the sparse fallback is kept only for images too large to back at all. Each failed allocation is also counted, and the texture cache answers by keeping more room free: 512 MiB more per event up to 3 GiB, released 128 MiB at a time once 600 frames pass without a new one. In the log it shows as Out of device memory: keeping N MiB more free. (eff0fe3)

Rendering

  • Splatoon Raiders: the missing fog was three pixel shaders being thrown out. Three of its pixel shaders used TXD and TXQ forms the Ampere→Maxwell lowering rejected, so their draws were skipped. Both checks were stricter than they needed to be: TXD refused a word-2 bit that its own emit already forwards as Maxwell's NODEP, and TXQ refused query mask 4 (depth), whose Maxwell mask bits are passed through exactly like the other masks. They lower now, so the fog draws. (a42b4d4)

Logging

  • GameChat's camera polling no longer floods the log. GameChat asks nx2:camera command 29 for camera state every frame. It fell through the nx2 auto stub, which logged a Critical plus a Warning line on every call — 40,000 calls in one session. Commands 3, 21 and 29 are now answered directly with the same empty success and log once each. Nothing about the game changes; the log file just stops growing. (0b7b562)

What this build does not have

These are already in the regular build 98 and are not here, because this branch is a parallel line:

  • AMD Boost (post_shaders/AMDBoost.fx — FSR 1 EASU upscaling, RCAS sharpening, optional denoise) — build 87.
  • GPU buffer readback to the CPU, which fixes visible glitches such as missing collision on some objects — build 89.
  • Pokopia's name entry (Switch 2 software keyboard) and its Linux Opus bundling (without it the game gets stuck on Ditto) — builds 96 and 98.
  • Linux ARM64 builds, Linux .tar.gz packages and the Discord pre-release ping — CI only, builds 89 and later.

Downloads

x86_64 only, same as build 94: Linux AppImage and Windows x64 zip, each plain and PGO.

Windows: extract the zip and run eglantine.exe, or eden-cli.exe from a terminal.
Linux (AppImage): chmod +x it and run it; it bundles its libraries and needs glibc 2.39 or newer (Ubuntu 24.04, Fedora 40, Debian 13, Arch).
The -pgo builds are the same programs compiled with profile-guided optimization (clang plus Eden's profile); prefer them when your CPU supports it. The Windows PGO build is a MinGW build, so it carries its own DLLs and needs no Visual C++ redistributable.

Full diff against the previous build of this line: build-94...build-99


Full Changelog: build-96...build-99

Eglantine nx2 build 98 (adae763)

Pre-release

Choose a tag to compare

@github-actions github-actions released this 01 Nov 13:05

What's Changed

Full Changelog: build-96...build-98

Eglantine nx2 build 96 (e96917c)

Pre-release

Choose a tag to compare

@github-actions github-actions released this 01 Nov 07:48
e96917c

What's Changed

  • fix: resolve frame_gen double binding in graphics configuration by @sdas-19 in #112
  • am: fix Pokopia freezing at the name entry (software keyboard on Switch 2) by @rdenno in #135

New Contributors

Full Changelog: build-92...build-96

AMD Experimental Build 77 (3af11ac)

Pre-release

Choose a tag to compare

@github-actions github-actions released this 01 Nov 03:01

Experimental AMD build — not the regular nx2 build. This one comes from the hotfix/amd-sparse-lazy-crash branch at 3af11ac, which branched off before build 92's work. It exists to test AMD driver crash fixes on Switch 2 titles (Mario Kart World in particular). If you are not on an AMD GPU, use build 92 instead — it is the regular build and has everything listed as missing below.

What's new in this build

  • Large sparse images are backed normally on AMD again. Lazy Switch 2 sparse regions made the texture cache create large images with no memory bound and sample them; AMD's driver crashes shortly after the first such draw (builds 49+). Unbacked-image paths are now skipped on AMD drivers, so images get regular backing as in build 47. (c2a3ae1)
  • No more divide by a zero sparse block size. Image::InitSparseLayers divided by the image granularity the driver reports, which AMD reports as 0. It now uses Vulkan's standard 2D block shape when the device reports residencyStandard2DBlockShape, and otherwise does not use sparse layers at all. (eadb9fc)
  • Command lists are executed as submitted. With present waiting on the previous frame's fence, the game refilled command memory it had already submitted while the GPU thread was still running that frame, so some frames rendered into the wrong image. Each entry's words are now copied at submit time and the copy is executed. Resumed entries and ranges the GPU has newer words for still read memory. EDEN_NX2_PB_SNAPSHOT=0 restores executing from memory. (408bb84)
  • Native shader programs are captured and lowered once instead of once per pipeline environment. Capture also reads a 4 KiB page at a time instead of flushing caches per instruction, and cached native programs fold bank 1 reads the same way live ones do. (3af11ac)

What this build does not have

These landed after this branch point and are not in this build — they are in build 92:

  • The AMD Boost post-processing effect (post_shaders/AMDBoost.fx) is absent.
  • Linux ARM64 builds and Linux .tar.gz packages are not produced from this branch.

Corrected: an earlier version of this list said handheld present images were still not cropped to the panel. They are cropped in this build, so only the two items above are actually missing.

Downloads

Only x86_64 is built from this branch:

  • Linux: AppImage, plain and PGO.
  • Windows: x64 zip, plain and PGO.

Windows: extract the zip and run eglantine.exe, or eden-cli.exe from a terminal.
Linux (AppImage): make it executable (chmod +x) and run it; it bundles its libraries and needs glibc 2.39 or newer (Ubuntu 24.04, Fedora 40, Debian 13, Arch).
The -pgo builds are the same programs compiled with profile-guided optimization (clang plus Eden's profile); prefer them when your CPU supports it. The Windows PGO build is a MinGW build, so it carries its own DLLs and needs no Visual C++ redistributable.

Full diff against build 92: build-92...build-94 (12 commits ahead, 18 behind — the branch is a parallel line, not a superset).

Eglantine nx2 build 92 (3790898)

Pre-release

Choose a tag to compare

@github-actions github-actions released this 01 Nov 01:44

What's changed in this build

No emulation changes. Build 92 is build 91 plus one fix for building from source.

  • Configure works in a git worktree or submodule checkout. .git is a file there, not a directory, so the pre-commit hook copy is now skipped instead of aborting configure. Normal clones are unaffected, and nothing changes for people who only run the emulator. (#140)

Also new, if you have not updated since build 86

  • Handheld present images are cropped to the panel (build 86). Handheld titles that keep docked-size present images now fill the screen instead of drawing the frame into the top-left inside black margins, which scaled with the window. Mario Kart World and Splatoon Raiders were the visible cases. Mario Kart World's docked 2560x1440 crop is unchanged. (#126)
  • New post-processing effect: AMD Boost (build 87). post_shaders/AMDBoost.fx is a combined upscale/sharpen chain — FSR 1 EASU upscaling (1.0x-4.0x), RCAS sharpening and optional denoise — with its sliders and checkbox in the post-processing settings.
  • Linux ARM64 builds, experimental (build 89). aarch64 AppImages and tarballs are now published next to the x86_64 ones, with and without PGO.
  • Linux tar.gz packages (build 89). Every Linux build also ships as .tar.gz, which links your system Qt 6 instead of bundling it.

Automatic build of nx2 at 3790898.

Windows: extract the zip and run eglantine.exe, or eden-cli.exe from a terminal.
Linux (AppImage): make it executable (chmod +x) and run it; it bundles its libraries and needs glibc 2.39 or newer (Ubuntu 24.04, Fedora 40, Debian 13, Arch).
Linux (tar.gz): extract it and run ./eglantine or ./eden-cli; it uses your system libraries, so Qt 6 and the usual libraries must be installed.
The -pgo builds are the same programs compiled with profile-guided optimization (clang plus Eden's profile); prefer them when your CPU supports it. The Windows PGO build is a MinGW build, so it carries its own DLLs and needs no Visual C++ redistributable.

Eglantine nx2 build 91 (feff94e)

Pre-release

Choose a tag to compare

@github-actions github-actions released this 01 Nov 00:23

What this build adds

No emulator changes. This tag is build 90 plus a single CI commit, so the emulator code is the same as the last build; only the release automation changed.

Release link in the Discord announcement. The webhook message from build 90 named the build and its commit but gave no way to reach the download:

  • The step now builds the direct URL from GITHUB_REPOSITORY and the run number (https://github.com/<repo>/releases/tag/build-<run number>) and appends it as a second line of the message.
  • The tag is the run number the workflow itself publishes under, so the link is always the release that was just created.
  • The message is assembled with printf into MSG and handed to jq --arg in one go, so the newline and any quoting in the URL cannot break the JSON payload.

Automatic build of nx2 at feff94e.

Windows: extract the zip and run eglantine.exe, or eden-cli.exe from a terminal.
Linux (AppImage): make it executable (chmod +x) and run it; it bundles its libraries and needs glibc 2.39 or newer (Ubuntu 24.04, Fedora 40, Debian 13, Arch).
Linux (tar.gz): extract it and run ./eglantine or ./eden-cli; it uses your system libraries, so Qt 6 and the usual libraries must be installed.
The -pgo builds are the same programs compiled with profile-guided optimization (clang plus Eden's profile); prefer them when your CPU supports it. The Windows PGO build is a MinGW build, so it carries its own DLLs and needs no Visual C++ redistributable.

Eglantine nx2 build 110 (f6d03bc)

Pre-release

Choose a tag to compare

@github-actions github-actions released this 01 Nov 23:04
f6d03bc

What's new in this build

This is build 110 of the nx2 branch (f6d03bc). Against the previous nx2 build (104) it adds .nup support and updates the Nix dev shell; nothing else in the tree changed.

.nup games now load

If your dump is a single .nup file rather than an .nsp/.xci, you can now add it to the game list and launch it like any other title: the emulator reads the program, the RomFS, the name, the icon and the version straight out of the container.

  • Base and update in one file. A NUP can hold the base program together with its updates; the newest update inside the container is layered over the base automatically, so the game runs at the version that was packed. A container with only an update (no base) boots on its own from its complete patched tree.
  • It appears like a normal game. Title name, icon and display version are read from the container's metadata, when the container carries them.
  • DLC is not available yet. Add-on content packages inside a container are recognised but not mounted; the log says NUP container has N add-on content package(s); AoC mounting is not supported yet when there are any.
  • A corrupt file is rejected, not crashed on. The table of contents is SHA-256 checked when the file is opened, and a bad file gives "The NUP container is malformed or its TOC hash does not match" instead of a crash; a container without a loadable program gives "The NUP container does not contain a loadable base package".
  • .nup is a normal supported extension, so nothing needs configuring: it works through Open file and when scanning a folder.

Also in this build

  • shell.nix: moved to nixpkgs 25.05 (ninja, fmt_11, sdl3, qt6.qtcharts, mesa), VK_DRIVER_FILES now points at Nix's Mesa RADV because host /usr Vulkan drivers cannot be loaded inside the Nix shell, and a shellHook exports CMAKE_PREFIX_PATH. This only affects building in a Nix dev shell.

If you are coming from build 109

Build 109 was an nx2-experimental build that merged nx2 with the test/linux-all-prs topic batch. This build does not contain that batch. It is nx2 at f6d03bc plus the .nup loader, and the experimental commits — task/mesh shader support and the EDEN_NX2_NO_MESH switches, the ISBERD/ISBEWR Ampere lowering, reading GPU-written command lists, the EDEN_NX2_DRAW_LOG diagnostics, and the Vulkan memory, texture-cache, Dynarmic and vfs work — are not in it. If you were running 109, take an nx2-experimental build (113 or later) instead of this one.

How it works, for the technically curious

  • New FileType::NUP with Loader::AppLoader_NUP and FileSys::NupContainer. Layout: a 0x80-byte superblock (magic NUP\x01), a table of contents (package records, dir/file nodes, children array, string pool), then a blob region of 16-byte-aligned per-file extents that are either raw or zstd-compressed.
  • The TOC's SHA-256 is compared with the superblock before anything else is trusted, and VerifyIntegrity streams each member against its own stored SHA-256.
  • Packages are base, update and add-on. FindBestUpdatePackage takes the highest version; the update's ExeFS and RomFS are shadow-merged over the base (MergeShadowDirs) and the ExeFS is wrapped as a deconstructed ROM directory. An update-only container boots its update tree directly.
  • Per-package meta TLVs carry NPDM bytes, default and localized names, default and localized icons and a display version; a NACP is synthesised from them for the game list.
  • zstd extents are decompressed on first read and cached per container (LRU, 512 MiB cap).
  • IsSwitch2Program also reads main.npdm from a NUP's ExeFS, so a Switch 2 title packed as NUP gets the same per-title handling as a loose NX2 dump.
  • Two new result statuses: ErrorNUPBadFormat, ErrorNUPNoBasePackage.

Automatic build of nx2 at f6d03bc.

Windows: extract the zip and run eglantine.exe, or eden-cli.exe from a terminal.
Linux (AppImage): make it executable (chmod +x) and run it; it bundles its libraries and needs glibc 2.39 or newer (Ubuntu 24.04, Fedora 40, Debian 13, Arch).
Linux (tar.gz): extract it and run ./eglantine or ./eden-cli; it uses your system libraries, so Qt 6 and the usual libraries must be installed.
macOS: Apple Silicon and macOS 15 or newer. Unzip and move eglantine.app to Applications; eden-cli is inside it, in Contents/MacOS. The app is not notarized, so the first time right-click it and choose Open (or run xattr -dr com.apple.quarantine eglantine.app).
The -pgo builds are the same programs compiled with profile-guided optimization (clang plus Eden's profile); prefer them when your CPU supports it. The Windows PGO build is a MinGW build, so it carries its own DLLs and needs no Visual C++ redistributable.

Performance Update (nx2-experimental)

Pre-release

Choose a tag to compare

@github-actions github-actions released this 01 Nov 22:13

What's new in this build

Games that are able to boot

Donkey Kong Bananza (Boots to warning screen)
Pokopia (Goes in game now with graphic inaccuracies)
Nintendo Switch Sports Resort (Goes to Title Screen and Sports Select)
Kirby Air Riders (Goes to Title Screen)

This build is a merge of the latest nx2 work (nx2 plus the test/linux-all-prs topic branches). Compared with build 104 it is mostly Switch 2 graphics and service progress, plus another round of Vulkan memory and pipeline work.

Task and mesh shaders (Switch 2)

Switch 2 titles draw some geometry with NVN task + mesh programs, which Eden used to reject and skip.

  • Task and mesh programs are now translated in the shader recompiler (ISBERD/ISBEWR are kept as a pseudo instruction through the Ampere lowering, with an emulated stage buffer for the task payload and workgroup memory) and drawn as native Vulkan mesh pipelines through VK_EXT_mesh_shader.
  • The pipelines are keyed by SET_MESH_SHADER_A/B and SET_MESH_INIT_SHADER and are deliberately kept out of the disk pipeline cache.
  • Practically: high-detail LODs and other task/mesh-drawn geometry now render instead of popping in and out at low quality.
  • EDEN_NX2_NO_MESH and EDEN_NX2_NO_MESH_FILE disable task/mesh at run time, if you want to compare or bisect a problem.

Switch 2 GPU ISA coverage

A large batch of Ampere instructions now lowers instead of being rejected:

  • Textures: TEX.B/TLD.B with an explicit LOD, TLD.SCR/TLD.SCR.LL with texel offsets, TLD4 with texel offsets and with a uniform handle, TMML (including .B, 1D/3D/cube and uniform handles), TXQ/TXQ.B with three or four outputs and on any descriptor buffer, bindless TEX.
  • ALU and control: LEA (with carry out and with a uniform addend), IADD3.X, IMAD.WIDE.U32/UIMAD.WIDE.U32 with immediate multipliers, ISETP.EX, FSETP on uniform registers, USHF above UR15, FRND from a constant buffer, MUFU from a uniform register, UPRMT, I2F.U8, REDUX.MIN/OR/XOR, MATCH.ALL (32-bit and .ALL), CSMTEST, jump tables with instructions between the clamp and BRX.
  • Memory: all ATOMS operations and ATOMS.POPC.INC, SULD.P.3D, SURED.ADD on 2D surfaces, LDC.IS, 128-bit and register-addressed local spills, local load/store size read from bits 73-75, more special registers through S2R.
  • Uniform registers above UR27 are mirrored below R216, and SR_VARIABLE_RATE reads as 1x1 shading.

Switch 2 display, GPU and services

  • gsv: image commands in the feature groups now reach the real image handlers, commands games call get their real behavior, decoder output images are freed on gsv 912, later-SDK video decoder commands are handled, and the area of a present the game says it drew is reported.
  • vi2: full replies to display queries, vi2 212 answers with the layer's ready buffer slots, each event slot has its own source, SDR output is reported on vi2 104, and the TIPC 0 handshake is echoed on the gpu and vi2 sessions.
  • nvdrv/GPU: guest GPU memory is mapped on the GPU thread, GPU-only regions are backed as they are written, the graphics server pool is down to 2 GiB, graphics device ids are handed out for gpu 41/42, nvhost-prof-gpu can be opened, syncpoint signals past the table are ignored, 2D/3D/compute/I2M/ZBC support is reported in the Switch 2 GPU flags, and frame pacing also waits for the presented frame when the GPU is behind.
  • HLE: placeholder handlers for known-but-unimplemented commands, auto-stubbed commands return zeroed replies and are reported only once; bsd command 36 (client registration), hid 213 and 220, audio device notification events, real objects for auddmg:u/audsmx:u, audio renderer revision 16, ssl:s CreateContext and three reply shapes, nsd reply sizes 15/21, am IApplicationFunctions 320/321 and a 12-byte GetCurrentGraphicsScale, ro NRR hash lists read in place, built-in Switch 2 fonts on their own shared memory, and an empty archive served when Switch 2 system data is missing.

Vulkan renderer

  • Memory: 16 MiB and 32 MiB blocks with best-fit placement for images, sparse pages and device-local buffers kept out of the image blocks, images collected in the emptiest blocks first, device memory collected from 5 GiB on every GPU, and a stream buffer that stays inside a small iGPU heap.
  • Pipeline cache: the disk cache is left to NVIDIA's and AMD's drivers, only the pipelines recent sessions used are built at boot, graphics pipelines unused for 9000 frames are destroyed, shader modules are dropped once their pipeline is built, and boot builds are capped when there is no used list yet.
  • Streaming and blits: 128 MiB stream buffer everywhere, ASTC transcode decode images are reused, software blits keep scratch buffers up to 2 MiB, touch only the rows they cover, and release buffers grown for huge surfaces.
  • Guest memory uploads are hinted as cold, clearing is skipped when the memory is still zero, big pages are copied without per-page host work, and the memory manager notifies the caches once per changed range.
  • A failing shader's dump no longer takes the process down with it.

Texture cache

  • Deleted allocations and framebuffers release their slots; deleting an image no longer walks every channel's tables, finds view entries without a scan, and waits for the GPU to be past the image; images still waiting to be destroyed are not counted.
  • Sparse images get no device memory over unwritten blocks and their guest memory is cold-hinted; large ASTC arrays are decoded only for the written layers.
  • Huge ASTC arrays are trimmed harder on small GPUs, and the ASTC opaque check uses a table of block modes.
  • Default ASTC recompression is now BC3 instead of uncompressed, which keeps VRAM use in check on GPUs without ASTC support.

CPU (Dynarmic)

  • Compact per-block tables, untouched locations skipped at the end of an IR instruction, the x64 code cache committed as code is emitted, and the cached code page dropped when a range is invalidated.
  • Faster register allocation.

Filesystem, loader and UI

  • vfs_real keeps only the path in a real file and forgets a path when its file is gone; a RomFS build's nodes no longer own each other; a loose RomFS is built once and only when it is read; a loose dump's display version is read from its own files.
  • Qt no longer asks for decryption keys at startup.
  • Fixed the nix shell script.

Full Changelog: build-104...build-109


Automatic build of nx2-experimental at 350c647.

Windows: extract the zip and run eglantine.exe, or eden-cli.exe from a terminal.
Linux (AppImage): make it executable (chmod +x) and run it; it bundles its libraries and needs glibc 2.39 or newer (Ubuntu 24.04, Fedora 40, Debian 13, Arch).
Linux (tar.gz): extract it and run ./eglantine or ./eden-cli; it uses your system libraries, so Qt 6 and the usual libraries must be installed.
macOS: Apple Silicon and macOS 15 or newer. Unzip and move eglantine.app to Applications; eden-cli is inside it, in Contents/MacOS. The app is not notarized, so the first time right-click it and choose Open (or run xattr -dr com.apple.quarantine eglantine.app).
The -pgo builds are the same programs compiled with profile-guided optimization (clang plus Eden's profile); prefer them when your CPU supports it. The Windows PGO build is a MinGW build, so it carries its own DLLs and needs no Visual C++ redistributable.