On 2023-09-25 15:49, Melissa Wen wrote: > Brief documentation about pre-defined transfer function usage on AMD > display driver and standardized EOTFs and inverse EOTFs. > > v3: > - Document BT709 OETF (Pekka) > - Fix description of sRGB and pure power funcs (Pekka) > > 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 d03bdb010e8b..14f9c02539c6 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; > + * - Gamma 2.2, Gamma 2.4, Gamma 2.6: pure power functions; > + * - sRGB: 2.4: The piece-wise transfer function from IEC 61966-2-1:1999; > + * - BT.709: has a linear segment in the bottom part and then a power function > + * with a 0.45 (~1/2.22) gamma for the rest of the range; standardized by > + * ITU-R BT.709-6; > + * - PQ (Perceptual Quantizer): used for HDR display, allows luminance range > + * capability of 0 to 10,000 nits; standardized by SMPTE ST 2084. > + * I think it's important to highlight that the AMD color model is designed with an assumption that SDR (sRGB, BT.709, G2.2, etc.) peak white maps (normalized to 1.0 FP) to 80 nits in the PQ system. This has the implication that PQ EOTF (NL-to-L) maps to [0.0..125.0]. 125.0 = 10,000 nits / 80 nits I think we'll want table or some other way describing this: (Using L to mean linear and NL to mean non-linear.) == sRGB, BT709, Gamma 2.x == NL form is either UNORM or [0.0, 1.0] L form is [0.0, 1.0] Note that HDR multiplier can wide range beyond [0.0, 1.0]. In practice this means that PQ TF is needed for any subsequent L-to-NL transforms. == PQ == NL form is either UNORM or FP16 CCCS (Windows canonical composition color space, see [1]) L form is [0.0, 125.0] == Unity, Default == NL form is either UNORM or FP16 CCCS L form is either [0.0, 1.0] (mapping from UNORM) or CCCS (mapping from CCCS FP16) Harry > + * 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",