vulkan: Enable midpoint sampling for interleaved 8-bit YCbCr
Vulkan has two sampling modes for down-sampled chroma:
VK_CHROMA_LOCATION_COSITED_EVENspecifies that downsampled chroma samples are aligned with luma samples with even coordinates.
VK_CHROMA_LOCATION_MIDPOINTspecifies that downsampled chroma samples are located half way between each even luma sample and the nearest higher odd luma sample.
For multi-plane formats, we have one
nir_op_tex for luminance and one or two
nir_op_tex for chroma. (Luminance is always in its own plane.)
MIDPOINT sampling is the trivial case here because, with normalized coordinates, the coordinate at the center of the one chroma pixel will naturally lie at the center of the cluster of 2 or 4 Luminance pixels. We handle
COSITED_EVEN by adding a half pixel to the chroma coordinate, thus making it so that when you sample at the center of the upper-left luminance pixel, you get the center of the chroma pixel.
For single-plane interleaved 8-bit YCbCr, i.e.
VK_FORMAT_B8G8R8G8_422_UNORM, we only have a single
nir_op_tex and it's up to the hardware to decide how to sample from chroma vs. luminance. Both Intel and NVIDIA hardware default to
COSITED_EVEN and, indeed, that is the only one which is required by the Vulkan spec. Without a sampler or image descriptor bit to tweak the sampling position, this is all we can get on that hardware in a single
However, it is possible to get
MIDPOINT sampling if we do two texture ops, one for luminance and one for chroma, which both target plane 0. We just have to subtract a quarter pixel from the X coordinate when we sample for chroma. This is a slightly annoying modification to the lowering pass but should be possible. It would allow enabling
MIDPOINT sampling in both NVK and ANV.