Module: Mesa
Branch: main
Commit: 4a48896a0d2981ca45bd88e7c16a17377952dda7
URL:    
http://cgit.freedesktop.org/mesa/mesa/commit/?id=4a48896a0d2981ca45bd88e7c16a17377952dda7

Author: Agate, Jesse <jesse.ag...@amd.com>
Date:   Thu Nov 30 13:27:19 2023 -0500

amd/vpelib: White Screen Fix

- Observed white screen after changing edp display brightness and
  resizing video.
- Root cause: ogam sequence was not being updated when 3dlut
  transition from disabled->enabled.

Reviewed-by: Roy Chan <roy.c...@amd.com>
Acked-by: Alan Liu <haoping....@amd.com>
Signed-off-by: Jesse Agate <jesse.ag...@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/26841>

---

 src/amd/vpelib/src/core/color.c | 160 ++++++++++++++++++++++++----------------
 1 file changed, 97 insertions(+), 63 deletions(-)

diff --git a/src/amd/vpelib/src/core/color.c b/src/amd/vpelib/src/core/color.c
index fdf95ccae10..a1d7399d512 100644
--- a/src/amd/vpelib/src/core/color.c
+++ b/src/amd/vpelib/src/core/color.c
@@ -370,7 +370,7 @@ static bool color_update_input_cs(struct vpe_priv 
*vpe_priv, enum color_space in
     return true;
 }
 
-/* This function generates software points for the blnd gam and ogam 
programming blocks.
+/* This function generates software points for the blnd gam programming block.
    The logic for the blndgam/ogam programming sequence is a function of:
    1. Output Range (Studio Full)
    2. 3DLUT usage
@@ -392,87 +392,113 @@ static bool color_update_input_cs(struct vpe_priv 
*vpe_priv, enum color_space in
          OGAM    : L -> NL
 
 */
- 
-static bool vpe_update_output_gamma_sequence(struct vpe_priv *vpe_priv,
-    const struct vpe_build_param *param)
+
+static enum vpe_status vpe_update_blnd_gamma(
+    struct vpe_priv                 *vpe_priv,
+    const struct vpe_build_param    *param,
+    const struct vpe_tonemap_params *tm_params,
+    struct transfer_func            *blnd_tf)
 {
 
-    struct stream_ctx       *stream_ctx;
-    struct output_ctx       *output_ctx;
+    struct output_ctx *output_ctx;
     struct vpe_color_space   tm_out_cs;
-    struct fixed31_32        x_scale;
-    struct fixed31_32        y_scale;
-    struct fixed31_32        y_bias;
-    enum vpe_status          status;
-    bool                     is_studio;
+    struct fixed31_32        x_scale       = vpe_fixpt_one;
+    struct fixed31_32        y_scale       = vpe_fixpt_one;
+    struct fixed31_32        y_bias        = vpe_fixpt_zero;
+    bool                     is_studio     = false;
     bool                     can_bypass    = false;
     bool                     lut3d_enabled = false;
+    enum color_space         cs            = COLOR_SPACE_2020_RGB_FULLRANGE;
+    enum color_transfer_func tf            = TRANSFER_FUNC_LINEAR_0_1;
+    enum vpe_status          status        = VPE_STATUS_OK;
 
-
-    status   = VPE_STATUS_OK;
-    x_scale  = vpe_fixpt_one;
-    y_bias   = vpe_fixpt_zero;
-    y_scale  = vpe_fixpt_one;
     is_studio = (param->dst_surface.cs.range == VPE_COLOR_RANGE_STUDIO);
+    output_ctx = &vpe_priv->output_ctx;
+    lut3d_enabled = tm_params->enable_3dlut;
 
     if (is_studio) {
 
         if (vpe_is_rgb8(param->dst_surface.format)) {
             y_scale = STUDIO_RANGE_SCALE_8_BIT;
-            y_bias  = STUDIO_RANGE_FOOT_ROOM_8_BIT;
-        } else {
+            y_bias = STUDIO_RANGE_FOOT_ROOM_8_BIT;
+        }
+        else {
+
             y_scale = STUDIO_RANGE_SCALE_10_BIT;
-            y_bias  = STUDIO_RANGE_FOOT_ROOM_10_BIT;
+            y_bias = STUDIO_RANGE_FOOT_ROOM_10_BIT;
         }
     }
 
-    output_ctx = &vpe_priv->output_ctx;
-
-    for (uint32_t stream_idx = 0; stream_idx < param->num_streams; 
stream_idx++) {
-
-        enum color_space         cs;
-        enum color_transfer_func tf = TRANSFER_FUNC_LINEAR_0_1;
-
-        stream_ctx    = &vpe_priv->stream_ctx[stream_idx];
-        lut3d_enabled = stream_ctx->enable_3dlut;
-
-        //If SDR out -> Blend should be NL
-        //If studio out -> No choice but to blend in NL
-        if (!vpe_is_HDR(output_ctx->tf) || is_studio) {
-            if (lut3d_enabled) {
-                tf = TRANSFER_FUNC_LINEAR_0_1;
-            }
-            else {
-                tf = output_ctx->tf;
-            }
-
-            color_update_regamma_tf(vpe_priv,
-                tf,
-                x_scale,
-                y_scale,
-                y_bias,
-                can_bypass,
-                stream_ctx->blend_tf);
+    //If SDR out -> Blend should be NL
+    //If studio out -> No choice but to blend in NL
+    if (!vpe_is_HDR(output_ctx->tf) || is_studio) {
+        if (lut3d_enabled) {
+            tf = TRANSFER_FUNC_LINEAR_0_1;
         }
         else {
+            tf = output_ctx->tf;
+        }
 
-            if (lut3d_enabled) {
-                vpe_color_build_tm_cs(&stream_ctx->stream.tm_params, 
param->dst_surface, &tm_out_cs);
-                vpe_color_get_color_space_and_tf(&tm_out_cs, &cs, &tf);
-            }
-            else {
-                can_bypass = true;
-            }
+        color_update_regamma_tf(vpe_priv,
+            tf,
+            x_scale,
+            y_scale,
+            y_bias,
+            can_bypass,
+            blnd_tf);
+    }
+    else {
 
-            color_update_degamma_tf(vpe_priv,
-                tf,
-                x_scale,
-                y_scale,
-                y_bias,
-                can_bypass,
-                stream_ctx->blend_tf);
+        if (lut3d_enabled) {
+            vpe_color_build_tm_cs(tm_params, param->dst_surface, &tm_out_cs);
+            vpe_color_get_color_space_and_tf(&tm_out_cs, &cs, &tf);
         }
+        else {
+            can_bypass = true;
+        }
+
+        color_update_degamma_tf(vpe_priv,
+            tf,
+            x_scale,
+            y_scale,
+            y_bias,
+            can_bypass,
+            blnd_tf);
     }
+    return status;
+}
+
+/* This function generates software points for the ogam gamma programming 
block.
+   The logic for the blndgam/ogam programming sequence is a function of:
+   1. Output Range (Studio Full)
+   2. 3DLUT usage
+   3. Output format (HDR SDR)
+
+   SDR Out or studio range out
+      TM Case
+         BLNDGAM : NL -> NL*S + B
+         OGAM    : Bypass
+      Non TM Case
+         BLNDGAM : L -> NL*S + B
+         OGAM    : Bypass
+   Full range HDR Out
+      TM Case
+         BLNDGAM : NL -> L
+         OGAM    : L -> NL
+      Non TM Case
+         BLNDGAM : Bypass
+         OGAM    : L -> NL
+
+*/
+static enum vpe_status vpe_update_output_gamma(
+    struct vpe_priv              *vpe_priv,
+    const struct vpe_build_param *param,
+    struct transfer_func         *output_tf)
+{
+    bool               can_bypass = false;
+    struct output_ctx *output_ctx = &vpe_priv->output_ctx;
+    bool               is_studio  = (param->dst_surface.cs.range == 
VPE_COLOR_RANGE_STUDIO);
+    enum vpe_status    status     = VPE_STATUS_OK;
 
     if (vpe_is_HDR(output_ctx->tf) && !is_studio)
         can_bypass = false; //Blending is done in linear light so ogam needs 
to handle the regam
@@ -485,7 +511,7 @@ static bool vpe_update_output_gamma_sequence(struct 
vpe_priv *vpe_priv,
         vpe_fixpt_one,
         vpe_fixpt_zero,
         can_bypass,
-        output_ctx->output_tf);
+        output_tf);
 
     return status;
 }
@@ -684,12 +710,20 @@ enum vpe_status vpe_color_update_color_space_and_tf(
                 status = vpe_color_update_gamut(vpe_priv, stream_ctx->cs, 
output_ctx->cs,
                     stream_ctx->gamut_remap, 
stream_ctx->stream.tm_params.enable_3dlut);
             }
+
+            
+            if (output_ctx->dirty_bits.transfer_function ||
+                output_ctx->dirty_bits.color_space ||
+                stream_ctx->update_3dlut) {
+                vpe_update_blnd_gamma(vpe_priv, param, 
&stream_ctx->stream.tm_params, stream_ctx->blend_tf);
+            }
         }
 
         if (status == VPE_STATUS_OK) {
             if (output_ctx->dirty_bits.transfer_function ||
-                output_ctx->dirty_bits.color_space)
-                vpe_update_output_gamma_sequence(vpe_priv, param);
+                output_ctx->dirty_bits.color_space) {
+                vpe_update_output_gamma(vpe_priv, param, 
output_ctx->output_tf);
+            }
         }
 
     }

Reply via email to