Hi viejunerd,
I've been trying to get Ocarina of Time running on my PS5 since i…t came out, and it now gets to the point where you can walk Link out of his house into Kokiri Forest. It's nowhere near playable, it crashes after a couple of minutes, but it's further than I ever expected to get.
I'm not a programmer. I did this with Claude, and ChatGPT and DeepSeek to double check things, over about a day and a night. Claude wrote the patches and read the logs, I tested every build on my own console. There were a lot of crashes, and a lot of forced power-offs and re-jailbreaks along the way.
Your v1.219.015 came out while I was working on this, and it already has a lot of the same things, which is great. I'm sharing all of it anyway, so you can check what we did and take anything that's useful. I used my own dumps and keys only.
## The result
On firmware 12.40, Ocarina of Time loads a save into Link's house, and you can walk him out the door onto the porch and into Kokiri Forest at about 15 to 20 fps. New Game plays through the movies. Then it runs out of memory, near 10.6 GB of the 12224 MiB pool, usually a couple of minutes in. There's a heavy white fog outside, and some geometry is missing.
The same builds also got Mario Kart World through all its menus to race select at 24 to 28 fps, before the same memory crash.
Video is attached below.
https://github.com/user-attachments/assets/747c286b-0be3-47fd-99a6-540238b1ba61
The Legend of Zelda: Ocarina of Time (Switch 2), display version 1.1.1, title ID `0400486024DEC000`, region Europe. My settings were Docked, Vulkan, 1x, Bilinear, 1080p, 60 Hz, async shaders off; fast GPU on and reactive flushing off per game.
## What looks new compared with v1.219.015
This is my reading of the comparison, not a claim that the two trees are otherwise identical. The following work is on `ocarina-next13`; **nothing that is only on next13 has been tested on my console yet.**
- DMA and puller work on the split back thread: `0045`, `0046`, `0053`.
- Large decoded images uploaded in slices: `0069`, corrected by `0088`.
- A refused allocation no longer immediately ends the app: `0089`, `0090`, `0095` to `0097`, `0130` to `0132`.
- Depth-compare descriptors stay float: `0081`, from Orchid `052478de5b`. This one is already proven on the old saved shader list that had aborted at boot: it loaded 853 pipelines with no SPIR-V failures.
- Empty heap arenas are returned and heap reports added.
- The memory layout work: a flexible 320 MiB area with 512 KiB fiber stacks, no `cpuPageTableSize` key, and framebuffers at output size.
- A design for paging cold guest memory to storage. It is off by default.
Going the other way, your `0041` and `0045` are now on next13, and `0046` and `0047` are not. Some queue, mesh, puller and upscale work is solved differently on each side. I would be very happy to be corrected on any of this.
## The journey
This went from a stop at boot, to movie 2, black 3D, GPU hangs, and eventually the forest. I logged more than 50 test runs and made 14 test builds on the fork. There were also many full console freezes at different points. Each one meant a forced power-off and a new jailbreak before I could continue.
Crash times count from app launch. “In game” is the session time when it was available, not necessarily the full app time.
| Run | Build | Stop | Largest free | What happened |
|---|---|---:|---:|---|
| 24 | first AV1, mesh on | 313 s | 5 MiB | Out of memory. A later launch reached real 3D at about 738 s, then lost the device. |
| 28, 29 | queue build | 283 s | | GPU-thread SIGSEGV at `0x10`. |
| 30 | queue build, split off | 663 s | 8 MiB | Out of memory. First time past the dialogue crash; 3D was black. |
| 31 | plus shader lowering | 173 s | 224 MiB | Continue, then out of memory. |
| 35 | ocarina-next | 420 s | 12 MiB | Out of memory with split back on. |
| 36 | ocarina-next2 | 418 s | 8 MiB | AV1 at 60 fps, movie 3 video, then stopped just before Link. |
| 37 | next2 | 506 s | 81 MiB | Pipeline-builder SIGSEGV at `0x40`; reached Link's scene. |
| 38 | ocarina-next6 | 93 s | 2 MiB | Continue stopped during load; title video was back. |
| 39 | ocarina-next6 | 248 s | 117 MiB | A 226 MiB array went through a 256 MiB staging buffer. |
| 40 | next6, transcode 0 | 663 s | 8 MiB | Link, hearts, and save icon, but no control. |
| 41, 42 | ocarina-next7 | 12, 10 s | | Pipeline-builder abort on a saved shader list. |
| 43 | ocarina-next7 | 703 s | 12 MiB | Moved Link for a few seconds. |
| 44 | ocarina-next8 | 665 s | 9 MiB | Link took one step. |
| 45 | ocarina-next8 | 561 s | 1 MiB | Mario Kart World past loading, Mario driving at about 20 fps. |
| 46 | ocarina-next8 | 314 s | 1 MiB | Continue reached Link's house, 11 to 21 fps. |
| 47 | ocarina-next9 | 88 s | 40 MiB | Old saved list booted, then GPU-decode memory failure. |
| 48 | next9, no transcode line | 120 s | 1 MiB | Continue reached the door, 12 to 17 fps. |
| 49 | ocarina-next10 | 131 s | 4 MiB | Continue reached the porch, heavy white fog, then a `RefreshContents` texture-upload failure. |
| 51 | ocarina-next11 | 139 s | 1 MiB | Porch again, fog workaround applied, outdoors still washed out. Refused 21 MB buffer. |
| 52 | ocarina-next12 | 173 s | 2 MiB | Mario Kart World: all menus to race select at 24 to 28 fps with compact memory. |
| 53 | ocarina-next12 | 123 s | 1 MiB | Zelda, little cutscene just outside, refused buffer in a query sync. |
The four long New Game runs stopped 624 to 662 seconds after the game session began. Continue reaches a similar memory state much sooner. I do not know why.
## Everything we made
The labels below come from comparing core patches with v1.219.015. “You also have this now” means the same change or an equivalent is there. “Only in my fork” means I did not find it. Frontend changes were not compared line by line, and exact implementations may differ.
### AV1 movies: `0047`, `0024`, frontend `50dc29c` and `1c3c9bf`
**You also have this now** (AV1 through dav1d). The fixed four-thread decoder setting may still be worth a look.
Adds dav1d and FFmpeg's libdav1d. `0047` gives the decoder four threads, because auto thread count left dav1d single-threaded on a pinned thread. `0024` supplies blank frames if no decoder opens. dav1d 1.5.1 is from VideoLAN through FFmpeg. The frontend rerun check is from heydemoura `73fc4ed8`. This is what got past movie 2: it needed real frames.
### Boot and command lists: `0025` to `0029`
**You also have this now.**
`0025` copies command lists behind queued GPU maps. `0026` reads all-zero lists at parse time for Switch 2 titles. `0028` makes the command queue unbounded. `0027` and `0029` are A/B switches and were not used. `0025` is Djihads80/Eglantine PR 543 by Sssnowyyy, rebased with a log line and overflow guard. `0026` extends your Bananza patch `0012`. `0028` follows the design in heydemoura's core patch `0004`.
### Ocarina shader lowering: `0030` to `0039`, `0057`, `0058`
**You also have this now.**
This covers ISETP.EX, F32 reductions, uniform IMAD `0x4a4`, CALL helpers, 64-bit shifts, guarded uniform compares, 2D-array and depth gathers, routed 32-bit global atomics, FP16 texture packing, re-uploading a native program's 64 KiB uniform bank, and F2I abs/neg on constant-buffer sources. It came from Djihads80/Eglantine `scratch/oot-shader-lab`.
`0030` to `0033` are by kraibse, ported from zortos293/Lichii `fix/oot-bloom`; `0034` to `0036` are by kraibse; `0037` by zortos293; `0038` by Franseven from Quixomatic/Eglantine; `0039` by Franseven from monkeefunnee/Eglantine, ported by kraibse. `0057` is from Lichii `fix/oot-fog`. `0058` is a warning I added.
### Upscale stand-in, title, and scene picture: `0040`, `0044`, `0048`
**You also have this now.**
When the tensor upscale network is rejected, the stand-in takes images from the handles used by the native program. `0040` is by kraibse and was hand-merged to keep Bananza's slots. `0044` and `0048` are fork work; `0048` brought the title video back in run 38. The comparison says the upstream native-HMMA route is a different solution, so I would keep this as a discussion point rather than assume equivalence.
### GPU split races: `0041`, `0045`, `0046`, `0053`
**Partly yours too.** Your `0049` and `0050` cover fences and flushes in a different way; the DMA read and macro paths may still be only in my fork.
This moves fence release, semaphore flushes, sync fences, GPU-written-list flushes, and macro DMA reads to the split back thread. The front side had touched scheduler state owned by the back after a drain and hit a null chunk. This is fork work. The GPU-thread `0x10` fault from runs 28 and 29 did not return after it.
### Memory diagnostics and earlier memory work: `0054`, `0060`, `0061`, `0062`, frontend `ca23d4b`, collector `d0258b2`, Mesa pin
**Only in my fork.**
`0054` decodes large ASTC on the CPU, though it was switched off in runs 40 to 47. `0060` and the frontend report cache ownership on memory refusal and retry once. `0061` quarters descriptor queues. `0062` sizes kernel reference tables by region. The frontend wires fiber stacks and Fine slots for Ocarina. The collector skips dirty passes that free nothing.
`0061` and `0062` are by exploitizm; `0062` was adapted from the original PS5 patch `0014`. The Mesa driver is Mihawk's `mihawk-99/PS5_Mesa` `f5610fe27`, with the pin and build script from viejunerd `d5b0279`, from next8 onward. The refusal report was useful, but these changes did not move the final stop.
### Haze test and SPIR-V failure report: `0059`, frontend `5385d26`
**Only in my fork.**
`0059`, from next7, re-records alpha-to-coverage when the pipeline changes, from zortos293/Lichii `fix/oot-fog`. The RADV change prints SPIR-V parser failures and stops with a message rather than faulting at `0x40`; that exposed the exact message from runs 41 and 42. `0059` did not visibly change the haze.
### Mesh, task, and native HMMA work: `0042`, `0050`, `0051`, `0052`, `0055`, RADV `39a6b4d`, and `0043`
**Only in my fork.**
`0051` is from heydemoura's core patch `0004`; the other mesh/task changes are fork work. `0043` is a backport of heydemoura's patch `0013`, active only with `EDEN_NX2_TENSOR`, which I never set. None of the mesh-targeted changes has been tested with mesh enabled. Mesh has been off in every run since run33.
### Next9 and next10 additions: `0069`, `0078` to `0090`, and frontend changes
**Only in my fork.**
`0069` slices large decoded-image uploads; `0088` fixes its stream-ring wrap and zero fill. `0089` lets a download without staging wait for the GPU instead of ending the session, but run49 failed on an upload, so it never reached that path. `0090` keeps the decoder alive after a refusal.
`0086` decodes ASTC one layer at a time, taking scratch for the 1365x1365x90 array from 640 MiB to 7.1 MiB. It is Portablelle/EdGlantine-PS5 PR 25. `0078` counts actual host-image use, from v1.219.011 and MythosOfs/Orchid plus godpow. `0079` backs sparse images whole where tiles or layers cannot be set up, from Orchid.
`0082` downloads only Preflushable GPU-written pages at fences, from Lichii PR 104 by Zarigis. `0083` uploads CPU writes onto GPU-written pages instead of downloading and waiting, from Lichii PR 103 by Zarigis. The reported RX 7800 XT result for those together was by FabianZettl and is PC data, not PS5 data. `0085` adds optional Switch 2 nanosecond timestamps after zortos293/Lichii 84 and 114. `0081` is the Orchid depth-compare fix mentioned above. `0084` shadows the data register of STG.U and ISBEWR, from Lichii PR 100 by Zarigis and PR 65 by Zortos. `0087` fixes invalid depth-stencil copies in ReinterpretImage, from Lichii 89 by cr1ckt.
The remaining v1.219.011 work was `0070` to `0077`, `0080`, and frontend `da09610` and `e5a3137`, from viejunerd and Heyde Moura, with sources in Orchid, godpow, andrewleeog, and kraibse. I kept my `0028` and `0043` instead of the queue and HMMA versions in your series; if yours are the right replacements, I will drop mine.
## Findings so far
### Memory
At the run49 refusal, the 12224 MiB pool had 126 MiB free in 190 blocks, but the largest block was 4 MiB. The texture upload asked for 13,039,296 bytes; a 14 MiB retry also could not fit. That looks like fragmentation as well as exhaustion, but I cannot say what causes it.
The reported values were guest 5809 MiB, allocator 3192 MiB with 2961 MiB in use, heap 1807 MiB, and images 2375 MiB in 1238 images. The collector counted 6119 MiB against 3584/4096 MiB marks. The guest reserve held all 256 MiB and lent none. Kernel maps were reported as 9678 MiB. I cannot reconcile these counters: older reports leave roughly 1290 to 1589 MiB unnamed, and the collector/image gap is also unresolved.
The memory-layout changes now prepared for next13 are based on the same refusal logs, not console proof. The 320 MiB flexible area plus 512 KiB fiber stacks is intended to keep all 128 to 255 fiber stacks there rather than spilling into the heap. Removing `kernel.cpuPageTableSize` is expected to return about 64 MiB to the title pool. Output-size framebuffers are expected to save about 110 MiB at 1080p. These are mechanisms and arithmetic checked in the notes, not tested results on this console.
### Empty arenas and collector
Empty heap arenas are now returned and reported in next13. Earlier, the collector was far over its critical mark while images accounted for much less. Once 3D began, the logs also showed heavy image churn. That could contribute to stutter and fragmentation, but it is not proven.
### Guest-memory paging
The cold-guest-memory paging design is off by default and untested on console. It first has a measure mode: it protects 2 MiB Own slots, observes which ones fault back in, and estimates cold memory without moving it. The eventual eviction mode writes cold slots to storage only when the pool is short. It has a self-test and a guard for frequent read-backs.
It may buy time, not solve the graphics-memory problem. The estimate of 1 to 1.5 GiB of cold memory is only a guess. The storage path, `mprotect` behavior on the direct mapping, and file I/O in this setting all need console testing. The design also adds an IPC-copy patch because a raw guest pointer sent to a system call can return `EFAULT` rather than fault in normally.
### Haze and mesh hangs
The white haze is strongest outside and at doors. `0059` and the new Mesa driver did not visibly change it. Door areas still wash out. There are also black bars and noise in movie 3, plus audio drops around camera cuts. I do not have a solid lead on those.
With mesh draws on, the GPU hangs and the console can freeze. That is why this remains in `env.txt`:
```text
EDEN_NX2_NO_MESH=1
EDEN_NX2_TC_EXPECTED_MIB=3584
EDEN_NX2_TC_CRITICAL_MIB=4096
```
`EDEN_NX2_NO_MESH=1` skips task and mesh draws, so geometry is missing. It is a safety setting, not a fix. Mesh-on runs lost the GPU repeatedly, and across this work the whole console froze many times, at different points, each time needing a forced power-off and a new jailbreak. The connection is likely but not proven. No mesh-off run lost the device. I have no evidence that the mesh-targeted patches fix it because they have not been run with mesh on.
For extra texture-cache lines only, I used this during later tests:
```text
EDEN_NX2_TC_LOG=1
```
It logs totals every 600 frames. The packaged `env.txt` need not include it. I would not set `RADV_DEBUG`: one run stalled at 268 of 482 pipelines and flooded the log.
## How to look at it
The current branch is here:
<https://github.com/Vampinity/Eglantine-PS5-/tree/ocarina-next13>
I would be glad to make small PRs in whatever form suits you. A possible split is AV1 movies, split-back DMA/puller work, command lists, picture/stand-in work, memory diagnostics, then the larger experimental memory changes separately. I do not expect a big patch pile to be useful as one PR.
The things I would most value your view on are the memory accounting and collector gap, a safe path to test mesh draws, whether the split-back work overlaps what you already have, and which small pieces are worth cleaning up first.
## Thanks and credits
Thank you, viejunerd, for the PS5 work and the release base that made this possible. Thanks as well to Djihads80 and the Eglantine contributors; heydemoura; Mihawk; zortos293 and the Lichii contributors; MythosOfs and the Orchid contributors; godpow; kraibse; Portablelle; Sssnowyyy; exploitizm; Zarigis; cr1ckt; Franseven; Quixomatic; monkeefunnee; FabianZettl; BlackBearReloaded; drakmor; andrewleeog; the Eden and yuzu projects; and everyone else named in the patch history above.
If any of this is useful, tell me which parts and I'll get them cleaned up and split out for you.