fix(vk): add VMA image allocation retry without WITHIN_BUDGET #1438
No reviewers
Labels
No labels
accessibility
autorelease: pending
autorelease: tagged
bug
dependencies
documentation
duplicate
enhancement
github_actions
good first issue
help wanted
invalid
question
testing wanted
wontfix
No milestone
No assignees
1 participant
Due date
No due date set.
Dependencies
No dependencies set
Reference
MagicBeanDev/Hookshot!1438
Loading…
Reference in a new issue
No description provided.
Delete branch "fix/amd-astc-upload-and-resolve-whitelist"
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?
Summary
gpu/vk/vk_vma.cpp):create_imagewithoutVMA_ALLOCATION_CREATE_WITHIN_BUDGET_BITif the initial allocation attempt fails.vk: image over budget, retrying without WITHIN_BUDGET).This landed in the v2.0.12 branch (merged there for testing; it reaches
mainwith that release), so closing. Thanks!Reopened: closing this was a mistake on my side. It was tested in the v2.0.12 branch, and it will be merged into main here, so it shows as merged. Sorry for the noise.
Thanks for digging into this. The resolve keys look like a real fix for AMD, but I'd like a couple of the other changes narrowed or explained before this goes in. Notes inline. Short version:
vk_texture.cpp). The two claims behindcan_be_rendereddon't hold on current main. Attachment views honour the view'sbase_level(texture_view/view_level), so a target can be a mip level of a texture with levels > 1. And since #1151, BC images get a raw colour-attachment usage because OoT renders into the BC4 noise volumes. The skip only fires when a new Texture is made over storage a render target took and the CPU hasn't written it since (texture_dirty(*tex, owned, ...)). So when the terrain comes out black, the data most likely got there some way the CPU write watch doesn't see, such as a GPU copy into a slot that used to be a render target. Clearing thegpu_ownedrange when that happens would fix the cause, rather than turning the skip off for every mipmapped or compressed texture. Can you post a log withwatch_tex/RX_VK_UPLOAD_ALLA/B for one of the black-terrain textures, showing its levels, format and how its memory got written?gameplay_network()(vk_draw.cpp). This list is used for more than keeping a network. It is theknownargument todlss_upscale, which skips the "is this frame's scene, B10G11R11 in and out" check. It also opts the key out of the movie-slow linear stub, the RGB9E5 fallback andRX_VK_FORCE_UPSCALE_STUB=1.0775215f…andf10782f9…are the fixed-share Render resolution networks that the DLSS code deliberately matches by shape. Your description says these run in pause menus too, and that's exactly where the scene check matters. Does thevk_shader.cppkeep list alone fix the black picture on AMD? If so, I'd leavegameplay_network()as it is.19346f9c9299279eisn't mentioned anywhere else in the tree, so please add a word on what it is.vk_vma.cpp). For images this skips the deliberate order: within budget first, then system memory (#96). Over budget, WDDM starts demoting other allocations. The buffer change concerns me more:create_device_buffermakes the pool mirrors (vk_memory.cpp), and a refused mirror is meant to degrade gracefully by leaving the pool in system memory. Now a mirror of up to 1 GB can push VRAM over budget, and that pressure lands on the images that actually need it. If this is needed, I'd keep it to images and put it after a log line.jobs_pending()(nit). It's only read for a log line, and a negativependingwould mean an unbalanced--. Clamping it hides that.The branch is also ~148 commits behind main. GitHub says it merges cleanly, but it's worth rebasing so it gets tested next to the #1151 BC attachment change. CI was still pending when I looked.
gameplay_network()is alsoknownfordlss_upscale, which bypasses the format and this-frame's-scene check, and it exempts the key from the slow-movie stub, the RGB9E5 path and FORCE_UPSCALE_STUB=1. Is the keep-list change invk_shader.cppenough for the AMD fix on its own? And what is19346f9c9299279e?Nit: only used in a log line, and a negative count would point to an unbalanced decrement. Clamping it hides that.
Attachment views can target a mip level (
texture_viewusesview_level(v)forViewUse::Attachment), and since #1151 BC images render as raw RGBA16UI targets. So "levels > 1 / compressed is never rendered" isn't safe as a rule. This also brings back the full unswizzle-from-memory cost that the comment above describes, for any mipmapped texture over rendered storage. A more targeted fix would drop thegpu_ownedrange when the new data arrives (if it's a GPU copy into the slot).This now goes over budget in VRAM before the #96 system-memory fallback below. That might be the better trade on some cards, but on Windows over-budget means WDDM demotes something else. A log line when it happens would help (like the "VRAM full" one below).
create_device_bufferis what the pool mirrors use (vk_memory.cpp). A refused mirror is designed to fall back to the pool staying in system memory, so dropping the budget here lets optional mirrors (up to 1 GB) push VRAM over budget at the images' expense. I'd leave buffers within budget.Thanks for the thorough review and guidance @hckrman101, and thanks @NotRexed for testing this in v2.0.12!
We have rebased the branch onto the latest
upstream/mainand narrowed the scope based on your feedback:gameplay_network()(vk_draw.cpp):keeplist invk_shader.cppalone is completely sufficient to prevent AMD from omitting the cooperative matrix resolve networks, without bypassing the DLSS scene format check or affecting the linear stub logic.0775215f8da720e6corresponds to the 33% render resolution network andf10782f9e58b6a7cto the 58% network.19346f9c9299279ewas a resolve pass observed during dynamic sub-passes / pause menus on RDNA 2. Keeping them purely invk_shader.cpppreserves the pipeline cleanly without side effects.VMA Budget Fallback (
vk_vma.cpp):create_device_bufferso memory pool mirrors continue to respect the budget and degrade gracefully into system memory as intended.create_imageand added a throttled log line (vk: image over budget, retrying without WITHIN_BUDGET) when it occurs.jobs_pending()(vk_jobs.cpp):std::max(0, ...)clamp so any unbalanced decrement remains visible for diagnostic logging.Texture Skip (
vk_texture.cpp):can_be_renderedcondition so it doesn't collide with the #1151 BC raw attachment changes or mip level attachment views.watch_tex/RX_VK_UPLOAD_ALLtrace for the recycled terrain allocation to properly clear thegpu_ownedrange when the new data arrives, and submit that as a separate, targeted PR.A note from reading the diff, not from running it: the description lists a change to
gpu/vk/vk_texture.cpp(constrainingcan_be_renderedto textures without mips or compression, so recycled addresses do not matchgpu_ownedrender-target ranges) and agpu/vk/vk_draw.cppchange, but the PR's files are onlygpu/vk/vk_shader.cpp(+1 -1) andgpu/vk/vk_vma.cpp(+7) (head 37743c9,gh api repos/NotRexed/Hookshot/pulls/1438/files). So the texture-upload fix is not in the diff, and the diff cannot be what fixes the flat or black terrain it describes. The two changes that are there: three more cooperative-matrix keys kept on non-NVIDIA cards invk_shader.cpp, and a retry ofcreate_imagewithoutWITHIN_BUDGETinvk_vma.cpp.git apply --checkof the diff passes againstrelease/v2.0.12. Maybe the other files were not pushed?Thanks for narrowing this down. Most of what I raised is sorted:
gameplay_network()is back to main's, so DLSS's scene check and the movie/RGB9E5/stub paths are untouched. Thanks for the notes on the keys.jobs_pending()clamp is reverted.can_be_renderedchange is out, and thegpu_ownedfix is going to a separate PR. That works for me.Still open:
vk_draw.cpp,vk_jobs.cppand buffer changes, but the diff is now just the keep list and the image retry (lucasmazzoni45-del noticed this too). Please update them before merge so the squash message matches what lands.vk_shader.cpp). This list is the issue 26 / 38 / 43 guard. Every key on it builds its software matrix multiply on every non-NVIDIA card (Intel too) and on NVIDIA withmma_software, and that build took minutes on AMD's compiler. When0775215f…/f10782f9…are left out,upscale_stubshould produce a linear upscale, not a black picture. So if they come out black on the 6600 XT, the stub is probably failing for them, and that may be the real bug. Inline question below.CI: the failures in Python source checks come from main, not from this PR. The merge ref was built on
03bce9b. Theretests/test_bc_raw_targets.pywas still looking for the oldcreate_image(ci, x.image, x.allocation) &&text, which #1151 had changed invk_texture.cpp, and #1498 fixed the test later. The other two Ubuntu failures,test_dlss_actor.py(stale SPIR-V header) andtest_menu_font_latin.py, are about files this PR doesn't touch either. Source regressions on main are green again (e.g.05098f9), so merging main in should clear them. GitHub says the branch merges cleanly.Two questions about these keys, since this list is also what keeps the software-MMA networks off AMD/Intel (issues 26/38/43):
0775215f…andf10782f9…take, and what do they cost per frame at 33% / 58%? Issue 26 was a multi-minute compile stall.upscale_stub's linear blit. Do you get a black picture when they're left out (RX_VK_NETWORK_KEEP=fd029a317a9a4b94,9dc98871eb7fc101), or just a softer one? If it's black, the stub is returning false for them, and fixing that would cover every card. A log of that run would help.19346f9c9299279eis still only described as "observed in pause menus". Which pass is it (what it reads and writes, and at what size)? Nit: please keep the per-key note in the comment, as the old one had for9dc98871. Then the next person can tell why each key is here.Thanks @hckrman101! We have addressed all points:
Title & Description:
Inline per-key comments (\k_shader.cpp):
Thanks for the update. The new title matches the diff now, and the image retry in
vk_vma.cpplooks good to me with its log line.Still open:
0775215f…/f10782f9…on the 6600 XT, and no run with them left out. These keys would now build a software matrix multiply on every AMD and Intel card. Main expects them to be left out on those cards:temporal_rejected_networkand the comment abovetemporal_stand_ininvk_draw.cppboth name the 58% and 33% networks as the ones that don't translate on RDNA 2, and they hand those to FSR/DLSS or the stub. Also, #1552 landed on main today and your branch now includes it. It fixes exactly the case of a failed gameplay upscale writing RGB9E5 bits into an R11G11B10 image. So the black picture may already be gone on this head without these keys. Could you try the current head withRX_VK_NETWORK_KEEP=fd029a317a9a4b94,9dc98871eb7fc101and post the log? If it's still black, thevk: dispatches of program … are left outline and whatever the stub logs would show where it fails. If it isn't black, the keep-list change can go and the PR becomes just the VMA retry.19346f9c9299279eis still only described as a "menu/pause resolve". What does it read and write, and at what size?CI: none of the failures come from this PR.
nx2/test_draw_parameters,test_lift_cleanup_errorandtest_recomplauncher_jsonfail on main too.test_draw_stream_visibility(a fixture compile error) fails at your base but passes on current main, so merging main in should clear it. The appimage job failed fetching the dav1d dependency (not a git repository: .../src-dav1d/.git). The branch merges cleanly.This comment says the opposite of the one just above it. That one says a network that's left out becomes a linear upscale via
upscale_stub, and main'stemporal_rejected_networkexists for these fixed-share networks on RDNA 2. If the stub really fails for0775215f/f10782f9, that's the bug to fix, because it would hit every card without cooperative matrices. Keeping them instead brings back the software-MMA build that issues 26/38/43 were about. Please check the current head (it includes #1552's RGB9E5 fallback) with them left out first.Thanks @hckrman101! That makes total sense.
With #1552 landed on
main, the RGB9E5 typed fallback inupscale_stubproperly handles the omitted upscale networks without leaving the picture unwritten. You're completely right that adding those cooperative matrix keys to the defaultkeeplist would impose software matrix multiplication on other AMD and Intel hardware where it isn't wanted.Per your suggestion:
vk_shader.cppchanges entirely.gpu/vk/vk_vma.cpp.Thanks, this is what I was hoping for. The keep-list change is gone, so the PR is now just the image retry in
vk_vma.cpp. That keeps main's linear-stub path for the fixed-share networks, and #1552's RGB9E5 fallback covers the case that looked black. It also fixes the earlier points: the retry is images only, it logs (throttled to 10), and it sits ahead of the #96 system-memory fallback.<atomic>andlogfare already in that file, and the diff is small and self-contained.Two small things, neither blocking:
vk: image over budgetline would show it firing).mkwvk::present_commit,present_defer_intoundefined) and the Python failures (nx2/test_draw_parameters,test_nup_out_of_space) come from the branch base, which is a few commits behind main; main is green again at78e1112. Merging main in should clear them. The appimage job failed while setting up its container. GitHub says it merges cleanly.Good to merge once CI re-runs green after a main merge.