Merge branch 'mesa_7_6_branch'
[mesa.git] / src / gallium / state_trackers / xorg / xorg_driver.c
1 /*
2 * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
3 * All Rights Reserved.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the
7 * "Software"), to deal in the Software without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sub license, and/or sell copies of the Software, and to
10 * permit persons to whom the Software is furnished to do so, subject to
11 * the following conditions:
12 *
13 * The above copyright notice and this permission notice (including the
14 * next paragraph) shall be included in all copies or substantial portions
15 * of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
20 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
21 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
22 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
23 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 *
25 *
26 * Author: Alan Hourihane <alanh@tungstengraphics.com>
27 * Author: Jakob Bornecrantz <wallbraker@gmail.com>
28 *
29 */
30
31
32 #include "xorg-server.h"
33 #include "xf86.h"
34 #include "xf86_OSproc.h"
35 #include "compiler.h"
36 #include "xf86PciInfo.h"
37 #include "xf86Pci.h"
38 #include "mipointer.h"
39 #include "micmap.h"
40 #include <X11/extensions/randr.h>
41 #include "fb.h"
42 #include "edid.h"
43 #include "xf86i2c.h"
44 #include "xf86Crtc.h"
45 #include "miscstruct.h"
46 #include "dixstruct.h"
47 #include "xf86xv.h"
48 #include <X11/extensions/Xv.h>
49 #ifndef XSERVER_LIBPCIACCESS
50 #error "libpciaccess needed"
51 #endif
52
53 #include <pciaccess.h>
54
55 #include "pipe/p_context.h"
56 #include "xorg_tracker.h"
57 #include "xorg_winsys.h"
58
59 static void AdjustFrame(int scrnIndex, int x, int y, int flags);
60 static Bool CloseScreen(int scrnIndex, ScreenPtr pScreen);
61 static Bool EnterVT(int scrnIndex, int flags);
62 static Bool SaveHWState(ScrnInfoPtr pScrn);
63 static Bool RestoreHWState(ScrnInfoPtr pScrn);
64
65
66 static ModeStatus ValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose,
67 int flags);
68 static void FreeScreen(int scrnIndex, int flags);
69 static void LeaveVT(int scrnIndex, int flags);
70 static Bool SwitchMode(int scrnIndex, DisplayModePtr mode, int flags);
71 static Bool ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc,
72 char **argv);
73 static Bool PreInit(ScrnInfoPtr pScrn, int flags);
74
75 typedef enum
76 {
77 OPTION_SW_CURSOR,
78 } modesettingOpts;
79
80 static const OptionInfoRec Options[] = {
81 {OPTION_SW_CURSOR, "SWcursor", OPTV_BOOLEAN, {0}, FALSE},
82 {-1, NULL, OPTV_NONE, {0}, FALSE}
83 };
84
85 /*
86 * Exported Xorg driver functions to winsys
87 */
88
89 const OptionInfoRec *
90 xorg_tracker_available_options(int chipid, int busid)
91 {
92 return Options;
93 }
94
95 void
96 xorg_tracker_set_functions(ScrnInfoPtr scrn)
97 {
98 scrn->PreInit = PreInit;
99 scrn->ScreenInit = ScreenInit;
100 scrn->SwitchMode = SwitchMode;
101 scrn->AdjustFrame = AdjustFrame;
102 scrn->EnterVT = EnterVT;
103 scrn->LeaveVT = LeaveVT;
104 scrn->FreeScreen = FreeScreen;
105 scrn->ValidMode = ValidMode;
106 }
107
108 /*
109 * Static Xorg funtctions
110 */
111
112 static Bool
113 GetRec(ScrnInfoPtr pScrn)
114 {
115 if (pScrn->driverPrivate)
116 return TRUE;
117
118 pScrn->driverPrivate = xnfcalloc(sizeof(modesettingRec), 1);
119
120 return TRUE;
121 }
122
123 static void
124 FreeRec(ScrnInfoPtr pScrn)
125 {
126 if (!pScrn)
127 return;
128
129 if (!pScrn->driverPrivate)
130 return;
131
132 xfree(pScrn->driverPrivate);
133
134 pScrn->driverPrivate = NULL;
135 }
136
137 static void
138 ProbeDDC(ScrnInfoPtr pScrn, int index)
139 {
140 ConfiguredMonitor = NULL;
141 }
142
143 static Bool
144 CreateFrontBuffer(ScrnInfoPtr pScrn)
145 {
146 modesettingPtr ms = modesettingPTR(pScrn);
147 unsigned handle, stride;
148 struct pipe_texture *tex;
149
150 ms->noEvict = TRUE;
151
152 tex = xorg_exa_create_root_texture(pScrn, pScrn->virtualX, pScrn->virtualY,
153 pScrn->depth, pScrn->bitsPerPixel);
154
155 if (!tex)
156 return FALSE;
157
158 if (!ms->api->local_handle_from_texture(ms->api, ms->screen,
159 tex,
160 &stride,
161 &handle))
162 return FALSE;
163
164 drmModeAddFB(ms->fd,
165 pScrn->virtualX,
166 pScrn->virtualY,
167 pScrn->depth,
168 pScrn->bitsPerPixel,
169 stride,
170 handle,
171 &ms->fb_id);
172
173 pScrn->frameX0 = 0;
174 pScrn->frameY0 = 0;
175 AdjustFrame(pScrn->scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
176
177 pipe_texture_reference(&ms->root_texture, tex);
178 pipe_texture_reference(&tex, NULL);
179 return TRUE;
180 }
181
182 static Bool
183 BindTextureToRoot(ScrnInfoPtr pScrn)
184 {
185 modesettingPtr ms = modesettingPTR(pScrn);
186 ScreenPtr pScreen = pScrn->pScreen;
187 struct pipe_texture *check;
188 PixmapPtr rootPixmap;
189
190 rootPixmap = pScreen->GetScreenPixmap(pScreen);
191
192 xorg_exa_set_displayed_usage(rootPixmap);
193 xorg_exa_set_shared_usage(rootPixmap);
194 xorg_exa_set_texture(rootPixmap, ms->root_texture);
195 if (!pScreen->ModifyPixmapHeader(rootPixmap, -1, -1, -1, -1, -1, NULL))
196 FatalError("Couldn't adjust screen pixmap\n");
197
198 check = xorg_exa_get_texture(rootPixmap);
199 if (ms->root_texture != check)
200 FatalError("Created new root texture\n");
201
202 pipe_texture_reference(&check, NULL);
203
204 return TRUE;
205 }
206
207 static Bool
208 crtc_resize(ScrnInfoPtr pScrn, int width, int height)
209 {
210 modesettingPtr ms = modesettingPTR(pScrn);
211 unsigned handle, stride;
212 PixmapPtr rootPixmap;
213 ScreenPtr pScreen = pScrn->pScreen;
214
215 if (width == pScrn->virtualX && height == pScrn->virtualY)
216 return TRUE;
217
218 ErrorF("RESIZING TO %dx%d\n", width, height);
219
220 pScrn->virtualX = width;
221 pScrn->virtualY = height;
222
223 /*
224 * Remove the old framebuffer & texture.
225 */
226 drmModeRmFB(ms->fd, ms->fb_id);
227 pipe_texture_reference(&ms->root_texture, NULL);
228
229
230 rootPixmap = pScreen->GetScreenPixmap(pScreen);
231 if (!pScreen->ModifyPixmapHeader(rootPixmap, width, height, -1, -1, -1, NULL))
232 return FALSE;
233
234 /* takes one ref */
235 ms->root_texture = xorg_exa_get_texture(rootPixmap);
236
237 if (!ms->api->local_handle_from_texture(ms->api, ms->screen,
238 ms->root_texture,
239 &stride,
240 &handle))
241 FatalError("Could not get handle and stride from texture\n");
242
243 drmModeAddFB(ms->fd,
244 pScrn->virtualX,
245 pScrn->virtualY,
246 pScrn->depth,
247 pScrn->bitsPerPixel,
248 stride,
249 handle,
250 &ms->fb_id);
251
252 /* HW dependent - FIXME */
253 pScrn->displayWidth = pScrn->virtualX;
254
255 /* now create new frontbuffer */
256 return CreateFrontBuffer(pScrn) && BindTextureToRoot(pScrn);
257 }
258
259 static const xf86CrtcConfigFuncsRec crtc_config_funcs = {
260 crtc_resize
261 };
262
263 static Bool
264 InitDRM(ScrnInfoPtr pScrn)
265 {
266 modesettingPtr ms = modesettingPTR(pScrn);
267
268 /* deal with server regeneration */
269 if (ms->fd < 0) {
270 char *BusID;
271
272 BusID = xalloc(64);
273 sprintf(BusID, "PCI:%d:%d:%d",
274 ((ms->PciInfo->domain << 8) | ms->PciInfo->bus),
275 ms->PciInfo->dev, ms->PciInfo->func
276 );
277
278 ms->fd = drmOpen(NULL, BusID);
279
280 if (ms->fd < 0)
281 return FALSE;
282 }
283
284 if (!ms->api) {
285 ms->api = drm_api_create();
286
287 if (!ms->api)
288 return FALSE;
289 }
290
291 return TRUE;
292 }
293
294 static Bool
295 PreInit(ScrnInfoPtr pScrn, int flags)
296 {
297 xf86CrtcConfigPtr xf86_config;
298 modesettingPtr ms;
299 rgb defaultWeight = { 0, 0, 0 };
300 EntityInfoPtr pEnt;
301 EntPtr msEnt = NULL;
302 int max_width, max_height;
303
304 if (pScrn->numEntities != 1)
305 return FALSE;
306
307 pEnt = xf86GetEntityInfo(pScrn->entityList[0]);
308
309 if (flags & PROBE_DETECT) {
310 ProbeDDC(pScrn, pEnt->index);
311 return TRUE;
312 }
313
314 /* Allocate driverPrivate */
315 if (!GetRec(pScrn))
316 return FALSE;
317
318 ms = modesettingPTR(pScrn);
319 ms->SaveGeneration = -1;
320 ms->pEnt = pEnt;
321
322 pScrn->displayWidth = 640; /* default it */
323
324 if (ms->pEnt->location.type != BUS_PCI)
325 return FALSE;
326
327 ms->PciInfo = xf86GetPciInfoForEntity(ms->pEnt->index);
328
329 /* Allocate an entity private if necessary */
330 if (xf86IsEntityShared(pScrn->entityList[0])) {
331 FatalError("Entity");
332 #if 0
333 msEnt = xf86GetEntityPrivate(pScrn->entityList[0],
334 modesettingEntityIndex)->ptr;
335 ms->entityPrivate = msEnt;
336 #else
337 (void)msEnt;
338 #endif
339 } else
340 ms->entityPrivate = NULL;
341
342 if (xf86IsEntityShared(pScrn->entityList[0])) {
343 if (xf86IsPrimInitDone(pScrn->entityList[0])) {
344 /* do something */
345 } else {
346 xf86SetPrimInitDone(pScrn->entityList[0]);
347 }
348 }
349
350 ms->fd = -1;
351 ms->api = NULL;
352 if (!InitDRM(pScrn))
353 return FALSE;
354
355 pScrn->monitor = pScrn->confScreen->monitor;
356 pScrn->progClock = TRUE;
357 pScrn->rgbBits = 8;
358
359 if (!xf86SetDepthBpp
360 (pScrn, 0, 0, 0,
361 PreferConvert24to32 | SupportConvert24to32 | Support32bppFb))
362 return FALSE;
363
364 switch (pScrn->depth) {
365 case 15:
366 case 16:
367 case 24:
368 break;
369 default:
370 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
371 "Given depth (%d) is not supported by the driver\n",
372 pScrn->depth);
373 return FALSE;
374 }
375 xf86PrintDepthBpp(pScrn);
376
377 if (!xf86SetWeight(pScrn, defaultWeight, defaultWeight))
378 return FALSE;
379 if (!xf86SetDefaultVisual(pScrn, -1))
380 return FALSE;
381
382 /* Process the options */
383 xf86CollectOptions(pScrn, NULL);
384 if (!(ms->Options = xalloc(sizeof(Options))))
385 return FALSE;
386 memcpy(ms->Options, Options, sizeof(Options));
387 xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, ms->Options);
388
389 /* Allocate an xf86CrtcConfig */
390 xf86CrtcConfigInit(pScrn, &crtc_config_funcs);
391 xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
392
393 max_width = 8192;
394 max_height = 8192;
395 xf86CrtcSetSizeRange(pScrn, 320, 200, max_width, max_height);
396
397 if (xf86ReturnOptValBool(ms->Options, OPTION_SW_CURSOR, FALSE)) {
398 ms->SWCursor = TRUE;
399 }
400
401 SaveHWState(pScrn);
402
403 crtc_init(pScrn);
404 output_init(pScrn);
405
406 if (!xf86InitialConfiguration(pScrn, TRUE)) {
407 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes.\n");
408 RestoreHWState(pScrn);
409 return FALSE;
410 }
411
412 RestoreHWState(pScrn);
413
414 /*
415 * If the driver can do gamma correction, it should call xf86SetGamma() here.
416 */
417 {
418 Gamma zeros = { 0.0, 0.0, 0.0 };
419
420 if (!xf86SetGamma(pScrn, zeros)) {
421 return FALSE;
422 }
423 }
424
425 if (pScrn->modes == NULL) {
426 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No modes.\n");
427 return FALSE;
428 }
429
430 pScrn->currentMode = pScrn->modes;
431
432 /* Set display resolution */
433 xf86SetDpi(pScrn, 0, 0);
434
435 /* Load the required sub modules */
436 if (!xf86LoadSubModule(pScrn, "fb")) {
437 return FALSE;
438 }
439
440 xf86LoadSubModule(pScrn, "exa");
441
442 #ifdef DRI2
443 xf86LoadSubModule(pScrn, "dri2");
444 #endif
445
446 return TRUE;
447 }
448
449 static Bool
450 SaveHWState(ScrnInfoPtr pScrn)
451 {
452 /*xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);*/
453
454 return TRUE;
455 }
456
457 static Bool
458 RestoreHWState(ScrnInfoPtr pScrn)
459 {
460 /*xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);*/
461
462 return TRUE;
463 }
464
465 static void xorgBlockHandler(int i, pointer blockData, pointer pTimeout,
466 pointer pReadmask)
467 {
468 ScreenPtr pScreen = screenInfo.screens[i];
469 modesettingPtr ms = modesettingPTR(xf86Screens[pScreen->myNum]);
470
471 pScreen->BlockHandler = ms->blockHandler;
472 pScreen->BlockHandler(i, blockData, pTimeout, pReadmask);
473 pScreen->BlockHandler = xorgBlockHandler;
474
475 ms->ctx->flush(ms->ctx, PIPE_FLUSH_RENDER_CACHE, NULL);
476
477 #ifdef DRM_MODE_FEATURE_DIRTYFB
478 {
479 RegionPtr dirty = DamageRegion(ms->damage);
480 unsigned num_cliprects = REGION_NUM_RECTS(dirty);
481
482 if (num_cliprects) {
483 drmModeClip *clip = alloca(num_cliprects * sizeof(drmModeClip));
484 BoxPtr rect = REGION_RECTS(dirty);
485 int i;
486
487 /* XXX no need for copy? */
488 for (i = 0; i < num_cliprects; i++, rect++) {
489 clip[i].x1 = rect->x1;
490 clip[i].y1 = rect->y1;
491 clip[i].x2 = rect->x2;
492 clip[i].y2 = rect->y2;
493 }
494
495 /* TODO query connector property to see if this is needed */
496 drmModeDirtyFB(ms->fd, ms->fb_id, clip, num_cliprects);
497
498 DamageEmpty(ms->damage);
499 }
500 }
501 #endif
502 }
503
504 static Bool
505 CreateScreenResources(ScreenPtr pScreen)
506 {
507 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
508 modesettingPtr ms = modesettingPTR(pScrn);
509 PixmapPtr rootPixmap;
510 Bool ret;
511
512 ms->noEvict = TRUE;
513
514 pScreen->CreateScreenResources = ms->createScreenResources;
515 ret = pScreen->CreateScreenResources(pScreen);
516 pScreen->CreateScreenResources = CreateScreenResources;
517
518 BindTextureToRoot(pScrn);
519
520 ms->noEvict = FALSE;
521
522 AdjustFrame(pScrn->scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
523
524 #ifdef DRM_MODE_FEATURE_DIRTYFB
525 rootPixmap = pScreen->GetScreenPixmap(pScreen);
526 ms->damage = DamageCreate(NULL, NULL, DamageReportNone, TRUE,
527 pScreen, rootPixmap);
528
529 if (ms->damage) {
530 DamageRegister(&rootPixmap->drawable, ms->damage);
531
532 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Damage tracking initialized\n");
533 } else {
534 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
535 "Failed to create screen damage record\n");
536 return FALSE;
537 }
538 #else
539 (void)rootPixmap;
540 #endif
541
542 return ret;
543 }
544
545 static Bool
546 ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
547 {
548 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
549 modesettingPtr ms = modesettingPTR(pScrn);
550 VisualPtr visual;
551
552 if (!InitDRM(pScrn))
553 return FALSE;
554
555 if (!ms->screen) {
556 ms->screen = ms->api->create_screen(ms->api, ms->fd, NULL);
557
558 if (!ms->screen) {
559 FatalError("Could not init pipe_screen\n");
560 return FALSE;
561 }
562 }
563
564 pScrn->pScreen = pScreen;
565
566 /* HW dependent - FIXME */
567 pScrn->displayWidth = pScrn->virtualX;
568
569 miClearVisualTypes();
570
571 if (!miSetVisualTypes(pScrn->depth,
572 miGetDefaultVisualMask(pScrn->depth),
573 pScrn->rgbBits, pScrn->defaultVisual))
574 return FALSE;
575
576 if (!miSetPixmapDepths())
577 return FALSE;
578
579 pScrn->memPhysBase = 0;
580 pScrn->fbOffset = 0;
581
582 if (!fbScreenInit(pScreen, NULL,
583 pScrn->virtualX, pScrn->virtualY,
584 pScrn->xDpi, pScrn->yDpi,
585 pScrn->displayWidth, pScrn->bitsPerPixel))
586 return FALSE;
587
588 if (pScrn->bitsPerPixel > 8) {
589 /* Fixup RGB ordering */
590 visual = pScreen->visuals + pScreen->numVisuals;
591 while (--visual >= pScreen->visuals) {
592 if ((visual->class | DynamicClass) == DirectColor) {
593 visual->offsetRed = pScrn->offset.red;
594 visual->offsetGreen = pScrn->offset.green;
595 visual->offsetBlue = pScrn->offset.blue;
596 visual->redMask = pScrn->mask.red;
597 visual->greenMask = pScrn->mask.green;
598 visual->blueMask = pScrn->mask.blue;
599 }
600 }
601 }
602
603 fbPictureInit(pScreen, NULL, 0);
604
605 ms->blockHandler = pScreen->BlockHandler;
606 pScreen->BlockHandler = xorgBlockHandler;
607 ms->createScreenResources = pScreen->CreateScreenResources;
608 pScreen->CreateScreenResources = CreateScreenResources;
609
610 xf86SetBlackWhitePixels(pScreen);
611
612 ms->exa = xorg_exa_init(pScrn);
613 ms->debug_fallback = debug_get_bool_option("XORG_DEBUG_FALLBACK", TRUE);
614
615 xorg_init_video(pScreen);
616
617 miInitializeBackingStore(pScreen);
618 xf86SetBackingStore(pScreen);
619 xf86SetSilkenMouse(pScreen);
620 miDCInitialize(pScreen, xf86GetPointerScreenFuncs());
621
622 /* Need to extend HWcursor support to handle mask interleave */
623 if (!ms->SWCursor)
624 xf86_cursors_init(pScreen, 64, 64,
625 HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_64 |
626 HARDWARE_CURSOR_ARGB);
627
628 /* Must force it before EnterVT, so we are in control of VT and
629 * later memory should be bound when allocating, e.g rotate_mem */
630 pScrn->vtSema = TRUE;
631
632 pScreen->SaveScreen = xf86SaveScreen;
633 ms->CloseScreen = pScreen->CloseScreen;
634 pScreen->CloseScreen = CloseScreen;
635
636 if (!xf86CrtcScreenInit(pScreen))
637 return FALSE;
638
639 if (!miCreateDefColormap(pScreen))
640 return FALSE;
641
642 xf86DPMSInit(pScreen, xf86DPMSSet, 0);
643
644 if (serverGeneration == 1)
645 xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
646
647 #if 1
648 #ifdef DRI2
649 driScreenInit(pScreen);
650 #endif
651 #endif
652
653 return EnterVT(scrnIndex, 1);
654 }
655
656 static void
657 AdjustFrame(int scrnIndex, int x, int y, int flags)
658 {
659 ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
660 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
661 xf86OutputPtr output = config->output[config->compat_output];
662 xf86CrtcPtr crtc = output->crtc;
663
664 if (crtc && crtc->enabled) {
665 crtc->funcs->set_mode_major(crtc, pScrn->currentMode,
666 RR_Rotate_0, x, y);
667 crtc->x = output->initial_x + x;
668 crtc->y = output->initial_y + y;
669 }
670 }
671
672 static void
673 FreeScreen(int scrnIndex, int flags)
674 {
675 FreeRec(xf86Screens[scrnIndex]);
676 }
677
678 static void
679 LeaveVT(int scrnIndex, int flags)
680 {
681 ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
682 modesettingPtr ms = modesettingPTR(pScrn);
683 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
684 int o;
685
686 for (o = 0; o < config->num_crtc; o++) {
687 xf86CrtcPtr crtc = config->crtc[o];
688
689 crtc_cursor_destroy(crtc);
690
691 if (crtc->rotatedPixmap || crtc->rotatedData) {
692 crtc->funcs->shadow_destroy(crtc, crtc->rotatedPixmap,
693 crtc->rotatedData);
694 crtc->rotatedPixmap = NULL;
695 crtc->rotatedData = NULL;
696 }
697 }
698
699 drmModeRmFB(ms->fd, ms->fb_id);
700
701 RestoreHWState(pScrn);
702
703 if (drmDropMaster(ms->fd))
704 xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
705 "drmDropMaster failed: %s\n", strerror(errno));
706
707 pScrn->vtSema = FALSE;
708 }
709
710 /*
711 * This gets called when gaining control of the VT, and from ScreenInit().
712 */
713 static Bool
714 EnterVT(int scrnIndex, int flags)
715 {
716 ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
717 modesettingPtr ms = modesettingPTR(pScrn);
718
719 if (drmSetMaster(ms->fd)) {
720 if (errno == EINVAL) {
721 xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
722 "drmSetMaster failed: 2.6.29 or newer kernel required for "
723 "multi-server DRI\n");
724 } else {
725 xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
726 "drmSetMaster failed: %s\n", strerror(errno));
727 }
728 }
729
730 /*
731 * Only save state once per server generation since that's what most
732 * drivers do. Could change this to save state at each VT enter.
733 */
734 if (ms->SaveGeneration != serverGeneration) {
735 ms->SaveGeneration = serverGeneration;
736 SaveHWState(pScrn);
737 }
738
739 if (!CreateFrontBuffer(pScrn))
740 return FALSE;
741
742 if (!flags && !BindTextureToRoot(pScrn))
743 return FALSE;
744
745 if (!xf86SetDesiredModes(pScrn))
746 return FALSE;
747
748 return TRUE;
749 }
750
751 static Bool
752 SwitchMode(int scrnIndex, DisplayModePtr mode, int flags)
753 {
754 ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
755
756 return xf86SetSingleMode(pScrn, mode, RR_Rotate_0);
757 }
758
759 static Bool
760 CloseScreen(int scrnIndex, ScreenPtr pScreen)
761 {
762 ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
763 modesettingPtr ms = modesettingPTR(pScrn);
764
765 if (pScrn->vtSema) {
766 LeaveVT(scrnIndex, 0);
767 }
768 #ifdef DRI2
769 driCloseScreen(pScreen);
770 #endif
771
772 pScreen->BlockHandler = ms->blockHandler;
773 pScreen->CreateScreenResources = ms->createScreenResources;
774
775 #ifdef DRM_MODE_FEATURE_DIRTYFB
776 if (ms->damage) {
777 DamageUnregister(&pScreen->GetScreenPixmap(pScreen)->drawable, ms->damage);
778 DamageDestroy(ms->damage);
779 ms->damage = NULL;
780 }
781 #endif
782
783 pipe_texture_reference(&ms->root_texture, NULL);
784
785 if (ms->exa)
786 xorg_exa_close(pScrn);
787
788 if (ms->api && ms->api->destroy)
789 ms->api->destroy(ms->api);
790 ms->api = NULL;
791
792 drmClose(ms->fd);
793 ms->fd = -1;
794
795 pScrn->vtSema = FALSE;
796 pScreen->CloseScreen = ms->CloseScreen;
797 return (*pScreen->CloseScreen) (scrnIndex, pScreen);
798 }
799
800 static ModeStatus
801 ValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags)
802 {
803 return MODE_OK;
804 }
805
806 /* vim: set sw=4 ts=8 sts=4: */