Skip to content

fix(agc): accept MSAA_ENABLE on a single-sample target sampled at the pixel center - #4309

Merged
oneandonlydean merged 1 commit into
boykopovar:mainfrom
oneandonlydean:up4/fix-2776-msaa-enable-single-sample
Oct 12, 2026
Merged

oneandonlydean merged 1 commit into
boykopovar:mainfrom
oneandonlydean:up4/fix-2776-msaa-enable-single-sample

Conversation

@oneandonlydean

@oneandonlydean oneandonlydean commented Oct 12, 2026 •

Copy link
Copy Markdown
Collaborator

What

Refs #2776. Resident Evil 4 (PPSA07411) stops at scan conversion mode is unsupported (register 0x292 = 0x00000003): PA_SC_MODE_CNTL_0.MSAA_ENABLE (bit 0) with PA_SC_AA_CONFIG.MSAA_NUM_SAMPLES = 0. Since #419 the bit is accepted only with more than one sample. #2169 does not decode sample locations for one sample, so this rule reads sample 0 from the registers.

What the bit does with one sample, from Mesa at 745709a0 (the drivers for this GPU family; nothing here is measured on a console):

  • RADV programs exactly this state, MSAA_ENABLE = 1 with MSAA_NUM_SAMPLES = 0, for one-sample custom sample locations: radv_emit_msaa_state (msaa_enable = rasterization_samples > 1 || enable_1x_user_sample_locs, with the sample count at L13674). The commit that added it, 061bc615, says "Only GFX10+ can support 1x user sample locations, but MSAA_ENABLE needs to be enabled", and RADV advertises one-sample locations from GFX10 (radv_physical_device.c L2161). So with one sample the bit makes the rasterizer sample at the programmed location of sample 0 (S0_X/S0_Y of the four PA_SC_AA_SAMPLE_LOCS_PIXEL_*_0 registers) instead of the pixel center.
  • The common preamble sets PA_SU_SMALL_PRIM_FILTER_CNTL.SC_1XMSAA_COMPATIBLE_DISABLE with the comment "use sample locations even for MSAA 1x" (ac_cmdbuf.c L751-753), and radeonsi writes the one-sample locations as zero, noting that only sample 0 is used (si_state_msaa.c L70-73, L265-270).
  • radeonsi sets the bit from the rasterizer state alone (multisample || poly_smooth || line_smooth, si_state.c L967-971) and the sample count separately (L3373-3382), so the bit with one sample is a state the driver produces.
  • Fields: gfx10.json PA_SC_MODE_CNTL_0.

The sources do not say what the bit does to points, lines (it is also the line and polygon smoothing switch in radeonsi), rectangles, alpha-to-coverage or conservative rasterization with one sample, and they do not state that it changes nothing else for filled triangles; that last part is inferred from RADV drawing one-sample triangles in this state, and is recorded in TechnicalDebt.

The change: with one sample, bit 0 is accepted when sample 0 of all four PA_SC_AA_SAMPLE_LOCS_PIXEL_*_0 registers is (0, 0) (the pixel center, where a draw without the bit samples), the draw rasterizes triangles (triangle list, fan or strip, or triangle output from tessellation or a geometry shader), and alpha-to-coverage and conservative rasterization are off. It then decodes to the same state as without the bit. Each other case throws with its own message naming the register: a sample 0 off the center, points, lines, rectangles, alpha-to-coverage, conservative rasterization. Location registers the title never wrote throw as a missing register, because their value is not known. LINE_STIPPLE_ENABLE and the other bits of the register are refused as before, and the draw precheck applies the same rules.

The issue only gives the value of 0x292, so I do not know whether the title's draw has its sample at the center or draws triangles. @xXPBSXx, once #3737 and #4044 are in, could you run PPSA07411 with this and say whether it gets past this stop, or post the new message if it names another register?

Tested

Linux (CachyOS, GCC, RTX 4090, NVIDIA driver), Release, configured with the CI flags (-DBUILD_TESTING=ON -DANYPS5_ENABLE_SPIRV_TOOLS=ON), on main 2ccbd37 (after #2169):

  • agc_driver_graphics (new MsaaEnableSingleSampleTests): the accepted state decodes like the same registers with bit 0 clear and passes the precheck; a sample 0 off the center in any of the four pixels, a missing location register, alpha-to-coverage, conservative rasterization, lines, rectangles, points (precheck) and LINE_STIPPLE_ENABLE are refused; triangle fans and strips are accepted; without the bit, sample locations and alpha-to-coverage are accepted as before.
  • agc_driver_msaa_enable_single_sample (new): one command buffer draws the same triangle, with an edge through the target, into two color targets, with 0x292 = 2 and 0x292 = 3; the two memories are equal byte for byte and partly covered.
  • Both fail on main with scan conversion mode is unsupported (register 0x292 = 0x00000003) and pass with the change.
  • ctest -R "agc|shader": 442 of 442 pass.
  • python3 tools/check_conventions.py --base origin/main and tools/check_test_registration.py pass.
  • A 2D title we test with: one unattended run to gameplay passes its frame checks, no skipped draws, no GPU errors in the kernel log (run on the previous base, d146ec1; the rebase over feat(agc): support uniform custom MSAA sample locations #2169 did not change this commit's code).

Not tested: PPSA07411 (I do not have the title); a console or an AMD GPU (the behaviour rests on the Mesa sources above); lavapipe and Windows (not installed here; the CI jobs are the test).

Checklist

  • Based on current main; no other open PR implements the same functions
  • One topic per PR; follow-ups go in a new PR
  • No comments in code except technical debt
  • Unimplemented paths throw (NotImplemented_nid_no_patch); silent stubs are listed in TechnicalDebt
  • No notes, investigation .md files or images added to the repository (attach them to this PR)
  • New third-party code is a submodule built from source
  • Generic behaviour, not specific to one title
  • Depends on: none
  • AI-assisted: yes (Claude Code)

@oneandonlydean oneandonlydean self-assigned this Oct 12, 2026
@github-actions github-actions Bot added docs agc libSceAgc* labels Oct 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agc libSceAgc* docs

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant