Repository navigation
feat(agc): emulate PA_SC_AA_MASK sample masks - #6015
Conversation
c7c1e51 to
f1e4dec
Compare
|
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.
|
f1e4dec to
9519b53
Compare
|
GPUs tested: NVIDIA GeForce RTX 3060 12 GB, driver 591.86, Windows Server 2025 (10.0.26100), Ryzen 9 5900X. Build: MinGW GCC 15.2, Release -O3, Commits: PR head
Result lines: Not tested: the kill path without demote on a GPU (this device exposes demote), GTA V, AMD/Intel GPUs, the full ctest suite. AI-assisted: yes |
With one sample, PA_SC_AA_MASK leaves one coverage bit per pixel of the 2x2 quad, so a draw can cover only some pixels of every quad (GTA V renders a target one quarter of the pixels at a time this way). The pixel stage info carries that 4-bit mask; a fragment shader whose mask is not full starts by killing the invocation unless its gl_FragCoord quad position is covered, and runs without early fragment tests. The mask is part of the recompile cache key and the serialized request (version 24). Sample masks of multisampled draws stay refused.
With PA_SC_AA_MASK covering only some pixels of a quad, the uncovered pixels run on the hardware as helper lanes, so derivatives of the covered pixels stay defined. OpKill ends those invocations; OpDemoteToHelperInvocation keeps them as helpers. The device enables VK_EXT_shader_demote_to_helper_invocation when available and passes the DemoteToHelperInvocation capability and its SPIR-V extension to the recompiler target and the graphics shader validation. A demoted pixel also reads as a helper, so its initial EXEC bit is clear as on the hardware. Without demote, OpKill stays for pixel programs that read no neighbouring lanes; implicit-LOD sampling, LOD queries and cross-lane reads are refused. The quad pixel mask execution test now also samples a mipmapped texture with implicit LOD under the mask.
…ask without demote A program that enables whole-quad mode (s_wqm_b64) and then reads a ballot or readfirstlane sees the helper lanes, which OpKill removes.
Decode the four PA_SC_AA_MASK fields at the rasterized sample count. Use the native Vulkan mask when all four pixels agree and apply varying masks in the fragment shader, preserving helpers and combining coverage with alpha-to-coverage and shader mask exports. Add the normalized masks to pipeline, draw and shader keys and the versioned replay request. Refuse unsupported conservative-raster, centroid and early depth/stencil memory-write cases. Synthetic readbacks cover driver submission, depth/stencil suppression, fragment stores and one-sample and four-sample coverage.
ReadFirstLane, Ballot and PermuteU32 can consume uncovered helper lanes after a fragment explicitly enables EXEC. Classify those operations as neighbour reads so a partial quad mask refuses their kill fallback when demote is unavailable. ReadFirstLane also stays protected when a constant whole-quad instruction folds away. The CPU regression covers explicit EXEC, constant WQM, a comparison ballot and ds_permute. Unmasked programs still compile, supported masked programs retain demote and their subgroup operation, and constant colour keeps the kill fallback. The recovered source fails the readfirstlane and ballot checks; the corrected source passes both the focused check and shader-memory suite. Co-Authored-By: Codex <noreply@openai.com>
…n the serializer replays Requests replayed from versions 22 to 24 now re-serialize at version 29 with the default quad pixel mask (0xf) and quad sample masks (0xffff) after the dither and front-face flags, plus the empty linked call fallback list.
9519b53 to
5fd9c80
Compare
|
Rebased onto main (debt entry next to #5631's). A pixel program #5631 skips is replaced by the null pixel program, which applies the quad mask at entry like any other, so the two combine. Thanks @fdfawef324 for the Windows runs. |
What
Emulates
PA_SC_AA_MASK_X0Y0_X1Y0/PA_SC_AA_MASK_X0Y1_X1Y1(one 16-bit sample mask per pixel of the 2x2 quad) instead of refusing the draw withAGC graphics: sample masks are unsupported.pSampleMask.VK_EXT_shader_demote_to_helper_invocation, so derivatives of the covered pixels stay defined); a partial mask is ANDed intogl_SampleMask.OpKillis used only for pixel programs that read no neighbouring lanes; implicit-LOD sampling, LOD queries, whole-quad mode and cross-lane reads (ReadFirstLane,Ballot,PermuteU32) are refused.docs/dev/debt/libSceAgcDriver.md.Carries @MichonGoddijn231849's #448 and @fdfawef324's revision (codex/samplemask-no-demote-review), authorship kept; supersedes #448.
Rebased onto current
main: next tomain's dithered alpha-to-coverage flag (request version 25) andruntimeDescriptorArrayvalidation parameter.Tested
BUILD_TESTING=ON,ANYPS5_ENABLE_SPIRV_TOOLS=ON: allagc_tests (576) and the rest of ctest pass;request_serializerneeded its main-side replays moved to version 29 (last commit). New tests:agc_shader_quad_mask_no_demote,agc_driver_quad_pixel_mask,agc_driver_sample_mask_draw,agc_driver_sample_mask_depth_stencil,agc_driver_sample_mask_multisample.mainStory Mode stops withAGC graphics: sample masks are unsupported. With this PR it gets past that, through the Story Mode loading screen and onto the prologue title card (Ludendorff, North Yankton). The next stop isAGC graphics: CB resolve into a target without a resident image is not implemented, a separate topic.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)