Repository navigation
fix(agc): read a multisampled target's CMASK by its MSAA codes - #6669
Conversation
|
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.
|
|
Independent component check of #5939 + #6543 + this PR, on main Merge: composition 13ed9df uses #5939 guard(context, use, created.active, created.metadataValid);
if (use.cmaskFastClear && use.dccAddress == 0) created.cmask.SeedCode(CurrentUniformMetadataByte(use.cmaskAddress, static_cast<std::size_t>(use.cmaskBytes)));Windows: full application/libs build, library/convention/test-registration checks pass. Five repetitions each of CPU groups Small optional test addition: 036b7f0 adds only seven lines to the existing graphics fixture. It enumerates all 256 byte values, expecting 00 as clear, cc/dd/ee/ff as expanded and the other 251 inputs as unmodeled. Its patch also applies cleanly to your original The expanded fixture passed five Windows processes, failed five times at input 204/0xcc with a narrowed-classification control, then passed five times after restoring the exact positive head. The control retains the new reader/API and only narrows expanded recognition back to ff; it is not unmodified main. This checks the proposed classifier contract, not hardware semantics for every possible CMASK state. Linux: at test head Cppcheck 2.20.0 then clang-tidy 23.1.3 completed for This confirms the component combination and preserves the DCC exclusion; it does not independently reproduce Ruffle, Rush 2, Wave Race or Sonic. The resident-target/metadata-write refusal is unchanged. AI-assisted validation/test/report: yes. |
|
Windows cross-check on Ruffle (PPSA68091), Cross pressed at 8, 11 and 14 s ("Play the demo"):
So your Linux table reproduces on Windows/NVIDIA. With both, the demo's presents match Tests: The head moved to Not checked: this PR without #6543 on a title, AMD or Intel, Linux, the full GPU Written with Claude Code assistance (validation by a subagent, reviewed in this session). |
|
Thanks @screamm, good to have the Ruffle result on Windows too. I added it to the description. AI-assisted: yes |
c8950bb to
8455a5c
Compare
|
Rebased onto AI-assisted: yes (Claude Code) |
|
Rechecked on head
Not checked: this PR alone, AMD/Intel, Linux. Written with Claude Code assistance (validation by a subagent, reviewed in this session). |
A multisampled color target with a CMASK fast clear seeds its state from
the CMASK when it is first used, and later fills of the CMASK update it.
Both read the bytes as DCC keys: 0x00 is a clear, 0xff uncompressed, and
anything else refuses ("reads as mixed"). But an MSAA CMASK nibble is
FMASK code | color code << 2 (Mesa ac_descriptors.h CMASK_MSAA_CODE), so
0xcc (FMASK cleared to fragment 0, color expanded), and the 2x and 4x
"FMASK uncompressed, color expanded" codes 0xdd and 0xee, are states with
no pending fast clear that were refused. Ruffle (PPSA68091) clears its
target's CMASK to 0xcc every frame and stopped on the refusal whenever
that clear landed before the target's first use.
The seed now reads the uniform CMASK byte (after pending writes, like the
key read) and both paths classify it by those codes: 0x00 (register color
clear, FMASK cleared) is the fast clear as before, any color-expanded code
(0xc to 0xf in both nibbles) is "no fast clear", and other codes, or bytes
that differ, are still refused.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
8455a5c to
c660ed5
Compare
|
Checked the MSAA CMASK nibble classification against Mesa's |
What
A multisampled color target with a CMASK fast clear (
CB_COLOR_INFO.FAST_CLEAR) seeds its CMASK state when it is first used, and fills of its CMASK update it later.mainreads those bytes as DCC keys:0x00is a fast clear,0xffis uncompressed, and anything else is refused:An MSAA CMASK nibble is not a DCC key, though. It is
fmask | color << 2(MesaCMASK_MSAA_CODE):main0x00FMASK_CLEAR_0_COLOR_CLEAR_REG0xccFMASK_CLEAR_0_COLOR_EXPANDED0xdd,0xeeFMASK_UNCOMPRESSED_COLOR_EXPANDED0xffFMASK_UNCOMPRESSED_COLOR_EXPANDEDSo a CMASK whose color is expanded, with no fast clear pending, is refused unless it happens to be the 8x code. The host image of a multisampled target starts cleared to zero. A uniform fill of its color memory can give it a clear value, but it never reads other guest color data. "No fast clear" is therefore what
0xffalready does, whatever the FMASK code.Ruffle (PPSA68091) clears its target's CMASK to
0xccevery frame, with a compute dispatch. Onmainthat dispatch is address-based, so the target's first use usually reads the CMASK before the clear has landed, sees zeros and runs. When the clear landed first, it stopped on the line above, in 2 of my 6 earlier sweep runs on oldermainbuilds (11 to 12 s in). #6543 runs that kernel as a buffer fill, so the clear is always ordered before the read, and Ruffle then stops there every time.The seed now reads the uniform CMASK byte, after pending writes as the key read does (
CurrentUniformMetadataByte). The seed and CMASK fills both classify it withMultisampledCmaskKeys.Tested
Linux (Ubuntu 24.04, GCC 13.3, Release), RTX 4070 Ti, NVIDIA 595.99.
agc_driver_graphics: seeds and whole-CMASK fills of0xcc,0xdd,0xeeand0xffgive no fast clear,0x00still clears once, and0x11,0x33,0x44,0x88,0xcd, an uneven pattern and an unknown (mixed) seed are refused. Withmain's fill classification the test fails ona fill of the CMASK ... with 0xcccccccc leaves its tiles mixed. It passes 3 of 3 with this change.^agc_driver_|^agc_vertex_barrier|recompiler|shader_cache|request_serializer|spirv, 469 tests), with this change plus a local match of the same fill kernel, which I'm not opening since fix(agc): take RADV's fill-memory kernel as a buffer fill #6543 has it: 468 pass.agc_driver_store_over_untrackedfails the same way onmain5d9dcc4; test(agc): keep waiting for the neighbour copy case's result #6385 addresses it.Ruffle (PPSA68091), 60 s with scripted pad input, three runs each:
main5d9dcc42fc4fe5e0)@Amoenus checked this PR together with #5939 and #6543 on
main5d9dcc4. The one conflict, inMultisampleTarget::acquire, resolves by keeping #5939's guard argument and DCC exclusion along with this PR's raw CMASK reader. On Windows they ran the MSAA DCC, fill and sample tests on an RTX 5080 (610.62) and an AMD Radeon iGPU, 70 processes passing, and on Linux with llvmpipe 20 processes passing. Their test commit, c8950bb (cherry-picked with their authorship), enumerates all 256 uniform CMASK bytes: 00 is a clear, cc/dd/ee/ff are expanded, and the other 251 are unmodeled. It passes 3 of 3 here.@screamm reproduced the Ruffle table on Windows (RTX 4070, NVIDIA 596.21) with #6543 on
main5d9dcc4.mainruns to the 125 s limit 3 of 3. With #6543, Ruffle stops 2 of 2 on the CMASK line as the demo starts. With #6543 and this PR, 2 of 2 run to the limit. vkQuake (PPSA99010) with both also runs to the limit 2 of 2. The tests pass 3 of 3, and fail withMultisampledCmaskKeysset back tomain's codes.Update after #5939 merged: Ruffle's target carries DCC, so on current
mainthe title stops earlier, as the demo starts, on #5939'smultisampled DCC CMASK compression or register clear is not implemented. That happens with or without this PR, and the seed this PR changes (dccAddress == 0) is not reached. @screamm's recheck on Windows shows this. So the Ruffle table above predates #5939 and no longer applies; theagc_driver_graphicsandagc_driver_covered_centroid_statechecks above still cover the change, and pass 3 of 3 there.Not checked on Intel or on a console.
#5939 changes the seed line, adding a DCC condition, and #6215 changes the lines next to it. Whichever lands second needs a small rebase.
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)main(Ruffle stops earlier since feat(agc): import uniform multisampled DCC fast clears #5939; see Tested)🤖 Generated with Claude Code