RE: [PATCH v2 2/2] drm/selftest: Add drm damage helper selftest

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



> Hi Deepak,
> 
> Something to consider, with this approach we kind of break the
> following behaviour:
> "Only tests enabled as module parameters are run, if no test is
> explicitly enabled then all of them are run"
> 
> What I think we should do is have just one header where we put the
> selftest(check_plane_state, igt_check_plane_statea)
> ...
> selftest(damage_iter_no_damage, igt_damage_iter_no_damage)
> ...
> call it drm_modeset_selftests.h
> 
> And separate just the implementations in different source files.
> 
> Then we could call run_selftests just once from test_drm_modeset_init.
> 
> Does this makes sense to you?
> 

Hi Alexandru,

Thanks for the review. Yes this does make sense to me. I will change this
one to have run_selftests on one single header, single patch 01 is already
merged to drm-mics. 


> > > > Cc: Daniel Vetter <daniel.vetter@xxxxxxxx>
> > > > Cc: alexandru-cosmin.gheorghe@xxxxxxx
> > > > Signed-off-by: Deepak Rawat <drawat@xxxxxxxxxx>
> > > > Reviewed-by: Daniel Vetter <daniel.vetter@xxxxxxxx>
> > > > Reviewed-by: Thomas Hellstrom <thellstrom@xxxxxxxxxx>
> > >
> > > I guess this needs your entire damage series to make sense, right?
> >
> > Ah yes sorry. Although this patch is same as what I sent earlier
> > except linking with test-drm_modeset.ko
> >
> > >
> > > Another question: Does anyone from vmwgfx want drm-misc commit rights
> for
> > > pushing stuff like this?
> >
> > Hi Daniel, Thanks for the suggestion. I am not sure about eligibility criteria for
> > commit rights but I think I will wait until drm-mics is moved to gitlab and I have
> > more experience working with open-source. Beside me Thomas works on
> > vmwgfx, I am not sure if he already have commit rights.
> >
> > > -Daniel
> > > > ---
> > > >  drivers/gpu/drm/selftests/Makefile            |   3 +-
> > > >  .../selftests/drm_damage_helper_selftests.h   |  22 +
> > > >  .../drm/selftests/test-drm_damage_helper.c    | 828
> ++++++++++++++++++
> > > >  .../drm/selftests/test-drm_modeset_common.c   |  10 +-
> > > >  .../drm/selftests/test-drm_modeset_common.h   |   1 +
> > > >  5 files changed, 862 insertions(+), 2 deletions(-)
> > > >  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 7e6581921da0..c6e63ed12f02 100644
> > > > --- a/drivers/gpu/drm/selftests/Makefile
> > > > +++ b/drivers/gpu/drm/selftests/Makefile
> > > > @@ -1,3 +1,4 @@
> > > > -test-drm_modeset-y := test-drm_modeset_common.o test-
> > > drm_plane_helper.o
> > > > +test-drm_modeset-y := test-drm_modeset_common.o test-
> > > drm_plane_helper.o \
> > > > +		      test-drm_damage_helper.o
> > > >
> > > >  obj-$(CONFIG_DRM_DEBUG_SELFTEST) += test-drm_mm.o test-
> > > drm_modeset.o
> > > > 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..9cec7778e5b2
> > > > --- /dev/null
> > > > +++ b/drivers/gpu/drm/selftests/test-drm_damage_helper.c
> > > > @@ -0,0 +1,828 @@
> > > > +// 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 "test-drm_modeset_common.h"
> > > > +
> > > > +#define TESTS "drm_damage_helper_selftests.h"
> > > > +#include "drm_selftest.h"
> > > > +
> > > > +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"
> > > > +
> > > > +/**
> > > > + * test_drm_damage_helper - Run drm damage helper selftests.
> > > > + */
> > > > +int test_drm_damage_helper(void)
> > > > +{
> > > > +	int err;
> > > > +
> > > > +	err = run_selftests(selftests, ARRAY_SIZE(selftests), NULL);
> > > > +
> > > > +	return err > 0 ? 0 : err;
> > > > +}
> > > > diff --git a/drivers/gpu/drm/selftests/test-drm_modeset_common.c
> > > b/drivers/gpu/drm/selftests/test-drm_modeset_common.c
> > > > index fad5209043f1..43a9ab522a66 100644
> > > > --- a/drivers/gpu/drm/selftests/test-drm_modeset_common.c
> > > > +++ b/drivers/gpu/drm/selftests/test-drm_modeset_common.c
> > > > @@ -9,7 +9,15 @@
> > > >
> > > >  static int __init test_drm_modeset_init(void)
> > > >  {
> > > > -	return test_drm_plane_helper();
> > > > +	int ret = 0, err;
> > > > +
> > > > +	if ((err = test_drm_plane_helper()))
> > > > +		ret = err;
> > > > +
> > > > +	if ((err = test_drm_damage_helper()))
> > > > +		ret = err;
> > > > +
> > > > +	return ret;
> > > >  }
> > > >
> > > >  static void __exit test_drm_modeset_exit(void)
> > > > diff --git a/drivers/gpu/drm/selftests/test-drm_modeset_common.h
> > > b/drivers/gpu/drm/selftests/test-drm_modeset_common.h
> > > > index bdeba264661f..5fa8fb07e0e9 100644
> > > > --- a/drivers/gpu/drm/selftests/test-drm_modeset_common.h
> > > > +++ b/drivers/gpu/drm/selftests/test-drm_modeset_common.h
> > > > @@ -14,5 +14,6 @@
> > > >  #define FAIL_ON(x) FAIL((x), "%s", "FAIL_ON(" __stringify(x) ")\n")
> > > >
> > > >  int test_drm_plane_helper(void);
> > > > +int test_drm_damage_helper(void);
> > > >
> > > >  #endif
> > > > --
> > > > 2.17.1
> > > >
> > >
> > > --
> > > Daniel Vetter
> > > Software Engineer, Intel Corporation
> > >
> https://na01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fblog.ffwll.
> > >
> ch&amp;data=02%7C01%7Cdrawat%40vmware.com%7C26ffc4b4ed0b4da17da
> > >
> 508d633fb73a4%7Cb39138ca3cee4b4aa4d6cd83d9dd62f0%7C1%7C0%7C63675
> > >
> 3552420942632&amp;sdata=rq68c2dOssSNp2B1gC6verDYoItm6mSGPS4oIwJzJa
> > > c%3D&amp;reserved=0
> > _______________________________________________
> > dri-devel mailing list
> > dri-devel@xxxxxxxxxxxxxxxxxxxxx
> >
> https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Flists.freed
> esktop.org%2Fmailman%2Flistinfo%2Fdri-
> devel&amp;data=02%7C01%7Cdrawat%40vmware.com%7C5bf5fab9045d42212
> 79308d635a44710%7Cb39138ca3cee4b4aa4d6cd83d9dd62f0%7C1%7C0%7C63
> 6755377032775591&amp;sdata=zog2AzRVKdj8ynnU%2F9sbM7G4jJK1g6WzjT08
> BrkSwpg%3D&amp;reserved=0
> 
> --
> Cheers,
> Alex G
> _______________________________________________
> dri-devel mailing list
> dri-devel@xxxxxxxxxxxxxxxxxxxxx
> https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Flists.freed
> esktop.org%2Fmailman%2Flistinfo%2Fdri-
> devel&amp;data=02%7C01%7Cdrawat%40vmware.com%7C5bf5fab9045d42212
> 79308d635a44710%7Cb39138ca3cee4b4aa4d6cd83d9dd62f0%7C1%7C0%7C63
> 6755377032775591&amp;sdata=zog2AzRVKdj8ynnU%2F9sbM7G4jJK1g6WzjT08
> BrkSwpg%3D&amp;reserved=0
_______________________________________________
dri-devel mailing list
dri-devel@xxxxxxxxxxxxxxxxxxxxx
https://lists.freedesktop.org/mailman/listinfo/dri-devel





[Index of Archives]     [Linux DRI Users]     [Linux Intel Graphics]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [XFree86]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [XFree86]
  Powered by Linux