aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGerd Hoffmann <kraxel@redhat.com>2018-10-15 22:52:25 +0200
committerGerd Hoffmann <kraxel@redhat.com>2018-10-15 22:52:25 +0200
commit873d87b4914c1224ba9076e2cbb5e7d95c45f2fc (patch)
tree4368eb6d9bd91c475b00192b712ebfc0c5fdc834
parent811de87d5ede98023ad862bbfd0fbe959efbaed9 (diff)
downloaddrminfo-873d87b4914c1224ba9076e2cbb5e7d95c45f2fc.tar.gz
virtio test
-rw-r--r--Makefile2
-rw-r--r--drmtest.c6
-rw-r--r--drmtools.c7
-rw-r--r--drmtools.h3
-rw-r--r--meson.build2
-rw-r--r--virtiotest.c148
6 files changed, 157 insertions, 11 deletions
diff --git a/Makefile b/Makefile
index f7f0a1f..7768692 100644
--- a/Makefile
+++ b/Makefile
@@ -49,7 +49,7 @@ clean:
drminfo: drminfo.o drmtools.o
drmtest: drmtest.o drmtools.o ttytools.o render.o image.o
-virtiotest: virtiotest.o drmtools.o
+virtiotest: virtiotest.o drmtools.o ttytools.o render.o
gtktest: gtktest.o render.o image.o
endif
diff --git a/drmtest.c b/drmtest.c
index 5efb796..b4ed929 100644
--- a/drmtest.c
+++ b/drmtest.c
@@ -34,12 +34,10 @@ static const struct fbformat *fmt = NULL;
static uint8_t *fbmem;
/* cairo */
-cairo_device_t *cd;
-cairo_surface_t *cs;
-cairo_t *cc;
+static cairo_surface_t *cs;
/* user options */
-cairo_surface_t *image;
+static cairo_surface_t *image;
/* ------------------------------------------------------------------ */
diff --git a/drmtools.c b/drmtools.c
index e2a7a25..dbbff33 100644
--- a/drmtools.c
+++ b/drmtools.c
@@ -9,6 +9,7 @@
#include <endian.h>
#include <sys/ioctl.h>
+#include <linux/virtio_gpu.h>
#include <libdrm/drm_fourcc.h>
#include <xf86drm.h>
@@ -271,6 +272,7 @@ const struct fbformat fmts[] = {
.bits = "8:8:8:8",
.bpp = 32,
.fourcc = DRM_FORMAT_XRGB8888,
+ .virtio = VIRTIO_GPU_FORMAT_B8G8R8X8_UNORM,
.cairo = LE_BE(CAIRO_FORMAT_RGB24, CAIRO_FORMAT_INVALID),
.pixman = LE_BE(PIXMAN_x8r8g8b8, PIXMAN_b8g8r8x8),
},{
@@ -295,6 +297,7 @@ const struct fbformat fmts[] = {
.bits = "8:8:8:8",
.bpp = 32,
.fourcc = DRM_FORMAT_BGRX8888,
+ .virtio = VIRTIO_GPU_FORMAT_X8R8G8B8_UNORM,
.cairo = LE_BE(CAIRO_FORMAT_INVALID, CAIRO_FORMAT_RGB24),
.pixman = LE_BE(PIXMAN_b8g8r8x8, PIXMAN_x8r8g8b8),
},{
@@ -303,6 +306,7 @@ const struct fbformat fmts[] = {
.bits = "8:8:8:8",
.bpp = 32,
.fourcc = DRM_FORMAT_ARGB8888,
+ .virtio = VIRTIO_GPU_FORMAT_B8G8R8A8_UNORM,
.cairo = CAIRO_FORMAT_INVALID,
.pixman = LE_BE(PIXMAN_a8r8g8b8, PIXMAN_b8g8r8a8),
},{
@@ -327,6 +331,7 @@ const struct fbformat fmts[] = {
.bits = "8:8:8:8",
.bpp = 32,
.fourcc = DRM_FORMAT_BGRA8888,
+ .virtio = VIRTIO_GPU_FORMAT_A8R8G8B8_UNORM,
.cairo = CAIRO_FORMAT_INVALID,
.pixman = LE_BE(PIXMAN_b8g8r8a8, PIXMAN_a8r8g8b8),
},{
@@ -726,7 +731,7 @@ void drm_show_fb(void)
&conn->connector_id, 1,
mode);
if (rc < 0) {
- fprintf(stderr, "drmModeSetCrtc() failed\n");
+ fprintf(stderr, "drmModeSetCrtc() failed: %s\n", strerror(errno));
exit (1);
}
}
diff --git a/drmtools.h b/drmtools.h
index d83e3a5..45ca206 100644
--- a/drmtools.h
+++ b/drmtools.h
@@ -6,7 +6,8 @@ struct fbformat {
uint32_t depth; /* legacy (ADDFB) */
uint32_t fourcc; /* DRM_FORMAT_* (ADDFB2) */
cairo_format_t cairo; /* CAIRO_FORMAT_* */
- pixman_format_code_t pixman; /* PIXMAN_* */
+ pixman_format_code_t pixman; /* PIXMAN_* */
+ uint32_t virtio; /* VIRTIO_GPU_FORMAT_* */
};
extern const struct fbformat fmts[];
diff --git a/meson.build b/meson.build
index 7ec5cd1..c213828 100644
--- a/meson.build
+++ b/meson.build
@@ -13,7 +13,7 @@ jpeg_dep = declare_dependency(link_args : '-ljpeg')
drminfo_srcs = [ 'drminfo.c', 'drmtools.c' ]
drmtest_srcs = [ 'drmtest.c', 'drmtools.c', 'ttytools.c', 'render.c', 'image.c' ]
-viotest_srcs = [ 'virtiotest.c', 'drmtools.c' ]
+viotest_srcs = [ 'virtiotest.c', 'drmtools.c', 'ttytools.c', 'render.c' ]
gtktest_srcs = [ 'gtktest.c', 'render.c', 'image.c' ]
drminfo_deps = [ libdrm_dep, cairo_dep, pixman_dep ]
diff --git a/virtiotest.c b/virtiotest.c
index fe56948..77fbab5 100644
--- a/virtiotest.c
+++ b/virtiotest.c
@@ -8,9 +8,13 @@
#include <string.h>
#include <inttypes.h>
#include <getopt.h>
+#include <assert.h>
+#include <sys/mman.h>
#include <sys/ioctl.h>
-#include "virtgpu_drm.h"
+#include <linux/virtio_gpu.h>
+#include <libdrm/drm_fourcc.h>
+#include <libdrm/virtgpu_drm.h>
#include <xf86drm.h>
#include <xf86drmMode.h>
@@ -19,6 +23,8 @@
#include <pixman.h>
#include "drmtools.h"
+#include "ttytools.h"
+#include "render.h"
/* ------------------------------------------------------------------ */
@@ -92,6 +98,117 @@ static void virtio_check(int cardno)
/* ------------------------------------------------------------------ */
+static struct drm_virtgpu_resource_create create;
+static uint8_t *fbmem;
+static const struct fbformat *fmt;
+static cairo_surface_t *cs;
+
+static void virtio_init_fb(void)
+{
+ struct drm_virtgpu_resource_info info;
+ struct drm_virtgpu_map map;
+ uint32_t stride, zero = 0;
+ int rc;
+
+ /* create framebuffer */
+ memset(&create, 0, sizeof(create));
+ create.target = 2; /* ??? */
+ create.format = fmt->virtio;
+ create.width = mode->hdisplay;
+ create.height = mode->vdisplay;
+ stride = create.width * fmt->bpp / 8;
+ create.size = stride * create.height;
+#if 0
+ __u32 target;
+ __u32 bind;
+ __u32 depth;
+ __u32 array_size;
+ __u32 last_level;
+ __u32 nr_samples;
+ __u32 flags;
+#endif
+ rc = drmIoctl(fd, DRM_IOCTL_VIRTGPU_RESOURCE_CREATE, &create);
+ if (rc < 0) {
+ fprintf(stderr, "DRM_IOCTL_VIRTGPU_RESOURCE_CREATE: %s\n",
+ strerror(errno));
+ exit(1);
+ }
+
+ memset(&info, 0, sizeof(info));
+ info.bo_handle = create.bo_handle;
+ rc = drmIoctl(fd, DRM_IOCTL_VIRTGPU_RESOURCE_INFO, &info);
+ if (rc < 0) {
+ fprintf(stderr, "DRM_IOCTL_VIRTGPU_RESOURCE_INFO: %s\n",
+ strerror(errno));
+ exit(1);
+ }
+
+ memset(&map, 0, sizeof(map));
+ map.handle = create.bo_handle;
+ rc = drmIoctl(fd, DRM_IOCTL_VIRTGPU_MAP, &map);
+ if (rc < 0) {
+ fprintf(stderr, "DRM_IOCTL_VIRTGPU_MAP: %s\n", strerror(errno));
+ exit(1);
+ }
+
+ fbmem = mmap(0, info.size, PROT_READ | PROT_WRITE,
+ MAP_SHARED, fd, map.offset);
+ if (fbmem == MAP_FAILED) {
+ fprintf(stderr, "framebuffer mmap: %s\n", strerror(errno));
+ exit(1);
+ }
+
+ if (info.stride)
+ stride = info.stride;
+ rc = drmModeAddFB2(fd, create.width, create.height, fmt->fourcc,
+ &create.bo_handle, &stride, &zero, &fb_id, 0);
+ if (rc < 0) {
+ fprintf(stderr, "drmModeAddFB2() failed: %s\n", strerror(errno));
+ exit(1);
+ }
+
+ cs = cairo_image_surface_create_for_data(fbmem,
+ fmt->cairo,
+ create.width,
+ create.height,
+ stride);
+}
+
+static void virtio_draw(const char *text)
+{
+ char info[80];
+ cairo_t *cr;
+
+ snprintf(info, sizeof(info), "virtiotest: %dx%d, fourcc %c%c%c%c",
+ mode->hdisplay, mode->vdisplay,
+ (fmt->fourcc >> 0) & 0xff,
+ (fmt->fourcc >> 8) & 0xff,
+ (fmt->fourcc >> 16) & 0xff,
+ (fmt->fourcc >> 24) & 0xff);
+ cr = cairo_create(cs);
+ render_test(cr, mode->hdisplay, mode->vdisplay, info, text);
+ cairo_destroy(cr);
+}
+
+static void virtio_transfer(void)
+{
+ struct drm_virtgpu_3d_transfer_to_host xfer;
+ int rc;
+
+ memset(&xfer, 0, sizeof(xfer));
+ xfer.bo_handle = create.bo_handle;
+ xfer.box.w = mode->hdisplay;
+ xfer.box.h = mode->vdisplay;
+ rc = drmIoctl(fd, DRM_IOCTL_VIRTGPU_TRANSFER_TO_HOST, &xfer);
+ if (rc < 0) {
+ fprintf(stderr, "DRM_IOCTL_VIRTGPU_TRANSFER_TO_HOST: %s\n",
+ strerror(errno));
+ exit(1);
+ }
+}
+
+/* ------------------------------------------------------------------ */
+
static void usage(FILE *fp)
{
fprintf(fp,
@@ -108,19 +225,24 @@ static void usage(FILE *fp)
int main(int argc, char **argv)
{
int card = 0;
+ int secs = 60;
char *output = NULL;
char *modename = NULL;
bool printinfo = false;
- int c;
+ char buf[32];
+ int c, i;
for (;;) {
- c = getopt(argc, argv, "hic:");
+ c = getopt(argc, argv, "hic:s:");
if (c == -1)
break;
switch (c) {
case 'c':
card = atoi(optarg);
break;
+ case 's':
+ secs = atoi(optarg);
+ break;
case 'i':
printinfo = true;
break;
@@ -135,12 +257,32 @@ int main(int argc, char **argv)
virtio_check(card);
+ for (i = 0; i < fmtcnt; i++) {
+ if (fmts[i].cairo == CAIRO_FORMAT_RGB24) {
+ fmt = &fmts[i];
+ }
+ }
+ assert(fmt != NULL);
+ assert(fmt->virtio != 0);
+
drm_init_dev(card, output, modename, false);
if (printinfo) {
virtio_print_caps();
+ goto done;
}
+ virtio_init_fb();
+ virtio_draw("hello world");
+ virtio_transfer();
+ drm_show_fb();
+
+ tty_raw();
+ kbd_wait(secs);
+ read(0, buf, sizeof(buf));
+ tty_restore();
+
+done:
drm_fini_dev();
return 0;
}