Degamma has always been on the plane on AMD. CRTC DEGAMMA_LUT has actually just been applying it to every plane pre-blend.<br><br>Degamma makes no sense after blending anyway.<br>The entire point is for it to happen before blending to blend in linear space. Otherwise DEGAMMA_LUT and REGAMMA_LUT are the exact same thing...<br><br>- Joshie 🐸<br><br>On Tuesday, 22 August 2023, Pekka Paalanen <<a href="mailto:pekka.paalanen@collabora.com">pekka.paalanen@collabora.com</a>> wrote:<br>> On Thu, 10 Aug 2023 15:02:59 -0100<br>> Melissa Wen <<a href="mailto:mwen@igalia.com">mwen@igalia.com</a>> wrote:<br>><br>>> The next patch adds pre-blending degamma to AMD color mgmt pipeline, but<br>>> pre-blending degamma caps (DPP) is currently in use to provide DRM CRTC<br>>> atomic degamma or implict degamma on legacy gamma. Detach degamma usage<br>>> regarging CRTC color properties to manage plane and CRTC color<br>>> correction combinations.<br>>><br>>> Reviewed-by: Harry Wentland <<a href="mailto:harry.wentland@amd.com">harry.wentland@amd.com</a>><br>>> Signed-off-by: Melissa Wen <<a href="mailto:mwen@igalia.com">mwen@igalia.com</a>><br>>> ---<br>>>  .../amd/display/amdgpu_dm/amdgpu_dm_color.c   | 59 +++++++++++++------<br>>>  1 file changed, 41 insertions(+), 18 deletions(-)<br>>><br>>> 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<br>>> index 68e9f2c62f2e..74eb02655d96 100644<br>>> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c<br>>> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c<br>>> @@ -764,20 +764,9 @@ int amdgpu_dm_update_crtc_color_mgmt(struct dm_crtc_state *crtc)<br>>>       return 0;<br>>>  }<br>>> <br>>> -/**<br>>> - * amdgpu_dm_update_plane_color_mgmt: Maps DRM color management to DC plane.<br>>> - * @crtc: amdgpu_dm crtc state<br>>> - * @dc_plane_state: target DC surface<br>>> - *<br>>> - * Update the underlying dc_stream_state's input transfer function (ITF) in<br>>> - * preparation for hardware commit. The transfer function used depends on<br>>> - * the preparation done on the stream for color management.<br>>> - *<br>>> - * Returns:<br>>> - * 0 on success. -ENOMEM if mem allocation fails.<br>>> - */<br>>> -int amdgpu_dm_update_plane_color_mgmt(struct dm_crtc_state *crtc,<br>>> -                                   struct dc_plane_state *dc_plane_state)<br>>> +static int<br>>> +map_crtc_degamma_to_dc_plane(struct dm_crtc_state *crtc,<br>>> +                          struct dc_plane_state *dc_plane_state)<br>>>  {<br>>>       const struct drm_color_lut *degamma_lut;<br>>>       enum dc_transfer_func_predefined tf = TRANSFER_FUNCTION_SRGB;<br>>> @@ -800,8 +789,7 @@ int amdgpu_dm_update_plane_color_mgmt(struct dm_crtc_state *crtc,<br>>>                                                &degamma_size);<br>>>               ASSERT(degamma_size == MAX_COLOR_LUT_ENTRIES);<br>>> <br>>> -             dc_plane_state->in_transfer_func->type =<br>>> -                     TF_TYPE_DISTRIBUTED_POINTS;<br>>> +             dc_plane_state->in_transfer_func->type = TF_TYPE_DISTRIBUTED_POINTS;<br>>> <br>>>               /*<br>>>                * This case isn't fully correct, but also fairly<br>>> @@ -837,7 +825,7 @@ int amdgpu_dm_update_plane_color_mgmt(struct dm_crtc_state *crtc,<br>>>                                  degamma_lut, degamma_size);<br>>>               if (r)<br>>>                       return r;<br>>> -     } else if (crtc->cm_is_degamma_srgb) {<br>>> +     } else {<br>>>               /*<br>>>                * For legacy gamma support we need the regamma input<br>>>                * in linear space. Assume that the input is sRGB.<br>>> @@ -847,8 +835,43 @@ int amdgpu_dm_update_plane_color_mgmt(struct dm_crtc_state *crtc,<br>>> <br>>>               if (tf != TRANSFER_FUNCTION_SRGB &&<br>>>                   !mod_color_calculate_degamma_params(NULL,<br>>> -                         dc_plane_state->in_transfer_func, NULL, false))<br>>> +                                                     dc_plane_state->in_transfer_func,<br>>> +                                                     NULL, false))<br>>>                       return -ENOMEM;<br>>> +     }<br>>> +<br>>> +     return 0;<br>>> +}<br>>> +<br>>> +/**<br>>> + * amdgpu_dm_update_plane_color_mgmt: Maps DRM color management to DC plane.<br>>> + * @crtc: amdgpu_dm crtc state<br>>> + * @dc_plane_state: target DC surface<br>>> + *<br>>> + * Update the underlying dc_stream_state's input transfer function (ITF) in<br>>> + * preparation for hardware commit. The transfer function used depends on<br>>> + * the preparation done on the stream for color management.<br>>> + *<br>>> + * Returns:<br>>> + * 0 on success. -ENOMEM if mem allocation fails.<br>>> + */<br>>> +int amdgpu_dm_update_plane_color_mgmt(struct dm_crtc_state *crtc,<br>>> +                                   struct dc_plane_state *dc_plane_state)<br>>> +{<br>>> +     bool has_crtc_cm_degamma;<br>>> +     int ret;<br>>> +<br>>> +     has_crtc_cm_degamma = (crtc->cm_has_degamma || crtc->cm_is_degamma_srgb);<br>>> +     if (has_crtc_cm_degamma){<br>>> +             /* AMD HW doesn't have post-blending degamma caps. When DRM<br>>> +              * CRTC atomic degamma is set, we maps it to DPP degamma block<br>>> +              * (pre-blending) or, on legacy gamma, we use DPP degamma to<br>>> +              * linearize (implicit degamma) from sRGB/BT709 according to<br>>> +              * the input space.<br>><br>> Uhh, you can't just move degamma before blending if KMS userspace<br>> wants it after blending. That would be incorrect behaviour. If you<br>> can't implement it correctly, reject it.<br>><br>> I hope that magical unexpected linearization is not done with atomic,<br>> either.<br>><br>> Or maybe this is all a lost cause, and only the new color-op pipeline<br>> UAPI will actually work across drivers.<br>><br>><br>> Thanks,<br>> pq<br>><br>>> +              */<br>>> +             ret = map_crtc_degamma_to_dc_plane(crtc, dc_plane_state);<br>>> +             if (ret)<br>>> +                     return ret;<br>>>       } else {<br>>>               /* ...Otherwise we can just bypass the DGM block. */<br>>>               dc_plane_state->in_transfer_func->type = TF_TYPE_BYPASS;<br>><br>>