diff options
author | Alon Levy <alevy@redhat.com> | 2012-07-24 18:48:56 +0300 |
---|---|---|
committer | Alon Levy <alevy@redhat.com> | 2012-10-23 18:46:58 +0200 |
commit | 0dbb62d61ba8a3bd03da83ac8155e53242128e52 (patch) | |
tree | 91ed781a03e1b9cea3b04b82c2cbabae7d0ea789 | |
parent | f9a35e911bc770f905a126601333c7bd4632a94c (diff) |
qxl(kms): fails on primary surface creation alloc because of kernel. ums no regression
-rw-r--r-- | src/qxl.h | 2 | ||||
-rw-r--r-- | src/qxl_driver.c | 309 | ||||
-rw-r--r-- | src/qxl_surface.c | 2 |
3 files changed, 197 insertions, 116 deletions
@@ -181,6 +181,8 @@ struct _qxl_screen_t long vram_size; long ram_size; + int n_surfaces; + DisplayModePtr x_modes; int virtual_x; diff --git a/src/qxl_driver.c b/src/qxl_driver.c index ee9f736..9aac8f3 100644 --- a/src/qxl_driver.c +++ b/src/qxl_driver.c @@ -293,6 +293,9 @@ qxl_kms_create_primary_surface(qxl_screen_t *qxl, QXLMode *mode) uint32_t handle = qxl_kms_alloc_resource(qxl, size, QXL_ALLOC_TYPE_SURFACE_PRIMARY); + if (handle == 0) { + return NULL; + } // NB: we may be repeatedly mapping here. should be cached. qxl->device_primary = QXL_DEVICE_PRIMARY_CREATED; qxl->primary_handle = handle; @@ -784,7 +787,7 @@ qxl_dump_ring_stat (qxl_screen_t *qxl) * This is done via already known code, so use that by default now. */ static int -qxl_resize_surface0 (qxl_screen_t *qxl, long surface0_size) +qxl_ums_resize_surface0 (qxl_screen_t *qxl, long surface0_size) { long ram_header_size = qxl->ram_size - qxl->rom->ram_header_offset; long new_mem_size = qxl->ram_size - @@ -858,11 +861,14 @@ qxl_map_memory (qxl_screen_t *qxl, int scrnIndex) qxl->surface0_area = qxl->ram; qxl->surface0_size = 0; qxl->mem = NULL; - if (!qxl_resize_surface0 (qxl, qxl->rom->surface0_area_size)) - return FALSE; - qxl->surf_mem = qxl_mem_create ((void *)((unsigned long)qxl->vram), qxl->vram_size); + if (!is_kms (qxl)) { + if (!qxl_ums_resize_surface0 (qxl, qxl->rom->surface0_area_size)) + return FALSE; + qxl->surf_mem = qxl_mem_create ((void *)((unsigned long)qxl->vram), + qxl->vram_size); + } qxl_allocate_monitors_config (qxl); - + return TRUE; } @@ -882,7 +888,10 @@ static void qxl_save_state (ScrnInfoPtr pScrn) { qxl_screen_t *qxl = pScrn->driverPrivate; - + + if (is_kms (qxl)) { + return; + } if (xf86IsPrimaryPci (qxl->pci)) vgaHWSaveFonts (pScrn, &qxl->vgaRegs); } @@ -891,9 +900,12 @@ static void qxl_restore_state (ScrnInfoPtr pScrn) { qxl_screen_t *qxl = pScrn->driverPrivate; - + + if (is_kms(qxl)) { + return; + } if (xf86IsPrimaryPci (qxl->pci)) - vgaHWRestoreFonts (pScrn, &qxl->vgaRegs); + vgaHWRestoreFonts (pScrn, &qxl->vgaRegs); } #endif /* XSPICE */ @@ -1029,12 +1041,15 @@ qxl_close_screen (CLOSE_SCREEN_ARGS_DECL) if (!xf86IsPrimaryPci(qxl->pci) && qxl->primary) qxl->reset_and_create_mem_slots(qxl); #endif - - if (pScrn->vtSema) - { - qxl_restore_state (pScrn); - qxl_mark_mem_unverifiable (qxl); - qxl_unmap_memory (qxl); + + if (pScrn->vtSema) { + qxl_restore_state (pScrn); + if (is_kms (qxl)) { + // TODO: relinquish drm master, close device. + } else { + qxl_mark_mem_unverifiable (qxl); + qxl_unmap_memory (qxl); + } } pScrn->vtSema = FALSE; @@ -1069,30 +1084,38 @@ set_screen_pixmap_header (ScreenPtr pScreen) } static Bool -qxl_resize_primary_to_virtual (qxl_screen_t *qxl) +qxl_kms_resize_primary_to_virtual (qxl_screen_t *qxl) +{ + struct QXLMode *pm = &qxl->primary_mode; + + ErrorF("unimplemented kms resize to %dx%d\n", + qxl->virtual_x, qxl->virtual_y); + pm->id = 0x435; + pm->x_res = qxl->virtual_x; + pm->y_res = qxl->virtual_y; + pm->bits = qxl->pScrn->bitsPerPixel; + pm->stride = qxl->virtual_x * pm->bits / 8; + pm->x_mili = 0; // TODO + pm->y_mili = 0; // TODO + pm->orientation = 0; // ? supported by us for single head usage? more TODO + return TRUE; +} + +static Bool +qxl_ums_resize_primary_to_virtual (qxl_screen_t *qxl) { - ScreenPtr pScreen; long new_surface0_size; - - if ((qxl->primary_mode.x_res == qxl->virtual_x && - qxl->primary_mode.y_res == qxl->virtual_y) && - qxl->device_primary == QXL_DEVICE_PRIMARY_CREATED) - { - return TRUE; /* empty Success */ - } - - ErrorF ("resizing primary to %dx%d\n", qxl->virtual_x, qxl->virtual_y); - + new_surface0_size = qxl->virtual_x * qxl->pScrn->bitsPerPixel / 8 * qxl->virtual_y; - + if (new_surface0_size > qxl->surface0_size) { - if (!qxl_resize_surface0 (qxl, new_surface0_size)) + if (is_kms(qxl) || !qxl_ums_resize_surface0(qxl, new_surface0_size)) { - ErrorF ("not resizing primary to virtual, leaving old virtual\n"); - return FALSE; - } + ErrorF ("not resizing primary to virtual, leaving old virtual\n"); + return FALSE; + } } if (qxl->primary) @@ -1113,7 +1136,34 @@ qxl_resize_primary_to_virtual (qxl_screen_t *qxl) pm->y_mili = 0; // TODO pm->orientation = 0; // ? supported by us for single head usage? more TODO } - qxl->primary = qxl_surface_cache_create_primary (qxl->surface_cache, &qxl->primary_mode); + return TRUE; +} + +static Bool +qxl_resize_primary_to_virtual(qxl_screen_t *qxl) +{ + ScreenPtr pScreen; + Bool ret; + + if ((qxl->primary_mode.x_res == qxl->virtual_x && + qxl->primary_mode.y_res == qxl->virtual_y) && + qxl->device_primary == QXL_DEVICE_PRIMARY_CREATED) { + return TRUE; /* empty Success */ + } + + ErrorF("resizing primary to %dx%d\n", qxl->virtual_x, qxl->virtual_y); + + if (is_kms(qxl)) { + ret = qxl_kms_resize_primary_to_virtual(qxl); + } else { + ret = qxl_ums_resize_primary_to_virtual(qxl); + } + if (!ret) + return ret; + qxl->primary = qxl_surface_cache_create_primary (qxl->surface_cache, + &qxl->primary_mode); + if (!qxl->primary) + return FALSE; qxl->bytes_per_pixel = (qxl->pScrn->bitsPerPixel + 7) / 8; pScreen = qxl->pScrn->pScreen; @@ -1868,40 +1918,86 @@ qxl_fb_init (qxl_screen_t *qxl, ScreenPtr pScreen) return TRUE; } +#ifdef XSPICE +static Bool +open_drm(qxl_screen_t *qxl, ScrnInfoPtr pScrn) +{ + return FALSE; +} +#else // not Xspice +static Bool +open_drm(qxl_screen_t *qxl, ScrnInfoPtr pScrn) +{ + char *BusID; + + if (qxl->drm_fd >= 0) { + return TRUE; + } + BusID = malloc(64); + sprintf(BusID, "PCI:%d:%d:%d", +#if XSERVER_LIBPCIACCESS + ((qxl->pci->domain << 8) | qxl->pci->bus), + qxl->pci->dev, qxl->pci->func +#else + ((pciConfigPtr) qxl->pci->thisCard)->busnum, + ((pciConfigPtr) qxl->pci->thisCard)->devnum, + ((pciConfigPtr) qxl->pci->thisCard)->funcnum +#endif + ); + + qxl->drm_fd = drmOpen(NULL, BusID); + free(BusID); + if (qxl->drm_fd < 0) + return FALSE; + return TRUE; +} +#endif + static Bool qxl_screen_init (SCREEN_INIT_ARGS_DECL) { ScrnInfoPtr pScrn = xf86ScreenToScrn (pScreen); qxl_screen_t * qxl = pScrn->driverPrivate; struct QXLRam *ram_header; - VisualPtr visual; - + VisualPtr visual; + CHECK_POINT (); - + assert (qxl->pScrn == pScrn); - - if (!qxl_map_memory (qxl, pScrn->scrnIndex)) - return FALSE; - + + if (!open_drm (qxl, pScrn)) { + if (!qxl_map_memory (qxl, pScrn->scrnIndex)) + return FALSE; + } else { + ErrorF("KMS HACK: setting screen to 640x480"); + pScrn->currentMode->HDisplay = 640; + pScrn->currentMode->VDisplay = 480; + pScrn->virtualY = 480; + pScrn->displayWidth = 640; + } + #ifdef XSPICE spiceqxl_screen_init (pScrn, qxl); #endif - ram_header = (void *)((unsigned long)qxl->ram + (unsigned long)qxl->rom->ram_header_offset); - - printf ("ram_header at %d\n", qxl->rom->ram_header_offset); - printf ("surf0 size: %d\n", qxl->rom->surface0_area_size); - + if (!is_kms(qxl)) { + ram_header = (void *)((unsigned long)qxl->ram + + (unsigned long)qxl->rom->ram_header_offset); + + printf ("ram_header at %d\n", qxl->rom->ram_header_offset); + printf ("surf0 size: %d\n", qxl->rom->surface0_area_size); + } + qxl_save_state (pScrn); qxl_blank_screen (pScreen, SCREEN_SAVER_ON); - + miClearVisualTypes (); - if (!miSetVisualTypes (pScrn->depth, miGetDefaultVisualMask (pScrn->depth), + if (!miSetVisualTypes (pScrn->depth, miGetDefaultVisualMask(pScrn->depth), pScrn->rgbBits, pScrn->defaultVisual)) - goto out; + goto out; if (!miSetPixmapDepths ()) - goto out; + goto out; pScrn->displayWidth = pScrn->virtualX; - + qxl->fb = calloc (pScrn->virtualY * pScrn->displayWidth, 4); if (!qxl->fb) goto out; @@ -1936,25 +2032,25 @@ qxl_screen_init (SCREEN_INIT_ARGS_DECL) qxl->reset_and_create_mem_slots(qxl); ErrorF("done reset\n"); + if (!is_kms(qxl)) { #ifndef XSPICE - 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->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->release_ring = qxl_ring_create ((struct qxl_ring_header *)&(ram_header->release_ring), - sizeof (uint64_t), - QXL_RELEASE_RING_SIZE, 0, 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->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->release_ring = qxl_ring_create ((struct qxl_ring_header *)&(ram_header->release_ring), + sizeof (uint64_t), + QXL_RELEASE_RING_SIZE, 0, qxl); + } qxl->surface_cache = qxl_surface_cache_create (qxl); - - /* xf86DPMSInit (pScreen, xf86DPMSSet, 0); */ - + + /* xf86DPMSInit(pScreen, xf86DPMSSet, 0); */ + pScreen->SaveScreen = qxl_blank_screen; setup_uxa (qxl, pScreen); @@ -2030,19 +2126,21 @@ qxl_enter_vt (VT_FUNC_ARGS_DECL) if (!qxl_resize_primary_to_virtual(qxl)) return FALSE; - if (qxl->mem) { - qxl_mem_free_all(qxl->mem); - qxl_drop_image_cache(qxl); + if (is_kms(qxl)) { + xf86DrvMsg(qxl->pScrn->scrnIndex, X_INFO, + "KMS qxl_enter_vt (empty)\n"); + } else { + if (qxl->mem) { + qxl_mem_free_all (qxl->mem); + qxl_drop_image_cache (qxl); + } + if (qxl->surf_mem) + qxl_mem_free_all (qxl->surf_mem); } - - if (qxl->surf_mem) - qxl_mem_free_all (qxl->surf_mem); - - if (qxl->vt_surfaces) - { - qxl_surface_cache_replace_all (qxl->surface_cache, qxl->vt_surfaces); - - qxl->vt_surfaces = NULL; + if (qxl->vt_surfaces) { + qxl_surface_cache_replace_all (qxl->surface_cache, qxl->vt_surfaces); + + qxl->vt_surfaces = NULL; } qxl_create_desired_modes (qxl); @@ -2118,33 +2216,6 @@ print_modes (qxl_screen_t *qxl, int scrnIndex) #ifndef XSPICE static Bool -open_drm(qxl_screen_t *qxl, ScrnInfoPtr pScrn) -{ - char *BusID; - - if (qxl->drm_fd >= 0) { - return TRUE; - } - BusID = malloc(64); - sprintf(BusID, "PCI:%d:%d:%d", -#if XSERVER_LIBPCIACCESS - ((qxl->pci->domain << 8) | qxl->pci->bus), - qxl->pci->dev, qxl->pci->func -#else - ((pciConfigPtr) qxl->pci->thisCard)->busnum, - ((pciConfigPtr) qxl->pci->thisCard)->devnum, - ((pciConfigPtr) qxl->pci->thisCard)->funcnum -#endif - ); - - qxl->drm_fd = drmOpen(NULL, BusID); - free(BusID); - if (qxl->drm_fd < 0) - return FALSE; - return TRUE; -} - -static Bool qxl_check_device(ScrnInfoPtr pScrn, qxl_screen_t *qxl) { int scrnIndex = pScrn->scrnIndex; @@ -2807,13 +2878,12 @@ qxl_pre_init (ScrnInfoPtr pScrn, int flags) xf86DrvMsg (scrnIndex, X_INFO, "Fallback Cache: %s\n", qxl->enable_fallback_cache? "Enabled" : "Disabled"); - if (!qxl_map_memory (qxl, scrnIndex)) - goto out; - qxl->drm_fd = -1; #ifndef XSPICE open_drm(qxl, pScrn); if (!is_kms(qxl)) { + if (!qxl_map_memory(qxl, scrnIndex)) + goto out; if (!qxl_check_device(pScrn, qxl)) goto out; set_callbacks_to_ums(qxl); @@ -2824,10 +2894,18 @@ qxl_pre_init (ScrnInfoPtr pScrn, int flags) set_callbacks_to_ums(qxl); xspice_init_qxl_ram(qxl); /* initialize the rings */ #endif - pScrn->videoRam = (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); - + + if (is_kms(qxl)) { + xf86DrvMsg(scrnIndex, X_ERROR, "kms guessing videoRam & n_surfaces\n"); + pScrn->videoRam = 1024; // TODO?? who uses this anyway? + qxl->n_surfaces = 1024; // TODO - read from kernel (or let kernel virtualize this?) + } else { + pScrn->videoRam = (qxl->rom->num_pages * 4096) / 1024; + qxl->n_surfaces = qxl->rom->n_surfaces; + } + xf86DrvMsg(scrnIndex, X_INFO, "%d KB of video RAM\n", pScrn->videoRam); + xf86DrvMsg(scrnIndex, X_INFO, "%d surfaces\n", qxl->n_surfaces); + /* ddc stuff here */ clockRanges = xnfcalloc (sizeof (ClockRange), 1); @@ -2919,10 +2997,11 @@ qxl_pre_init (ScrnInfoPtr pScrn, int flags) #endif /* hate */ - qxl_unmap_memory (qxl); - + if (!is_kms(qxl)) + qxl_unmap_memory (qxl); + CHECK_POINT (); - + xf86DrvMsg (scrnIndex, X_INFO, "PreInit complete\n"); #ifdef GIT_VERSION xf86DrvMsg (scrnIndex, X_INFO, "git commit %s\n", GIT_VERSION); diff --git a/src/qxl_surface.c b/src/qxl_surface.c index 00d8b05..13f193b 100644 --- a/src/qxl_surface.c +++ b/src/qxl_surface.c @@ -182,7 +182,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 = qxl->n_surfaces; int i; if (!cache->all_surfaces) |