Repository navigation
fix(agc): clear a multisampled target on a uniform fill of its color memory - #2132
Conversation
|
Additional platform validation on standalone PR head Windows: passed — Windows 11, supported WinLibs GCC 15.2.0 UCRT/POSIX/SEH r7; CMake 4.3.1 / Ninja. Release / Tests: Reproduce after building the test targets: Vulkan: native AMD RX 6900 XT, driver 32.0.21045.5002. Integration limitation: a local merge against main |
Inherited CMASK state model: source-backed validation (2026-10-11)At current head A proposed correction with state tests separates those states, scans the complete CMASK range, checks mode/clear eligibility, and consumes a pending host clear once while preserving guest metadata classification. It depends on our experimental MSAA foundation; it is not a standalone upstream cherry-pick. This is feedback on the inherited CMASK model; I have not independently reproduced this PR's Hades II color-fill gameplay result. Windows 11 / RTX 5080: full build/120 libraries, 30 final relevant test runs, six caught implementation mutants, ten native positives using two complete captured DCC/CMASK pairs and sixteen exact-diagnostic negative controls. Our PPSA99902 before/full-after/AGC-only startup still stops at the DCC multisample refusal; no startup or console/coherence equivalence claim. Full validation and limits on #419; tracking issue #3262. Fork only, no new PR. AI-assisted implementation and investigation: Codex. |
|
#419 is merged. Please rebase onto main so this carries only its own commit, and mark it ready. |
a41f1d7 to
0e2219b
Compare
Current conditional MSAA reset finding — PPSA99902 /01.003.000Our preserved fac106b2b integration, with validated #4822 libc and original #3644 pipe-poll fixes, reaches the existing private MSAA residency guard. The newest replay ends after 801.006s, exit0xC0000409, no timeout. Six inputs are confirmed consumed/released; sparse captures retain prompt/opening-movie scope, not interactive gameplay or unique-frame FPS. Original dump/modules, baseline runtime, converted guest module and user data are restored/hash-verified. Confirmed first rejection: the 510MiB color range changed according to All 8,160 64KiB color blocks have newer latest stamps of kind Cpu, made by the existing Windows dirty-page collection path. The first/newest block is0x405fc00000; its recorded generation1943351 equals the tracker stamp, CPU stamp and written stamp. Its previous recorded stamp37566 predates initialGeneration869030. The trace distinguishes this from a coverage/generation refusal. It records the kind and creation site of the latest general stamp for every color block; it does not identify the backend event that made the pages dirty or prove guest CPU stores. The newest color stamp predates the active clear certificate1943905 (CMASK1943906), with matching write serials44112. Newer DCC/CMASK general stamps after the clear attempt do not mean their CPU-side certificate checks rejected. This run's target/use XOR is0/0x8000 and FMASK pointer0x407fa08000/0x407fa04000; the refusal occurs before XOR conversion. Validation scope: the observer preserves the original check/collect calls and refusal; it adds only bounded stamp records and scalar logging, without extra guest-byte reads. Its libraries and affected Shared-backend follow-up (787.785s, 2026-10-13)The same frozen fac106b title stack reaches the private guard again, no timeout, baseline restored/hash-verified. Rebuilt controls pass three groups×20. Temporary libc/driver observers preserve the mapping, protection and collection operations and add scalar provenance only; source/ordinary binaries are restored before replay. No actual guest store or whole-color overwrite is proved. The first dirty color views are fresh shared-map records at the same virtual addresses, rather than a pin/unpin, host-write or handled-fault invalidation. The first view appears twice with seen0/generation2 and no recorded prior event, but at later map event serials: Three views at the start of each of two large collection chunks were sampled. Each has one recorded alias (its own address), offset0/0x4000/0x8000 or0x10000000 onward, and #4474 already addresses retirement after successful full allocation removal/unmap. It is now the focused validation candidate; its current026c198e head has no Windows/title validation from this investigation yet. Verify which registry removal/unmap covers this transition, then test its notification/retirement on Windows and adapt it to the private integration's color-plus-metadata guarded ranges. Retain partial-unmap and live-data refusals. This is stronger lifetime evidence than the older CPU-flag/pinning hypotheses, but not a pass/fail verdict on unchanged #4474. No duplicate retirement PR or new current-main issue. What this does and does not validate for #2132The target is3840x2160 RGBA16F/eight-sample, color span0x1fe00000, matching the32x32 fragment-block sizing. Existing fill logs recognize FMASK0x76543210, CMASK0xffffffff/0xcccccccc and DCC0; none of3,074 completely parsed records targets the color range, with one interleaved DCC continuation retained. Requests are not completed stores or uniform-overwrite proof. This is not a pass/fail test of unchanged #2132 or confirmation that its uniform whole-color-fill path solves this guard. Main has no equivalent private reuse check, so no new unchanged-main title defect is established. Preserved earlier scopes
Next: validate #4474's full-unmap retirement and determine whether its successful registry notifications cover this remapping; the sampled backend cause is now map-shared. The latest color stamps are not directly ImportWindow, so #3874 is not confirmed as the solution; an earlier import effect remains possible. Map/unmap retirement (#4474) and fresh-import tracking (#4535) are existing candidates only if the corresponding provenance is established. Preserve the guard until actual contents/lifetime are understood. No duplicate issue or speculative fix. Bring-up #4443 tracks progress; private binaries and captures remain local. AI-assisted: Codex. |
…memory A multisampled target's samples live only in its host image, so a fill of its color memory never reached them: a title that clears its MSAA targets that way (with no CMASK) kept drawing over the previous frame. A uniform fill over the whole color memory now clears the host image to that value at the target's next use, the same way a CMASK fast clear does, and a pending CMASK clear still takes precedence. The color memory is sized with addrlib's block dimensions for the sample count (ComputeThinBlockDimension): a 64 KiB block holds width x height x samples elements, laid out width first for 1x and 4x. A fill over part of it, over a target whose footprint is not computed, or with a value that has no exact clear value in the format throws at the next use. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
0e2219b to
1baf077
Compare
… fill ApplyFastClear took the color fill before the CMASK clear, so a partial fill of a multisampled target's color memory threw at the next use even when a CMASK fast clear was pending over the whole target. The CB reads a cleared tile's color from the clear registers whatever the memory holds, so the CMASK clear is applied and the recorded fill dropped.
|
Pushed one commit on top (e322c6e): |
|
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.
|
What
Follow-up to #419, as discussed there. A multisampled target's samples only live in its host image, so a fill of its color memory never reached them. A title that clears its MSAA targets that way, with no CMASK, kept drawing over the previous frame's contents.
ComputeThinBlockDimension): a block holds width × height × samples elements, so a 4x 8-byte target is 64x32 pixels per 64 KiB block, and 2x/8x lay the block out height first.ClearColorForTexel. It has no layout for sRGB formats, so those go through their UNORM layout and are accepted only when every color channel is 0 or 1, the two codes whose sRGB decode is exact (alpha is linear).MultisampledColorFillnext toMultisampledCmask, so it is tested without a device.PPSA36082
Hades II clears its two 4x targets by filling their color memory with 0: 0x2400000 bytes over a 1536x1536 sRGB 8_8_8_8 target and 0xff0000 bytes over a 960x540 16_16_16_16 float target. Both match the footprints above exactly. On main f145139 with the fixes it needs to get that far plus #419, #2121 and the follow-up for its sample positions, the character was drawn with ghost copies around her and her shadow was broken; with this change both render correctly in gameplay. I tested that in game before moving the fill state into its own class; the behaviour did not change.
Tested
Linux (CachyOS), x86-64, GCC, 7800X3D / RTX 4090.
agc_driver_graphics(new checks):build.ymlrun locally on this head, rebased on main d1fd937 (SPIRV tools on, test registration check, build, libs, ctest): 1003/1004. The one failure,guest_kernel_fcntl, came from my script running ctest with no terminal on stdin; it passes when run from a terminal.Checklist
main; no other open PR implements the same functionsNotImplemented_nid_no_patch); silent stubs are listed in TechnicalDebt.mdfiles or images added to the repository (attach them to this PR)