mirror of
https://github.com/torvalds/linux.git
synced 2026-10-16 04:39:02 +02:00
drm/amd/display: Fix mem_type change detection for async flips
[Why] amdgpu_dm_crtc_mem_type_changed() fetches the "old" and "new" plane state with two drm_atomic_get_plane_state() calls, which both return the new state. It compares a state against itself, so it never detects a mem_type change and never rejects the async flip. On DCN 3.0.1, this shows up as intermittent corruption when a single DCC plane is scanned out with immediate flips under gamescope and its buffer moves between the VRAM carveout and GTT. [How] Use drm_atomic_get_old_plane_state() and drm_atomic_get_new_plane_state() to compare the actual old and new states. These return NULL rather than an error pointer for a plane that is not part of the commit, so the IS_ERR() check becomes a NULL check that skips those planes, such as an unmodified cursor still in the CRTC's plane_mask. Fixes:4caacd1671("drm/amd/display: Do not elevate mem_type change to full update") Reviewed-by: Harry Wentland <harry.wentland@amd.com> Reviewed-by: Melissa Wen <mwen@igalia.com> Signed-off-by: Matthew Schwartz <matthew.schwartz@linux.dev> Signed-off-by: Alex Deucher <alexander.deucher@amd.com> (cherry picked from commit13158e5dbd)
This commit is contained in:
parent
40f9e2f514
commit
8e792f018e
|
|
@ -12938,13 +12938,11 @@ static bool amdgpu_dm_crtc_mem_type_changed(struct drm_device *dev,
|
|||
struct drm_plane_state *new_plane_state, *old_plane_state;
|
||||
|
||||
drm_for_each_plane_mask(plane, dev, crtc_state->plane_mask) {
|
||||
new_plane_state = drm_atomic_get_plane_state(state, plane);
|
||||
old_plane_state = drm_atomic_get_plane_state(state, plane);
|
||||
new_plane_state = drm_atomic_get_new_plane_state(state, plane);
|
||||
old_plane_state = drm_atomic_get_old_plane_state(state, plane);
|
||||
|
||||
if (IS_ERR(new_plane_state) || IS_ERR(old_plane_state)) {
|
||||
drm_err(dev, "Failed to get plane state for plane %s\n", plane->name);
|
||||
return false;
|
||||
}
|
||||
if (!old_plane_state || !new_plane_state)
|
||||
continue;
|
||||
|
||||
if (old_plane_state->fb && new_plane_state->fb &&
|
||||
get_mem_type(old_plane_state->fb) != get_mem_type(new_plane_state->fb))
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user