[PATCH 08/22] drm/amd/display: support plane clip with zero recout size

Tom Chung chiahsuan.chung at amd.com
Wed Aug 2 06:51:18 UTC 2023


From: Wenjing Liu <wenjing.liu at amd.com>

[why]
If plane clip is outside current pipe's ODM slice rect, our logic will
fail validation because we assume that when a pipe is acquired
to support a plane clip, it must blend some portion of the plane
on the screen. This assumption needs to be changed.
When a pipe is acquired to render the plane, we are now allowing
it to support a case where it can take minimum viewport and draw
with zero recout size when the plane clip is outside current ODM
slice rect. The reason is that we want to allocate and get the pipe
pre-programmed so it is ready to be rendered when user moves
the plane over to the current ODM slice with a fast update.
Whereas with the existing solution when user moves the plane
over, we will need to allocate a pipe as needed and power it up
and program it through a full update. This not only impacts the
user experience with unnecessary delay of a frame but also
doesn't generate any benefit to the user because DML doesn't
support it. DML will invalidate based on worst case scenario and
it doesn't depend on the plane location. So having our
programming sequence support such dynamic pipe allocation is
not meaningful anyway.

[how]
In build scaler params allow recout to be zero size and if viewport
is smaller than minimum, set minimum viewport size.

Reviewed-by: Jun Lei <jun.lei at amd.com>
Acked-by: Tom Chung <chiahsuan.chung at amd.com>
Signed-off-by: Wenjing Liu <wenjing.liu at amd.com>
---
 .../gpu/drm/amd/display/dc/core/dc_resource.c | 57 +++++++++++--------
 1 file changed, 33 insertions(+), 24 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
index d0f4b86cadf1..ea09830a649c 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
@@ -1157,15 +1157,23 @@ static void calculate_recout(struct pipe_ctx *pipe_ctx)
 			pipe_ctx, &plane_clip);
 	odm_slice = calculate_odm_slice_in_timing_active(pipe_ctx);
 	overlapping_area = intersect_rec(&mpc_slice_of_plane_clip, &odm_slice);
-	/* shift the overlapping area so it is with respect to current ODM
-	 * slice's position
-	 */
-	pipe_ctx->plane_res.scl_data.recout = shift_rec(
-			&overlapping_area,
-			-odm_slice.x, -odm_slice.y);
+	if (overlapping_area.height > 0 &&
+			overlapping_area.width > 0) {
+		/* shift the overlapping area so it is with respect to current
+		 * ODM slice's position
+		 */
+		pipe_ctx->plane_res.scl_data.recout = shift_rec(
+				&overlapping_area,
+				-odm_slice.x, -odm_slice.y);
+		adjust_recout_for_visual_confirm(
+				&pipe_ctx->plane_res.scl_data.recout,
+				pipe_ctx);
+	} else {
+		/* if there is no overlap, zero recout */
+		memset(&pipe_ctx->plane_res.scl_data.recout, 0,
+				sizeof(struct rect));
+	}
 
-	adjust_recout_for_visual_confirm(&pipe_ctx->plane_res.scl_data.recout,
-			pipe_ctx);
 }
 
 static void calculate_scaling_ratios(struct pipe_ctx *pipe_ctx)
@@ -1292,6 +1300,7 @@ static void calculate_inits_and_viewports(struct pipe_ctx *pipe_ctx)
 	struct rect recout_dst_in_active_timing;
 	struct rect recout_clip_in_active_timing;
 	struct rect recout_clip_in_recout_dst;
+	struct rect overlap_in_active_timing;
 	struct rect odm_slice = calculate_odm_slice_in_timing_active(pipe_ctx);
 	int vpc_div = (data->format == PIXEL_FORMAT_420BPP8
 				|| data->format == PIXEL_FORMAT_420BPP10) ? 2 : 1;
@@ -1301,11 +1310,16 @@ static void calculate_inits_and_viewports(struct pipe_ctx *pipe_ctx)
 			&data->recout, odm_slice.x, odm_slice.y);
 	recout_dst_in_active_timing = calculate_plane_rec_in_timing_active(
 			pipe_ctx, &plane_state->dst_rect);
-	recout_clip_in_recout_dst = shift_rec(&recout_clip_in_active_timing,
-			-recout_dst_in_active_timing.x,
-			-recout_dst_in_active_timing.y);
-	ASSERT(recout_clip_in_recout_dst.x >= 0 &&
-			recout_clip_in_recout_dst.y >= 0);
+	overlap_in_active_timing = intersect_rec(&recout_clip_in_active_timing,
+			&recout_dst_in_active_timing);
+	if (overlap_in_active_timing.width > 0 &&
+			overlap_in_active_timing.height > 0)
+		recout_clip_in_recout_dst = shift_rec(&overlap_in_active_timing,
+				-recout_dst_in_active_timing.x,
+				-recout_dst_in_active_timing.y);
+	else
+		memset(&recout_clip_in_recout_dst, 0, sizeof(struct rect));
+
 	/*
 	 * Work in recout rotation since that requires less transformations
 	 */
@@ -1487,17 +1501,12 @@ bool resource_build_scaling_params(struct pipe_ctx *pipe_ctx)
 			pipe_ctx->plane_res.scl_data.recout.x += pipe_ctx->plane_res.scl_data.recout.width;
 	}
 
-	if (!pipe_ctx->stream->ctx->dc->config.enable_windowed_mpo_odm) {
-		if (pipe_ctx->plane_res.scl_data.viewport.height < MIN_VIEWPORT_SIZE ||
-				pipe_ctx->plane_res.scl_data.viewport.width < MIN_VIEWPORT_SIZE)
-			res = false;
-	} else {
-		/* Clamp minimum viewport size */
-		if (pipe_ctx->plane_res.scl_data.viewport.height < MIN_VIEWPORT_SIZE)
-			pipe_ctx->plane_res.scl_data.viewport.height = MIN_VIEWPORT_SIZE;
-		if (pipe_ctx->plane_res.scl_data.viewport.width < MIN_VIEWPORT_SIZE)
-			pipe_ctx->plane_res.scl_data.viewport.width = MIN_VIEWPORT_SIZE;
-	}
+	/* Clamp minimum viewport size */
+	if (pipe_ctx->plane_res.scl_data.viewport.height < MIN_VIEWPORT_SIZE)
+		pipe_ctx->plane_res.scl_data.viewport.height = MIN_VIEWPORT_SIZE;
+	if (pipe_ctx->plane_res.scl_data.viewport.width < MIN_VIEWPORT_SIZE)
+		pipe_ctx->plane_res.scl_data.viewport.width = MIN_VIEWPORT_SIZE;
+
 
 	DC_LOG_SCALER("%s pipe %d:\nViewport: height:%d width:%d x:%d y:%d  Recout: height:%d width:%d x:%d y:%d  HACTIVE:%d VACTIVE:%d\n"
 			"src_rect: height:%d width:%d x:%d y:%d  dst_rect: height:%d width:%d x:%d y:%d  clip_rect: height:%d width:%d x:%d y:%d\n",
-- 
2.25.1



More information about the amd-gfx mailing list