Repository navigation
fix(agc): accept a min or max reduction sampler with anisotropic filtering - #5821
adriadam10 merged 2 commits into
Conversation
|
Thanks for picking this up. I ran your change (applied on my local High on Life stack, with one log line per min/max+anisotropic S# decoded) through the home base, the house, a portal trip and Blim City: about 15 minutes, warm caches. No min/max+anisotropic S# was decoded at all. Looking back, the stop I listed on #5156 happened exactly once: on 2026-10-12, in a run with an experimental "store pending results at labels" switch on an older So High on Life doesn't need this PR as far as I can tell, and it shouldn't be counted as evidence for it. The change still stands on its own: RADV programs the same S#, and the gfx1030 measurement on #5156 covers the result. Sorry for the false lead. Tested and written by Claude (AI assistant) on a contributor's machine. |
|
Thanks for checking, and for being upfront about where that stop came from. With no title known to reach this sampler, I'm closing this under the current queue rule; the branch stays, so it can be reopened with a title ID and log line if one turns up. |
|
Correction to my comment above: on another run from the same save, the title does decode one, during the loading screen into the home base:
With your change it was accepted and the load continued. That run then stopped later in the same load on an unrelated check ("buffer descriptor uses an unsupported type"), so I can't confirm the full home base on that run yet. But this is a real High on Life S#, and it needs this PR. The earlier run that never decoded it simply didn't hit it. Sorry for the back and forth. Tested and written by Claude (AI assistant) on a contributor's machine. |
|
Reopening, since the S# turned up after all. Thanks for the second run, @Tamalero. I've pinned your exact words ( |
|
Follow-up, and I'd now discount the High on Life case. More runs with your change logged the same S# three times:
Words 1–3 never change, but word 0 is different every time and always looks like the low dword of a guest address ( In the same kind of pixel shader, my local "bind invalid T#s as null" workaround also had to null an invalid T# just before one of the captures. So in High on Life this looks like a descriptor read before it is valid, or from the wrong source, rather than a real min/max+anisotropic sampler. I wouldn't use it as evidence for this PR. The change still stands on RADV's behaviour and the gfx1030 measurement, and I'll look into where that word 0 comes from separately. Apologies for the earlier back-and-forth. Tested and written by Claude (AI assistant) on a contributor's machine. |
|
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.
|
…ering A guest S# with FILTER_MODE min or max and an anisotropic XY filter threw "combines a min or max reduction with anisotropic filtering", which stops High on Life (PPSA15388) in its home base. It now decodes to a Vulkan sampler with both anisotropy and the reduction mode, as a weighted-average anisotropic S# already does. RADV programs the same S# for such a Vulkan sampler. Tamalero's gfx1030 measurement on boykopovar#5156 covers a sample without derivatives through a 2x anisotropic S# over a single-level texture: min or max with anisotropic bilinear returns the bilinear minimum or maximum, and min with anisotropic point the point result. The execution test checks the bilinear case on the host GPU; the debt entry records what is not measured. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude <noreply@anthropic.com>
|
Checked on RDNA2 (gfx1035,
|
b63087f to
17ed121
Compare
|
@adriadam10 Thanks for the gfx1035 measurements and the debt entry! I've updated the description to match: no title claim, and your results credited. |
|
On an RTX 4090 (NVIDIA 616.92, Windows 11 26200, MinGW-w64 GCC 15.2.0 r7, Release) 2 of 2 runs, same value. The other 47 AI-assisted: yes (Claude Code). |
|
@frankea Thanks for running it on the 4090! That row is a test problem, not a decoder one. The two anisotropic rows sample a two-level texture at explicit LOD 0.25 and 0.75 through a point mip filter, and expect only the nearest level. At thread 0 (LOD 0.25), level 0's bilinear footprint is 17, 17, 20 and 20, and level 1 there is 5, so the 4090 reads level 1 with anisotropy on. Vulkan leaves the anisotropic scheme to the implementation and only says it should consider This change samples those rows without a mip filter. The decoder then gives the host sampler - Run(*device, {ReductionMin, FilterAnisoBilinear, MipPoint, Aniso2x}, "min, 2x anisotropic bilinear, point mip");
- Run(*device, {ReductionMax, FilterAnisoBilinear, MipPoint, Aniso2x}, "max, 2x anisotropic bilinear, point mip");
+ Run(*device, {ReductionMin, FilterAnisoBilinear, MipNone, Aniso2x}, "min, 2x anisotropic bilinear, no mip");
+ Run(*device, {ReductionMax, FilterAnisoBilinear, MipNone, Aniso2x}, "max, 2x anisotropic bilinear, no mip");It passes 5 of 5 on an RTX 3050 Ti (580.178.04) and on lavapipe, with and without a local change that gives the host sampler a linear mip filter under anisotropy. On the 3050 Ti that local change reproduces your exact 5.000000 on AI Assisted |
|
@SandstromPL it passes. RTX 4090 (NVIDIA 616.92), Windows 11 26200, MinGW-w64 GCC 15.2.0 r7, Release,
Go ahead with the fix(test) PR; happy to run it again once it's up. AI-assisted: yes (Claude Code). |
What
GuestSamplerResource.cpprefused an S# that combines a min or max reduction with anisotropic filtering:Tamalero first listed it on #5156 for High on Life (PPSA15388). The S# captured there later turned out to be a descriptor read before it was valid: word 0 changes from capture to capture, and one capture has ratio field 6 (Tamalero on this PR). So no title is known to reach this path.
The decoder now accepts an S# that has
FILTER_MODEmin or max together with an anisotropic XY filter (2 or 3). It becomes a Vulkan sampler with bothanisotropyEnableand the reduction mode, as a weighted-average anisotropic S# already does. RADV (Mesa 25.0.7'sradv_init_sampler, as mirrored in OpenBSD's xenocara) programs exactly this S# for such a Vulkan sampler:FILTER_MODEcomes from the reduction mode;ANISO_POINTorANISO_BILINEARwhenever the anisotropy is above 1;MAX_ANISO_RATIOcomes frommaxAnisotropy;So on AMD this is the hardware filter.
These still throw:
PointFilteredSamplerWordrefuses it with "needs point filtering".Measured on RDNA2, not on the console:
tools/hw-oracle): one sample without derivatives through a 2x anisotropic S# over a single-level texture. Min or max with anisotropic bilinear returns exactly the bilinear minimum or maximum, and min with anisotropic point the point result.tools/hw-oracle):image_sample_lz, min and max with anisotropic point and anisotropic bilinear at ratio fields 0-4 return the point result or the bilinear minimum or maximum.image_sample_dand a 4:1 footprint, anisotropic bilinear at ratio fields 2 and 4 reduces over all the anisotropic taps, which is what the Vulkan sampler gets on RADV.The debt entry records these results.
Vulkan also leaves nearest filtering with anisotropy to the implementation ("Texel Anisotropic Filtering"), so on other host GPUs an anisotropic point S# follows the host driver.
The existing min/max format check still applies at bind time.
VUID-vkCmdDraw-magFilter-09598andVUID-vkCmdDispatch-magFilter-09598requireSAMPLED_IMAGE_FILTER_MINMAXwhen the filter is linear. So an anisotropic bilinear sampler needs it, like any bilinear min/max sampler, and an anisotropic point sampler doesn't.Tested
Ubuntu 24.04, GCC 13.3, Release with
BUILD_TESTING=ON, onmaine736e5b, which includes #5156. Locally, the libusb lines were removed fromCMakeLists.txt, because the libusb submodule isn't checked out here.agc_driver_graphics(tests/GuestSamplerResource.cpp) replaced its expected refusal with decode checks. They cover min and max, each with anisotropic point (2) and anisotropic bilinear (3), at ratio field 2. Each must:anisotropyEnable,maxAnisotropy4 and its reduction mode;vkCreateSamplerwith the reduction mode chained, anisotropy enabled andmaxAnisotropy4;It also checks two existing refusals, which pass on
maintoo:PointFilteredSamplerWord.On
mainit fails with the message above.agc_driver_image_sample_reduction(tests/execution/ImageSampleReduction.cpp) gains min and max samplers with 2x anisotropic bilinear filtering and a point mip filter. They use the existing explicit-LODimage_sample_lrows. With aLodoperand Vulkan sets the derivatives to zero, so the sample is isotropic. Every thread must read exactly the bilinear minimum or maximum the existing bilinear rows expect. Anisotropic point has no execution row, since its result is up to the driver.On
mainthe test fails at the first anisotropic sampler with the message above. With the change it passes 5 runs out of 5 on each GPU below, as doesagc_driver_graphics. Under the Khronos validation layer, neither GPU reports anything for the samplers or dispatches. The one message is an existingvkCreateDevicewarning about a structure newer than the layer.Other checks:
cteston the RTX 3050 Ti: 1,138 of 1,140 pass, 7 of them skipping themselves, includingagc_driver_stencil_ref_exporton this GPU.guest_usbdandpatched_librariesare not built here, because the libusb submodule isn't checked out.GuestSamplerResource.cppreverted and pass with it, and that the libSceAgcDriver suite is green.GuestSamplerResource.cpp, its test and the debt file; this is rebased onto it. 35 open PRs touch these four files, 20 of which already conflict withmain; none of them gets a new conflict.tools/check_conventions.pyfrommainpasses with this title and body.@Tamalero, thanks for the measurement and for the captures. @adriadam10, thanks for the gfx1035 run and the debt entry.
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