All of lore.kernel.org
 help / color / mirror / Atom feed
From: Max Reitz <mreitz@redhat.com>
To: Gerd Hoffmann <kraxel@redhat.com>, qemu-devel@nongnu.org
Cc: Dave Airlie <airlied@redhat.com>, "Michael S. Tsirkin" <mst@redhat.com>
Subject: Re: [Qemu-devel] [PATCH 2/9] virtio-gpu/2d: add virtio gpu core code
Date: Mon, 16 Mar 2015 16:15:10 -0400	[thread overview]
Message-ID: <550739CE.90903@redhat.com> (raw)
In-Reply-To: <1426240033-24673-4-git-send-email-kraxel@redhat.com>

On 2015-03-13 at 05:47, Gerd Hoffmann wrote:
> This patch adds the core code for virtio gpu emulation,
> covering 2d support.
>
> Written by Dave Airlie and Gerd Hoffmann.
>
> Signed-off-by: Dave Airlie <airlied@redhat.com>
> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
> ---
>   hw/display/Makefile.objs       |   2 +
>   hw/display/virtio-gpu.c        | 923 +++++++++++++++++++++++++++++++++++++++++
>   include/hw/virtio/virtio-gpu.h | 147 +++++++
>   trace-events                   |  14 +
>   4 files changed, 1086 insertions(+)
>   create mode 100644 hw/display/virtio-gpu.c
>   create mode 100644 include/hw/virtio/virtio-gpu.h
>
> diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c
> new file mode 100644
> index 0000000..ab71291
> --- /dev/null
> +++ b/hw/display/virtio-gpu.c

[snip]

> +static void virtio_gpu_device_realize(DeviceState *qdev, Error **errp)
> +{
> +    VirtIODevice *vdev = VIRTIO_DEVICE(qdev);
> +    VirtIOGPU *g = VIRTIO_GPU(qdev);
> +    int i;
> +
> +    g->config_size = sizeof(struct virtio_gpu_config);
> +    g->virtio_config.num_scanouts = g->conf.max_outputs;
> +    virtio_init(VIRTIO_DEVICE(g), "virtio-gpu", VIRTIO_ID_GPU,
> +                g->config_size);
> +
> +    g->req_state[0].width = 1024;
> +    g->req_state[0].height = 768;
> +
> +    g->ctrl_vq   = virtio_add_queue(vdev, 256, virtio_gpu_handle_ctrl_cb);
> +    g->cursor_vq = virtio_add_queue(vdev, 256, virtio_gpu_handle_cursor_cb);
> +
> +    g->ctrl_bh = qemu_bh_new(virtio_gpu_ctrl_bh, g);
> +    g->cursor_bh = qemu_bh_new(virtio_gpu_cursor_bh, g);
> +    QTAILQ_INIT(&g->reslist);
> +    QTAILQ_INIT(&g->fenceq);
> +
> +    g->enabled_output_bitmask = 1;
> +    g->qdev = qdev;
> +
> +    for (i = 0; i < g->conf.max_outputs; i++) {
> +        g->scanout[i].con =
> +            graphic_console_init(DEVICE(g), i, &virtio_gpu_ops, g);
> +        if (i > 0) {
> +            dpy_gfx_replace_surface(g->scanout[i].con, NULL);

GTK can't cope very well with NULL surfaces (read: after patch 7 (when 
using -vga virtio finally works) "x86_64-softmmu/qemu-system-x86_64 -vga 
virtio -display gtk" segfaults). With SDL (SDL2), it works fine.

A simple block like "if (!surface) { if (vc->gfx.surface) { 
cairo_surface_destroy(vc->gfx.surface); } vc->gfx.surface = NULL; 
return; }" at the beginning of gd_switch() in ui/gtk.c seems to work for 
me, though.

A similar problem exists with SDL1: Using Ctrl-Alt-2 segfaults (which is 
due to new_surface being NULL in sdl_switch(), and thus 
new_surface->format in the very first statement failing).

Max

> +        }
> +    }
> +}
> +
> +static void virtio_gpu_instance_init(Object *obj)
> +{
> +}
> +
> +static void virtio_gpu_reset(VirtIODevice *vdev)
> +{
> +    VirtIOGPU *g = VIRTIO_GPU(vdev);
> +    struct virtio_gpu_simple_resource *res, *tmp;
> +    int i;
> +
> +    g->enable = 0;
> +
> +    QTAILQ_FOREACH_SAFE(res, &g->reslist, next, tmp) {
> +        virtio_gpu_resource_destroy(g, res);
> +    }
> +    for (i = 0; i < g->conf.max_outputs; i++) {
> +#if 0
> +        g->req_state[i].x = 0;
> +        g->req_state[i].y = 0;
> +        if (i == 0) {
> +            g->req_state[0].width = 1024;
> +            g->req_state[0].height = 768;
> +        } else {
> +            g->req_state[i].width = 0;
> +            g->req_state[i].height = 0;
> +        }
> +#endif
> +        g->scanout[i].resource_id = 0;
> +        g->scanout[i].width = 0;
> +        g->scanout[i].height = 0;
> +        g->scanout[i].x = 0;
> +        g->scanout[i].y = 0;
> +        g->scanout[i].ds = NULL;
> +    }
> +    g->enabled_output_bitmask = 1;
> +}
> +
> +static Property virtio_gpu_properties[] = {
> +    DEFINE_VIRTIO_GPU_PROPERTIES(VirtIOGPU, conf),
> +    DEFINE_PROP_END_OF_LIST(),
> +};
> +
> +static void virtio_gpu_class_init(ObjectClass *klass, void *data)
> +{
> +    DeviceClass *dc = DEVICE_CLASS(klass);
> +    VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);
> +
> +    vdc->realize = virtio_gpu_device_realize;
> +    vdc->get_config = virtio_gpu_get_config;
> +    vdc->set_config = virtio_gpu_set_config;
> +    vdc->get_features = virtio_gpu_get_features;
> +    vdc->set_features = virtio_gpu_set_features;
> +
> +    vdc->reset = virtio_gpu_reset;
> +
> +    dc->props = virtio_gpu_properties;
> +}
> +
> +static const TypeInfo virtio_gpu_info = {
> +    .name = TYPE_VIRTIO_GPU,
> +    .parent = TYPE_VIRTIO_DEVICE,
> +    .instance_size = sizeof(VirtIOGPU),
> +    .instance_init = virtio_gpu_instance_init,
> +    .class_init = virtio_gpu_class_init,
> +};
> +
> +static void virtio_register_types(void)
> +{
> +    type_register_static(&virtio_gpu_info);
> +}
> +
> +type_init(virtio_register_types)
> +
> +QEMU_BUILD_BUG_ON(sizeof(struct virtio_gpu_ctrl_hdr)                != 24);
> +QEMU_BUILD_BUG_ON(sizeof(struct virtio_gpu_update_cursor)           != 56);
> +QEMU_BUILD_BUG_ON(sizeof(struct virtio_gpu_resource_unref)          != 32);
> +QEMU_BUILD_BUG_ON(sizeof(struct virtio_gpu_resource_create_2d)      != 40);
> +QEMU_BUILD_BUG_ON(sizeof(struct virtio_gpu_set_scanout)             != 48);
> +QEMU_BUILD_BUG_ON(sizeof(struct virtio_gpu_resource_flush)          != 48);
> +QEMU_BUILD_BUG_ON(sizeof(struct virtio_gpu_transfer_to_host_2d)     != 56);
> +QEMU_BUILD_BUG_ON(sizeof(struct virtio_gpu_mem_entry)               != 16);
> +QEMU_BUILD_BUG_ON(sizeof(struct virtio_gpu_resource_attach_backing) != 32);
> +QEMU_BUILD_BUG_ON(sizeof(struct virtio_gpu_resource_detach_backing) != 32);
> +QEMU_BUILD_BUG_ON(sizeof(struct virtio_gpu_resp_display_info)       != 408);
> diff --git a/include/hw/virtio/virtio-gpu.h b/include/hw/virtio/virtio-gpu.h
> new file mode 100644
> index 0000000..5d26ca9
> --- /dev/null
> +++ b/include/hw/virtio/virtio-gpu.h
> @@ -0,0 +1,147 @@
> +/*
> + * Virtio GPU Device
> + *
> + * Copyright Red Hat, Inc. 2013-2014
> + *
> + * Authors:
> + *     Dave Airlie <airlied@redhat.com>
> + *     Gerd Hoffmann <kraxel@redhat.com>
> + *
> + * This work is licensed under the terms of the GNU GPL, version 2.
> + * See the COPYING file in the top-level directory.
> + */
> +
> +#ifndef _QEMU_VIRTIO_VGA_H
> +#define _QEMU_VIRTIO_VGA_H
> +
> +#include "qemu/queue.h"
> +#include "ui/qemu-pixman.h"
> +#include "ui/console.h"
> +#include "hw/virtio/virtio.h"
> +#include "hw/pci/pci.h"
> +
> +#include "hw/virtio/virtgpu_hw.h"
> +#define TYPE_VIRTIO_GPU "virtio-gpu-device"
> +#define VIRTIO_GPU(obj)                                        \
> +        OBJECT_CHECK(VirtIOGPU, (obj), TYPE_VIRTIO_GPU)
> +
> +#define VIRTIO_ID_GPU 16
> +
> +#define VIRTIO_GPU_MAX_RES 16
> +
> +#define VIRTIO_GPU_MAX_SCANOUT 4
> +
> +struct virtio_gpu_simple_resource {
> +    uint32_t resource_id;
> +    uint32_t width;
> +    uint32_t height;
> +    uint32_t format;
> +    struct iovec *iov;
> +    unsigned int iov_cnt;
> +    uint32_t scanout_bitmask;
> +    pixman_image_t *image;
> +    QTAILQ_ENTRY(virtio_gpu_simple_resource) next;
> +};
> +
> +struct virtio_gpu_scanout {
> +    QemuConsole *con;
> +    DisplaySurface *ds;
> +    uint32_t width, height;
> +    int x, y;
> +    int invalidate;
> +    uint32_t resource_id;
> +    QEMUCursor *current_cursor;
> +};
> +
> +struct virtio_gpu_requested_state {
> +    uint32_t width, height;
> +    int x, y;
> +};
> +
> +struct virtio_gpu_conf {
> +    uint32_t max_outputs;
> +};
> +
> +struct virtio_gpu_ctrl_command {
> +    VirtQueueElement elem;
> +    VirtQueue *vq;
> +    struct virtio_gpu_ctrl_hdr cmd_hdr;
> +    uint32_t error;
> +    bool finished;
> +    QTAILQ_ENTRY(virtio_gpu_ctrl_command) next;
> +};
> +
> +typedef struct VirtIOGPU {
> +    VirtIODevice parent_obj;
> +
> +    QEMUBH *ctrl_bh;
> +    QEMUBH *cursor_bh;
> +    VirtQueue *ctrl_vq;
> +    VirtQueue *cursor_vq;
> +
> +    int enable;
> +
> +    int config_size;
> +    DeviceState *qdev;
> +
> +    QTAILQ_HEAD(, virtio_gpu_simple_resource) reslist;
> +    QTAILQ_HEAD(, virtio_gpu_ctrl_command) fenceq;
> +
> +    struct virtio_gpu_scanout scanout[VIRTIO_GPU_MAX_SCANOUT];
> +    struct virtio_gpu_requested_state req_state[VIRTIO_GPU_MAX_SCANOUT];
> +
> +    struct virtio_gpu_conf conf;
> +    int enabled_output_bitmask;
> +    struct virtio_gpu_config virtio_config;
> +
> +    QEMUTimer *fence_poll;
> +    QEMUTimer *print_stats;
> +
> +    struct {
> +        uint32_t inflight;
> +        uint32_t max_inflight;
> +        uint32_t requests;
> +        uint32_t req_3d;
> +        uint32_t bytes_3d;
> +    } stats;
> +} VirtIOGPU;
> +
> +extern const GraphicHwOps virtio_gpu_ops;
> +
> +/* to share between PCI and VGA */
> +#define DEFINE_VIRTIO_GPU_PCI_PROPERTIES(_state)               \
> +    DEFINE_PROP_BIT("ioeventfd", _state, flags,                \
> +                    VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, false), \
> +    DEFINE_PROP_UINT32("vectors", _state, nvectors, 3)
> +
> +#define DEFINE_VIRTIO_GPU_PROPERTIES(_state, _conf_field)               \
> +    DEFINE_PROP_UINT32("max_outputs", _state, _conf_field.max_outputs, 2)
> +
> +#define VIRTIO_GPU_FILL_CMD(out) do {                                   \
> +        size_t s;                                                       \
> +        s = iov_to_buf(cmd->elem.out_sg, cmd->elem.out_num, 0,          \
> +                       &out, sizeof(out));                              \
> +        if (s != sizeof(out)) {                                         \
> +            qemu_log_mask(LOG_GUEST_ERROR,                              \
> +                          "%s: command size incorrect %zu vs %zu\n",    \
> +                          __func__, s, sizeof(out));                    \
> +            return;                                                     \
> +        }                                                               \
> +    } while (0)
> +
> +/* virtio-gpu.c */
> +void virtio_gpu_ctrl_response(VirtIOGPU *g,
> +                              struct virtio_gpu_ctrl_command *cmd,
> +                              struct virtio_gpu_ctrl_hdr *resp,
> +                              size_t resp_len);
> +void virtio_gpu_ctrl_response_nodata(VirtIOGPU *g,
> +                                     struct virtio_gpu_ctrl_command *cmd,
> +                                     enum virtio_gpu_ctrl_type type);
> +void virtio_gpu_get_display_info(VirtIOGPU *g,
> +                                 struct virtio_gpu_ctrl_command *cmd);
> +int virtio_gpu_create_mapping_iov(struct virtio_gpu_resource_attach_backing *ab,
> +                                  struct virtio_gpu_ctrl_command *cmd,
> +                                  struct iovec **iov);
> +void virtio_gpu_cleanup_mapping_iov(struct iovec *iov, uint32_t count);
> +
> +#endif
> diff --git a/trace-events b/trace-events
> index 30eba92..a3d6fff 100644
> --- a/trace-events
> +++ b/trace-events
> @@ -1167,6 +1167,20 @@ vmware_scratch_read(uint32_t index, uint32_t value) "index %d, value 0x%x"
>   vmware_scratch_write(uint32_t index, uint32_t value) "index %d, value 0x%x"
>   vmware_setmode(uint32_t w, uint32_t h, uint32_t bpp) "%dx%d @ %d bpp"
>   
> +# hw/display/virtio-gpu.c
> +virtio_gpu_cmd_get_display_info(void) ""
> +virtio_gpu_cmd_get_caps(void) ""
> +virtio_gpu_cmd_set_scanout(uint32_t id, uint32_t res, uint32_t w, uint32_t h, uint32_t x, uint32_t y) "id %d, res 0x%x, w %d, h %d, x %d, y %d"
> +virtio_gpu_cmd_res_create_2d(uint32_t res, uint32_t fmt, uint32_t w, uint32_t h) "res 0x%x, fmt 0x%x, w %d, h %d"
> +virtio_gpu_cmd_res_create_3d(uint32_t res, uint32_t fmt, uint32_t w, uint32_t h, uint32_t d) "res 0x%x, fmt 0x%x, w %d, h %d, d %d"
> +virtio_gpu_cmd_res_unref(uint32_t res) "res 0x%x"
> +virtio_gpu_cmd_res_back_attach(uint32_t res) "res 0x%x"
> +virtio_gpu_cmd_res_back_detach(uint32_t res) "res 0x%x"
> +virtio_gpu_cmd_res_xfer_toh_2d(uint32_t res) "res 0x%x"
> +virtio_gpu_cmd_res_flush(uint32_t res, uint32_t w, uint32_t h, uint32_t x, uint32_t y) "res 0x%x, w %d, h %d, x %d, y %d"
> +virtio_gpu_fence_ctrl(uint64_t fence, uint32_t type) "fence 0x%" PRIx64 ", type 0x%x"
> +virtio_gpu_fence_resp(uint64_t fence) "fence 0x%" PRIx64
> +
>   # savevm.c
>   qemu_loadvm_state_section(unsigned int section_type) "%d"
>   qemu_loadvm_state_section_partend(uint32_t section_id) "%u"

  parent reply	other threads:[~2015-03-16 20:15 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-03-13  9:47 [Qemu-devel] [PATCH 0/9] add virtio-gpu with 2d support Gerd Hoffmann
2015-03-13  9:47 ` [Qemu-devel] [PATCH] opengl: require glx Gerd Hoffmann
2015-03-13 10:31   ` Gerd Hoffmann
2015-03-13  9:47 ` [Qemu-devel] [PATCH 1/9] virtio-gpu/2d: add hardware spec include file Gerd Hoffmann
2015-03-16 16:20   ` Max Reitz
2015-03-17  7:54     ` Gerd Hoffmann
2015-03-13  9:47 ` [Qemu-devel] [PATCH 2/9] virtio-gpu/2d: add virtio gpu core code Gerd Hoffmann
2015-03-16 18:28   ` Max Reitz
2015-03-16 20:15   ` Max Reitz [this message]
2015-03-17  8:21     ` Gerd Hoffmann
2015-03-13  9:47 ` [Qemu-devel] [PATCH 3/9] virtio-gpu-pci: add virtio pci support Gerd Hoffmann
2015-03-16 18:49   ` Max Reitz
2015-03-13  9:47 ` [Qemu-devel] [PATCH 4/9] virtio-vga: add virtio gpu device with vga compatibility Gerd Hoffmann
2015-03-16 19:17   ` Max Reitz
2015-03-13  9:47 ` [Qemu-devel] [PATCH 5/9] virtio-vga: add '-vga virtio' support Gerd Hoffmann
2015-03-16 19:30   ` Max Reitz
2015-03-13  9:47 ` [Qemu-devel] [PATCH 6/9] virtio-vga: add vgabios configuration Gerd Hoffmann
2015-03-16 19:38   ` Max Reitz
2015-03-13  9:47 ` [Qemu-devel] [PATCH 7/9] virtio-vga: add vgabios binary Gerd Hoffmann
2015-03-16 19:39   ` Max Reitz
2015-03-13  9:47 ` [Qemu-devel] [PATCH 8/9] virtio-gpu: add to display-vga test Gerd Hoffmann
2015-03-16 17:16   ` Paolo Bonzini
2015-03-17  8:25     ` Gerd Hoffmann
2015-03-13  9:47 ` [Qemu-devel] [PATCH 9/9] [hack] virtio-gpu: maskerade as -device VGA Gerd Hoffmann
2015-03-23 20:19 ` [Qemu-devel] [PATCH 0/9] add virtio-gpu with 2d support Christopher Covington

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=550739CE.90903@redhat.com \
    --to=mreitz@redhat.com \
    --cc=airlied@redhat.com \
    --cc=kraxel@redhat.com \
    --cc=mst@redhat.com \
    --cc=qemu-devel@nongnu.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 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.