diff options
author | Gerd Hoffmann <kraxel@redhat.com> | 2018-10-15 22:52:25 +0200 |
---|---|---|
committer | Gerd Hoffmann <kraxel@redhat.com> | 2018-10-15 22:52:25 +0200 |
commit | 873d87b4914c1224ba9076e2cbb5e7d95c45f2fc (patch) | |
tree | 4368eb6d9bd91c475b00192b712ebfc0c5fdc834 | |
parent | 811de87d5ede98023ad862bbfd0fbe959efbaed9 (diff) | |
download | drminfo-873d87b4914c1224ba9076e2cbb5e7d95c45f2fc.tar.gz |
virtio test
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | drmtest.c | 6 | ||||
-rw-r--r-- | drmtools.c | 7 | ||||
-rw-r--r-- | drmtools.h | 3 | ||||
-rw-r--r-- | meson.build | 2 | ||||
-rw-r--r-- | virtiotest.c | 148 |
6 files changed, 157 insertions, 11 deletions
@@ -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 @@ -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; /* ------------------------------------------------------------------ */ @@ -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); } } @@ -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; } |