diff options
author | Keith Packard <keithp@keithp.com> | 2014-10-09 14:21:19 +0200 |
---|---|---|
committer | Keith Packard <keithp@keithp.com> | 2014-10-09 14:21:19 +0200 |
commit | f12e7f4980416b74988052a04d0f2487b2c4a7e9 (patch) | |
tree | 7f40f5011b445d2cb38e3fd4a93fb53f8645830c | |
parent | da887726eeaece0396962dd3912578d3372881b1 (diff) | |
parent | aaf5e2d643af590366b2d02ad1c2db05d1fc4131 (diff) |
Merge remote-tracking branch 'anholt/modesetting-glamor'
-rw-r--r-- | hw/xfree86/drivers/modesetting/Makefile.am | 1 | ||||
-rw-r--r-- | hw/xfree86/drivers/modesetting/driver.c | 677 | ||||
-rw-r--r-- | hw/xfree86/drivers/modesetting/driver.h | 7 | ||||
-rw-r--r-- | hw/xfree86/drivers/modesetting/drmmode_display.c | 2502 | ||||
-rw-r--r-- | hw/xfree86/drivers/modesetting/drmmode_display.h | 14 | ||||
-rw-r--r-- | hw/xfree86/drivers/modesetting/modesetting.man | 3 |
6 files changed, 1678 insertions, 1526 deletions
diff --git a/hw/xfree86/drivers/modesetting/Makefile.am b/hw/xfree86/drivers/modesetting/Makefile.am index ca3279e23..e6834e283 100644 --- a/hw/xfree86/drivers/modesetting/Makefile.am +++ b/hw/xfree86/drivers/modesetting/Makefile.am @@ -28,6 +28,7 @@ AM_CFLAGS = $(DIX_CFLAGS) $(XORG_CFLAGS) $(LIBDRM_CFLAGS) $(UDEV_CFLAGS) $(CWARN AM_CPPFLAGS = \ $(XORG_INCS) \ + -I$(top_srcdir)/glamor \ -I$(srcdir)/../../ddc \ -I$(srcdir)/../../i2c \ -I$(srcdir)/../../modes \ diff --git a/hw/xfree86/drivers/modesetting/driver.c b/hw/xfree86/drivers/modesetting/driver.c index adfb69c9f..c62147a0f 100644 --- a/hw/xfree86/drivers/modesetting/driver.c +++ b/hw/xfree86/drivers/modesetting/driver.c @@ -61,13 +61,18 @@ #include "driver.h" +#ifdef GLAMOR +#define GLAMOR_FOR_XORG 1 +#include "glamor.h" +#endif + static void AdjustFrame(ScrnInfoPtr pScrn, int x, int y); static Bool CloseScreen(ScreenPtr pScreen); static Bool EnterVT(ScrnInfoPtr pScrn); static void Identify(int flags); static const OptionInfoRec *AvailableOptions(int chipid, int busid); -static ModeStatus ValidMode(ScrnInfoPtr pScrn, DisplayModePtr mode, Bool verbose, - int flags); +static ModeStatus ValidMode(ScrnInfoPtr pScrn, DisplayModePtr mode, + Bool verbose, int flags); static void FreeScreen(ScrnInfoPtr pScrn); static void LeaveVT(ScrnInfoPtr pScrn); static Bool SwitchMode(ScrnInfoPtr pScrn, DisplayModePtr mode); @@ -76,26 +81,25 @@ static Bool PreInit(ScrnInfoPtr pScrn, int flags); static Bool Probe(DriverPtr drv, int flags); static Bool ms_pci_probe(DriverPtr driver, - int entity_num, struct pci_device *device, - intptr_t match_data); -static Bool ms_driver_func(ScrnInfoPtr scrn, xorgDriverFuncOp op, - void *data); + int entity_num, struct pci_device *device, + intptr_t match_data); +static Bool ms_driver_func(ScrnInfoPtr scrn, xorgDriverFuncOp op, void *data); #ifdef XSERVER_LIBPCIACCESS static const struct pci_id_match ms_device_match[] = { { - PCI_MATCH_ANY, PCI_MATCH_ANY, PCI_MATCH_ANY, PCI_MATCH_ANY, - 0x00030000, 0x00ff0000, 0 - }, + PCI_MATCH_ANY, PCI_MATCH_ANY, PCI_MATCH_ANY, PCI_MATCH_ANY, + 0x00030000, 0x00ff0000, 0}, - { 0, 0, 0 }, + {0, 0, 0}, }; #endif #ifdef XSERVER_PLATFORM_BUS static Bool ms_platform_probe(DriverPtr driver, - int entity_num, int flags, struct xf86_platform_device *device, - intptr_t match_data); + int entity_num, int flags, + struct xf86_platform_device *device, + intptr_t match_data); #endif _X_EXPORT DriverRec modesetting = { @@ -115,21 +119,22 @@ _X_EXPORT DriverRec modesetting = { }; static SymTabRec Chipsets[] = { - {0, "kms" }, + {0, "kms"}, {-1, NULL} }; -typedef enum -{ +typedef enum { OPTION_SW_CURSOR, OPTION_DEVICE_PATH, OPTION_SHADOW_FB, + OPTION_ACCEL_METHOD, } modesettingOpts; static const OptionInfoRec Options[] = { {OPTION_SW_CURSOR, "SWcursor", OPTV_BOOLEAN, {0}, FALSE}, - {OPTION_DEVICE_PATH, "kmsdev", OPTV_STRING, {0}, FALSE }, - {OPTION_SHADOW_FB, "ShadowFB", OPTV_BOOLEAN, {0}, FALSE }, + {OPTION_DEVICE_PATH, "kmsdev", OPTV_STRING, {0}, FALSE}, + {OPTION_SHADOW_FB, "ShadowFB", OPTV_BOOLEAN, {0}, FALSE}, + {OPTION_ACCEL_METHOD, "AccelMethod", OPTV_STRING, {0}, FALSE}, {-1, NULL, OPTV_NONE, {0}, FALSE} }; @@ -155,25 +160,26 @@ static XF86ModuleVersionInfo VersRec = { _X_EXPORT XF86ModuleData modesettingModuleData = { &VersRec, Setup, NULL }; static void * -Setup(void * module, void * opts, int *errmaj, int *errmin) +Setup(void *module, void *opts, int *errmaj, int *errmin) { static Bool setupDone = 0; /* This module should be loaded only once, but check to be sure. */ if (!setupDone) { - setupDone = 1; - xf86AddDriver(&modesetting, module, HaveDriverFuncs); - - /* - * The return value must be non-NULL on success even though there - * is no TearDownProc. - */ - return (void *) 1; - } else { - if (errmaj) - *errmaj = LDR_ONCEONLY; - return NULL; + setupDone = 1; + xf86AddDriver(&modesetting, module, HaveDriverFuncs); + + /* + * The return value must be non-NULL on success even though there + * is no TearDownProc. + */ + return (void *) 1; + } + else { + if (errmaj) + *errmaj = LDR_ONCEONLY; + return NULL; } } @@ -181,28 +187,31 @@ static void Identify(int flags) { xf86PrintChipsets("modesetting", "Driver for Modesetting Kernel Drivers", - Chipsets); + Chipsets); } -static int open_hw(const char *dev) +static int +open_hw(const char *dev) { int fd; + if (dev) - fd = open(dev, O_RDWR, 0); + fd = open(dev, O_RDWR, 0); else { - dev = getenv("KMSDEVICE"); - if ((NULL == dev) || ((fd = open(dev, O_RDWR, 0)) == -1)) { - dev = "/dev/dri/card0"; - fd = open(dev,O_RDWR, 0); - } + dev = getenv("KMSDEVICE"); + if ((NULL == dev) || ((fd = open(dev, O_RDWR, 0)) == -1)) { + dev = "/dev/dri/card0"; + fd = open(dev, O_RDWR, 0); + } } if (fd == -1) - xf86DrvMsg(-1, X_ERROR,"open %s: %s\n", dev, strerror(errno)); + xf86DrvMsg(-1, X_ERROR, "open %s: %s\n", dev, strerror(errno)); return fd; } -static int check_outputs(int fd) +static int +check_outputs(int fd) { drmModeResPtr res = drmModeGetResources(fd); int ret; @@ -214,7 +223,8 @@ static int check_outputs(int fd) return ret; } -static Bool probe_hw(const char *dev, struct xf86_platform_device *platform_dev) +static Bool +probe_hw(const char *dev, struct xf86_platform_device *platform_dev) { int fd; @@ -230,6 +240,7 @@ static Bool probe_hw(const char *dev, struct xf86_platform_device *platform_dev) fd = open_hw(dev); if (fd != -1) { int ret = check_outputs(fd); + close(fd); return ret; } @@ -248,15 +259,15 @@ ms_DRICreatePCIBusID(const struct pci_device *dev) return busID; } - -static Bool probe_hw_pci(const char *dev, struct pci_device *pdev) +static Bool +probe_hw_pci(const char *dev, struct pci_device *pdev) { int ret = FALSE, fd = open_hw(dev); char *id, *devid; drmSetVersion sv; if (fd == -1) - return FALSE; + return FALSE; sv.drm_di_major = 1; sv.drm_di_minor = 4; @@ -267,7 +278,6 @@ static Bool probe_hw_pci(const char *dev, struct pci_device *pdev) return FALSE; } - id = drmGetBusid(fd); devid = ms_DRICreatePCIBusID(pdev); @@ -279,6 +289,7 @@ static Bool probe_hw_pci(const char *dev, struct pci_device *pdev) free(devid); return ret; } + static const OptionInfoRec * AvailableOptions(int chipid, int busid) { @@ -289,55 +300,63 @@ static Bool ms_driver_func(ScrnInfoPtr scrn, xorgDriverFuncOp op, void *data) { xorgHWFlags *flag; - + switch (op) { - case GET_REQUIRED_HW_INTERFACES: - flag = (CARD32 *)data; - (*flag) = 0; - return TRUE; - case SUPPORTS_SERVER_FDS: - return TRUE; - default: - return FALSE; + case GET_REQUIRED_HW_INTERFACES: + flag = (CARD32 *) data; + (*flag) = 0; + return TRUE; + case SUPPORTS_SERVER_FDS: + return TRUE; + default: + return FALSE; } } +static void +ms_setup_scrn_hooks(ScrnInfoPtr scrn) +{ + scrn->driverVersion = 1; + scrn->driverName = "modesetting"; + scrn->name = "modeset"; + + scrn->Probe = NULL; + scrn->PreInit = PreInit; + scrn->ScreenInit = ScreenInit; + scrn->SwitchMode = SwitchMode; + scrn->AdjustFrame = AdjustFrame; + scrn->EnterVT = EnterVT; + scrn->LeaveVT = LeaveVT; + scrn->FreeScreen = FreeScreen; + scrn->ValidMode = ValidMode; +} + #if XSERVER_LIBPCIACCESS static Bool ms_pci_probe(DriverPtr driver, - int entity_num, struct pci_device *dev, intptr_t match_data) + int entity_num, struct pci_device *dev, intptr_t match_data) { ScrnInfoPtr scrn = NULL; scrn = xf86ConfigPciEntity(scrn, 0, entity_num, NULL, - NULL, NULL, NULL, NULL, NULL); + NULL, NULL, NULL, NULL, NULL); if (scrn) { - const char *devpath; - GDevPtr devSection = xf86GetDevFromEntity(scrn->entityList[0], - scrn->entityInstanceList[0]); - - devpath = xf86FindOptionValue(devSection->options, "kmsdev"); - if (probe_hw_pci(devpath, dev)) { - scrn->driverVersion = 1; - scrn->driverName = "modesetting"; - scrn->name = "modeset"; - scrn->Probe = NULL; - scrn->PreInit = PreInit; - scrn->ScreenInit = ScreenInit; - scrn->SwitchMode = SwitchMode; - scrn->AdjustFrame = AdjustFrame; - scrn->EnterVT = EnterVT; - scrn->LeaveVT = LeaveVT; - scrn->FreeScreen = FreeScreen; - scrn->ValidMode = ValidMode; - - xf86DrvMsg(scrn->scrnIndex, X_CONFIG, - "claimed PCI slot %d@%d:%d:%d\n", - dev->bus, dev->domain, dev->dev, dev->func); - xf86DrvMsg(scrn->scrnIndex, X_INFO, - "using %s\n", devpath ? devpath : "default device"); - } else - scrn = NULL; + const char *devpath; + GDevPtr devSection = xf86GetDevFromEntity(scrn->entityList[0], + scrn->entityInstanceList[0]); + + devpath = xf86FindOptionValue(devSection->options, "kmsdev"); + if (probe_hw_pci(devpath, dev)) { + ms_setup_scrn_hooks(scrn); + + xf86DrvMsg(scrn->scrnIndex, X_CONFIG, + "claimed PCI slot %d@%d:%d:%d\n", + dev->bus, dev->domain, dev->dev, dev->func); + xf86DrvMsg(scrn->scrnIndex, X_INFO, + "using %s\n", devpath ? devpath : "default device"); + } + else + scrn = NULL; } return scrn != NULL; } @@ -346,29 +365,22 @@ ms_pci_probe(DriverPtr driver, #ifdef XSERVER_PLATFORM_BUS static Bool ms_platform_probe(DriverPtr driver, - int entity_num, int flags, struct xf86_platform_device *dev, intptr_t match_data) + int entity_num, int flags, struct xf86_platform_device *dev, + intptr_t match_data) { ScrnInfoPtr scrn = NULL; const char *path = xf86_platform_device_odev_attributes(dev)->path; int scr_flags = 0; if (flags & PLATFORM_PROBE_GPU_SCREEN) - scr_flags = XF86_ALLOCATE_GPU_SCREEN; + scr_flags = XF86_ALLOCATE_GPU_SCREEN; if (probe_hw(path, dev)) { scrn = xf86AllocateScreen(driver, scr_flags); xf86AddEntityToScreen(scrn, entity_num); - scrn->driverName = "modesetting"; - scrn->name = "modesetting"; - scrn->PreInit = PreInit; - scrn->ScreenInit = ScreenInit; - scrn->SwitchMode = SwitchMode; - scrn->AdjustFrame = AdjustFrame; - scrn->EnterVT = EnterVT; - scrn->LeaveVT = LeaveVT; - scrn->FreeScreen = FreeScreen; - scrn->ValidMode = ValidMode; + ms_setup_scrn_hooks(scrn); + xf86DrvMsg(scrn->scrnIndex, X_INFO, "using drv %s\n", path ? path : "default device"); } @@ -388,44 +400,34 @@ Probe(DriverPtr drv, int flags) /* For now, just bail out for PROBE_DETECT. */ if (flags & PROBE_DETECT) - return FALSE; + return FALSE; /* * Find the config file Device sections that match this * driver, and return if there are none. */ if ((numDevSections = xf86MatchDevice("modesetting", &devSections)) <= 0) { - return FALSE; + return FALSE; } for (i = 0; i < numDevSections; i++) { - dev = xf86FindOptionValue(devSections[i]->options,"kmsdev"); - if (probe_hw(dev, NULL)) { - int entity; - entity = xf86ClaimFbSlot(drv, 0, devSections[i], TRUE); - scrn = xf86ConfigFbEntity(scrn, 0, entity, - NULL, NULL, NULL, NULL); - } - - if (scrn) { - foundScreen = TRUE; - scrn->driverVersion = 1; - scrn->driverName = "modesetting"; - scrn->name = "modesetting"; - scrn->Probe = Probe; - scrn->PreInit = PreInit; - scrn->ScreenInit = ScreenInit; - scrn->SwitchMode = SwitchMode; - scrn->AdjustFrame = AdjustFrame; - scrn->EnterVT = EnterVT; - scrn->LeaveVT = LeaveVT; - scrn->FreeScreen = FreeScreen; - scrn->ValidMode = ValidMode; - - xf86DrvMsg(scrn->scrnIndex, X_INFO, - "using %s\n", dev ? dev : "default device"); - } + dev = xf86FindOptionValue(devSections[i]->options, "kmsdev"); + if (probe_hw(dev, NULL)) { + int entity; + + entity = xf86ClaimFbSlot(drv, 0, devSections[i], TRUE); + scrn = xf86ConfigFbEntity(scrn, 0, entity, NULL, NULL, NULL, NULL); + } + + if (scrn) { + foundScreen = TRUE; + ms_setup_scrn_hooks(scrn); + scrn->Probe = Probe; + + xf86DrvMsg(scrn->scrnIndex, X_INFO, + "using %s\n", dev ? dev : "default device"); + } } free(devSections); @@ -437,51 +439,51 @@ static Bool GetRec(ScrnInfoPtr pScrn) { if (pScrn->driverPrivate) - return TRUE; + return TRUE; pScrn->driverPrivate = xnfcalloc(sizeof(modesettingRec), 1); return TRUE; } -static int dispatch_dirty_region(ScrnInfoPtr scrn, - PixmapPtr pixmap, - DamagePtr damage, - int fb_id) +static int +dispatch_dirty_region(ScrnInfoPtr scrn, + PixmapPtr pixmap, DamagePtr damage, int fb_id) { modesettingPtr ms = modesettingPTR(scrn); RegionPtr dirty = DamageRegion(damage); unsigned num_cliprects = REGION_NUM_RECTS(dirty); if (num_cliprects) { - drmModeClip *clip = malloc(num_cliprects * sizeof(drmModeClip)); - BoxPtr rect = REGION_RECTS(dirty); - int i, ret; - - if (!clip) - return -ENOMEM; - - /* XXX no need for copy? */ - for (i = 0; i < num_cliprects; i++, rect++) { - clip[i].x1 = rect->x1; - clip[i].y1 = rect->y1; - clip[i].x2 = rect->x2; - clip[i].y2 = rect->y2; - } - - /* TODO query connector property to see if this is needed */ - ret = drmModeDirtyFB(ms->fd, fb_id, clip, num_cliprects); - free(clip); - DamageEmpty(damage); - if (ret) { - if (ret == -EINVAL) - return ret; - } + drmModeClip *clip = malloc(num_cliprects * sizeof(drmModeClip)); + BoxPtr rect = REGION_RECTS(dirty); + int i, ret; + + if (!clip) + return -ENOMEM; + + /* XXX no need for copy? */ + for (i = 0; i < num_cliprects; i++, rect++) { + clip[i].x1 = rect->x1; + clip[i].y1 = rect->y1; + clip[i].x2 = rect->x2; + clip[i].y2 = rect->y2; + } + + /* TODO query connector property to see if this is needed */ + ret = drmModeDirtyFB(ms->fd, fb_id, clip, num_cliprects); + free(clip); + DamageEmpty(damage); + if (ret) { + if (ret == -EINVAL) + return ret; + } } return 0; } -static void dispatch_dirty(ScreenPtr pScreen) +static void +dispatch_dirty(ScreenPtr pScreen) { ScrnInfoPtr scrn = xf86ScreenToScrn(pScreen); modesettingPtr ms = modesettingPTR(scrn); @@ -491,16 +493,18 @@ static void dispatch_dirty(ScreenPtr pScreen) ret = dispatch_dirty_region(scrn, pixmap, ms->damage, fb_id); if (ret == -EINVAL || ret == -ENOSYS) { - ms->dirty_enabled = FALSE; - DamageUnregister(ms->damage); - DamageDestroy(ms->damage); - ms->damage = NULL; - xf86DrvMsg(scrn->scrnIndex, X_INFO, "Disabling kernel dirty updates, not required.\n"); - return; + ms->dirty_enabled = FALSE; + DamageUnregister(ms->damage); + DamageDestroy(ms->damage); + ms->damage = NULL; + xf86DrvMsg(scrn->scrnIndex, X_INFO, + "Disabling kernel dirty updates, not required.\n"); + return; } } -static void dispatch_dirty_crtc(ScrnInfoPtr scrn, xf86CrtcPtr crtc) +static void +dispatch_dirty_crtc(ScrnInfoPtr scrn, xf86CrtcPtr crtc) { modesettingPtr ms = modesettingPTR(scrn); PixmapPtr pixmap = crtc->randr_crtc->scanout_pixmap; @@ -516,25 +520,27 @@ static void dispatch_dirty_crtc(ScrnInfoPtr scrn, xf86CrtcPtr crtc) } } -static void dispatch_slave_dirty(ScreenPtr pScreen) +static void +dispatch_slave_dirty(ScreenPtr pScreen) { ScrnInfoPtr scrn = xf86ScreenToScrn(pScreen); xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); int c; for (c = 0; c < xf86_config->num_crtc; c++) { - xf86CrtcPtr crtc = xf86_config->crtc[c]; + xf86CrtcPtr crtc = xf86_config->crtc[c]; - if (!crtc->randr_crtc) - continue; - if (!crtc->randr_crtc->scanout_pixmap) - continue; + if (!crtc->randr_crtc) + continue; + if (!crtc->randr_crtc->scanout_pixmap) + continue; - dispatch_dirty_crtc(scrn, crtc); + dispatch_dirty_crtc(scrn, crtc); } } -static void msBlockHandler(ScreenPtr pScreen, void *pTimeout, void *pReadmask) +static void +msBlockHandler(ScreenPtr pScreen, void *pTimeout, void *pReadmask) { modesettingPtr ms = modesettingPTR(xf86ScreenToScrn(pScreen)); @@ -568,7 +574,7 @@ FreeRec(ScrnInfoPtr pScrn) else #ifdef XF86_PDEV_SERVER_FD if (!(ms->pEnt->location.type == BUS_PLATFORM && - (ms->pEnt->location.id.plat->flags & XF86_PDEV_SERVER_FD))) + (ms->pEnt->location.id.plat->flags & XF86_PDEV_SERVER_FD))) #endif ret = close(ms->fd); (void) ret; @@ -578,6 +584,43 @@ FreeRec(ScrnInfoPtr pScrn) } +static void +try_enable_glamor(ScrnInfoPtr pScrn) +{ + modesettingPtr ms = modesettingPTR(pScrn); + const char *accel_method_str = xf86GetOptValString(ms->Options, + OPTION_ACCEL_METHOD); + Bool do_glamor = (!accel_method_str || + strcmp(accel_method_str, "glamor") == 0); + + ms->glamor = FALSE; + +#ifdef GLAMOR + if (!do_glamor) { + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "glamor disabled\n"); + return; + } + + if (xf86LoadSubModule(pScrn, GLAMOR_EGL_MODULE_NAME)) { + if (glamor_egl_init(pScrn, ms->fd)) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "glamor initialized\n"); + ms->glamor = TRUE; + } else { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "glamor initialization failed\n"); + } + } else { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Failed to load glamor module.\n"); + } +#else + if (do_glamor) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "No glamor support in the X Server\n"); + } +#endif +} + #ifndef DRM_CAP_CURSOR_WIDTH #define DRM_CAP_CURSOR_WIDTH 0x8 #endif @@ -595,45 +638,46 @@ PreInit(ScrnInfoPtr pScrn, int flags) EntPtr msEnt = NULL; char *BusID = NULL; const char *devicename; - Bool prefer_shadow = TRUE; uint64_t value = 0; int ret; int bppflags; int defaultdepth, defaultbpp; if (pScrn->numEntities != 1) - return FALSE; + return FALSE; pEnt = xf86GetEntityInfo(pScrn->entityList[0]); if (flags & PROBE_DETECT) { - return FALSE; + return FALSE; } /* Allocate driverPrivate */ if (!GetRec(pScrn)) - return FALSE; + return FALSE; ms = modesettingPTR(pScrn); ms->SaveGeneration = -1; ms->pEnt = pEnt; - pScrn->displayWidth = 640; /* default it */ + pScrn->displayWidth = 640; /* default it */ /* Allocate an entity private if necessary */ if (xf86IsEntityShared(pScrn->entityList[0])) { - msEnt = xf86GetEntityPrivate(pScrn->entityList[0], - modesettingEntityIndex)->ptr; - ms->entityPrivate = msEnt; - } else - ms->entityPrivate = NULL; + msEnt = xf86GetEntityPrivate(pScrn->entityList[0], + modesettingEntityIndex)->ptr; + ms->entityPrivate = msEnt; + } + else + ms->entityPrivate = NULL; if (xf86IsEntityShared(pScrn->entityList[0])) { - if (xf86IsPrimInitDone(pScrn->entityList[0])) { - /* do something */ - } else { - xf86SetPrimInitDone(pScrn->entityList[0]); - } + if (xf86IsPrimInitDone(pScrn->entityList[0])) { + /* do something */ + } + else { + xf86SetPrimInitDone(pScrn->entityList[0]); + } } pScrn->monitor = pScrn->confScreen->monitor; @@ -644,15 +688,19 @@ PreInit(ScrnInfoPtr pScrn, int flags) if (pEnt->location.type == BUS_PLATFORM) { #ifdef XF86_PDEV_SERVER_FD if (pEnt->location.id.plat->flags & XF86_PDEV_SERVER_FD) - ms->fd = xf86_platform_device_odev_attributes(pEnt->location.id.plat)->fd; + ms->fd = + xf86_platform_device_odev_attributes(pEnt->location.id.plat)-> + fd; else #endif { - char *path = xf86_platform_device_odev_attributes(pEnt->location.id.plat)->path; + char *path = + xf86_platform_device_odev_attributes(pEnt->location.id.plat)-> + path; ms->fd = open_hw(path); } } - else + else #endif if (pEnt->location.type == BUS_PCI) { ms->PciInfo = xf86GetPciInfoForEntity(ms->pEnt->index); @@ -670,12 +718,13 @@ PreInit(ScrnInfoPtr pScrn, int flags) ); } ms->fd = drmOpen(NULL, BusID); - } else { + } + else { devicename = xf86FindOptionValue(ms->pEnt->device->options, "kmsdev"); ms->fd = open_hw(devicename); } if (ms->fd < 0) - return FALSE; + return FALSE; ms->drmmode.fd = ms->fd; @@ -689,81 +738,93 @@ PreInit(ScrnInfoPtr pScrn, int flags) #endif drmmode_get_default_bpp(pScrn, &ms->drmmode, &defaultdepth, &defaultbpp); if (defaultdepth == 24 && defaultbpp == 24) - bppflags = SupportConvert32to24 | Support24bppFb; + bppflags = SupportConvert32to24 | Support24bppFb; else - bppflags = PreferConvert24to32 | SupportConvert24to32 | Support32bppFb; - + bppflags = PreferConvert24to32 | SupportConvert24to32 | Support32bppFb; + if (!xf86SetDepthBpp - (pScrn, defaultdepth, defaultdepth, defaultbpp, bppflags)) - return FALSE; + (pScrn, defaultdepth, defaultdepth, defaultbpp, bppflags)) + return FALSE; switch (pScrn->depth) { case 15: case 16: case 24: - break; + break; default: - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Given depth (%d) is not supported by the driver\n", - pScrn->depth); - return FALSE; + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Given depth (%d) is not supported by the driver\n", + pScrn->depth); + return FALSE; } xf86PrintDepthBpp(pScrn); /* Process the options */ xf86CollectOptions(pScrn, NULL); if (!(ms->Options = malloc(sizeof(Options)))) - return FALSE; + return FALSE; memcpy(ms->Options, Options, sizeof(Options)); xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, ms->Options); if (!xf86SetWeight(pScrn, defaultWeight, defaultWeight)) - return FALSE; + return FALSE; if (!xf86SetDefaultVisual(pScrn, -1)) - return FALSE; + return FALSE; if (xf86ReturnOptValBool(ms->Options, OPTION_SW_CURSOR, FALSE)) { - ms->drmmode.sw_cursor = TRUE; - } - - ret = drmGetCap(ms->fd, DRM_CAP_DUMB_PREFER_SHADOW, &value); - if (!ret) { - prefer_shadow = !!value; + ms->drmmode.sw_cursor = TRUE; } ms->cursor_width = 64; ms->cursor_height = 64; ret = drmGetCap(ms->fd, DRM_CAP_CURSOR_WIDTH, &value); if (!ret) { - ms->cursor_width = value; + ms->cursor_width = value; } ret = drmGetCap(ms->fd, DRM_CAP_CURSOR_HEIGHT, &value); if (!ret) { - ms->cursor_height = value; + ms->cursor_height = value; } - ms->drmmode.shadow_enable = xf86ReturnOptValBool(ms->Options, OPTION_SHADOW_FB, prefer_shadow); + try_enable_glamor(pScrn); + + if (!ms->glamor) { + Bool prefer_shadow = TRUE; + + ret = drmGetCap(ms->fd, DRM_CAP_DUMB_PREFER_SHADOW, &value); + if (!ret) { + prefer_shadow = !!value; + } + + ms->drmmode.shadow_enable = xf86ReturnOptValBool(ms->Options, + OPTION_SHADOW_FB, + prefer_shadow); + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "ShadowFB: preferred %s, enabled %s\n", + prefer_shadow ? "YES" : "NO", + ms->drmmode.shadow_enable ? "YES" : "NO"); + } - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ShadowFB: preferred %s, enabled %s\n", prefer_shadow ? "YES" : "NO", ms->drmmode.shadow_enable ? "YES" : "NO"); if (drmmode_pre_init(pScrn, &ms->drmmode, pScrn->bitsPerPixel / 8) == FALSE) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "KMS setup failed\n"); - goto fail; + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "KMS setup failed\n"); + goto fail; } /* * If the driver can do gamma correction, it should call xf86SetGamma() here. */ { - Gamma zeros = { 0.0, 0.0, 0.0 }; + Gamma zeros = { 0.0, 0.0, 0.0 }; - if (!xf86SetGamma(pScrn, zeros)) { - return FALSE; - } + if (!xf86SetGamma(pScrn, zeros)) { + return FALSE; + } } if (pScrn->modes == NULL) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No modes.\n"); - return FALSE; + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No modes.\n"); + return FALSE; } pScrn->currentMode = pScrn->modes; @@ -773,23 +834,23 @@ PreInit(ScrnInfoPtr pScrn, int flags) /* Load the required sub modules */ if (!xf86LoadSubModule(pScrn, "fb")) { - return FALSE; + return FALSE; } if (ms->drmmode.shadow_enable) { - if (!xf86LoadSubModule(pScrn, "shadow")) { - return FALSE; - } + if (!xf86LoadSubModule(pScrn, "shadow")) { + return FALSE; + } } return TRUE; - fail: + fail: return FALSE; } static void * msShadowWindow(ScreenPtr screen, CARD32 row, CARD32 offset, int mode, - CARD32 *size, void *closure) + CARD32 *size, void *closure) { ScrnInfoPtr pScrn = xf86ScreenToScrn(screen); modesettingPtr ms = modesettingPTR(pScrn); @@ -798,7 +859,7 @@ msShadowWindow(ScreenPtr screen, CARD32 row, CARD32 offset, int mode, stride = (pScrn->displayWidth * pScrn->bitsPerPixel) / 8; *size = stride; - return ((uint8_t *)ms->drmmode.front_bo->ptr + row * stride + offset); + return ((uint8_t *) ms->drmmode.front_bo->ptr + row * stride + offset); } static void @@ -815,12 +876,27 @@ CreateScreenResources(ScreenPtr pScreen) PixmapPtr rootPixmap; Bool ret; void *pixels; + pScreen->CreateScreenResources = ms->createScreenResources; ret = pScreen->CreateScreenResources(pScreen); pScreen->CreateScreenResources = CreateScreenResources; if (!drmmode_set_desired_modes(pScrn, &ms->drmmode)) - return FALSE; + return FALSE; + +#ifdef GLAMOR + if (ms->glamor) { + if (!glamor_egl_create_textured_screen_ext(pScreen, + ms->drmmode.front_bo->handle, + pScrn->displayWidth * + pScrn->bitsPerPixel / 8, + NULL)) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "glamor_egl_create_textured_screen_ext() failed\n"); + return FALSE; + } + } +#endif drmmode_uevent_init(pScrn, &ms->drmmode); @@ -828,33 +904,34 @@ CreateScreenResources(ScreenPtr pScreen) drmmode_map_cursor_bos(pScrn, &ms->drmmode); pixels = drmmode_map_front_bo(&ms->drmmode); if (!pixels) - return FALSE; + return FALSE; rootPixmap = pScreen->GetScreenPixmap(pScreen); if (ms->drmmode.shadow_enable) - pixels = ms->drmmode.shadow_fb; - + pixels = ms->drmmode.shadow_fb; + if (!pScreen->ModifyPixmapHeader(rootPixmap, -1, -1, -1, -1, -1, pixels)) - FatalError("Couldn't adjust screen pixmap\n"); + FatalError("Couldn't adjust screen pixmap\n"); if (ms->drmmode.shadow_enable) { - if (!shadowAdd(pScreen, rootPixmap, msUpdatePacked, - msShadowWindow, 0, 0)) - return FALSE; + if (!shadowAdd(pScreen, rootPixmap, msUpdatePacked, + msShadowWindow, 0, 0)) + return FALSE; } ms->damage = DamageCreate(NULL, NULL, DamageReportNone, TRUE, pScreen, rootPixmap); if (ms->damage) { - DamageRegister(&rootPixmap->drawable, ms->damage); - ms->dirty_enabled = TRUE; - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Damage tracking initialized\n"); - } else { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Failed to create screen damage record\n"); - return FALSE; + DamageRegister(&rootPixmap->drawable, ms->damage); + ms->dirty_enabled = TRUE; + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Damage tracking initialized\n"); + } + else { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Failed to create screen damage record\n"); + return FALSE; } return ret; } @@ -863,7 +940,7 @@ static Bool msShadowInit(ScreenPtr pScreen) { if (!shadowSetup(pScreen)) { - return FALSE; + return FALSE; } return TRUE; } @@ -876,11 +953,11 @@ msSetSharedPixmapBacking(PixmapPtr ppix, void *fd_handle) modesettingPtr ms = modesettingPTR(scrn); Bool ret; int size = ppix->devKind * ppix->drawable.height; - int ihandle = (int)(long)fd_handle; + int ihandle = (int) (long) fd_handle; ret = drmmode_SetSlaveBO(ppix, &ms->drmmode, ihandle, ppix->devKind, size); if (ret == FALSE) - return ret; + return ret; return TRUE; } @@ -893,7 +970,7 @@ SetMaster(ScrnInfoPtr pScrn) #ifdef XF86_PDEV_SERVER_FD if (ms->pEnt->location.type == BUS_PLATFORM && - (ms->pEnt->location.id.plat->flags & XF86_PDEV_SERVER_FD)) + (ms->pEnt->location.id.plat->flags & XF86_PDEV_SERVER_FD)) return TRUE; #endif @@ -920,62 +997,77 @@ ScreenInit(ScreenPtr pScreen, int argc, char **argv) /* HW dependent - FIXME */ pScrn->displayWidth = pScrn->virtualX; if (!drmmode_create_initial_bos(pScrn, &ms->drmmode)) - return FALSE; + return FALSE; if (ms->drmmode.shadow_enable) { - ms->drmmode.shadow_fb = calloc(1, pScrn->displayWidth * pScrn->virtualY * - ((pScrn->bitsPerPixel + 7) >> 3)); - if (!ms->drmmode.shadow_fb) - ms->drmmode.shadow_enable = FALSE; - } - + ms->drmmode.shadow_fb = + calloc(1, + pScrn->displayWidth * pScrn->virtualY * + ((pScrn->bitsPerPixel + 7) >> 3)); + if (!ms->drmmode.shadow_fb) + ms->drmmode.shadow_enable = FALSE; + } + miClearVisualTypes(); if (!miSetVisualTypes(pScrn->depth, - miGetDefaultVisualMask(pScrn->depth), - pScrn->rgbBits, pScrn->defaultVisual)) - return FALSE; + miGetDefaultVisualMask(pScrn->depth), + pScrn->rgbBits, pScrn->defaultVisual)) + return FALSE; if (!miSetPixmapDepths()) - return FALSE; + return FALSE; - if (!dixRegisterScreenSpecificPrivateKey(pScreen, &ms->drmmode.pixmapPrivateKeyRec, - PRIVATE_PIXMAP, sizeof(msPixmapPrivRec))) { - return FALSE; + if (!dixRegisterScreenSpecificPrivateKey + (pScreen, &ms->drmmode.pixmapPrivateKeyRec, PRIVATE_PIXMAP, + sizeof(msPixmapPrivRec))) { + return FALSE; } pScrn->memPhysBase = 0; pScrn->fbOffset = 0; if (!fbScreenInit(pScreen, NULL, - pScrn->virtualX, pScrn->virtualY, - pScrn->xDpi, pScrn->yDpi, - pScrn->displayWidth, pScrn->bitsPerPixel)) - return FALSE; + pScrn->virtualX, pScrn->virtualY, + pScrn->xDpi, pScrn->yDpi, + pScrn->displayWidth, pScrn->bitsPerPixel)) + return FALSE; if (pScrn->bitsPerPixel > 8) { - /* Fixup RGB ordering */ - visual = pScreen->visuals + pScreen->numVisuals; - while (--visual >= pScreen->visuals) { - if ((visual->class | DynamicClass) == DirectColor) { - visual->offsetRed = pScrn->offset.red; - visual->offsetGreen = pScrn->offset.green; - visual->offsetBlue = pScrn->offset.blue; - visual->redMask = pScrn->mask.red; - visual->greenMask = pScrn->mask.green; - visual->blueMask = pScrn->mask.blue; - } - } + /* Fixup RGB ordering */ + visual = pScreen->visuals + pScreen->numVisuals; + while (--visual >= pScreen->visuals) { + if ((visual->class | DynamicClass) == DirectColor) { + visual->offsetRed = pScrn->offset.red; + visual->offsetGreen = pScrn->offset.green; + visual->offsetBlue = pScrn->offset.blue; + visual->redMask = pScrn->mask.red; + visual->greenMask = pScrn->mask.green; + visual->blueMask = pScrn->mask.blue; + } + } } fbPictureInit(pScreen, NULL, 0); +#ifdef GLAMOR + if (ms->glamor) { + if (!glamor_init(pScreen, + GLAMOR_USE_EGL_SCREEN | + GLAMOR_USE_SCREEN | + GLAMOR_USE_PICTURE_SCREEN)) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Failed to initialize glamor at ScreenInit() time.\n"); + return FALSE; + } + } +#endif + if (ms->drmmode.shadow_enable && !msShadowInit(pScreen)) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "shadow fb init failed\n"); - return FALSE; + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "shadow fb init failed\n"); + return FALSE; } - + ms->createScreenResources = pScreen->CreateScreenResources; pScreen->CreateScreenResources = CreateScreenResources; @@ -987,9 +1079,9 @@ ScreenInit(ScreenPtr pScreen, int argc, char **argv) /* Need to extend HWcursor support to handle mask interleave */ if (!ms->drmmode.sw_cursor) - xf86_cursors_init(pScreen, ms->cursor_width, ms->cursor_height, - HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_64 | - HARDWARE_CURSOR_ARGB); + xf86_cursors_init(pScreen, ms->cursor_width, ms->cursor_height, + HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_64 | + HARDWARE_CURSOR_ARGB); /* Must force it before EnterVT, so we are in control of VT and * later memory should be bound when allocating, e.g rotate_mem */ @@ -1005,15 +1097,15 @@ ScreenInit(ScreenPtr pScreen, int argc, char **argv) pScreen->SetSharedPixmapBacking = msSetSharedPixmapBacking; if (!xf86CrtcScreenInit(pScreen)) - return FALSE; + return FALSE; if (!miCreateDefColormap(pScreen)) - return FALSE; + return FALSE; xf86DPMSInit(pScreen, xf86DPMSSet, 0); if (serverGeneration == 1) - xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options); + xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options); return EnterVT(pScrn); } @@ -1036,13 +1128,14 @@ static void LeaveVT(ScrnInfoPtr pScrn) { modesettingPtr ms = modesettingPTR(pScrn); + xf86_hide_cursors(pScrn); pScrn->vtSema = FALSE; #ifdef XF86_PDEV_SERVER_FD if (ms->pEnt->location.type == BUS_PLATFORM && - (ms->pEnt->location.id.plat->flags & XF86_PDEV_SERVER_FD)) + (ms->pEnt->location.id.plat->flags & XF86_PDEV_SERVER_FD)) return; #endif @@ -1062,7 +1155,7 @@ EnterVT(ScrnInfoPtr pScrn) SetMaster(pScrn); if (!drmmode_set_desired_modes(pScrn, &ms->drmmode)) - return FALSE; + return FALSE; return TRUE; } @@ -1080,15 +1173,15 @@ CloseScreen(ScreenPtr pScreen) modesettingPtr ms = modesettingPTR(pScrn); if (ms->damage) { - DamageUnregister(ms->damage); - DamageDestroy(ms->damage); - ms->damage = NULL; + DamageUnregister(ms->damage); + DamageDestroy(ms->damage); + ms->damage = NULL; } if (ms->drmmode.shadow_enable) { - shadowRemove(pScreen, pScreen->GetScreenPixmap(pScreen)); - free(ms->drmmode.shadow_fb); - ms->drmmode.shadow_fb = NULL; + shadowRemove(pScreen, pScreen->GetScreenPixmap(pScreen)); + free(ms->drmmode.shadow_fb); + ms->drmmode.shadow_fb = NULL; } drmmode_uevent_fini(pScrn, &ms->drmmode); diff --git a/hw/xfree86/drivers/modesetting/driver.h b/hw/xfree86/drivers/modesetting/driver.h index 450b29c2b..35f24193a 100644 --- a/hw/xfree86/drivers/modesetting/driver.h +++ b/hw/xfree86/drivers/modesetting/driver.h @@ -35,16 +35,14 @@ #include "drmmode_display.h" #define DRV_ERROR(msg) xf86DrvMsg(pScrn->scrnIndex, X_ERROR, msg); -typedef struct -{ +typedef struct { int lastInstance; int refCount; ScrnInfoPtr pScrn_1; ScrnInfoPtr pScrn_2; } EntRec, *EntPtr; -typedef struct _modesettingRec -{ +typedef struct _modesettingRec { int fd; EntPtr entityPrivate; @@ -76,6 +74,7 @@ typedef struct _modesettingRec Bool dirty_enabled; uint32_t cursor_width, cursor_height; + Bool glamor; } modesettingRec, *modesettingPtr; #define modesettingPTR(p) ((modesettingPtr)((p)->driverPrivate)) diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.c b/hw/xfree86/drivers/modesetting/drmmode_display.c index 9723ccd0e..d959837ae 100644 --- a/hw/xfree86/drivers/modesetting/drmmode_display.c +++ b/hw/xfree86/drivers/modesetting/drmmode_display.c @@ -49,181 +49,183 @@ #include "driver.h" -static struct dumb_bo *dumb_bo_create(int fd, - const unsigned width, const unsigned height, - const unsigned bpp) +static struct dumb_bo * +dumb_bo_create(int fd, + const unsigned width, const unsigned height, const unsigned bpp) { - struct drm_mode_create_dumb arg; - struct dumb_bo *bo; - int ret; - - bo = calloc(1, sizeof(*bo)); - if (!bo) - return NULL; - - memset(&arg, 0, sizeof(arg)); - arg.width = width; - arg.height = height; - arg.bpp = bpp; - - ret = drmIoctl(fd, DRM_IOCTL_MODE_CREATE_DUMB, &arg); - if (ret) - goto err_free; - - bo->handle = arg.handle; - bo->size = arg.size; - bo->pitch = arg.pitch; - - return bo; + struct drm_mode_create_dumb arg; + struct dumb_bo *bo; + int ret; + + bo = calloc(1, sizeof(*bo)); + if (!bo) + return NULL; + + memset(&arg, 0, sizeof(arg)); + arg.width = width; + arg.height = height; + arg.bpp = bpp; + + ret = drmIoctl(fd, DRM_IOCTL_MODE_CREATE_DUMB, &arg); + if (ret) + goto err_free; + + bo->handle = arg.handle; + bo->size = arg.size; + bo->pitch = arg.pitch; + + return bo; err_free: - free(bo); - return NULL; + free(bo); + return NULL; } -static int dumb_bo_map(int fd, struct dumb_bo *bo) +static int +dumb_bo_map(int fd, struct dumb_bo *bo) { - struct drm_mode_map_dumb arg; - int ret; - void *map; + struct drm_mode_map_dumb arg; + int ret; + void *map; - if (bo->ptr) { - bo->map_count++; - return 0; - } + if (bo->ptr) { + bo->map_count++; + return 0; + } - memset(&arg, 0, sizeof(arg)); - arg.handle = bo->handle; + memset(&arg, 0, sizeof(arg)); + arg.handle = bo->handle; - ret = drmIoctl(fd, DRM_IOCTL_MODE_MAP_DUMB, &arg); - if (ret) - return ret; + ret = drmIoctl(fd, DRM_IOCTL_MODE_MAP_DUMB, &arg); + if (ret) + return ret; - map = mmap(0, bo->size, PROT_READ | PROT_WRITE, MAP_SHARED, - fd, arg.offset); - if (map == MAP_FAILED) - return -errno; + map = mmap(0, bo->size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, arg.offset); + if (map == MAP_FAILED) + return -errno; - bo->ptr = map; - return 0; + bo->ptr = map; + return 0; } #if 0 -static int dumb_bo_unmap(int fd, struct dumb_bo *bo) +static int +dumb_bo_unmap(int fd, struct dumb_bo *bo) { - bo->map_count--; - return 0; + bo->map_count--; + return 0; } #endif -static int dumb_bo_destroy(int fd, struct dumb_bo *bo) +static int +dumb_bo_destroy(int fd, struct dumb_bo *bo) { - struct drm_mode_destroy_dumb arg; - int ret; - - if (bo->ptr) { - munmap(bo->ptr, bo->size); - bo->ptr = NULL; - } - - memset(&arg, 0, sizeof(arg)); - arg.handle = bo->handle; - ret = drmIoctl(fd, DRM_IOCTL_MODE_DESTROY_DUMB, &arg); - if (ret) - return -errno; - - free(bo); - return 0; + struct drm_mode_destroy_dumb arg; + int ret; + + if (bo->ptr) { + munmap(bo->ptr, bo->size); + bo->ptr = NULL; + } + + memset(&arg, 0, sizeof(arg)); + arg.handle = bo->handle; + ret = drmIoctl(fd, DRM_IOCTL_MODE_DESTROY_DUMB, &arg); + if (ret) + return -errno; + + free(bo); + return 0; } -static struct dumb_bo *dumb_get_bo_from_handle(int fd, int handle, int pitch, int size) +static struct dumb_bo * +dumb_get_bo_from_handle(int fd, int handle, int pitch, int size) { - struct dumb_bo *bo; - int ret; - - bo = calloc(1, sizeof(*bo)); - if (!bo) - return NULL; - - ret = drmPrimeFDToHandle(fd, handle, &bo->handle); - if (ret) { - free(bo); - return NULL; - } - bo->pitch = pitch; - bo->size = size; - return bo; + struct dumb_bo *bo; + int ret; + + bo = calloc(1, sizeof(*bo)); + if (!bo) + return NULL; + + ret = drmPrimeFDToHandle(fd, handle, &bo->handle); + if (ret) { + free(bo); + return NULL; + } + bo->pitch = pitch; + bo->size = size; + return bo; } -Bool drmmode_SetSlaveBO(PixmapPtr ppix, - drmmode_ptr drmmode, - int fd_handle, int pitch, int size) +Bool +drmmode_SetSlaveBO(PixmapPtr ppix, + drmmode_ptr drmmode, int fd_handle, int pitch, int size) { - msPixmapPrivPtr ppriv = msGetPixmapPriv(drmmode, ppix); + msPixmapPrivPtr ppriv = msGetPixmapPriv(drmmode, ppix); - ppriv->backing_bo = dumb_get_bo_from_handle(drmmode->fd, fd_handle, pitch, size); - if (!ppriv->backing_bo) - return FALSE; + ppriv->backing_bo = + dumb_get_bo_from_handle(drmmode->fd, fd_handle, pitch, size); + if (!ppriv->backing_bo) + return FALSE; - close(fd_handle); - return TRUE; + close(fd_handle); + return TRUE; } static void -drmmode_ConvertFromKMode(ScrnInfoPtr scrn, - drmModeModeInfo *kmode, - DisplayModePtr mode) +drmmode_ConvertFromKMode(ScrnInfoPtr scrn, + drmModeModeInfo * kmode, DisplayModePtr mode) { - memset(mode, 0, sizeof(DisplayModeRec)); - mode->status = MODE_OK; - - mode->Clock = kmode->clock; - - mode->HDisplay = kmode->hdisplay; - mode->HSyncStart = kmode->hsync_start; - mode->HSyncEnd = kmode->hsync_end; - mode->HTotal = kmode->htotal; - mode->HSkew = kmode->hskew; - - mode->VDisplay = kmode->vdisplay; - mode->VSyncStart = kmode->vsync_start; - mode->VSyncEnd = kmode->vsync_end; - mode->VTotal = kmode->vtotal; - mode->VScan = kmode->vscan; - - mode->Flags = kmode->flags; //& FLAG_BITS; - mode->name = strdup(kmode->name); - - if (kmode->type & DRM_MODE_TYPE_DRIVER) - mode->type = M_T_DRIVER; - if (kmode->type & DRM_MODE_TYPE_PREFERRED) - mode->type |= M_T_PREFERRED; - xf86SetModeCrtc (mode, scrn->adjustFlags); + memset(mode, 0, sizeof(DisplayModeRec)); + mode->status = MODE_OK; + + mode->Clock = kmode->clock; + + mode->HDisplay = kmode->hdisplay; + mode->HSyncStart = kmode->hsync_start; + mode->HSyncEnd = kmode->hsync_end; + mode->HTotal = kmode->htotal; + mode->HSkew = kmode->hskew; + + mode->VDisplay = kmode->vdisplay; + mode->VSyncStart = kmode->vsync_start; + mode->VSyncEnd = kmode->vsync_end; + mode->VTotal = kmode->vtotal; + mode->VScan = kmode->vscan; + + mode->Flags = kmode->flags; //& FLAG_BITS; + mode->name = strdup(kmode->name); + + if (kmode->type & DRM_MODE_TYPE_DRIVER) + mode->type = M_T_DRIVER; + if (kmode->type & DRM_MODE_TYPE_PREFERRED) + mode->type |= M_T_PREFERRED; + xf86SetModeCrtc(mode, scrn->adjustFlags); } static void -drmmode_ConvertToKMode(ScrnInfoPtr scrn, - drmModeModeInfo *kmode, - DisplayModePtr mode) +drmmode_ConvertToKMode(ScrnInfoPtr scrn, + drmModeModeInfo * kmode, DisplayModePtr mode) { - memset(kmode, 0, sizeof(*kmode)); - - kmode->clock = mode->Clock; - kmode->hdisplay = mode->HDisplay; - kmode->hsync_start = mode->HSyncStart; - kmode->hsync_end = mode->HSyncEnd; - kmode->htotal = mode->HTotal; - kmode->hskew = mode->HSkew; - - kmode->vdisplay = mode->VDisplay; - kmode->vsync_start = mode->VSyncStart; - kmode->vsync_end = mode->VSyncEnd; - kmode->vtotal = mode->VTotal; - kmode->vscan = mode->VScan; - - kmode->flags = mode->Flags; //& FLAG_BITS; - if (mode->name) - strncpy(kmode->name, mode->name, DRM_DISPLAY_MODE_LEN); - kmode->name[DRM_DISPLAY_MODE_LEN-1] = 0; + memset(kmode, 0, sizeof(*kmode)); + + kmode->clock = mode->Clock; + kmode->hdisplay = mode->HDisplay; + kmode->hsync_start = mode->HSyncStart; + kmode->hsync_end = mode->HSyncEnd; + kmode->htotal = mode->HTotal; + kmode->hskew = mode->HSkew; + + kmode->vdisplay = mode->VDisplay; + kmode->vsync_start = mode->VSyncStart; + kmode->vsync_end = mode->VSyncEnd; + kmode->vtotal = mode->VTotal; + kmode->vscan = mode->VScan; + + kmode->flags = mode->Flags; //& FLAG_BITS; + if (mode->name) + strncpy(kmode->name, mode->name, DRM_DISPLAY_MODE_LEN); + kmode->name[DRM_DISPLAY_MODE_LEN - 1] = 0; } @@ -231,331 +233,337 @@ static void drmmode_crtc_dpms(xf86CrtcPtr crtc, int mode) { #if 0 - xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn); -// drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; -// drmmode_ptr drmmode = drmmode_crtc->drmmode; - - /* bonghits in the randr 1.2 - uses dpms to disable crtc - bad buzz */ - if (mode == DPMSModeOff) { -// drmModeSetCrtc(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, -// 0, 0, 0, NULL, 0, NULL); - } + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn); + +// drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; +// drmmode_ptr drmmode = drmmode_crtc->drmmode; + + /* bonghits in the randr 1.2 - uses dpms to disable crtc - bad buzz */ + if (mode == DPMSModeOff) { +// drmModeSetCrtc(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, +// 0, 0, 0, NULL, 0, NULL); + } #endif } #if 0 static PixmapPtr -create_pixmap_for_fbcon(drmmode_ptr drmmode, - ScrnInfoPtr pScrn, int crtc_id) +create_pixmap_for_fbcon(drmmode_ptr drmmode, ScrnInfoPtr pScrn, int crtc_id) { - xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); - drmmode_crtc_private_ptr drmmode_crtc; - ScreenPtr pScreen = pScrn->pScreen; - PixmapPtr pixmap; - struct radeon_bo *bo; - drmModeFBPtr fbcon; - struct drm_gem_flink flink; - - drmmode_crtc = xf86_config->crtc[crtc_id]->driver_private; - - fbcon = drmModeGetFB(drmmode->fd, drmmode_crtc->mode_crtc->buffer_id); - if (fbcon == NULL) - return NULL; - - flink.handle = fbcon->handle; - if (ioctl(drmmode->fd, DRM_IOCTL_GEM_FLINK, &flink) < 0) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Couldn't flink fbcon handle\n"); - return NULL; - } - - bo = radeon_bo_open(drmmode->bufmgr, flink.name, 0, 0, 0, 0); - if (bo == NULL) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Couldn't allocate bo for fbcon handle\n"); - return NULL; - } - - pixmap = drmmode_create_bo_pixmap(pScreen, fbcon->width, fbcon->height, - fbcon->depth, fbcon->bpp, - fbcon->pitch, bo); - if (!pixmap) - return NULL; - - radeon_bo_unref(bo); - drmModeFreeFB(fbcon); - return pixmap; + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); + drmmode_crtc_private_ptr drmmode_crtc; + ScreenPtr pScreen = pScrn->pScreen; + PixmapPtr pixmap; + struct radeon_bo *bo; + drmModeFBPtr fbcon; + struct drm_gem_flink flink; + + drmmode_crtc = xf86_config->crtc[crtc_id]->driver_private; + + fbcon = drmModeGetFB(drmmode->fd, drmmode_crtc->mode_crtc->buffer_id); + if (fbcon == NULL) + return NULL; + + flink.handle = fbcon->handle; + if (ioctl(drmmode->fd, DRM_IOCTL_GEM_FLINK, &flink) < 0) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Couldn't flink fbcon handle\n"); + return NULL; + } + + bo = radeon_bo_open(drmmode->bufmgr, flink.name, 0, 0, 0, 0); + if (bo == NULL) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Couldn't allocate bo for fbcon handle\n"); + return NULL; + } + + pixmap = drmmode_create_bo_pixmap(pScreen, fbcon->width, fbcon->height, + fbcon->depth, fbcon->bpp, + fbcon->pitch, bo); + if (!pixmap) + return NULL; + + radeon_bo_unref(bo); + drmModeFreeFB(fbcon); + return pixmap; } #endif static Bool drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode, - Rotation rotation, int x, int y) + Rotation rotation, int x, int y) { - ScrnInfoPtr pScrn = crtc->scrn; - xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn); - drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; - drmmode_ptr drmmode = drmmode_crtc->drmmode; - int saved_x, saved_y; - Rotation saved_rotation; - DisplayModeRec saved_mode; - uint32_t *output_ids; - int output_count = 0; - Bool ret = TRUE; - int i; - uint32_t fb_id; - drmModeModeInfo kmode; - int height; - - height = pScrn->virtualY; - - if (drmmode->fb_id == 0) { - ret = drmModeAddFB(drmmode->fd, - pScrn->virtualX, height, - pScrn->depth, pScrn->bitsPerPixel, - drmmode->front_bo->pitch, - drmmode->front_bo->handle, - &drmmode->fb_id); - if (ret < 0) { - ErrorF("failed to add fb %d\n", ret); - return FALSE; - } + ScrnInfoPtr pScrn = crtc->scrn; + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn); + drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; + drmmode_ptr drmmode = drmmode_crtc->drmmode; + int saved_x, saved_y; + Rotation saved_rotation; + DisplayModeRec saved_mode; + uint32_t *output_ids; + int output_count = 0; + Bool ret = TRUE; + int i; + uint32_t fb_id; + drmModeModeInfo kmode; + int height; + + height = pScrn->virtualY; + + if (drmmode->fb_id == 0) { + ret = drmModeAddFB(drmmode->fd, + pScrn->virtualX, height, + pScrn->depth, pScrn->bitsPerPixel, + drmmode->front_bo->pitch, + drmmode->front_bo->handle, &drmmode->fb_id); + if (ret < 0) { + ErrorF("failed to add fb %d\n", ret); + return FALSE; + } + } + + saved_mode = crtc->mode; + saved_x = crtc->x; + saved_y = crtc->y; + saved_rotation = crtc->rotation; + + if (mode) { + crtc->mode = *mode; + crtc->x = x; + crtc->y = y; + crtc->rotation = rotation; + crtc->transformPresent = FALSE; + } + + output_ids = calloc(sizeof(uint32_t), xf86_config->num_output); + if (!output_ids) { + ret = FALSE; + goto done; + } + + if (mode) { + for (i = 0; i < xf86_config->num_output; i++) { + xf86OutputPtr output = xf86_config->output[i]; + drmmode_output_private_ptr drmmode_output; + + if (output->crtc != crtc) + continue; + + drmmode_output = output->driver_private; + output_ids[output_count] = + drmmode_output->mode_output->connector_id; + output_count++; } - saved_mode = crtc->mode; - saved_x = crtc->x; - saved_y = crtc->y; - saved_rotation = crtc->rotation; - - if (mode) { - crtc->mode = *mode; - crtc->x = x; - crtc->y = y; - crtc->rotation = rotation; - crtc->transformPresent = FALSE; - } - - output_ids = calloc(sizeof(uint32_t), xf86_config->num_output); - if (!output_ids) { - ret = FALSE; - goto done; - } - - if (mode) { - for (i = 0; i < xf86_config->num_output; i++) { - xf86OutputPtr output = xf86_config->output[i]; - drmmode_output_private_ptr drmmode_output; - - if (output->crtc != crtc) - continue; - - drmmode_output = output->driver_private; - output_ids[output_count] = drmmode_output->mode_output->connector_id; - output_count++; - } - - if (!xf86CrtcRotate(crtc)) { - goto done; - } - crtc->funcs->gamma_set(crtc, crtc->gamma_red, crtc->gamma_green, - crtc->gamma_blue, crtc->gamma_size); - - drmmode_ConvertToKMode(crtc->scrn, &kmode, mode); - - fb_id = drmmode->fb_id; - if (crtc->randr_crtc->scanout_pixmap) { - msPixmapPrivPtr ppriv = msGetPixmapPriv(drmmode, crtc->randr_crtc->scanout_pixmap); - fb_id = ppriv->fb_id; - x = y = 0; - } else if (drmmode_crtc->rotate_fb_id) { - fb_id = drmmode_crtc->rotate_fb_id; - x = y = 0; - } - ret = drmModeSetCrtc(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, - fb_id, x, y, output_ids, output_count, &kmode); - if (ret) - xf86DrvMsg(crtc->scrn->scrnIndex, X_ERROR, - "failed to set mode: %s", strerror(-ret)); - else - ret = TRUE; - - if (crtc->scrn->pScreen) - xf86CrtcSetScreenSubpixelOrder(crtc->scrn->pScreen); - /* go through all the outputs and force DPMS them back on? */ - for (i = 0; i < xf86_config->num_output; i++) { - xf86OutputPtr output = xf86_config->output[i]; - - if (output->crtc != crtc) - continue; - - output->funcs->dpms(output, DPMSModeOn); - } - } + if (!xf86CrtcRotate(crtc)) { + goto done; + } + crtc->funcs->gamma_set(crtc, crtc->gamma_red, crtc->gamma_green, + crtc->gamma_blue, crtc->gamma_size); + + drmmode_ConvertToKMode(crtc->scrn, &kmode, mode); + + fb_id = drmmode->fb_id; + if (crtc->randr_crtc->scanout_pixmap) { + msPixmapPrivPtr ppriv = + msGetPixmapPriv(drmmode, crtc->randr_crtc->scanout_pixmap); + fb_id = ppriv->fb_id; + x = y = 0; + } + else if (drmmode_crtc->rotate_fb_id) { + fb_id = drmmode_crtc->rotate_fb_id; + x = y = 0; + } + ret = drmModeSetCrtc(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, + fb_id, x, y, output_ids, output_count, &kmode); + if (ret) + xf86DrvMsg(crtc->scrn->scrnIndex, X_ERROR, + "failed to set mode: %s", strerror(-ret)); + else + ret = TRUE; + + if (crtc->scrn->pScreen) + xf86CrtcSetScreenSubpixelOrder(crtc->scrn->pScreen); + /* go through all the outputs and force DPMS them back on? */ + for (i = 0; i < xf86_config->num_output; i++) { + xf86OutputPtr output = xf86_config->output[i]; + + if (output->crtc != crtc) + continue; + + output->funcs->dpms(output, DPMSModeOn); + } + } #if 0 - if (pScrn->pScreen && - !xf86ReturnOptValBool(info->Options, OPTION_SW_CURSOR, FALSE)) - xf86_reload_cursors(pScrn->pScreen); + if (pScrn->pScreen && + !xf86ReturnOptValBool(info->Options, OPTION_SW_CURSOR, FALSE)) + xf86_reload_cursors(pScrn->pScreen); #endif -done: - if (!ret) { - crtc->x = saved_x; - crtc->y = saved_y; - crtc->rotation = saved_rotation; - crtc->mode = saved_mode; - } + done: + if (!ret) { + crtc->x = saved_x; + crtc->y = saved_y; + crtc->rotation = saved_rotation; + crtc->mode = saved_mode; + } #if defined(XF86_CRTC_VERSION) && XF86_CRTC_VERSION >= 3 - else - crtc->active = TRUE; + else + crtc->active = TRUE; #endif - return ret; + return ret; } static void -drmmode_set_cursor_colors (xf86CrtcPtr crtc, int bg, int fg) +drmmode_set_cursor_colors(xf86CrtcPtr crtc, int bg, int fg) { } static void -drmmode_set_cursor_position (xf86CrtcPtr crtc, int x, int y) +drmmode_set_cursor_position(xf86CrtcPtr crtc, int x, int y) { - drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; - drmmode_ptr drmmode = drmmode_crtc->drmmode; + drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; + drmmode_ptr drmmode = drmmode_crtc->drmmode; - drmModeMoveCursor(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, x, y); + drmModeMoveCursor(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, x, y); } static void -drmmode_load_cursor_argb (xf86CrtcPtr crtc, CARD32 *image) +drmmode_load_cursor_argb(xf86CrtcPtr crtc, CARD32 *image) { - modesettingPtr ms = modesettingPTR(crtc->scrn); - drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; - int i; - uint32_t *ptr; - uint32_t handle = drmmode_crtc->cursor_bo->handle; - int ret; - /* cursor should be mapped already */ - ptr = (uint32_t *)(drmmode_crtc->cursor_bo->ptr); - - for (i = 0; i < ms->cursor_width * ms->cursor_height; i++) - ptr[i] = image[i];// cpu_to_le32(image[i]); - - ret = drmModeSetCursor(drmmode_crtc->drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, handle, - ms->cursor_width, ms->cursor_height); - if (ret) { - xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn); - xf86CursorInfoPtr cursor_info = xf86_config->cursor_info; - - cursor_info->MaxWidth = cursor_info->MaxHeight = 0; - drmmode_crtc->drmmode->sw_cursor = TRUE; - /* fallback to swcursor */ - } + modesettingPtr ms = modesettingPTR(crtc->scrn); + drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; + int i; + uint32_t *ptr; + uint32_t handle = drmmode_crtc->cursor_bo->handle; + int ret; + + /* cursor should be mapped already */ + ptr = (uint32_t *) (drmmode_crtc->cursor_bo->ptr); + + for (i = 0; i < ms->cursor_width * ms->cursor_height; i++) + ptr[i] = image[i]; // cpu_to_le32(image[i]); + + ret = + drmModeSetCursor(drmmode_crtc->drmmode->fd, + drmmode_crtc->mode_crtc->crtc_id, handle, + ms->cursor_width, ms->cursor_height); + if (ret) { + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn); + xf86CursorInfoPtr cursor_info = xf86_config->cursor_info; + + cursor_info->MaxWidth = cursor_info->MaxHeight = 0; + drmmode_crtc->drmmode->sw_cursor = TRUE; + /* fallback to swcursor */ + } } - static void -drmmode_hide_cursor (xf86CrtcPtr crtc) +drmmode_hide_cursor(xf86CrtcPtr crtc) { - modesettingPtr ms = modesettingPTR(crtc->scrn); - drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; - drmmode_ptr drmmode = drmmode_crtc->drmmode; + modesettingPtr ms = modesettingPTR(crtc->scrn); + drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; + drmmode_ptr drmmode = drmmode_crtc->drmmode; - drmModeSetCursor(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, 0, - ms->cursor_width, ms->cursor_height); + drmModeSetCursor(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, 0, + ms->cursor_width, ms->cursor_height); } static void -drmmode_show_cursor (xf86CrtcPtr crtc) +drmmode_show_cursor(xf86CrtcPtr crtc) { - modesettingPtr ms = modesettingPTR(crtc->scrn); - drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; - drmmode_ptr drmmode = drmmode_crtc->drmmode; - uint32_t handle = drmmode_crtc->cursor_bo->handle; - static Bool use_set_cursor2 = TRUE; - - if (use_set_cursor2) { - xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn); - CursorPtr cursor = xf86_config->cursor; - int ret; - ret = drmModeSetCursor2(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, handle, ms->cursor_width, ms->cursor_height, cursor->bits->xhot, cursor->bits->yhot); - if (ret == -EINVAL) - use_set_cursor2 = FALSE; - else - return; - } - - drmModeSetCursor(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, handle, - ms->cursor_width, ms->cursor_height); + modesettingPtr ms = modesettingPTR(crtc->scrn); + drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; + drmmode_ptr drmmode = drmmode_crtc->drmmode; + uint32_t handle = drmmode_crtc->cursor_bo->handle; + static Bool use_set_cursor2 = TRUE; + + if (use_set_cursor2) { + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn); + CursorPtr cursor = xf86_config->cursor; + int ret; + + ret = + drmModeSetCursor2(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, + handle, ms->cursor_width, ms->cursor_height, + cursor->bits->xhot, cursor->bits->yhot); + if (ret == -EINVAL) + use_set_cursor2 = FALSE; + else + return; + } + + drmModeSetCursor(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, handle, + ms->cursor_width, ms->cursor_height); } static void -drmmode_crtc_gamma_set(xf86CrtcPtr crtc, uint16_t *red, uint16_t *green, - uint16_t *blue, int size) +drmmode_crtc_gamma_set(xf86CrtcPtr crtc, uint16_t * red, uint16_t * green, + uint16_t * blue, int size) { - drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; - drmmode_ptr drmmode = drmmode_crtc->drmmode; + drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; + drmmode_ptr drmmode = drmmode_crtc->drmmode; - drmModeCrtcSetGamma(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, - size, red, green, blue); + drmModeCrtcSetGamma(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, + size, red, green, blue); } static Bool drmmode_set_scanout_pixmap(xf86CrtcPtr crtc, PixmapPtr ppix) { - drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; - drmmode_ptr drmmode = drmmode_crtc->drmmode; - msPixmapPrivPtr ppriv; - void *ptr; - - if (!ppix) { - if (crtc->randr_crtc->scanout_pixmap) { - ppriv = msGetPixmapPriv(drmmode, crtc->randr_crtc->scanout_pixmap); - drmModeRmFB(drmmode->fd, ppriv->fb_id); - } - if (drmmode_crtc->slave_damage) { - DamageUnregister(drmmode_crtc->slave_damage); - drmmode_crtc->slave_damage = NULL; - } - return TRUE; - } - - ppriv = msGetPixmapPriv(drmmode, ppix); - if (!drmmode_crtc->slave_damage) { - drmmode_crtc->slave_damage = DamageCreate(NULL, NULL, - DamageReportNone, - TRUE, - crtc->randr_crtc->pScreen, - NULL); - } - ptr = drmmode_map_slave_bo(drmmode, ppriv); - ppix->devPrivate.ptr = ptr; - DamageRegister(&ppix->drawable, drmmode_crtc->slave_damage); - - if (ppriv->fb_id == 0) { - drmModeAddFB(drmmode->fd, ppix->drawable.width, - ppix->drawable.height, - ppix->drawable.depth, - ppix->drawable.bitsPerPixel, - ppix->devKind, - ppriv->backing_bo->handle, - &ppriv->fb_id); - } - return TRUE; + drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; + drmmode_ptr drmmode = drmmode_crtc->drmmode; + msPixmapPrivPtr ppriv; + void *ptr; + + if (!ppix) { + if (crtc->randr_crtc->scanout_pixmap) { + ppriv = msGetPixmapPriv(drmmode, crtc->randr_crtc->scanout_pixmap); + drmModeRmFB(drmmode->fd, ppriv->fb_id); + } + if (drmmode_crtc->slave_damage) { + DamageUnregister(drmmode_crtc->slave_damage); + drmmode_crtc->slave_damage = NULL; + } + return TRUE; + } + + ppriv = msGetPixmapPriv(drmmode, ppix); + if (!drmmode_crtc->slave_damage) { + drmmode_crtc->slave_damage = DamageCreate(NULL, NULL, + DamageReportNone, + TRUE, + crtc->randr_crtc->pScreen, + NULL); + } + ptr = drmmode_map_slave_bo(drmmode, ppriv); + ppix->devPrivate.ptr = ptr; + DamageRegister(&ppix->drawable, drmmode_crtc->slave_damage); + + if (ppriv->fb_id == 0) { + drmModeAddFB(drmmode->fd, ppix->drawable.width, + ppix->drawable.height, + ppix->drawable.depth, + ppix->drawable.bitsPerPixel, + ppix->devKind, ppriv->backing_bo->handle, &ppriv->fb_id); + } + return TRUE; } -static void *drmmode_shadow_allocate(xf86CrtcPtr crtc, int width, int height) +static void * +drmmode_shadow_allocate(xf86CrtcPtr crtc, int width, int height) { - return NULL; + return NULL; } -static PixmapPtr drmmode_shadow_create(xf86CrtcPtr crtc, void *data, int width, - int height) +static PixmapPtr +drmmode_shadow_create(xf86CrtcPtr crtc, void *data, int width, int height) { - return NULL; + return NULL; } static const xf86CrtcFuncsRec drmmode_crtc_funcs = { @@ -568,7 +576,7 @@ static const xf86CrtcFuncsRec drmmode_crtc_funcs = { .load_cursor_argb = drmmode_load_cursor_argb, .gamma_set = drmmode_crtc_gamma_set, - .destroy = NULL, /* XXX */ + .destroy = NULL, /* XXX */ .set_scanout_pixmap = drmmode_set_scanout_pixmap, .shadow_allocate = drmmode_shadow_allocate, .shadow_create = drmmode_shadow_create, @@ -577,222 +585,224 @@ static const xf86CrtcFuncsRec drmmode_crtc_funcs = { static void drmmode_crtc_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int num) { - xf86CrtcPtr crtc; - drmmode_crtc_private_ptr drmmode_crtc; - - crtc = xf86CrtcCreate(pScrn, &drmmode_crtc_funcs); - if (crtc == NULL) - return; - - drmmode_crtc = xnfcalloc(sizeof(drmmode_crtc_private_rec), 1); - drmmode_crtc->mode_crtc = drmModeGetCrtc(drmmode->fd, drmmode->mode_res->crtcs[num]); - drmmode_crtc->drmmode = drmmode; - crtc->driver_private = drmmode_crtc; + xf86CrtcPtr crtc; + drmmode_crtc_private_ptr drmmode_crtc; + + crtc = xf86CrtcCreate(pScrn, &drmmode_crtc_funcs); + if (crtc == NULL) + return; + + drmmode_crtc = xnfcalloc(sizeof(drmmode_crtc_private_rec), 1); + drmmode_crtc->mode_crtc = + drmModeGetCrtc(drmmode->fd, drmmode->mode_res->crtcs[num]); + drmmode_crtc->drmmode = drmmode; + crtc->driver_private = drmmode_crtc; } static xf86OutputStatus drmmode_output_detect(xf86OutputPtr output) { - /* go to the hw and retrieve a new output struct */ - drmmode_output_private_ptr drmmode_output = output->driver_private; - drmmode_ptr drmmode = drmmode_output->drmmode; - xf86OutputStatus status; - drmModeFreeConnector(drmmode_output->mode_output); - - drmmode_output->mode_output = drmModeGetConnector(drmmode->fd, drmmode_output->output_id); - if (!drmmode_output->mode_output) - return XF86OutputStatusDisconnected; - - switch (drmmode_output->mode_output->connection) { - case DRM_MODE_CONNECTED: - status = XF86OutputStatusConnected; - break; - case DRM_MODE_DISCONNECTED: - status = XF86OutputStatusDisconnected; - break; - default: - case DRM_MODE_UNKNOWNCONNECTION: - status = XF86OutputStatusUnknown; - break; - } - return status; + /* go to the hw and retrieve a new output struct */ + drmmode_output_private_ptr drmmode_output = output->driver_private; + drmmode_ptr drmmode = drmmode_output->drmmode; + xf86OutputStatus status; + + drmModeFreeConnector(drmmode_output->mode_output); + + drmmode_output->mode_output = + drmModeGetConnector(drmmode->fd, drmmode_output->output_id); + if (!drmmode_output->mode_output) + return XF86OutputStatusDisconnected; + + switch (drmmode_output->mode_output->connection) { + case DRM_MODE_CONNECTED: + status = XF86OutputStatusConnected; + break; + case DRM_MODE_DISCONNECTED: + status = XF86OutputStatusDisconnected; + break; + default: + case DRM_MODE_UNKNOWNCONNECTION: + status = XF86OutputStatusUnknown; + break; + } + return status; } static Bool drmmode_output_mode_valid(xf86OutputPtr output, DisplayModePtr pModes) { - return MODE_OK; + return MODE_OK; } static Bool has_panel_fitter(xf86OutputPtr output) { - drmmode_output_private_ptr drmmode_output = output->driver_private; - drmModeConnectorPtr koutput = drmmode_output->mode_output; - drmmode_ptr drmmode = drmmode_output->drmmode; - int i; - - /* Presume that if the output supports scaling, then we have a - * panel fitter capable of adjust any mode to suit. - */ - for (i = 0; i < koutput->count_props; i++) { - drmModePropertyPtr props; - Bool found = FALSE; - - props = drmModeGetProperty(drmmode->fd, koutput->props[i]); - if (props) { - found = strcmp(props->name, "scaling mode") == 0; - drmModeFreeProperty(props); - } - - if (found) - return TRUE; - } - - return FALSE; + drmmode_output_private_ptr drmmode_output = output->driver_private; + drmModeConnectorPtr koutput = drmmode_output->mode_output; + drmmode_ptr drmmode = drmmode_output->drmmode; + int i; + + /* Presume that if the output supports scaling, then we have a + * panel fitter capable of adjust any mode to suit. + */ + for (i = 0; i < koutput->count_props; i++) { + drmModePropertyPtr props; + Bool found = FALSE; + + props = drmModeGetProperty(drmmode->fd, koutput->props[i]); + if (props) { + found = strcmp(props->name, "scaling mode") == 0; + drmModeFreeProperty(props); + } + + if (found) + return TRUE; + } + + return FALSE; } static DisplayModePtr -drmmode_output_add_gtf_modes(xf86OutputPtr output, - DisplayModePtr Modes) +drmmode_output_add_gtf_modes(xf86OutputPtr output, DisplayModePtr Modes) { - xf86MonPtr mon = output->MonInfo; - DisplayModePtr i, m, preferred = NULL; - int max_x = 0, max_y = 0; - float max_vrefresh = 0.0; - - if (mon && GTF_SUPPORTED(mon->features.msc)) - return Modes; - - if (!has_panel_fitter(output)) - return Modes; - - for (m = Modes; m; m = m->next) { - if (m->type & M_T_PREFERRED) - preferred = m; - max_x = max(max_x, m->HDisplay); - max_y = max(max_y, m->VDisplay); - max_vrefresh = max(max_vrefresh, xf86ModeVRefresh(m)); - } - - max_vrefresh = max(max_vrefresh, 60.0); - max_vrefresh *= (1 + SYNC_TOLERANCE); - - m = xf86GetDefaultModes(); - xf86ValidateModesSize(output->scrn, m, max_x, max_y, 0); - - for (i = m; i; i = i->next) { - if (xf86ModeVRefresh(i) > max_vrefresh) - i->status = MODE_VSYNC; - if (preferred && - i->HDisplay >= preferred->HDisplay && - i->VDisplay >= preferred->VDisplay && - xf86ModeVRefresh(i) >= xf86ModeVRefresh(preferred)) - i->status = MODE_VSYNC; - } - - xf86PruneInvalidModes(output->scrn, &m, FALSE); - - return xf86ModesAdd(Modes, m); + xf86MonPtr mon = output->MonInfo; + DisplayModePtr i, m, preferred = NULL; + int max_x = 0, max_y = 0; + float max_vrefresh = 0.0; + + if (mon && GTF_SUPPORTED(mon->features.msc)) + return Modes; + + if (!has_panel_fitter(output)) + return Modes; + + for (m = Modes; m; m = m->next) { + if (m->type & M_T_PREFERRED) + preferred = m; + max_x = max(max_x, m->HDisplay); + max_y = max(max_y, m->VDisplay); + max_vrefresh = max(max_vrefresh, xf86ModeVRefresh(m)); + } + + max_vrefresh = max(max_vrefresh, 60.0); + max_vrefresh *= (1 + SYNC_TOLERANCE); + + m = xf86GetDefaultModes(); + xf86ValidateModesSize(output->scrn, m, max_x, max_y, 0); + + for (i = m; i; i = i->next) { + if (xf86ModeVRefresh(i) > max_vrefresh) + i->status = MODE_VSYNC; + if (preferred && + i->HDisplay >= preferred->HDisplay && + i->VDisplay >= preferred->VDisplay && + xf86ModeVRefresh(i) >= xf86ModeVRefresh(preferred)) + i->status = MODE_VSYNC; + } + + xf86PruneInvalidModes(output->scrn, &m, FALSE); + + return xf86ModesAdd(Modes, m); } static DisplayModePtr drmmode_output_get_modes(xf86OutputPtr output) { - drmmode_output_private_ptr drmmode_output = output->driver_private; - drmModeConnectorPtr koutput = drmmode_output->mode_output; - drmmode_ptr drmmode = drmmode_output->drmmode; - int i; - DisplayModePtr Modes = NULL, Mode; - drmModePropertyPtr props; - xf86MonPtr mon = NULL; - - if (!koutput) - return NULL; - - /* look for an EDID property */ - for (i = 0; i < koutput->count_props; i++) { - props = drmModeGetProperty(drmmode->fd, koutput->props[i]); - if (props && (props->flags & DRM_MODE_PROP_BLOB)) { - if (!strcmp(props->name, "EDID")) { - if (drmmode_output->edid_blob) - drmModeFreePropertyBlob(drmmode_output->edid_blob); - drmmode_output->edid_blob = drmModeGetPropertyBlob(drmmode->fd, koutput->prop_values[i]); - } - drmModeFreeProperty(props); - } - } - - if (drmmode_output->edid_blob) { - mon = xf86InterpretEDID(output->scrn->scrnIndex, - drmmode_output->edid_blob->data); - if (mon && drmmode_output->edid_blob->length > 128) - mon->flags |= MONITOR_EDID_COMPLETE_RAWDATA; - } - xf86OutputSetEDID(output, mon); - - /* modes should already be available */ - for (i = 0; i < koutput->count_modes; i++) { - Mode = xnfalloc(sizeof(DisplayModeRec)); - - drmmode_ConvertFromKMode(output->scrn, &koutput->modes[i], Mode); - Modes = xf86ModesAdd(Modes, Mode); - - } - - return drmmode_output_add_gtf_modes(output, Modes); + drmmode_output_private_ptr drmmode_output = output->driver_private; + drmModeConnectorPtr koutput = drmmode_output->mode_output; + drmmode_ptr drmmode = drmmode_output->drmmode; + int i; + DisplayModePtr Modes = NULL, Mode; + drmModePropertyPtr props; + xf86MonPtr mon = NULL; + + if (!koutput) + return NULL; + + /* look for an EDID property */ + for (i = 0; i < koutput->count_props; i++) { + props = drmModeGetProperty(drmmode->fd, koutput->props[i]); + if (props && (props->flags & DRM_MODE_PROP_BLOB)) { + if (!strcmp(props->name, "EDID")) { + if (drmmode_output->edid_blob) + drmModeFreePropertyBlob(drmmode_output->edid_blob); + drmmode_output->edid_blob = + drmModeGetPropertyBlob(drmmode->fd, + koutput->prop_values[i]); + } + drmModeFreeProperty(props); + } + } + + if (drmmode_output->edid_blob) { + mon = xf86InterpretEDID(output->scrn->scrnIndex, + drmmode_output->edid_blob->data); + if (mon && drmmode_output->edid_blob->length > 128) + mon->flags |= MONITOR_EDID_COMPLETE_RAWDATA; + } + xf86OutputSetEDID(output, mon); + + /* modes should already be available */ + for (i = 0; i < koutput->count_modes; i++) { + Mode = xnfalloc(sizeof(DisplayModeRec)); + + drmmode_ConvertFromKMode(output->scrn, &koutput->modes[i], Mode); + Modes = xf86ModesAdd(Modes, Mode); + + } + + return drmmode_output_add_gtf_modes(output, Modes); } static void drmmode_output_destroy(xf86OutputPtr output) { - drmmode_output_private_ptr drmmode_output = output->driver_private; - int i; - - if (drmmode_output->edid_blob) - drmModeFreePropertyBlob(drmmode_output->edid_blob); - for (i = 0; i < drmmode_output->num_props; i++) { - drmModeFreeProperty(drmmode_output->props[i].mode_prop); - free(drmmode_output->props[i].atoms); - } - free(drmmode_output->props); - for (i = 0; i < drmmode_output->mode_output->count_encoders; i++) { - drmModeFreeEncoder(drmmode_output->mode_encoders[i]); - } - free(drmmode_output->mode_encoders); - drmModeFreeConnector(drmmode_output->mode_output); - free(drmmode_output); - output->driver_private = NULL; + drmmode_output_private_ptr drmmode_output = output->driver_private; + int i; + + if (drmmode_output->edid_blob) + drmModeFreePropertyBlob(drmmode_output->edid_blob); + for (i = 0; i < drmmode_output->num_props; i++) { + drmModeFreeProperty(drmmode_output->props[i].mode_prop); + free(drmmode_output->props[i].atoms); + } + free(drmmode_output->props); + for (i = 0; i < drmmode_output->mode_output->count_encoders; i++) { + drmModeFreeEncoder(drmmode_output->mode_encoders[i]); + } + free(drmmode_output->mode_encoders); + drmModeFreeConnector(drmmode_output->mode_output); + free(drmmode_output); + output->driver_private = NULL; } static void drmmode_output_dpms(xf86OutputPtr output, int mode) { - drmmode_output_private_ptr drmmode_output = output->driver_private; - drmModeConnectorPtr koutput = drmmode_output->mode_output; - drmmode_ptr drmmode = drmmode_output->drmmode; + drmmode_output_private_ptr drmmode_output = output->driver_private; + drmModeConnectorPtr koutput = drmmode_output->mode_output; + drmmode_ptr drmmode = drmmode_output->drmmode; - if (!koutput) - return; + if (!koutput) + return; - drmModeConnectorSetProperty(drmmode->fd, koutput->connector_id, - drmmode_output->dpms_enum_id, mode); - return; + drmModeConnectorSetProperty(drmmode->fd, koutput->connector_id, + drmmode_output->dpms_enum_id, mode); + return; } - static Bool drmmode_property_ignore(drmModePropertyPtr prop) { if (!prop) - return TRUE; + return TRUE; /* ignore blob prop */ if (prop->flags & DRM_MODE_PROP_BLOB) - return TRUE; + return TRUE; /* ignore standard property */ - if (!strcmp(prop->name, "EDID") || - !strcmp(prop->name, "DPMS")) - return TRUE; + if (!strcmp(prop->name, "EDID") || !strcmp(prop->name, "DPMS")) + return TRUE; return FALSE; } @@ -806,128 +816,143 @@ drmmode_output_create_resources(xf86OutputPtr output) drmModePropertyPtr drmmode_prop; int i, j, err; - drmmode_output->props = calloc(mode_output->count_props, sizeof(drmmode_prop_rec)); + drmmode_output->props = + calloc(mode_output->count_props, sizeof(drmmode_prop_rec)); if (!drmmode_output->props) - return; - + return; + drmmode_output->num_props = 0; for (i = 0, j = 0; i < mode_output->count_props; i++) { - drmmode_prop = drmModeGetProperty(drmmode->fd, mode_output->props[i]); - if (drmmode_property_ignore(drmmode_prop)) { - drmModeFreeProperty(drmmode_prop); - continue; - } - drmmode_output->props[j].mode_prop = drmmode_prop; - drmmode_output->props[j].value = mode_output->prop_values[i]; - drmmode_output->num_props++; - j++; + drmmode_prop = drmModeGetProperty(drmmode->fd, mode_output->props[i]); + if (drmmode_property_ignore(drmmode_prop)) { + drmModeFreeProperty(drmmode_prop); + continue; + } + drmmode_output->props[j].mode_prop = drmmode_prop; + drmmode_output->props[j].value = mode_output->prop_values[i]; + drmmode_output->num_props++; + j++; } for (i = 0; i < drmmode_output->num_props; i++) { - drmmode_prop_ptr p = &drmmode_output->props[i]; - drmmode_prop = p->mode_prop; - - if (drmmode_prop->flags & DRM_MODE_PROP_RANGE) { - INT32 prop_range[2]; - INT32 value = p->value; - - p->num_atoms = 1; - p->atoms = calloc(p->num_atoms, sizeof(Atom)); - if (!p->atoms) - continue; - p->atoms[0] = MakeAtom(drmmode_prop->name, strlen(drmmode_prop->name), TRUE); - prop_range[0] = drmmode_prop->values[0]; - prop_range[1] = drmmode_prop->values[1]; - err = RRConfigureOutputProperty(output->randr_output, p->atoms[0], - FALSE, TRUE, - drmmode_prop->flags & DRM_MODE_PROP_IMMUTABLE ? TRUE : FALSE, - 2, prop_range); - if (err != 0) { - xf86DrvMsg(output->scrn->scrnIndex, X_ERROR, - "RRConfigureOutputProperty error, %d\n", err); - } - err = RRChangeOutputProperty(output->randr_output, p->atoms[0], - XA_INTEGER, 32, PropModeReplace, 1, &value, FALSE, TRUE); - if (err != 0) { - xf86DrvMsg(output->scrn->scrnIndex, X_ERROR, - "RRChangeOutputProperty error, %d\n", err); - } - } else if (drmmode_prop->flags & DRM_MODE_PROP_ENUM) { - p->num_atoms = drmmode_prop->count_enums + 1; - p->atoms = calloc(p->num_atoms, sizeof(Atom)); - if (!p->atoms) - continue; - p->atoms[0] = MakeAtom(drmmode_prop->name, strlen(drmmode_prop->name), TRUE); - for (j = 1; j <= drmmode_prop->count_enums; j++) { - struct drm_mode_property_enum *e = &drmmode_prop->enums[j-1]; - p->atoms[j] = MakeAtom(e->name, strlen(e->name), TRUE); - } - err = RRConfigureOutputProperty(output->randr_output, p->atoms[0], - FALSE, FALSE, - drmmode_prop->flags & DRM_MODE_PROP_IMMUTABLE ? TRUE : FALSE, - p->num_atoms - 1, (INT32 *)&p->atoms[1]); - if (err != 0) { - xf86DrvMsg(output->scrn->scrnIndex, X_ERROR, - "RRConfigureOutputProperty error, %d\n", err); - } - for (j = 0; j < drmmode_prop->count_enums; j++) - if (drmmode_prop->enums[j].value == p->value) - break; - /* there's always a matching value */ - err = RRChangeOutputProperty(output->randr_output, p->atoms[0], - XA_ATOM, 32, PropModeReplace, 1, &p->atoms[j+1], FALSE, TRUE); - if (err != 0) { - xf86DrvMsg(output->scrn->scrnIndex, X_ERROR, - "RRChangeOutputProperty error, %d\n", err); - } - } + drmmode_prop_ptr p = &drmmode_output->props[i]; + + drmmode_prop = p->mode_prop; + + if (drmmode_prop->flags & DRM_MODE_PROP_RANGE) { + INT32 prop_range[2]; + INT32 value = p->value; + + p->num_atoms = 1; + p->atoms = calloc(p->num_atoms, sizeof(Atom)); + if (!p->atoms) + continue; + p->atoms[0] = + MakeAtom(drmmode_prop->name, strlen(drmmode_prop->name), TRUE); + prop_range[0] = drmmode_prop->values[0]; + prop_range[1] = drmmode_prop->values[1]; + err = RRConfigureOutputProperty(output->randr_output, p->atoms[0], + FALSE, TRUE, + drmmode_prop-> + flags & DRM_MODE_PROP_IMMUTABLE ? + TRUE : FALSE, 2, prop_range); + if (err != 0) { + xf86DrvMsg(output->scrn->scrnIndex, X_ERROR, + "RRConfigureOutputProperty error, %d\n", err); + } + err = RRChangeOutputProperty(output->randr_output, p->atoms[0], + XA_INTEGER, 32, PropModeReplace, 1, + &value, FALSE, TRUE); + if (err != 0) { + xf86DrvMsg(output->scrn->scrnIndex, X_ERROR, + "RRChangeOutputProperty error, %d\n", err); + } + } + else if (drmmode_prop->flags & DRM_MODE_PROP_ENUM) { + p->num_atoms = drmmode_prop->count_enums + 1; + p->atoms = calloc(p->num_atoms, sizeof(Atom)); + if (!p->atoms) + continue; + p->atoms[0] = + MakeAtom(drmmode_prop->name, strlen(drmmode_prop->name), TRUE); + for (j = 1; j <= drmmode_prop->count_enums; j++) { + struct drm_mode_property_enum *e = &drmmode_prop->enums[j - 1]; + + p->atoms[j] = MakeAtom(e->name, strlen(e->name), TRUE); + } + err = RRConfigureOutputProperty(output->randr_output, p->atoms[0], + FALSE, FALSE, + drmmode_prop-> + flags & DRM_MODE_PROP_IMMUTABLE ? + TRUE : FALSE, p->num_atoms - 1, + (INT32 *) &p->atoms[1]); + if (err != 0) { + xf86DrvMsg(output->scrn->scrnIndex, X_ERROR, + "RRConfigureOutputProperty error, %d\n", err); + } + for (j = 0; j < drmmode_prop->count_enums; j++) + if (drmmode_prop->enums[j].value == p->value) + break; + /* there's always a matching value */ + err = RRChangeOutputProperty(output->randr_output, p->atoms[0], + XA_ATOM, 32, PropModeReplace, 1, + &p->atoms[j + 1], FALSE, TRUE); + if (err != 0) { + xf86DrvMsg(output->scrn->scrnIndex, X_ERROR, + "RRChangeOutputProperty error, %d\n", err); + } + } } } static Bool drmmode_output_set_property(xf86OutputPtr output, Atom property, - RRPropertyValuePtr value) + RRPropertyValuePtr value) { drmmode_output_private_ptr drmmode_output = output->driver_private; drmmode_ptr drmmode = drmmode_output->drmmode; int i; for (i = 0; i < drmmode_output->num_props; i++) { - drmmode_prop_ptr p = &drmmode_output->props[i]; - - if (p->atoms[0] != property) - continue; - - if (p->mode_prop->flags & DRM_MODE_PROP_RANGE) { - uint32_t val; - - if (value->type != XA_INTEGER || value->format != 32 || - value->size != 1) - return FALSE; - val = *(uint32_t *)value->data; - - drmModeConnectorSetProperty(drmmode->fd, drmmode_output->output_id, - p->mode_prop->prop_id, (uint64_t)val); - return TRUE; - } else if (p->mode_prop->flags & DRM_MODE_PROP_ENUM) { - Atom atom; - const char *name; - int j; - - if (value->type != XA_ATOM || value->format != 32 || value->size != 1) - return FALSE; - memcpy(&atom, value->data, 4); - name = NameForAtom(atom); - - /* search for matching name string, then set its value down */ - for (j = 0; j < p->mode_prop->count_enums; j++) { - if (!strcmp(p->mode_prop->enums[j].name, name)) { - drmModeConnectorSetProperty(drmmode->fd, drmmode_output->output_id, - p->mode_prop->prop_id, p->mode_prop->enums[j].value); - return TRUE; - } - } - } + drmmode_prop_ptr p = &drmmode_output->props[i]; + + if (p->atoms[0] != property) + continue; + + if (p->mode_prop->flags & DRM_MODE_PROP_RANGE) { + uint32_t val; + + if (value->type != XA_INTEGER || value->format != 32 || + value->size != 1) + return FALSE; + val = *(uint32_t *) value->data; + + drmModeConnectorSetProperty(drmmode->fd, drmmode_output->output_id, + p->mode_prop->prop_id, (uint64_t) val); + return TRUE; + } + else if (p->mode_prop->flags & DRM_MODE_PROP_ENUM) { + Atom atom; + const char *name; + int j; + + if (value->type != XA_ATOM || value->format != 32 || + value->size != 1) + return FALSE; + memcpy(&atom, value->data, 4); + name = NameForAtom(atom); + + /* search for matching name string, then set its value down */ + for (j = 0; j < p->mode_prop->count_enums; j++) { + if (!strcmp(p->mode_prop->enums[j].name, name)) { + drmModeConnectorSetProperty(drmmode->fd, + drmmode_output->output_id, + p->mode_prop->prop_id, + p->mode_prop->enums[j].value); + return TRUE; + } + } + } } return TRUE; @@ -951,402 +976,420 @@ static const xf86OutputFuncsRec drmmode_output_funcs = { .destroy = drmmode_output_destroy }; -static int subpixel_conv_table[7] = { 0, SubPixelUnknown, - SubPixelHorizontalRGB, - SubPixelHorizontalBGR, - SubPixelVerticalRGB, - SubPixelVerticalBGR, - SubPixelNone }; - -static const char * const output_names[] = { "None", - "VGA", - "DVI", - "DVI", - "DVI", - "Composite", - "S-video", - "LVDS", - "CTV", - "DIN", - "DisplayPort", - "HDMI", - "HDMI", - "TV", - "eDP", - "Virtual", - "DSI", +static int subpixel_conv_table[7] = { + 0, + SubPixelUnknown, + SubPixelHorizontalRGB, + SubPixelHorizontalBGR, + SubPixelVerticalRGB, + SubPixelVerticalBGR, + SubPixelNone +}; + +static const char *const output_names[] = { + "None", + "VGA", + "DVI", + "DVI", + "DVI", + "Composite", + "S-video", + "LVDS", + "CTV", + "DIN", + "DisplayPort", + "HDMI", + "HDMI", + "TV", + "eDP", + "Virtual", + "DSI", }; static void -drmmode_output_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int num, int *num_dvi, int *num_hdmi) +drmmode_output_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int num, + int *num_dvi, int *num_hdmi) { - xf86OutputPtr output; - drmModeConnectorPtr koutput; - drmModeEncoderPtr *kencoders = NULL; - drmmode_output_private_ptr drmmode_output; - drmModePropertyPtr props; - char name[32]; - int i; - - koutput = drmModeGetConnector(drmmode->fd, drmmode->mode_res->connectors[num]); - if (!koutput) - return; - - kencoders = calloc(sizeof(drmModeEncoderPtr), koutput->count_encoders); - if (!kencoders) { - goto out_free_encoders; - } - - for (i = 0; i < koutput->count_encoders; i++) { - kencoders[i] = drmModeGetEncoder(drmmode->fd, koutput->encoders[i]); - if (!kencoders[i]) { - goto out_free_encoders; - } - } - - /* need to do smart conversion here for compat with non-kms ATI driver */ - if (koutput->connector_type >= MS_ARRAY_SIZE(output_names)) - snprintf(name, 32, "Unknown-%d", koutput->connector_type_id - 1); - else if (pScrn->is_gpu) - snprintf(name, 32, "%s-%d-%d", output_names[koutput->connector_type], pScrn->scrnIndex - GPU_SCREEN_OFFSET + 1, koutput->connector_type_id - 1); - else - snprintf(name, 32, "%s-%d", output_names[koutput->connector_type], koutput->connector_type_id - 1); - - output = xf86OutputCreate (pScrn, &drmmode_output_funcs, name); - if (!output) { - goto out_free_encoders; - } - - drmmode_output = calloc(sizeof(drmmode_output_private_rec), 1); - if (!drmmode_output) { - xf86OutputDestroy(output); - goto out_free_encoders; - } - - drmmode_output->output_id = drmmode->mode_res->connectors[num]; - drmmode_output->mode_output = koutput; - drmmode_output->mode_encoders = kencoders; - drmmode_output->drmmode = drmmode; - output->mm_width = koutput->mmWidth; - output->mm_height = koutput->mmHeight; - - output->subpixel_order = subpixel_conv_table[koutput->subpixel]; - output->interlaceAllowed = TRUE; - output->doubleScanAllowed = TRUE; - output->driver_private = drmmode_output; - - output->possible_crtcs = 0x7f; - for (i = 0; i < koutput->count_encoders; i++) { - output->possible_crtcs &= kencoders[i]->possible_crtcs; - } - /* work out the possible clones later */ - output->possible_clones = 0; - - for (i = 0; i < koutput->count_props; i++) { - props = drmModeGetProperty(drmmode->fd, koutput->props[i]); - if (props && (props->flags & DRM_MODE_PROP_ENUM)) { - if (!strcmp(props->name, "DPMS")) { - drmmode_output->dpms_enum_id = koutput->props[i]; - drmModeFreeProperty(props); - break; - } - drmModeFreeProperty(props); - } - } - - return; -out_free_encoders: - if (kencoders){ - for (i = 0; i < koutput->count_encoders; i++) - drmModeFreeEncoder(kencoders[i]); - free(kencoders); - } - drmModeFreeConnector(koutput); - + xf86OutputPtr output; + drmModeConnectorPtr koutput; + drmModeEncoderPtr *kencoders = NULL; + drmmode_output_private_ptr drmmode_output; + drmModePropertyPtr props; + char name[32]; + int i; + + koutput = + drmModeGetConnector(drmmode->fd, drmmode->mode_res->connectors[num]); + if (!koutput) + return; + + kencoders = calloc(sizeof(drmModeEncoderPtr), koutput->count_encoders); + if (!kencoders) { + goto out_free_encoders; + } + + for (i = 0; i < koutput->count_encoders; i++) { + kencoders[i] = drmModeGetEncoder(drmmode->fd, koutput->encoders[i]); + if (!kencoders[i]) { + goto out_free_encoders; + } + } + + /* need to do smart conversion here for compat with non-kms ATI driver */ + if (koutput->connector_type >= MS_ARRAY_SIZE(output_names)) + snprintf(name, 32, "Unknown-%d", koutput->connector_type_id - 1); + else if (pScrn->is_gpu) + snprintf(name, 32, "%s-%d-%d", output_names[koutput->connector_type], + pScrn->scrnIndex - GPU_SCREEN_OFFSET + 1, + koutput->connector_type_id - 1); + else + snprintf(name, 32, "%s-%d", output_names[koutput->connector_type], + koutput->connector_type_id - 1); + + output = xf86OutputCreate(pScrn, &drmmode_output_funcs, name); + if (!output) { + goto out_free_encoders; + } + + drmmode_output = calloc(sizeof(drmmode_output_private_rec), 1); + if (!drmmode_output) { + xf86OutputDestroy(output); + goto out_free_encoders; + } + + drmmode_output->output_id = drmmode->mode_res->connectors[num]; + drmmode_output->mode_output = koutput; + drmmode_output->mode_encoders = kencoders; + drmmode_output->drmmode = drmmode; + output->mm_width = koutput->mmWidth; + output->mm_height = koutput->mmHeight; + + output->subpixel_order = subpixel_conv_table[koutput->subpixel]; + output->interlaceAllowed = TRUE; + output->doubleScanAllowed = TRUE; + output->driver_private = drmmode_output; + + output->possible_crtcs = 0x7f; + for (i = 0; i < koutput->count_encoders; i++) { + output->possible_crtcs &= kencoders[i]->possible_crtcs; + } + /* work out the possible clones later */ + output->possible_clones = 0; + + for (i = 0; i < koutput->count_props; i++) { + props = drmModeGetProperty(drmmode->fd, koutput->props[i]); + if (props && (props->flags & DRM_MODE_PROP_ENUM)) { + if (!strcmp(props->name, "DPMS")) { + drmmode_output->dpms_enum_id = koutput->props[i]; + drmModeFreeProperty(props); + break; + } + drmModeFreeProperty(props); + } + } + + return; + out_free_encoders: + if (kencoders) { + for (i = 0; i < koutput->count_encoders; i++) + drmModeFreeEncoder(kencoders[i]); + free(kencoders); + } + drmModeFreeConnector(koutput); + } -static uint32_t find_clones(ScrnInfoPtr scrn, xf86OutputPtr output) +static uint32_t +find_clones(ScrnInfoPtr scrn, xf86OutputPtr output) { - drmmode_output_private_ptr drmmode_output = output->driver_private, clone_drmout; - int i; - xf86OutputPtr clone_output; - xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); - int index_mask = 0; - - if (drmmode_output->enc_clone_mask == 0) - return index_mask; - - for (i = 0; i < xf86_config->num_output; i++) { - clone_output = xf86_config->output[i]; - clone_drmout = clone_output->driver_private; - if (output == clone_output) - continue; - - if (clone_drmout->enc_mask == 0) - continue; - if (drmmode_output->enc_clone_mask == clone_drmout->enc_mask) - index_mask |= (1 << i); - } - return index_mask; + drmmode_output_private_ptr drmmode_output = + output->driver_private, clone_drmout; + int i; + xf86OutputPtr clone_output; + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); + int index_mask = 0; + + if (drmmode_output->enc_clone_mask == 0) + return index_mask; + + for (i = 0; i < xf86_config->num_output; i++) { + clone_output = xf86_config->output[i]; + clone_drmout = clone_output->driver_private; + if (output == clone_output) + continue; + + if (clone_drmout->enc_mask == 0) + continue; + if (drmmode_output->enc_clone_mask == clone_drmout->enc_mask) + index_mask |= (1 << i); + } + return index_mask; } - static void drmmode_clones_init(ScrnInfoPtr scrn, drmmode_ptr drmmode) { - int i, j; - xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); - - for (i = 0; i < xf86_config->num_output; i++) { - xf86OutputPtr output = xf86_config->output[i]; - drmmode_output_private_ptr drmmode_output; - - drmmode_output = output->driver_private; - drmmode_output->enc_clone_mask = 0xff; - /* and all the possible encoder clones for this output together */ - for (j = 0; j < drmmode_output->mode_output->count_encoders; j++) - { - int k; - for (k = 0; k < drmmode->mode_res->count_encoders; k++) { - if (drmmode->mode_res->encoders[k] == drmmode_output->mode_encoders[j]->encoder_id) - drmmode_output->enc_mask |= (1 << k); - } - - drmmode_output->enc_clone_mask &= drmmode_output->mode_encoders[j]->possible_clones; - } - } - - for (i = 0; i < xf86_config->num_output; i++) { - xf86OutputPtr output = xf86_config->output[i]; - output->possible_clones = find_clones(scrn, output); - } + int i, j; + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); + + for (i = 0; i < xf86_config->num_output; i++) { + xf86OutputPtr output = xf86_config->output[i]; + drmmode_output_private_ptr drmmode_output; + + drmmode_output = output->driver_private; + drmmode_output->enc_clone_mask = 0xff; + /* and all the possible encoder clones for this output together */ + for (j = 0; j < drmmode_output->mode_output->count_encoders; j++) { + int k; + + for (k = 0; k < drmmode->mode_res->count_encoders; k++) { + if (drmmode->mode_res->encoders[k] == + drmmode_output->mode_encoders[j]->encoder_id) + drmmode_output->enc_mask |= (1 << k); + } + + drmmode_output->enc_clone_mask &= + drmmode_output->mode_encoders[j]->possible_clones; + } + } + + for (i = 0; i < xf86_config->num_output; i++) { + xf86OutputPtr output = xf86_config->output[i]; + + output->possible_clones = find_clones(scrn, output); + } } static Bool -drmmode_xf86crtc_resize (ScrnInfoPtr scrn, int width, int height) +drmmode_xf86crtc_resize(ScrnInfoPtr scrn, int width, int height) { - xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); - drmmode_crtc_private_ptr - drmmode_crtc = xf86_config->crtc[0]->driver_private; - drmmode_ptr drmmode = drmmode_crtc->drmmode; - struct dumb_bo *old_front = NULL; - Bool ret; - ScreenPtr screen = xf86ScrnToScreen(scrn); - uint32_t old_fb_id; - int i, pitch, old_width, old_height, old_pitch; - int cpp = (scrn->bitsPerPixel + 7) / 8; - PixmapPtr ppix = screen->GetScreenPixmap(screen); - void *new_pixels; - - if (scrn->virtualX == width && scrn->virtualY == height) - return TRUE; - - xf86DrvMsg(scrn->scrnIndex, X_INFO, - "Allocate new frame buffer %dx%d stride\n", - width, height); - - old_width = scrn->virtualX; - old_height = scrn->virtualY; - old_pitch = drmmode->front_bo->pitch; - old_fb_id = drmmode->fb_id; - old_front = drmmode->front_bo; - - drmmode->front_bo = dumb_bo_create(drmmode->fd, width, height, scrn->bitsPerPixel); - if (!drmmode->front_bo) - goto fail; - - pitch = drmmode->front_bo->pitch; - - scrn->virtualX = width; - scrn->virtualY = height; - scrn->displayWidth = pitch / cpp; - - ret = drmModeAddFB(drmmode->fd, width, height, scrn->depth, - scrn->bitsPerPixel, pitch, - drmmode->front_bo->handle, - &drmmode->fb_id); - if (ret) - goto fail; - - new_pixels = drmmode_map_front_bo(drmmode); - if (!new_pixels) - goto fail; - - if (!drmmode->shadow_enable) - screen->ModifyPixmapHeader(ppix, width, height, -1, -1, - pitch, new_pixels); - else { - void *new_shadow; - uint32_t size = scrn->displayWidth * scrn->virtualY * - ((scrn->bitsPerPixel + 7) >> 3); - new_shadow = calloc(1, size); - if (new_shadow == NULL) - goto fail; - free(drmmode->shadow_fb); - drmmode->shadow_fb = new_shadow; - screen->ModifyPixmapHeader(ppix, width, height, -1, -1, - pitch, drmmode->shadow_fb); - } - - for (i = 0; i < xf86_config->num_crtc; i++) { - xf86CrtcPtr crtc = xf86_config->crtc[i]; - - if (!crtc->enabled) - continue; - - drmmode_set_mode_major(crtc, &crtc->mode, - crtc->rotation, crtc->x, crtc->y); - } - - if (old_fb_id) { - drmModeRmFB(drmmode->fd, old_fb_id); - dumb_bo_destroy(drmmode->fd, old_front); - } - - return TRUE; + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); + + drmmode_crtc_private_ptr + drmmode_crtc = xf86_config->crtc[0]->driver_private; + drmmode_ptr drmmode = drmmode_crtc->drmmode; + struct dumb_bo *old_front = NULL; + Bool ret; + ScreenPtr screen = xf86ScrnToScreen(scrn); + uint32_t old_fb_id; + int i, pitch, old_width, old_height, old_pitch; + int cpp = (scrn->bitsPerPixel + 7) / 8; + PixmapPtr ppix = screen->GetScreenPixmap(screen); + void *new_pixels; + + if (scrn->virtualX == width && scrn->virtualY == height) + return TRUE; + + xf86DrvMsg(scrn->scrnIndex, X_INFO, + "Allocate new frame buffer %dx%d stride\n", width, height); + + old_width = scrn->virtualX; + old_height = scrn->virtualY; + old_pitch = drmmode->front_bo->pitch; + old_fb_id = drmmode->fb_id; + old_front = drmmode->front_bo; + + drmmode->front_bo = + dumb_bo_create(drmmode->fd, width, height, scrn->bitsPerPixel); + if (!drmmode->front_bo) + goto fail; + + pitch = drmmode->front_bo->pitch; + + scrn->virtualX = width; + scrn->virtualY = height; + scrn->displayWidth = pitch / cpp; + + ret = drmModeAddFB(drmmode->fd, width, height, scrn->depth, + scrn->bitsPerPixel, pitch, + drmmode->front_bo->handle, &drmmode->fb_id); + if (ret) + goto fail; + + new_pixels = drmmode_map_front_bo(drmmode); + if (!new_pixels) + goto fail; + + if (!drmmode->shadow_enable) + screen->ModifyPixmapHeader(ppix, width, height, -1, -1, + pitch, new_pixels); + else { + void *new_shadow; + uint32_t size = scrn->displayWidth * scrn->virtualY * + ((scrn->bitsPerPixel + 7) >> 3); + new_shadow = calloc(1, size); + if (new_shadow == NULL) + goto fail; + free(drmmode->shadow_fb); + drmmode->shadow_fb = new_shadow; + screen->ModifyPixmapHeader(ppix, width, height, -1, -1, + pitch, drmmode->shadow_fb); + } + + for (i = 0; i < xf86_config->num_crtc; i++) { + xf86CrtcPtr crtc = xf86_config->crtc[i]; + + if (!crtc->enabled) + continue; + + drmmode_set_mode_major(crtc, &crtc->mode, + crtc->rotation, crtc->x, crtc->y); + } + + if (old_fb_id) { + drmModeRmFB(drmmode->fd, old_fb_id); + dumb_bo_destroy(drmmode->fd, old_front); + } + + return TRUE; fail: - if (drmmode->front_bo) - dumb_bo_destroy(drmmode->fd, drmmode->front_bo); - drmmode->front_bo = old_front; - scrn->virtualX = old_width; - scrn->virtualY = old_height; - scrn->displayWidth = old_pitch / cpp; - drmmode->fb_id = old_fb_id; - - return FALSE; + if (drmmode->front_bo) + dumb_bo_destroy(drmmode->fd, drmmode->front_bo); + drmmode->front_bo = old_front; + scrn->virtualX = old_width; + scrn->virtualY = old_height; + scrn->displayWidth = old_pitch / cpp; + drmmode->fb_id = old_fb_id; + + return FALSE; } static const xf86CrtcConfigFuncsRec drmmode_xf86crtc_config_funcs = { - drmmode_xf86crtc_resize + drmmode_xf86crtc_resize }; -Bool drmmode_pre_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int cpp) +Bool +drmmode_pre_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int cpp) { - int i, num_dvi = 0, num_hdmi = 0; - int ret; - uint64_t value = 0; - - /* check for dumb capability */ - ret = drmGetCap(drmmode->fd, DRM_CAP_DUMB_BUFFER, &value); - if (ret > 0 || value != 1) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "KMS doesn't support dumb interface\n"); - return FALSE; - } + int i, num_dvi = 0, num_hdmi = 0; + int ret; + uint64_t value = 0; + + /* check for dumb capability */ + ret = drmGetCap(drmmode->fd, DRM_CAP_DUMB_BUFFER, &value); + if (ret > 0 || value != 1) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "KMS doesn't support dumb interface\n"); + return FALSE; + } - xf86CrtcConfigInit(pScrn, &drmmode_xf86crtc_config_funcs); + xf86CrtcConfigInit(pScrn, &drmmode_xf86crtc_config_funcs); - drmmode->scrn = pScrn; - drmmode->cpp = cpp; - drmmode->mode_res = drmModeGetResources(drmmode->fd); - if (!drmmode->mode_res) - return FALSE; + drmmode->scrn = pScrn; + drmmode->cpp = cpp; + drmmode->mode_res = drmModeGetResources(drmmode->fd); + if (!drmmode->mode_res) + return FALSE; - xf86CrtcSetSizeRange(pScrn, 320, 200, drmmode->mode_res->max_width, drmmode->mode_res->max_height); - for (i = 0; i < drmmode->mode_res->count_crtcs; i++) - if (!xf86IsEntityShared(pScrn->entityList[0]) || pScrn->confScreen->device->screen == i) - drmmode_crtc_init(pScrn, drmmode, i); + xf86CrtcSetSizeRange(pScrn, 320, 200, drmmode->mode_res->max_width, + drmmode->mode_res->max_height); + for (i = 0; i < drmmode->mode_res->count_crtcs; i++) + if (!xf86IsEntityShared(pScrn->entityList[0]) || + pScrn->confScreen->device->screen == i) + drmmode_crtc_init(pScrn, drmmode, i); - for (i = 0; i < drmmode->mode_res->count_connectors; i++) - drmmode_output_init(pScrn, drmmode, i, &num_dvi, &num_hdmi); + for (i = 0; i < drmmode->mode_res->count_connectors; i++) + drmmode_output_init(pScrn, drmmode, i, &num_dvi, &num_hdmi); - /* workout clones */ - drmmode_clones_init(pScrn, drmmode); + /* workout clones */ + drmmode_clones_init(pScrn, drmmode); #if XF86_CRTC_VERSION >= 5 - xf86ProviderSetup(pScrn, NULL, "modesetting"); + xf86ProviderSetup(pScrn, NULL, "modesetting"); #endif - xf86InitialConfiguration(pScrn, TRUE); + xf86InitialConfiguration(pScrn, TRUE); - return TRUE; + return TRUE; } -void drmmode_adjust_frame(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int x, int y) +void +drmmode_adjust_frame(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int x, int y) { - xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); - xf86OutputPtr output = config->output[config->compat_output]; - xf86CrtcPtr crtc = output->crtc; - - if (crtc && crtc->enabled) { - drmmode_set_mode_major(crtc, &crtc->mode, crtc->rotation, - x, y); - } + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); + xf86OutputPtr output = config->output[config->compat_output]; + xf86CrtcPtr crtc = output->crtc; + + if (crtc && crtc->enabled) { + drmmode_set_mode_major(crtc, &crtc->mode, crtc->rotation, x, y); + } } -Bool drmmode_set_desired_modes(ScrnInfoPtr pScrn, drmmode_ptr drmmode) +Bool +drmmode_set_desired_modes(ScrnInfoPtr pScrn, drmmode_ptr drmmode) { - xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); - int c; - - for (c = 0; c < config->num_crtc; c++) { - xf86CrtcPtr crtc = config->crtc[c]; - drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; - xf86OutputPtr output = NULL; - int o; - - /* Skip disabled CRTCs */ - if (!crtc->enabled) { - drmModeSetCrtc(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, - 0, 0, 0, NULL, 0, NULL); - continue; - } - - if (config->output[config->compat_output]->crtc == crtc) - output = config->output[config->compat_output]; - else - { - for (o = 0; o < config->num_output; o++) - if (config->output[o]->crtc == crtc) - { - output = config->output[o]; - break; - } - } - /* paranoia */ - if (!output) - continue; - - /* Mark that we'll need to re-set the mode for sure */ - memset(&crtc->mode, 0, sizeof(crtc->mode)); - if (!crtc->desiredMode.CrtcHDisplay) - { - DisplayModePtr mode = xf86OutputFindClosestMode (output, pScrn->currentMode); - - if (!mode) - return FALSE; - crtc->desiredMode = *mode; - crtc->desiredRotation = RR_Rotate_0; - crtc->desiredX = 0; - crtc->desiredY = 0; - } - - if (!crtc->funcs->set_mode_major(crtc, &crtc->desiredMode, crtc->desiredRotation, - crtc->desiredX, crtc->desiredY)) - return FALSE; - } - return TRUE; + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); + int c; + + for (c = 0; c < config->num_crtc; c++) { + xf86CrtcPtr crtc = config->crtc[c]; + drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; + xf86OutputPtr output = NULL; + int o; + + /* Skip disabled CRTCs */ + if (!crtc->enabled) { + drmModeSetCrtc(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, + 0, 0, 0, NULL, 0, NULL); + continue; + } + + if (config->output[config->compat_output]->crtc == crtc) + output = config->output[config->compat_output]; + else { + for (o = 0; o < config->num_output; o++) + if (config->output[o]->crtc == crtc) { + output = config->output[o]; + break; + } + } + /* paranoia */ + if (!output) + continue; + + /* Mark that we'll need to re-set the mode for sure */ + memset(&crtc->mode, 0, sizeof(crtc->mode)); + if (!crtc->desiredMode.CrtcHDisplay) { + DisplayModePtr mode = + xf86OutputFindClosestMode(output, pScrn->currentMode); + + if (!mode) + return FALSE; + crtc->desiredMode = *mode; + crtc->desiredRotation = RR_Rotate_0; + crtc->desiredX = 0; + crtc->desiredY = 0; + } + + if (!crtc->funcs-> + set_mode_major(crtc, &crtc->desiredMode, crtc->desiredRotation, + crtc->desiredX, crtc->desiredY)) + return FALSE; + } + return TRUE; } -static void drmmode_load_palette(ScrnInfoPtr pScrn, int numColors, - int *indices, LOCO *colors, VisualPtr pVisual) +static void +drmmode_load_palette(ScrnInfoPtr pScrn, int numColors, + int *indices, LOCO * colors, VisualPtr pVisual) { - xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); - uint16_t lut_r[256], lut_g[256], lut_b[256]; + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); + uint16_t lut_r[256], lut_g[256], lut_b[256]; int index, j, i; int c; for (c = 0; c < xf86_config->num_crtc; c++) { xf86CrtcPtr crtc = xf86_config->crtc[c]; - drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; + drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; - for (i = 0 ; i < 256; i++) { + for (i = 0; i < 256; i++) { lut_r[i] = drmmode_crtc->lut_r[i] << 6; lut_g[i] = drmmode_crtc->lut_g[i] << 6; lut_b[i] = drmmode_crtc->lut_b[i] << 6; } - switch(pScrn->depth) { + switch (pScrn->depth) { case 15: for (i = 0; i < numColors; i++) { index = indices[i]; @@ -1356,56 +1399,55 @@ static void drmmode_load_palette(ScrnInfoPtr pScrn, int numColors, lut_b[index * 8 + j] = colors[index].blue << 6; } } - break; - case 16: - for (i = 0; i < numColors; i++) { - index = indices[i]; - - if (i <= 31) { - for (j = 0; j < 8; j++) { - lut_r[index * 8 + j] = colors[index].red << 6; - lut_b[index * 8 + j] = colors[index].blue << 6; - } - } - - for (j = 0; j < 4; j++) { - lut_g[index * 4 + j] = colors[index].green << 6; - } - } - break; - default: - for (i = 0; i < numColors; i++) { - index = indices[i]; - lut_r[index] = colors[index].red << 6; - lut_g[index] = colors[index].green << 6; - lut_b[index] = colors[index].blue << 6; - } - break; - } - - /* Make the change through RandR */ + break; + case 16: + for (i = 0; i < numColors; i++) { + index = indices[i]; + + if (i <= 31) { + for (j = 0; j < 8; j++) { + lut_r[index * 8 + j] = colors[index].red << 6; + lut_b[index * 8 + j] = colors[index].blue << 6; + } + } + + for (j = 0; j < 4; j++) { + lut_g[index * 4 + j] = colors[index].green << 6; + } + } + break; + default: + for (i = 0; i < numColors; i++) { + index = indices[i]; + lut_r[index] = colors[index].red << 6; + lut_g[index] = colors[index].green << 6; + lut_b[index] = colors[index].blue << 6; + } + break; + } + + /* Make the change through RandR */ if (crtc->randr_crtc) RRCrtcGammaSet(crtc->randr_crtc, lut_r, lut_g, lut_b); else crtc->funcs->gamma_set(crtc, lut_r, lut_g, lut_b, 256); - } + } } -Bool drmmode_setup_colormap(ScreenPtr pScreen, ScrnInfoPtr pScrn) +Bool +drmmode_setup_colormap(ScreenPtr pScreen, ScrnInfoPtr pScrn) { - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 0, - "Initializing kms color map\n"); + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 0, "Initializing kms color map\n"); if (!miCreateDefColormap(pScreen)) return FALSE; /* all radeons support 10 bit CLUTs */ if (!xf86HandleColormaps(pScreen, 256, 10, - drmmode_load_palette, NULL, - CMAP_PALETTED_TRUECOLOR -#if 0 /* This option messes up text mode! (eich@suse.de) */ + drmmode_load_palette, NULL, CMAP_PALETTED_TRUECOLOR +#if 0 /* This option messes up text mode! (eich@suse.de) */ | CMAP_LOAD_EVEN_IF_OFFSCREEN #endif | CMAP_RELOAD_ON_MODE_SWITCH)) - return FALSE; + return FALSE; return TRUE; } @@ -1413,204 +1455,220 @@ Bool drmmode_setup_colormap(ScreenPtr pScreen, ScrnInfoPtr pScrn) static void drmmode_handle_uevents(int fd, void *closure) { - drmmode_ptr drmmode = closure; - ScrnInfoPtr scrn = drmmode->scrn; - struct udev_device *dev; - dev = udev_monitor_receive_device(drmmode->uevent_monitor); - if (!dev) - return; - - RRGetInfo(xf86ScrnToScreen(scrn), TRUE); - udev_device_unref(dev); + drmmode_ptr drmmode = closure; + ScrnInfoPtr scrn = drmmode->scrn; + struct udev_device *dev; + + dev = udev_monitor_receive_device(drmmode->uevent_monitor); + if (!dev) + return; + + RRGetInfo(xf86ScrnToScreen(scrn), TRUE); + udev_device_unref(dev); } #endif -void drmmode_uevent_init(ScrnInfoPtr scrn, drmmode_ptr drmmode) +void +drmmode_uevent_init(ScrnInfoPtr scrn, drmmode_ptr drmmode) { #ifdef HAVE_UDEV - struct udev *u; - struct udev_monitor *mon; - - u = udev_new(); - if (!u) - return; - mon = udev_monitor_new_from_netlink(u, "udev"); - if (!mon) { - udev_unref(u); - return; - } - - if (udev_monitor_filter_add_match_subsystem_devtype(mon, - "drm", - "drm_minor") < 0 || - udev_monitor_enable_receiving(mon) < 0) { - udev_monitor_unref(mon); - udev_unref(u); - return; - } - - drmmode->uevent_handler = - xf86AddGeneralHandler(udev_monitor_get_fd(mon), - drmmode_handle_uevents, - drmmode); - - drmmode->uevent_monitor = mon; + struct udev *u; + struct udev_monitor *mon; + + u = udev_new(); + if (!u) + return; + mon = udev_monitor_new_from_netlink(u, "udev"); + if (!mon) { + udev_unref(u); + return; + } + + if (udev_monitor_filter_add_match_subsystem_devtype(mon, + "drm", + "drm_minor") < 0 || + udev_monitor_enable_receiving(mon) < 0) { + udev_monitor_unref(mon); + udev_unref(u); + return; + } + + drmmode->uevent_handler = + xf86AddGeneralHandler(udev_monitor_get_fd(mon), + drmmode_handle_uevents, drmmode); + + drmmode->uevent_monitor = mon; #endif } -void drmmode_uevent_fini(ScrnInfoPtr scrn, drmmode_ptr drmmode) +void +drmmode_uevent_fini(ScrnInfoPtr scrn, drmmode_ptr drmmode) { #ifdef HAVE_UDEV - if (drmmode->uevent_handler) { - struct udev *u = udev_monitor_get_udev(drmmode->uevent_monitor); - xf86RemoveGeneralHandler(drmmode->uevent_handler); + if (drmmode->uevent_handler) { + struct udev *u = udev_monitor_get_udev(drmmode->uevent_monitor); + + xf86RemoveGeneralHandler(drmmode->uevent_handler); - udev_monitor_unref(drmmode->uevent_monitor); - udev_unref(u); - } + udev_monitor_unref(drmmode->uevent_monitor); + udev_unref(u); + } #endif } /* create front and cursor BOs */ -Bool drmmode_create_initial_bos(ScrnInfoPtr pScrn, drmmode_ptr drmmode) +Bool +drmmode_create_initial_bos(ScrnInfoPtr pScrn, drmmode_ptr drmmode) { - modesettingPtr ms = modesettingPTR(pScrn); - xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); - int width; - int height; - int bpp = pScrn->bitsPerPixel; - int i; - int cpp = (bpp + 7) / 8; - - width = pScrn->virtualX; - height = pScrn->virtualY; - - drmmode->front_bo = dumb_bo_create(drmmode->fd, width, height, bpp); - if (!drmmode->front_bo) - return FALSE; - pScrn->displayWidth = drmmode->front_bo->pitch / cpp; - - width = ms->cursor_width; - height = ms->cursor_height; - bpp = 32; - for (i = 0; i < xf86_config->num_crtc; i++) { - xf86CrtcPtr crtc = xf86_config->crtc[i]; - drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; - drmmode_crtc->cursor_bo = dumb_bo_create(drmmode->fd, width, height, bpp); - } - return TRUE; + modesettingPtr ms = modesettingPTR(pScrn); + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); + int width; + int height; + int bpp = pScrn->bitsPerPixel; + int i; + int cpp = (bpp + 7) / 8; + + width = pScrn->virtualX; + height = pScrn->virtualY; + + drmmode->front_bo = dumb_bo_create(drmmode->fd, width, height, bpp); + if (!drmmode->front_bo) + return FALSE; + pScrn->displayWidth = drmmode->front_bo->pitch / cpp; + + width = ms->cursor_width; + height = ms->cursor_height; + bpp = 32; + for (i = 0; i < xf86_config->num_crtc; i++) { + xf86CrtcPtr crtc = xf86_config->crtc[i]; + drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; + + drmmode_crtc->cursor_bo = + dumb_bo_create(drmmode->fd, width, height, bpp); + } + return TRUE; } -void *drmmode_map_front_bo(drmmode_ptr drmmode) +void * +drmmode_map_front_bo(drmmode_ptr drmmode) { - int ret; + int ret; - if (drmmode->front_bo->ptr) - return drmmode->front_bo->ptr; + if (drmmode->front_bo->ptr) + return drmmode->front_bo->ptr; - ret = dumb_bo_map(drmmode->fd, drmmode->front_bo); - if (ret) - return NULL; + ret = dumb_bo_map(drmmode->fd, drmmode->front_bo); + if (ret) + return NULL; + + return drmmode->front_bo->ptr; - return drmmode->front_bo->ptr; - } -void *drmmode_map_slave_bo(drmmode_ptr drmmode, msPixmapPrivPtr ppriv) +void * +drmmode_map_slave_bo(drmmode_ptr drmmode, msPixmapPrivPtr ppriv) { - int ret; + int ret; - if (ppriv->backing_bo->ptr) - return ppriv->backing_bo->ptr; + if (ppriv->backing_bo->ptr) + return ppriv->backing_bo->ptr; - ret = dumb_bo_map(drmmode->fd, ppriv->backing_bo); - if (ret) - return NULL; + ret = dumb_bo_map(drmmode->fd, ppriv->backing_bo); + if (ret) + return NULL; - return ppriv->backing_bo->ptr; + return ppriv->backing_bo->ptr; } -Bool drmmode_map_cursor_bos(ScrnInfoPtr pScrn, drmmode_ptr drmmode) +Bool +drmmode_map_cursor_bos(ScrnInfoPtr pScrn, drmmode_ptr drmmode) { - xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); - int i, ret; - for (i = 0; i < xf86_config->num_crtc; i++) { - xf86CrtcPtr crtc = xf86_config->crtc[i]; - drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; - ret = dumb_bo_map(drmmode->fd, drmmode_crtc->cursor_bo); - if (ret) - return FALSE; - } - return TRUE; + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); + int i, ret; + + for (i = 0; i < xf86_config->num_crtc; i++) { + xf86CrtcPtr crtc = xf86_config->crtc[i]; + drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; + + ret = dumb_bo_map(drmmode->fd, drmmode_crtc->cursor_bo); + if (ret) + return FALSE; + } + return TRUE; } -void drmmode_free_bos(ScrnInfoPtr pScrn, drmmode_ptr drmmode) +void +drmmode_free_bos(ScrnInfoPtr pScrn, drmmode_ptr drmmode) { - xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); - int i; - - if (drmmode->fb_id) { - drmModeRmFB(drmmode->fd, drmmode->fb_id); - drmmode->fb_id = 0; - } - - dumb_bo_destroy(drmmode->fd, drmmode->front_bo); - drmmode->front_bo = NULL; - - for (i = 0; i < xf86_config->num_crtc; i++) { - xf86CrtcPtr crtc = xf86_config->crtc[i]; - drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; - dumb_bo_destroy(drmmode->fd, drmmode_crtc->cursor_bo); - } + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); + int i; + + if (drmmode->fb_id) { + drmModeRmFB(drmmode->fd, drmmode->fb_id); + drmmode->fb_id = 0; + } + + dumb_bo_destroy(drmmode->fd, drmmode->front_bo); + drmmode->front_bo = NULL; + + for (i = 0; i < xf86_config->num_crtc; i++) { + xf86CrtcPtr crtc = xf86_config->crtc[i]; + drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; + + dumb_bo_destroy(drmmode->fd, drmmode_crtc->cursor_bo); + } } /* ugly workaround to see if we can create 32bpp */ -void drmmode_get_default_bpp(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int *depth, int *bpp) +void +drmmode_get_default_bpp(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int *depth, + int *bpp) { - drmModeResPtr mode_res; - uint64_t value; - struct dumb_bo *bo; - uint32_t fb_id; - int ret; - - /* 16 is fine */ - ret = drmGetCap(drmmode->fd, DRM_CAP_DUMB_PREFERRED_DEPTH, &value); - if (!ret && (value == 16 || value == 8)) { - *depth = value; - *bpp = value; - return; - } - - *depth = 24; - mode_res = drmModeGetResources(drmmode->fd); - if (!mode_res) - return; - - if (mode_res->min_width == 0) - mode_res->min_width = 1; - if (mode_res->min_height == 0) - mode_res->min_height = 1; - /*create a bo */ - bo = dumb_bo_create(drmmode->fd, mode_res->min_width, mode_res->min_height, 32); - if (!bo) { - *bpp = 24; - goto out; - } - - ret = drmModeAddFB(drmmode->fd, mode_res->min_width, mode_res->min_height, - 24, 32, bo->pitch, bo->handle, &fb_id); - - if (ret) { - *bpp = 24; - dumb_bo_destroy(drmmode->fd, bo); - goto out; - } - - drmModeRmFB(drmmode->fd, fb_id); - *bpp = 32; - - dumb_bo_destroy(drmmode->fd, bo); -out: - drmModeFreeResources(mode_res); - return; + drmModeResPtr mode_res; + uint64_t value; + struct dumb_bo *bo; + uint32_t fb_id; + int ret; + + /* 16 is fine */ + ret = drmGetCap(drmmode->fd, DRM_CAP_DUMB_PREFERRED_DEPTH, &value); + if (!ret && (value == 16 || value == 8)) { + *depth = value; + *bpp = value; + return; + } + + *depth = 24; + mode_res = drmModeGetResources(drmmode->fd); + if (!mode_res) + return; + + if (mode_res->min_width == 0) + mode_res->min_width = 1; + if (mode_res->min_height == 0) + mode_res->min_height = 1; + /*create a bo */ + bo = dumb_bo_create(drmmode->fd, mode_res->min_width, mode_res->min_height, + 32); + if (!bo) { + *bpp = 24; + goto out; + } + + ret = drmModeAddFB(drmmode->fd, mode_res->min_width, mode_res->min_height, + 24, 32, bo->pitch, bo->handle, &fb_id); + + if (ret) { + *bpp = 24; + dumb_bo_destroy(drmmode->fd, bo); + goto out; + } + + drmModeRmFB(drmmode->fd, fb_id); + *bpp = 32; + + dumb_bo_destroy(drmmode->fd, bo); + out: + drmModeFreeResources(mode_res); + return; } diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.h b/hw/xfree86/drivers/modesetting/drmmode_display.h index 7bfe885f5..438743b01 100644 --- a/hw/xfree86/drivers/modesetting/drmmode_display.h +++ b/hw/xfree86/drivers/modesetting/drmmode_display.h @@ -74,11 +74,10 @@ typedef struct { typedef struct { drmModePropertyPtr mode_prop; uint64_t value; - int num_atoms; /* if range prop, num_atoms == 1; if enum prop, num_atoms == num_enums + 1 */ + int num_atoms; /* if range prop, num_atoms == 1; if enum prop, num_atoms == num_enums + 1 */ Atom *atoms; } drmmode_prop_rec, *drmmode_prop_ptr; - typedef struct { drmmode_ptr drmmode; int output_id; @@ -97,16 +96,16 @@ typedef struct _msPixmapPriv { struct dumb_bo *backing_bo; /* if this pixmap is backed by a dumb bo */ } msPixmapPrivRec, *msPixmapPrivPtr; - extern DevPrivateKeyRec msPixmapPrivateKeyRec; + #define msPixmapPrivateKey (&msPixmapPrivateKeyRec) #define msGetPixmapPriv(drmmode, p) ((msPixmapPrivPtr)dixGetPrivateAddr(&(p)->devPrivates, &(drmmode)->pixmapPrivateKeyRec)) void *drmmode_map_slave_bo(drmmode_ptr drmmode, msPixmapPrivPtr ppriv); Bool drmmode_SetSlaveBO(PixmapPtr ppix, - drmmode_ptr drmmode, - int fd_handle, int pitch, int size); + drmmode_ptr drmmode, + int fd_handle, int pitch, int size); extern Bool drmmode_pre_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int cpp); void drmmode_adjust_frame(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int x, int y); @@ -120,8 +119,8 @@ Bool drmmode_create_initial_bos(ScrnInfoPtr pScrn, drmmode_ptr drmmode); void *drmmode_map_front_bo(drmmode_ptr drmmode); Bool drmmode_map_cursor_bos(ScrnInfoPtr pScrn, drmmode_ptr drmmode); void drmmode_free_bos(ScrnInfoPtr pScrn, drmmode_ptr drmmode); -void drmmode_get_default_bpp(ScrnInfoPtr pScrn, drmmode_ptr drmmmode, int *depth, int *bpp); - +void drmmode_get_default_bpp(ScrnInfoPtr pScrn, drmmode_ptr drmmmode, + int *depth, int *bpp); #ifndef DRM_CAP_DUMB_PREFERRED_DEPTH #define DRM_CAP_DUMB_PREFERRED_DEPTH 3 @@ -132,5 +131,4 @@ void drmmode_get_default_bpp(ScrnInfoPtr pScrn, drmmode_ptr drmmmode, int *depth #define MS_ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0])) - #endif diff --git a/hw/xfree86/drivers/modesetting/modesetting.man b/hw/xfree86/drivers/modesetting/modesetting.man index 34baa9c53..9cb27d728 100644 --- a/hw/xfree86/drivers/modesetting/modesetting.man +++ b/hw/xfree86/drivers/modesetting/modesetting.man @@ -47,6 +47,9 @@ The framebuffer device to use. Default: /dev/dri/card0. .BI "Option \*qShadowFB\*q \*q" boolean \*q Enable or disable use of the shadow framebuffer layer. Default: on. .TP +.BI "Option \*qAccelMethod\*q \*q" string \*q +One of \*qglamor\*q or \*qnone\*q. Default: glamor +.TP .SH "SEE ALSO" __xservername__(__appmansuffix__), __xconfigfile__(__filemansuffix__), Xserver(__appmansuffix__), X(__miscmansuffix__) |