All of lore.kernel.org
 help / color / mirror / Atom feed
From: Paul Kocialkowski <paul.kocialkowski@bootlin.com>
To: Lyude Paul <lyude@redhat.com>, igt-dev@lists.freedesktop.org
Cc: Petri Latvala <petri.latvala@intel.com>,
	Eben Upton <eben@raspberrypi.org>,
	Thomas Petazzoni <thomas.petazzoni@bootlin.com>
Subject: Re: [igt-dev] [PATCH i-g-t v3 21/21] chamelium: Add a display test for randomized planes
Date: Fri, 25 Jan 2019 14:58:56 +0100	[thread overview]
Message-ID: <a2e4df6f896eadb2432d4932b214689d1a3af42a.camel@bootlin.com> (raw)
In-Reply-To: <6b128c813b480be98fcb68666884ca9bfb6c0c5d.camel@redhat.com>

Hi,

On Tue, 2019-01-15 at 17:56 -0500, Lyude Paul wrote:
> On Fri, 2019-01-11 at 10:05 +0100, Paul Kocialkowski wrote:
> > This introduces a new test for the Chamelium, that sets up planes
> > with randomized properties such as the format, dimensions, position,
> > in-framebuffer offsets and stride. The Chamelium capture is checked
> > against the reference generated by cairo with either a CRC or the
> > checkerboard-specific comparison method.
> > 
> > This test also includes testing of the VC4-specific T-tiled and
> > SAND-tiled modes, in all formats supported by the hardware.
> > 
> > Since this test does not share much with previous Chamelium display
> > tests (especially regarding KMS configuration), most of the code is
> > not shared with other tests.
> > 
> > This test can be derived with reproducible properties for regression
> > testing in the future. For now, it serves as a fuzzing test
> > 
> > Signed-off-by: Paul Kocialkowski <paul.kocialkowski@bootlin.com>
> > ---
> >  tests/kms_chamelium.c | 446 ++++++++++++++++++++++++++++++++++++++++++
> >  1 file changed, 446 insertions(+)
> > 
> > diff --git a/tests/kms_chamelium.c b/tests/kms_chamelium.c
> > index 2779d74f55b6..5963964878ba 100644
> > --- a/tests/kms_chamelium.c
> > +++ b/tests/kms_chamelium.c
> > @@ -26,6 +26,7 @@
> >  
> >  #include "config.h"
> >  #include "igt.h"
> > +#include "igt_vc4.h"
> >  
> >  #include <fcntl.h>
> >  #include <string.h>
> > @@ -702,6 +703,443 @@ test_display_frame_dump(data_t *data, struct
> > chamelium_port *port)
> >  	drmModeFreeConnector(connector);
> >  }
> >  
> > +static void randomize_plane_format_stride(igt_plane_t *plane, uint32_t
> > width,
> > +					  uint32_t *format, size_t *stride,
> > +					  bool *tiled, bool allow_yuv)
> > +{
> > +	size_t stride_min;
> > +	uint32_t *formats_array;
> > +	unsigned int formats_count;
> > +	unsigned int count = 0;
> > +	unsigned int i;
> > +	int index;
> > +
> > +	igt_format_array_fill(&formats_array, &formats_count, allow_yuv);
> > +
> > +	/* First pass to count the supported formats. */
> > +	for (i = 0; i < formats_count; i++)
> > +		if (igt_plane_has_format_mod(plane, formats_array[i],
> > +					     DRM_FORMAT_MOD_LINEAR))
> > +			count++;
> > +
> > +	igt_assert(count > 0);
> > +
> > +	index = rand() % count;
> > +
> > +	/* Second pass to get the index-th supported format. */
> > +	for (i = 0; i < formats_count; i++) {
> > +		if (!igt_plane_has_format_mod(plane, formats_array[i],
> > +					      DRM_FORMAT_MOD_LINEAR))
> > +			continue;
> > +
> > +		if (!index--) {
> > +			*format = formats_array[i];
> > +			break;
> > +		}
> > +	}
> > +
> > +	free(formats_array);
> > +
> > +	igt_assert(index < 0);
> > +
> > +	stride_min = width * igt_format_plane_bpp(*format, 0) / 8;
> > +
> > +	/* Randomize the stride with at most twice the minimum. */
> > +	*stride = (rand() % stride_min) + stride_min;
> Maybe need to change the comment or fix this line? Given
> 
> rand() = 9999999
> stride_min = 10
> 
> This would come out to 19, e.g. less then twice the maximum. Maybe you meant
> 
> *stride = (rand() % (stride_min + 1)) + stride_min;

Good catch, thanks! I think I'll just update the comments to be
consistent though, having the limit included or not does not cause
adverse effects in practice (in these cases only, I think I had already
taken care of the ones where it's significant) and I find it slightly
more readable with the limit excluded.

[...]

> > +static void prepare_tiled_plane(data_t *data, igt_plane_t *plane,
> > +				unsigned int index, uint32_t format,
> > +				struct igt_fb *overlay_fb)
> > +{
> > +	struct igt_fb tiled_fb;
> > +	unsigned int fb_id;
> > +
> > +	if (is_vc4_device(data->drm_fd) &&
> > +	    igt_vc4_plane_supports_t_tiling(plane, format)) {
> > +		igt_debug("Plane %d: using VC4 T-tiling\n", index);
> > +
> > +		fb_id = igt_vc4_fb_t_tiled_convert(&tiled_fb, overlay_fb);
> > +	} else if (is_vc4_device(data->drm_fd) &&
> > +		   igt_vc4_plane_supports_sand_tiling(plane, format, 256)) {
> > +		/* Randomize the column height with at most twice the height.
> > */
> > +		size_t column_height = (rand() % overlay_fb->height) +
> > +				       overlay_fb->height;
> > +
> > +		igt_debug("Plane %d: using VC4 SAND256 tiling with column
> > height %ld\n",
> > +			  index, column_height);
> > +
> > +		fb_id = vc4_fb_sand_tiled_convert(&tiled_fb, overlay_fb, 256,
> > +						  column_height);
> > +	} else {
> > +		return;
> > +	}
> 
> Bikeshed: Why not remove the two is_vc4_device(data->drm_fd) checks and just
> put this at the top of prepare_tiled_plane():
> 
> if (!is_vc4_device(data->drm_fd))
> 	return;
> 
> Would make these conditionals a bit easier to read

I have dropped that check altogether. After all, there is no need to
double-check for VC4 if the modifiers were reported by the driver.

> > +
> > +	igt_assert(fb_id > 0);
> > +
> > +	/* Make the tiled framebuffer the overlay. */
> > +	igt_remove_fb(data->drm_fd, overlay_fb);
> > +	*overlay_fb = tiled_fb;
> > +}
> > +
> > +static void prepare_randomized_plane(data_t *data,
> > +				     drmModeModeInfo *mode,
> > +				     igt_plane_t *plane,
> > +				     struct igt_fb *overlay_fb,
> > +				     unsigned int index,
> > +				     cairo_surface_t *result_surface,
> > +				     bool allow_scaling, bool allow_yuv)
> > +{
> > +	struct igt_fb pattern_fb;
> > +	uint32_t overlay_fb_w, overlay_fb_h;
> > +	uint32_t overlay_src_w, overlay_src_h;
> > +	uint32_t overlay_src_x, overlay_src_y;
> > +	int32_t overlay_crtc_x, overlay_crtc_y;
> > +	uint32_t overlay_crtc_w, overlay_crtc_h;
> > +	uint32_t format;
> > +	size_t stride;
> > +	bool tiled;
> > +	int fb_id;
> > +
> > +	randomize_plane_dimensions(mode, &overlay_fb_w, &overlay_fb_h,
> > +				   &overlay_src_w, &overlay_src_h,
> > +				   &overlay_src_x, &overlay_src_y,
> > +				   &overlay_crtc_w, &overlay_crtc_h,
> > +				   &overlay_crtc_x, &overlay_crtc_y,
> > +				   allow_scaling);
> > +
> > +	igt_debug("Plane %d: framebuffer size %dx%d\n", index,
> > +		  overlay_fb_w, overlay_fb_h);
> > +	igt_debug("Plane %d: on-crtc size %dx%d\n", index,
> > +		  overlay_crtc_w, overlay_crtc_h);
> > +	igt_debug("Plane %d: on-crtc position %dx%d\n", index,
> > +		  overlay_crtc_x, overlay_crtc_y);
> > +	igt_debug("Plane %d: in-framebuffer size %dx%d\n", index,
> > +		  overlay_src_w, overlay_src_h);
> > +	igt_debug("Plane %d: in-framebuffer position %dx%d\n", index,
> > +		  overlay_src_x, overlay_src_y);
> > +
> > +	/* Get a pattern framebuffer for the overlay plane. */
> > +	fb_id = chamelium_get_pattern_fb(data, overlay_fb_w, overlay_fb_h,
> > +					 DRM_FORMAT_XRGB8888, 32,
> > &pattern_fb);
> > +	igt_assert(fb_id > 0);
> > +
> > +	randomize_plane_format_stride(plane, overlay_fb_w, &format, &stride,
> > +				      &tiled, allow_yuv);
> > +
> > +	igt_debug("Plane %d: %s format with stride %ld\n", index,
> > +		  igt_format_str(format), stride);
> > +
> > +	fb_id = igt_fb_convert_with_stride(overlay_fb, &pattern_fb, format,
> > +					   stride);
> > +	igt_assert(fb_id > 0);
> > +
> > +	if (tiled)
> > +		prepare_tiled_plane(data, plane, index, format, overlay_fb);
> > +
> > +	blit_plane_cairo(data, result_surface, overlay_src_w, overlay_src_h,
> > +			 overlay_src_x, overlay_src_y,
> > +			 overlay_crtc_w, overlay_crtc_h,
> > +			 overlay_crtc_x, overlay_crtc_y, &pattern_fb);
> > +
> > +	configure_plane(plane, overlay_src_w, overlay_src_h,
> > +			overlay_src_x, overlay_src_y,
> > +			overlay_crtc_w, overlay_crtc_h,
> > +			overlay_crtc_x, overlay_crtc_y, overlay_fb);
> > +
> > +	/* Remove the original pattern framebuffer. */
> > +	igt_remove_fb(data->drm_fd, &pattern_fb);
> > +}
> > +
> > +static void test_display_planes_random(data_t *data,
> > +				       struct chamelium_port *port,
> > +				       enum chamelium_check check)
> > +{
> > +	igt_output_t *output;
> > +	drmModeModeInfo *mode;
> > +	igt_plane_t *primary_plane;
> > +	struct igt_fb primary_fb;
> > +	struct igt_fb result_fb;
> > +	struct igt_fb *overlay_fbs;
> > +	igt_crc_t *crc;
> > +	igt_crc_t *expected_crc;
> > +	struct chamelium_fb_crc_async_data *fb_crc;
> > +	unsigned int overlay_planes_max = 0;
> > +	unsigned int overlay_planes_count;
> > +	cairo_surface_t *result_surface;
> > +	int captured_frame_count;
> > +	bool allow_scaling;
> > +	bool allow_yuv;
> > +	unsigned int i;
> > +	unsigned int fb_id;
> > +
> > +	switch (check) {
> > +	case CHAMELIUM_CHECK_CRC:
> > +		allow_scaling = false;
> > +		allow_yuv = false;
> > +		break;
> > +	case CHAMELIUM_CHECK_CHECKERBOARD:
> > +		allow_scaling = true;
> > +		allow_yuv = true;
> > +		break;
> > +	default:
> > +		igt_assert(false);
> > +	}
> > +
> > +	srand(time(NULL));
> > +
> > +	reset_state(data, port);
> > +
> > +	/* Find the connector and pipe. */
> > +	output = prepare_output(data, port);
> > +
> > +	mode = igt_output_get_mode(output);
> > +
> > +	/* Get a framebuffer for the primary plane. */
> > +	primary_plane = igt_output_get_plane_type(output,
> > DRM_PLANE_TYPE_PRIMARY);
> > +	igt_assert(primary_plane);
> > +
> > +	fb_id = chamelium_get_pattern_fb(data, mode->hdisplay, mode->vdisplay,
> > +					 DRM_FORMAT_XRGB8888, 64,
> > &primary_fb);
> > +	igt_assert(fb_id > 0);
> > +
> > +	/* Get a framebuffer for the cairo composition result. */
> > +	fb_id = igt_create_fb(data->drm_fd, mode->hdisplay,
> > +			      mode->vdisplay, DRM_FORMAT_XRGB8888,
> > +			      LOCAL_DRM_FORMAT_MOD_NONE, &result_fb);
> > +	igt_assert(fb_id > 0);
> > +
> > +	result_surface = igt_get_cairo_surface(data->drm_fd, &result_fb);
> > +
> > +	/* Paint the primary framebuffer on the result surface. */
> > +	blit_plane_cairo(data, result_surface, 0, 0, 0, 0, 0, 0, 0, 0,
> > +			 &primary_fb);
> > +
> > +	/* Configure the primary plane. */
> > +	igt_plane_set_fb(primary_plane, &primary_fb);
> > +
> > +	overlay_planes_max =
> > +		igt_output_count_plane_type(output, DRM_PLANE_TYPE_OVERLAY);
> > +
> > +	/* Limit the number of planes to a reasonable scene. */
> > +	if (overlay_planes_max > 4)
> > +		overlay_planes_max = 4;
> 
> Why not just use max() here?

Sure, I'll do that!

> > +
> > +	overlay_planes_count = (rand() % overlay_planes_max) + 1;
> > +	igt_debug("Using %d overlay planes\n", overlay_planes_count);
> > +
> > +	overlay_fbs = calloc(sizeof(struct igt_fb), overlay_planes_count);
> igt_assert(overlay_fbs);
> 
> Other then that, looks really good!

Great, thanks a lot for the review!

Cheers,

Paul

> > +
> > +	for (i = 0; i < overlay_planes_count; i++) {
> > +		struct igt_fb *overlay_fb = &overlay_fbs[i];
> > +		igt_plane_t *plane =
> > +			igt_output_get_plane_type_index(output,
> > +							DRM_PLANE_TYPE_OVERLAY
> > ,
> > +							i);
> > +		igt_assert(plane);
> > +
> > +		prepare_randomized_plane(data, mode, plane, overlay_fb, i,
> > +					 result_surface, allow_scaling,
> > +					 allow_yuv);
> > +	}
> > +
> > +	cairo_surface_destroy(result_surface);
> > +
> > +	if (check == CHAMELIUM_CHECK_CRC)
> > +		fb_crc = chamelium_calculate_fb_crc_async_start(data->drm_fd,
> > +								&result_fb);
> > +
> > +	igt_display_commit2(&data->display, COMMIT_ATOMIC);
> > +
> > +	if (check == CHAMELIUM_CHECK_CRC) {
> > +		chamelium_capture(data->chamelium, port, 0, 0, 0, 0, 1);
> > +		crc = chamelium_read_captured_crcs(data->chamelium,
> > +						   &captured_frame_count);
> > +
> > +		igt_assert(captured_frame_count == 1);
> > +
> > +		expected_crc =
> > chamelium_calculate_fb_crc_async_finish(fb_crc);
> > +
> > +		chamelium_assert_crc_eq_or_dump(data->chamelium,
> > +						expected_crc, crc,
> > +						&result_fb, 0);
> > +
> > +		free(expected_crc);
> > +		free(crc);
> > +	} else if (check == CHAMELIUM_CHECK_CHECKERBOARD) {
> > +		struct chamelium_frame_dump *dump;
> > +
> > +		dump = chamelium_port_dump_pixels(data->chamelium, port, 0, 0,
> > +						  0, 0);
> > +		chamelium_assert_frame_match_or_dump(data->chamelium, port,
> > +						     dump, &result_fb, check);
> > +		chamelium_destroy_frame_dump(dump);
> > +	}
> > +
> > +	for (i = 0; i < overlay_planes_count; i++) {
> > +		struct igt_fb *overlay_fb = &overlay_fbs[i];
> > +		igt_plane_t *plane;
> > +
> > +		plane = igt_output_get_plane_type_index(output,
> > +							DRM_PLANE_TYPE_OVERLAY
> > ,
> > +							i);
> > +		igt_assert(plane);
> > +
> > +		igt_remove_fb(data->drm_fd, overlay_fb);
> > +	}
> > +
> > +	free(overlay_fbs);
> > +
> > +	igt_remove_fb(data->drm_fd, &primary_fb);
> > +	igt_remove_fb(data->drm_fd, &result_fb);
> > +}
> > +
> >  static void
> >  test_hpd_without_ddc(data_t *data, struct chamelium_port *port)
> >  {
> > @@ -976,6 +1414,10 @@ igt_main
> >  			test_display_one_mode(&data, port,
> > DRM_FORMAT_XRGB1555,
> >  					      CHAMELIUM_CHECK_CRC, 1);
> >  
> > +		connector_subtest("hdmi-crc-planes-random", HDMIA)
> > +			test_display_planes_random(&data, port,
> > +						   CHAMELIUM_CHECK_CRC);
> > +
> >  		connector_subtest("hdmi-cmp-nv12", HDMIA)
> >  			test_display_one_mode(&data, port, DRM_FORMAT_NV12,
> >  					      CHAMELIUM_CHECK_CHECKERBOARD,
> > 1);
> > @@ -1008,6 +1450,10 @@ igt_main
> >  			test_display_one_mode(&data, port, DRM_FORMAT_YVU422,
> >  					      CHAMELIUM_CHECK_CHECKERBOARD,
> > 1);
> >  
> > +		connector_subtest("hdmi-cmp-planes-random", HDMIA)
> > +			test_display_planes_random(&data, port,
> > +						   CHAMELIUM_CHECK_CHECKERBOAR
> > D);
> > +
> >  		connector_subtest("hdmi-frame-dump", HDMIA)
> >  			test_display_frame_dump(&data, port);
> >  	}
-- 
Paul Kocialkowski, Bootlin
Embedded Linux and kernel engineering
https://bootlin.com

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

  reply	other threads:[~2019-01-25 13:58 UTC|newest]

Thread overview: 67+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-01-11  9:05 [igt-dev] [PATCH i-g-t v3 00/21] Chamelium VC4 plane fuzzy testing, with SAND and T-tiled mode Paul Kocialkowski
2019-01-11  9:05 ` [igt-dev] [PATCH i-g-t v3 01/21] lib: drmtest: Add helpers to check and require the VC4 driver Paul Kocialkowski
2019-01-11  9:05 ` [igt-dev] [PATCH i-g-t v3 02/21] lib/igt_fb: Add checks on i915 for i915-specific tiled buffer allocation Paul Kocialkowski
2019-01-11 15:09   ` Maxime Ripard
2019-01-15  0:39   ` Lyude Paul
2019-01-11  9:05 ` [igt-dev] [PATCH i-g-t v3 03/21] lib/igt_fb: Add support for allocating T-tiled VC4 buffers Paul Kocialkowski
2019-01-11 15:09   ` Maxime Ripard
2019-01-15  0:41   ` Lyude Paul
2019-01-11  9:05 ` [igt-dev] [PATCH i-g-t v3 04/21] lib/igt_fb: Add support for VC4 SAND tiling modes Paul Kocialkowski
2019-01-11 15:09   ` Maxime Ripard
2019-01-15  0:43   ` Lyude Paul
2019-01-11  9:05 ` [igt-dev] [PATCH i-g-t v3 05/21] lib/igt_fb: Allow interpreting the tile height as a stride equivalent Paul Kocialkowski
2019-01-11 15:10   ` Maxime Ripard
2019-01-15  0:45   ` Lyude Paul
2019-01-11  9:05 ` [igt-dev] [PATCH i-g-t v3 06/21] lib/igt_fb: Add a stride-provisioned fashion of igt_fb_convert Paul Kocialkowski
2019-01-11  9:05 ` [igt-dev] [PATCH i-g-t v3 07/21] lib/igt_fb: Add a helper to retreive the plane bpp for a given format Paul Kocialkowski
2019-01-11  9:05 ` [igt-dev] [PATCH i-g-t v3 08/21] lib/igt_fb: Add a helper to fill-in the available DRM formats Paul Kocialkowski
2019-01-15 20:49   ` Lyude Paul
2019-01-11  9:05 ` [igt-dev] [PATCH i-g-t v3 09/21] lib/igt_vc4: Add helpers for converting linear to T-tiled RGB buffers Paul Kocialkowski
2019-01-11 15:25   ` Maxime Ripard
2019-01-14 14:57     ` Paul Kocialkowski
2019-01-15 21:20   ` Lyude Paul
2019-01-22 16:07     ` Paul Kocialkowski
2019-01-22 17:47       ` Lyude Paul
2019-01-11  9:05 ` [igt-dev] [PATCH i-g-t v3 10/21] lib/igt_vc4: Add helper for checking T-tiling support on plane Paul Kocialkowski
2019-01-11 15:11   ` Maxime Ripard
2019-01-15 21:49   ` Lyude Paul
2019-01-11  9:05 ` [igt-dev] [PATCH i-g-t v3 11/21] lib/igt_vc4: Add helpers for converting linear to SAND-tiled buffers Paul Kocialkowski
2019-01-15 21:53   ` Lyude Paul
2019-01-11  9:05 ` [igt-dev] [PATCH i-g-t v3 12/21] lib/igt_vc4: Add helper for checking SAND tiling support on plane Paul Kocialkowski
2019-01-11 15:15   ` Maxime Ripard
2019-01-14 15:01     ` Paul Kocialkowski
2019-01-15  8:25       ` Maxime Ripard
2019-01-15 21:54   ` Lyude Paul
2019-01-11  9:05 ` [igt-dev] [PATCH i-g-t v3 13/21] lib/igt_kms: Add helpers to count and iterate planes from pipe Paul Kocialkowski
2019-01-11 15:11   ` Maxime Ripard
2019-01-15 21:57   ` Lyude Paul
2019-01-11  9:05 ` [igt-dev] [PATCH i-g-t v3 14/21] lib/igt_kms: Add helpers to count and iterate planes from output Paul Kocialkowski
2019-01-11 15:12   ` Maxime Ripard
2019-01-15 22:00   ` Lyude Paul
2019-01-11  9:05 ` [igt-dev] [PATCH i-g-t v3 15/21] lib/igt_chamelium: Fixup resources liberation in comparison helpers Paul Kocialkowski
2019-01-11 15:15   ` Maxime Ripard
2019-01-15 22:01   ` Lyude Paul
2019-01-11  9:05 ` [igt-dev] [PATCH i-g-t v3 16/21] lib/igt_chamelium: Split frames dump logic and rework surroundings Paul Kocialkowski
2019-01-11 15:16   ` Maxime Ripard
2019-01-15 22:05   ` Lyude Paul
2019-01-11  9:05 ` [igt-dev] [PATCH i-g-t v3 17/21] lib/igt_chamelium: Generalize the frame match helper with check type Paul Kocialkowski
2019-01-11 15:17   ` Maxime Ripard
2019-01-15 22:07   ` Lyude Paul
2019-01-11  9:05 ` [igt-dev] [PATCH i-g-t v3 18/21] lib/igt_frame: Add a checkerboard frame comparison method Paul Kocialkowski
2019-01-11 15:19   ` Maxime Ripard
2019-01-14 15:04     ` Paul Kocialkowski
2019-01-15 16:13       ` Maxime Ripard
2019-01-15 22:14   ` Lyude Paul
2019-01-11  9:05 ` [igt-dev] [PATCH i-g-t v3 19/21] lib/igt_chamelium: Hook-in checkerboard comparison method in helpers Paul Kocialkowski
2019-01-11 15:19   ` Maxime Ripard
2019-01-15 22:14   ` Lyude Paul
2019-01-11  9:05 ` [igt-dev] [PATCH i-g-t v3 20/21] chamelium: Move the YUV tests over to the checkerboard checking method Paul Kocialkowski
2019-01-11 15:20   ` Maxime Ripard
2019-01-15 22:15   ` Lyude Paul
2019-01-11  9:05 ` [igt-dev] [PATCH i-g-t v3 21/21] chamelium: Add a display test for randomized planes Paul Kocialkowski
2019-01-11 15:23   ` Maxime Ripard
2019-01-15 22:56   ` Lyude Paul
2019-01-25 13:58     ` Paul Kocialkowski [this message]
2019-01-11  9:29 ` [igt-dev] ✗ Fi.CI.BAT: failure for Chamelium VC4 plane fuzzy testing, with SAND and T-tiled mode Patchwork
2019-01-15  0:46 ` [igt-dev] [PATCH i-g-t v3 00/21] " Lyude Paul
2019-01-15  9:34   ` Paul Kocialkowski

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=a2e4df6f896eadb2432d4932b214689d1a3af42a.camel@bootlin.com \
    --to=paul.kocialkowski@bootlin.com \
    --cc=eben@raspberrypi.org \
    --cc=igt-dev@lists.freedesktop.org \
    --cc=lyude@redhat.com \
    --cc=petri.latvala@intel.com \
    --cc=thomas.petazzoni@bootlin.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.