[Spice-devel] [PATCH 3/3] qxl-virtio: introducing changes to support virtio based transport
Erlon Cruz
erlon.cruz at br.flextronics.com
Fri Aug 24 12:11:00 PDT 2012
Signed-off-by: Erlon R. Cruz <erlon.cruz at fit-tecnologia.org.br>
Signed-off-by: Fabiano Fidêncio <fabiano.fidencio at fit-tecnologia.org.br>
Signed-off-by: Rafael F. Santos <fonsecasantos.rafael at gmail.com>
---
examples/Makefile.am | 6 +-
examples/virtioqxl.xorg.conf.example | 24 +++
src/Makefile.am | 11 +-
src/qxl.h | 196 +++++++++++++++++++++++-
src/qxl_driver.c | 275 ++++++++++++++++++++++++++--------
src/qxl_logger.c | 8 +
src/qxl_ring.c | 169 ++++++++++++++++++++-
src/qxl_surface.c | 94 ++++--------
8 files changed, 637 insertions(+), 146 deletions(-)
create mode 100644 examples/virtioqxl.xorg.conf.example
diff --git a/examples/Makefile.am b/examples/Makefile.am
index 75e61ea..251f6f1 100644
--- a/examples/Makefile.am
+++ b/examples/Makefile.am
@@ -19,6 +19,8 @@
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
if BUILD_XSPICE
-doc_DATA = spiceqxl.xorg.conf.example
+doc_DATA = spiceqxl.xorg.conf.example \
+ virtioqxl.xorg.conf.example
endif
-EXTRA_DIST = spiceqxl.xorg.conf.example
+EXTRA_DIST = spiceqxl.xorg.conf.example \
+ virtioqxl.xorg.conf.example
diff --git a/examples/virtioqxl.xorg.conf.example b/examples/virtioqxl.xorg.conf.example
new file mode 100644
index 0000000..bcb9b9d
--- /dev/null
+++ b/examples/virtioqxl.xorg.conf.example
@@ -0,0 +1,24 @@
+Section "Device"
+ Identifier "QXL_device"
+ Driver "virtioqxl"
+ Option "virtiodev" "/dev/virtioqxl0"
+EndSection
+
+Section "InputDevice"
+ Identifier "Mouse"
+ Driver "mouse"
+ Option "Protocol" "PS/2"
+ Option "Device" "/dev/input/mice"
+EndSection
+
+Section "Monitor"
+ Identifier "Configured Monitor"
+EndSection
+
+Section "Screen"
+ Identifier "Screen"
+ Monitor "Configured Monitor"
+ Device "QXL_device"
+ DefaultDepth 24
+EndSection
+
diff --git a/src/Makefile.am b/src/Makefile.am
index 3ffa3ce..09d89ad 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -31,6 +31,7 @@ AM_CFLAGS = $(SPICE_PROTOCOL_CFLAGS) $(XORG_CFLAGS) $(PCIACCESS_CFLAGS) $(CWARNF
if ENABLE_DEBUG
DEBUGFLAGS = -DENABLE_DEBUG -O0 -g
+DEBUG_FILES = qxl_logger.c
endif
if BUILD_DUMP_COMMANDS
@@ -57,7 +58,7 @@ qxl_drv_la_SOURCES = \
murmurhash3.h \
qxl_cursor.c \
compat-api.h \
- qxl_logger.c
+ $(DEBUG_FILES)
endif
if BUILD_VIRTIO_QXL
@@ -80,7 +81,7 @@ virtioqxl_drv_la_SOURCES = \
murmurhash3.c \
murmurhash3.h \
qxl_cursor.c \
- qxl_logger.c
+ $(DEBUG_FILES)
endif
if BUILD_XSPICE
@@ -103,7 +104,7 @@ spiceqxl_drv_la_SOURCES = \
spiceqxl_driver.c \
spiceqxl_driver.h \
spiceqxl_main_loop.c \
- spiceqxl_main_loop.h \
+ spiceqxl_main_loop.h \
spiceqxl_display.c \
spiceqxl_display.h \
spiceqxl_inputs.c \
@@ -118,5 +119,5 @@ spiceqxl_drv_la_SOURCES = \
murmurhash3.c \
murmurhash3.h \
qxl_cursor.c \
- qxl_logger.c
-endif
+ $(DEBUG_FILES)
+endif
\ No newline at end of file
diff --git a/src/qxl.h b/src/qxl.h
index 7d90dfc..83eea99 100644
--- a/src/qxl.h
+++ b/src/qxl.h
@@ -30,6 +30,21 @@
#include <spice.h>
#endif
+#ifdef VIRTIO_QXL
+#include <linux/virtio_bridge.h>
+#include <sys/ioctl.h>
+#include <unistd.h>
+#include <endian.h>
+
+#ifdef ENABLE_DEBUG
+#define DEBUG_RINGS 0
+#define DEBUG_CURSOR_RING 0
+#define DEBUG_COMMAND_RING 0
+#define DEBUG_RELEASE_RING 0
+#define DEBUG_RAM_UPDATES 0
+#endif
+#endif // VIRTIO_QXL
+
#include "compiler.h"
#include "xf86.h"
#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 6
@@ -53,7 +68,10 @@
#include "compat-api.h"
#define hidden _X_HIDDEN
-#ifdef XSPICE
+#ifdef VIRTIO_QXL
+#define QXL_NAME "virtioqxl"
+#define QXL_DRIVER_NAME "virtioqxl"
+#elif defined XSPICE
#define QXL_NAME "spiceqxl"
#define QXL_DRIVER_NAME "spiceqxl"
#else
@@ -92,6 +110,47 @@ typedef struct
typedef struct qxl_surface_t qxl_surface_t;
+struct qxl_surface_t
+{
+ surface_cache_t *cache;
+
+ uint32_t id;
+
+ pixman_image_t * dev_image;
+ pixman_image_t * host_image;
+
+ uxa_access_t access_type;
+ RegionRec access_region;
+
+ void * address;
+ void * end;
+
+ qxl_surface_t * next;
+ qxl_surface_t * prev; /* Only used in the 'live'
+ * chain in the surface cache
+ */
+
+ int in_use;
+ int bpp; /* bpp of the pixmap */
+ int ref_count;
+
+ PixmapPtr pixmap;
+
+ struct evacuated_surface_t *evacuated;
+
+ union
+ {
+ qxl_surface_t *copy_src;
+ Pixel solid_pixel;
+ } u;
+};
+
+typedef enum {
+ CURSOR_RING,
+ COMMAND_RING,
+ RELEASE_RING
+} ring_type;
+
/*
* Config Options
*/
@@ -172,7 +231,7 @@ struct _qxl_screen_t
EntityInfoPtr entity;
-#ifndef XSPICE
+#if !defined XSPICE && !defined VIRTIO_QXL
void * io_pages;
void * io_pages_physical;
@@ -220,6 +279,13 @@ struct _qxl_screen_t
int enable_fallback_cache;
int enable_surfaces;
+#ifdef VIRTIO_QXL
+ int virtiofd;
+ struct virtioqxl_config virtio_config;
+ void *vmem_start;
+ char *device_name;
+#endif
+
#ifdef XSPICE
/* XSpice specific */
struct QXLRom shadow_rom; /* Parameter RAM */
@@ -248,6 +314,54 @@ struct _qxl_screen_t
#endif /* XSPICE */
};
+#ifdef VIRTIO_QXL
+static inline uint64_t physical_address(qxl_screen_t *qxl,
+ void *virtual,
+ uint8_t slot_id){
+
+ char *ram;
+ uint64_t offset;
+ int maplen;
+
+ ram = (char *)qxl->ram;
+ maplen = qxl->virtio_config.ramsize + qxl->virtio_config.vramsize +
+ qxl->virtio_config.romsize;
+ offset = (char *)virtual - ram;
+
+ if (offset >= 0 && offset < maplen) {
+ return offset;
+ }
+
+ // Die
+ fprintf(stderr, "GUEST (%s): Memory %p (%ld) out of bounds [%p - %p]\n",
+ __func__, virtual, (char *)virtual - ram, ram, ram + maplen);
+ exit(1);
+}
+
+static inline void * virtual_address (qxl_screen_t *qxl,
+ void *physical,
+ uint8_t slot_id){
+
+ char *ram;
+ uint64_t offset;
+ void *local;
+ int memlen = qxl->virtio_config.ramsize + qxl->virtio_config.vramsize +
+ qxl->virtio_config.romsize;
+
+ ram = (char *)qxl->ram;
+ offset = (uint64_t)physical;
+
+ if (offset >= 0 && offset < memlen) {
+ local = (void *)(ram + offset);
+ } else {
+ fprintf(stderr, "GUEST (%s): Memory %p (%ld) out of bounds [%p - %p]\n",
+ __func__, (uint64_t)physical + ram, offset, ram, ram + memlen);
+ exit(1);
+ }
+
+ return local;
+}
+#else
static inline uint64_t
physical_address (qxl_screen_t *qxl, void *virtual, uint8_t slot_id)
{
@@ -267,6 +381,7 @@ virtual_address (qxl_screen_t *qxl, void *physical, uint8_t slot_id)
return (void *)virt;
}
+#endif // VIRTIO_QXL
static inline void *
u64_to_pointer (uint64_t u)
@@ -296,7 +411,8 @@ struct qxl_ring * qxl_ring_create (struct qxl_ring_header *header,
int element_size,
int n_elements,
int prod_notify,
- qxl_screen_t *qxl);
+ qxl_screen_t *qxl,
+ int ring_type);
void qxl_ring_push (struct qxl_ring *ring,
const void *element);
Bool qxl_ring_pop (struct qxl_ring *ring,
@@ -387,7 +503,7 @@ static inline struct QXLRam *
get_ram_header (qxl_screen_t *qxl)
{
return (struct QXLRam *)
- ((uint8_t *)qxl->ram + qxl->rom->ram_header_offset);
+ ((uint8_t *)qxl->ram + le32toh(qxl->rom->ram_header_offset));
}
/*
@@ -430,13 +546,13 @@ void qxl_mem_unverifiable(struct qxl_mem *mem);
static inline void qxl_mem_unverifiable(struct qxl_mem *mem) {}
#endif
-#ifdef DUMP_COMMANDS
+#ifdef ENABLE_DEBUG
void qxl_log_command(qxl_screen_t *qxl, QXLCommand *cmd, char *direction);
#endif
/*
* I/O port commands
*/
-void qxl_update_area(qxl_screen_t *qxl);
+void qxl_update_area(qxl_screen_t *qxl,qxl_surface_t *surface);
void qxl_io_memslot_add(qxl_screen_t *qxl, uint8_t id);
void qxl_io_create_primary(qxl_screen_t *qxl);
void qxl_io_destroy_primary(qxl_screen_t *qxl);
@@ -447,6 +563,12 @@ void qxl_io_destroy_all_surfaces (qxl_screen_t *qxl);
#ifdef XSPICE
/* device to spice-server, now xspice to spice-server */
void ioport_write(qxl_screen_t *qxl, uint32_t io_port, uint32_t val);
+#elif defined VIRTIO_QXL
+static inline void ioport_write(qxl_screen_t *qxl, int port, int val)
+{
+ int cmd = _IOW(QXLMAGIC, port, unsigned int);
+ ioctl(qxl->virtiofd, cmd, val);
+}
#else
static inline void ioport_write(qxl_screen_t *qxl, int port, int val)
{
@@ -454,6 +576,68 @@ static inline void ioport_write(qxl_screen_t *qxl, int port, int val)
}
#endif
+#ifdef ENABLE_DEBUG
+void qxl_log_command(qxl_screen_t *qxl, QXLCommand *cmd, char *direction);
+#endif
+
+#ifdef VIRTIO_QXL
+/* Write guest memory on host*/
+static inline void virtioqxl_push_ram(qxl_screen_t *qxl, void *ptr, int len)
+{
+ char *start, *end;
+ struct qxl_ram_area ram_area;
+ int memlen = qxl->virtio_config.ramsize + qxl->virtio_config.vramsize +
+ qxl->virtio_config.romsize;
+
+ start = (char *)ptr;
+ end = (char *)ptr + len;
+
+ if (start < (char *)qxl->ram ||
+ end > ((char *)qxl->ram + memlen)) {
+ fprintf(stderr,"%s: Error pushing memory [%p - %p] out of bounds "
+ "[%p - %p]\n", __func__, start, end, qxl->ram,
+ (char *)qxl->ram + memlen);
+ return;
+ }
+
+ ram_area.offset = start - (char *)qxl->ram;
+ ram_area.len = len;
+
+#ifdef ENABLE_DEBUG
+ fprintf(stderr,"%s: pushing area[%d->%d]. %d bytes\n",
+ __func__, ram_area.offset, ram_area.offset + ram_area.len,
+ ram_area.len);
+#endif
+
+ write(qxl->virtiofd,ptr,len);
+}
+
+/* Read from memory on host*/
+static inline void virtioqxl_pull_ram(qxl_screen_t *qxl, void *ptr, int len)
+{
+ struct qxl_ram_area ram_area;
+ int mem_size = qxl->virtio_config.ramsize + qxl->virtio_config.vramsize +
+ qxl->virtio_config.romsize;
+
+ if ((uint8_t *)ptr < (uint8_t *)qxl->ram ||
+ (uint8_t *)ptr+len > ((uint8_t *)qxl->ram + mem_size)) {
+ fprintf(stderr,"%s: Error pulling memory out of bounds\n",__func__);
+ return;
+ }
+
+ ram_area.offset = (uint8_t *)ptr - (uint8_t *)qxl->ram;
+ ram_area.len = len;
+
+#ifdef ENABLE_DEBUG
+ fprintf(stderr,"%s: pulling area[%d->%d]. %d bytes\n",
+ __func__, ram_area.offset, ram_area.offset + ram_area.len,
+ ram_area.len);
+#endif
+
+ read(qxl->virtiofd,ptr,len);
+}
+#endif // VIRTIO_QXL
+
#ifdef XSPICE
#define MEMSLOT_GROUP 0
diff --git a/src/qxl_driver.c b/src/qxl_driver.c
index e4c477a..5474850 100644
--- a/src/qxl_driver.c
+++ b/src/qxl_driver.c
@@ -46,6 +46,14 @@
#include "assert.h"
#include "qxl_option_helpers.h"
+#ifdef VIRTIO_QXL
+#include <linux/virtio_bridge.h>
+#include "spiceqxl_driver.h"
+#define VIRTIO_DEV "/dev/virtioqxl0"
+#include <sys/stat.h>
+#include <fcntl.h>
+#endif
+
#ifdef XSPICE
#include "spiceqxl_driver.h"
#include "spiceqxl_main_loop.h"
@@ -126,7 +134,7 @@ qxl_available_options (int chipid, int busid)
return DefaultOptions;
}
-#ifndef XSPICE
+#if (!defined XSPICE && !defined VIRTIO_QXL)
static void qxl_wait_for_io_command(qxl_screen_t *qxl)
{
struct QXLRam *ram_header = (void *)(
@@ -139,9 +147,16 @@ static void qxl_wait_for_io_command(qxl_screen_t *qxl)
}
#endif
-void qxl_update_area(qxl_screen_t *qxl)
+void qxl_update_area(qxl_screen_t *qxl, qxl_surface_t *surface)
{
-#ifndef XSPICE
+
+#ifdef VIRTIO_QXL
+ QXLRam *ram_header = get_ram_header(qxl);
+ virtioqxl_push_ram(qxl, &ram_header->update_area, sizeof(QXLRect));
+ virtioqxl_push_ram(qxl, &ram_header->update_surface, sizeof(int));
+#endif
+
+#if !defined XSPICE && !defined VIRTIO_QXL
if (qxl->pci->revision >= 3) {
ioport_write(qxl, QXL_IO_UPDATE_AREA_ASYNC, 0);
qxl_wait_for_io_command(qxl);
@@ -151,11 +166,20 @@ void qxl_update_area(qxl_screen_t *qxl)
#else
ioport_write(qxl, QXL_IO_UPDATE_AREA, 0);
#endif
+
+#ifdef VIRTIO_QXL
+ if (!surface || !surface->id) { //Primary
+ virtioqxl_pull_ram(qxl, qxl->surface0_area, qxl->surface0_size);
+ } else {
+ virtioqxl_pull_ram(qxl, surface->address,
+ (intptr_t)surface->end - (intptr_t)surface->address);
+ }
+#endif
}
void qxl_io_memslot_add(qxl_screen_t *qxl, uint8_t id)
{
-#ifndef XSPICE
+#if !defined XSPICE && !defined VIRTIO_QXL
if (qxl->pci->revision >= 3) {
ioport_write(qxl, QXL_IO_MEMSLOT_ADD_ASYNC, id);
qxl_wait_for_io_command(qxl);
@@ -169,7 +193,7 @@ void qxl_io_memslot_add(qxl_screen_t *qxl, uint8_t id)
void qxl_io_create_primary(qxl_screen_t *qxl)
{
-#ifndef XSPICE
+#if !defined XSPICE && !defined VIRTIO_QXL
if (qxl->pci->revision >= 3) {
ioport_write(qxl, QXL_IO_CREATE_PRIMARY_ASYNC, 0);
qxl_wait_for_io_command(qxl);
@@ -184,7 +208,7 @@ void qxl_io_create_primary(qxl_screen_t *qxl)
void qxl_io_destroy_primary(qxl_screen_t *qxl)
{
-#ifndef XSPICE
+#if (!defined XSPICE && !defined VIRTIO_QXL)
if (qxl->pci->revision >= 3)
{
ioport_write(qxl, QXL_IO_DESTROY_PRIMARY_ASYNC, 0);
@@ -206,7 +230,7 @@ void qxl_io_notify_oom(qxl_screen_t *qxl)
void qxl_io_flush_surfaces(qxl_screen_t *qxl)
{
-#ifndef XSPICE
+#if (!defined XSPICE && !defined VIRTIO_QXL)
ioport_write(qxl, QXL_IO_FLUSH_SURFACES_ASYNC, 0);
qxl_wait_for_io_command(qxl);
#else
@@ -273,9 +297,14 @@ qxl_garbage_collect (qxl_screen_t *qxl)
qxl_surface_recycle (qxl->surface_cache, surface_cmd->surface_id);
qxl_surface_cache_sanity_check (qxl->surface_cache);
}
-
- id = info->next;
-
+
+#ifdef VIRTIO_QXL
+ virtioqxl_pull_ram(qxl,&info->next,sizeof(info->next));
+ id = info->next;
+#else
+ id = info->next;
+#endif
+
qxl_free (qxl->mem, info);
++i;
@@ -358,7 +387,99 @@ qxl_blank_screen(ScreenPtr pScreen, int mode)
return TRUE;
}
-#ifdef XSPICE
+#ifdef VIRTIO_QXL
+
+#undef SPICE_RING_PROD_ITEM
+#define SPICE_RING_PROD_ITEM(r, ret) { \
+ typeof(r) start = r; \
+ typeof(r) end = r + 1; \
+ uint32_t prod = (r)->prod & SPICE_RING_INDEX_MASK(r); \
+ typeof(&(r)->items[prod]) m_item = &(r)->items[prod]; \
+ if (!((uint8_t *)m_item >= (uint8_t *)(start) && (uint8_t *)(m_item + 1) <= (uint8_t *)(end))) { \
+ abort(); \
+ } \
+ ret = &m_item->el; \
+}
+
+#undef SPICE_RING_CONS_ITEM
+#define SPICE_RING_CONS_ITEM(r, ret) { \
+ typeof(r) start = r; \
+ typeof(r) end = r + 1; \
+ uint32_t cons = (r)->cons & SPICE_RING_INDEX_MASK(r); \
+ typeof(&(r)->items[cons]) m_item = &(r)->items[cons]; \
+ if (!((uint8_t *)m_item >= (uint8_t *)(start) && (uint8_t *)(m_item + 1) <= (uint8_t *)(end))) { \
+ abort(); \
+ } \
+ ret = &m_item->el; \
+}
+
+static void virtio_init_qxl_ram(qxl_screen_t *qxl)
+{
+ QXLRam *ram = get_ram_header(qxl);
+ uint64_t *item;
+
+ ram->magic = htole32(QXL_RAM_MAGIC);
+ ram->int_pending = htole32(0);
+ ram->int_mask = htole32(0);
+ SPICE_RING_INIT(&ram->cmd_ring);
+ SPICE_RING_INIT(&ram->cursor_ring);
+ SPICE_RING_INIT(&ram->release_ring);
+ SPICE_RING_PROD_ITEM(&ram->release_ring, item);
+ *item = 0;
+}
+
+static void unmap_memory_helper(qxl_screen_t *qxl)
+{
+ free(qxl->ram);
+ close(qxl->virtiofd);
+}
+
+static void map_memory_helper(qxl_screen_t *qxl)
+{
+ void *vmem_start,*modes_start;
+ int memlen, num_modes;
+ struct QXLRom *rom;
+ QXLRam *ram_header;
+
+ CHECK_POINT();
+
+ qxl->virtiofd = open(qxl->device_name, O_RDWR | O_SYNC);
+
+ if (qxl->virtiofd < 0) {
+ ErrorF("Error opening virtio device. Check if "
+ " virtio-qxl-bridge is loaded\n");
+ return;
+ }
+
+ ioctl(qxl->virtiofd, QXL_IOCTL_QXL_IO_GETCFG, &qxl->virtio_config);
+
+ memlen = qxl->virtio_config.ramsize + qxl->virtio_config.vramsize +
+ qxl->virtio_config.romsize;
+
+ qxl->ram = vmem_start = qxl->ram_physical = malloc(memlen);
+ memset(qxl->ram,0x0,memlen);
+ ErrorF("%s: allocated %d bytes as video memory at %p\n",__func__, memlen,qxl->ram);
+ ioctl(qxl->virtiofd, QXL_IOCTL_QXL_IO_SET_RAMSTART, &qxl->ram);
+
+ qxl->vram = (uint8_t *)vmem_start + qxl->virtio_config.ramsize;
+ qxl->vram_size = qxl->virtio_config.vramsize;
+ qxl->vram_physical = qxl->vram;
+ qxl->rom = (void *)((uint8_t *)vmem_start + qxl->virtio_config.ramsize +
+ qxl->virtio_config.vramsize);
+
+ ram_header = get_ram_header(qxl);
+ rom = qxl->rom;
+ //Read the ROM contents from the device
+ //The 4 aditional bits brings the number of modes
+ read(qxl->virtiofd, qxl->rom,sizeof(*qxl->rom)+sizeof(int));
+ num_modes = le32toh(*(int *)((char *)qxl->rom+sizeof(*qxl->rom)));
+ modes_start = (char *)qxl->rom+sizeof(*qxl->rom)+sizeof(int);
+ read(qxl->virtiofd, modes_start,sizeof(QXLMode)*num_modes);
+
+ read(qxl->virtiofd, ram_header,sizeof(*ram_header));
+}
+
+#elif defined XSPICE
static void
unmap_memory_helper(qxl_screen_t *qxl)
{
@@ -441,7 +562,7 @@ map_memory_helper(qxl_screen_t *qxl)
qxl->io_base = qxl->pci->ioBase[3];
#endif
}
-#endif /* XSPICE */
+#endif /* VIRTIO_QXL */
static void
qxl_unmap_memory(qxl_screen_t *qxl)
@@ -477,30 +598,35 @@ qxl_mspace_print_func(void *user_data, const char *format, ...)
static Bool
qxl_map_memory(qxl_screen_t *qxl, int scrnIndex)
{
+
+#ifdef VIRTIO_QXL
+ xf86DrvMsg(scrnIndex, X_INFO, "Opening device %s.\n", qxl->device_name);
+#endif
+
map_memory_helper(qxl);
if (!qxl->ram || !qxl->vram || !qxl->rom)
return FALSE;
xf86DrvMsg(scrnIndex, X_INFO, "framebuffer at %p (%d KB)\n",
- qxl->ram, qxl->rom->surface0_area_size / 1024);
+ qxl->ram, le32toh(qxl->rom->surface0_area_size) / 1024);
xf86DrvMsg(scrnIndex, X_INFO, "command ram at %p (%d KB)\n",
- (void *)((unsigned long)qxl->ram + qxl->rom->surface0_area_size),
- (qxl->rom->num_pages * getpagesize() - qxl->rom->surface0_area_size)/1024);
+ (void *)((unsigned long)qxl->ram + le32toh(qxl->rom->surface0_area_size)),
+ (le32toh(qxl->rom->num_pages) * getpagesize() - le32toh(qxl->rom->surface0_area_size))/1024);
xf86DrvMsg(scrnIndex, X_INFO, "vram at %p (%ld KB)\n",
qxl->vram, qxl->vram_size / 1024);
xf86DrvMsg(scrnIndex, X_INFO, "rom at %p\n", qxl->rom);
- qxl->num_modes = *(uint32_t *)((uint8_t *)qxl->rom + qxl->rom->modes_offset);
- qxl->modes = (struct QXLMode *)(((uint8_t *)qxl->rom) + qxl->rom->modes_offset + 4);
+ qxl->num_modes = le32toh(*(uint32_t *)((uint8_t *)qxl->rom + le32toh(qxl->rom->modes_offset)));
+ qxl->modes = (struct QXLMode *)(((uint8_t *)qxl->rom) + le32toh(qxl->rom->modes_offset) + 4);
qxl->surface0_area = qxl->ram;
- qxl->surface0_size = qxl->rom->surface0_area_size;
+ qxl->surface0_size = le32toh(qxl->rom->surface0_area_size);
qxl->mem = qxl_mem_create ((void *)((unsigned long)qxl->ram + qxl->surface0_size),
- qxl->rom->num_pages * getpagesize() - qxl->surface0_size);
+ le32toh(qxl->rom->num_pages) * getpagesize() - qxl->surface0_size);
qxl->surf_mem = qxl_mem_create ((void *)((unsigned long)qxl->vram), qxl->vram_size);
mspace_set_abort_func(qxl_mspace_abort_func);
@@ -509,7 +635,7 @@ qxl_map_memory(qxl_screen_t *qxl, int scrnIndex)
return TRUE;
}
-#ifdef XSPICE
+#if defined XSPICE || defined VIRTIO_QXL
static void
qxl_save_state(ScrnInfoPtr pScrn)
{
@@ -589,7 +715,10 @@ qxl_reset_and_create_mem_slots (qxl_screen_t *qxl)
qxl->mem_slots = xnfalloc (qxl->n_mem_slots * sizeof (qxl_memslot_t));
-#ifdef XSPICE
+#ifdef VIRTIO_QXL
+ virtio_init_qxl_ram(qxl);
+ qxl->main_mem_slot = qxl->vram_mem_slot = setup_slot(qxl, 0, 0, ~0, 0, ~0);
+#elif defined XSPICE
qxl->main_mem_slot = qxl->vram_mem_slot = setup_slot(qxl, 0, 0, ~0, 0, ~0);
#else /* QXL */
qxl->main_mem_slot = setup_slot(qxl, 0,
@@ -616,7 +745,7 @@ qxl_mark_mem_unverifiable(qxl_screen_t *qxl)
void
qxl_io_destroy_all_surfaces (qxl_screen_t *qxl)
{
-#ifndef XSPICE
+#if (!defined XSPICE && !defined VIRTIO_QXL)
if (qxl->pci->revision >= 3)
{
ioport_write(qxl, QXL_IO_DESTROY_ALL_SURFACES_ASYNC, 0);
@@ -648,7 +777,7 @@ qxl_close_screen(CLOSE_SCREEN_ARGS_DECL)
result = pScreen->CloseScreen(CLOSE_SCREEN_ARGS);
-#ifndef XSPICE
+#if (!defined XSPICE && !defined VIRTIO_QXL)
if (!xf86IsPrimaryPci (qxl->pci) && qxl->primary)
qxl_reset_and_create_mem_slots (qxl);
#endif
@@ -679,7 +808,7 @@ set_screen_pixmap_header (ScreenPtr pScreen)
pScreen->ModifyPixmapHeader(
pPixmap,
- qxl->current_mode->x_res, qxl->current_mode->y_res,
+ le32toh(qxl->current_mode->x_res), le32toh(qxl->current_mode->y_res),
-1, -1,
qxl->pScrn->displayWidth * qxl->bytes_per_pixel,
NULL);
@@ -1170,20 +1299,20 @@ qxl_screen_init(SCREEN_INIT_ARGS_DECL)
qxl_reset_and_create_mem_slots (qxl);
ErrorF ("done reset\n");
-#ifndef XSPICE
+#if (!defined XSPICE && !defined VIRTIO_QXL)
qxl->io_pages = (void *)((unsigned long)qxl->ram);
qxl->io_pages_physical = (void *)((unsigned long)qxl->ram_physical);
#endif
qxl->command_ring = qxl_ring_create ((struct qxl_ring_header *)&(ram_header->cmd_ring),
sizeof (struct QXLCommand),
- QXL_COMMAND_RING_SIZE, QXL_IO_NOTIFY_CMD, qxl);
+ QXL_COMMAND_RING_SIZE, QXL_IO_NOTIFY_CMD, qxl,COMMAND_RING);
qxl->cursor_ring = qxl_ring_create ((struct qxl_ring_header *)&(ram_header->cursor_ring),
sizeof (struct QXLCommand),
- QXL_CURSOR_RING_SIZE, QXL_IO_NOTIFY_CURSOR, qxl);
+ QXL_CURSOR_RING_SIZE, QXL_IO_NOTIFY_CURSOR, qxl,CURSOR_RING);
qxl->release_ring = qxl_ring_create ((struct qxl_ring_header *)&(ram_header->release_ring),
sizeof (uint64_t),
- QXL_RELEASE_RING_SIZE, 0, qxl);
+ QXL_RELEASE_RING_SIZE, 0, qxl,RELEASE_RING);
qxl->surface_cache = qxl_surface_cache_create (qxl);
@@ -1325,12 +1454,12 @@ print_modes (qxl_screen_t *qxl, int scrnIndex)
xf86DrvMsg (scrnIndex, X_INFO,
"%d: %dx%d, %d bits, stride %d, %dmm x %dmm, orientation %d\n",
- m->id, m->x_res, m->y_res, m->bits, m->stride, m->x_mili,
- m->y_mili, m->orientation);
+ le32toh(m->id), le32toh(m->x_res), le32toh(m->y_res), le32toh(m->bits), le32toh(m->stride), le32toh(m->x_mili),
+ le32toh(m->y_mili), le32toh(m->orientation));
}
}
-#ifndef XSPICE
+#if (!defined XSPICE && !defined VIRTIO_QXL)
static Bool
qxl_check_device(ScrnInfoPtr pScrn, qxl_screen_t *qxl)
{
@@ -1381,18 +1510,18 @@ qxl_find_native_mode(ScrnInfoPtr pScrn, DisplayModePtr p)
for (i = 0; i < qxl->num_modes; i++)
{
struct QXLMode *m = qxl->modes + i;
-
- if (m->x_res == p->HDisplay &&
- m->y_res == p->VDisplay &&
- m->bits == pScrn->bitsPerPixel)
+
+ if (le32toh(m->x_res) == p->HDisplay &&
+ le32toh(m->y_res) == p->VDisplay &&
+ le32toh(m->bits) == pScrn->bitsPerPixel)
{
- if (m->bits == 16)
+ if (le32toh(m->bits) == 16)
{
/* What QXL calls 16 bit is actually x1r5g5b515 */
if (pScrn->depth == 15)
return i;
}
- else if (m->bits == 32)
+ else if (le32toh(m->bits) == 32)
{
/* What QXL calls 32 bit is actually x8r8g8b8 */
if (pScrn->depth == 24)
@@ -1499,7 +1628,7 @@ qxl_pre_init(ScrnInfoPtr pScrn, int flags)
qxl->entity = xf86GetEntityInfo(pScrn->entityList[0]);
-#ifndef XSPICE
+#if (!defined XSPICE && !defined VIRTIO_QXL)
qxl->pci = xf86GetPciInfoForEntity(qxl->entity->index);
#ifndef XSERVER_LIBPCIACCESS
qxl->pci_tag = pciTag(qxl->pci->bus, qxl->pci->device, qxl->pci->func);
@@ -1529,19 +1658,28 @@ qxl_pre_init(ScrnInfoPtr pScrn, int flags)
qxl->enable_image_cache? "Enabled" : "Disabled");
xf86DrvMsg(scrnIndex, X_INFO, "Fallback Cache: %s\n",
qxl->enable_fallback_cache? "Enabled" : "Disabled");
-
+
+#ifdef VIRTIO_QXL
+ qxl->device_name = xf86FindOptionValue(pScrn->options,"virtiodev");
+
+ if (!qxl->device_name)
+ qxl->device_name = VIRTIO_DEV;
+
+ xf86DrvMsg(scrnIndex, X_INFO, "Using virtio device %s.\n", qxl->device_name);
+#endif
+
if (!qxl_map_memory(qxl, scrnIndex))
goto out;
-
-#ifndef XSPICE
+
+#if (!defined XSPICE && !defined VIRTIO_QXL)
if (!qxl_check_device(pScrn, qxl))
goto out;
-#else
+#elif defined XSPICE
xspice_init_qxl_ram(qxl); /* initialize the rings */
#endif
- pScrn->videoRam = (qxl->rom->num_pages * 4096) / 1024;
+ pScrn->videoRam = (le32toh(qxl->rom->num_pages) * 4096) / 1024;
xf86DrvMsg(scrnIndex, X_INFO, "%d KB of video RAM\n", pScrn->videoRam);
- xf86DrvMsg(scrnIndex, X_INFO, "%d surfaces\n", qxl->rom->n_surfaces);
+ xf86DrvMsg(scrnIndex, X_INFO, "%d surfaces\n", le32toh(qxl->rom->n_surfaces));
/* ddc stuff here */
@@ -1568,13 +1706,13 @@ qxl_pre_init(ScrnInfoPtr pScrn, int flags)
/* Add any modes not in xorg's default mode list */
for (i = 0; i < qxl->num_modes; i++)
- if (qxl->modes[i].orientation == 0) {
- qxl_add_mode(pScrn, qxl->modes[i].x_res, qxl->modes[i].y_res,
+ if (le32toh(qxl->modes[i].orientation) == 0) {
+ qxl_add_mode(pScrn, le32toh(qxl->modes[i].x_res), le32toh(qxl->modes[i].y_res),
M_T_DRIVER);
- if (qxl->modes[i].x_res > max_x)
- max_x = qxl->modes[i].x_res;
- if (qxl->modes[i].y_res > max_y)
- max_y = qxl->modes[i].y_res;
+ if (le32toh(qxl->modes[i].x_res) > max_x)
+ max_x = le32toh(qxl->modes[i].x_res);
+ if (le32toh(qxl->modes[i].y_res) > max_y)
+ max_y = le32toh(qxl->modes[i].y_res);
}
if (pScrn->display->virtualX == 0 && pScrn->display->virtualY == 0) {
@@ -1582,8 +1720,8 @@ qxl_pre_init(ScrnInfoPtr pScrn, int flags)
to a virtual size which will not fit into the framebuffer when this
happens we prefer max width and make height as large as possible */
if (max_x * max_y * (pScrn->bitsPerPixel / 8) >
- qxl->rom->surface0_area_size)
- pScrn->display->virtualY = qxl->rom->surface0_area_size /
+ le32toh(qxl->rom->surface0_area_size))
+ pScrn->display->virtualY = le32toh(qxl->rom->surface0_area_size) /
(max_x * (pScrn->bitsPerPixel / 8));
else
pScrn->display->virtualY = max_y;
@@ -1618,7 +1756,7 @@ qxl_pre_init(ScrnInfoPtr pScrn, int flags)
xf86SetDpi(pScrn, 0, 0);
if (!xf86LoadSubModule(pScrn, "fb")
-#ifndef XSPICE
+#if (!defined XSPICE && !defined VIRTIO_QXL)
|| !xf86LoadSubModule(pScrn, "ramdac")
|| !xf86LoadSubModule(pScrn, "vgahw")
#endif
@@ -1629,7 +1767,7 @@ qxl_pre_init(ScrnInfoPtr pScrn, int flags)
print_modes (qxl, scrnIndex);
-#ifndef XSPICE
+#if (!defined XSPICE && !defined VIRTIO_QXL)
/* VGA hardware initialisation */
if (!vgaHWGetHWRec(pScrn))
return FALSE;
@@ -1656,7 +1794,7 @@ out:
return FALSE;
}
-#ifndef XSPICE
+#if (!defined XSPICE && !defined VIRTIO_QXL)
#ifdef XSERVER_LIBPCIACCESS
enum qxl_class
{
@@ -1695,7 +1833,7 @@ static PciChipsets qxlPciChips[] =
static void
qxl_identify(int flags)
{
-#ifndef XSPICE
+#if (!defined XSPICE && !defined VIRTIO_QXL)
xf86PrintChipsets("qxl", "Driver for QXL virtual graphics", qxlChips);
#endif
}
@@ -1713,7 +1851,7 @@ qxl_init_scrn(ScrnInfoPtr pScrn)
pScrn->LeaveVT = qxl_leave_vt;
}
-#ifdef XSPICE
+#if (defined VIRTIO_QXL || defined XSPICE)
static Bool
qxl_probe(struct _DriverRec *drv, int flags)
{
@@ -1738,11 +1876,6 @@ qxl_probe(struct _DriverRec *drv, int flags)
return TRUE;
}
-static Bool qxl_driver_func(ScrnInfoPtr screen_info_ptr, xorgDriverFuncOp xorg_driver_func_op, pointer hw_flags)
-{
- *(xorgHWFlags*)hw_flags = (xorgHWFlags)HW_SKIP_CONSOLE;
- return TRUE;
-}
#else /* normal, not XSPICE */
#ifndef XSERVER_LIBPCIACCESS
static Bool
@@ -1812,7 +1945,15 @@ qxl_pci_probe(DriverPtr drv, int entity, struct pci_device *dev, intptr_t match)
#define qxl_probe NULL
#endif
-#endif /* XSPICE */
+#endif /* VIRTIO_QXL || XSPICE */
+
+#ifdef XSPICE
+static Bool qxl_driver_func(ScrnInfoPtr screen_info_ptr, xorgDriverFuncOp xorg_driver_func_op, pointer hw_flags)
+{
+ *(xorgHWFlags*)hw_flags = (xorgHWFlags)HW_SKIP_CONSOLE;
+ return TRUE;
+}
+#endif
static DriverRec qxl_driver = {
0,
@@ -1822,7 +1963,11 @@ static DriverRec qxl_driver = {
qxl_available_options,
NULL,
0,
-#ifdef XSPICE
+#ifdef VIRTIO_QXL
+ NULL,
+ NULL,
+ NULL
+#elif defined XSPICE
qxl_driver_func,
NULL,
NULL
@@ -1870,6 +2015,8 @@ static XF86ModuleVersionInfo qxl_module_info = {
_X_EXPORT XF86ModuleData
#ifdef XSPICE
spiceqxlModuleData
+#elif VIRTIO_QXL
+virtioqxlModuleData
#else
qxlModuleData
#endif
diff --git a/src/qxl_logger.c b/src/qxl_logger.c
index 40025e4..98286b8 100644
--- a/src/qxl_logger.c
+++ b/src/qxl_logger.c
@@ -180,6 +180,7 @@ static void
qxl_log_cmd_surface(qxl_screen_t *qxl, QXLSurfaceCmd *cmd)
{
uint64_t offset;
+ void *data;
fprintf(stderr," %s id %d",
qxl_name(qxl_surface_cmd, cmd->type),
@@ -189,7 +190,14 @@ qxl_log_cmd_surface(qxl_screen_t *qxl, QXLSurfaceCmd *cmd)
return;
}
+#ifdef VIRTIO_QXL
offset = cmd->u.surface_create.data;
+#else
+ data = virtual_address(qxl, (void *)cmd->u.surface_create.data,
+ qxl->vram_mem_slot);
+ offset = virtual_address(qxl, data, qxl->vram_mem_slot);
+#endif
+
fprintf(stderr," size %dx%d stride %d format %s data @ %llu",
cmd->u.surface_create.width,
cmd->u.surface_create.height,
diff --git a/src/qxl_ring.c b/src/qxl_ring.c
index 5dd1f90..e503ae0 100644
--- a/src/qxl_ring.c
+++ b/src/qxl_ring.c
@@ -46,6 +46,7 @@ struct qxl_ring
int n_elements;
int io_port_prod_notify;
qxl_screen_t *qxl;
+ int type;
};
struct qxl_ring *
@@ -53,7 +54,7 @@ qxl_ring_create (struct qxl_ring_header *header,
int element_size,
int n_elements,
int io_port_prod_notify,
- qxl_screen_t *qxl)
+ qxl_screen_t *qxl, int ring_type)
{
struct qxl_ring *ring;
@@ -61,6 +62,7 @@ qxl_ring_create (struct qxl_ring_header *header,
if (!ring)
return NULL;
+ ring->type = ring_type;
ring->ring = (volatile struct ring *)header;
ring->element_size = element_size;
ring->n_elements = n_elements;
@@ -69,6 +71,132 @@ qxl_ring_create (struct qxl_ring_header *header,
return ring;
}
+#ifdef VIRTIO_QXL
+static void
+update_cursor_ring(qxl_screen_t *qxl) {
+ char *push1 = (char *)qxl->cursor_ring->ring;
+ char *pull = push1 + sizeof(uint32_t) * 3;
+ char *push2 = pull + sizeof(uint32_t);
+
+ virtioqxl_push_ram(qxl, (void *)push2,
+ sizeof(QXLCursorRing) - sizeof(uint32_t) * 4);
+ virtioqxl_push_ram(qxl, (void *)push1, sizeof(uint32_t) * 3);
+ virtioqxl_pull_ram(qxl, (void *)pull, sizeof(uint32_t));
+}
+
+static void
+update_command_ring(qxl_screen_t *qxl) {
+ char *push1 = (char *)qxl->command_ring->ring;
+ char *pull = push1 + sizeof(uint32_t) * 3;
+ char *push2 = pull + sizeof(uint32_t);
+
+ virtioqxl_push_ram(qxl, (void *)push2,
+ sizeof(QXLCommandRing) - sizeof(uint32_t) * 4);
+ virtioqxl_push_ram(qxl, (void *)push1, sizeof(uint32_t) * 3);
+ virtioqxl_pull_ram(qxl, (void *)pull, sizeof(uint32_t));
+}
+
+static void
+update_release_ring(qxl_screen_t *qxl) {
+ char *pull1 = (char *)qxl->release_ring->ring;
+ char *push = pull1 + sizeof(uint32_t) * 3;
+ char *pull2 = push + sizeof(uint32_t);
+
+ virtioqxl_pull_ram(qxl, (void *)pull2,
+ sizeof(QXLReleaseRing) - sizeof(uint32_t) * 4);
+ virtioqxl_pull_ram(qxl, (void *)pull1, sizeof(uint32_t) * 3);
+ virtioqxl_push_ram(qxl, (void *)push, sizeof(uint32_t));
+}
+#endif
+
+#ifdef VIRTIO_QXL
+static void
+qxl_ring_push_command(struct qxl_ring *ring, struct QXLCommand *cmd)
+{
+ qxl_screen_t *qxl = ring->qxl;
+
+ switch (cmd->type) {
+ case QXL_CMD_SURFACE:
+ {
+ int stride;
+ QXLSurface surf;
+ uint8_t *ptr;
+ QXLSurfaceCmd *c = virtual_address(qxl, (void *)cmd->data,
+ qxl->main_mem_slot);
+
+ virtioqxl_push_ram(qxl, (void *)c, sizeof(*c));
+
+ if (c->type == QXL_SURFACE_CMD_DESTROY) {
+ break;
+ }
+
+ surf = c->u.surface_create;
+ stride = abs(surf.stride);
+ ptr = virtual_address(qxl, (void *)surf.data, qxl->vram_mem_slot);
+ virtioqxl_push_ram(qxl, (void *)ptr,
+ surf.height * stride + stride);
+ break;
+ }
+ case QXL_CMD_DRAW:
+ {
+ QXLPHYSICAL addr;
+ QXLImage *image;
+ QXLDataChunk *chunk;
+ QXLDrawable *draw = virtual_address(qxl, (void *)cmd->data,
+ qxl->main_mem_slot);
+
+ virtioqxl_push_ram(qxl, (void *)draw, sizeof(*draw));
+
+ if (draw->type != QXL_DRAW_COPY) {
+ break;
+ }
+
+ image = virtual_address(qxl, (void *)draw->u.copy.src_bitmap,
+ qxl->main_mem_slot);
+ virtioqxl_push_ram(qxl, (void *)image, sizeof(*image));
+
+ if (image->descriptor.type == SPICE_IMAGE_TYPE_SURFACE) {
+ break;
+ }
+
+ if (image->bitmap.flags & QXL_BITMAP_DIRECT) {
+ uint8_t *ptr = virtual_address(qxl, (void *)image->bitmap.data,
+ qxl->main_mem_slot);
+ virtioqxl_push_ram(qxl, (void *)ptr,
+ image->descriptor.height * image->bitmap.stride);
+ break;
+ }
+ addr = image->bitmap.data;
+ while (addr) {
+ chunk = virtual_address(qxl, (void *)addr, qxl->main_mem_slot);
+ virtioqxl_push_ram(qxl, (void *)chunk,
+ sizeof(*chunk) + chunk->data_size);
+ addr = chunk->next_chunk;
+ }
+ break;
+ }
+ case QXL_CMD_CURSOR:
+ {
+ QXLCursor *cursor;
+ QXLCursorCmd *c = virtual_address(qxl, (void *)cmd->data,
+ qxl->main_mem_slot);
+
+ virtioqxl_push_ram(qxl, (void *)c, sizeof(*c));
+
+ if (c->type != QXL_CURSOR_SET) {
+ break;
+ }
+
+ cursor = virtual_address(qxl, (void *)c->u.set.shape,
+ qxl->main_mem_slot);
+ virtioqxl_push_ram(qxl, (void *)cursor,
+ sizeof(*cursor) + cursor->data_size);
+ break;
+ }
+ }
+}
+#endif // VIRTIO_QXL
+
void
qxl_ring_push (struct qxl_ring *ring,
const void *new_elt)
@@ -77,18 +205,40 @@ qxl_ring_push (struct qxl_ring *ring,
volatile uint8_t *elt;
int idx;
-#ifdef DUMP_COMMANDS
- struct QXLCommand *cmd = (QXLCommand *)new_elt;
+#if defined VIRTIO_QXL || defined ENABLE_DEBUG
+ struct QXLCommand *cmd = (QXLCommand *)new_elt;
+#endif
+
+#ifdef VIRTIO_QXL
+ struct QXLRam *ram = get_ram_header(ring->qxl);
+ if(ring->type == CURSOR_RING){
+ // When the guest stop sending cursor commands, the host side
+ // consumer(libspice thread) sleeps. This avoid a delay when starting
+ // to move the mouse again.
+ if(SPICE_RING_IS_EMPTY(&ram->cursor_ring)){
+ ioport_write(ring->qxl, QXL_IO_NOTIFY_CURSOR, 0);
+ }
+ }
+ qxl_ring_push_command(ring, cmd);
+#endif
+
+#ifdef ENABLE_DEBUG
qxl_log_command(ring->qxl, cmd, "");
#endif
while (header->prod - header->cons == header->num_items)
{
- header->notify_on_cons = header->cons + 1;
+#ifdef VIRTIO_QXL
+ ioport_write(ring->qxl, QXL_IO_NOTIFY_CURSOR, 0);
+ update_command_ring(ring->qxl);
+ update_cursor_ring(ring->qxl);
+ sched_yield();
+#endif
+ header->notify_on_cons = header->cons + 1;
#ifdef XSPICE
/* in gtkperf, circles, this is a major bottleneck. Can't be that good in a vm either
* Adding the yield reduces cpu usage, but doesn't improve throughput. */
- sched_yield();
+ sched_yield();
#endif
mem_barrier();
}
@@ -102,6 +252,11 @@ qxl_ring_push (struct qxl_ring *ring,
mem_barrier();
+#ifdef VIRTIO_QXL
+ update_command_ring(ring->qxl);
+ update_cursor_ring(ring->qxl);
+#endif
+
if (header->prod == header->notify_on_prod) {
ioport_write (ring->qxl, ring->io_port_prod_notify, 0);
}
@@ -115,6 +270,10 @@ qxl_ring_pop (struct qxl_ring *ring,
volatile uint8_t *ring_elt;
int idx;
+#ifdef VIRTIO_QXL
+ update_release_ring(ring->qxl);
+#endif
+
if (header->cons == header->prod)
return FALSE;
diff --git a/src/qxl_surface.c b/src/qxl_surface.c
index 113f09b..22823ba 100644
--- a/src/qxl_surface.c
+++ b/src/qxl_surface.c
@@ -57,41 +57,6 @@ static FILE* surface_log;
typedef struct evacuated_surface_t evacuated_surface_t;
-struct qxl_surface_t
-{
- surface_cache_t *cache;
-
- uint32_t id;
-
- pixman_image_t * dev_image;
- pixman_image_t * host_image;
-
- uxa_access_t access_type;
- RegionRec access_region;
-
- void * address;
- void * end;
-
- qxl_surface_t * next;
- qxl_surface_t * prev; /* Only used in the 'live'
- * chain in the surface cache
- */
-
- int in_use;
- int bpp; /* bpp of the pixmap */
- int ref_count;
-
- PixmapPtr pixmap;
-
- struct evacuated_surface_t *evacuated;
-
- union
- {
- qxl_surface_t *copy_src;
- Pixel solid_pixel;
- } u;
-};
-
struct evacuated_surface_t
{
pixman_image_t *image;
@@ -169,7 +134,7 @@ static void debug_surface_log(surface_cache_t *cache)
static Bool
surface_cache_init (surface_cache_t *cache, qxl_screen_t *qxl)
{
- int n_surfaces = qxl->rom->n_surfaces;
+ int n_surfaces = le32toh(qxl->rom->n_surfaces);
int i;
if (!cache->all_surfaces)
@@ -356,38 +321,40 @@ qxl_surface_cache_create_primary (surface_cache_t *cache,
qxl_surface_t *surface;
qxl_screen_t *qxl = cache->qxl;
- if (mode->bits == 16)
+ if (le32toh(mode->bits) == 16)
{
format = PIXMAN_x1r5g5b5;
}
- else if (mode->bits == 32)
+ else if (le32toh(mode->bits) == 32)
{
format = PIXMAN_x8r8g8b8;
}
else
{
- xf86DrvMsg (cache->qxl->pScrn->scrnIndex, X_ERROR,
- "Unknown bit depth %d\n", mode->bits);
+ xf86DrvMsg (cache->qxl->pScrn->scrnIndex, X_ERROR,
+ "Unknown bit depth %d\n", le32toh(mode->bits));
return NULL;
}
-
- create->width = mode->x_res;
- create->height = mode->y_res;
- create->stride = - mode->stride;
- create->format = mode->bits;
- create->position = 0; /* What is this? The Windows driver doesn't use it */
- create->flags = 0;
- create->type = QXL_SURF_TYPE_PRIMARY;
- create->mem = physical_address (cache->qxl, cache->qxl->ram, cache->qxl->main_mem_slot);
+
+ create->width = mode->x_res; //this will be sent to the host that spect LE values
+ create->height = mode->y_res; //Modes is in LE already. No need to convert
+ create->stride = htole32(-le32toh(mode->stride));
+ create->format = mode->bits;
+ create->position = 0; /* What is this? The Windows driver doesn't use it */
+ create->flags = 0;
+ create->type = htole32(QXL_SURF_TYPE_PRIMARY);
+ create->mem = htole64(physical_address(cache->qxl, cache->qxl->ram, cache->qxl->main_mem_slot));
+
+#ifdef VIRTIO_QXL
+ virtioqxl_push_ram(qxl, create, sizeof(*create));
+#endif
qxl_io_create_primary(qxl);
- dev_addr = (uint8_t *)qxl->ram + mode->stride * (mode->y_res - 1);
-
- dev_image = pixman_image_create_bits (format, mode->x_res, mode->y_res,
- (uint32_t *)dev_addr, -mode->stride);
-
- host_image = pixman_image_create_bits (format,
+ dev_addr = (uint8_t *)qxl->ram + le32toh(mode->stride) * (le32toh(mode->y_res) - 1);
+ dev_image = pixman_image_create_bits (format, le32toh(mode->x_res), le32toh(mode->y_res),
+ (uint32_t *)dev_addr, le32toh(-mode->stride));
+ host_image = pixman_image_create_bits (format,
qxl->virtual_x, qxl->virtual_y,
qxl->fb, qxl->stride);
@@ -396,7 +363,7 @@ qxl_surface_cache_create_primary (surface_cache_t *cache,
surface->dev_image = dev_image;
surface->host_image = host_image;
surface->cache = cache;
- surface->bpp = mode->bits;
+ surface->bpp = le32toh(mode->bits);
surface->next = NULL;
surface->prev = NULL;
surface->evacuated = NULL;
@@ -486,7 +453,7 @@ make_drawable (qxl_screen_t *qxl, int surface, uint8_t type,
if (rect)
drawable->bbox = *rect;
- drawable->mm_time = qxl->rom->mm_clock;
+ drawable->mm_time = le32toh(qxl->rom->mm_clock);
return drawable;
}
@@ -894,14 +861,13 @@ download_box (qxl_surface_t *surface, int x1, int y1, int x2, int y2)
{
struct QXLRam *ram_header = get_ram_header (surface->cache->qxl);
- ram_header->update_area.top = y1;
- ram_header->update_area.bottom = y2;
- ram_header->update_area.left = x1;
- ram_header->update_area.right = x2;
-
- ram_header->update_surface = surface->id;
+ ram_header->update_area.top = htole32(y1);
+ ram_header->update_area.bottom = htole32(y2);
+ ram_header->update_area.left = htole32(x1);
+ ram_header->update_area.right = htole32(x2);
+ ram_header->update_surface = htole32(surface->id);
- qxl_update_area(surface->cache->qxl);
+ qxl_update_area(surface->cache->qxl,surface);
pixman_image_composite (PIXMAN_OP_SRC,
surface->dev_image,
--
1.7.4.1
More information about the Spice-devel
mailing list