Repository navigation
Conversation
Draws into a color target with CB_COLOR_INFO FAST_CLEAR (bit 13) were rejected. The CMASK keeps one nibble per 8x8 tile: 0 means the tile is fast-cleared and reads as CB_COLOR_CLEAR_WORD, 0xF means expanded (the texels hold the color). The texture units and display scanout do not read it, so a title runs a fast-clear eliminate pass before sampling or flipping such a target. DecodeColorBuffer now takes the CMASK address (CB_COLOR0_CMASK and CB_COLOR0_CMASK_BASE_EXT) and the bytes one nibble per 8x8 tile spans. Before a draw renders into the target, and in a fast-clear eliminate pass, a CMASK whose nibbles are all 0 is materialized: the target is filled with the clear texel (FillClear on its resident image, else guest memory on the CPU) and the CMASK bytes are stored as expanded, through the same GPU-ordered store as the DCC "uncompressed" keys (0xFF either way). The result equals the draw followed by the eliminate pass. An all-expanded CMASK changes nothing; a mixed one throws, as do fast clears of DCC, mipmapped, 3D and array targets. PPSA14632 (LEGO Horizon Adventures) fast-clears its two 3840x2160 display buffers through CMASK, so its final composite draw was dropped on every frame and only black was presented. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A color target with both DCC and CB_COLOR_INFO.FAST_CLEAR keeps its fast clear in the DCC keys and fills its CMASK with 0xF (expanded), as radv does (radv_get_cmask_fast_clear_value) and as PPSA21567 does (CB_COLOR_INFO 0x10042730, reported on boykopovar#419). Such targets now decode; their clear is materialized by the existing DCC path. A DCC target's CMASK that is not all expanded throws. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A CMASK holds 4 KiB per 1024x512-pixel metablock, not one nibble per 8x8 tile of the target: 1920x1080 spans 0x6000 bytes, as titles clear it, not 16200. The swizzled nibbles of the lower-right tiles lie past the packed size, so the fast-clear check missed them and the expanded store left them cleared. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Thanks. The sizes match an independent model of the CMASK as 4 KiB metablocks of 128x64 tiles: 0x1000 for 800x450, 0x2000 for 960x544, 0x6000 for 1920x1080. This is being tested now on top of @alfalfa-star, if testing passes, the plan is to merge #1072 first and then this PR, so #1072 closes as merged. After that, #788 and #1073 will need a rebase. I'll post the results here. |
With the CMASK sized by whole metablocks, the check covers the swizzled nibbles past the packed size, and titles that partly draw over a fast-cleared target now show a mixed CMASK where the packed check saw a uniform one. Refusing those draws drops them; the target is drawn as it is instead, and only an all-cleared CMASK is materialized. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Please drop |
|
Closing: the CMASK metablock sizing ( 🤖 Generated with Claude Code |
What
Follow-up to #1072. The branch contains #1072's two commits; only the last commit (
fix(agc): size CMASK by whole 1024x512 metablocks) is new.#1072 takes a target's CMASK as one nibble per 8x8 tile, packed (
(tiles + 1) / 2bytes). The CMASK is actually laid out in 4 KiB metablocks of 128x64 tiles (1024x512 pixels), and the nibble addresses are swizzled within them. For 1920x1080 it spans 2x3 metablocks = 0x6000 bytes, not 16200. The nibbles of the lower-right tiles lie past the packed size, so:A title that reads its CMASK back then sees those tiles as never drawn.
CmaskBytes(width, height)(State) returnsceil(w / 1024) * ceil(h / 512) * 4096, andDecodeColorBufferuses it forColorTarget::cmaskBytes.cmaskTestsCMASK is one metablock (4096 bytes). The mixed case sets the last byte. New checks cover the sizes for 1920x1080, 960x544, 800x450, 1024x512 and 3840x2160.[gpu] CMASK of color target 0x… is mixed … left as it is), so logs show when a title relies on this. Only an all-cleared CMASK is materialized, as before. The fast-cleared tiles of a mixed CMASK keep their stale texels, and the TechnicalDebt line says so.cmaskTestsnow checks that a mixed CMASK leaves both the texels and the CMASK unchanged.The size matches every CMASK clear PPSA23566 (UFC 6) issues, for 8, 16 and 64 bpp color formats. The title fills each CMASK with a compute fill of exactly this many bytes before using it:
CmaskBytesThe metablock size also follows from the title's own CMASK reader. Its address equation takes tile x >> 7 and tile y >> 6 as the metablock coordinates and steps 0x2000 nibbles per metablock.
Tested
Windows 11, MinGW, NVIDIA RTX (Vulkan).
PPSA23566 (UFC 6) reads its UI target's CMASK in a compute pass to build a per-tile mask of where the UI was drawn. The composite blends the UI only on those tiles. With the packed size, 210 of 4050 mask words were missing bits:
With this change all 4050 words are set and the splash renders cleanly. That run also includes the host-import fix from fix(agc): retire host imports of ranges mapped again #1235, which the title needs to read the CMASK at all.
ctest: 383 of 383 pass, includingagc_driver_graphicswith the new size checks.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)🤖 Generated with Claude Code