Repository navigation
fix(agc): build sampled array views from the slices they read - #7258
Conversation
|
Other open pull requests touch the same code. Merging one will break the other, or both implement the same thing. If this one builds on them, list them in Depends on.
Some comparisons could not be completed because a pull request conflicts with the base branch. Review these shared files manually before concluding that there is no overlap.
|
|
Review of 2b2f060. The window math, the XOR slice guard, the texture-relative view ranges and flush coherence all check out. On a local merge with main, The image-table revalidation path still builds from the un-narrowed words. The image-table slow path in
On main both paths used the raw words and agreed, so the mismatch is new. Only the binding revalidation (around 2914) is narrowed so far. Suggested fix: apply the same |
2b2f060 to
0b3603b
Compare
|
Thanks, you were right: Revalidate rebuilt an image table element from the raw T# words, while resolveImageTables binds the first-layer texture for a 2D read of a 2D array. The whole array was compared against the narrowed texture, so the proof always failed. Fixed in 0b3603b (branch rebased on main ed01d79): Revalidate now narrows the words with firstLayerWords before decoding, like the other paths. Added imageTableFirstLayerRevalidateTests, run by agc_draw_descriptors. It requires the table to revalidate on the full proof path and to keep its texture on a second pass. Without the fix it fails with "AGC graphics: an image table holding a 2D read of a 2D array did not revalidate". With it, ctest passes 1471 of 1471. The debt entry for views of 1 GiB or more now also covers storage views, which are logged too. AI-assisted: yes (Claude Code) |
A sampled 2D array, 1D array or cube view created and snapshotted the whole array from slice 0 to its last viewed slice. Ghost of Yotei views six faces at slice 7227 of a 256x256 cube array (3.8 GB built for 3 MB) and one slice at 1536 of a 3328x1872 R8 array (12.4 GiB built for 8 MiB). SampledArrayWindow describes the viewed slices as an array of their own at the first viewed slice when the layout of those slices does not depend on their index: a thin array without DCC metadata, and for an XOR swizzle a first slice that keeps the slice bits the equation mixes in. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A shader that declares a 2D image reads only the base slice of a 2D array T# (the first-layer view), but the texture was built from every slice the T# names. In Ghost of Yotei (PPSA26344) such a read names 1537 slices of a 3328x1872 R_X surface: a 12.4 GiB image that does not fit the 4090's device-local budget and stalls 11-14 s on each rebuild. The sampled lookups (stage A records, stage B bindings, revalidation and image tables) now narrow such a T# to its base slice before the cache key, the decode and the image are made, so a whole-array read of the same T# keeps its own entry. Views of 1 GiB or more that stay whole are logged with the guest allocation they lie in and how many of their slices fit it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Revalidate rebuilt the cached texture of an image table element from the raw T# words, while resolveImageTables binds the first-layer texture for a 2D read of a 2D array. The whole array was rebuilt and compared against the narrowed texture, so revalidation always failed. Narrow the words with firstLayerWords before decoding, as the other paths do. Add imageTableFirstLayerRevalidateTests, run by agc_draw_descriptors: it fails with "an image table holding a 2D read of a 2D array did not revalidate" without the fix. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
0b3603b to
a71ba9e
Compare
|
Rebased onto current main (conflicts in |
What
A sampled array texture was built from slice 0 to the last slice its T# names, whatever slices the view actually reads. Two cases in Ghost of Yōtei (PPSA26344) made that the largest memory cost of its loading phase:
How
ViewedArrayWindow(TextureTiling.cpp) rebases a sampled 2D array, 1D array or cube view to its viewed slices, at the guest address of its base slice. It applies only when the window is exact: a thin surface with no DCC metadata and, for a 64 KiB XOR swizzle, a base slice that keeps the equation's slice bits at zero. Anything else keeps the whole array.FirstLayerDescriptor(GuestTextureResource.cpp) narrows a 2D array T# to its base slice. The sampled lookups apply it before the decode, cache key and image are made when the shader shape is 2D. That covers stage A records, stage B bindings, revalidation and image tables. A whole-array read of the same T# keeps its own cache entry.ShaderResources::Revalidatenarrows the T# words of an image table element withfirstLayerWordsbefore decoding, as the other paths do. Without it the whole array was rebuilt and compared against the narrowed texture, so an image table holding a 2D read of a 2D array never revalidated.This is independent of #6772, which serves storage views past
maxImageArrayLayersand refuses cubes and slice-dependent XOR swizzles, and of #6481, which faults image table entries the device or guest memory cannot hold. The 1537-slice image is below the 4090's 2048-layer limit and lies in readable memory, so neither one catches it.Tested
agc_driver_graphics:FirstLayerDescriptornarrowing, including a separate cache entry from the whole array.imageTableFirstLayerRevalidateTests(run byagc_draw_descriptors): an image table holding a 2D read of a 2D array must revalidate on the full proof path and keep its texture across a second revalidation. Without theRevalidatefix it fails withAGC graphics: an image table holding a 2D read of a 2D array did not revalidate.The loading phase starts around frame 620, so run204 presented 371 frames in it against 343 for run201 (+8%) and built 24% more resource sets.
Log lines from run204
Technical debt
Added to
docs/dev/debt/libSceAgcDriver.md:Checklist
main; no other open PR implements the same functionsNotImplemented_nid_no_patch); silent stubs are listed under Silent stubs in their library's technical debt file.mdfiles or images added to the repository (attach them to this PR)🤖 Generated with Claude Code