From dc8e8920035f0d471584938f6d9ec55c6bb82532 Mon Sep 17 00:00:00 2001 From: Nicholas Kazlauskas Date: Fri, 18 Jan 2019 13:17:55 -0500 Subject: [PATCH 1265/2940] drm/amd/display: Fix wrong z-order when updating overlay planes [Why] If a commit updates an overlay plane via the legacy plane IOCTL then the only plane in the state will be the overlay plane. Overlay planes need to be added first to the DC context, but in the scenario above the plane will be added last. This will result in wrong z-order during rendering. [How] If any non-cursor plane has been updated then the rest of the non-cursor planes should be added to the CRTC state. The cursor plane doesn't need to be included for stream updates and locking it will cause performance issues. It should be ignored. DC requires that the surface count passed during stream updates be the number of surfaces currently on the stream to enable fast updates. This previously wasn't the case without this patch, so this also allows this optimization to occur. Signed-off-by: Nicholas Kazlauskas Reviewed-by: Leo Li Acked-by: Tony Cheng --- .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 3cc42a882d36..93042b12c934 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -6065,6 +6065,42 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev, goto fail; } + /* + * Add all primary and overlay planes on the CRTC to the state + * whenever a plane is enabled to maintain correct z-ordering + * and to enable fast surface updates. + */ + drm_for_each_crtc(crtc, dev) { + bool modified = false; + + for_each_oldnew_plane_in_state(state, plane, old_plane_state, new_plane_state, i) { + if (plane->type == DRM_PLANE_TYPE_CURSOR) + continue; + + if (new_plane_state->crtc == crtc || + old_plane_state->crtc == crtc) { + modified = true; + break; + } + } + + if (!modified) + continue; + + drm_for_each_plane_mask(plane, state->dev, crtc->state->plane_mask) { + if (plane->type == DRM_PLANE_TYPE_CURSOR) + continue; + + new_plane_state = + drm_atomic_get_plane_state(state, plane); + + if (IS_ERR(new_plane_state)) { + ret = PTR_ERR(new_plane_state); + goto fail; + } + } + } + /* Remove exiting planes if they are modified */ for_each_oldnew_plane_in_state_reverse(state, plane, old_plane_state, new_plane_state, i) { ret = dm_update_plane_state(dc, state, plane, -- 2.17.1