summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
diff options
context:
space:
mode:
authorWenjing Liu <wenjing.liu@amd.com>2023-07-20 11:47:55 -0400
committerAlex Deucher <alexander.deucher@amd.com>2023-08-07 17:14:08 -0400
commite75b965e9aacb53ed30fadb5bed7f92fb75fe9f4 (patch)
treeaa465b33028966b923683554adf5936e5fa275b0 /drivers/gpu/drm/amd/display/dc/core/dc_resource.c
parent4a30cc2bd281fa176a68b5305cd3695d636152ad (diff)
drm/amd/display: support plane clip with zero recout size
[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@amd.com> Acked-by: Tom Chung <chiahsuan.chung@amd.com> Signed-off-by: Wenjing Liu <wenjing.liu@amd.com> Tested-by: Daniel Wheeler <daniel.wheeler@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/amd/display/dc/core/dc_resource.c')
-rw-r--r--drivers/gpu/drm/amd/display/dc/core/dc_resource.c57
1 files 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",