diff options
author | Alon Levy <alevy@redhat.com> | 2012-07-22 17:31:22 +0300 |
---|---|---|
committer | Alon Levy <alevy@redhat.com> | 2012-10-23 18:46:58 +0200 |
commit | 3bf1fc61a7a9b902d5a64530a62f2df34090e2c7 (patch) | |
tree | e05cb3b7c1db1edb5a4052dfb115b4414afad4ab | |
parent | 80675313563b28158de8773cf2ca156ef573200d (diff) |
qxl: add cb create_primary_surface
-rw-r--r-- | src/qxl.h | 1 | ||||
-rw-r--r-- | src/qxl_driver.c | 84 | ||||
-rw-r--r-- | src/qxl_surface.c | 21 |
3 files changed, 88 insertions, 18 deletions
@@ -239,6 +239,7 @@ struct _qxl_screen_t int drm_fd; void (*reset_and_create_mem_slots)(qxl_screen_t *qxl); + uint8_t *(*create_primary_surface)(qxl_screen_t *qxl, QXLMode *mode); #ifdef XSPICE /* XSpice specific */ diff --git a/src/qxl_driver.c b/src/qxl_driver.c index 976d9e0..83d7252 100644 --- a/src/qxl_driver.c +++ b/src/qxl_driver.c @@ -38,10 +38,12 @@ #include <errno.h> #include <time.h> #include <stdlib.h> +#include <sys/mman.h> #include <xf86drm.h> #include <xf86Crtc.h> #include <xf86RandR12.h> +#include <libdrm/qxl_drm.h> #include "mspace.h" @@ -222,8 +224,84 @@ qxl_io_create_primary (qxl_screen_t *qxl) qxl->device_primary = QXL_DEVICE_PRIMARY_CREATED; } -void -qxl_io_destroy_primary (qxl_screen_t *qxl) +static uint64_t qxl_kms_alloc_resource(qxl_screen_t *qxl, + uint32_t size, uint32_t type) +{ + struct drm_qxl_alloc alloc; + int ret; + + alloc.type = type; + alloc.size = size; + alloc.handle = 0; + ret = drmIoctl(qxl->drm_fd, DRM_IOCTL_QXL_ALLOC, &alloc); + if (ret) { + xf86DrvMsg(qxl->pScrn->scrnIndex, X_ERROR, + "error doing QXL_ALLOC\n"); + return 0; // an invalid handle + } + return alloc.handle; +} + +static void * +qxl_kms_mmap(qxl_screen_t *qxl, uint32_t handle, size_t size) +{ + struct drm_qxl_map qxl_map; + void *map; + + memset(&qxl_map, 0, sizeof(qxl_map)); + qxl_map.handle = handle; + qxl_map.offset = 0; // filled by kernel + + if (drmIoctl(qxl->drm_fd, DRM_IOCTL_QXL_MAP, &qxl_map)) { + xf86DrvMsg(qxl->pScrn->scrnIndex, X_ERROR, + "error doing QXL_MAP: %s\n", strerror(errno)); + return NULL; + } + + map = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, qxl->drm_fd, + qxl_map.offset); + if (map == MAP_FAILED) { + xf86DrvMsg(qxl->pScrn->scrnIndex, X_ERROR, + "mmap failure: %s\n", strerror(errno)); + return NULL; + } + return map; +} + +static uint8_t * +qxl_kms_create_primary_surface(qxl_screen_t *qxl, QXLMode *mode) +{ + // TODO - actually set primary to mode. Requires no new ioctl introduction, + // reuse the dumb ones for this, should be perfect. + // NB: size needs to match closely with mode. + size_t size = 640*480*4; + + uint64_t handle = qxl_kms_alloc_resource(qxl, size, + QXL_ALLOC_TYPE_SURFACE_PRIMARY); + // NB: we may be repeatedly mapping here. should be cached. + return qxl_kms_mmap(qxl, handle, size); +} + +static uint8_t * +qxl_ums_create_primary_surface(qxl_screen_t *qxl, QXLMode *mode) +{ + struct QXLRam *ram_header = + (void *)((unsigned long)qxl->ram + qxl->rom->ram_header_offset); + struct QXLSurfaceCreate *create = &(ram_header->create_surface); + + 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 (qxl, qxl->ram, qxl->main_mem_slot); + qxl_io_create_primary(qxl); + return (uint8_t *)qxl->ram + mode->stride * (mode->y_res - 1); +} + +void qxl_io_destroy_primary(qxl_screen_t *qxl) { #ifndef XSPICE if (qxl->pci->revision >= 3) @@ -2390,6 +2468,7 @@ static void set_callbacks_to_ums(qxl_screen_t *qxl) { qxl->reset_and_create_mem_slots = qxl_ums_reset_and_create_mem_slots; + qxl->create_primary_surface = qxl_ums_create_primary_surface; } #ifndef XSPICE @@ -2397,6 +2476,7 @@ static void set_callbacks_to_kms(qxl_screen_t *qxl) { qxl->reset_and_create_mem_slots = qxl_kms_reset_and_create_mem_slots; + qxl->create_primary_surface = qxl_kms_create_primary_surface; } #endif diff --git a/src/qxl_surface.c b/src/qxl_surface.c index e88675f..8f0d227 100644 --- a/src/qxl_surface.c +++ b/src/qxl_surface.c @@ -364,9 +364,6 @@ qxl_surface_t * qxl_surface_cache_create_primary (surface_cache_t *cache, struct QXLMode *mode) { - struct QXLRam *ram_header = - (void *)((unsigned long)cache->qxl->ram + cache->qxl->rom->ram_header_offset); - struct QXLSurfaceCreate *create = &(ram_header->create_surface); pixman_format_code_t format; uint8_t *dev_addr; pixman_image_t *dev_image, *host_image; @@ -387,19 +384,11 @@ qxl_surface_cache_create_primary (surface_cache_t *cache, "Unknown bit depth %d\n", 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); - - qxl_io_create_primary(qxl); - - dev_addr = (uint8_t *)qxl->ram + mode->stride * (mode->y_res - 1); + + dev_addr = qxl->create_primary_surface(qxl, mode); + if (!dev_addr) { + return NULL; + } dev_image = pixman_image_create_bits (format, mode->x_res, mode->y_res, (uint32_t *)dev_addr, -mode->stride); |