From: Thomas Zimmermann <tzimmermann@suse.de>
To: mripard@kernel.org, maarten.lankhorst@linux.intel.com,
airlied@redhat.com, airlied@gmail.com, simona@ffwll.ch,
admin@kodeit.net, gargaditya08@proton.me, paul@crapouillou.net,
jani.nikula@linux.intel.com, mhklkml@zohomail.com,
zack.rusin@broadcom.com, bcm-kernel-feedback-list@broadcom.com,
harry.wentland@amd.com, sunpeng.li@amd.com, siqueira@igalia.com,
alexander.deucher@amd.com, rodrigo.vivi@intel.com,
joonas.lahtinen@linux.intel.com, tursulin@ursulin.net,
javierm@redhat.com, dmitry.osipenko@collabora.com,
gurchetansingh@chromium.org, olvaffe@gmail.com
Cc: dri-devel@lists.freedesktop.org, linux-hyperv@vger.kernel.org,
intel-gfx@lists.freedesktop.org, intel-xe@lists.freedesktop.org,
linux-mips@vger.kernel.org, virtualization@lists.linux.dev,
amd-gfx@lists.freedesktop.org,
Thomas Zimmermann <tzimmermann@suse.de>
Subject: [PATCH v5 11/15] drm/damage-helper: Test src coord in drm_atomic_helper_check_plane_damage()
Date: Wed, 10 Jun 2026 17:18:27 +0200 [thread overview]
Message-ID: <20260610152505.260172-12-tzimmermann@suse.de> (raw)
In-Reply-To: <20260610152505.260172-1-tzimmermann@suse.de>
Planes require a full update if the source coordinates change across
atomic commits. Evaluate this during the atomic-check and set the flag
ignore_damage_clips in the plane state, if so. Remove the check from
drm_atomic_helper_damage_iter_init().
This will help with removing the old state from the atomic-commit phase
and simplify atomic_update helpers a bit.
Several unit tests check against the change of the src coordinate. Drop
them as they do no longer serve a purpose. If the src coordinate changes
across commits, atomic helpers will set the plane state's
ignore_damage_clips flag, for which a separate unit test exists.
Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Reviewed-by: Javier Martinez Canillas <javierm@redhat.com>
Acked-by: Zack Rusin <zack.rusin@broadcom.com>
---
drivers/gpu/drm/drm_atomic_helper.c | 2 +-
drivers/gpu/drm/drm_damage_helper.c | 20 ++-
.../gpu/drm/tests/drm_damage_helper_test.c | 151 ------------------
include/drm/drm_damage_helper.h | 3 +-
4 files changed, 15 insertions(+), 161 deletions(-)
diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
index d9cb9b3f8490..9c95fbc978fc 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -1070,7 +1070,7 @@ drm_atomic_helper_check_planes(struct drm_device *dev,
}
for_each_oldnew_plane_in_state(state, plane, old_plane_state, new_plane_state, i) {
- drm_atomic_helper_check_plane_damage(state, new_plane_state);
+ drm_atomic_helper_check_plane_damage(state, old_plane_state, new_plane_state);
}
return ret;
diff --git a/drivers/gpu/drm/drm_damage_helper.c b/drivers/gpu/drm/drm_damage_helper.c
index 945fac8dc27b..f492a59edbeb 100644
--- a/drivers/gpu/drm/drm_damage_helper.c
+++ b/drivers/gpu/drm/drm_damage_helper.c
@@ -55,7 +55,8 @@ static void convert_clip_rect_to_rect(const struct drm_clip_rect *src,
/**
* drm_atomic_helper_check_plane_damage - Verify plane damage on atomic_check.
* @state: The driver state object.
- * @plane_state: Plane state for which to verify damage.
+ * @old_plane_state: Old plane state to verify against.
+ * @new_plane_state: Plane state for which to verify damage.
*
* This helper function makes sure that damage from plane state is discarded
* for full modeset. If there are more reasons a driver would want to do a full
@@ -67,19 +68,23 @@ static void convert_clip_rect_to_rect(const struct drm_clip_rect *src,
* &drm_plane_state.src as damage.
*/
void drm_atomic_helper_check_plane_damage(struct drm_atomic_commit *state,
- struct drm_plane_state *plane_state)
+ const struct drm_plane_state *old_plane_state,
+ struct drm_plane_state *new_plane_state)
{
struct drm_crtc_state *crtc_state;
- if (plane_state->crtc) {
+ if (!drm_rect_equals(&new_plane_state->src, &old_plane_state->src))
+ new_plane_state->ignore_damage_clips = true;
+
+ if (new_plane_state->crtc) {
crtc_state = drm_atomic_get_new_crtc_state(state,
- plane_state->crtc);
+ new_plane_state->crtc);
if (WARN_ON(!crtc_state))
return;
if (drm_atomic_crtc_needs_modeset(crtc_state))
- plane_state->ignore_damage_clips = true;
+ new_plane_state->ignore_damage_clips = true;
}
}
EXPORT_SYMBOL(drm_atomic_helper_check_plane_damage);
@@ -204,7 +209,7 @@ EXPORT_SYMBOL(drm_atomic_helper_dirtyfb);
/**
* drm_atomic_helper_damage_iter_init - Initialize the damage iterator.
* @iter: The iterator to initialize.
- * @old_state: Old plane state for validation.
+ * @old_state: Unused, pass NULL.
* @state: Plane state from which to iterate the damage clips.
*
* Initialize an iterator, which clips plane damage
@@ -241,8 +246,7 @@ drm_atomic_helper_damage_iter_init(struct drm_atomic_helper_damage_iter *iter,
iter->plane_src.x2 = (src.x2 >> 16) + !!(src.x2 & 0xFFFF);
iter->plane_src.y2 = (src.y2 >> 16) + !!(src.y2 & 0xFFFF);
- if (!iter->clips || state->ignore_damage_clips ||
- !drm_rect_equals(&state->src, &old_state->src)) {
+ if (!iter->clips || state->ignore_damage_clips) {
iter->clips = NULL;
iter->num_clips = 0;
iter->full_update = true;
diff --git a/drivers/gpu/drm/tests/drm_damage_helper_test.c b/drivers/gpu/drm/tests/drm_damage_helper_test.c
index 64f038a62ffe..ef931497baf9 100644
--- a/drivers/gpu/drm/tests/drm_damage_helper_test.c
+++ b/drivers/gpu/drm/tests/drm_damage_helper_test.c
@@ -155,45 +155,6 @@ static void drm_test_damage_iter_no_damage_fractional_src(struct kunit *test)
check_damage_clip(test, &clip, 3, 3, 1028, 772);
}
-static void drm_test_damage_iter_no_damage_src_moved(struct kunit *test)
-{
- struct drm_damage_mock *mock = test->priv;
- struct drm_atomic_helper_damage_iter iter;
- struct drm_rect clip;
- u32 num_hits = 0;
-
- /* Plane src moved since old plane state. */
- set_plane_src(&mock->old_state, 0, 0, 1024 << 16, 768 << 16);
- set_plane_src(&mock->state, 10 << 16, 10 << 16,
- (10 + 1024) << 16, (10 + 768) << 16);
- drm_atomic_helper_damage_iter_init(&iter, &mock->old_state, &mock->state);
- drm_atomic_for_each_plane_damage(&iter, &clip)
- num_hits++;
-
- KUNIT_EXPECT_EQ_MSG(test, num_hits, 1, "Should return plane src as damage.");
- check_damage_clip(test, &clip, 10, 10, 1034, 778);
-}
-
-static void drm_test_damage_iter_no_damage_fractional_src_moved(struct kunit *test)
-{
- struct drm_damage_mock *mock = test->priv;
- struct drm_atomic_helper_damage_iter iter;
- struct drm_rect clip;
- u32 num_hits = 0;
-
- /* Plane src has fractional part and it moved since old plane state. */
- set_plane_src(&mock->old_state, 0x3fffe, 0x3fffe,
- 0x3fffe + (1024 << 16), 0x3fffe + (768 << 16));
- set_plane_src(&mock->state, 0x40002, 0x40002,
- 0x40002 + (1024 << 16), 0x40002 + (768 << 16));
- drm_atomic_helper_damage_iter_init(&iter, &mock->old_state, &mock->state);
- drm_atomic_for_each_plane_damage(&iter, &clip)
- num_hits++;
-
- KUNIT_EXPECT_EQ_MSG(test, num_hits, 1, "Should return plane src as damage.");
- check_damage_clip(test, &clip, 4, 4, 1029, 773);
-}
-
static void drm_test_damage_iter_no_damage_not_visible(struct kunit *test)
{
struct drm_damage_mock *mock = test->priv;
@@ -415,58 +376,6 @@ static void drm_test_damage_iter_single_damage_outside_fractional_src(struct kun
KUNIT_EXPECT_EQ_MSG(test, num_hits, 0, "Should have no damage.");
}
-static void drm_test_damage_iter_single_damage_src_moved(struct kunit *test)
-{
- struct drm_damage_mock *mock = test->priv;
- struct drm_atomic_helper_damage_iter iter;
- struct drm_property_blob damage_blob;
- struct drm_mode_rect damage;
- struct drm_rect clip;
- u32 num_hits = 0;
-
- /* Plane src moved since old plane state. */
- set_plane_src(&mock->old_state, 0, 0, 1024 << 16, 768 << 16);
- set_plane_src(&mock->state, 10 << 16, 10 << 16,
- (10 + 1024) << 16, (10 + 768) << 16);
- set_damage_clip(&damage, 20, 30, 256, 256);
- set_damage_blob(&damage_blob, &damage, sizeof(damage));
- set_plane_damage(&mock->state, &damage_blob);
- drm_atomic_helper_damage_iter_init(&iter, &mock->old_state, &mock->state);
- drm_atomic_for_each_plane_damage(&iter, &clip)
- num_hits++;
-
- KUNIT_EXPECT_EQ_MSG(test, num_hits, 1,
- "Should return plane src as damage.");
- check_damage_clip(test, &clip, 10, 10, 1034, 778);
-}
-
-static void drm_test_damage_iter_single_damage_fractional_src_moved(struct kunit *test)
-{
- struct drm_damage_mock *mock = test->priv;
- struct drm_atomic_helper_damage_iter iter;
- struct drm_property_blob damage_blob;
- struct drm_mode_rect damage;
- struct drm_rect clip;
- u32 num_hits = 0;
-
- /* Plane src with fractional part moved since old plane state. */
- set_plane_src(&mock->old_state, 0x3fffe, 0x3fffe,
- 0x3fffe + (1024 << 16), 0x3fffe + (768 << 16));
- set_plane_src(&mock->state, 0x40002, 0x40002,
- 0x40002 + (1024 << 16), 0x40002 + (768 << 16));
- /* Damage intersect with plane src. */
- set_damage_clip(&damage, 20, 30, 1360, 256);
- set_damage_blob(&damage_blob, &damage, sizeof(damage));
- set_plane_damage(&mock->state, &damage_blob);
- drm_atomic_helper_damage_iter_init(&iter, &mock->old_state, &mock->state);
- drm_atomic_for_each_plane_damage(&iter, &clip)
- num_hits++;
-
- KUNIT_EXPECT_EQ_MSG(test, num_hits, 1,
- "Should return rounded off plane as damage.");
- check_damage_clip(test, &clip, 4, 4, 1029, 773);
-}
-
static void drm_test_damage_iter_damage(struct kunit *test)
{
struct drm_damage_mock *mock = test->priv;
@@ -549,60 +458,6 @@ static void drm_test_damage_iter_damage_one_outside(struct kunit *test)
check_damage_clip(test, &clip, 240, 200, 280, 250);
}
-static void drm_test_damage_iter_damage_src_moved(struct kunit *test)
-{
- struct drm_damage_mock *mock = test->priv;
- struct drm_atomic_helper_damage_iter iter;
- struct drm_property_blob damage_blob;
- struct drm_mode_rect damage[2];
- struct drm_rect clip;
- u32 num_hits = 0;
-
- set_plane_src(&mock->old_state, 0x40002, 0x40002,
- 0x40002 + (1024 << 16), 0x40002 + (768 << 16));
- set_plane_src(&mock->state, 0x3fffe, 0x3fffe,
- 0x3fffe + (1024 << 16), 0x3fffe + (768 << 16));
- /* 2 damage clips, one outside plane src. */
- set_damage_clip(&damage[0], 1360, 1360, 1380, 1380);
- set_damage_clip(&damage[1], 240, 200, 280, 250);
- set_damage_blob(&damage_blob, &damage[0], sizeof(damage));
- set_plane_damage(&mock->state, &damage_blob);
- drm_atomic_helper_damage_iter_init(&iter, &mock->old_state, &mock->state);
- drm_atomic_for_each_plane_damage(&iter, &clip)
- num_hits++;
-
- KUNIT_EXPECT_EQ_MSG(test, num_hits, 1,
- "Should return round off plane src as damage.");
- check_damage_clip(test, &clip, 3, 3, 1028, 772);
-}
-
-static void drm_test_damage_iter_damage_not_visible(struct kunit *test)
-{
- struct drm_damage_mock *mock = test->priv;
- struct drm_atomic_helper_damage_iter iter;
- struct drm_property_blob damage_blob;
- struct drm_mode_rect damage[2];
- struct drm_rect clip;
- u32 num_hits = 0;
-
- mock->state.visible = false;
-
- set_plane_src(&mock->old_state, 0x40002, 0x40002,
- 0x40002 + (1024 << 16), 0x40002 + (768 << 16));
- set_plane_src(&mock->state, 0x3fffe, 0x3fffe,
- 0x3fffe + (1024 << 16), 0x3fffe + (768 << 16));
- /* 2 damage clips, one outside plane src. */
- set_damage_clip(&damage[0], 1360, 1360, 1380, 1380);
- set_damage_clip(&damage[1], 240, 200, 280, 250);
- set_damage_blob(&damage_blob, &damage[0], sizeof(damage));
- set_plane_damage(&mock->state, &damage_blob);
- drm_atomic_helper_damage_iter_init(&iter, &mock->old_state, &mock->state);
- drm_atomic_for_each_plane_damage(&iter, &clip)
- num_hits++;
-
- KUNIT_EXPECT_EQ_MSG(test, num_hits, 0, "Should not return any damage.");
-}
-
static void drm_test_damage_iter_damage_ignore(struct kunit *test)
{
struct drm_damage_mock *mock = test->priv;
@@ -633,8 +488,6 @@ static void drm_test_damage_iter_damage_ignore(struct kunit *test)
static struct kunit_case drm_damage_helper_tests[] = {
KUNIT_CASE(drm_test_damage_iter_no_damage),
KUNIT_CASE(drm_test_damage_iter_no_damage_fractional_src),
- KUNIT_CASE(drm_test_damage_iter_no_damage_src_moved),
- KUNIT_CASE(drm_test_damage_iter_no_damage_fractional_src_moved),
KUNIT_CASE(drm_test_damage_iter_no_damage_not_visible),
KUNIT_CASE(drm_test_damage_iter_no_damage_no_crtc),
KUNIT_CASE(drm_test_damage_iter_no_damage_no_fb),
@@ -645,13 +498,9 @@ static struct kunit_case drm_damage_helper_tests[] = {
KUNIT_CASE(drm_test_damage_iter_single_damage_fractional_src),
KUNIT_CASE(drm_test_damage_iter_single_damage_intersect_fractional_src),
KUNIT_CASE(drm_test_damage_iter_single_damage_outside_fractional_src),
- KUNIT_CASE(drm_test_damage_iter_single_damage_src_moved),
- KUNIT_CASE(drm_test_damage_iter_single_damage_fractional_src_moved),
KUNIT_CASE(drm_test_damage_iter_damage),
KUNIT_CASE(drm_test_damage_iter_damage_one_intersect),
KUNIT_CASE(drm_test_damage_iter_damage_one_outside),
- KUNIT_CASE(drm_test_damage_iter_damage_src_moved),
- KUNIT_CASE(drm_test_damage_iter_damage_not_visible),
KUNIT_CASE(drm_test_damage_iter_damage_ignore),
{ }
};
diff --git a/include/drm/drm_damage_helper.h b/include/drm/drm_damage_helper.h
index 3661aeab2cd3..e93eaa0fbcb6 100644
--- a/include/drm/drm_damage_helper.h
+++ b/include/drm/drm_damage_helper.h
@@ -65,7 +65,8 @@ struct drm_atomic_helper_damage_iter {
};
void drm_atomic_helper_check_plane_damage(struct drm_atomic_commit *state,
- struct drm_plane_state *plane_state);
+ const struct drm_plane_state *old_plane_state,
+ struct drm_plane_state *new_plane_state);
int drm_atomic_helper_dirtyfb(struct drm_framebuffer *fb,
struct drm_file *file_priv, unsigned int flags,
unsigned int color, struct drm_clip_rect *clips,
--
2.54.0
next prev parent reply other threads:[~2026-06-10 15:26 UTC|newest]
Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-06-10 15:18 [PATCH v5 00/15] drm: Improve logic behind damage handling Thomas Zimmermann
2026-06-10 15:18 ` [PATCH v5 01/15] drm/amd/display: Handle struct drm_plane_state.ignore_damage_clips Thomas Zimmermann
2026-06-11 10:10 ` Javier Martinez Canillas
2026-06-11 10:41 ` Thomas Zimmermann
2026-06-11 10:59 ` Javier Martinez Canillas
2026-06-11 11:09 ` Thomas Zimmermann
2026-06-24 16:06 ` Harry Wentland
2026-06-10 15:18 ` [PATCH v5 02/15] drm/i915/display: " Thomas Zimmermann
2026-06-11 10:11 ` Javier Martinez Canillas
2026-06-10 15:18 ` [PATCH v5 03/15] drm/vboxvideo: " Thomas Zimmermann
2026-06-11 10:12 ` Javier Martinez Canillas
2026-06-10 15:18 ` [PATCH v5 04/15] drm/vmwgfx: " Thomas Zimmermann
2026-06-11 10:12 ` Javier Martinez Canillas
2026-06-10 15:18 ` [PATCH v5 05/15] drm/appletbdrm: Allocate request/response buffers in begin_fb_access Thomas Zimmermann
2026-06-10 15:18 ` [PATCH v5 06/15] drm/damage-helper: Clear ignore_damage_clips in plane-state duplication Thomas Zimmermann
2026-06-10 15:18 ` [PATCH v5 07/15] drm/damage-helper: Do not alter damage clips on modeset, but ignore them Thomas Zimmermann
2026-06-10 15:18 ` [PATCH v5 08/15] drm/atomic-helpers: Evaluate plane damage after atomic_check Thomas Zimmermann
2026-06-10 15:18 ` [PATCH v5 09/15] drm/ingenic: Remove calls to drm_atomic_helper_check_plane_damage() Thomas Zimmermann
2026-06-10 15:18 ` [PATCH v5 10/15] drm/atomic_helper: Do not evaluate plane damage before atomic_check Thomas Zimmermann
2026-06-10 15:18 ` Thomas Zimmermann [this message]
2026-06-10 15:18 ` [PATCH v5 12/15] drm/damage-helper: Remove old state from drm_atomic_helper_damage_iter_init() Thomas Zimmermann
2026-06-10 15:18 ` [PATCH v5 13/15] drm/damage-helper: Remove old state from drm_atomic_helper_damage_merged() Thomas Zimmermann
2026-06-10 15:18 ` [PATCH v5 14/15] drm/damage-helper: Rename state parameters in damage helpers Thomas Zimmermann
2026-06-10 15:18 ` [PATCH v5 15/15] drm/vmwgfx: Remove unused field struct vmwgfx_du_update_plane.old_state Thomas Zimmermann
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260610152505.260172-12-tzimmermann@suse.de \
--to=tzimmermann@suse.de \
--cc=admin@kodeit.net \
--cc=airlied@gmail.com \
--cc=airlied@redhat.com \
--cc=alexander.deucher@amd.com \
--cc=amd-gfx@lists.freedesktop.org \
--cc=bcm-kernel-feedback-list@broadcom.com \
--cc=dmitry.osipenko@collabora.com \
--cc=dri-devel@lists.freedesktop.org \
--cc=gargaditya08@proton.me \
--cc=gurchetansingh@chromium.org \
--cc=harry.wentland@amd.com \
--cc=intel-gfx@lists.freedesktop.org \
--cc=intel-xe@lists.freedesktop.org \
--cc=jani.nikula@linux.intel.com \
--cc=javierm@redhat.com \
--cc=joonas.lahtinen@linux.intel.com \
--cc=linux-hyperv@vger.kernel.org \
--cc=linux-mips@vger.kernel.org \
--cc=maarten.lankhorst@linux.intel.com \
--cc=mhklkml@zohomail.com \
--cc=mripard@kernel.org \
--cc=olvaffe@gmail.com \
--cc=paul@crapouillou.net \
--cc=rodrigo.vivi@intel.com \
--cc=simona@ffwll.ch \
--cc=siqueira@igalia.com \
--cc=sunpeng.li@amd.com \
--cc=tursulin@ursulin.net \
--cc=virtualization@lists.linux.dev \
--cc=zack.rusin@broadcom.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox