diff options
| author | Peter Maydell <peter.maydell@linaro.org> | 2021-05-12 14:45:21 +0100 |
|---|---|---|
| committer | Peter Maydell <peter.maydell@linaro.org> | 2021-05-12 14:45:21 +0100 |
| commit | a5ccdccc97d6e0d75282ede5b866cf694e9602b0 (patch) | |
| tree | 326271f7177132e4340f4eeb173cb07b4482b1ac /hw/display/virtio-gpu.c | |
| parent | 4f24f774ba83e4c4a3179929d5f2ee183ce4fd2f (diff) | |
| parent | b36eb8860f8f4a9c6f131c3fd380116a3017e022 (diff) | |
| download | focaccia-qemu-a5ccdccc97d6e0d75282ede5b866cf694e9602b0.tar.gz focaccia-qemu-a5ccdccc97d6e0d75282ede5b866cf694e9602b0.zip | |
Merge remote-tracking branch 'remotes/kraxel/tags/vga-20210510-pull-request' into staging
edid: display id support (for 5k+), bugfixes. virtio-gpu: iommu fix, device split. # gpg: Signature made Mon 10 May 2021 14:20:36 BST # gpg: using RSA key A0328CFFB93A17A79901FE7D4CB6D8EED3E87138 # gpg: Good signature from "Gerd Hoffmann (work) <kraxel@redhat.com>" [full] # gpg: aka "Gerd Hoffmann <gerd@kraxel.org>" [full] # gpg: aka "Gerd Hoffmann (private) <kraxel@gmail.com>" [full] # Primary key fingerprint: A032 8CFF B93A 17A7 9901 FE7D 4CB6 D8EE D3E8 7138 * remotes/kraxel/tags/vga-20210510-pull-request: (25 commits) virtio-gpu: add virtio-vga-gl modules: add have_vga virtio-gpu: add virtio-gpu-gl-pci virtio-gpu: move fields to struct VirtIOGPUGL virtio-gpu: drop use_virgl_renderer virtio-gpu: move virtio-gpu-gl-device to separate module virtio-gpu: drop VIRGL() macro virtio-gpu: move update_cursor_data virtio-gpu: move virgl process_cmd virtio-gpu: move virgl gl_flushed virtio-gpu: move virgl handle_ctrl virtio-gpu: use class function for ctrl queue handlers virtio-gpu: move virgl reset virtio-gpu: move virgl realize + properties virtio-gpu: add virtio-gpu-gl-device virtio-gpu: rename virgl source file. virtio-gpu: handle partial maps properly edid: add support for DisplayID extension (5k resolution) edid: allow arbitrary-length checksums edid: move timing generation into a separate function ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw/display/virtio-gpu.c')
| -rw-r--r-- | hw/display/virtio-gpu.c | 218 |
1 files changed, 66 insertions, 152 deletions
diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c index c9f5e36fd0..db56f0454a 100644 --- a/hw/display/virtio-gpu.c +++ b/hw/display/virtio-gpu.c @@ -39,26 +39,9 @@ virtio_gpu_find_resource(VirtIOGPU *g, uint32_t resource_id); static void virtio_gpu_cleanup_mapping(VirtIOGPU *g, struct virtio_gpu_simple_resource *res); -#ifdef CONFIG_VIRGL -#include <virglrenderer.h> -#define VIRGL(_g, _virgl, _simple, ...) \ - do { \ - if (_g->parent_obj.use_virgl_renderer) { \ - _virgl(__VA_ARGS__); \ - } else { \ - _simple(__VA_ARGS__); \ - } \ - } while (0) -#else -#define VIRGL(_g, _virgl, _simple, ...) \ - do { \ - _simple(__VA_ARGS__); \ - } while (0) -#endif - -static void update_cursor_data_simple(VirtIOGPU *g, - struct virtio_gpu_scanout *s, - uint32_t resource_id) +void virtio_gpu_update_cursor_data(VirtIOGPU *g, + struct virtio_gpu_scanout *s, + uint32_t resource_id) { struct virtio_gpu_simple_resource *res; uint32_t pixels; @@ -79,36 +62,10 @@ static void update_cursor_data_simple(VirtIOGPU *g, pixels * sizeof(uint32_t)); } -#ifdef CONFIG_VIRGL - -static void update_cursor_data_virgl(VirtIOGPU *g, - struct virtio_gpu_scanout *s, - uint32_t resource_id) -{ - uint32_t width, height; - uint32_t pixels, *data; - - data = virgl_renderer_get_cursor_data(resource_id, &width, &height); - if (!data) { - return; - } - - if (width != s->current_cursor->width || - height != s->current_cursor->height) { - free(data); - return; - } - - pixels = s->current_cursor->width * s->current_cursor->height; - memcpy(s->current_cursor->data, data, pixels * sizeof(uint32_t)); - free(data); -} - -#endif - static void update_cursor(VirtIOGPU *g, struct virtio_gpu_update_cursor *cursor) { struct virtio_gpu_scanout *s; + VirtIOGPUClass *vgc = VIRTIO_GPU_GET_CLASS(g); bool move = cursor->hdr.type == VIRTIO_GPU_CMD_MOVE_CURSOR; if (cursor->pos.scanout_id >= g->parent_obj.conf.max_outputs) { @@ -131,8 +88,7 @@ static void update_cursor(VirtIOGPU *g, struct virtio_gpu_update_cursor *cursor) s->current_cursor->hot_y = cursor->hot_y; if (cursor->resource_id > 0) { - VIRGL(g, update_cursor_data_virgl, update_cursor_data_simple, - g, s, cursor->resource_id); + vgc->update_cursor_data(g, s, cursor->resource_id); } dpy_cursor_define(s->con, s->current_cursor); @@ -608,11 +564,12 @@ static void virtio_gpu_set_scanout(VirtIOGPU *g, int virtio_gpu_create_mapping_iov(VirtIOGPU *g, struct virtio_gpu_resource_attach_backing *ab, struct virtio_gpu_ctrl_command *cmd, - uint64_t **addr, struct iovec **iov) + uint64_t **addr, struct iovec **iov, + uint32_t *niov) { struct virtio_gpu_mem_entry *ents; size_t esize, s; - int i; + int e, v; if (ab->nr_entries > 16384) { qemu_log_mask(LOG_GUEST_ERROR, @@ -633,37 +590,53 @@ int virtio_gpu_create_mapping_iov(VirtIOGPU *g, return -1; } - *iov = g_malloc0(sizeof(struct iovec) * ab->nr_entries); + *iov = NULL; if (addr) { - *addr = g_malloc0(sizeof(uint64_t) * ab->nr_entries); + *addr = NULL; } - for (i = 0; i < ab->nr_entries; i++) { - uint64_t a = le64_to_cpu(ents[i].addr); - uint32_t l = le32_to_cpu(ents[i].length); - hwaddr len = l; - (*iov)[i].iov_base = dma_memory_map(VIRTIO_DEVICE(g)->dma_as, - a, &len, DMA_DIRECTION_TO_DEVICE); - (*iov)[i].iov_len = len; - if (addr) { - (*addr)[i] = a; - } - if (!(*iov)[i].iov_base || len != l) { - qemu_log_mask(LOG_GUEST_ERROR, "%s: failed to map MMIO memory for" - " resource %d element %d\n", - __func__, ab->resource_id, i); - if ((*iov)[i].iov_base) { - i++; /* cleanup the 'i'th map */ + for (e = 0, v = 0; e < ab->nr_entries; e++) { + uint64_t a = le64_to_cpu(ents[e].addr); + uint32_t l = le32_to_cpu(ents[e].length); + hwaddr len; + void *map; + + do { + len = l; + map = dma_memory_map(VIRTIO_DEVICE(g)->dma_as, + a, &len, DMA_DIRECTION_TO_DEVICE); + if (!map) { + qemu_log_mask(LOG_GUEST_ERROR, "%s: failed to map MMIO memory for" + " resource %d element %d\n", + __func__, ab->resource_id, e); + virtio_gpu_cleanup_mapping_iov(g, *iov, v); + g_free(ents); + *iov = NULL; + if (addr) { + g_free(*addr); + *addr = NULL; + } + return -1; } - virtio_gpu_cleanup_mapping_iov(g, *iov, i); - g_free(ents); - *iov = NULL; + + if (!(v % 16)) { + *iov = g_realloc(*iov, sizeof(struct iovec) * (v + 16)); + if (addr) { + *addr = g_realloc(*addr, sizeof(uint64_t) * (v + 16)); + } + } + (*iov)[v].iov_base = map; + (*iov)[v].iov_len = len; if (addr) { - g_free(*addr); - *addr = NULL; + (*addr)[v] = a; } - return -1; - } + + a += len; + l -= len; + v += 1; + } while (l > 0); } + *niov = v; + g_free(ents); return 0; } @@ -717,13 +690,12 @@ virtio_gpu_resource_attach_backing(VirtIOGPU *g, return; } - ret = virtio_gpu_create_mapping_iov(g, &ab, cmd, &res->addrs, &res->iov); + ret = virtio_gpu_create_mapping_iov(g, &ab, cmd, &res->addrs, + &res->iov, &res->iov_cnt); if (ret != 0) { cmd->error = VIRTIO_GPU_RESP_ERR_UNSPEC; return; } - - res->iov_cnt = ab.nr_entries; } static void @@ -747,8 +719,8 @@ virtio_gpu_resource_detach_backing(VirtIOGPU *g, virtio_gpu_cleanup_mapping(g, res); } -static void virtio_gpu_simple_process_cmd(VirtIOGPU *g, - struct virtio_gpu_ctrl_command *cmd) +void virtio_gpu_simple_process_cmd(VirtIOGPU *g, + struct virtio_gpu_ctrl_command *cmd) { VIRTIO_GPU_FILL_CMD(cmd->cmd_hdr); virtio_gpu_ctrl_hdr_bswap(&cmd->cmd_hdr); @@ -806,6 +778,7 @@ static void virtio_gpu_handle_cursor_cb(VirtIODevice *vdev, VirtQueue *vq) void virtio_gpu_process_cmdq(VirtIOGPU *g) { struct virtio_gpu_ctrl_command *cmd; + VirtIOGPUClass *vgc = VIRTIO_GPU_GET_CLASS(g); if (g->processing_cmdq) { return; @@ -819,8 +792,7 @@ void virtio_gpu_process_cmdq(VirtIOGPU *g) } /* process command */ - VIRGL(g, virtio_gpu_virgl_process_cmd, virtio_gpu_simple_process_cmd, - g, cmd); + vgc->process_cmd(g, cmd); QTAILQ_REMOVE(&g->cmdq, cmd, next); if (virtio_gpu_stats_enabled(g->parent_obj.conf)) { @@ -843,19 +815,6 @@ void virtio_gpu_process_cmdq(VirtIOGPU *g) g->processing_cmdq = false; } -static void virtio_gpu_gl_flushed(VirtIOGPUBase *b) -{ - VirtIOGPU *g = VIRTIO_GPU(b); - -#ifdef CONFIG_VIRGL - if (g->renderer_reset) { - g->renderer_reset = false; - virtio_gpu_virgl_reset(g); - } -#endif - virtio_gpu_process_cmdq(g); -} - static void virtio_gpu_handle_ctrl(VirtIODevice *vdev, VirtQueue *vq) { VirtIOGPU *g = VIRTIO_GPU(vdev); @@ -865,13 +824,6 @@ static void virtio_gpu_handle_ctrl(VirtIODevice *vdev, VirtQueue *vq) return; } -#ifdef CONFIG_VIRGL - if (!g->renderer_inited && g->parent_obj.use_virgl_renderer) { - virtio_gpu_virgl_init(g); - g->renderer_inited = true; - } -#endif - cmd = virtqueue_pop(vq, sizeof(struct virtio_gpu_ctrl_command)); while (cmd) { cmd->vq = vq; @@ -882,18 +834,14 @@ static void virtio_gpu_handle_ctrl(VirtIODevice *vdev, VirtQueue *vq) } virtio_gpu_process_cmdq(g); - -#ifdef CONFIG_VIRGL - if (g->parent_obj.use_virgl_renderer) { - virtio_gpu_virgl_fence_poll(g); - } -#endif } static void virtio_gpu_ctrl_bh(void *opaque) { VirtIOGPU *g = opaque; - virtio_gpu_handle_ctrl(&g->parent_obj.parent_obj, g->ctrl_vq); + VirtIOGPUClass *vgc = VIRTIO_GPU_GET_CLASS(g); + + vgc->handle_ctrl(&g->parent_obj.parent_obj, g->ctrl_vq); } static void virtio_gpu_handle_cursor(VirtIODevice *vdev, VirtQueue *vq) @@ -1105,25 +1053,10 @@ static int virtio_gpu_load(QEMUFile *f, void *opaque, size_t size, return 0; } -static void virtio_gpu_device_realize(DeviceState *qdev, Error **errp) +void virtio_gpu_device_realize(DeviceState *qdev, Error **errp) { VirtIODevice *vdev = VIRTIO_DEVICE(qdev); VirtIOGPU *g = VIRTIO_GPU(qdev); - bool have_virgl; - -#if !defined(CONFIG_VIRGL) || defined(HOST_WORDS_BIGENDIAN) - have_virgl = false; -#else - have_virgl = display_opengl; -#endif - if (!have_virgl) { - g->parent_obj.conf.flags &= ~(1 << VIRTIO_GPU_FLAG_VIRGL_ENABLED); - } else { -#if defined(CONFIG_VIRGL) - VIRTIO_GPU_BASE(g)->virtio_config.num_capsets = - virtio_gpu_virgl_get_num_capsets(g); -#endif - } if (!virtio_gpu_base_device_realize(qdev, virtio_gpu_handle_ctrl_cb, @@ -1141,18 +1074,12 @@ static void virtio_gpu_device_realize(DeviceState *qdev, Error **errp) QTAILQ_INIT(&g->fenceq); } -static void virtio_gpu_reset(VirtIODevice *vdev) +void virtio_gpu_reset(VirtIODevice *vdev) { VirtIOGPU *g = VIRTIO_GPU(vdev); struct virtio_gpu_simple_resource *res, *tmp; struct virtio_gpu_ctrl_command *cmd; -#ifdef CONFIG_VIRGL - if (g->parent_obj.use_virgl_renderer) { - virtio_gpu_virgl_reset(g); - } -#endif - QTAILQ_FOREACH_SAFE(res, &g->reslist, next, tmp) { virtio_gpu_resource_destroy(g, res); } @@ -1170,17 +1097,6 @@ static void virtio_gpu_reset(VirtIODevice *vdev) g_free(cmd); } -#ifdef CONFIG_VIRGL - if (g->parent_obj.use_virgl_renderer) { - if (g->parent_obj.renderer_blocked) { - g->renderer_reset = true; - } else { - virtio_gpu_virgl_reset(g); - } - g->parent_obj.use_virgl_renderer = false; - } -#endif - virtio_gpu_base_reset(VIRTIO_GPU_BASE(vdev)); } @@ -1235,12 +1151,6 @@ static Property virtio_gpu_properties[] = { VIRTIO_GPU_BASE_PROPERTIES(VirtIOGPU, parent_obj.conf), DEFINE_PROP_SIZE("max_hostmem", VirtIOGPU, conf_max_hostmem, 256 * MiB), -#ifdef CONFIG_VIRGL - DEFINE_PROP_BIT("virgl", VirtIOGPU, parent_obj.conf.flags, - VIRTIO_GPU_FLAG_VIRGL_ENABLED, true), - DEFINE_PROP_BIT("stats", VirtIOGPU, parent_obj.conf.flags, - VIRTIO_GPU_FLAG_STATS_ENABLED, false), -#endif DEFINE_PROP_END_OF_LIST(), }; @@ -1248,9 +1158,12 @@ static void virtio_gpu_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass); - VirtIOGPUBaseClass *vgc = VIRTIO_GPU_BASE_CLASS(klass); + VirtIOGPUClass *vgc = VIRTIO_GPU_CLASS(klass); + + vgc->handle_ctrl = virtio_gpu_handle_ctrl; + vgc->process_cmd = virtio_gpu_simple_process_cmd; + vgc->update_cursor_data = virtio_gpu_update_cursor_data; - vgc->gl_flushed = virtio_gpu_gl_flushed; vdc->realize = virtio_gpu_device_realize; vdc->reset = virtio_gpu_reset; vdc->get_config = virtio_gpu_get_config; @@ -1264,6 +1177,7 @@ static const TypeInfo virtio_gpu_info = { .name = TYPE_VIRTIO_GPU, .parent = TYPE_VIRTIO_GPU_BASE, .instance_size = sizeof(VirtIOGPU), + .class_size = sizeof(VirtIOGPUClass), .class_init = virtio_gpu_class_init, }; |