public inbox for igt-dev@lists.freedesktop.org
 help / color / mirror / Atom feed
From: Austin Hu <austin.hu@intel.com>
To: igt-dev@lists.freedesktop.org
Cc: chris@chris-wilson.co.uk
Subject: [PATCH i-g-t] tools/intel_framebuffer_dump: dump frame buffers with igt_fb API.
Date: Mon, 16 Mar 2026 11:36:58 -0700	[thread overview]
Message-ID: <20260316183658.384575-1-austin.hu@intel.com> (raw)

This app is out of date as it opens i915 DRM device to just dump
the "main" frame buffer connected to a CRTC.

So improve it to support Xe driver as well, and dump all the frame
buffers attached to active Planes (including Cursor) of each CRTC
with igt_fb API.

Signed-off-by: Austin Hu <austin.hu@intel.com>
---
 tools/intel_framebuffer_dump.c | 137 +++++++++++++++++++--------------
 1 file changed, 81 insertions(+), 56 deletions(-)

diff --git a/tools/intel_framebuffer_dump.c b/tools/intel_framebuffer_dump.c
index 79c0688b1..907c65a14 100644
--- a/tools/intel_framebuffer_dump.c
+++ b/tools/intel_framebuffer_dump.c
@@ -36,75 +36,100 @@
 
 #include "intel_io.h"
 #include "drmtest.h"
+#include "igt_fb.h"
 
-int main(int argc, char **argv)
+static void dump_frame_buffer(int fd, uint32_t crtc_id, uint32_t fb_id)
 {
-	drmModeResPtr res;
-	int fd, n;
+	drmModeFB2Ptr fb = drmModeGetFB2(fd, fb_id);
+
+	if (fb == NULL)
+		return;
+
+	/* Wrap drmModeFB2Ptr object into the igt_fb one. */
+	struct igt_fb igt_fb;
+
+	igt_init_fb(&igt_fb, fd, fb->width, fb->height,
+			fb->pixel_format, fb->modifier,
+			IGT_COLOR_YCBCR_BT709, IGT_COLOR_YCBCR_LIMITED_RANGE);
+
+	/* Update more attributes of the igt_fb object. */
+	igt_calc_fb_size(&igt_fb);
+
+	/* Import the GEM handle from drmModeFB2Ptr object into igt_fb object. */
+	igt_fb.gem_handle = fb->handles[0];
+
+	/* Dump the framebuffer contents with igt_fb and Cairo APIs. */
+	/* Note: the FB memory layout may be non-linear (like X/Y-Major Tile). */
+	cairo_surface_t *surface = igt_get_cairo_surface(fd, &igt_fb);
+
+	if (surface != NULL) {
+		char name[80];
 
-	fd = drmOpen("i915", NULL);
+		snprintf(name, sizeof(name), "crtc-%d-fb-%d.png", crtc_id, fb->fb_id);
+		cairo_surface_write_to_png(surface, name);
+		fprintf(stdout, "Framebuffer dumped to %s\n", name);
+
+		cairo_surface_destroy(surface);
+	}
+
+	drmModeFreeFB2(fb);
+}
+
+int main(int argc, char **argv)
+{
+	int fd = drm_open_driver(DRIVER_INTEL | DRIVER_XE);
 	if (fd < 0)
-		return ENOENT;
+		return -ENOENT;
 
-	res = drmModeGetResources(fd);
-	if (res == NULL)
-		return ENOMEM;
+	/* To enumerate DRM Plane attached to cursor frame buffer. */
+	drmSetClientCap(fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1);
 
-	for (n = 0; n < res->count_crtcs; n++) {
-		struct drm_gem_open open_arg;
-		struct drm_gem_flink flink;
-		drmModeCrtcPtr crtc;
-		drmModeFBPtr fb;
+	drmModeResPtr res = drmModeGetResources(fd);
 
-		crtc = drmModeGetCrtc(fd, res->crtcs[n]);
-		if (crtc == NULL)
-			continue;
+	if (res == NULL) {
+		close(fd);
+		return -ENOMEM;
+	}
 
-		fb = drmModeGetFB(fd, crtc->buffer_id);
-		drmModeFreeCrtc(crtc);
-		if (fb == NULL)
-			continue;
+	drmModePlaneResPtr pres = drmModeGetPlaneResources(fd);
 
-		flink.handle = fb->handle;
-		if (drmIoctl(fd, DRM_IOCTL_GEM_FLINK, &flink)) {
-			drmModeFreeFB(fb);
+	if (pres == NULL) {
+		drmModeFreeResources(res);
+		close(fd);
+		return -ENOMEM;
+	}
+
+	/* Iterate CRTCs. */
+	for (int c = 0; c < res->count_crtcs; c++) {
+		uint32_t cid = res->crtcs[c];
+		drmModeCrtcPtr crtc = drmModeGetCrtc(fd, cid);
+
+		if ((crtc == NULL) || (crtc->buffer_id == 0))
 			continue;
-		}
 
-		open_arg.name = flink.name;
-		if (drmIoctl(fd, DRM_IOCTL_GEM_OPEN, &open_arg) == 0) {
-			struct drm_i915_gem_mmap_gtt mmap_arg;
-			void *ptr;
-
-						mmap_arg.handle = open_arg.handle;
-			if (drmIoctl(fd, DRM_IOCTL_I915_GEM_MMAP_GTT, &mmap_arg) == 0 &&
-			    (ptr = mmap(0, open_arg.size, PROT_READ, MAP_SHARED, fd, mmap_arg.offset)) != (void *)-1) {
-				cairo_surface_t *surface;
-				cairo_format_t format;
-				char name[80];
-
-				snprintf(name, sizeof(name), "fb-%d.png",  fb->fb_id);
-
-				switch (fb->depth) {
-				case 16: format = CAIRO_FORMAT_RGB16_565; break;
-				case 24: format = CAIRO_FORMAT_RGB24; break;
-				case 30: format = CAIRO_FORMAT_RGB30; break;
-				case 32: format = CAIRO_FORMAT_ARGB32; break;
-				default: format = CAIRO_FORMAT_INVALID; break;
-				}
-
-				surface = cairo_image_surface_create_for_data(ptr, format,
-									      fb->width, fb->height, fb->pitch);
-				cairo_surface_write_to_png(surface, name);
-				cairo_surface_destroy(surface);
-
-				munmap(ptr, open_arg.size);
-			}
-			drmIoctl(fd, DRM_IOCTL_GEM_CLOSE, &open_arg.handle);
-		}
+		/* Dump the 'main' frame buffer attached to this CRTC. */
+		dump_frame_buffer(fd, cid, crtc->buffer_id);
+
+		/* Iterate and dump other FBs of Planes attached to this CRTC. */
+		for (int p = 0; p < pres->count_planes; p++) {
+			uint32_t pid = pres->planes[p];
+			drmModePlanePtr pl = drmModeGetPlane(fd, pid);
+
+			if (!pl)
+				continue;
+
+			if ((pl->crtc_id == cid) && (pl->fb_id != 0) &&
+					(pl->fb_id != crtc->buffer_id))
+				dump_frame_buffer(fd, cid, pl->fb_id);
 
-		drmModeFreeFB(fb);
+			drmModeFreePlane(pl);
+		}
+		drmModeFreeCrtc(crtc);
 	}
 
+	drmModeFreePlaneResources(pres);
+	drmModeFreeResources(res);
+	close(fd);
+
 	return 0;
 }
-- 
2.34.1


             reply	other threads:[~2026-03-16 18:39 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-03-16 18:36 Austin Hu [this message]
2026-03-17 12:52 ` ✓ Xe.CI.BAT: success for tools/intel_framebuffer_dump: dump frame buffers with igt_fb API Patchwork
2026-03-17 14:05 ` ✓ i915.CI.BAT: " Patchwork
2026-03-18 15:20 ` ✓ i915.CI.Full: " Patchwork
2026-03-18 20:50 ` ✓ Xe.CI.FULL: " Patchwork

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=20260316183658.384575-1-austin.hu@intel.com \
    --to=austin.hu@intel.com \
    --cc=chris@chris-wilson.co.uk \
    --cc=igt-dev@lists.freedesktop.org \
    /path/to/YOUR_REPLY

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

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