The matrix for Zero Tangent Cardinal weights at https://docs.vulkan.org/spec/latest/chapters/textures.html#textures-texel-cubic-filtering is incorrect.
It is given as:
[ 0 2 0 0]
[-2 0 2 0]
[ 4 -4 2 -2]
[-2 2 -2 1]
But the following Python code which calculates the weights at α=0 and α=1:
import numpy as np
M = np.array([[0, 2, 0, 0], [-2, 0, 2, 0], [4, -4, 2, -2], [-2, 2, -2, 1]])
a = 0
print(0.5 * np.array([1, a, a**2, a**3]) @ M)
a = 1
print(0.5 * np.array([1, a, a**2, a**3]) @ M)
gives
[0. 1. 0. 0.]
[0. 0. 1. -0.5]
which shows that there is a discontinuity in the interpolation... the second value should instead be [0. 0. 1. 0.].
In practice this means that with a conformant implementation, sampling from a texture with a solid colour C would not produce a constant result, but rather one varying between C/2 and C, which is undesired for texture filtering.
From implementing cubic filtering myself (using multiple texture fetches instead of the extension), and trying different possibilities, I think that the correct matrix might be this:
[ 0 2 0 0]
[-2 0 2 0]
[ 4 -4 2 -2]
[-2 2 -2 2]
I do not know whether shipping drivers/hardware uses incorrect weights, or if the problem is only in the documentation, since I only have X1-85 (so A7xx) Adreno hardware, and it seems that configurable cubic filtering weights were introduced with A8xx.
The matrix for Zero Tangent Cardinal weights at https://docs.vulkan.org/spec/latest/chapters/textures.html#textures-texel-cubic-filtering is incorrect.
It is given as:
But the following Python code which calculates the weights at α=0 and α=1:
gives
which shows that there is a discontinuity in the interpolation... the second value should instead be
[0. 0. 1. 0.].In practice this means that with a conformant implementation, sampling from a texture with a solid colour C would not produce a constant result, but rather one varying between C/2 and C, which is undesired for texture filtering.
From implementing cubic filtering myself (using multiple texture fetches instead of the extension), and trying different possibilities, I think that the correct matrix might be this:
I do not know whether shipping drivers/hardware uses incorrect weights, or if the problem is only in the documentation, since I only have X1-85 (so A7xx) Adreno hardware, and it seems that configurable cubic filtering weights were introduced with A8xx.