fix(vulkan): track writes from direct buffer bindings #1133

Merged
monsterlag merged 6 commits from fix/direct-buffer-write-bookkeeping into main 2026-11-10 20:59:32 +00:00
monsterlag commented 2026-11-09 13:47:58 +00:00 (Migrated from github.com)

With buffer mirrors disabled or unavailable, CPU readback can miss GPU-written values because an early direct binding does not record the write's pages or epoch. Record that bookkeeping on both direct returns in gpu_buffer_bind, addressing the source gap reported in #1126. Credit to @drpowerup for the original observation.

note_direct_write marks the current mirror epoch and records the translated, pool-clamped guest range for writes up to 1 MiB. Read-only bindings, mirrored writebacks, the current WB_MAX policy and upstream shadow_forget behavior remain intact. This does not include the separate #1150 import policy.

This refresh normally merges main at 117eae79, including #1858's presentation link repair and #1793's shared source-check repairs, without rewriting history. The runner, API header and workflow are unchanged from that base; the test declares its own RUN_ALL_ARGS. The fixture extracts the actual production shadow_forget and checks precisely which pool-relative shadow pages are invalidated. Every original case and assertion is preserved. All 15 extracted production inputs, both complete fixture files and the runner are byte-identical to the previously tested 7ca77cb head; upstream's imported-buffer destruction changes are outside those inputs.

Validation on this refresh:

  • Identical final fixture against unmodified current-main production code: seven intended behavioral failures and five passing controls, on Windows and Linux.
  • Fixed actual-function fixture: all 12 cases pass on Windows LLVM and Linux GCC. Strict selected runner passes without failures or skips on both platforms.
  • Removing only the upstream shadow-invalidation call causes seven intended bitmap failures while five controls pass, showing that the new assertions protect that behavior too.
  • Binding memo and null/unbound/empty/bound SSBO range checks pass on both platforms; the five upstream CPU-shadow policy checks pass on Windows.
  • The three-file topic diff passes the whitespace check. Whitespace already present in upstream test/vendor files was preserved.

Historical hardware reports remain attributed to their authors and earlier code: @DarkGhostHunter reported no more blinking wrong textures on an RDNA3 iGPU. @djanice1980 reported steady Castle-gate ground on Radeon 8060S/RADV, with about 9 ms/frame of readback-wait cost; that test applied page notes without the epoch line.

All eight hosted checks now pass on current head 2babca1a: Windows/Linux source suites, Windows Builder packaging, Windows Vulkan, Linux AppImage, both native lowering checks and workflow lint. Release-upload checks are correctly skipped for a pull request. The normal merges incorporate #1858's presentation definitions and #1793's shared source-check repairs.

Gaps: no full local suite, current-head GPU/game or timeline test, or new iGPU measurement. The fixture executes actual binding/page-table/shadow functions with authored pool, mirror, host and hazard boundaries; it does not allocate a real Vulkan device or access a game dump. Hardware reports above remain historical and attributed to the original testers.

With buffer mirrors disabled or unavailable, CPU readback can miss GPU-written values because an early direct binding does not record the write's pages or epoch. Record that bookkeeping on both direct returns in `gpu_buffer_bind`, addressing the source gap reported in #1126. Credit to @drpowerup for the original observation. `note_direct_write` marks the current mirror epoch and records the translated, pool-clamped guest range for writes up to 1 MiB. Read-only bindings, mirrored writebacks, the current `WB_MAX` policy and upstream `shadow_forget` behavior remain intact. This does not include the separate #1150 import policy. This refresh normally merges `main` at `117eae79`, including #1858's presentation link repair and #1793's shared source-check repairs, without rewriting history. The runner, API header and workflow are unchanged from that base; the test declares its own `RUN_ALL_ARGS`. The fixture extracts the actual production `shadow_forget` and checks precisely which pool-relative shadow pages are invalidated. Every original case and assertion is preserved. All 15 extracted production inputs, both complete fixture files and the runner are byte-identical to the previously tested `7ca77cb` head; upstream's imported-buffer destruction changes are outside those inputs. Validation on this refresh: - Identical final fixture against unmodified current-main production code: seven intended behavioral failures and five passing controls, on Windows and Linux. - Fixed actual-function fixture: all 12 cases pass on Windows LLVM and Linux GCC. Strict selected runner passes without failures or skips on both platforms. - Removing only the upstream shadow-invalidation call causes seven intended bitmap failures while five controls pass, showing that the new assertions protect that behavior too. - Binding memo and null/unbound/empty/bound SSBO range checks pass on both platforms; the five upstream CPU-shadow policy checks pass on Windows. - The three-file topic diff passes the whitespace check. Whitespace already present in upstream test/vendor files was preserved. Historical hardware reports remain attributed to their authors and earlier code: [@DarkGhostHunter reported no more blinking wrong textures on an RDNA3 iGPU](https://git.magicbean.dev/MagicBeanDev/Hookshot/pulls/1133). [@djanice1980 reported steady Castle-gate ground on Radeon 8060S/RADV, with about 9 ms/frame of readback-wait cost](https://git.magicbean.dev/MagicBeanDev/Hookshot/pulls/1133); that test applied page notes without the epoch line. All eight hosted checks now pass on current head `2babca1a`: Windows/Linux source suites, Windows Builder packaging, Windows Vulkan, Linux AppImage, both native lowering checks and workflow lint. Release-upload checks are correctly skipped for a pull request. The normal merges incorporate #1858's presentation definitions and #1793's shared source-check repairs. Gaps: no full local suite, current-head GPU/game or timeline test, or new iGPU measurement. The fixture executes actual binding/page-table/shadow functions with authored pool, mirror, host and hazard boundaries; it does not allocate a real Vulkan device or access a game dump. Hardware reports above remain historical and attributed to the original testers.
hckrman101 (Migrated from github.com) reviewed 2026-11-09 18:52:31 +00:00
hckrman101 (Migrated from github.com) left a comment

The fix itself looks right to me. The early return in gpu_buffer_bind() (mirrors off, outside a recording, refused pool) binds the pool's own import, so the GPU writes guest memory directly, the same as the mstate != MIRROR_ON path further down. That path already sets direct_write_epoch and notes the pages, and this one didn't. Same 1 MiB cap, same clamp to the pool end, and mem_rec_value is the recording the write belongs to, so the readback wait in vk_replay.cpp waits for the right submission. wb_pages_note already drops value == 0 and RX_VK_NO_READBACK_WAIT. Read bindings (memo/TLS shortcuts) aren't touched. Direct writes never go through a write-back, so the write-back diff and the cpu_words cut don't apply here. Setting direct_write_epoch on this path can only stop a mirror being made later in the same part, which is the intended rule.

CI: both "Python source checks" jobs fail only on tests/test_program_answer_domains.py, the same failure as on main. test_direct_buffer_writes.py passes on Linux and Windows.

One blocker, though: that pass was on the merge with 8b2e1d3. Main is ~160 commits ahead and the test won't compile against it:

  • the slice from std::mutex wb_pages_mu; to void wb_pages_note( now pulls in struct WbPages (chunked table, #1161 and the bookkeeping series), which needs kPages, kChunkPages and std::unique_ptr. The test only defines kPageShift.
  • main's gpu_buffer_bind now calls rb_hazard_locked() in the mirrored write path (#1069), and the test has no stub for it.

Since it's registered in run_all.py, it'll go red as soon as CI runs on current main. Please rebase and update the stubs/extraction (tests/test_wb_pages.py on main already extracts the new table, which could help). The Common::FastHash shim can go too.

Non-blocking:

  • On mirror-off setups (iGPUs by default, i.e. the #1126 hardware, or RX_VK_MIRROR=0), every small written binding now takes wb_pages_mu and sets up to 257 pages, per binding per draw. On main's chunked table that's cheap, but a CPU readback that touches those pages will now actually wait (that's the point). A quick frame-time A/B on an iGPU would be good to have before this ships.
  • Overlap: #1150 adds another early return in this function (rb_direct_hit) that binds guest memory without this bookkeeping. If written bindings can reach it, it has the same gap. With three copies of these two lines, a small note_direct_write(p, off, size) helper would keep them in sync. #1184 also edits this function, so expect a trivial conflict.
The fix itself looks right to me. The early return in `gpu_buffer_bind()` (mirrors off, outside a recording, refused pool) binds the pool's own import, so the GPU writes guest memory directly, the same as the `mstate != MIRROR_ON` path further down. That path already sets `direct_write_epoch` and notes the pages, and this one didn't. Same 1 MiB cap, same clamp to the pool end, and `mem_rec_value` is the recording the write belongs to, so the readback wait in vk_replay.cpp waits for the right submission. `wb_pages_note` already drops `value == 0` and `RX_VK_NO_READBACK_WAIT`. Read bindings (memo/TLS shortcuts) aren't touched. Direct writes never go through a write-back, so the write-back diff and the `cpu_words` cut don't apply here. Setting `direct_write_epoch` on this path can only stop a mirror being made later in the same part, which is the intended rule. CI: both "Python source checks" jobs fail only on `tests/test_program_answer_domains.py`, the same failure as on main. `test_direct_buffer_writes.py` passes on Linux and Windows. One blocker, though: that pass was on the merge with `8b2e1d3`. Main is ~160 commits ahead and the test won't compile against it: - the slice from `std::mutex wb_pages_mu;` to `void wb_pages_note(` now pulls in `struct WbPages` (chunked table, #1161 and the bookkeeping series), which needs `kPages`, `kChunkPages` and `std::unique_ptr`. The test only defines `kPageShift`. - main's `gpu_buffer_bind` now calls `rb_hazard_locked()` in the mirrored write path (#1069), and the test has no stub for it. Since it's registered in run_all.py, it'll go red as soon as CI runs on current main. Please rebase and update the stubs/extraction (tests/test_wb_pages.py on main already extracts the new table, which could help). The `Common::FastHash` shim can go too. Non-blocking: - On mirror-off setups (iGPUs by default, i.e. the #1126 hardware, or `RX_VK_MIRROR=0`), every small written binding now takes `wb_pages_mu` and sets up to 257 pages, per binding per draw. On main's chunked table that's cheap, but a CPU readback that touches those pages will now actually wait (that's the point). A quick frame-time A/B on an iGPU would be good to have before this ships. - Overlap: #1150 adds another early return in this function (`rb_direct_hit`) that binds guest memory without this bookkeeping. If written bindings can reach it, it has the same gap. With three copies of these two lines, a small `note_direct_write(p, off, size)` helper would keep them in sync. #1184 also edits this function, so expect a trivial conflict.
hckrman101 (Migrated from github.com) commented 2026-11-09 18:52:32 +00:00

These two lines are now in two places (and #1150 adds a third early return). A tiny helper used by both paths would keep them from drifting apart.

These two lines are now in two places (and #1150 adds a third early return). A tiny helper used by both paths would keep them from drifting apart.
@ -0,0 +48,4 @@
dimensions.append("constexpr uint64_t %s = %s;" % (name, value[1]))
types = "\n".join(dimensions) + "\n\n" + "\n\n".join([block(header, "struct BufferRef {", True), block(source, "struct Pool {", True),
block(source, "struct TlPool {", True), block(source, "struct WriteBack {", True)])
pages = source[source.index("std::mutex wb_pages_mu;"):source.index("void wb_pages_note(")]
hckrman101 (Migrated from github.com) commented 2026-11-09 18:52:32 +00:00

Against current main this slice includes struct WbPages, which needs kPages/kChunkPages/<memory>, and the extracted gpu_buffer_bind calls rb_hazard_locked(), so the test stops compiling after a rebase. It passed in CI only because the merge base was 8b2e1d3.

Against current main this slice includes `struct WbPages`, which needs `kPages`/`kChunkPages`/`<memory>`, and the extracted `gpu_buffer_bind` calls `rb_hazard_locked()`, so the test stops compiling after a rebase. It passed in CI only because the merge base was `8b2e1d3`.
hckrman101 (Migrated from github.com) approved these changes 2026-11-09 23:07:49 +00:00
hckrman101 (Migrated from github.com) left a comment

The blocker is fixed. The test now reads kPageShift, kChunkPages and kPages from the production source, so the chunked WbPages slice compiles. It also stubs rb_hazard_locked() and checks that the mirror_on case calls it once with the right range. The code change is the same 3 lines in gpu_buffer_bind as before, and it still looks right.

Two small things, not blocking: the two copies of the direct-write lines could share a note_direct_write helper, and a frame-time check on a mirror-off iGPU would still be nice to have. CI is green.

The blocker is fixed. The test now reads kPageShift, kChunkPages and kPages from the production source, so the chunked WbPages slice compiles. It also stubs `rb_hazard_locked()` and checks that the mirror_on case calls it once with the right range. The code change is the same 3 lines in `gpu_buffer_bind` as before, and it still looks right. Two small things, not blocking: the two copies of the direct-write lines could share a `note_direct_write` helper, and a frame-time check on a mirror-off iGPU would still be nice to have. CI is green.
DarkGhostHunter commented 2026-11-10 04:58:03 +00:00 (Migrated from github.com)

Can confirm it works on iGPU (RDNA3): no more blinking wrong textures. Had a very hard stop on entering the market but probably shaders, after a few seconds it run again like normal. Performance is acceptable, it seems there is a lot of work to do there.

Can confirm it works on iGPU (RDNA3): no more blinking wrong textures. Had a very hard stop on entering the market but probably shaders, after a few seconds it run again like normal. Performance is _acceptable_, it seems there is a lot of work to do there.
djanice1980 commented 2026-11-10 05:00:22 +00:00 (Migrated from github.com)

Hardware test on an integrated GPU with the mirror off, as asked above. Radeon 8060S (RADV STRIX_HALO, Mesa driver 0x6802006), CachyOS, kernel 7.3.3. Built from main 5609af4 plus the same wb_pages_note lines in the no-mirror return of gpu_buffer_bind (without the direct_write_epoch line).

Before: shaded ground at the Hyrule Castle gate flipped between two colors several times a second (stone floor mean sRGB 68/61/50 vs 62/76/92 in two screenshots; sunlit areas, sky and HUD within 3%). No "readbacks of GPU results" line in the log. After: steady.

Frame-time A/B, same save, standing still, about 1335 draws a frame, frame generation and frame pacing off, one build with switches:

with the change RX_VK_MIRROR=1 RX_VK_NO_READBACK_WAIT=1
picture steady steady heavy flicker
fps ~35 (32-37) ~40 (38-44) ~52 (51-53)
slowest frame per 600 37-45 ms 33-35 ms 26-30 ms
readbacks that waited, of 3000 660-935 1340-1490 none
each wait 2.7-4.7 ms 0.7-1.4 ms -
VRAM in use 4.2 GB 5.8 GB 4.2 GB

So the change fixes the flicker and costs about 9 ms a frame here; the mirror costs about 6 ms. For comparison, an RTX 5070 Ti with RX_VK_MIRROR=0 also stopped flickering with the change, with waits of 0.24 ms each (0.13 ms with the mirror on). I can rerun anything that would help.

Hardware test on an integrated GPU with the mirror off, as asked above. Radeon 8060S (RADV STRIX_HALO, Mesa driver 0x6802006), CachyOS, kernel 7.3.3. Built from main 5609af4 plus the same `wb_pages_note` lines in the no-mirror return of `gpu_buffer_bind` (without the `direct_write_epoch` line). Before: shaded ground at the Hyrule Castle gate flipped between two colors several times a second (stone floor mean sRGB 68/61/50 vs 62/76/92 in two screenshots; sunlit areas, sky and HUD within 3%). No "readbacks of GPU results" line in the log. After: steady. Frame-time A/B, same save, standing still, about 1335 draws a frame, frame generation and frame pacing off, one build with switches: | | with the change | RX_VK_MIRROR=1 | RX_VK_NO_READBACK_WAIT=1 | |---|---|---|---| | picture | steady | steady | heavy flicker | | fps | ~35 (32-37) | ~40 (38-44) | ~52 (51-53) | | slowest frame per 600 | 37-45 ms | 33-35 ms | 26-30 ms | | readbacks that waited, of 3000 | 660-935 | 1340-1490 | none | | each wait | 2.7-4.7 ms | 0.7-1.4 ms | - | | VRAM in use | 4.2 GB | 5.8 GB | 4.2 GB | So the change fixes the flicker and costs about 9 ms a frame here; the mirror costs about 6 ms. For comparison, an RTX 5070 Ti with RX_VK_MIRROR=0 also stopped flickering with the change, with waits of 0.24 ms each (0.13 ms with the mirror on). I can rerun anything that would help.
hckrman101 (Migrated from github.com) approved these changes 2026-11-10 16:19:55 +00:00
hckrman101 (Migrated from github.com) left a comment

Still looks right after the refresh. note_direct_write() is a straight extraction of the old lines (epoch, 1 MiB cap, clamp to the pool end, mem_rec_value), both direct returns in gpu_buffer_bind use it under pools_mu, and the new async-import branch and TLS shortcut on main only take read bindings, so no written binding skips the bookkeeping. The fixture asserting no async copy is a nice touch. CI is green.

The iGPU numbers from djanice1980 are useful: ~9 ms/frame of readback waits with the mirror off vs ~6 ms with it on is a real cost, but steady ground beats flicker, and it's worth a follow-up on the wait side rather than holding this back. On mirror-off setups the epoch line is a no-op anyway (mirror_on() is false), so that test covers what ships there.

One thing before merging: main has moved again and this now conflicts. The only conflict I can see is tests/run_all.py, where your ARGS entry and main's new test_dlss_sdk_cache / test_builder_dlss_update / test_png_publication entries all land right after ARGS = {. Keep both. vk_memory.cpp merges cleanly and main's changes there (submitted pages, the commit walk) are outside the slices the test extracts, so the fixture should still build. Could you merge main once more?

Still looks right after the refresh. `note_direct_write()` is a straight extraction of the old lines (epoch, 1 MiB cap, clamp to the pool end, `mem_rec_value`), both direct returns in `gpu_buffer_bind` use it under `pools_mu`, and the new async-import branch and TLS shortcut on main only take read bindings, so no written binding skips the bookkeeping. The fixture asserting no async copy is a nice touch. CI is green. The iGPU numbers from djanice1980 are useful: ~9 ms/frame of readback waits with the mirror off vs ~6 ms with it on is a real cost, but steady ground beats flicker, and it's worth a follow-up on the wait side rather than holding this back. On mirror-off setups the epoch line is a no-op anyway (`mirror_on()` is false), so that test covers what ships there. One thing before merging: main has moved again and this now conflicts. The only conflict I can see is `tests/run_all.py`, where your `ARGS` entry and main's new `test_dlss_sdk_cache` / `test_builder_dlss_update` / `test_png_publication` entries all land right after `ARGS = {`. Keep both. `vk_memory.cpp` merges cleanly and main's changes there (submitted pages, the commit walk) are outside the slices the test extracts, so the fixture should still build. Could you merge main once more?
hckrman101 (Migrated from github.com) reviewed 2026-11-10 16:20:00 +00:00
hckrman101 (Migrated from github.com) commented 2026-11-10 16:20:00 +00:00

Done with note_direct_write(), thanks.

Done with note_direct_write(), thanks.
hclaria commented 2026-11-10 16:23:40 +00:00 (Migrated from github.com)

Hardware test on a Steam Deck OLED (AMD Custom APU 0932, RADV VANGOGH, SteamOS, kernel 7.2.7-valve2), mirrors off as on every integrated GPU.

Not this branch itself: I tested the equivalent change on main d8f0513 (plus #1625 and #1574), a wb_pages_note for written bindings of 1 MB or less in the no-mirror early return of gpu_buffer_bind, without the direct_write_epoch line.

Before: in Kokiri Forest the whole picture flickered several times a second, all at once: foliage going from dark green to brightly lit and back. It looks like the exposure stepping, not textures going missing. The log had VRAM mirror of buffer pools off and never printed a readbacks of GPU results line, over tens of thousands of frames.

What pointed at the wait:

  • RX_VK_MIRROR=1 removed the flicker, with RX_VK_MIRROR_MB=1024 and with 256.
  • RX_VK_MIRROR=1 with RX_VK_NO_READBACK_WAIT=1 brought it back. So it is the readback wait that fixes it, and the mirrors only mattered because their write-backs fed wb_pages.
  • RX_VK_WAIT_GPU=1 alone did not help.

After, mirrors off: no flicker in several runs of a few minutes each. The log now shows readbacks of GPU results: ~930 of 3000 waited for their write-back, 1.4-1.8 ms each.

Cost here: about 30-31 fps (flickering) to about 26.5 fps at ~2,000 draws. The GPU takes ~17 ms a frame on this APU, so each wait is long. With RX_VK_LOG_READBACK_WAITS=1, two alternating ranges of 0x3980 bytes account for nearly all of it, about 5 ms a wait (up to 14 ms), on ModuleSystemWorker threads. The other ranges wait under 0.6 ms. Compared with getting the same fix through RX_VK_MIRROR=1, this is 1-2 fps faster and leaves about 1 GB more memory free.

Hardware test on a Steam Deck OLED (AMD Custom APU 0932, RADV VANGOGH, SteamOS, kernel 7.2.7-valve2), mirrors off as on every integrated GPU. Not this branch itself: I tested the equivalent change on `main` d8f0513 (plus #1625 and #1574), a `wb_pages_note` for written bindings of 1 MB or less in the no-mirror early return of `gpu_buffer_bind`, without the `direct_write_epoch` line. **Before:** in Kokiri Forest the whole picture flickered several times a second, all at once: foliage going from dark green to brightly lit and back. It looks like the exposure stepping, not textures going missing. The log had `VRAM mirror of buffer pools off` and never printed a `readbacks of GPU results` line, over tens of thousands of frames. **What pointed at the wait:** - `RX_VK_MIRROR=1` removed the flicker, with `RX_VK_MIRROR_MB=1024` and with `256`. - `RX_VK_MIRROR=1` with `RX_VK_NO_READBACK_WAIT=1` brought it back. So it is the readback wait that fixes it, and the mirrors only mattered because their write-backs fed `wb_pages`. - `RX_VK_WAIT_GPU=1` alone did not help. **After, mirrors off:** no flicker in several runs of a few minutes each. The log now shows `readbacks of GPU results: ~930 of 3000 waited for their write-back, 1.4-1.8 ms each`. **Cost here:** about 30-31 fps (flickering) to about 26.5 fps at ~2,000 draws. The GPU takes ~17 ms a frame on this APU, so each wait is long. With `RX_VK_LOG_READBACK_WAITS=1`, two alternating ranges of `0x3980` bytes account for nearly all of it, about 5 ms a wait (up to 14 ms), on `ModuleSystemWorker` threads. The other ranges wait under 0.6 ms. Compared with getting the same fix through `RX_VK_MIRROR=1`, this is 1-2 fps faster and leaves about 1 GB more memory free.
hckrman101 commented 2026-11-10 17:49:03 +00:00 (Migrated from github.com)

Heads-up: this conflicts with main now (a lot landed today). Could you merge main into the branch (or rebase) and resolve the conflicts? Thanks!

Heads-up: this conflicts with main now (a lot landed today). Could you merge main into the branch (or rebase) and resolve the conflicts? Thanks!
hckrman101 (Migrated from github.com) approved these changes 2026-11-10 20:52:49 +00:00
hckrman101 (Migrated from github.com) left a comment

Thanks for merging main. The conflict is gone and GitHub reports the branch as clean. The gpu_buffer_bind change is the same as the version I approved: note_direct_write() is used on both direct returns, only for written bindings, with the 1 MiB cap and the pool-end clamp. The only changes since are merges of main, and CI is green on this head (Linux and Windows source checks, Windows Vulkan, AppImage, Builder).

The two non-blocking points still stand: a frame-time check on a mirror-off iGPU (djanice1980's and hclaria's numbers help here), and the readback-wait cost as a follow-up. Neither should hold this back.

Thanks for merging main. The conflict is gone and GitHub reports the branch as clean. The `gpu_buffer_bind` change is the same as the version I approved: `note_direct_write()` is used on both direct returns, only for written bindings, with the 1 MiB cap and the pool-end clamp. The only changes since are merges of main, and CI is green on this head (Linux and Windows source checks, Windows Vulkan, AppImage, Builder). The two non-blocking points still stand: a frame-time check on a mirror-off iGPU (djanice1980's and hclaria's numbers help here), and the readback-wait cost as a follow-up. Neither should hold this back.
Hashyirama commented 2026-11-11 02:38:11 +00:00 (Migrated from github.com)

Tested on a Lenovo Legion Go (Ryzen Z1 Extreme, Radeon 780M iGPU), Windows. On v2.0.14 (which doesn't include this PR) I get constant white flashes in Kokiri Forest, and RX_VK_MIRROR=1 removes them completely, which points at the non-mirror path this PR fixes. I'll test 2.1.0-rc without the env switch and report back.

Tested on a Lenovo Legion Go (Ryzen Z1 Extreme, Radeon 780M iGPU), Windows. On v2.0.14 (which doesn't include this PR) I get constant white flashes in Kokiri Forest, and RX_VK_MIRROR=1 removes them completely, which points at the non-mirror path this PR fixes. I'll test 2.1.0-rc without the env switch and report back.
DarkGhostHunter commented 2026-11-11 03:49:07 +00:00 (Migrated from github.com)

Tested on a Lenovo Legion Go (Ryzen Z1 Extreme, Radeon 780M iGPU), Windows. On v2.0.14 (which doesn't include this PR) I get constant white flashes in Kokiri Forest, and RX_VK_MIRROR=1 removes them completely, which points at the non-mirror path this PR fixes. I'll test 2.1.0-rc without the env switch and report back.

I tested 2.1.0-RC2 and I can confirm there are no white flashes, at least on Linux.

> Tested on a Lenovo Legion Go (Ryzen Z1 Extreme, Radeon 780M iGPU), Windows. On v2.0.14 (which doesn't include this PR) I get constant white flashes in Kokiri Forest, and RX_VK_MIRROR=1 removes them completely, which points at the non-mirror path this PR fixes. I'll test 2.1.0-rc without the env switch and report back. I tested 2.1.0-RC2 and I can confirm there are no white flashes, at least on Linux.
Commenting is not possible because the repository is archived.
No description provided.