Repository navigation
Conversation
An ASTC texture kept as BC3 was decoded, (on AMD) resized and encoded on the GPU in one upload command buffer. Hyrule
Field's two terrain material arrays (1365 x 1365 x 90, 11 levels, BC3 at 1536 x 1536 x 8 levels on AMD) are evicted
in Castle Town and made again when Link comes back: ~570 M texels of decode, blit and encode in one submission. On an
RX 7700S (8 GB, Adrenalin 26.10.1, Windows 11) that ran past Windows' 2-second limit three times out of three: the
driver was reset ("AMD Software detected a driver timeout") and the device lost, with VRAM not full.
upload_astc_gpu now records runs of layers (each with all its levels) while the recording's share lasts,
RX_VK_BC_PART_MTEXELS (16 M texels; 0: all at once, as before), at least one run per call; the layers left wait in
bc_pending and texture_bc_continue() records more at the start of each next recording. While some wait, a submission
is split every 16 draws instead of 120, so they are in within a frame or two. Until then the texture shows what its
image held for those layers, during the scene change. The run arithmetic is in gpu/vk/bc_parts.h.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Assisted-by: Claude Opus 5.5
|
Tested on NVIDIA (RTX 3070 8 GB, Windows 11), merged onto v2.0.8-rc.5, with a scripted run: load the Hyrule Castle autosave, turn the camera.
|
…rter load hitch) Nitnek's RTX 3070 test of this PR: the Hyrule Castle load hitch went from ~0.9 s to ~2.1 s with the per-recording budget, and NVIDIA had no reset to avoid. The budget now defaults to 16 M texels on AMD (vendor 0x1002) and 0 (all at once, as before) elsewhere; RX_VK_BC_PART_MTEXELS still overrides it on any GPU. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015DmSMGJSY9hHswALy4eqtQ
|
Thanks @Nitnek, that's exactly the data this needed. Pushed b7f5525: the per-recording budget now defaults to AMD only ( (AI-assisted via Claude Code on my behalf.) |
…ssion-rebase # Conflicts: # tests/run_all.py
|
Merged |
|
Test result from an AMD card, since this PR defaults to AMD only and the one test above was on NVIDIA (where it is off): on an RX 7800 XT the default of 16 M texels a recording showed large blocks of wrong colour in the sky, and they went away with Setup: RX 7800 XT 16 GB, Ryzen 7 5800X3D, Windows 11, driver 0x8001a0 as Vulkan reports it, v2.0.11 with this PR merged by hand on top (see the caveat), 2560x1440, frame generation x2, normal play. The log line for the split path appears ( What I saw, about 11 minutes after start, standing in Castle Town below the ruined castle: big square blocks, black, purple, yellow and red, over the sky (and over the top-left corner behind the HUD), with a stepped outline like wrong BC blocks. Two screenshots 0.7 s apart were identical (the fairy and the flames moved, the blocks did not), so it is a texture that stayed wrong, not an interpolated frame. I then set only Caveats:
If there is a place where a deferred layer can be skipped (a texture used again, or made again, before |
|
Thanks @lucasmazzoni45-del, that's an important lead, since AMD is exactly where this is on by default. I've moved the PR back to draft until it's understood: as you say, with I can't reproduce this without an AMD card. If a longer run confirms it, the most useful data would be whether the blocks appear only after a texture had (AI-assisted via Claude Code on my behalf.) |
|
Thanks @metroid98 for moving it to draft and for the questions. What my log from the session with the blocks can and cannot answer:
What would settle it is one more log line when a deferred texture is finished or dropped (the Also, my build is v2.0.11 + this PR + AMD changes of mine, so it may not behave exactly like the PR on stock main. |
|
Correction to my earlier report here, so nobody chases the wrong thing: square blocks came back while the split was off. With They do not look like the first ones, though. The first were opaque black, purple, yellow and red blocks over the sky of Castle Town. These are translucent squares, mostly greyer than the glow around them, in a grid over a very bright light shaft in a forest area (RX 7800 XT, v2.0.11, same machine). That second kind looks like #1117 (blocky light halos around bright spots, the few NEAREST samplers), not like a texture that was left half uploaded. So what I can say now:
I would not treat "clean with 0" as a confirmation of anything yet. Sorry for the noise. |
|
Thanks for the careful correction, @lucasmazzoni45-del. That makes the translucent grid look like #1117 rather than this PR. I'll keep this as a draft until someone gets a longer AMD run with the default 16 M budget and either sees the opaque sky blocks again or doesn't, then mark it ready or dig in. (AI-assisted via Claude Code on my behalf.) |
|
Follow-up with a useful detail: the place where I first saw the opaque black/purple/yellow/red blocks (the sky of Castle Town, below the ruined castle) is clean again with The translucent squares I mentioned in my correction are somewhere else, in a strong light shaft in the Kakariko graveyard, and I think they are #1117's blocky glow and not this PR. So the two things are separate, and the Castle Town result is consistent with my first report: the blocks there went away when the split was turned off. Still one observation on one machine, and a few minutes in the same spot, not a long run, so I would still call it a lead. Today's log has no deferral line at all with the setting at 0; the earlier session with the default had 20 printed ones (the only texture shown was the 1365x1365 x90 array, at the load). |
bc_pending is a plain vector the replay thread drains at each recording's start; with RX_VK_PARALLEL > 1 several segment workers upload at once, so pushes raced the drain, and a deferred run could be recorded in another segment that the queue reaches before the image's first layout change. Segment workers now upload all layers at once (budget 0), as before this PR. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015DmSMGJSY9hHswALy4eqtQ
|
Thanks @lucasmazzoni45-del, that makes the split path the suspect for the opaque blocks. I've read through it for a cause; here's what I found:
Still a draft. Not built or run here (no AMD card). (AI-assisted via Claude Code on my behalf.) |
|
Thanks @metroid98 for reading through it. Answers:
What I can do next without a rebuild: a longer run with the split on at the default 16 and the preallocation at the default as well, to separate "split path" from "split path with a big preallocated pool". If I rebuild, I would add a log line when a deferred texture finishes, with its address. Tell me which of the two is more useful to you; I will report here either way. |
…ith it For the AMD sky-block report on this PR: the log printed only the first 20 deferrals, so it could not show whether a texture's continuation ever finished. Now a line when its last deferred layers are in (first 40, then every 200th) and one when destroy_later drops pending layers. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015DmSMGJSY9hHswALy4eqtQ
|
Thanks, that settles parallel replay. The gap you found (deferrals at present ~2280, blocks at ~15960) is the key question: did that array's continuation ever finish? Pushed f494015, which adds the line you suggested:
Running with the default pool size at the same time, as you planned, would separate the pool question as well. (AI-assisted via Claude Code on my behalf; not built here.) |
…ontinuation Two holes in the split BC3 upload, behind the opaque black/purple/yellow blocks reported in the sky on an RX 7800 XT with the default budget: - Until texture_bc_continue reached them, a new image's deferred layers showed whatever its memory held before: with pooled image memory, other textures' BC3 blocks. They are now filled in the same recording with a VRAM-to-VRAM vkCmdCopyImage of the last layer encoded (every level, no decode or encode, so the long submission does not come back). A texture uploaded before keeps its old layers meanwhile. - A continuation whose upload_astc_gpu returned false (no staging arena, no scratch) was dropped and logged as "its last N deferred layers are in": those layers kept the old memory for good. It now goes back on the list up to bc_parts::kContinueTries times, and "in" is logged only when it recorded; giving up is logged as such. tests/test_bc_parts: fill_source / retry_continue, and source checks for both paths. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Thanks @metroid98 for carrying this, and @lucasmazzoni45-del for the careful runs. Reading the current head (f494015), I found two holes in the split path that would explain opaque blocks. Both are fixed in one commit on top of f494015: 6f76660 on ZurielAtr:fix/bc3-parts-fill.
Tested on RX 7700S 8 GB, Windows 11, Adrenalin 26.10.1, v2.0.11 + this PR + the fix, default budget (16 M texels): one session of about 5.5 minutes in play, including the spot where I used to see blocks in the sky. Seven textures deferred layers (the two 1365x1365 x90 terrain arrays, twice each, plus three small arrays); all seven logged @metroid98, feel free to cherry-pick it onto this branch ( AI-assisted (Claude Code) on my behalf. |
|
Thanks @ZurielAtr, both holes are real. The second is in the log line I added: it would have called a failed continuation "in". I fast-forwarded this PR to your 6f76660, so it's now the head here, with your authorship kept. The fill is a VRAM copy inside the same recording, so it shouldn't bring back the long submission. @lucasmazzoni45-del, a run of this head with the default 16 would now be the real test: no opaque blocks at all, plus the new |
|
Thanks @ZurielAtr and @metroid98, both holes read right to me, and the first one describes what I saw (opaque black, purple, yellow and red squares with BC-block edges, not moving between two screenshots). I will run the head you pushed (6f76660) tomorrow on the RX 7800 XT / Windows 11, with the defaults you asked for: the split at 16 and the image pool at its default size, no I will also look at what it does to performance on this card: frame times and the replay |
|
Thanks @metroid98 and @ZurielAtr! Tomorrow I'll run the current head
(6f76660) with the default 16, both with my larger pool and with the
default pool size, and report whether the opaque blocks are gone and
whether the `filled from layer` / `last … are in` lines show up.
…On Tue, Nov 10, 2026 12:04 AM, metroid98 ***@***.***> wrote:
*metroid98* left a comment (NotRexed/Hookshot#1130)
<#1130 (comment)>
Thanks @ZurielAtr <https://github.com/ZurielAtr>, both holes are real.
The second is in the log line I added: it would have called a failed
continuation "in". I fast-forwarded this PR to your 6f76660
<6f76660>,
so it's now the head here, with your authorship kept. The fill is a VRAM
copy inside the same recording, so it shouldn't bring back the long
submission. @lucasmazzoni45-del <https://github.com/lucasmazzoni45-del>,
a run of this head with the default 16 would now be the real test: no
opaque blocks at all, plus the new filled from layer and last … are in
lines. Still a draft until then. (AI-assisted via Claude Code on my behalf;
not built here.)
—
Reply to this email directly, view it on GitHub
<#1130?email_source=notifications&email_token=BXKPXORHNMTUF6NGEZVK2CL5YJEOHA5CNFSNUABFM5UWIORPF5TWS5BNNB2WEL2JONZXKZKDN5WW2ZLOOQXTMNZVGM4DGMRZGA42M4TFMFZW63VHNVSW45DJN5XKKZLWMVXHJLDGN5XXIZLSL5RWY2LDNM#issuecomment-6753832909>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/BXKPXOWS3MSGAJTXHBPBINL5YJEOHAVCNFSNUABGKJSXA33TNF2G64TZHMYTINBWHE3DENJSGA5US43TOVSTWNRSHA3TCMBVGQYDDILWAI>
.
You are receiving this because you were mentioned.Message ID:
***@***.***>
|
|
Small change of plans: I'm setting everything up for testing right now
instead of tomorrow. I'll run the current head (6f76660) with the default
16 and report back here with the log (opaque blocks or not, plus the
`filled from layer` / `last … are in` lines).
…On Tue, Nov 10, 2026 12:04 AM, metroid98 ***@***.***> wrote:
*metroid98* left a comment (NotRexed/Hookshot#1130)
<#1130 (comment)>
Thanks @ZurielAtr <https://github.com/ZurielAtr>, both holes are real.
The second is in the log line I added: it would have called a failed
continuation "in". I fast-forwarded this PR to your 6f76660
<6f76660>,
so it's now the head here, with your authorship kept. The fill is a VRAM
copy inside the same recording, so it shouldn't bring back the long
submission. @lucasmazzoni45-del <https://github.com/lucasmazzoni45-del>,
a run of this head with the default 16 would now be the real test: no
opaque blocks at all, plus the new filled from layer and last … are in
lines. Still a draft until then. (AI-assisted via Claude Code on my behalf;
not built here.)
—
Reply to this email directly, view it on GitHub
<#1130?email_source=notifications&email_token=BXKPXORHNMTUF6NGEZVK2CL5YJEOHA5CNFSNUABFM5UWIORPF5TWS5BNNB2WEL2JONZXKZKDN5WW2ZLOOQXTMNZVGM4DGMRZGA42M4TFMFZW63VHNVSW45DJN5XKKZLWMVXHJLDGN5XXIZLSL5RWY2LDNM#issuecomment-6753832909>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/BXKPXOWS3MSGAJTXHBPBINL5YJEOHAVCNFSNUABGKJSXA33TNF2G64TZHMYTINBWHE3DENJSGA5US43TOVSTWNRSHA3TCMBVGQYDDILWAI>
.
You are receiving this because you were mentioned.Message ID:
***@***.***>
|
|
Starting the test of 6f76660 now. Build: current main (0828863) with this head merged on top (one conflict, only in the test list in tests/run_all.py), no patches of mine, stock settings: the split at the default 16, no RX_VK_BC_PART_MTEXELS, no RX_VK_IMAGE_PREALLOC. RX 7800 XT / Windows 11. The first start after the swap redoes the shaders and pipelines, so that session will not count for performance. After that I will walk Castle Town below the ruined castle, out to Hyrule Field and back, look for opaque blocks, and post the |
Only tests/run_all.py conflicted: kept test_bc_parts.py and main's new entries. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015DmSMGJSY9hHswALy4eqtQ
|
Result of 6f76660 on RX 7800 XT / Windows 11: the split runs and the loading is fast; I cannot yet say the opaque blocks are gone for good. Build and setup: current main (0828863) with this head merged (one conflict, only in the test list in What the log shows:
What I saw playing (my own words, no measurement):
I will do Castle Town below the ruined castle and Hyrule Field next, and a session with the split off for the frame-time comparison, and post those here. |
…ice lost ends the game too PR NotRexed#1130's update: on an RTX 3070 the parts made the Hyrule Castle load hitch ~1.2 s longer (2.1 s against 0.9 s) with no driver reset to avoid, so bc_part_budget's default is 16 M texels on AMD and 0 (all at once, as before the parts) elsewhere. RX_VK_BC_PART_MTEXELS=16 brings them back on any GPU. tests/test_bc_parts.py checks the default. PR NotRexed#1291 took four VK_ERROR_DEVICE_LOST checks to device_lost(); this branch has a fifth, in submit_segment_recording (the parallel replay), which now goes there as well (tests/test_device_lost_exit.py refuses a stray one). Co-Authored-By: Claude <noreply@anthropic.com>
|
Correction to my run above: at Ganon's Castle I also saw, briefly, black
opaque blocks in the sky. This is separate from the white glow I mentioned
(#1004), which was a different thing. The black blocks went away after I
left the area and came back.
So this session was not fully clean: the blocks can still appear on head
6f76660 with the default split, but they did not persist after re-entering
the area. I don't have the exact time in the log, so I can't tie them to a
specific deferred fill yet.
|
|
Log lines from the 6f76660 session I reported above (RX 7800 XT, main 0828863 + this head, split at the default 16, empty What it shows: 7 fills, 7 "last N ... are in", so every fill finished, and only the two terrain arrays (0x10a228a600, 0x10a5b02c00) were ever deferred. Because the 20-line limit stops the "left" lines after the first fill, I cannot tell from the log how long the later fills took. What it does not show: the black blocks in the sky at Ganon's Castle. I did not note the time, so I cannot say which fill they were near. If it is useful, next time I will write down the clock time when they appear, and can run with |
|
Two things from reading the code of the merged head ( 1. Staging memory that is not cleared before the GPU decodes it (lead, unverified). In 2. A test that separates the deferred path from the rest: What I did check and found no defect in: the fill copy and its barriers, and Also: this is the same sky I could not identify (the only deferred textures in my log are two 1365x1365 x90 BC3 arrays). If someone knows which texture the Castle Town / Ganon sky is, I can log that one. |
|
A small thing I hit when merging this PR's head (6f76660) into thread_local uint64_t bc_part_texels = 0; // (vk_texture.cpp: the BC3 parts a recording holds; the fixture's texture refresh resets it)With that, |
Joey-Magnus
left a comment
There was a problem hiding this comment.
The Python source check failures are caused by this PR. tests/test_parallel_rb_refresh.py and tests/test_parallel_init_order.py cut texture code out of gpu/vk/vk_texture.cpp into their fixtures. The new bc_part_texels = 0; at vk_texture.cpp:1938 (and the use at :1950) now ends up in those fixtures without the thread_local declaration at :766, so both fail with "use of undeclared identifier 'bc_part_texels'". I reproduced test_parallel_rb_refresh.py locally on b4fed0c, and @lucasmazzoni45-del reported the same thing. The fixtures need the declaration added, or the reset moved out of the functions they cut. Loosening the text the tests match on would not be a fix.
The branch also conflicts with main again in vk_texture.cpp and tests/run_all.py. Main now discovers tests and reads each test's arguments from RUN_ALL_ARGS in the test file, so the run_all.py line can simply go.
The 16 M-texel split is the default on AMD, and the RX 7800 XT run on 6f76660 still showed black blocks at Ganon's Castle. I'd keep this in draft until a long, clean AMD run.
|
I rebased this onto current main on a branch in my fork: fix/pr1130-bc3-multisubmit. main is a single commit now, so the PR's net diff is applied as one commit.
Full suite on Windows (llvm-mingw, .NET 8): the failures are the same ones that fail on main here. Still open: the AMD sky blocks at Ganon's Castle. A read of the code found no confirmed cause; a long AMD run at the default 16 M budget (with and without the large pool preallocation) is still needed. 🤖 Generated with Claude Code |
|
Follow-up: while reading the deferred BC3 path I found a separate defect that could explain the colored sky blocks, though it is not confirmed as the cause. 🤖 Generated with Claude Code |
|
One more fix for the split path, on ZurielAtr:fix/bc3-parts-fill: d1074fa "stage only the BC3 layers a recording takes", on top of 6f76660. What was wrong. The fix. The split is decided before staging ( This may also be behind two things reported here, though I have not measured either: @Nitnek's ~1.2 s longer castle load on the RTX 3070 (since b7f5525 the budget is off on NVIDIA by default anyway), and the 500 ms submit @lucasmazzoni45-del saw right after two arrays were filled. Applying it.
About the sky blocks at Ganon's Castle. One data point that may save some searching. On the same machine (v2.0.11 + this PR + 6f76660), I saw purple and black blocks in the sky on Death Mountain Trail and took an F9 dump. The blocks first appear in the cloud draw, program AI-assisted (Claude Code) on my behalf. |
This is #900 by @ZurielAtr, rebased onto current main because it was closed only for conflicts ("please rebase on current main and reopen"). Their commit is kept as is (authorship preserved); the conflict resolution is part of that cherry-picked commit. The original description and hardware test (RX 7700S, Windows 11, Adrenalin 26.10.1: Castle Town to Hyrule Field reset the driver 3 out of 3 times before, no reset after) are in #900.
It belongs to the AMD-on-Windows tracker #996 ("device lost after minutes of play"). It has no
Fixesline, because the original did not have one.What was resolved
Two conflicts, nothing else changed:
tests/run_all.py: kept main's three newerARGSentries and addedtests/test_bc_parts.py. The original workflow-file registration is not needed, since the runner discovers tests.gpu/vk/vk_texture.cpp: the#includelist (kept main's includes plusbc_parts.h), and the layer-run loop inupload_astc_gpu. Since fix(vk): upload ASTC textures re-encoded as BC3 over several submissions #900, main made BC3 uploads one layer a run by default (RX_VK_BC_LAYERS, default 1, to stop the dark lines on Hyrule Field's terrain). The loop now takes its run length from that samerunvalue, passed tobc_parts::run_endinstead ofkBcLayers, so main's behaviour is kept and only the per-recording budget (RX_VK_BC_PART_MTEXELS) is added.tests/test_bc_parts.py's source checks still match the resolved files (I compared the needles by reading).Not run
Nothing was compiled or run locally: this was code-only work and no tests, game or build were executed. The behaviour is the original author's tested one; only the merge was done here. It needs a build,
tests/run_all.py, and ideally a repeat of the Castle Town to Hyrule Field test on AMD, with the one-layer-a-run default in place.AI-assisted (Claude Code) on behalf of metroid98.
🤖 Generated with Claude Code
https://claude.ai/code/session_015DmSMGJSY9hHswALy4eqtQ