mirror of
https://github.com/ARMSX2/ARMSX3.git
synced 2026-08-24 16:58:52 -07:00
Snapdragon Game Super Resolution 1.0, mobile variant: a single-pass edge-directed spatial upscaler Qualcomm wrote for Adreno. Against FSR1 it is one dispatch instead of two and one target instead of two, which is what makes it worth having on a phone -- cheaper, not better. Licensing is the reason this is a reimplementation rather than a port. Suggested by CamilleLaVey, who made the same filter work in Eden, but Eden's glue is GPL-3.0-or-later and RPCS3 is GPL-2.0-ONLY, so none of it is used -- the same blocker that stopped the LSFG adoption, and permission cannot fix it because Eden has other contributors. What IS used is Qualcomm's BSD-3-Clause release, which is GPL-2.0 compatible, with the copyright notice kept. The crop mapping and the widened sharpness range are reimplemented from a description of what they do, which is not copyrightable. Qualcomm ship it as a fragment shader over a fullscreen triangle; this is a compute pass because that is what the VK device layer already schedules. The interpolated texcoord becomes a UV from the invocation id and the fragment output becomes an imageStore, with a bounds check because a dispatch rounds up to whole workgroups. The push constant offsets were read out of the compiled SPIR-V rather than derived from the struct -- 0/8/16/24/32/40, 44 bytes -- because a mismatch there produces garbage that looks exactly like a shader bug. glslc also type-checks the GLSL, which the native build cannot: shaders here are compiled at runtime, so a broken one builds fine and fails on device. No vendor gate, deliberately: its requirements are a strict subset of FSR1's (textureGather with a constant component and no offset, an rgba8 storage image, one descriptor set), so anywhere FSR1 runs, this runs. It no-ops when the frame is already at or above output resolution, which is correct and indistinguishable from broken, so the setting text says so. Wired at all five places the mode is represented: the enum (appended, never inserted -- it is serialised by ordinal in savestates), the fmt_class_string case (a missing one serialises as 'unknown' and the mode is silently never selectable), the VK dispatch, both Kotlin pickers, and the persisted clamp that would otherwise rewrite the new value straight back to FSR.