From: Navid Assadian <navid.assad...@amd.com>

[Why]
For subsampled YUV output formats, more pixels can get fetched and be
used for scaling.

[How]
Add the adjustment to the calculated recout, so the viewport covers the
corresponding pixels on the source plane.

Signed-off-by: Navid Assadian <navid.assad...@amd.com>
Reviewed-by: Samson Tam <samson....@amd.com>
---
 drivers/gpu/drm/amd/display/dc/sspl/dc_spl.c  | 31 +++++++++++++++----
 .../drm/amd/display/dc/sspl/dc_spl_types.h    | 10 ++++++
 2 files changed, 35 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/sspl/dc_spl.c 
b/drivers/gpu/drm/amd/display/dc/sspl/dc_spl.c
index 31495c9978b0..72a79288ab79 100644
--- a/drivers/gpu/drm/amd/display/dc/sspl/dc_spl.c
+++ b/drivers/gpu/drm/amd/display/dc/sspl/dc_spl.c
@@ -76,6 +76,21 @@ static struct spl_rect shift_rec(const struct spl_rect 
*rec_in, int x, int y)
        return rec_out;
 }
 
+static void spl_opp_adjust_rect(struct spl_rect *rec, const struct 
spl_opp_adjust *adjust)
+{
+       if ((rec->x + adjust->x) >= 0)
+               rec->x += adjust->x;
+
+       if ((rec->y + adjust->y) >= 0)
+               rec->y += adjust->y;
+
+       if ((rec->width + adjust->width) >= 1)
+               rec->width += adjust->width;
+
+       if ((rec->height + adjust->height) >= 1)
+               rec->height += adjust->height;
+}
+
 static struct spl_rect calculate_plane_rec_in_timing_active(
                struct spl_in *spl_in,
                const struct spl_rect *rec_in)
@@ -723,13 +738,15 @@ static void spl_handle_3d_recout(struct spl_in *spl_in, 
struct spl_rect *recout)
        }
 }
 
-static void spl_clamp_viewport(struct spl_rect *viewport)
+static void spl_clamp_viewport(struct spl_rect *viewport, int 
min_viewport_size)
 {
+       if (min_viewport_size == 0)
+               min_viewport_size = MIN_VIEWPORT_SIZE;
        /* Clamp minimum viewport size */
-       if (viewport->height < MIN_VIEWPORT_SIZE)
-               viewport->height = MIN_VIEWPORT_SIZE;
-       if (viewport->width < MIN_VIEWPORT_SIZE)
-               viewport->width = MIN_VIEWPORT_SIZE;
+       if (viewport->height < min_viewport_size)
+               viewport->height = min_viewport_size;
+       if (viewport->width < min_viewport_size)
+               viewport->width = min_viewport_size;
 }
 
 static enum scl_mode spl_get_dscl_mode(const struct spl_in *spl_in,
@@ -1764,6 +1781,8 @@ static bool spl_calculate_number_of_taps(struct spl_in 
*spl_in, struct spl_scrat
        spl_calculate_recout(spl_in, spl_scratch, spl_out);
        /* depends on pixel format */
        spl_calculate_scaling_ratios(spl_in, spl_scratch, spl_out);
+       /* Adjust recout for opp if needed */
+       spl_opp_adjust_rect(&spl_scratch->scl_data.recout, 
&spl_in->basic_in.opp_recout_adjust);
        /* depends on scaling ratios and recout, does not calculate offset yet 
*/
        spl_calculate_viewport_size(spl_in, spl_scratch);
 
@@ -1800,7 +1819,7 @@ bool spl_calculate_scaler_params(struct spl_in *spl_in, 
struct spl_out *spl_out)
        // Handle 3d recout
        spl_handle_3d_recout(spl_in, &spl_scratch.scl_data.recout);
        // Clamp
-       spl_clamp_viewport(&spl_scratch.scl_data.viewport);
+       spl_clamp_viewport(&spl_scratch.scl_data.viewport, 
spl_in->min_viewport_size);
 
        // Save all calculated parameters in dscl_prog_data structure to 
program hw registers
        spl_set_dscl_prog_data(spl_in, &spl_scratch, spl_out, enable_easf_v, 
enable_easf_h, enable_isharp);
diff --git a/drivers/gpu/drm/amd/display/dc/sspl/dc_spl_types.h 
b/drivers/gpu/drm/amd/display/dc/sspl/dc_spl_types.h
index 467af9dd90de..0130673ceee6 100644
--- a/drivers/gpu/drm/amd/display/dc/sspl/dc_spl_types.h
+++ b/drivers/gpu/drm/amd/display/dc/sspl/dc_spl_types.h
@@ -427,6 +427,14 @@ struct spl_out     {
 
 // SPL inputs
 
+// opp extra adjustment for rect
+struct spl_opp_adjust {
+       int x;
+       int y;
+       int width;
+       int height;
+};
+
 // Basic input information
 struct basic_in        {
        enum spl_pixel_format format; // Pixel Format
@@ -444,6 +452,7 @@ struct basic_in     {
                } num_slices_recout_width;
        } num_h_slices_recout_width_align;
        int mpc_h_slice_index; // previous mpc_combine_v - split_idx
+       struct spl_opp_adjust opp_recout_adjust;
        // Inputs for adaptive scaler - TODO
        enum spl_transfer_func_type tf_type; /* Transfer function type */
        enum spl_transfer_func_predefined tf_predefined_type; /* Transfer 
function predefined type */
@@ -535,6 +544,7 @@ struct spl_in       {
        bool is_hdr_on;
        int h_active;
        int v_active;
+       int min_viewport_size;
        int sdr_white_level_nits;
        enum sharpen_policy sharpen_policy;
 };
-- 
2.34.1

Reply via email to