fix(vk): prevent device loss when rendering to 3D BC slices #2327
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!2327
Loading…
Reference in a new issue
No description provided.
Delete branch "fix-gtx1080-noise-volume"
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?
The opening cutscene crashes on a GTX 1080 with driver 581.80 when the noise pass renders to a raw color view of a BC4 volume. A standalone Vulkan probe reproduces device loss by clearing the attachment without running any game shaders.
Load each compressed slice into an uncompressed attachment with one texel per block, then copy the result back after rendering. Use the same path for texture clears and preserve mip and slice addressing, including partial blocks at the edges.
On the GTX 1080, the standalone probe read back all 16,384 blocks correctly. Hookshot now recorded all 128 noise draws and reached the Great Deku Tree and Navi dialogue without device loss. The full Windows test suite had the same seven failures as the baseline.
Refs: #996
Refs: #1001
Refs: #1338
Thanks, this looks right to me. A separate uncompressed 3D image per level (one texel a block), loaded from the BC volume before the pass and copied back after it, keeps the noise pass and the compressed sampling format without ever binding a raw view of the BC volume. I went through the pieces that could bite:
vkCmdCopyImageis legal. The extents are right both ways (source texels for compressed to raw, blocks for raw to compressed), and partial edge blocks are handled.begin_passand the stores inend_passreplacepass_start_barrieronly when a block image is involved, and the new image's UNDEFINED to GENERAL change goes throughupload_cmd()underInitRedirect, the same as other new images.block_image[i]is zeroed for empty slots and cleared on duplicate views, soend_passnever copies a stale slot back.deadwith the texture'slast_value, and their views stay intex->views, so they're destroyed with the texture's other views. BC textures never go to the render target pool, so no pooledview_mapkeeps a view of a freed block image. Compaction clearst->views, and they're made again from the kept block image. The bytes are counted inpad, sototal_bytescomes back down.clear_tex: volume clears now go overs.z .. s.z + s.dinstead of one layer. Whole clears of 2D BC images also stop usingvkCmdClearColorImage, which isn't valid on a compressed format anyway (VUID-vkCmdClearColorImage-image-00007). Both are good changes.Non-blocking:
test_bc_raw_targets.pyandtest_vulkan_clear_mip.pystill need a run in CI.Good to merge once CI is green.
github-sync referenced this pull request2026-11-12 06:22:54 +00:00