From: Nicholas Kazlauskas Date: Fri, 18 Jan 2019 18:17:55 +0000 (-0500) Subject: drm/amd/display: Fix wrong z-order when updating overlay planes X-Git-Url: http://git.lede-project.org./?a=commitdiff_plain;h=2d9e64317e3ab6e751d7bc10ad9839d3fd7a5efa;p=openwrt%2Fstaging%2Fblogic.git 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 Signed-off-by: Alex Deucher --- 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 c7b66fa4a13e..409e603a3686 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -5948,6 +5948,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,