linux-stable/drivers/gpu/drm/selftests/test-drm_damage_helper.c
Daniel Vetter 2f425cf524 drm: Fix oops in damage self-tests by mocking damage property
I've added a new check to make sure that drivers which insepct the
damage property have it set up correctly, but somehow missed that this
borke the damage selftest in the CI result noise.

Fix it up by mocking enough of drm_device and drm_plane so we can call
drm_plane_enable_fb_damage_clips() to make the new check happy.

Since there's a lot of duplicated mock code already copy-pasted into
each test I've also refactored this a bit to trim it down.

v2: Squash in fixup from 0day for

drivers/gpu/drm/selftests/test-drm_damage_helper.c:15:19: warning: symbol 'mock_device' was not declared. Should it be static?
drivers/gpu/drm/selftests/test-drm_damage_helper.c:16:30: warning: symbol 'mock_obj_props' was not declared. Should it be static?
drivers/gpu/drm/selftests/test-drm_damage_helper.c:17:18: warning: symbol 'mock_plane' was not declared. Should it be static?
drivers/gpu/drm/selftests/test-drm_damage_helper.c:18:21: warning: symbol 'mock_prop' was not declared. Should it be static?

Reported-by: kernel test robot <lkp@intel.com>
Signed-off-by: kernel test robot <lkp@intel.com>

Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
Fixes: c7fcbf2513 ("drm/plane: check that fb_damage is set up when used")
Cc: José Roberto de Souza <jose.souza@intel.com> (v1)
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: Gwan-gyeong Mun <gwan-gyeong.mun@intel.com>
Cc: José Roberto de Souza <jose.souza@intel.com>
Cc: Hans de Goede <hdegoede@redhat.com>
Cc: Daniel Vetter <daniel.vetter@intel.com>
Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Cc: Maxime Ripard <mripard@kernel.org>
Cc: Thomas Zimmermann <tzimmermann@suse.de>
Link: https://patchwork.freedesktop.org/patch/msgid/20210730095251.4343-1-daniel.vetter@ffwll.ch
Link: https://patchwork.freedesktop.org/patch/msgid/20210730141948.GA11955@243d74413310
2021-08-02 11:15:11 +02:00

666 lines
19 KiB
C

// SPDX-License-Identifier: GPL-2.0
/*
* Test case for drm_damage_helper functions
*/
#define pr_fmt(fmt) "drm_damage_helper: " fmt
#include <drm/drm_damage_helper.h>
#include <drm/drm_plane.h>
#include <drm/drm_drv.h>
#include "test-drm_modeset_common.h"
struct drm_driver mock_driver;
static struct drm_device mock_device;
static struct drm_object_properties mock_obj_props;
static struct drm_plane mock_plane;
static struct drm_property mock_prop;
static void mock_setup(struct drm_plane_state *state)
{
static bool setup_done = false;
state->plane = &mock_plane;
if (setup_done)
return;
/* just enough so that drm_plane_enable_fb_damage_clips() works */
mock_device.driver = &mock_driver;
mock_device.mode_config.prop_fb_damage_clips = &mock_prop;
mock_plane.dev = &mock_device;
mock_plane.base.properties = &mock_obj_props;
mock_prop.base.id = 1; /* 0 is an invalid id */
mock_prop.dev = &mock_device;
drm_plane_enable_fb_damage_clips(&mock_plane);
}
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 dimension.\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;
}
const struct drm_framebuffer fb = {
.width = 2048,
.height = 2048
};
/* common mocked structs many tests need */
#define MOCK_VARIABLES() \
struct drm_plane_state old_state; \
struct drm_plane_state state = { \
.crtc = ZERO_SIZE_PTR, \
.fb = (struct drm_framebuffer *) &fb, \
.visible = true, \
}; \
mock_setup(&old_state); \
mock_setup(&state);
int igt_damage_iter_no_damage(void *ignored)
{
struct drm_atomic_helper_damage_iter iter;
struct drm_rect clip;
uint32_t num_hits = 0;
MOCK_VARIABLES();
/* 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;
}
int igt_damage_iter_no_damage_fractional_src(void *ignored)
{
struct drm_atomic_helper_damage_iter iter;
struct drm_rect clip;
uint32_t num_hits = 0;
MOCK_VARIABLES();
/* 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;
}
int igt_damage_iter_no_damage_src_moved(void *ignored)
{
struct drm_atomic_helper_damage_iter iter;
struct drm_rect clip;
uint32_t num_hits = 0;
MOCK_VARIABLES();
/* 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;
}
int igt_damage_iter_no_damage_fractional_src_moved(void *ignored)
{
struct drm_atomic_helper_damage_iter iter;
struct drm_rect clip;
uint32_t num_hits = 0;
MOCK_VARIABLES();
/* 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;
}
int igt_damage_iter_no_damage_not_visible(void *ignored)
{
struct drm_atomic_helper_damage_iter iter;
struct drm_rect clip;
uint32_t num_hits = 0;
MOCK_VARIABLES();
state.visible = false;
mock_setup(&old_state);
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;
}
int igt_damage_iter_no_damage_no_crtc(void *ignored)
{
struct drm_atomic_helper_damage_iter iter;
struct drm_rect clip;
uint32_t num_hits = 0;
MOCK_VARIABLES();
state.crtc = NULL;
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;
}
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,
};
mock_setup(&old_state);
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;
}
int igt_damage_iter_simple_damage(void *ignored)
{
struct drm_atomic_helper_damage_iter iter;
struct drm_property_blob damage_blob;
struct drm_mode_rect damage;
struct drm_rect clip;
uint32_t num_hits = 0;
MOCK_VARIABLES();
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;
}
int igt_damage_iter_single_damage(void *ignored)
{
struct drm_atomic_helper_damage_iter iter;
struct drm_property_blob damage_blob;
struct drm_mode_rect damage;
struct drm_rect clip;
uint32_t num_hits = 0;
MOCK_VARIABLES();
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;
}
int igt_damage_iter_single_damage_intersect_src(void *ignored)
{
struct drm_atomic_helper_damage_iter iter;
struct drm_property_blob damage_blob;
struct drm_mode_rect damage;
struct drm_rect clip;
uint32_t num_hits = 0;
MOCK_VARIABLES();
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;
}
int igt_damage_iter_single_damage_outside_src(void *ignored)
{
struct drm_atomic_helper_damage_iter iter;
struct drm_property_blob damage_blob;
struct drm_mode_rect damage;
struct drm_rect clip;
uint32_t num_hits = 0;
MOCK_VARIABLES();
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;
}
int igt_damage_iter_single_damage_fractional_src(void *ignored)
{
struct drm_atomic_helper_damage_iter iter;
struct drm_property_blob damage_blob;
struct drm_mode_rect damage;
struct drm_rect clip;
uint32_t num_hits = 0;
MOCK_VARIABLES();
/* 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;
}
int igt_damage_iter_single_damage_intersect_fractional_src(void *ignored)
{
struct drm_atomic_helper_damage_iter iter;
struct drm_property_blob damage_blob;
struct drm_mode_rect damage;
struct drm_rect clip;
uint32_t num_hits = 0;
MOCK_VARIABLES();
/* 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;
}
int igt_damage_iter_single_damage_outside_fractional_src(void *ignored)
{
struct drm_atomic_helper_damage_iter iter;
struct drm_property_blob damage_blob;
struct drm_mode_rect damage;
struct drm_rect clip;
uint32_t num_hits = 0;
MOCK_VARIABLES();
/* 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;
}
int igt_damage_iter_single_damage_src_moved(void *ignored)
{
struct drm_atomic_helper_damage_iter iter;
struct drm_property_blob damage_blob;
struct drm_mode_rect damage;
struct drm_rect clip;
uint32_t num_hits = 0;
MOCK_VARIABLES();
/* 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;
}
int igt_damage_iter_single_damage_fractional_src_moved(void *ignored)
{
struct drm_atomic_helper_damage_iter iter;
struct drm_property_blob damage_blob;
struct drm_mode_rect damage;
struct drm_rect clip;
uint32_t num_hits = 0;
MOCK_VARIABLES();
/* 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;
}
int igt_damage_iter_damage(void *ignored)
{
struct drm_atomic_helper_damage_iter iter;
struct drm_property_blob damage_blob;
struct drm_mode_rect damage[2];
struct drm_rect clip;
uint32_t num_hits = 0;
MOCK_VARIABLES();
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;
}
int igt_damage_iter_damage_one_intersect(void *ignored)
{
struct drm_atomic_helper_damage_iter iter;
struct drm_property_blob damage_blob;
struct drm_mode_rect damage[2];
struct drm_rect clip;
uint32_t num_hits = 0;
MOCK_VARIABLES();
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;
}
int igt_damage_iter_damage_one_outside(void *ignored)
{
struct drm_atomic_helper_damage_iter iter;
struct drm_property_blob damage_blob;
struct drm_mode_rect damage[2];
struct drm_rect clip;
uint32_t num_hits = 0;
MOCK_VARIABLES();
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;
}
int igt_damage_iter_damage_src_moved(void *ignored)
{
struct drm_atomic_helper_damage_iter iter;
struct drm_property_blob damage_blob;
struct drm_mode_rect damage[2];
struct drm_rect clip;
uint32_t num_hits = 0;
MOCK_VARIABLES();
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;
}
int igt_damage_iter_damage_not_visible(void *ignored)
{
struct drm_atomic_helper_damage_iter iter;
struct drm_property_blob damage_blob;
struct drm_mode_rect damage[2];
struct drm_rect clip;
uint32_t num_hits = 0;
MOCK_VARIABLES();
state.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;
}