On Tue, Oct 16, 2018 at 02:21:17PM +0200, Daniel Vetter wrote: > On Mon, Oct 15, 2018 at 04:11:41PM +0000, Deepak Singh Rawat wrote: > > > On Wed, Oct 10, 2018 at 05:16:43PM -0700, Deepak Rawat wrote: > > > > Selftest for drm damage helper iterator functions. > > > > > > > > Cc: ville.syrjala@xxxxxxxxxxxxxxx > > > > Cc: Daniel Vetter <daniel.vetter@xxxxxxxx> > > > > Cc: Pekka Paalanen <ppaalanen@xxxxxxxxx> > > > > Cc: Daniel Stone <daniel@xxxxxxxxxxxxx> > > > > Cc: intel-gfx@xxxxxxxxxxxxxxxxxxxxx > > > > Cc: igt-dev@xxxxxxxxxxxxxxxxxxxxx > > > > Cc: petri.latvala@xxxxxxxxx > > > > Cc: chris@xxxxxxxxxxxxxxxxxx > > > > Signed-off-by: Deepak Rawat <drawat@xxxxxxxxxx> > > > > --- > > > > drivers/gpu/drm/selftests/Makefile | 3 +- > > > > .../selftests/drm_damage_helper_selftests.h | 22 + > > > > .../drm/selftests/test-drm_damage_helper.c | 844 > > > ++++++++++++++++++ > > > > 3 files changed, 868 insertions(+), 1 deletion(-) > > > > create mode 100644 > > > drivers/gpu/drm/selftests/drm_damage_helper_selftests.h > > > > create mode 100644 drivers/gpu/drm/selftests/test- > > > drm_damage_helper.c > > > > > > > > diff --git a/drivers/gpu/drm/selftests/Makefile > > > b/drivers/gpu/drm/selftests/Makefile > > > > index 9fc349fa18e9..88ac216f5962 100644 > > > > --- a/drivers/gpu/drm/selftests/Makefile > > > > +++ b/drivers/gpu/drm/selftests/Makefile > > > > @@ -1 +1,2 @@ > > > > -obj-$(CONFIG_DRM_DEBUG_SELFTEST) += test-drm_mm.o test-drm- > > > helper.o > > > > +obj-$(CONFIG_DRM_DEBUG_SELFTEST) += test-drm_mm.o test-drm- > > > helper.o \ > > > > + test-drm_damage_helper.o > > > > > > With the testcase intagrated into the test-drm-helper.ko module, for > > > patches 1-4 in this series: > > > > > > Reviewed-by: Daniel Vetter <daniel.vetter@xxxxxxxx> > > > > > > Obviously needs some adjusting on the igt side too, since we seem to be > > > missing the igt scaffolding for tests-drm-helper.ko. > > > -Daniel > > > > Hi Daniel, > > > > Thanks for the review. I am a little confused here. Should we have single > > kernel module for drm plane helper selftest and damage helper selftest? > > Also shall I rename the kernel selfttest to kms_*? > > > > For user-space igt test it should be it makes sense to rename to kms_selftets? > > Since I went back&forth on this way too many times: > - igt should be called kms_selftest. Please work together with igt > maintainers (Arek and Petri), since we also need to update the CI > building infrastructure to make sure it updates the list of subtests > implemented by the kernel. > > - Kernel module I'd call test-drm_modeset.ko. That kernel module can then > include the existing test-drm-helper.c (could probably rename to > test-drm_plane_helper.c for clarity) and your new damage helper (named > test-drm_damage_helper.c for consistency). > > Does that make sense to everyone? I was trying to add some selftests, as well here [1], with that in mind, I think it makes sense to have just one module, call it "test-drm_modeset" or whatever and separate the tests source code base on whatever core functionality they are testing. Besides compiling everything together, probably some stuff will have to move out of test-drm-helper.c into some common header. For example this "FAIL/FAIL_ON" macros [1] https://lists.freedesktop.org/archives/dri-devel/2018-October/192973.html > > Thanks, Daniel > > > > > > > > > > diff --git a/drivers/gpu/drm/selftests/drm_damage_helper_selftests.h > > > b/drivers/gpu/drm/selftests/drm_damage_helper_selftests.h > > > > new file mode 100644 > > > > index 000000000000..3a1cbe05bef0 > > > > --- /dev/null > > > > +++ b/drivers/gpu/drm/selftests/drm_damage_helper_selftests.h > > > > @@ -0,0 +1,22 @@ > > > > +/* SPDX-License-Identifier: GPL-2.0 */ > > > > +selftest(damage_iter_no_damage, igt_damage_iter_no_damage) > > > > +selftest(damage_iter_no_damage_fractional_src, > > > igt_damage_iter_no_damage_fractional_src) > > > > +selftest(damage_iter_no_damage_src_moved, > > > igt_damage_iter_no_damage_src_moved) > > > > +selftest(damage_iter_no_damage_fractional_src_moved, > > > igt_damage_iter_no_damage_fractional_src_moved) > > > > +selftest(damage_iter_no_damage_not_visible, > > > igt_damage_iter_no_damage_not_visible) > > > > +selftest(damage_iter_no_damage_no_crtc, > > > igt_damage_iter_no_damage_no_crtc) > > > > +selftest(damage_iter_no_damage_no_fb, > > > igt_damage_iter_no_damage_no_fb) > > > > +selftest(damage_iter_simple_damage, > > > igt_damage_iter_simple_damage) > > > > +selftest(damage_iter_single_damage, igt_damage_iter_single_damage) > > > > +selftest(damage_iter_single_damage_intersect_src, > > > igt_damage_iter_single_damage_intersect_src) > > > > +selftest(damage_iter_single_damage_outside_src, > > > igt_damage_iter_single_damage_outside_src) > > > > +selftest(damage_iter_single_damage_fractional_src, > > > igt_damage_iter_single_damage_fractional_src) > > > > +selftest(damage_iter_single_damage_intersect_fractional_src, > > > igt_damage_iter_single_damage_intersect_fractional_src) > > > > +selftest(damage_iter_single_damage_outside_fractional_src, > > > igt_damage_iter_single_damage_outside_fractional_src) > > > > +selftest(damage_iter_single_damage_src_moved, > > > igt_damage_iter_single_damage_src_moved) > > > > +selftest(damage_iter_single_damage_fractional_src_moved, > > > igt_damage_iter_single_damage_fractional_src_moved) > > > > +selftest(damage_iter_damage, igt_damage_iter_damage) > > > > +selftest(damage_iter_damage_one_intersect, > > > igt_damage_iter_damage_one_intersect) > > > > +selftest(damage_iter_damage_one_outside, > > > igt_damage_iter_damage_one_outside) > > > > +selftest(damage_iter_damage_src_moved, > > > igt_damage_iter_damage_src_moved) > > > > +selftest(damage_iter_damage_not_visible, > > > igt_damage_iter_damage_not_visible) > > > > diff --git a/drivers/gpu/drm/selftests/test-drm_damage_helper.c > > > b/drivers/gpu/drm/selftests/test-drm_damage_helper.c > > > > new file mode 100644 > > > > index 000000000000..17754734c47a > > > > --- /dev/null > > > > +++ b/drivers/gpu/drm/selftests/test-drm_damage_helper.c > > > > @@ -0,0 +1,844 @@ > > > > +/* SPDX-License-Identifier: GPL-2.0 */ > > > > +/* > > > > + * Test case for drm_damage_helper functions > > > > + */ > > > > + > > > > +#define pr_fmt(fmt) "drm_damage_helper: " fmt > > > > + > > > > +#include <linux/module.h> > > > > +#include <drm/drm_damage_helper.h> > > > > + > > > > +#define TESTS "drm_damage_helper_selftests.h" > > > > +#include "drm_selftest.h" > > > > + > > > > +#define FAIL(test, msg, ...) \ > > > > + do { \ > > > > + if (test) { \ > > > > + pr_err("%s/%u: " msg, __FUNCTION__, __LINE__, > > > ##__VA_ARGS__); \ > > > > + return -EINVAL; \ > > > > + } \ > > > > + } while (0) > > > > + > > > > +#define FAIL_ON(x) FAIL((x), "%s", "FAIL_ON(" __stringify(x) ")\n") > > > > + > > > > +static void set_plane_src(struct drm_plane_state *state, int x1, int y1, int > > > x2, > > > > + int y2) > > > > +{ > > > > + state->src.x1 = x1; > > > > + state->src.y1 = y1; > > > > + state->src.x2 = x2; > > > > + state->src.y2 = y2; > > > > +} > > > > + > > > > +static void set_damage_clip(struct drm_mode_rect *r, int x1, int y1, int > > > x2, > > > > + int y2) > > > > +{ > > > > + r->x1 = x1; > > > > + r->y1 = y1; > > > > + r->x2 = x2; > > > > + r->y2 = y2; > > > > +} > > > > + > > > > +static void set_damage_blob(struct drm_property_blob *damage_blob, > > > > + struct drm_mode_rect *r, uint32_t size) > > > > +{ > > > > + damage_blob->length = size; > > > > + damage_blob->data = r; > > > > +} > > > > + > > > > +static void set_plane_damage(struct drm_plane_state *state, > > > > + struct drm_property_blob *damage_blob) > > > > +{ > > > > + state->fb_damage_clips = damage_blob; > > > > +} > > > > + > > > > +static bool check_damage_clip(struct drm_plane_state *state, struct > > > drm_rect *r, > > > > + int x1, int y1, int x2, int y2) > > > > +{ > > > > + /* > > > > + * Round down x1/y1 and round up x2/y2. This is because damage is > > > not in > > > > + * 16.16 fixed point so to catch all pixels. > > > > + */ > > > > + int src_x1 = state->src.x1 >> 16; > > > > + int src_y1 = state->src.y1 >> 16; > > > > + int src_x2 = (state->src.x2 >> 16) + !!(state->src.x2 & 0xFFFF); > > > > + int src_y2 = (state->src.y2 >> 16) + !!(state->src.y2 & 0xFFFF); > > > > + > > > > + if (x1 >= x2 || y1 >= y2) { > > > > + pr_err("Cannot have damage clip with no dimention.\n"); > > > > + return false; > > > > + } > > > > + > > > > + if (x1 < src_x1 || y1 < src_y1 || x2 > src_x2 || y2 > src_y2) { > > > > + pr_err("Damage cannot be outside rounded plane src.\n"); > > > > + return false; > > > > + } > > > > + > > > > + if (r->x1 != x1 || r->y1 != y1 || r->x2 != x2 || r->y2 != y2) { > > > > + pr_err("Damage = %d %d %d %d\n", r->x1, r->y1, r->x2, r- > > > >y2); > > > > + return false; > > > > + } > > > > + > > > > + return true; > > > > +} > > > > + > > > > +static int igt_damage_iter_no_damage(void *ignored) > > > > +{ > > > > + struct drm_atomic_helper_damage_iter iter; > > > > + struct drm_plane_state old_state; > > > > + struct drm_rect clip; > > > > + uint32_t num_hits = 0; > > > > + > > > > + struct drm_framebuffer fb = { > > > > + .width = 2048, > > > > + .height = 2048 > > > > + }; > > > > + > > > > + struct drm_plane_state state = { > > > > + .crtc = ZERO_SIZE_PTR, > > > > + .fb = &fb, > > > > + .visible = true, > > > > + }; > > > > + > > > > + /* Plane src same as fb size. */ > > > > + set_plane_src(&old_state, 0, 0, fb.width << 16, fb.height << 16); > > > > + set_plane_src(&state, 0, 0, fb.width << 16, fb.height << 16); > > > > + drm_atomic_helper_damage_iter_init(&iter, &old_state, &state); > > > > + drm_atomic_for_each_plane_damage(&iter, &clip) > > > > + num_hits++; > > > > + > > > > + FAIL(num_hits != 1, "Should return plane src as damage."); > > > > + FAIL_ON(!check_damage_clip(&state, &clip, 0, 0, 2048, 2048)); > > > > + > > > > + return 0; > > > > +} > > > > + > > > > +static int igt_damage_iter_no_damage_fractional_src(void *ignored) > > > > +{ > > > > + struct drm_atomic_helper_damage_iter iter; > > > > + struct drm_plane_state old_state; > > > > + struct drm_rect clip; > > > > + uint32_t num_hits = 0; > > > > + > > > > + struct drm_framebuffer fb = { > > > > + .width = 2048, > > > > + .height = 2048 > > > > + }; > > > > + > > > > + struct drm_plane_state state = { > > > > + .crtc = ZERO_SIZE_PTR, > > > > + .fb = &fb, > > > > + .visible = true, > > > > + }; > > > > + > > > > + /* Plane src has fractional part. */ > > > > + set_plane_src(&old_state, 0x3fffe, 0x3fffe, > > > > + 0x3fffe + (1024 << 16), 0x3fffe + (768 << 16)); > > > > + set_plane_src(&state, 0x3fffe, 0x3fffe, > > > > + 0x3fffe + (1024 << 16), 0x3fffe + (768 << 16)); > > > > + drm_atomic_helper_damage_iter_init(&iter, &old_state, &state); > > > > + drm_atomic_for_each_plane_damage(&iter, &clip) > > > > + num_hits++; > > > > + > > > > + FAIL(num_hits != 1, "Should return rounded off plane src as > > > damage."); > > > > + FAIL_ON(!check_damage_clip(&state, &clip, 3, 3, 1028, 772)); > > > > + > > > > + return 0; > > > > +} > > > > + > > > > +static int igt_damage_iter_no_damage_src_moved(void *ignored) > > > > +{ > > > > + struct drm_atomic_helper_damage_iter iter; > > > > + struct drm_plane_state old_state; > > > > + struct drm_rect clip; > > > > + uint32_t num_hits = 0; > > > > + > > > > + struct drm_framebuffer fb = { > > > > + .width = 2048, > > > > + .height = 2048 > > > > + }; > > > > + > > > > + struct drm_plane_state state = { > > > > + .crtc = ZERO_SIZE_PTR, > > > > + .fb = &fb, > > > > + .visible = true, > > > > + }; > > > > + > > > > + /* Plane src moved since old plane state. */ > > > > + set_plane_src(&old_state, 0, 0, 1024 << 16, 768 << 16); > > > > + set_plane_src(&state, 10 << 16, 10 << 16, > > > > + (10 + 1024) << 16, (10 + 768) << 16); > > > > + drm_atomic_helper_damage_iter_init(&iter, &old_state, &state); > > > > + drm_atomic_for_each_plane_damage(&iter, &clip) > > > > + num_hits++; > > > > + > > > > + FAIL(num_hits != 1, "Should return plane src as damage."); > > > > + FAIL_ON(!check_damage_clip(&state, &clip, 10, 10, 1034, 778)); > > > > + > > > > + return 0; > > > > +} > > > > + > > > > +static int igt_damage_iter_no_damage_fractional_src_moved(void > > > *ignored) > > > > +{ > > > > + struct drm_atomic_helper_damage_iter iter; > > > > + struct drm_plane_state old_state; > > > > + struct drm_rect clip; > > > > + uint32_t num_hits = 0; > > > > + > > > > + struct drm_framebuffer fb = { > > > > + .width = 2048, > > > > + .height = 2048 > > > > + }; > > > > + > > > > + struct drm_plane_state state = { > > > > + .crtc = ZERO_SIZE_PTR, > > > > + .fb = &fb, > > > > + .visible = true, > > > > + }; > > > > + > > > > + /* Plane src has fractional part and it moved since old plane state. */ > > > > + set_plane_src(&old_state, 0x3fffe, 0x3fffe, > > > > + 0x3fffe + (1024 << 16), 0x3fffe + (768 << 16)); > > > > + set_plane_src(&state, 0x40002, 0x40002, > > > > + 0x40002 + (1024 << 16), 0x40002 + (768 << 16)); > > > > + drm_atomic_helper_damage_iter_init(&iter, &old_state, &state); > > > > + drm_atomic_for_each_plane_damage(&iter, &clip) > > > > + num_hits++; > > > > + > > > > + FAIL(num_hits != 1, "Should return plane src as damage."); > > > > + FAIL_ON(!check_damage_clip(&state, &clip, 4, 4, 1029, 773)); > > > > + > > > > + return 0; > > > > +} > > > > + > > > > +static int igt_damage_iter_no_damage_not_visible(void *ignored) > > > > +{ > > > > + struct drm_atomic_helper_damage_iter iter; > > > > + struct drm_plane_state old_state; > > > > + struct drm_rect clip; > > > > + uint32_t num_hits = 0; > > > > + > > > > + struct drm_framebuffer fb = { > > > > + .width = 2048, > > > > + .height = 2048 > > > > + }; > > > > + > > > > + struct drm_plane_state state = { > > > > + .crtc = ZERO_SIZE_PTR, > > > > + .fb = &fb, > > > > + .visible = false, > > > > + }; > > > > + > > > > + set_plane_src(&old_state, 0, 0, 1024 << 16, 768 << 16); > > > > + set_plane_src(&state, 0, 0, 1024 << 16, 768 << 16); > > > > + drm_atomic_helper_damage_iter_init(&iter, &old_state, &state); > > > > + drm_atomic_for_each_plane_damage(&iter, &clip) > > > > + num_hits++; > > > > + > > > > + FAIL(num_hits != 0, "Should have no damage."); > > > > + > > > > + return 0; > > > > +} > > > > + > > > > +static int igt_damage_iter_no_damage_no_crtc(void *ignored) > > > > +{ > > > > + struct drm_atomic_helper_damage_iter iter; > > > > + struct drm_plane_state old_state; > > > > + struct drm_rect clip; > > > > + uint32_t num_hits = 0; > > > > + > > > > + struct drm_framebuffer fb = { > > > > + .width = 2048, > > > > + .height = 2048 > > > > + }; > > > > + > > > > + struct drm_plane_state state = { > > > > + .crtc = 0, > > > > + .fb = &fb, > > > > + }; > > > > + > > > > + set_plane_src(&old_state, 0, 0, 1024 << 16, 768 << 16); > > > > + set_plane_src(&state, 0, 0, 1024 << 16, 768 << 16); > > > > + drm_atomic_helper_damage_iter_init(&iter, &old_state, &state); > > > > + drm_atomic_for_each_plane_damage(&iter, &clip) > > > > + num_hits++; > > > > + > > > > + FAIL(num_hits != 0, "Should have no damage."); > > > > + > > > > + return 0; > > > > +} > > > > + > > > > +static int igt_damage_iter_no_damage_no_fb(void *ignored) > > > > +{ > > > > + struct drm_atomic_helper_damage_iter iter; > > > > + struct drm_plane_state old_state; > > > > + struct drm_rect clip; > > > > + uint32_t num_hits = 0; > > > > + > > > > + struct drm_plane_state state = { > > > > + .crtc = ZERO_SIZE_PTR, > > > > + .fb = 0, > > > > + }; > > > > + > > > > + set_plane_src(&old_state, 0, 0, 1024 << 16, 768 << 16); > > > > + set_plane_src(&state, 0, 0, 1024 << 16, 768 << 16); > > > > + drm_atomic_helper_damage_iter_init(&iter, &old_state, &state); > > > > + drm_atomic_for_each_plane_damage(&iter, &clip) > > > > + num_hits++; > > > > + > > > > + FAIL(num_hits != 0, "Should have no damage."); > > > > + > > > > + return 0; > > > > +} > > > > + > > > > +static int igt_damage_iter_simple_damage(void *ignored) > > > > +{ > > > > + struct drm_atomic_helper_damage_iter iter; > > > > + struct drm_plane_state old_state; > > > > + struct drm_property_blob damage_blob; > > > > + struct drm_mode_rect damage; > > > > + struct drm_rect clip; > > > > + uint32_t num_hits = 0; > > > > + > > > > + struct drm_framebuffer fb = { > > > > + .width = 2048, > > > > + .height = 2048 > > > > + }; > > > > + > > > > + struct drm_plane_state state = { > > > > + .crtc = ZERO_SIZE_PTR, > > > > + .fb = &fb, > > > > + .visible = true, > > > > + }; > > > > + > > > > + set_plane_src(&old_state, 0, 0, 1024 << 16, 768 << 16); > > > > + set_plane_src(&state, 0, 0, 1024 << 16, 768 << 16); > > > > + /* Damage set to plane src */ > > > > + set_damage_clip(&damage, 0, 0, 1024, 768); > > > > + set_damage_blob(&damage_blob, &damage, sizeof(damage)); > > > > + set_plane_damage(&state, &damage_blob); > > > > + drm_atomic_helper_damage_iter_init(&iter, &old_state, &state); > > > > + drm_atomic_for_each_plane_damage(&iter, &clip) > > > > + num_hits++; > > > > + > > > > + FAIL(num_hits != 1, "Should return damage when set."); > > > > + FAIL_ON(!check_damage_clip(&state, &clip, 0, 0, 1024, 768)); > > > > + > > > > + return 0; > > > > +} > > > > + > > > > +static int igt_damage_iter_single_damage(void *ignored) > > > > +{ > > > > + struct drm_atomic_helper_damage_iter iter; > > > > + struct drm_plane_state old_state; > > > > + struct drm_property_blob damage_blob; > > > > + struct drm_mode_rect damage; > > > > + struct drm_rect clip; > > > > + uint32_t num_hits = 0; > > > > + > > > > + struct drm_framebuffer fb = { > > > > + .width = 2048, > > > > + .height = 2048 > > > > + }; > > > > + > > > > + struct drm_plane_state state = { > > > > + .crtc = ZERO_SIZE_PTR, > > > > + .fb = &fb, > > > > + .visible = true, > > > > + }; > > > > + > > > > + set_plane_src(&old_state, 0, 0, 1024 << 16, 768 << 16); > > > > + set_plane_src(&state, 0, 0, 1024 << 16, 768 << 16); > > > > + set_damage_clip(&damage, 256, 192, 768, 576); > > > > + set_damage_blob(&damage_blob, &damage, sizeof(damage)); > > > > + set_plane_damage(&state, &damage_blob); > > > > + drm_atomic_helper_damage_iter_init(&iter, &old_state, &state); > > > > + drm_atomic_for_each_plane_damage(&iter, &clip) > > > > + num_hits++; > > > > + > > > > + FAIL(num_hits != 1, "Should return damage when set."); > > > > + FAIL_ON(!check_damage_clip(&state, &clip, 256, 192, 768, 576)); > > > > + > > > > + return 0; > > > > +} > > > > + > > > > +static int igt_damage_iter_single_damage_intersect_src(void *ignored) > > > > +{ > > > > + struct drm_atomic_helper_damage_iter iter; > > > > + struct drm_plane_state old_state; > > > > + struct drm_property_blob damage_blob; > > > > + struct drm_mode_rect damage; > > > > + struct drm_rect clip; > > > > + uint32_t num_hits = 0; > > > > + > > > > + struct drm_framebuffer fb = { > > > > + .width = 2048, > > > > + .height = 2048 > > > > + }; > > > > + > > > > + struct drm_plane_state state = { > > > > + .crtc = ZERO_SIZE_PTR, > > > > + .fb = &fb, > > > > + .visible = true, > > > > + }; > > > > + > > > > + set_plane_src(&old_state, 0, 0, 1024 << 16, 768 << 16); > > > > + set_plane_src(&state, 0, 0, 1024 << 16, 768 << 16); > > > > + /* Damage intersect with plane src. */ > > > > + set_damage_clip(&damage, 256, 192, 1360, 768); > > > > + set_damage_blob(&damage_blob, &damage, sizeof(damage)); > > > > + set_plane_damage(&state, &damage_blob); > > > > + drm_atomic_helper_damage_iter_init(&iter, &old_state, &state); > > > > + drm_atomic_for_each_plane_damage(&iter, &clip) > > > > + num_hits++; > > > > + > > > > + FAIL(num_hits != 1, "Should return damage clipped to src."); > > > > + FAIL_ON(!check_damage_clip(&state, &clip, 256, 192, 1024, 768)); > > > > + > > > > + return 0; > > > > +} > > > > + > > > > +static int igt_damage_iter_single_damage_outside_src(void *ignored) > > > > +{ > > > > + struct drm_atomic_helper_damage_iter iter; > > > > + struct drm_plane_state old_state; > > > > + struct drm_property_blob damage_blob; > > > > + struct drm_mode_rect damage; > > > > + struct drm_rect clip; > > > > + uint32_t num_hits = 0; > > > > + > > > > + struct drm_framebuffer fb = { > > > > + .width = 2048, > > > > + .height = 2048 > > > > + }; > > > > + > > > > + struct drm_plane_state state = { > > > > + .crtc = ZERO_SIZE_PTR, > > > > + .fb = &fb, > > > > + .visible = true, > > > > + }; > > > > + > > > > + set_plane_src(&old_state, 0, 0, 1024 << 16, 768 << 16); > > > > + set_plane_src(&state, 0, 0, 1024 << 16, 768 << 16); > > > > + /* Damage clip outside plane src */ > > > > + set_damage_clip(&damage, 1360, 1360, 1380, 1380); > > > > + set_damage_blob(&damage_blob, &damage, sizeof(damage)); > > > > + set_plane_damage(&state, &damage_blob); > > > > + drm_atomic_helper_damage_iter_init(&iter, &old_state, &state); > > > > + drm_atomic_for_each_plane_damage(&iter, &clip) > > > > + num_hits++; > > > > + > > > > + FAIL(num_hits != 0, "Should have no damage."); > > > > + > > > > + return 0; > > > > +} > > > > + > > > > +static int igt_damage_iter_single_damage_fractional_src(void *ignored) > > > > +{ > > > > + struct drm_atomic_helper_damage_iter iter; > > > > + struct drm_plane_state old_state; > > > > + struct drm_property_blob damage_blob; > > > > + struct drm_mode_rect damage; > > > > + struct drm_rect clip; > > > > + uint32_t num_hits = 0; > > > > + > > > > + struct drm_framebuffer fb = { > > > > + .width = 2048, > > > > + .height = 2048 > > > > + }; > > > > + > > > > + struct drm_plane_state state = { > > > > + .crtc = ZERO_SIZE_PTR, > > > > + .fb = &fb, > > > > + .visible = true, > > > > + }; > > > > + > > > > + /* Plane src has fractional part. */ > > > > + set_plane_src(&old_state, 0x40002, 0x40002, > > > > + 0x40002 + (1024 << 16), 0x40002 + (768 << 16)); > > > > + set_plane_src(&state, 0x40002, 0x40002, > > > > + 0x40002 + (1024 << 16), 0x40002 + (768 << 16)); > > > > + set_damage_clip(&damage, 10, 10, 256, 330); > > > > + set_damage_blob(&damage_blob, &damage, sizeof(damage)); > > > > + set_plane_damage(&state, &damage_blob); > > > > + drm_atomic_helper_damage_iter_init(&iter, &old_state, &state); > > > > + drm_atomic_for_each_plane_damage(&iter, &clip) > > > > + num_hits++; > > > > + > > > > + FAIL(num_hits != 1, "Should return damage when set."); > > > > + FAIL_ON(!check_damage_clip(&state, &clip, 10, 10, 256, 330)); > > > > + > > > > + return 0; > > > > +} > > > > + > > > > +static int igt_damage_iter_single_damage_intersect_fractional_src(void > > > *ignored) > > > > +{ > > > > + struct drm_atomic_helper_damage_iter iter; > > > > + struct drm_plane_state old_state; > > > > + struct drm_property_blob damage_blob; > > > > + struct drm_mode_rect damage; > > > > + struct drm_rect clip; > > > > + uint32_t num_hits = 0; > > > > + > > > > + struct drm_framebuffer fb = { > > > > + .width = 2048, > > > > + .height = 2048 > > > > + }; > > > > + > > > > + struct drm_plane_state state = { > > > > + .crtc = ZERO_SIZE_PTR, > > > > + .fb = &fb, > > > > + .visible = true, > > > > + }; > > > > + > > > > + /* Plane src has fractional part. */ > > > > + set_plane_src(&old_state, 0x40002, 0x40002, > > > > + 0x40002 + (1024 << 16), 0x40002 + (768 << 16)); > > > > + set_plane_src(&state, 0x40002, 0x40002, > > > > + 0x40002 + (1024 << 16), 0x40002 + (768 << 16)); > > > > + /* Damage intersect with plane src. */ > > > > + set_damage_clip(&damage, 10, 1, 1360, 330); > > > > + set_damage_blob(&damage_blob, &damage, sizeof(damage)); > > > > + set_plane_damage(&state, &damage_blob); > > > > + drm_atomic_helper_damage_iter_init(&iter, &old_state, &state); > > > > + drm_atomic_for_each_plane_damage(&iter, &clip) > > > > + num_hits++; > > > > + > > > > + FAIL(num_hits != 1, "Should return damage clipped to rounded off > > > src."); > > > > + FAIL_ON(!check_damage_clip(&state, &clip, 10, 4, 1029, 330)); > > > > + > > > > + return 0; > > > > +} > > > > + > > > > +static int igt_damage_iter_single_damage_outside_fractional_src(void > > > *ignored) > > > > +{ > > > > + struct drm_atomic_helper_damage_iter iter; > > > > + struct drm_plane_state old_state; > > > > + struct drm_property_blob damage_blob; > > > > + struct drm_mode_rect damage; > > > > + struct drm_rect clip; > > > > + uint32_t num_hits = 0; > > > > + > > > > + struct drm_framebuffer fb = { > > > > + .width = 2048, > > > > + .height = 2048 > > > > + }; > > > > + > > > > + struct drm_plane_state state = { > > > > + .crtc = ZERO_SIZE_PTR, > > > > + .fb = &fb, > > > > + .visible = true, > > > > + }; > > > > + > > > > + /* Plane src has fractional part. */ > > > > + set_plane_src(&old_state, 0x40002, 0x40002, > > > > + 0x40002 + (1024 << 16), 0x40002 + (768 << 16)); > > > > + set_plane_src(&state, 0x40002, 0x40002, > > > > + 0x40002 + (1024 << 16), 0x40002 + (768 << 16)); > > > > + /* Damage clip outside plane src */ > > > > + set_damage_clip(&damage, 1360, 1360, 1380, 1380); > > > > + set_damage_blob(&damage_blob, &damage, sizeof(damage)); > > > > + set_plane_damage(&state, &damage_blob); > > > > + drm_atomic_helper_damage_iter_init(&iter, &old_state, &state); > > > > + drm_atomic_for_each_plane_damage(&iter, &clip) > > > > + num_hits++; > > > > + > > > > + FAIL(num_hits != 0, "Should have no damage."); > > > > + > > > > + return 0; > > > > +} > > > > + > > > > +static int igt_damage_iter_single_damage_src_moved(void *ignored) > > > > +{ > > > > + struct drm_atomic_helper_damage_iter iter; > > > > + struct drm_plane_state old_state; > > > > + struct drm_property_blob damage_blob; > > > > + struct drm_mode_rect damage; > > > > + struct drm_rect clip; > > > > + uint32_t num_hits = 0; > > > > + > > > > + struct drm_framebuffer fb = { > > > > + .width = 2048, > > > > + .height = 2048 > > > > + }; > > > > + > > > > + struct drm_plane_state state = { > > > > + .crtc = ZERO_SIZE_PTR, > > > > + .fb = &fb, > > > > + .visible = true, > > > > + }; > > > > + > > > > + /* Plane src moved since old plane state. */ > > > > + set_plane_src(&old_state, 0, 0, 1024 << 16, 768 << 16); > > > > + set_plane_src(&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(&state, &damage_blob); > > > > + drm_atomic_helper_damage_iter_init(&iter, &old_state, &state); > > > > + drm_atomic_for_each_plane_damage(&iter, &clip) > > > > + num_hits++; > > > > + > > > > + FAIL(num_hits != 1, "Should return plane src as damage."); > > > > + FAIL_ON(!check_damage_clip(&state, &clip, 10, 10, 1034, 778)); > > > > + > > > > + return 0; > > > > +} > > > > + > > > > +static int igt_damage_iter_single_damage_fractional_src_moved(void > > > *ignored) > > > > +{ > > > > + struct drm_atomic_helper_damage_iter iter; > > > > + struct drm_plane_state old_state; > > > > + struct drm_property_blob damage_blob; > > > > + struct drm_mode_rect damage; > > > > + struct drm_rect clip; > > > > + uint32_t num_hits = 0; > > > > + > > > > + struct drm_framebuffer fb = { > > > > + .width = 2048, > > > > + .height = 2048 > > > > + }; > > > > + > > > > + struct drm_plane_state state = { > > > > + .crtc = ZERO_SIZE_PTR, > > > > + .fb = &fb, > > > > + .visible = true, > > > > + }; > > > > + > > > > + /* Plane src with fractional part moved since old plane state. */ > > > > + set_plane_src(&old_state, 0x3fffe, 0x3fffe, > > > > + 0x3fffe + (1024 << 16), 0x3fffe + (768 << 16)); > > > > + set_plane_src(&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(&state, &damage_blob); > > > > + drm_atomic_helper_damage_iter_init(&iter, &old_state, &state); > > > > + drm_atomic_for_each_plane_damage(&iter, &clip) > > > > + num_hits++; > > > > + > > > > + FAIL(num_hits != 1, "Should return rounded off plane src as > > > damage."); > > > > + FAIL_ON(!check_damage_clip(&state, &clip, 4, 4, 1029, 773)); > > > > + > > > > + return 0; > > > > +} > > > > + > > > > +static int igt_damage_iter_damage(void *ignored) > > > > +{ > > > > + struct drm_atomic_helper_damage_iter iter; > > > > + struct drm_plane_state old_state; > > > > + struct drm_property_blob damage_blob; > > > > + struct drm_mode_rect damage[2]; > > > > + struct drm_rect clip; > > > > + uint32_t num_hits = 0; > > > > + > > > > + struct drm_framebuffer fb = { > > > > + .width = 2048, > > > > + .height = 2048 > > > > + }; > > > > + > > > > + struct drm_plane_state state = { > > > > + .crtc = ZERO_SIZE_PTR, > > > > + .fb = &fb, > > > > + .visible = true, > > > > + }; > > > > + > > > > + set_plane_src(&old_state, 0, 0, 1024 << 16, 768 << 16); > > > > + set_plane_src(&state, 0, 0, 1024 << 16, 768 << 16); > > > > + /* 2 damage clips. */ > > > > + set_damage_clip(&damage[0], 20, 30, 200, 180); > > > > + set_damage_clip(&damage[1], 240, 200, 280, 250); > > > > + set_damage_blob(&damage_blob, &damage[0], sizeof(damage)); > > > > + set_plane_damage(&state, &damage_blob); > > > > + drm_atomic_helper_damage_iter_init(&iter, &old_state, &state); > > > > + drm_atomic_for_each_plane_damage(&iter, &clip) { > > > > + if (num_hits == 0) > > > > + FAIL_ON(!check_damage_clip(&state, &clip, 20, 30, > > > 200, 180)); > > > > + if (num_hits == 1) > > > > + FAIL_ON(!check_damage_clip(&state, &clip, 240, > > > 200, 280, 250)); > > > > + num_hits++; > > > > + } > > > > + > > > > + FAIL(num_hits != 2, "Should return damage when set."); > > > > + > > > > + return 0; > > > > +} > > > > + > > > > +static int igt_damage_iter_damage_one_intersect(void *ignored) > > > > +{ > > > > + struct drm_atomic_helper_damage_iter iter; > > > > + struct drm_plane_state old_state; > > > > + struct drm_property_blob damage_blob; > > > > + struct drm_mode_rect damage[2]; > > > > + struct drm_rect clip; > > > > + uint32_t num_hits = 0; > > > > + > > > > + struct drm_framebuffer fb = { > > > > + .width = 2048, > > > > + .height = 2048 > > > > + }; > > > > + > > > > + struct drm_plane_state state = { > > > > + .crtc = ZERO_SIZE_PTR, > > > > + .fb = &fb, > > > > + .visible = true, > > > > + }; > > > > + > > > > + set_plane_src(&old_state, 0x40002, 0x40002, > > > > + 0x40002 + (1024 << 16), 0x40002 + (768 << 16)); > > > > + set_plane_src(&state, 0x40002, 0x40002, > > > > + 0x40002 + (1024 << 16), 0x40002 + (768 << 16)); > > > > + /* 2 damage clips, one intersect plane src. */ > > > > + set_damage_clip(&damage[0], 20, 30, 200, 180); > > > > + set_damage_clip(&damage[1], 2, 2, 1360, 1360); > > > > + set_damage_blob(&damage_blob, &damage[0], sizeof(damage)); > > > > + set_plane_damage(&state, &damage_blob); > > > > + drm_atomic_helper_damage_iter_init(&iter, &old_state, &state); > > > > + drm_atomic_for_each_plane_damage(&iter, &clip) { > > > > + if (num_hits == 0) > > > > + FAIL_ON(!check_damage_clip(&state, &clip, 20, 30, > > > 200, 180)); > > > > + if (num_hits == 1) > > > > + FAIL_ON(!check_damage_clip(&state, &clip, 4, 4, > > > 1029, 773)); > > > > + num_hits++; > > > > + } > > > > + > > > > + FAIL(num_hits != 2, "Should return damage when set."); > > > > + > > > > + return 0; > > > > +} > > > > + > > > > +static int igt_damage_iter_damage_one_outside(void *ignored) > > > > +{ > > > > + struct drm_atomic_helper_damage_iter iter; > > > > + struct drm_plane_state old_state; > > > > + struct drm_property_blob damage_blob; > > > > + struct drm_mode_rect damage[2]; > > > > + struct drm_rect clip; > > > > + uint32_t num_hits = 0; > > > > + > > > > + struct drm_framebuffer fb = { > > > > + .width = 2048, > > > > + .height = 2048 > > > > + }; > > > > + > > > > + struct drm_plane_state state = { > > > > + .crtc = ZERO_SIZE_PTR, > > > > + .fb = &fb, > > > > + .visible = true, > > > > + }; > > > > + > > > > + set_plane_src(&old_state, 0, 0, 1024 << 16, 768 << 16); > > > > + set_plane_src(&state, 0, 0, 1024 << 16, 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(&state, &damage_blob); > > > > + drm_atomic_helper_damage_iter_init(&iter, &old_state, &state); > > > > + drm_atomic_for_each_plane_damage(&iter, &clip) > > > > + num_hits++; > > > > + > > > > + FAIL(num_hits != 1, "Should return damage when set."); > > > > + FAIL_ON(!check_damage_clip(&state, &clip, 240, 200, 280, 250)); > > > > + > > > > + return 0; > > > > +} > > > > + > > > > +static int igt_damage_iter_damage_src_moved(void *ignored) > > > > +{ > > > > + struct drm_atomic_helper_damage_iter iter; > > > > + struct drm_plane_state old_state; > > > > + struct drm_property_blob damage_blob; > > > > + struct drm_mode_rect damage[2]; > > > > + struct drm_rect clip; > > > > + uint32_t num_hits = 0; > > > > + > > > > + struct drm_framebuffer fb = { > > > > + .width = 2048, > > > > + .height = 2048 > > > > + }; > > > > + > > > > + struct drm_plane_state state = { > > > > + .crtc = ZERO_SIZE_PTR, > > > > + .fb = &fb, > > > > + .visible = true, > > > > + }; > > > > + > > > > + set_plane_src(&old_state, 0x40002, 0x40002, > > > > + 0x40002 + (1024 << 16), 0x40002 + (768 << 16)); > > > > + set_plane_src(&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(&state, &damage_blob); > > > > + drm_atomic_helper_damage_iter_init(&iter, &old_state, &state); > > > > + drm_atomic_for_each_plane_damage(&iter, &clip) > > > > + num_hits++; > > > > + > > > > + FAIL(num_hits != 1, "Should return round off plane src as damage."); > > > > + FAIL_ON(!check_damage_clip(&state, &clip, 3, 3, 1028, 772)); > > > > + > > > > + return 0; > > > > +} > > > > + > > > > +static int igt_damage_iter_damage_not_visible(void *ignored) > > > > +{ > > > > + struct drm_atomic_helper_damage_iter iter; > > > > + struct drm_plane_state old_state; > > > > + struct drm_property_blob damage_blob; > > > > + struct drm_mode_rect damage[2]; > > > > + struct drm_rect clip; > > > > + uint32_t num_hits = 0; > > > > + > > > > + struct drm_framebuffer fb = { > > > > + .width = 2048, > > > > + .height = 2048 > > > > + }; > > > > + > > > > + struct drm_plane_state state = { > > > > + .crtc = ZERO_SIZE_PTR, > > > > + .fb = &fb, > > > > + .visible = false, > > > > + }; > > > > + > > > > + set_plane_src(&old_state, 0x40002, 0x40002, > > > > + 0x40002 + (1024 << 16), 0x40002 + (768 << 16)); > > > > + set_plane_src(&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(&state, &damage_blob); > > > > + drm_atomic_helper_damage_iter_init(&iter, &old_state, &state); > > > > + drm_atomic_for_each_plane_damage(&iter, &clip) > > > > + num_hits++; > > > > + > > > > + FAIL(num_hits != 0, "Should not return any damage."); > > > > + > > > > + return 0; > > > > +} > > > > + > > > > +#include "drm_selftest.c" > > > > + > > > > +static int __init test_drm_damage_helper_init(void) > > > > +{ > > > > + int err; > > > > + > > > > + err = run_selftests(selftests, ARRAY_SIZE(selftests), NULL); > > > > + > > > > + return err > 0 ? 0 : err; > > > > +} > > > > + > > > > +static void __exit test_drm_damage_helper_exit(void) > > > > +{ > > > > +} > > > > + > > > > +module_init(test_drm_damage_helper_init); > > > > +module_exit(test_drm_damage_helper_exit); > > > > + > > > > +MODULE_AUTHOR("VMware Inc."); > > > > +MODULE_LICENSE("GPL"); > > > > -- > > > > 2.17.1 > > > > > > > > > > -- > > > Daniel Vetter > > > Software Engineer, Intel Corporation > > > https://na01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fblog.ff > > > wll.ch&data=02%7C01%7Cdrawat%40vmware.com%7C64e7deb3dc264c > > > 6f11a008d62f95d96e%7Cb39138ca3cee4b4aa4d6cd83d9dd62f0%7C1%7C0%7 > > > C636748717979714197&sdata=vCz71L%2BoMpFSGFZifg%2F0bR1CxzReLa > > > 7Dy3ss3UKeLrU%3D&reserved=0 > > -- > Daniel Vetter > Software Engineer, Intel Corporation > http://blog.ffwll.ch > _______________________________________________ > dri-devel mailing list > dri-devel@xxxxxxxxxxxxxxxxxxxxx > https://lists.freedesktop.org/mailman/listinfo/dri-devel -- Cheers, Alex G _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/dri-devel