fix(vk): count BC textures by blocks in the texture budget #2624
Closed
mooki000 wants to merge 1 commit from
mooki000/fix/vk-block-texture-budget into main
pull from: mooki000/fix/vk-block-texture-budget
merge into: MagicBeanDev:main
MagicBeanDev:main
MagicBeanDev:github/pr/2893
MagicBeanDev:github/pr/2890
MagicBeanDev:github/pr/2887
MagicBeanDev:github/pr/2878
MagicBeanDev:github/pr/2875
MagicBeanDev:github/pr/2874
MagicBeanDev:github/pr/2873
MagicBeanDev:github/pr/2871
MagicBeanDev:github/pr/2756
MagicBeanDev:github/pr/2897
MagicBeanDev:github/pr/2896
MagicBeanDev:github/pr/2718
MagicBeanDev:github/pr/2842
MagicBeanDev:github/pr/2691
MagicBeanDev:github/pr/2895
MagicBeanDev:github/pr/2743
MagicBeanDev:github/pr/2765
MagicBeanDev:github/pr/2708
MagicBeanDev:github/pr/2732
MagicBeanDev:github/pr/2755
MagicBeanDev:github/pr/2817
MagicBeanDev:github/pr/2876
MagicBeanDev:release-please--branches--main
MagicBeanDev:release-please--branches--main--release-notes
MagicBeanDev:github/pr/2778
MagicBeanDev:github/pr/2888
MagicBeanDev:github/pr/2866
MagicBeanDev:github/pr/2877
MagicBeanDev:github/pr/2800
MagicBeanDev:github/pr/2829
MagicBeanDev:github/pr/2850
MagicBeanDev:github/pr/2889
MagicBeanDev:github/pr/2882
MagicBeanDev:github/pr/2860
MagicBeanDev:github/pr/2849
MagicBeanDev:github/pr/2886
MagicBeanDev:github/pr/2794
MagicBeanDev:github/pr/2840
MagicBeanDev:github/pr/2830
MagicBeanDev:github/pr/2834
MagicBeanDev:github/pr/2719
MagicBeanDev:github/pr/2742
MagicBeanDev:github/pr/2741
MagicBeanDev:github/pr/2820
MagicBeanDev:github/pr/2771
MagicBeanDev:github/pr/2859
MagicBeanDev:github/pr/2858
MagicBeanDev:github/pr/2823
MagicBeanDev:github/pr/2757
MagicBeanDev:github/pr/2769
MagicBeanDev:github/pr/2844
MagicBeanDev:github/pr/2843
MagicBeanDev:github/pr/2673
MagicBeanDev:github/pr/2855
MagicBeanDev:github/pr/2739
MagicBeanDev:github/pr/2807
MagicBeanDev:github/pr/2851
MagicBeanDev:github/pr/2789
MagicBeanDev:github/pr/2814
MagicBeanDev:github/pr/2818
MagicBeanDev:github/pr/2774
MagicBeanDev:github/pr/2772
MagicBeanDev:github/pr/2750
MagicBeanDev:github/pr/2786
MagicBeanDev:github/pr/2785
MagicBeanDev:github/pr/2782
MagicBeanDev:github/pr/2779
MagicBeanDev:github/pr/2775
MagicBeanDev:github/pr/2706
MagicBeanDev:github/pr/2766
MagicBeanDev:github/pr/2747
MagicBeanDev:github/pr/2759
MagicBeanDev:github/pr/2745
MagicBeanDev:github/pr/2740
MagicBeanDev:github/pr/2733
MagicBeanDev:github/pr/2725
MagicBeanDev:github/pr/2727
MagicBeanDev:github/pr/2728
MagicBeanDev:github/pr/2729
MagicBeanDev:github/pr/2721
MagicBeanDev:github/pr/2722
MagicBeanDev:github/pr/2715
MagicBeanDev:github/pr/2714
MagicBeanDev:github/pr/2707
MagicBeanDev:github/pr/2703
MagicBeanDev:github/pr/2705
MagicBeanDev:github/pr/2697
MagicBeanDev:github/pr/2679
MagicBeanDev:github/pr/2676
MagicBeanDev:github/pr/2669
MagicBeanDev:docs/what-hookshot-connects-to
MagicBeanDev:fix/hdr-encode-test
MagicBeanDev:fix/main-tests
MagicBeanDev:fix/play-cache-files
MagicBeanDev:perf/game-barrier-order
MagicBeanDev:feat/heap-lazy
MagicBeanDev:feat/texture-detail
MagicBeanDev:perf/astc-opaque-bc1
MagicBeanDev:fix/fs-dir-lock
MagicBeanDev:fix/framegen-native-kept
MagicBeanDev:fix/update-no-downgrade
MagicBeanDev:port/k10-gcn-f16-mirrors
MagicBeanDev:fix/framegen-mult-cap
MagicBeanDev:chore/release-as-2.1.1
MagicBeanDev:perf/pcache-load-switch
MagicBeanDev:fix/prepare-progress-log
MagicBeanDev:fix/update-closes-stale-game
MagicBeanDev:fix/hdr-scaled-sampled
MagicBeanDev:perf/first-start-preset
MagicBeanDev:perf/zero-upload
MagicBeanDev:fix/vcore-escape-2s
MagicBeanDev:test/fake-gh-atomic
MagicBeanDev:perf/batch-idle-flush
MagicBeanDev:test/finish-stub-a
MagicBeanDev:chore/record-2.1.0
MagicBeanDev:fix/main-red-tests
MagicBeanDev:fix/test-display-startup-driver-cache
MagicBeanDev:feat/mesh-shader-mode
MagicBeanDev:fix/menu-probes-at-startup
MagicBeanDev:fix/fps-counter-classic
MagicBeanDev:fix/test-log-batch-flake
MagicBeanDev:fix/narrow-screen-hud
MagicBeanDev:ci/prereleases
MagicBeanDev:release/v2.0.15
MagicBeanDev:hotfix/v2.0.15
MagicBeanDev:fix/present-ahead-replay
MagicBeanDev:release/v2.0.13
MagicBeanDev:fix/bracket-paths-2013
MagicBeanDev:fix/hdr-overlays-2013
MagicBeanDev:fix/fps-counter-scale-2013
MagicBeanDev:fix/stick-seen-at-rest
MagicBeanDev:hotfix/menu-fits-screen
MagicBeanDev:fix/f1-always-opens-menu
MagicBeanDev:fix/ini-keep-lines
MagicBeanDev:claude/cranky-pike-7cf247
MagicBeanDev:perf/texture-answer-flat
MagicBeanDev:fix/stamp-test-modules
MagicBeanDev:fix/appimage-fonts
MagicBeanDev:fix/display-awake
MagicBeanDev:release/v2.0.12
MagicBeanDev:fix/discord-windows
MagicBeanDev:rc/v2.0.12-tests
MagicBeanDev:fix/dlss-keep-feature
MagicBeanDev:rc/v2.0.12
MagicBeanDev:button-icons
No reviewers
Labels
Clear labels
accessibility
Barrier affecting people with disabilities
autorelease: pending
autorelease: tagged
bug
Something isn't working
dependencies
Pull requests that update a dependency file
documentation
Improvements or additions to documentation
duplicate
This issue or pull request already exists
enhancement
New feature or request
github_actions
Pull requests that update GitHub Actions code
good first issue
Good for newcomers
help wanted
Extra attention is needed
invalid
This doesn't seem right
question
Further information is requested
testing wanted
wontfix
This will not be worked on
No labels
accessibility
autorelease: pending
autorelease: tagged
bug
dependencies
documentation
duplicate
enhancement
github_actions
good first issue
help wanted
invalid
question
testing wanted
wontfix
Milestone
Clear milestone
No items
No milestone
Assignees
Clear assignees
No assignees
2 participants
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".
No due date set.
Dependencies
No dependencies set
Reference
MagicBeanDev/Hookshot!2624
Loading…
Reference in a new issue
No description provided.
Delete branch "mooki000/fix/vk-block-texture-budget"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
What this is for: stop the texture budget from charging BC1/BC4 images about twice their compressed size, and make the estimate taken before an image is created use whole compressed blocks too, following hckrman101's review of #2288. What is measured: game-free runs of the production accounting with GCC and Clang: 4,845 cases plus the original 182 helper cases pass, and 3,040 of them fail on main. One pair of game runs (main and the change, Kokiri Forest, RTX 4090) shows no fault and no difference in behaviour, because the budget is never reached there. Not measured: eviction in play, any frame-rate effect, AMD, Windows, or a long session on a card with little VRAM.
Problem
The review's follow-up on BC was:
create()summed the mip chain's texels and charged every BC format one byte a texel. BC1 and BC4 have eight-byte blocks, the other BC formats sixteen-byte blocks, and every level needs its extent rounded up to whole 4x4 blocks, the 1x1 tail included. The allocator floor covers an underestimate but cannot undo an overestimate, and the inflated count goes intototal_bytes, which the eviction sweep compares with the budget.The review also pointed at the separate estimate taken before creation (
bytes_at): an ASTC image the GPU samples itself was still treated as at least one byte a texel, four times the size of 8x8 blocks and nine times that of 12x12 blocks. That estimate decides whether the top levels of a very large image are dropped and whether an array is made sparse.Last, the ASTC test mixed decimal MB with binary MiB. Its example is 3,410.0 MiB by the old texel count and 53.8 MiB of blocks; comment and output now agree.
What changed
gpu/vk/vk_texture.cpp:texture_level_unitsis used for native BC and native ASTC in both the estimate before creation and the final count. The helper already rounds each level to whole blocks; no allocation and no further pass over the mip chain is added.tests/test_native_astc_texture_count.py: the helper's cases stay, and the old checks of the source's text are replaced by compiling and running the production estimate and final count: all 16 BC formats, all 14 ASTC block sizes, partial blocks, 1x1 tails, skipped top levels, arrays, volumes and samples, decoded and re-encoded ASTC, widening, sparse images and the allocator floor.tests/test_low_vram_texture_mips.py: its cut-out fixture now brings the real format predicates andtexture_level_unitsalong, which the changed estimate needs to compile. Every configuration and assertion is kept.docs/development.md, theRX_VK_VRAM_MBrow: what a texture counts, that the log prints MiB asMB, and the default as the code computes it (70% of what the driver allows the process, 45% where that is 8.5 GB or less, at most 6 GB; on an integrated GPU less, by the system's RAM: 1 GB with 8 GB of RAM, 2 with 12, 2.5 with 16, 3.5 with 24, 4 with 32, up to 6 above that).The count changes; the image data, formats, uploads and compression do not. A smaller count is not less VRAM allocated.
How to try it
No new switch. Compare the log's
textures N MB (budget B MB)andtextures retired ...: budget Nlines in one scene with the same budget settings. Game-free:How it was tested
Arch Linux, Core i9-13900K, GCC 16.2.1 and Clang 23.1.3. Branch
883c3072, one commit on main0ec31ff6(rebased from1c08cde1on8568959d: at that base main's ownvk_texture.cppdid not compile on Linux,std::minandstd::maxwith mixed integer types in the integrated-GPU budget, which is why this pull request's first AppImage job failed; main has since fixed it).On this head, both compilers:
The negative checks compile and run rather than fail on a missing string:
de866017)The last two rows were run on the same code change one rebase earlier (a comment and the documentation row changed since); they show that neither half of the fix hides a missing check of the other.
The whole
tests/run_all.pysuite was run once on the earlier base (fce53453): 447 passed, 3 failed, 20 skipped. The three: the mip-policy fixture, which did not compile without the helpers and is repaired here (above);nx2/test_depth_sample_types.py, whose Clang process was killed by SIGKILL (the cause was not established; the machine was heavily loaded) and which passes when run alone; andtest_env_on.py, main'sHOS_FPS_LOGfailure of that day, since fixed by #2575.In the game (RTX 4090, NVIDIA 615.78.08, headless, a save in Kokiri Forest with camera turns, 170 s each, one after the other): main
fce53453and a build of the same base with this change'svk_texture.cpp(the code is the same as on this branch; one comment differs).The pictures of both runs show the forest and the HUD as they should be. Neither run reached its budget, so this pair shows that the change does no harm in an ordinary scene on a large card. It does not show an eviction that comes later, and it is not a timing.
What to expect in play
Reasoned, not measured: with BC1/BC4 no longer counted double, the fixed texture budget is reached later, not earlier. The allocator floor stays, and the rules that react to the driver's own figures still use what the driver reports, so this does not postpone every eviction. A smaller count can also put a BC texture the GPU drew under one of the existing keep-size thresholds; those rules are unchanged. Tiny and partial mip levels that the old formula undercounted now count a whole block, which the allocator floor usually covered already.
Not tested
Risks
Unlike #2288, this changes the count on NVIDIA and AMD too. An undercount would put eviction off too long; the per-format arithmetic in the test, the tiny-level cases and the allocator floor guard against that. Correcting the estimate before creation can keep a large compressed image whole where the old estimate dropped its top levels or made it sparse. That is intended, but how it behaves at those thresholds needs other workloads and hardware.
Overlaps
RX_VK_VRAM_MBrow indocs/development.md: keep their rows and this description.tests/test_low_vram_texture_mips.pybeside this change's two imports: keep both.docs/development.mdin its rewrite of the docs: the row's new wording should move with it.vk_texture.cppthe overlap scan of 2026-11-11 found no conflict with an open pull request.No separate issue: this is the follow-up the review of #2288 asked for.
Assisted-by: GPT-6 Astra
Co-Authored-By: GPT-6 Astra [email protected]
Thanks, this is the BC follow-up I asked for in #2288 and the math checks out.
I went through it format by format against
nvn_fmt_bpb(host/nvn_layout.c), which is wherebpb/bw/bhcome from: DXT1 and RGTC1 (BC1/BC4) give 8 bytes per 4x4 block; DXT3/DXT5, RGTC2 and BPTC (BC2/3/5/6H/7) give 16. Both the estimate (bytes_at) and the final count now go throughtexture_level_units, which rounds every level up to whole blocks, so 13x13 counts as 4x4 blocks and the 1x1 tail as one block. 3D levels are blocked in x/y only, which is right for BC. Re-encoded ASTC counts as 4x4 blocks of 16 bytes no matter the source block size, and the same holds for the BC7 variant. Decoded RGBA8 and the widened formats are unchanged.What players will see: on NVIDIA/AMD the game's ASTC still goes through the decoded path, so the RGBA8 count is unchanged and BC3 only changes at partial-block tails (the allocator floor already covered those). Native BC1/BC4 drop from twice their size to their real size. Since
x.padstill raises the count toallocation_size, a texture never counts for less than VMA gave it, so this can't push eviction past real use, and the integrated-GPU budget only gets an honest count to compare against. Low-VRAM cards reach the budget a little later where BC1/BC4 are involved, but the driver-figure rules (the 90%/97% squeeze, compaction) are untouched.Two behaviour changes worth knowing about, neither blocking:
bytes_atagainst the 1536 MBRX_VK_TEX_MAX_MBcap: a big native BC1 or native ASTC (8x8 and up, Intel) array that used to go sparse or lose its top levels can now stay whole. That's correct now that the number is right. For the 1365x1365x90 arrays it makes no difference: they were under the cap before and still are.tex->bytes, for textures the GPU wrote) now see BC at its real size, as the description says. That's fine.Tests: the new fixture runs the production estimate and final count rather than matching strings, the expected values are computed independently, and
test_low_vram_texture_mips.pynow pulls in the real helpers. Both pass in CI on Linux and Windows. The red jobs are main's known failures plus the ten fixtures #2648 repaired (now on main), none of them this PR's tests. A merge of main should turn most of it green.One nit on the docs row, inline. Approving.
Nit: by the code, an 8 GB-RAM integrated GPU gets 1 GB, not 1.5 GB.
reservedis at least 8 GB, soavailablecomes out 0, the cap gives 0, and the 1 GB floor wins. 12 GB gives 2 GB, 16 GB gives 2.5, 24 GB gives 3.5, 32 GB gives 4, and above that up to 6 GB. Something like "1 GB with 8 GB of RAM up to 4 GB with 32 GB (6 GB above)" would match.You are right, I read the caps and missed that
reservedleaves nothing to cap at 8 GB. Corrected in883c3072to what the code gives: 1 GB with 8 GB of RAM, 2 GB with 12, 2.5 GB with 16, 3.5 GB with 24, 4 GB with 32, and up to 6 GB above that. The same push rebases over #2651, which added the row above this one.A data point from the case the description lists as not measured (Windows, a card short of VRAM, in play), which turned out inconclusive.
Windows 11, RTX 3060 Ti 8 GB (driver 32.0.16.2114), Ryzen 5 5600X, 2560x1440 DLSS.
mainba005ca4with #2711, #2731, #2685 and #2709 merged locally; with and without this PR on top (two builds, so the arms could not be alternated: base, this PR, base again). Castle Town Market child, 30 s of the camera turning after a settle, where the texture budget is reached all the time (budget ~1.5-2.1 GB, 2.3-2.9 GB of textures).The same base build drifted from ~48 to ~42 fps between the two sets, so the Market on this card moves too much between launches to call this PR's lower numbers a regression. Evictions per run were about the same in all nine (26-30 thousand textures retired); this PR's runs had fewer compactions (2-7 against 7-9). No fault, no texture in system memory. I'd treat it as "no improvement seen here" rather than evidence either way.
@klikso thank you, that is exactly the case the description leaves open, and your three sets are enough to take seriously even with the drift: the runs with this change are the lowest of the three.
Please hold the merge until this is settled. I am measuring it now on this PC under an 8 GB memory model (a 24 GB card held to a small allowance, as #2690 and #2711 were measured), in the Market with the camera turning: this change against its own base, the two builds alternated in one hold, plus a control with memory to spare. The reason it could be real: counting BC textures at their true, smaller size lets the same budget admit more of them, and that can change when the squeeze and compaction start even though the driver's allowance is untouched. The result and what follows from it (unchanged, a fix on top, or a draft until a real 8 GB card has run it) go here.
I merged this into current main (it merges cleanly) and ran test_native_astc_texture_count, test_low_vram_texture_mips, test_texture_staging_publication, test_ui_texture_upload and the other texture tests on Linux. All pass. The one red job is test_nightly_two_runs_at_once_end_at_the_newer_commit in test_release_scripts, which flakes on main too and has nothing to do with this PR. hckrman101's docs nit about the 1 GB minimum with 8 GB of RAM is fixed in the current head.
The arithmetic matches nvn_fmt_bpb, and x.pad still floors the count at the allocation. The open question is the one klikso raised and you're measuring. With the budget number unchanged, the cache now keeps up to twice as much real BC1/BC4 before it evicts. On an 8 GB card that moves more of the work onto the driver-figure rules (the 90%/97% squeeze and compaction). His three Market sets put this PR lowest, though the base drifted between them. Since you asked to hold the merge, I'll wait for your alternated runs. If they show a drop, lowering the default budget for under 8.5 GB to match the honest count would be one way to keep both.
Thanks. The alternated runs are queued on this PC: this pull request against its base in one session, Castle Town Market, with the card held to an 8 GB allowance, so the base cannot drift between sets. I will post them here. If they show a drop, I will try your suggestion (a lower default budget below 8.5 GB that matches the honest count) and measure that as a third column before asking for the hold to be lifted.
github-sync referenced this pull request2026-11-12 16:54:48 +00:00
@klikso @Joey-Magnus: the alternated pressure runs show no difference this PC can resolve, not proof that the Windows result was just drift. Against the PR's own parent, mean frame time rose 1.88%, beside 1.83% spread between the base repeats; the ranges are narrowly separated, so this is not an equivalence claim.
Linux/NVIDIA 615.78.08, RTX 4090 24 GB, i9-13900K; child Market south entrance, camera turning, 2560×1440, fixed 67% render scale, DLSS K, frame generation off, cap 240. Prepared caches and unmeasured warm-ups; A/B/A/B in one exclusive hold, at least 60 s measured per launch after settling.
ee29dd55da33e6cc1% lows: A 37.4 / 36.8 fps, B 35.9 / 35.6. Both B runs sit behind both A runs, by about the size of A's own spread: small and at the edge of what this PC can resolve, not nothing.
Model:
RX_VK_TEST_ALLOWED_MB=7000,RX_VK_IMAGE_PREALLOC=9, plusRX_VK_MIRROR_MB=2048to match an 8-GB heap's mirror limit. Every sampled pressure line exceeded the texture budget. Compaction starts per whole 110-s launch were A 14/17, B 16/19, not fewer on B; budget retirements A 17314/17220, B 17252/17358. No fault or logged system-memory image fallback.With the card's full memory (no model) the three accepted runs show no difference: A 86.4 fps, B 87.3 and 86.4. That control is incomplete: one A arm was rejected because other work peaked at 19.26 CPU cores; its raw result and the three accepted arms are retained. System-wide swap-in was also recorded, so the small pressure gap is not isolated from all host activity.
Your PR set was lowest (32.6–42.3 fps) against the first base (46.8–49.7) and rebuilt base (40.8–43.8), with more long frames. I am not dismissing that: your base drifted, and your
ba005ca4+ #2711/#2731/#2685/#2709 stack is not this isolated parent/head pair. Our standing point, camera speed and explicitly fixed DLSS settings may differ too.The model exercises renderer eviction/squeeze/compaction, not a real 8-GB heap or Windows residency/paging/allocation costs. The real driver allowance was still 22,473–22,488 MiB here. When driver pressure sets the budget, the smaller texture total also lowers that target; these runs do not show extra residency caused by the corrected count.
So the hold stays, for one check this PC cannot do: an alternated pair on a real 8 GB card on Windows. Many players have such cards, and the pair takes about 20 minutes. @klikso, you have the card: could you run it?
ee29dd55b593577ae0a7a6e2f871848ee5e176b4(this pull request's parent) and Bda33e6cc77309603063e038609e1e7c826a15ce4, built into two folders from the same game files, nothing else merged in.RX_VK_FRAME_LOG, the full logs, the driver version, and the dedicated and shared GPU memory if you can record them.If B is behind A by more than the two A runs differ, I will try Joey-Magnus's lower default budget below 8.5 GB as the next step and measure all three here and ask for the same pair again. If it is not, I lift the hold. I am also putting this in the test-request queue so anyone with an 8 GB card can take it.
No code changed from these results. The arithmetic of the count is right; what is open is only what it costs on a real small card.
Re-review. The code is the same as the commit I approved; this push rebased onto main and fixed the docs nit, and the row now matches what the integrated-GPU budget gives. Thanks.
I rechecked the block math on the rebased file. The image's own format decides. Decoded ASTC is an RGBA8 image, so it stays at 4 bytes a texel. ASTC re-encoded to BC3 or BC7 counts 4x4 blocks of 16 bytes. Native BC1/BC4 count 8 bytes a block, BC2/3/5/6H/7 16, and native ASTC 16 per bw x bh block. Each level is rounded up to whole blocks on its own, so 2x2 and 1x1 tails count one block each, and a level left out (
x.skip) shifts the extents first. Depth isn't blocked, which is right for 2D-block formats. Still approving.On klikso's Market numbers and the hold. I don't think this change explains that drop:
That agrees with your alternated 8 GB model: +1.9% beside 1.8% of spread between the A runs, with the same retirement and compaction counts. klikso's base itself went from about 48 to 42 fps between sets, on a stack that also had #2711, #2731, #2685 and #2709.
For one cheap number on the size, look at the log's 600-present
textures: decoded ASTC ... other N MBline in your unpressured control runs, A against B at the same spot. Native BC sits in "other", so the difference is about as much as this PR can move. A real 8 GB Windows pair from klikso is still welcome. Apart from that, the review needs nothing more. I also wouldn't lower the default for cards under 8.5 GB to make up for this unless that pair shows a drop: under pressure, the default isn't the line that binds.Overlaps: none in the code. #2711 (blocks made at the start in the textures' pool, and the 97% rule waiting while the pool is down to them) and #2826 (the 90%/97% rules evict their excess, not an eighth) change how the driver's excess becomes a target, at the other end of
vk_texture.cpp. They read the total but not how a texture is counted, so the three can land in any order. #2826 adds a row right after theRX_VK_VRAM_MBrow indocs/development.md, so whichever lands second may need a small merge there.CI: the one red job is
test_release_scripts'test_nightly_two_runs_at_once_end_at_the_newer_commit, which fails on main too, as Joey-Magnus said. It merges cleanly.Thanks for the re-review and for working through why the count is not what set the line in those runs. I am lifting the hold: this can merge.
The number you suggested, from the unpressured control runs here (Market, the same spot, the log's
textures:line once the scene has settled):ee29dd55(two runs)So at the Market the honest count is 133 MB lower, about 3% of what the textures count there: that is as much as this change can move in that scene. Together with the alternated runs under the 8 GB model (about 2%, at the edge of what this PC resolves) and klikso's note that his runs were on the harder model-L case with other pull requests stacked, I see no reason left to keep it waiting.
Test request T-TBJL stays open for an alternated pair on a real 8 GB card on Windows (recipe in my comment above): still welcome, as you say. If such a pair shows a real drop I will take it up at once, starting with where the line is set under pressure rather than the default budget.