[Spice-commits] Branch 'spice.kvm.v18' - 10 commits - hw/qxl-logger.c hw/qxl-render.c hw/qxl.c hw/qxl.h
Gerd Hoffmann
kraxel at kemper.freedesktop.org
Tue Oct 5 05:44:30 PDT 2010
hw/qxl-logger.c | 64 ++++++++++++++++++++++++++++++++++++++---
hw/qxl-render.c | 22 +++++++-------
hw/qxl.c | 87 ++++++++++++++++++++++++++++++++++++++++----------------
hw/qxl.h | 1
4 files changed, 135 insertions(+), 39 deletions(-)
New commits:
commit de44ce81f14972d8b317ccd55f08d3aa76be6f92
Author: Gerd Hoffmann <kraxel at redhat.com>
Date: Mon Sep 13 15:03:48 2010 +0200
qxl: release ring tweaks
diff --git a/hw/qxl.c b/hw/qxl.c
index 151967b..b86620d 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -400,30 +400,40 @@ static int interface_req_cmd_notification(QXLInstance *sin)
}
/* called from spice server thread context only */
-static inline void qxl_push_free_res(PCIQXLDevice *d)
+static inline void qxl_push_free_res(PCIQXLDevice *d, int flush)
{
QXLReleaseRing *ring = &d->ram->release_ring;
uint64_t *item;
+ int notify;
#define QXL_FREE_BUNCH_SIZE 32
- if (SPICE_RING_IS_EMPTY(ring) || (d->num_free_res >= QXL_FREE_BUNCH_SIZE &&
- ring->prod - ring->cons + 2 != ring->num_items)) {
- int notify;
+ if (ring->prod - ring->cons + 1 == ring->num_items) {
+ /* ring full -- can't push */
+ return;
+ }
+ if (!flush && d->oom_running) {
+ /* collect everything from oom handler before pushing */
+ return;
+ }
+ if (!flush && d->num_free_res < QXL_FREE_BUNCH_SIZE) {
+ /* collect a bit more before pushing */
+ return;
+ }
- SPICE_RING_PUSH(ring, notify);
- dprint(d, 1, "free: push %d items, notify %s, ring %d/%d\n",
- d->num_free_res, notify ? "yes" : "no",
- ring->prod - ring->cons, ring->num_items);
- if (notify) {
- qxl_send_events(d, QXL_INTERRUPT_DISPLAY);
- }
- SPICE_RING_PROD_ITEM(ring, item);
- *item = 0;
- d->num_free_res = 0;
- d->last_release = NULL;
- qxl_ring_set_dirty(d);
+ SPICE_RING_PUSH(ring, notify);
+ dprint(d, 1, "free: push %d items, notify %s, ring %d/%d [%d,%d]\n",
+ d->num_free_res, notify ? "yes" : "no",
+ ring->prod - ring->cons, ring->num_items,
+ ring->prod, ring->cons);
+ if (notify) {
+ qxl_send_events(d, QXL_INTERRUPT_DISPLAY);
}
+ SPICE_RING_PROD_ITEM(ring, item);
+ *item = 0;
+ d->num_free_res = 0;
+ d->last_release = NULL;
+ qxl_ring_set_dirty(d);
}
/* called from spice server thread context only */
@@ -463,7 +473,7 @@ static void interface_release_resource(QXLInstance *sin,
qxl->last_release = ext.info;
qxl->num_free_res++;
dprint(qxl, 1, "%4d\r", qxl->num_free_res);
- qxl_push_free_res(qxl);
+ qxl_push_free_res(qxl, 0);
}
/* called from spice server thread context only */
@@ -539,7 +549,7 @@ static int interface_flush_resources(QXLInstance *sin)
dprint(qxl, 1, "free: guest flush (have %d)\n", qxl->num_free_res);
ret = qxl->num_free_res;
if (ret) {
- qxl_push_free_res(qxl);
+ qxl_push_free_res(qxl, 1);
}
return ret;
}
@@ -877,7 +887,9 @@ static void qxl_set_mode(PCIQXLDevice *d, int modenr, int loadvm)
dprint(d, 1, "%s: mode %d [ %d x %d @ %d bpp devmem 0x%lx ]\n", __FUNCTION__,
modenr, mode->x_res, mode->y_res, mode->bits, devmem);
- qxl_hard_reset(d, 0);
+ if (!loadvm) {
+ qxl_hard_reset(d, 0);
+ }
d->guest_slots[0].slot = slot;
qxl_add_memslot(d, 0, devmem);
@@ -939,7 +951,9 @@ static void ioport_write(void *opaque, uint32_t addr, uint32_t val)
if (!SPICE_RING_IS_EMPTY(&d->ram->release_ring)) {
break;
}
+ d->oom_running = 1;
d->ssd.worker->oom(d->ssd.worker);
+ d->oom_running = 0;
break;
case QXL_IO_SET_MODE:
dprint(d, 1, "QXL_SET_MODE %d\n", val);
diff --git a/hw/qxl.h b/hw/qxl.h
index 8c0c928..6733ec2 100644
--- a/hw/qxl.h
+++ b/hw/qxl.h
@@ -63,6 +63,7 @@ typedef struct PCIQXLDevice {
uint32_t num_free_res;
QXLReleaseInfo *last_release;
uint32_t last_release_offset;
+ uint32_t oom_running;
/* rom pci bar */
QXLRom shadow_rom;
commit f99008b5ae78c16ed1d31ac600e83f988ee2d269
Author: Gerd Hoffmann <kraxel at redhat.com>
Date: Wed Sep 8 10:29:46 2010 +0200
[rhel6 compat experimental] qxl: zap separate vgafb
diff --git a/hw/qxl.c b/hw/qxl.c
index e701b54..151967b 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -172,7 +172,7 @@ static void init_qxl_rom(PCIQXLDevice *d)
if (maxfb < VGA_RAM_SIZE && d->id == 0)
maxfb = VGA_RAM_SIZE;
- if (d->revision == 1) {
+ if (0 && d->revision == 1) {
/* spice 0.4 has a separate vga mode framebuffer */
vgafb_size = VGA_RAM_SIZE;
rom->draw_area_offset = cpu_to_le32(VGA_RAM_SIZE);
commit 3164dc7ab1d3ed6cda71f0289cf81f3ab379dabd
Author: Gerd Hoffmann <kraxel at redhat.com>
Date: Wed Sep 8 10:27:43 2010 +0200
qxl: revert maxfb quirk
diff --git a/hw/qxl.c b/hw/qxl.c
index ba6e2e2..e701b54 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -169,8 +169,8 @@ static void init_qxl_rom(PCIQXLDevice *d)
modes->modes[i].y_mili = cpu_to_le32(qxl_modes[i].y_mili);
modes->modes[i].orientation = cpu_to_le32(qxl_modes[i].orientation);
}
- if (maxfb < VGA_RAM_SIZE*2 && d->id == 0)
- maxfb = VGA_RAM_SIZE*2;
+ if (maxfb < VGA_RAM_SIZE && d->id == 0)
+ maxfb = VGA_RAM_SIZE;
if (d->revision == 1) {
/* spice 0.4 has a separate vga mode framebuffer */
commit 9fecda7a46b2cc39a656dec9df1cc26bd4ebed71
Author: Gerd Hoffmann <kraxel at redhat.com>
Date: Wed Sep 8 09:44:00 2010 +0200
qxl: reorganize highres modes
diff --git a/hw/qxl.c b/hw/qxl.c
index 42bc9eb..ba6e2e2 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -86,11 +86,15 @@ static QXLMode qxl_modes[] = {
QXL_MODE_EX(1600, 1200),
QXL_MODE_EX(1680, 1050),
QXL_MODE_EX(1920, 1080),
-#ifdef QXL_HIRES_MODES
+#if VGA_RAM_SIZE >= (16 * 1024 * 1024)
+ /* these modes need more than 8 MB video memory */
QXL_MODE_EX(1920, 1200),
QXL_MODE_EX(1920, 1440),
QXL_MODE_EX(2048, 1536),
QXL_MODE_EX(2560, 1600),
+#endif
+#if VGA_RAM_SIZE >= (32 * 1024 * 1024)
+ /* these modes need more than 16 MB video memory */
QXL_MODE_EX(2560, 2048),
QXL_MODE_EX(2800, 2100),
QXL_MODE_EX(3200, 2400),
commit f3e054f21c86c1cf45770637959a8210dbf25a7c
Author: Gerd Hoffmann <kraxel at redhat.com>
Date: Tue Sep 7 16:47:21 2010 +0200
qxl: adjust render debug logging
diff --git a/hw/qxl-render.c b/hw/qxl-render.c
index 2b1c6e7..4a39c23 100644
--- a/hw/qxl-render.c
+++ b/hw/qxl-render.c
@@ -83,14 +83,14 @@ void qxl_render_update(PCIQXLDevice *qxl)
} else {
ptr = qxl->guest_primary.data;
}
- fprintf(stderr, "%s: %dx%d, stride %d, bpp %d, depth %d, flip %s\n",
- __FUNCTION__,
- qxl->guest_primary.surface.width,
- qxl->guest_primary.surface.height,
- qxl->guest_primary.stride,
- qxl->guest_primary.bytes_pp,
- qxl->guest_primary.bits_pp,
- qxl->guest_primary.flipped ? "yes" : "no");
+ dprint(qxl, 1, "%s: %dx%d, stride %d, bpp %d, depth %d, flip %s\n",
+ __FUNCTION__,
+ qxl->guest_primary.surface.width,
+ qxl->guest_primary.surface.height,
+ qxl->guest_primary.stride,
+ qxl->guest_primary.bytes_pp,
+ qxl->guest_primary.bits_pp,
+ qxl->guest_primary.flipped ? "yes" : "no");
vga->ds->surface =
qemu_create_displaysurface_from(qxl->guest_primary.surface.width,
qxl->guest_primary.surface.height,
@@ -141,7 +141,7 @@ static QEMUCursor *qxl_cursor(PCIQXLDevice *qxl, QXLCursor *cursor)
case SPICE_CURSOR_TYPE_ALPHA:
size = cursor->header.width * cursor->header.height * sizeof(uint32_t);
memcpy(c->data, cursor->chunk.data, size);
- if (qxl->debug > 1) {
+ if (qxl->debug > 2) {
cursor_print_ascii_art(c, "qxl/alpha");
}
break;
@@ -149,7 +149,7 @@ static QEMUCursor *qxl_cursor(PCIQXLDevice *qxl, QXLCursor *cursor)
mask = cursor->chunk.data;
image = mask + cursor_get_mono_bpl(c) * c->width;
cursor_set_mono(c, 0xffffff, 0x000000, image, 1, mask);
- if (qxl->debug > 1) {
+ if (qxl->debug > 2) {
cursor_print_ascii_art(c, "qxl/mono");
}
break;
@@ -178,7 +178,7 @@ void qxl_render_cursor(PCIQXLDevice *qxl, QXLCommandExt *ext)
return;
}
- if (qxl->debug && cmd->type != QXL_CURSOR_MOVE) {
+ if (qxl->debug > 1 && cmd->type != QXL_CURSOR_MOVE) {
fprintf(stderr, "%s", __FUNCTION__);
qxl_log_cmd_cursor(qxl, cmd, ext->group_id);
fprintf(stderr, "\n");
commit d9120e9be1830efa306198167e4f844313910f91
Author: Gerd Hoffmann <kraxel at redhat.com>
Date: Tue Sep 7 16:46:53 2010 +0200
qxl: add stuff to logger
diff --git a/hw/qxl-logger.c b/hw/qxl-logger.c
index 378770f..cad5165 100644
--- a/hw/qxl-logger.c
+++ b/hw/qxl-logger.c
@@ -87,19 +87,75 @@ static const char *qxl_v2n(const char *n[], size_t l, int v)
}
#define qxl_name(_list, _value) qxl_v2n(_list, ARRAY_SIZE(_list), _value)
-static void qxl_log_cmd_draw(PCIQXLDevice *qxl, QXLDrawable *draw)
+static void qxl_log_image(PCIQXLDevice *qxl, QXLPHYSICAL addr, int group_id)
+{
+ QXLImage *image;
+ QXLImageDescriptor *desc;
+
+ image = qxl_phys2virt(qxl, addr, group_id);
+ desc = &image->descriptor;
+ fprintf(stderr, " (id %" PRIx64 " type %d flags %d width %d height %d",
+ desc->id, desc->type, desc->flags, desc->width, desc->height);
+ switch (desc->type) {
+ case SPICE_IMAGE_TYPE_BITMAP:
+ fprintf(stderr, ", fmt %d flags %d x %d y %d stride %d"
+ " palette %" PRIx64 " data %" PRIx64,
+ image->bitmap.format, image->bitmap.flags,
+ image->bitmap.x, image->bitmap.y,
+ image->bitmap.stride,
+ image->bitmap.palette, image->bitmap.data);
+ break;
+ }
+ fprintf(stderr, ")");
+}
+
+static void qxl_log_rect(QXLRect *rect)
+{
+ fprintf(stderr, " %dx%d+%d+%d",
+ rect->right - rect->left,
+ rect->bottom - rect->top,
+ rect->left, rect->top);
+}
+
+static void qxl_log_cmd_draw_copy(PCIQXLDevice *qxl, QXLCopy *copy, int group_id)
+{
+ fprintf(stderr, " src %" PRIx64,
+ copy->src_bitmap);
+ qxl_log_image(qxl, copy->src_bitmap, group_id);
+ fprintf(stderr, " area");
+ qxl_log_rect(©->src_area);
+ fprintf(stderr, " rop %d", copy->rop_descriptor);
+}
+
+static void qxl_log_cmd_draw(PCIQXLDevice *qxl, QXLDrawable *draw, int group_id)
{
fprintf(stderr, ": surface_id %d type %s effect %s",
draw->surface_id,
qxl_name(qxl_draw_type, draw->type),
qxl_name(qxl_draw_effect, draw->effect));
+ switch (draw->type) {
+ case QXL_DRAW_COPY:
+ qxl_log_cmd_draw_copy(qxl, &draw->u.copy, group_id);
+ break;
+ }
}
-static void qxl_log_cmd_draw_compat(PCIQXLDevice *qxl, QXLCompatDrawable *draw)
+static void qxl_log_cmd_draw_compat(PCIQXLDevice *qxl, QXLCompatDrawable *draw,
+ int group_id)
{
fprintf(stderr, ": type %s effect %s",
qxl_name(qxl_draw_type, draw->type),
qxl_name(qxl_draw_effect, draw->effect));
+ if (draw->bitmap_offset) {
+ fprintf(stderr, ": bitmap %d",
+ draw->bitmap_offset);
+ qxl_log_rect(&draw->bitmap_area);
+ }
+ switch (draw->type) {
+ case QXL_DRAW_COPY:
+ qxl_log_cmd_draw_copy(qxl, &draw->u.copy, group_id);
+ break;
+ }
}
static void qxl_log_cmd_surface(PCIQXLDevice *qxl, QXLSurfaceCmd *cmd)
@@ -164,9 +220,9 @@ void qxl_log_command(PCIQXLDevice *qxl, const char *ring, QXLCommandExt *ext)
switch (ext->cmd.type) {
case QXL_CMD_DRAW:
if (!compat) {
- qxl_log_cmd_draw(qxl, data);
+ qxl_log_cmd_draw(qxl, data, ext->group_id);
} else {
- qxl_log_cmd_draw_compat(qxl, data);
+ qxl_log_cmd_draw_compat(qxl, data, ext->group_id);
}
break;
case QXL_CMD_SURFACE:
commit 7cf5d99858dc31b5eaddd67e800db32dfc1574fc
Author: Gerd Hoffmann <kraxel at redhat.com>
Date: Tue Sep 7 16:46:28 2010 +0200
[debug] qxl: resource free logging
diff --git a/hw/qxl.c b/hw/qxl.c
index c86d832..42bc9eb 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -408,6 +408,9 @@ static inline void qxl_push_free_res(PCIQXLDevice *d)
int notify;
SPICE_RING_PUSH(ring, notify);
+ dprint(d, 1, "free: push %d items, notify %s, ring %d/%d\n",
+ d->num_free_res, notify ? "yes" : "no",
+ ring->prod - ring->cons, ring->num_items);
if (notify) {
qxl_send_events(d, QXL_INTERRUPT_DISPLAY);
}
@@ -455,6 +458,7 @@ static void interface_release_resource(QXLInstance *sin,
}
qxl->last_release = ext.info;
qxl->num_free_res++;
+ dprint(qxl, 1, "%4d\r", qxl->num_free_res);
qxl_push_free_res(qxl);
}
@@ -528,6 +532,7 @@ static int interface_flush_resources(QXLInstance *sin)
PCIQXLDevice *qxl = container_of(sin, PCIQXLDevice, ssd.qxl);
int ret;
+ dprint(qxl, 1, "free: guest flush (have %d)\n", qxl->num_free_res);
ret = qxl->num_free_res;
if (ret) {
qxl_push_free_res(qxl);
commit 516c463d82d028ee195c3f7cc11ae6e430b53fff
Author: Gerd Hoffmann <kraxel at redhat.com>
Date: Tue Sep 7 16:45:27 2010 +0200
qxl: fix release ring overrun
diff --git a/hw/qxl.c b/hw/qxl.c
index a8ef869..c86d832 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -401,10 +401,10 @@ static inline void qxl_push_free_res(PCIQXLDevice *d)
QXLReleaseRing *ring = &d->ram->release_ring;
uint64_t *item;
-#define QXL_FREE_BUNCH_SIZE 10
+#define QXL_FREE_BUNCH_SIZE 32
- if (SPICE_RING_IS_EMPTY(ring) || (d->num_free_res == QXL_FREE_BUNCH_SIZE &&
- ring->prod - ring->cons + 1 != ring->num_items)) {
+ if (SPICE_RING_IS_EMPTY(ring) || (d->num_free_res >= QXL_FREE_BUNCH_SIZE &&
+ ring->prod - ring->cons + 2 != ring->num_items)) {
int notify;
SPICE_RING_PUSH(ring, notify);
commit 180dadd39efd419a7bdced6955e7042d729b691c
Author: Gerd Hoffmann <kraxel at redhat.com>
Date: Tue Sep 7 16:44:40 2010 +0200
qxl: more spice 0.4 migration compatibility
diff --git a/hw/qxl.c b/hw/qxl.c
index f6e2107..a8ef869 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -130,6 +130,7 @@ static void init_qxl_rom(PCIQXLDevice *d)
{
QXLRom *rom = qemu_get_ram_ptr(d->rom_offset);
QXLModes *modes = (QXLModes *)(rom + 1);
+ uint32_t vgafb_size;
uint32_t ram_header_size;
uint32_t surface0_area_size;
uint32_t num_pages;
@@ -164,19 +165,30 @@ static void init_qxl_rom(PCIQXLDevice *d)
modes->modes[i].y_mili = cpu_to_le32(qxl_modes[i].y_mili);
modes->modes[i].orientation = cpu_to_le32(qxl_modes[i].orientation);
}
- if (maxfb < VGA_RAM_SIZE && d->id == 0)
- maxfb = VGA_RAM_SIZE;
+ if (maxfb < VGA_RAM_SIZE*2 && d->id == 0)
+ maxfb = VGA_RAM_SIZE*2;
+
+ if (d->revision == 1) {
+ /* spice 0.4 has a separate vga mode framebuffer */
+ vgafb_size = VGA_RAM_SIZE;
+ rom->draw_area_offset = cpu_to_le32(VGA_RAM_SIZE);
+ } else {
+ /* in spice 0.6 the surface0 area is used for vga mode too */
+ vgafb_size = 0;
+ rom->draw_area_offset = 0;
+ }
ram_header_size = ALIGN(sizeof(QXLRam), 4096);
surface0_area_size = ALIGN(maxfb, 4096);
num_pages = d->vga.vram_size;
num_pages -= ram_header_size;
num_pages -= surface0_area_size;
+ num_pages -= vgafb_size;
num_pages = num_pages / TARGET_PAGE_SIZE;
rom->draw_area_offset = cpu_to_le32(0);
rom->surface0_area_size = cpu_to_le32(surface0_area_size);
- rom->pages_offset = cpu_to_le32(surface0_area_size);
+ rom->pages_offset = cpu_to_le32(surface0_area_size+vgafb_size);
rom->num_pages = cpu_to_le32(num_pages);
rom->ram_header_offset = cpu_to_le32(d->vga.vram_size - ram_header_size);
@@ -834,7 +846,7 @@ static void qxl_destroy_primary(PCIQXLDevice *d)
d->ssd.worker->destroy_primary_surface(d->ssd.worker, 0);
}
-static void qxl_set_mode(PCIQXLDevice *d, int modenr)
+static void qxl_set_mode(PCIQXLDevice *d, int modenr, int loadvm)
{
pcibus_t start = d->pci.io_regions[QXL_RAM_RANGE_INDEX].addr;
pcibus_t end = d->pci.io_regions[QXL_RAM_RANGE_INDEX].size + start;
@@ -849,8 +861,9 @@ static void qxl_set_mode(PCIQXLDevice *d, int modenr)
.height = mode->y_res,
.stride = -mode->x_res * 4,
.format = SPICE_SURFACE_FMT_32_xRGB,
+ .flags = loadvm ? QXL_SURF_FLAG_KEEP_DATA : 0,
.mouse_mode = true,
- .mem = devmem,
+ .mem = devmem + d->shadow_rom.draw_area_offset,
};
dprint(d, 1, "%s: mode %d [ %d x %d @ %d bpp devmem 0x%lx ]\n", __FUNCTION__,
@@ -921,7 +934,7 @@ static void ioport_write(void *opaque, uint32_t addr, uint32_t val)
break;
case QXL_IO_SET_MODE:
dprint(d, 1, "QXL_SET_MODE %d\n", val);
- qxl_set_mode(d, val);
+ qxl_set_mode(d, val, 0);
break;
case QXL_IO_LOG:
if (d->guestdebug) {
@@ -1328,7 +1341,7 @@ static int qxl_post_load(void *opaque, int version)
d->modes = (QXLModes*)((uint8_t*)d->rom + d->rom->modes_offset);
- dprint(d, 1, "%s: restore more\n", __FUNCTION__);
+ dprint(d, 1, "%s: restore mode\n", __FUNCTION__);
newmode = d->mode;
d->mode = QXL_MODE_UNDEFINED;
switch (newmode) {
@@ -1366,7 +1379,7 @@ static int qxl_post_load(void *opaque, int version)
break;
case QXL_MODE_COMPAT:
- qxl_set_mode(d, d->shadow_rom.mode);
+ qxl_set_mode(d, d->shadow_rom.mode, 1);
break;
}
dprint(d, 1, "%s: done\n", __FUNCTION__);
commit ca416e2dfeb507d165340c12ab6e3ca134089613
Author: Gerd Hoffmann <kraxel at redhat.com>
Date: Tue Sep 7 11:19:04 2010 +0200
qxl: set QXL_COMMAND_FLAG_COMPAT_16BPP flag
diff --git a/hw/qxl.c b/hw/qxl.c
index 63a96e8..f6e2107 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -865,6 +865,9 @@ static void qxl_set_mode(PCIQXLDevice *d, int modenr)
d->mode = QXL_MODE_COMPAT;
d->cmdflags = QXL_COMMAND_FLAG_COMPAT;
+ if (mode->bits == 16) {
+ d->cmdflags |= QXL_COMMAND_FLAG_COMPAT_16BPP;
+ }
d->shadow_rom.mode = cpu_to_le32(modenr);
d->rom->mode = cpu_to_le32(modenr);
qxl_rom_set_dirty(d);
More information about the Spice-commits
mailing list