Re: [PATCH v2 08/34] drm/amd/display: document AMDGPU pre-defined transfer functions

From: Pekka Paalanen
Date: Tue Aug 22 2023 - 07:46:57 EST


On Thu, 10 Aug 2023 15:02:48 -0100
Melissa Wen <mwen@xxxxxxxxxx> wrote:

> Brief documentation about pre-defined transfer function usage on AMD
> display driver and standardized EOTFs and inverse EOTFs.
>
> Co-developed-by: Harry Wentland <harry.wentland@xxxxxxx>
> Signed-off-by: Harry Wentland <harry.wentland@xxxxxxx>
> Signed-off-by: Melissa Wen <mwen@xxxxxxxxxx>
> ---
> .../amd/display/amdgpu_dm/amdgpu_dm_color.c | 39 +++++++++++++++++++
> 1 file changed, 39 insertions(+)
>
> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
> index cc2187c0879a..7f13bcdaf016 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
> @@ -85,6 +85,45 @@ void amdgpu_dm_init_color_mod(void)
> }
>
> #ifdef AMD_PRIVATE_COLOR
> +/* Pre-defined Transfer Functions (TF)
> + *
> + * AMD driver supports pre-defined mathematical functions for transferring
> + * between encoded values and optical/linear space. Depending on HW color caps,
> + * ROMs and curves built by the AMD color module support these transforms.
> + *
> + * The driver-specific color implementation exposes properties for pre-blending
> + * degamma TF, shaper TF (before 3D LUT), and blend(dpp.ogam) TF and
> + * post-blending regamma (mpc.ogam) TF. However, only pre-blending degamma
> + * supports ROM curves. AMD color module uses pre-defined coefficients to build
> + * curves for the other blocks. What can be done by each color block is
> + * described by struct dpp_color_capsand struct mpc_color_caps.
> + *
> + * AMD driver-specific color API exposes the following pre-defined transfer
> + * functions:
> + *
> + * - Linear/Unity: linear/identity relationship between pixel value and
> + * luminance value;

I asked about linear/unity on the previous patch.

> + * - Gamma 2.2, Gamma 2.4, Gamma 2.6: pure gamma functions;

I'd explain these as pure power functions. Gamma function is
something completely different:
https://en.wikipedia.org/wiki/Gamma_function

> + * - sRGB: 2.4 gamma with small initial linear section as standardized by IEC
> + * 61966-2-1:1999;

I'd leave out the mention of "2.4 gamma". Yes, the value of the gamma
parameter is 2.4, but the curve is actually an approximation of the
pure 2.2 power function suitable for integer arithmetic[1].

One could call it "The piece-wise transfer function from IEC ...".

[1] https://www.w3.org/Graphics/Color/sRGB.html

> + * - BT.709 (BT.1886): 2.4 gamma with differences in the dark end of the scale.
> + * Used in HD-TV and standardized by ITU-R BT.1886;

BT.1886 has two more parameters (a.k.a contrast and brightness). What
are their values?

It's also quite different from BT.709 inverse OETF. BT.1886 uses
exponent 2.4 while inverse of BT.709 OETF has exponent approximately
2.22. This difference is intentional and accounts for shooting vs.
viewing environment differences.

Either the curve comes from BT.709 or BT.1886. Which one is it?

Would be nice to spell out the mathematical formula in these cases.

> + * - PQ (Perceptual Quantizer): used for HDR display, allows luminance range
> + * capability of 0 to 10,000 nits; standardized by SMPTE ST 2084.

Right, but since we are working on numbers here,
is the PQ EOTF [0, 1] -> [0, 1] or [0, 10000]?


Thanks,
pq

> + *
> + * In the driver-specific API, color block names attached to TF properties
> + * suggest the intention regarding non-linear encoding pixel's luminance
> + * values. As some newer encodings don't use gamma curve, we make encoding and
> + * decoding explicit by defining an enum list of transfer functions supported
> + * in terms of EOTF and inverse EOTF, where:
> + *
> + * - EOTF (electro-optical transfer function): is the transfer function to go
> + * from the encoded value to an optical (linear) value. De-gamma functions
> + * traditionally do this.
> + * - Inverse EOTF (simply the inverse of the EOTF): is usually intended to go
> + * from an optical/linear space (which might have been used for blending)
> + * back to the encoded values. Gamma functions traditionally do this.
> + */
> static const char * const
> amdgpu_transfer_function_names[] = {
> [AMDGPU_TRANSFER_FUNCTION_DEFAULT] = "Default",