## 15.5. Derivative Operations

SPIR-V derivative instructions include `OpDPdx`, `OpDPdy`, `OpDPdxFine`, `OpDPdyFine`, `OpDPdxCoarse`, and `OpDPdyCoarse`. Derivative instructions are only available in a fragment shader.

Derivatives are computed as if there is a 2x2 neighborhood of fragments for each fragment shader invocation. These neighboring fragments are used to compute derivatives with the assumption that the values of P in the neighborhood are piecewise linear. It is further assumed that the values of P in the neighborhood are locally continuous, therefore derivatives in non-uniform control flow are undefined.

\begin{align*} dPdx_{i_1,j_0} & = dPdx_{i_0,j_0} & = P_{i_1,j_0} - P_{i_0,j_0} \\ dPdx_{i_1,j_1} & = dPdx_{i_0,j_1} & = P_{i_1,j_1} - P_{i_0,j_1} \\ \\ dPdy_{i_0,j_1} & = dPdy_{i_0,j_0} & = P_{i_0,j_1} - P_{i_0,j_0} \\ dPdy_{i_1,j_1} & = dPdy_{i_1,j_0} & = P_{i_1,j_1} - P_{i_1,j_0} \end{align*}

The `Fine` derivative instructions must return the values above, for a group of fragments in a 2x2 neighborhood. Coarse derivatives may return only two values. In this case, the values should be:

\begin{align*} dPdx & = \begin{cases} dPdx_{i_0,j_0} & \textrm{preferred}\\ dPdx_{i_0,j_1} \end{cases} \\ dPdy & = \begin{cases} dPdy_{i_0,j_0} & \textrm{preferred}\\ dPdy_{i_1,j_0} \end{cases} \end{align*}

`OpDPdx` and `OpDPdy` must return the same result as either `OpDPdxFine` or `OpDPdxCoarse` and either `OpDPdyFine` or `OpDPdyCoarse`, respectively. Implementations must make the same choice of either coarse or fine for both `OpDPdx` and `OpDPdy`, and implementations should make the choice that is more efficient to compute.