Repository navigation
fix(agc): sample a multisampled texture no draw rendered to from its uniform color memory - #5445
Conversation
|
A title case for this PR: SONIC SUPERSTARS (PPSA06888) samples a multisampled texture no draw has rendered to, and with this PR it stops on the tile mode: Setup: Windows 11, MinGW-w64 GCC 15, Release, AMD Radeon RX 5700 XT. Base: Merging this PR onto the current #4820 conflicts in targets().push_back(std::make_unique<MultisampleTarget>(context, use));
auto& created = *targets().back();
guard(context, use, created.active);The lookup loop also needs #4820's AI-assisted (Claude Code). |
|
Another title for the same stop: DAVE THE DIVER (PPSA19115, 01.041.000) stops here too, with tile mode 4 ( Composition:
AI-assisted: yes |
…uniform color memory A multisampled texture whose surface no draw has rendered to was refused. Its samples are the guest color memory, so when that memory repeats one 32-bit value over the surface's footprint, the host target is created and cleared to the color the value encodes, and a later draw into the surface reuses it. Memory that does not repeat one value, an unmodeled footprint and a value with no exact clear color keep throwing. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…rge with main Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Claude <noreply@anthropic.com>
|
#4820 is on main now, so I replayed this PR's own commit (0f3f690) on top of it and pushed the result. What I added:
Checked on the rebased tree: build and the AGC tests ( Not covered, as the PR says: titles that stop on tile mode 4 ( |
556890f to
f093cf4
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.
|
What
Follow-up to #4820. Sampling a multisampled texture (T# type 14) whose surface no draw has rendered to threw
sampling the WxH multisampled texture ..., which no draw rendered to, is not implemented. No host target exists for such a surface, so its samples are whatever the guest colour memory holds.Now, when that memory repeats one 32-bit value over the surface's footprint (
MultisampledColorBytes), the host multisample target is created from the T# (address, extent, format, samples, tile mode), cleared to the colour the value encodes (MultisampledFillClearColor, through the same pendingMultisampledColorFilla fill of an existing target uses) and bound. A later draw into the surface finds that target (sameTarget) and keeps its contents. Recorded GPU writes over the range are flushed before the memory is read (GuestMemory::FlushGpuWrites).Still thrown, each with its own message:
Standard4KB,Standard64KB,RenderTarget);Limit worth knowing: the footprint includes the padding up to whole tile blocks. A title that stores a non-zero colour only into the pixels inside the extent leaves the padding different, and that still throws.
Where the case comes from: ProsperoPuzzles clears a 4x canvas on the CPU and resolves it with a shader without drawing into it. Its GL driver is public (blackbearreloaded/ps5-opengl,
ps5_clear_msaa4_colorinsrc/gallium/ps5/ps5_screen.c, read at a519561): it stores the packed colour into every sample of every pixel through the mapped memory. In the run that stopped, no fill HLE, no DMA packet and no draw touched the surface before the sample, and the first 0x40000 bytes of its colour memory were all zero.Tested
Windows 11, MinGW-w64 GCC 15.2, NVIDIA GeForce RTX 4070 Laptop GPU. Not tested on Linux or on a console.
maindacd785):ctest -j 8, 1106 tests, 0 failed, 8 skipped (agc_driver_stencil_ref_exportand seven video-out tests).python tools/check_conventions.py --base origin/mainpasses.agc_driver_sample_multisample_target(extended): a 16x16 RGBA16F 4x surface no draw rendered to loads zeros from zeroed memory and ones from memory storing half-float ones, at every sample of every pixel, through a guest compute shader; a triangle drawn into the second surface afterwards leaves ones in the samples it does not cover; memory with one differing word at the end of the footprint is refused. With the change reverted the test fails at the first load with the old refusal. Removing only the pending fill makes the load of ones fail (zeros loaded); disabling only the uniformity check makes the refusal check fail. The check after the later draw was not mutated separately.agc_multisample_guest_access: the refusal of a linear multisampled texture no draw rendered to now expects the tile-mode message.main0214069), from a save with a 2048 game in progress, it stopped at the refusal above in three runs (after 19 s and 24 s in the two that were timed). With this branch merged with perf(agc): present and keep pending only the drawn slice of an array color target #4935 (2e1ef43c0, local only) it ran 45 s from that save until killed in two runs, with no refusal in its log; its driver loggedclear-msaa4-colortwice in each and the title created 48 canvases. From a clean state it ran 40 s with no refusal.Not covered: CPU writes to a multisampled surface after its host target exists are still not seen by the host (as on
main).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)🤖 Generated with Claude Code