aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile4
-rw-r--r--drminfo.c64
-rw-r--r--drmtest.c73
-rw-r--r--drmtools.c407
-rw-r--r--drmtools.h18
-rwxr-xr-xfbformat.sh12
-rw-r--r--meson.build2
7 files changed, 475 insertions, 105 deletions
diff --git a/Makefile b/Makefile
index dc89829..2f6e46e 100644
--- a/Makefile
+++ b/Makefile
@@ -4,8 +4,8 @@ CFLAGS += -Wall
TARGETS := drminfo drmtest gtktest
-drminfo : CFLAGS += $(shell pkg-config --cflags libdrm)
-drminfo : LDLIBS += $(shell pkg-config --libs libdrm)
+drminfo : CFLAGS += $(shell pkg-config --cflags libdrm cairo)
+drminfo : LDLIBS += $(shell pkg-config --libs libdrm cairo)
drmtest : CFLAGS += $(shell pkg-config --cflags libdrm gbm epoxy cairo cairo-gl pixman-1)
drmtest : LDLIBS += $(shell pkg-config --libs libdrm gbm epoxy cairo cairo-gl pixman-1)
diff --git a/drminfo.c b/drminfo.c
index 2020ddb..e0ee008 100644
--- a/drminfo.c
+++ b/drminfo.c
@@ -14,6 +14,8 @@
#include <xf86drm.h>
#include <xf86drmMode.h>
+#include <cairo.h>
+
#include "drmtools.h"
/* ------------------------------------------------------------------ */
@@ -102,49 +104,23 @@ static void drm_info(int devnr)
fprintf(stdout, "\n");
}
- fprintf(stdout, "legacy formats\n");
- drm_probe_format(fd, 32, 24, 0, true);
- drm_probe_format(fd, 32, 30, 0, true);
- drm_probe_format(fd, 24, 24, 0, true);
- drm_probe_format(fd, 16, 16, 0, true);
- drm_probe_format(fd, 16, 15, 0, true);
+ fprintf(stdout, "framebuffer formats\n");
+ for (i = 0; i < fmtcnt; i++) {
+ if (!drm_probe_format(fd, &fmts[i]))
+ continue;
+ drm_print_format(stdout, &fmts[i]);
+ }
fprintf(stdout, "\n");
+}
- fprintf(stdout, "fourcc formats\n");
- drm_probe_format(fd, 32, 0, DRM_FORMAT_XRGB8888, true);
- drm_probe_format(fd, 32, 0, DRM_FORMAT_XBGR8888, true);
- drm_probe_format(fd, 32, 0, DRM_FORMAT_RGBX8888, true);
- drm_probe_format(fd, 32, 0, DRM_FORMAT_BGRX8888, true);
- drm_probe_format(fd, 32, 0, DRM_FORMAT_ARGB8888, true);
- drm_probe_format(fd, 32, 0, DRM_FORMAT_ABGR8888, true);
- drm_probe_format(fd, 32, 0, DRM_FORMAT_RGBA8888, true);
- drm_probe_format(fd, 32, 0, DRM_FORMAT_BGRA8888, true);
- drm_probe_format(fd, 32, 0, DRM_FORMAT_XRGB2101010, true);
- drm_probe_format(fd, 32, 0, DRM_FORMAT_XBGR2101010, true);
- drm_probe_format(fd, 32, 0, DRM_FORMAT_RGBX1010102, true);
- drm_probe_format(fd, 32, 0, DRM_FORMAT_BGRX1010102, true);
-
- drm_probe_format(fd, 24, 0, DRM_FORMAT_RGB888, true);
- drm_probe_format(fd, 24, 0, DRM_FORMAT_BGR888, true);
-
- drm_probe_format(fd, 16, 0, DRM_FORMAT_XRGB4444, true);
- drm_probe_format(fd, 16, 0, DRM_FORMAT_XBGR4444, true);
- drm_probe_format(fd, 16, 0, DRM_FORMAT_RGBX4444, true);
- drm_probe_format(fd, 16, 0, DRM_FORMAT_BGRX4444, true);
- drm_probe_format(fd, 16, 0, DRM_FORMAT_ARGB4444, true);
- drm_probe_format(fd, 16, 0, DRM_FORMAT_ABGR4444, true);
- drm_probe_format(fd, 16, 0, DRM_FORMAT_RGBA4444, true);
- drm_probe_format(fd, 16, 0, DRM_FORMAT_BGRA4444, true);
- drm_probe_format(fd, 16, 0, DRM_FORMAT_XRGB1555, true);
- drm_probe_format(fd, 16, 0, DRM_FORMAT_XBGR1555, true);
- drm_probe_format(fd, 16, 0, DRM_FORMAT_RGBX5551, true);
- drm_probe_format(fd, 16, 0, DRM_FORMAT_BGRX5551, true);
- drm_probe_format(fd, 16, 0, DRM_FORMAT_ARGB1555, true);
- drm_probe_format(fd, 16, 0, DRM_FORMAT_ABGR1555, true);
- drm_probe_format(fd, 16, 0, DRM_FORMAT_RGBA5551, true);
- drm_probe_format(fd, 16, 0, DRM_FORMAT_BGRA5551, true);
- drm_probe_format(fd, 16, 0, DRM_FORMAT_RGB565, true);
- drm_probe_format(fd, 16, 0, DRM_FORMAT_BGR565, true);
+static void list_formats(FILE *fp)
+{
+ int i;
+
+ fprintf(stdout, "all known framebuffer formats (rgb + packed yuv)\n");
+ for (i = 0; i < fmtcnt; i++) {
+ drm_print_format(stdout, &fmts[i]);
+ }
fprintf(stdout, "\n");
}
@@ -159,6 +135,7 @@ static void usage(FILE *fp)
"options:\n"
" -h print this\n"
" -c <nr> pick card\n"
+ " -l print all known formats\n"
"\n");
}
@@ -168,13 +145,16 @@ int main(int argc, char **argv)
int c;
for (;;) {
- c = getopt(argc, argv, "hc:");
+ c = getopt(argc, argv, "hlc:");
if (c == -1)
break;
switch (c) {
case 'c':
card = atoi(optarg);
break;
+ case 'l':
+ list_formats(stdout);
+ exit(0);
case 'h':
usage(stdout);
exit(0);
diff --git a/drmtest.c b/drmtest.c
index 48e1384..da2e9f9 100644
--- a/drmtest.c
+++ b/drmtest.c
@@ -31,15 +31,6 @@
/* ------------------------------------------------------------------ */
-struct fbformat {
- const char *name;
- uint32_t bpp; /* bytes per pixel */
- cairo_format_t cairo; /* CAIRO_FORMAT_* */
- uint32_t fourcc; /* DRM_FORMAT_* */
-};
-
-/* ------------------------------------------------------------------ */
-
/* device */
static int fd;
static drmModeConnector *conn = NULL;
@@ -71,27 +62,6 @@ cairo_surface_t *image;
/* ------------------------------------------------------------------ */
-static const struct fbformat fmts[] = {
- {
- .name = "rgb24",
- .bpp = 32,
- .cairo = CAIRO_FORMAT_RGB24,
- .fourcc = DRM_FORMAT_XRGB8888,
- },{
- .name = "rgb30",
- .bpp = 32,
- .cairo = CAIRO_FORMAT_RGB30,
- .fourcc = DRM_FORMAT_XRGB2101010,
- },{
- .name = "rgb16",
- .bpp = 16,
- .cairo = CAIRO_FORMAT_RGB16_565,
- .fourcc = DRM_FORMAT_RGB565,
- }
-};
-
-/* ------------------------------------------------------------------ */
-
static void drm_init_dev(int devnr, const char *output, bool need_dumb)
{
drmModeRes *res;
@@ -241,16 +211,27 @@ static void drm_init_dumb_fb(void)
fprintf(stderr, "DRM_IOCTL_MODE_CREATE_DUMB: %s\n", strerror(errno));
exit(1);
}
- rc = drmModeAddFB2(fd, creq.width, creq.height, fmt->fourcc,
- &creq.handle, &creq.pitch, &zero,
- &fb_id, 0);
- if (rc < 0) {
- fprintf(stderr, "drmModeAddFB2() failed (fourcc %c%c%c%c)\n",
- (fmt->fourcc >> 0) & 0xff,
- (fmt->fourcc >> 8) & 0xff,
- (fmt->fourcc >> 16) & 0xff,
- (fmt->fourcc >> 24) & 0xff);
- exit(1);
+
+ if (fmt->fourcc) {
+ rc = drmModeAddFB2(fd, creq.width, creq.height, fmt->fourcc,
+ &creq.handle, &creq.pitch, &zero,
+ &fb_id, 0);
+ if (rc < 0) {
+ fprintf(stderr, "drmModeAddFB2() failed (fourcc %c%c%c%c)\n",
+ (fmt->fourcc >> 0) & 0xff,
+ (fmt->fourcc >> 8) & 0xff,
+ (fmt->fourcc >> 16) & 0xff,
+ (fmt->fourcc >> 24) & 0xff);
+ exit(1);
+ }
+ } else {
+ rc = drmModeAddFB(fd, creq.width, creq.height, fmt->depth, fmt->bpp,
+ creq.pitch, creq.handle, &fb_id);
+ if (rc < 0) {
+ fprintf(stderr, "drmModeAddFB() failed (bpp %d, depth %d)\n",
+ fmt->bpp, fmt->depth);
+ exit(1);
+ }
}
/* map framebuffer */
@@ -518,16 +499,18 @@ int main(int argc, char **argv)
}
if (format) {
- for (i = 0; i < sizeof(fmts)/sizeof(fmts[0]); i++) {
+ for (i = 0; i < fmtcnt; i++) {
if (strcmp(format, fmts[i].name) == 0) {
fmt = &fmts[i];
}
}
if (!fmt) {
- fprintf(stderr, "unknown format %s, valid choices are:", format);
- for (i = 0; i < sizeof(fmts)/sizeof(fmts[0]); i++)
- fprintf(stderr, " %s", fmts[i].name);
- fprintf(stderr, "\n");
+ fprintf(stderr, "unknown format %s, valid choices are:\n", format);
+ for (i = 0; i < fmtcnt; i++) {
+ if (fmts[i].cairo == CAIRO_FORMAT_INVALID)
+ continue;
+ drm_print_format(stderr, &fmts[i]);
+ }
exit(1);
}
} else {
diff --git a/drmtools.c b/drmtools.c
index 042b8d6..b3b3a9b 100644
--- a/drmtools.c
+++ b/drmtools.c
@@ -8,14 +8,392 @@
#include <inttypes.h>
#include <sys/ioctl.h>
+#include <drm/drm_fourcc.h>
#include <xf86drm.h>
#include <xf86drmMode.h>
+#include <cairo.h>
+
#include "drmtools.h"
/* ------------------------------------------------------------------ */
+#define FOURCC_NAME(_fcc) { \
+ (_fcc >> 0) & 0xff, \
+ (_fcc >> 8) & 0xff, \
+ (_fcc >> 16) & 0xff, \
+ (_fcc >> 24) & 0xff, \
+ 0 }
+
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+# define LE_BE(_le, _be) (_le)
+#endif
+#if __BYTE_ORDER == __BIG_ENDIAN
+# define LE_BE(_le, _be) (_be)
+#endif
+
+const struct fbformat fmts[] = {
+
+ /*
+ * -----------------------------------------------------------------
+ * legacy formats, native endian (DRM_IOCTL_MODE_ADDFB)
+ */
+ {
+ .name = "24",
+ .fields = "x:R:G:B",
+ .bits = "8:8:8:8",
+ .bpp = 32,
+ .depth = 24,
+ .cairo = CAIRO_FORMAT_RGB24,
+ },{
+ .name = "30",
+ .fields = "x:R:G:B",
+ .bits = "2:10:10:10",
+ .bpp = 32,
+ .depth = 30,
+ .cairo = CAIRO_FORMAT_RGB30,
+ },{
+ .name = "15",
+ .fields = "x:R:G:B",
+ .bits = "1:5:5:5",
+ .bpp = 16,
+ .depth = 15,
+ .cairo = CAIRO_FORMAT_INVALID,
+ },{
+ .name = "16",
+ .fields = "R:G:B",
+ .bits = "5:6:5",
+ .bpp = 16,
+ .depth = 16,
+ .cairo = CAIRO_FORMAT_RGB16_565,
+ },
+
+ /*
+ * -----------------------------------------------------------------
+ * fourcc formats, little endian (DRM_IOCTL_MODE_ADDFB2)
+ */
+
+ /* --- 8 bpp, rgb --- */
+ {
+ .name = FOURCC_NAME(DRM_FORMAT_RGB332),
+ .fields = "R:G:B",
+ .bits = "3:3:2",
+ .bpp = 8,
+ .fourcc = DRM_FORMAT_RGB332,
+ .cairo = CAIRO_FORMAT_INVALID,
+ },{
+ .name = FOURCC_NAME(DRM_FORMAT_BGR233),
+ .fields = "B:G:R",
+ .bits = "2:3:3",
+ .bpp = 8,
+ .fourcc = DRM_FORMAT_BGR233,
+ .cairo = CAIRO_FORMAT_INVALID,
+ },
+
+ /* -- 16 bpp, rgb --- */
+ {
+ .name = FOURCC_NAME(DRM_FORMAT_XRGB4444),
+ .fields = "x:R:G:B",
+ .bits = "4:4:4:4",
+ .bpp = 16,
+ .fourcc = DRM_FORMAT_XRGB4444,
+ .cairo = CAIRO_FORMAT_INVALID,
+ },{
+ .name = FOURCC_NAME(DRM_FORMAT_XBGR4444),
+ .fields = "x:B:G:R",
+ .bits = "4:4:4:4",
+ .bpp = 16,
+ .fourcc = DRM_FORMAT_XBGR4444,
+ .cairo = CAIRO_FORMAT_INVALID,
+ },{
+ .name = FOURCC_NAME(DRM_FORMAT_RGBX4444),
+ .fields = "R:G:B:x",
+ .bits = "4:4:4:4",
+ .bpp = 16,
+ .fourcc = DRM_FORMAT_RGBX4444,
+ .cairo = CAIRO_FORMAT_INVALID,
+ },{
+ .name = FOURCC_NAME(DRM_FORMAT_BGRX4444),
+ .fields = "B:G:R:x",
+ .bits = "4:4:4:4",
+ .bpp = 16,
+ .fourcc = DRM_FORMAT_BGRX4444,
+ .cairo = CAIRO_FORMAT_INVALID,
+ },{
+ .name = FOURCC_NAME(DRM_FORMAT_ARGB4444),
+ .fields = "A:R:G:B",
+ .bits = "4:4:4:4",
+ .bpp = 16,
+ .fourcc = DRM_FORMAT_ARGB4444,
+ .cairo = CAIRO_FORMAT_INVALID,
+ },{
+ .name = FOURCC_NAME(DRM_FORMAT_ABGR4444),
+ .fields = "A:B:G:R",
+ .bits = "4:4:4:4",
+ .bpp = 16,
+ .fourcc = DRM_FORMAT_ABGR4444,
+ .cairo = CAIRO_FORMAT_INVALID,
+ },{
+ .name = FOURCC_NAME(DRM_FORMAT_RGBA4444),
+ .fields = "R:G:B:A",
+ .bits = "4:4:4:4",
+ .bpp = 16,
+ .fourcc = DRM_FORMAT_RGBA4444,
+ .cairo = CAIRO_FORMAT_INVALID,
+ },{
+ .name = FOURCC_NAME(DRM_FORMAT_BGRA4444),
+ .fields = "B:G:R:A",
+ .bits = "4:4:4:4",
+ .bpp = 16,
+ .fourcc = DRM_FORMAT_BGRA4444,
+ .cairo = CAIRO_FORMAT_INVALID,
+ },{
+ .name = FOURCC_NAME(DRM_FORMAT_XRGB1555),
+ .fields = "x:R:G:B",
+ .bits = "1:5:5:5",
+ .bpp = 16,
+ .fourcc = DRM_FORMAT_XRGB1555,
+ .cairo = CAIRO_FORMAT_INVALID,
+ },{
+ .name = FOURCC_NAME(DRM_FORMAT_XBGR1555),
+ .fields = "x:B:G:R",
+ .bits = "1:5:5:5",
+ .bpp = 16,
+ .fourcc = DRM_FORMAT_XBGR1555,
+ .cairo = CAIRO_FORMAT_INVALID,
+ },{
+ .name = FOURCC_NAME(DRM_FORMAT_RGBX5551),
+ .fields = "R:G:B:x",
+ .bits = "5:5:5:1",
+ .bpp = 16,
+ .fourcc = DRM_FORMAT_RGBX5551,
+ .cairo = CAIRO_FORMAT_INVALID,
+ },{
+ .name = FOURCC_NAME(DRM_FORMAT_BGRX5551),
+ .fields = "B:G:R:x",
+ .bits = "5:5:5:1",
+ .bpp = 16,
+ .fourcc = DRM_FORMAT_BGRX5551,
+ .cairo = CAIRO_FORMAT_INVALID,
+ },{
+ .name = FOURCC_NAME(DRM_FORMAT_ARGB1555),
+ .fields = "A:R:G:B",
+ .bits = "1:5:5:5",
+ .bpp = 16,
+ .fourcc = DRM_FORMAT_ARGB1555,
+ .cairo = CAIRO_FORMAT_INVALID,
+ },{
+ .name = FOURCC_NAME(DRM_FORMAT_ABGR1555),
+ .fields = "A:B:G:R",
+ .bits = "1:5:5:5",
+ .bpp = 16,
+ .fourcc = DRM_FORMAT_ABGR1555,
+ .cairo = CAIRO_FORMAT_INVALID,
+ },{
+ .name = FOURCC_NAME(DRM_FORMAT_RGBA5551),
+ .fields = "R:G:B:A",
+ .bits = "5:5:5:1",
+ .bpp = 16,
+ .fourcc = DRM_FORMAT_RGBA5551,
+ .cairo = CAIRO_FORMAT_INVALID,
+ },{
+ .name = FOURCC_NAME(DRM_FORMAT_BGRA5551),
+ .fields = "B:G:R:A",
+ .bits = "5:5:5:1",
+ .bpp = 16,
+ .fourcc = DRM_FORMAT_BGRA5551,
+ .cairo = CAIRO_FORMAT_INVALID,
+ },{
+ .name = FOURCC_NAME(DRM_FORMAT_RGB565),
+ .fields = "R:G:B",
+ .bits = "5:6:5",
+ .bpp = 16,
+ .fourcc = DRM_FORMAT_RGB565,
+ .cairo = LE_BE(CAIRO_FORMAT_RGB16_565, CAIRO_FORMAT_INVALID),
+ },{
+ .name = FOURCC_NAME(DRM_FORMAT_BGR565),
+ .fields = "B:G:R",
+ .bits = "5:6:5",
+ .bpp = 16,
+ .fourcc = DRM_FORMAT_BGR565,
+ .cairo = CAIRO_FORMAT_INVALID,
+ },
+
+ /* --- 24 bpp, rgb --- */
+ {
+ .name = FOURCC_NAME(DRM_FORMAT_RGB888),
+ .fields = "R:G:B",
+ .bits = "8:8:8",
+ .bpp = 24,
+ .fourcc = DRM_FORMAT_RGB888,
+ .cairo = CAIRO_FORMAT_INVALID,
+ },{
+ .name = FOURCC_NAME(DRM_FORMAT_BGR888),
+ .fields = "B:G:R",
+ .bits = "8:8:8",
+ .bpp = 24,
+ .fourcc = DRM_FORMAT_BGR888,
+ .cairo = CAIRO_FORMAT_INVALID,
+ },
+
+ /* --- 32 bpp, rgb --- */
+ {
+ .name = FOURCC_NAME(DRM_FORMAT_XRGB8888),
+ .fields = "x:R:G:B",
+ .bits = "8:8:8:8",
+ .bpp = 32,
+ .fourcc = DRM_FORMAT_XRGB8888,
+ .cairo = LE_BE(CAIRO_FORMAT_RGB24, CAIRO_FORMAT_INVALID),
+ },{
+ .name = FOURCC_NAME(DRM_FORMAT_XBGR8888),
+ .fields = "x:B:G:R",
+ .bits = "8:8:8:8",
+ .bpp = 32,
+ .fourcc = DRM_FORMAT_XBGR8888,
+ .cairo = CAIRO_FORMAT_INVALID,
+ },{
+ .name = FOURCC_NAME(DRM_FORMAT_RGBX8888),
+ .fields = "R:G:B:x",
+ .bits = "8:8:8:8",
+ .bpp = 32,
+ .fourcc = DRM_FORMAT_RGBX8888,
+ .cairo = CAIRO_FORMAT_INVALID,
+ },{
+ .name = FOURCC_NAME(DRM_FORMAT_BGRX8888),
+ .fields = "B:G:R:x",
+ .bits = "8:8:8:8",
+ .bpp = 32,
+ .fourcc = DRM_FORMAT_BGRX8888,
+ .cairo = LE_BE(CAIRO_FORMAT_INVALID, CAIRO_FORMAT_RGB24),
+ },{
+ .name = FOURCC_NAME(DRM_FORMAT_ARGB8888),
+ .fields = "A:R:G:B",
+ .bits = "8:8:8:8",
+ .bpp = 32,
+ .fourcc = DRM_FORMAT_ARGB8888,
+ .cairo = CAIRO_FORMAT_INVALID,
+ },{
+ .name = FOURCC_NAME(DRM_FORMAT_ABGR8888),
+ .fields = "A:B:G:R",
+ .bits = "8:8:8:8",
+ .bpp = 32,
+ .fourcc = DRM_FORMAT_ABGR8888,
+ .cairo = CAIRO_FORMAT_INVALID,
+ },{
+ .name = FOURCC_NAME(DRM_FORMAT_RGBA8888),
+ .fields = "R:G:B:A",
+ .bits = "8:8:8:8",
+ .bpp = 32,
+ .fourcc = DRM_FORMAT_RGBA8888,
+ .cairo = CAIRO_FORMAT_INVALID,
+ },{
+ .name = FOURCC_NAME(DRM_FORMAT_BGRA8888),
+ .fields = "B:G:R:A",
+ .bits = "8:8:8:8",
+ .bpp = 32,
+ .fourcc = DRM_FORMAT_BGRA8888,
+ .cairo = CAIRO_FORMAT_INVALID,
+ },{
+ .name = FOURCC_NAME(DRM_FORMAT_XRGB2101010),
+ .fields = "x:R:G:B",
+ .bits = "2:10:10:10",
+ .bpp = 32,
+ .fourcc = DRM_FORMAT_XRGB2101010,
+ .cairo = LE_BE(CAIRO_FORMAT_RGB30, CAIRO_FORMAT_INVALID)
+ },{
+ .name = FOURCC_NAME(DRM_FORMAT_XBGR2101010),
+ .fields = "x:B:G:R",
+ .bits = "2:10:10:10",
+ .bpp = 32,
+ .fourcc = DRM_FORMAT_XBGR2101010,
+ .cairo = CAIRO_FORMAT_INVALID,
+ },{
+ .name = FOURCC_NAME(DRM_FORMAT_RGBX1010102),
+ .fields = "R:G:B:x",
+ .bits = "10:10:10:2",
+ .bpp = 32,
+ .fourcc = DRM_FORMAT_RGBX1010102,
+ .cairo = CAIRO_FORMAT_INVALID,
+ },{
+ .name = FOURCC_NAME(DRM_FORMAT_BGRX1010102),
+ .fields = "B:G:R:x",
+ .bits = "10:10:10:2",
+ .bpp = 32,
+ .fourcc = DRM_FORMAT_BGRX1010102,
+ .cairo = CAIRO_FORMAT_INVALID,
+ },{
+ .name = FOURCC_NAME(DRM_FORMAT_ARGB2101010),
+ .fields = "A:R:G:B",
+ .bits = "2:10:10:10",
+ .bpp = 32,
+ .fourcc = DRM_FORMAT_ARGB2101010,
+ .cairo = CAIRO_FORMAT_INVALID,
+ },{
+ .name = FOURCC_NAME(DRM_FORMAT_ABGR2101010),
+ .fields = "A:B:G:R",
+ .bits = "2:10:10:10",
+ .bpp = 32,
+ .fourcc = DRM_FORMAT_ABGR2101010,
+ .cairo = CAIRO_FORMAT_INVALID,
+ },{
+ .name = FOURCC_NAME(DRM_FORMAT_RGBA1010102),
+ .fields = "R:G:B:A",
+ .bits = "10:10:10:2",
+ .bpp = 32,
+ .fourcc = DRM_FORMAT_RGBA1010102,
+ .cairo = CAIRO_FORMAT_INVALID,
+ },{
+ .name = FOURCC_NAME(DRM_FORMAT_BGRA1010102),
+ .fields = "B:G:R:A",
+ .bits = "10:10:10:2",
+ .bpp = 32,
+ .fourcc = DRM_FORMAT_BGRA1010102,
+ .cairo = CAIRO_FORMAT_INVALID,
+ },
+
+ /* --- 32 bpp, yuv --- */
+ {
+ .name = FOURCC_NAME(DRM_FORMAT_YUYV),
+ .fields = "Cr0:Y1:Cb0:Y0",
+ .bits = "8:8:8:8",
+ .bpp = 32,
+ .fourcc = DRM_FORMAT_YUYV,
+ .cairo = CAIRO_FORMAT_INVALID,
+ },{
+ .name = FOURCC_NAME(DRM_FORMAT_YVYU),
+ .fields = "Cb0:Y1:Cr0:Y0",
+ .bits = "8:8:8:8",
+ .bpp = 32,
+ .fourcc = DRM_FORMAT_YVYU,
+ .cairo = CAIRO_FORMAT_INVALID,
+ },{
+ .name = FOURCC_NAME(DRM_FORMAT_UYVY),
+ .fields = "Y1:Cr0:Y0:Cb0",
+ .bits = "8:8:8:8",
+ .bpp = 32,
+ .fourcc = DRM_FORMAT_UYVY,
+ .cairo = CAIRO_FORMAT_INVALID,
+ },{
+ .name = FOURCC_NAME(DRM_FORMAT_VYUY),
+ .fields = "Y1:Cb0:Y0:Cr0",
+ .bits = "8:8:8:8",
+ .bpp = 32,
+ .fourcc = DRM_FORMAT_VYUY,
+ .cairo = CAIRO_FORMAT_INVALID,
+ },{
+ .name = FOURCC_NAME(DRM_FORMAT_AYUV),
+ .fields = "A:Y:Cb:Cr",
+ .bits = "8:8:8:8",
+ .bpp = 32,
+ .fourcc = DRM_FORMAT_AYUV,
+ .cairo = CAIRO_FORMAT_INVALID,
+ },
+};
+const uint32_t fmtcnt = sizeof(fmts)/sizeof(fmts[0]);
+
+/* ------------------------------------------------------------------ */
+
static const char *conn_type[] = {
[ DRM_MODE_CONNECTOR_Unknown ] = "Unknown",
[ DRM_MODE_CONNECTOR_VGA ] = "VGA",
@@ -93,7 +471,7 @@ void drm_conn_name(drmModeConnector *conn, char *dest, int dlen)
/* ------------------------------------------------------------------ */
-bool drm_probe_format(int fd, uint32_t bpp, uint32_t depth, uint32_t fourcc, bool print)
+bool drm_probe_format(int fd, const struct fbformat *fmt)
{
struct drm_mode_create_dumb cd;
struct drm_mode_destroy_dumb dd;
@@ -106,27 +484,19 @@ bool drm_probe_format(int fd, uint32_t bpp, uint32_t depth, uint32_t fourcc, boo
memset(&cd, 0, sizeof(cd));
cd.width = 64;
cd.height = 64;
- cd.bpp = bpp;
+ cd.bpp = fmt->bpp;
rc = drmIoctl(fd, DRM_IOCTL_MODE_CREATE_DUMB, &cd);
if (rc < 0)
goto done;
/* create framebuffer */
- if (fourcc) {
- rc = drmModeAddFB2(fd, cd.width, cd.height, fourcc,
+ if (fmt->fourcc) {
+ rc = drmModeAddFB2(fd, cd.width, cd.height, fmt->fourcc,
&cd.handle, &cd.pitch, &zero,
&fb_id, 0);
- if (rc == 0 && print)
- printf(" bpp %d, fourcc %c%c%c%c\n", cd.bpp,
- (fourcc >> 0) & 0xff,
- (fourcc >> 8) & 0xff,
- (fourcc >> 16) & 0xff,
- (fourcc >> 24) & 0xff);
- } else if (depth) {
- rc = drmModeAddFB(fd, cd.width, cd.height, depth, cd.bpp,
+ } else if (fmt->depth) {
+ rc = drmModeAddFB(fd, cd.width, cd.height, fmt->depth, cd.bpp,
cd.pitch, cd.handle, &fb_id);
- if (rc == 0 && print)
- printf(" bpp %d, depth %d\n", cd.bpp, depth);
} else {
rc = -1;
}
@@ -142,3 +512,12 @@ bool drm_probe_format(int fd, uint32_t bpp, uint32_t depth, uint32_t fourcc, boo
done:
return result;
}
+
+void drm_print_format(FILE *fp, const struct fbformat *fmt)
+{
+ fprintf(fp, " %-8s: [%2d:0] %-14s %-11s %s\n",
+ fmt->name, fmt->bpp - 1, fmt->fields, fmt->bits,
+ fmt->fourcc
+ ? "fourcc (addfb2), little endian"
+ : "legacy (addfb), native endian");
+}
diff --git a/drmtools.h b/drmtools.h
index 9560261..900e2cc 100644
--- a/drmtools.h
+++ b/drmtools.h
@@ -1,5 +1,21 @@
+struct fbformat {
+ const char name[8];
+ const char fields[16];
+ const char bits[16];
+ uint32_t bpp; /* bytes per pixel */
+ uint32_t depth; /* legacy (ADDFB) */
+ uint32_t fourcc; /* DRM_FORMAT_* (ADDFB2) */
+ cairo_format_t cairo; /* CAIRO_FORMAT_* */
+};
+
+extern const struct fbformat fmts[];
+extern const uint32_t fmtcnt;
+
+/* ------------------------------------------------------------------ */
+
const char *drm_connector_type_name(int nr);
const char *drm_connector_mode_name(int nr);
const char *drm_encoder_type_name(int nr);
void drm_conn_name(drmModeConnector *conn, char *dest, int dlen);
-bool drm_probe_format(int fd, uint32_t bpp, uint32_t depth, uint32_t fourcc, bool print);
+bool drm_probe_format(int fd, const struct fbformat *fmt);
+void drm_print_format(FILE *fp, const struct fbformat *fmt);
diff --git a/fbformat.sh b/fbformat.sh
new file mode 100755
index 0000000..a13b41e
--- /dev/null
+++ b/fbformat.sh
@@ -0,0 +1,12 @@
+#!/bin/sh
+
+awk '/define DRM.*fourcc_code.*\[.*\]/ {
+ printf " {\n";
+ printf " .name = FOURCC_NAME(%s),\n", $2;
+ printf " .fields = \"%s\",\n", $9;
+ printf " .bits = \"%s\",\n", $10;
+ printf " .bpp = ,\n";
+ printf " .fourcc = %s,\n", $2;
+ printf " .cairo = CAIRO_FORMAT_INVALID,\n", $2;
+ printf " },\n";
+}' /usr/include/drm/drm_fourcc.h
diff --git a/meson.build b/meson.build
index eadbc1a..3a8e7fc 100644
--- a/meson.build
+++ b/meson.build
@@ -16,7 +16,7 @@ drminfo_srcs = [ 'drminfo.c', 'drmtools.c' ]
drmtest_srcs = [ 'drmtest.c', 'drmtools.c', 'render.c', 'image.c' ]
gtktest_srcs = [ 'gtktest.c', 'render.c', 'image.c' ]
-drminfo_deps = [ libdrm_dep ]
+drminfo_deps = [ libdrm_dep, cairo_dep ]
drmtest_deps = [ libdrm_dep, gbm_dep, epoxy_dep,
cairo_dep, cairo_gl_dep, pixman_dep, jpeg_dep ]
gtktest_deps = [ gtk3_dep,