Files
AnyPS5/docs/dev
Yunus Shaikh 2cd0c9107a fix(recompiler): run a pixel shader the guest does not iterate once per pixel
The ancillary input's sample number (bits 11:8) was the SampleId
builtin in every pixel shader. Vulkan enables sample shading for a
shader that uses SampleId, so a shader that reads the sample field or
the whole ancillary word ran once per sample on a multisampled draw
even when the guest runs it once per pixel (PS_ITER_SAMPLE clear), and
FragCoord, and with it POS_X_FLOAT and POS_Y_FLOAT, moved to the
sample. The sample number is now SampleId only when the request says
the guest iterates the shader, and otherwise 0, the iterated sample
number of a pixel the hardware does not iterate.

The other inputs that depend on the sample follow where the console
evaluates them:
- PERSP_SAMPLE and LINEAR_SAMPLE are interpolated with
  InterpolateAtOffset at sample 0's offset in a shader the guest does
  not iterate, and in an iterated one at the offset of the host's
  SampleId, read from a table of the guest's locations, because Vulkan
  leaves plain barycentrics under sample shading at an
  implementation-defined position (lavapipe uses the pixel centre).
- PERSP_CENTER and LINEAR_CENTER are interpolated at offset 0 in an
  iterated shader.
- POS_X_FLOAT and POS_Y_FLOAT follow SPI_BARYC_CNTL: the centre is
  floor(FragCoord) + 0.5 under sample shading, a sample position in a
  shader the guest does not iterate is the centre plus sample 0's
  offset, and POS_FLOAT_ULC gives the upper-left corner.

The offsets need InterpolationFunction (sampleRateShading) and the
fragment-shader barycentric path; devices without them keep the host's
default positions. The shader disk cache format goes to 39.
2026-10-15 16:06:38 +00:00
..