1/************************************************************************** 2 3Copyright 2001 VA Linux Systems Inc., Fremont, California. 4Copyright © 2002 by David Dawes 5 6All Rights Reserved. 7 8Permission is hereby granted, free of charge, to any person obtaining a 9copy of this software and associated documentation files (the "Software"), 10to deal in the Software without restriction, including without limitation 11on the rights to use, copy, modify, merge, publish, distribute, sub 12license, and/or sell copies of the Software, and to permit persons to whom 13the Software is furnished to do so, subject to the following conditions: 14 15The above copyright notice and this permission notice (including the next 16paragraph) shall be included in all copies or substantial portions of the 17Software. 18 19THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 22THE COPYRIGHT HOLDERS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, 23DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 24OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 25USE OR OTHER DEALINGS IN THE SOFTWARE. 26 27**************************************************************************/ 28 29/* 30 * Authors: Jeff Hartmann <jhartmann@valinux.com> 31 * Abraham van der Merwe <abraham@2d3d.co.za> 32 * David Dawes <dawes@xfree86.org> 33 * Alan Hourihane <alanh@tungstengraphics.com> 34 */ 35 36#ifdef HAVE_CONFIG_H 37#include "config.h" 38#endif 39 40#include <string.h> 41#include <stdio.h> 42#include <unistd.h> 43#include <stdlib.h> 44#include <stdio.h> 45#include <errno.h> 46 47#include "sna.h" 48#include "sna_module.h" 49#include "sna_video.h" 50 51#include "intel_driver.h" 52#include "intel_options.h" 53 54#include <xf86cmap.h> 55#include <xf86drm.h> 56#include <xf86RandR12.h> 57#include <mi.h> 58#include <micmap.h> 59 60#include <sys/ioctl.h> 61#include <sys/fcntl.h> 62#include <sys/poll.h> 63#include "i915_drm.h" 64 65#ifdef HAVE_VALGRIND 66#include <valgrind.h> 67#include <memcheck.h> 68#endif 69 70#if HAVE_DOT_GIT 71#include "git_version.h" 72#endif 73 74#ifdef TEARFREE 75#define ENABLE_TEAR_FREE TRUE 76#else 77#define ENABLE_TEAR_FREE FALSE 78#endif 79 80DevPrivateKeyRec sna_pixmap_key; 81DevPrivateKeyRec sna_gc_key; 82DevPrivateKeyRec sna_window_key; 83DevPrivateKeyRec sna_glyph_key; 84DevPrivateKeyRec sna_client_key; 85 86static void 87sna_load_palette(ScrnInfoPtr scrn, int numColors, int *indices, 88 LOCO * colors, VisualPtr pVisual) 89{ 90 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); 91 int p, n, i, j; 92 uint16_t lut_r[256], lut_g[256], lut_b[256]; 93 94 DBG(("%s\n", __FUNCTION__)); 95 96 for (p = 0; p < xf86_config->num_crtc; p++) { 97 xf86CrtcPtr crtc = xf86_config->crtc[p]; 98 99#define C(I,RGB) (colors[I].RGB << 8 | colors[I].RGB) 100 switch (scrn->depth) { 101 case 15: 102 for (n = 0; n < numColors; n++) { 103 i = indices[n]; 104 for (j = 0; j < 8; j++) { 105 lut_r[8*i + j] = C(i, red); 106 lut_g[8*i + j] = C(i, green); 107 lut_b[8*i + j] = C(i, blue); 108 } 109 } 110 break; 111 case 16: 112 for (n = 0; n < numColors; n++) { 113 i = indices[n]; 114 115 if (i <= 31) { 116 for (j = 0; j < 8; j++) { 117 lut_r[8*i + j] = C(i, red); 118 lut_b[8*i + j] = C(i, blue); 119 } 120 } 121 122 for (j = 0; j < 4; j++) 123 lut_g[4*i + j] = C(i, green); 124 } 125 break; 126 default: 127 for (n = 0; n < numColors; n++) { 128 i = indices[n]; 129 lut_r[i] = C(i, red); 130 lut_g[i] = C(i, green); 131 lut_b[i] = C(i, blue); 132 } 133 break; 134 } 135#undef C 136 137 /* Make the change through RandR */ 138#ifdef RANDR_12_INTERFACE 139 RRCrtcGammaSet(crtc->randr_crtc, lut_r, lut_g, lut_b); 140#else 141 crtc->funcs->gamma_set(crtc, lut_r, lut_g, lut_b, 256); 142#endif 143 } 144} 145 146static void 147sna_set_fallback_mode(ScrnInfoPtr scrn) 148{ 149 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn); 150 xf86OutputPtr output = NULL; 151 xf86CrtcPtr crtc = NULL; 152 int n; 153 154 if ((unsigned)config->compat_output < config->num_output) { 155 output = config->output[config->compat_output]; 156 crtc = output->crtc; 157 } 158 159 for (n = 0; n < config->num_output; n++) 160 config->output[n]->crtc = NULL; 161 for (n = 0; n < config->num_crtc; n++) 162 config->crtc[n]->enabled = FALSE; 163 164 if (output && crtc) { 165 DisplayModePtr mode; 166 167 output->crtc = crtc; 168 169 mode = xf86OutputFindClosestMode(output, scrn->currentMode); 170 if (mode && 171 xf86CrtcSetModeTransform(crtc, mode, RR_Rotate_0, NULL, 0, 0)) { 172 crtc->desiredMode = *mode; 173 crtc->desiredMode.prev = crtc->desiredMode.next = NULL; 174 crtc->desiredMode.name = NULL; 175 crtc->desiredMode.PrivSize = 0; 176 crtc->desiredMode.PrivFlags = 0; 177 crtc->desiredMode.Private = NULL; 178 crtc->desiredRotation = RR_Rotate_0; 179 crtc->desiredTransformPresent = FALSE; 180 crtc->desiredX = 0; 181 crtc->desiredY = 0; 182 crtc->enabled = TRUE; 183 } 184 } 185 186 xf86DisableUnusedFunctions(scrn); 187#ifdef RANDR_12_INTERFACE 188 if (get_root_window(scrn->pScreen)) 189 xf86RandR12TellChanged(scrn->pScreen); 190#endif 191} 192 193static Bool sna_set_desired_mode(struct sna *sna) 194{ 195 ScrnInfoPtr scrn = sna->scrn; 196 197 DBG(("%s\n", __FUNCTION__)); 198 199 if (!xf86SetDesiredModes(scrn)) { 200 xf86DrvMsg(scrn->scrnIndex, X_WARNING, 201 "failed to restore desired modes on VT switch\n"); 202 sna_set_fallback_mode(scrn); 203 } 204 205 sna_mode_check(sna); 206 return TRUE; 207} 208 209/** 210 * Adjust the screen pixmap for the current location of the front buffer. 211 * This is done at EnterVT when buffers are bound as long as the resources 212 * have already been created, but the first EnterVT happens before 213 * CreateScreenResources. 214 */ 215static Bool sna_create_screen_resources(ScreenPtr screen) 216{ 217 struct sna *sna = to_sna_from_screen(screen); 218 PixmapPtr new_front; 219 unsigned hint; 220 221 DBG(("%s(%dx%d@%d)\n", __FUNCTION__, 222 screen->width, screen->height, screen->rootDepth)); 223 224 assert(sna->scrn == xf86ScreenToScrn(screen)); 225 assert(sna->scrn->pScreen == screen); 226 227 /* free the data used during miInitScreen */ 228 free(screen->devPrivate); 229 screen->devPrivate = NULL; 230 231 sna_accel_create(sna); 232 233 hint = SNA_CREATE_FB; 234 if (sna->flags & SNA_IS_HOSTED) 235 hint = 0; 236 237 new_front = screen->CreatePixmap(screen, 238 screen->width, 239 screen->height, 240 screen->rootDepth, 241 hint); 242 if (!new_front) { 243 xf86DrvMsg(screen->myNum, X_ERROR, 244 "[intel] Unable to create front buffer %dx%d at depth %d\n", 245 screen->width, 246 screen->height, 247 screen->rootDepth); 248 249 return FALSE; 250 } 251 252 /* Prefer to use the GPU for rendering into the eventual scanout 253 * bo so that we do not unduly stall when it is time to attach 254 * it to the CRTCs. 255 */ 256 (void)sna_pixmap_force_to_gpu(new_front, MOVE_READ | __MOVE_SCANOUT); 257 258 screen->SetScreenPixmap(new_front); 259 assert(screen->GetScreenPixmap(screen) == new_front); 260 assert(sna->front == new_front); 261 screen->DestroyPixmap(new_front); /* transfer ownership to screen */ 262 263 sna_mode_set_primary(sna); 264 265 /* Try to become master and copy the current fbcon before the 266 * actual VT switch. If we fail here, we will try to reset the 267 * mode in the eventual VT switch. This can fail if systemd has 268 * already revoked our KMS privileges, so just carry on regardless, 269 * and hope that everything is sorted after the VT switch. 270 */ 271 if (intel_get_master(sna->dev) == 0) { 272 /* Only preserve the fbcon, not any subsequent server regens */ 273 if (serverGeneration == 1 && (sna->flags & SNA_IS_HOSTED) == 0) 274 sna_copy_fbcon(sna); 275 276 (void)sna_set_desired_mode(sna); 277 } 278 279 return TRUE; 280} 281 282static Bool sna_save_screen(ScreenPtr screen, int mode) 283{ 284 ScrnInfoPtr scrn = xf86ScreenToScrn(screen); 285 286 DBG(("%s(mode=%d)\n", __FUNCTION__, mode)); 287 if (!scrn->vtSema) 288 return FALSE; 289 290 xf86SaveScreen(screen, mode); 291 sna_crtc_config_notify(screen); 292 return TRUE; 293} 294 295static void sna_dpms_set(ScrnInfoPtr scrn, int mode, int flags) 296{ 297 DBG(("%s(mode=%d, flags=%d)\n", __FUNCTION__, mode)); 298 if (!scrn->vtSema) 299 return; 300 301 xf86DPMSSet(scrn, mode, flags); 302 sna_crtc_config_notify(xf86ScrnToScreen(scrn)); 303} 304 305static void sna_selftest(void) 306{ 307 sna_damage_selftest(); 308} 309 310static bool has_vsync(struct sna *sna) 311{ 312 if (sna->flags & SNA_IS_HOSTED) 313 return false; 314 315 return true; 316} 317 318static void sna_setup_capabilities(ScrnInfoPtr scrn, int fd) 319{ 320#if HAS_PIXMAP_SHARING && defined(DRM_CAP_PRIME) 321 uint64_t value; 322 323 scrn->capabilities = 0; 324 if (drmGetCap(fd, DRM_CAP_PRIME, &value) == 0) { 325 if (value & DRM_PRIME_CAP_EXPORT) 326 scrn->capabilities |= RR_Capability_SourceOutput | RR_Capability_SinkOffload; 327 if (value & DRM_PRIME_CAP_IMPORT) 328 scrn->capabilities |= RR_Capability_SinkOutput; 329 } 330#endif 331} 332 333static int 334namecmp(const char *s1, const char *s2) 335{ 336 char c1, c2; 337 338 if (!s1 || *s1 == 0) { 339 if (!s2 || *s2 == 0) 340 return 0; 341 else 342 return 1; 343 } 344 345 while (*s1 == '_' || *s1 == ' ' || *s1 == '\t') 346 s1++; 347 348 while (*s2 == '_' || *s2 == ' ' || *s2 == '\t') 349 s2++; 350 351 c1 = isupper(*s1) ? tolower(*s1) : *s1; 352 c2 = isupper(*s2) ? tolower(*s2) : *s2; 353 while (c1 == c2) { 354 if (c1 == '\0') 355 return 0; 356 357 s1++; 358 while (*s1 == '_' || *s1 == ' ' || *s1 == '\t') 359 s1++; 360 361 s2++; 362 while (*s2 == '_' || *s2 == ' ' || *s2 == '\t') 363 s2++; 364 365 c1 = isupper(*s1) ? tolower(*s1) : *s1; 366 c2 = isupper(*s2) ? tolower(*s2) : *s2; 367 } 368 369 return c1 - c2; 370} 371 372static Bool sna_option_cast_to_bool(struct sna *sna, int id, Bool val) 373{ 374 const char *str = xf86GetOptValString(sna->Options, id); 375 376 if (str == NULL) 377 return val; 378 379 if (*str == '\0') 380 return TRUE; 381 382 if (namecmp(str, "1") == 0) 383 return TRUE; 384 if (namecmp(str, "on") == 0) 385 return TRUE; 386 if (namecmp(str, "true") == 0) 387 return TRUE; 388 if (namecmp(str, "yes") == 0) 389 return TRUE; 390 391 if (namecmp(str, "0") == 0) 392 return FALSE; 393 if (namecmp(str, "off") == 0) 394 return FALSE; 395 if (namecmp(str, "false") == 0) 396 return FALSE; 397 if (namecmp(str, "no") == 0) 398 return FALSE; 399 400 return val; 401} 402 403static unsigned sna_option_cast_to_unsigned(struct sna *sna, int id, unsigned val) 404{ 405 const char *str = xf86GetOptValString(sna->Options, id); 406 unsigned v; 407 408 if (str == NULL || *str == '\0') 409 return val; 410 411 if (namecmp(str, "on") == 0) 412 return val; 413 if (namecmp(str, "true") == 0) 414 return val; 415 if (namecmp(str, "yes") == 0) 416 return val; 417 418 if (namecmp(str, "0") == 0) 419 return 0; 420 if (namecmp(str, "off") == 0) 421 return 0; 422 if (namecmp(str, "false") == 0) 423 return 0; 424 if (namecmp(str, "no") == 0) 425 return 0; 426 427 v = atoi(str); 428 if (v) 429 return v; 430 431 return val; 432} 433 434static Bool fb_supports_depth(int fd, int depth) 435{ 436 struct drm_i915_gem_create create; 437 struct drm_mode_fb_cmd fb; 438 struct drm_mode_card_res res; 439 Bool ret; 440 441 memset(&res, 0, sizeof(res)); 442 (void)drmIoctl(fd, DRM_IOCTL_MODE_GETRESOURCES, &res); 443 if (res.count_crtcs == 0) 444 return TRUE; 445 446 VG_CLEAR(create); 447 create.handle = 0; 448 create.size = 4096; 449 if (drmIoctl(fd, DRM_IOCTL_I915_GEM_CREATE, &create)) 450 return FALSE; 451 452 VG_CLEAR(fb); 453 fb.width = 64; 454 fb.height = 16; 455 fb.pitch = 256; 456 fb.bpp = depth <= 8 ? 8 : depth <= 16 ? 16 : 32; 457 fb.depth = depth; 458 fb.handle = create.handle; 459 460 ret = drmIoctl(fd, DRM_IOCTL_MODE_ADDFB, &fb) == 0; 461 drmModeRmFB(fd, fb.fb_id); 462 463 (void)drmIoctl(fd, DRM_IOCTL_GEM_CLOSE, &create.handle); 464 465 return ret; 466} 467 468static void setup_dri(struct sna *sna) 469{ 470 unsigned level; 471 472 sna->dri2.available = false; 473 sna->dri3.available = false; 474 475 level = sna_option_cast_to_unsigned(sna, OPTION_DRI, ~0); 476#if HAVE_DRI3 477 if (level >= 3) 478 sna->dri3.available = !!xf86LoadSubModule(sna->scrn, "dri3"); 479#endif 480#if HAVE_DRI2 481 if (level >= 2) 482 sna->dri2.available = !!xf86LoadSubModule(sna->scrn, "dri2"); 483#endif 484} 485 486static bool enable_tear_free(struct sna *sna) 487{ 488 if (sna->flags & SNA_LINEAR_FB) 489 return false; 490 491 /* Under certain conditions, we should enable TearFree by default, 492 * for example when the hardware requires pageflipping to run within 493 * its power/performance budget. 494 */ 495 if (sna_mode_wants_tear_free(sna)) 496 return true; 497 498 return ENABLE_TEAR_FREE; 499} 500 501static void setup_tear_free(struct sna *sna) 502{ 503 MessageType from; 504 Bool enable; 505 506 if (sna->flags & SNA_LINEAR_FB) 507 return; 508 509 if ((sna->flags & SNA_HAS_FLIP) == 0) { 510 from = X_PROBED; 511 goto done; 512 } 513 514 if (!xf86GetOptValBool(sna->Options, OPTION_TEAR_FREE, &enable)) { 515 enable = enable_tear_free(sna); 516 from = X_DEFAULT; 517 } else 518 from = X_CONFIG; 519 520 if (enable) 521 sna->flags |= SNA_TEAR_FREE; 522 523done: 524 xf86DrvMsg(sna->scrn->scrnIndex, from, "TearFree %sabled\n", 525 sna->flags & SNA_TEAR_FREE ? "en" : "dis"); 526} 527 528/** 529 * This is called before ScreenInit to do any require probing of screen 530 * configuration. 531 * 532 * This code generally covers probing, module loading, option handling 533 * card mapping, and RandR setup. 534 * 535 * Since xf86InitialConfiguration ends up requiring that we set video modes 536 * in order to detect configuration, we end up having to do a lot of driver 537 * setup (talking to the DRM, mapping the device, etc.) in this function. 538 * As a result, we want to set up that server initialization once rather 539 * that doing it per generation. 540 */ 541static Bool sna_pre_init(ScrnInfoPtr scrn, int probe) 542{ 543 struct sna *sna; 544 char buf[1024]; 545 rgb defaultWeight = { 0, 0, 0 }; 546 EntityInfoPtr pEnt; 547 Gamma zeros = { 0.0, 0.0, 0.0 }; 548 int fd; 549 550 DBG(("%s flags=%x, numEntities=%d\n", 551 __FUNCTION__, probe, scrn->numEntities)); 552 553 if (scrn->numEntities != 1) 554 return FALSE; 555 556 pEnt = xf86GetEntityInfo(scrn->entityList[0]); 557 if (pEnt == NULL) { 558 ERR(("%s: no EntityInfo found for scrn\n", __FUNCTION__)); 559 return FALSE; 560 } 561 562 if (pEnt->location.type != BUS_PCI 563#ifdef XSERVER_PLATFORM_BUS 564 && pEnt->location.type != BUS_PLATFORM 565#endif 566 ) { 567 ERR(("%s: invalid EntityInfo found for scrn, location=%d\n", __FUNCTION__, pEnt->location.type)); 568 return FALSE; 569 } 570 571 if (probe & PROBE_DETECT) 572 return TRUE; 573 574 sna_selftest(); 575 576 probe = 0; 577 if (((uintptr_t)scrn->driverPrivate) & 3) { 578 if (posix_memalign((void **)&sna, 4096, sizeof(*sna))) 579 return FALSE; 580 581 memset(sna, 0, sizeof(*sna)); /* should be unnecessary */ 582 probe = (uintptr_t)scrn->driverPrivate & 1; 583 sna->info = (void *)((uintptr_t)scrn->driverPrivate & ~3); 584 scrn->driverPrivate = sna; 585 586 sna->cpu_features = sna_cpu_detect(); 587 sna->acpi.fd = sna_acpi_open(); 588 } 589 sna = to_sna(scrn); 590 sna->scrn = scrn; 591 sna->pEnt = pEnt; 592 sna->flags = probe; 593 594 scrn->displayWidth = 640; /* default it */ 595 596 scrn->monitor = scrn->confScreen->monitor; 597 scrn->progClock = TRUE; 598 scrn->rgbBits = 8; 599 600 sna->dev = intel_get_device(scrn, &fd); 601 if (sna->dev == NULL) { 602 xf86DrvMsg(scrn->scrnIndex, X_ERROR, 603 "Failed to claim DRM device.\n"); 604 goto cleanup; 605 } 606 607 /* Sanity check */ 608 if (hosted() && (sna->flags & SNA_IS_HOSTED) == 0) { 609 xf86DrvMsg(scrn->scrnIndex, X_ERROR, 610 "Failed to setup hosted device.\n"); 611 goto cleanup; 612 } 613 614 intel_detect_chipset(scrn, sna->dev); 615 xf86DrvMsg(scrn->scrnIndex, X_PROBED, "CPU: %s\n", 616 sna_cpu_features_to_string(sna->cpu_features, buf)); 617 618 if (!xf86SetDepthBpp(scrn, 24, 0, 0, 619 Support32bppFb | 620 SupportConvert24to32 | PreferConvert24to32)) 621 goto cleanup; 622 623 switch (scrn->depth) { 624 case 8: 625 case 15: 626 case 16: 627 case 24: 628 case 30: 629 if ((sna->flags & SNA_IS_HOSTED) || 630 fb_supports_depth(fd, scrn->depth)) 631 break; 632 default: 633 xf86DrvMsg(scrn->scrnIndex, X_ERROR, 634 "Given depth (%d) is not supported by the Intel driver and this chipset.\n", 635 scrn->depth); 636 goto cleanup; 637 } 638 xf86PrintDepthBpp(scrn); 639 640 if (!xf86SetWeight(scrn, defaultWeight, defaultWeight)) 641 goto cleanup; 642 if (!xf86SetDefaultVisual(scrn, -1)) 643 goto cleanup; 644 645 sna->Options = intel_options_get(scrn); 646 if (sna->Options == NULL) 647 goto cleanup; 648 649 sna_setup_capabilities(scrn, fd); 650 651 kgem_init(&sna->kgem, fd, 652 xf86GetPciInfoForEntity(pEnt->index), 653 sna->info->gen); 654 if (xf86ReturnOptValBool(sna->Options, OPTION_ACCEL_DISABLE, FALSE) || 655 !sna_option_cast_to_bool(sna, OPTION_ACCEL_METHOD, TRUE)) { 656 xf86DrvMsg(sna->scrn->scrnIndex, X_CONFIG, 657 "Disabling hardware acceleration.\n"); 658 sna->kgem.wedged = true; 659 } 660 661 if (xf86ReturnOptValBool(sna->Options, OPTION_TILING_FB, FALSE)) 662 sna->flags |= SNA_LINEAR_FB; 663 664 if (xf86ReturnOptValBool(sna->Options, OPTION_DELETE_DP12, FALSE)) 665 sna->flags |= SNA_REMOVE_OUTPUTS; 666 667 if (!xf86ReturnOptValBool(sna->Options, OPTION_SWAPBUFFERS_WAIT, TRUE)) 668 sna->flags |= SNA_NO_WAIT; 669 DBG(("%s: swapbuffer wait? %s\n", __FUNCTION__, sna->flags & SNA_NO_WAIT ? "disabled" : "enabled")); 670 671 if (!has_vsync(sna) || 672 !xf86ReturnOptValBool(sna->Options, OPTION_VSYNC, TRUE)) 673 sna->flags |= SNA_NO_VSYNC; 674 DBG(("%s: vsync? %s\n", __FUNCTION__, sna->flags & SNA_NO_VSYNC ? "disabled" : "enabled")); 675 676 if (sna->flags & SNA_IS_HOSTED || 677 !xf86ReturnOptValBool(sna->Options, OPTION_PAGEFLIP, TRUE)) 678 sna->flags |= SNA_NO_FLIP; 679 DBG(("%s: page flips? %s\n", __FUNCTION__, sna->flags & SNA_NO_FLIP ? "disabled" : "enabled")); 680 681 if ((sna->flags & (SNA_NO_VSYNC | SNA_NO_FLIP | SNA_NO_WAIT)) == 0 && 682 xf86ReturnOptValBool(sna->Options, OPTION_TRIPLE_BUFFER, TRUE)) 683 sna->flags |= SNA_TRIPLE_BUFFER; 684 DBG(("%s: triple buffer? %s\n", __FUNCTION__, sna->flags & SNA_TRIPLE_BUFFER ? "enabled" : "disabled")); 685 686 if (xf86ReturnOptValBool(sna->Options, OPTION_CRTC_PIXMAPS, FALSE)) { 687 xf86DrvMsg(scrn->scrnIndex, X_CONFIG, "Forcing per-crtc-pixmaps.\n"); 688 sna->flags |= SNA_FORCE_SHADOW; 689 } 690 691 if (!sna_mode_pre_init(scrn, sna)) { 692 xf86DrvMsg(scrn->scrnIndex, X_ERROR, 693 "No outputs and no modes.\n"); 694 goto cleanup; 695 } 696 scrn->currentMode = scrn->modes; 697 698 setup_tear_free(sna); 699 700 xf86SetGamma(scrn, zeros); 701 xf86SetDpi(scrn, 0, 0); 702 703 setup_dri(sna); 704 705 sna->present.available = false; 706 if (xf86ReturnOptValBool(sna->Options, OPTION_PRESENT, TRUE)) { 707#if HAVE_PRESENT 708 sna->present.available = !!xf86LoadSubModule(scrn, "present"); 709#endif 710 } 711 712 sna_acpi_init(sna); 713 714 return TRUE; 715 716cleanup: 717 scrn->driverPrivate = (void *)((uintptr_t)sna->info | (sna->flags & SNA_IS_SLAVED) | 2); 718 if (sna->dev) 719 intel_put_device(sna->dev); 720 free(sna); 721 return FALSE; 722} 723 724static bool has_shadow(struct sna *sna) 725{ 726 if (!sna->mode.shadow_damage) 727 return false; 728 729 if (RegionNil(DamageRegion(sna->mode.shadow_damage))) 730 return false; 731 732 return sna->mode.flip_active == 0; 733} 734 735static void 736sna_block_handler(BLOCKHANDLER_ARGS_DECL) 737{ 738#ifndef XF86_SCRN_INTERFACE 739 struct sna *sna = to_sna(xf86Screens[arg]); 740#else 741 struct sna *sna = to_sna_from_screen(arg); 742#endif 743#if ABI_VIDEODRV_VERSION < SET_ABI_VERSION(23, 0) 744 struct timeval **tv = timeout; 745 746 DBG(("%s (tv=%ld.%06ld)\n", __FUNCTION__, 747 *tv ? (*tv)->tv_sec : -1, *tv ? (*tv)->tv_usec : 0)); 748#else 749 int *tv = timeout; 750 751 DBG(("%s (tv=%ld.%06ld)\n", __FUNCTION__, 752 *tv / 1000, *tv % (1000 * 1000))); 753#endif 754 755 sna->BlockHandler(BLOCKHANDLER_ARGS); 756 757#if ABI_VIDEODRV_VERSION < SET_ABI_VERSION(23, 0) 758 if (*tv == NULL || ((*tv)->tv_usec | (*tv)->tv_sec) || has_shadow(sna)) 759#endif 760 sna_accel_block_handler(sna, tv); 761} 762 763static void 764sna_wakeup_handler(WAKEUPHANDLER_ARGS_DECL) 765{ 766#ifndef XF86_SCRN_INTERFACE 767 struct sna *sna = to_sna(xf86Screens[arg]); 768#else 769 struct sna *sna = to_sna_from_screen(arg); 770#endif 771 772 DBG(("%s\n", __FUNCTION__)); 773 774 /* despite all appearances, result is just a signed int */ 775 if ((int)result < 0) 776 return; 777 778 sna_acpi_wakeup(sna); 779 780 sna->WakeupHandler(WAKEUPHANDLER_ARGS); 781 782 sna_accel_wakeup_handler(sna); 783 784 sna_mode_wakeup(sna); 785} 786 787#if HAVE_UDEV 788static void 789sna_handle_uevents(int fd, void *closure) 790{ 791 struct sna *sna = closure; 792 struct udev_device *dev; 793 const char *str; 794 struct stat s; 795 dev_t udev_devnum; 796 797 DBG(("%s\n", __FUNCTION__)); 798 799 dev = udev_monitor_receive_device(sna->uevent_monitor); 800 if (!dev) 801 return; 802 803 udev_devnum = udev_device_get_devnum(dev); 804 if (fstat(sna->kgem.fd, &s) || memcmp(&s.st_rdev, &udev_devnum, sizeof (dev_t))) { 805 udev_device_unref(dev); 806 return; 807 } 808 809 str = udev_device_get_property_value(dev, "HOTPLUG"); 810 if (str && atoi(str) == 1) { 811 ScrnInfoPtr scrn = sna->scrn; 812 813 DBG(("%s: hotplug event (vtSema?=%d)\n", __FUNCTION__, scrn->vtSema)); 814 815 if (scrn->vtSema) { 816 sna_mode_discover(sna); 817 sna_mode_check(sna); 818 RRGetInfo(xf86ScrnToScreen(scrn), TRUE); 819 } else 820 sna->flags |= SNA_REPROBE; 821 } 822 823 udev_device_unref(dev); 824} 825 826static void 827sna_uevent_init(struct sna *sna) 828{ 829 struct udev *u; 830 struct udev_monitor *mon; 831 MessageType from = X_CONFIG; 832 833 if (sna->flags & SNA_IS_HOSTED) 834 return; 835 836 DBG(("%s\n", __FUNCTION__)); 837 838 /* RandR will be disabled if Xinerama is active, and so generating 839 * RR hotplug events is then verboten. 840 */ 841 if (!dixPrivateKeyRegistered(rrPrivKey)) 842 goto out; 843 844 u = NULL; 845 if (xf86ReturnOptValBool(sna->Options, OPTION_HOTPLUG, TRUE)) 846 u = udev_new(); 847 if (!u) 848 goto out; 849 850 from = X_DEFAULT; 851 852 mon = udev_monitor_new_from_netlink(u, "udev"); 853 if (!mon) 854 goto err_dev; 855 856 if (udev_monitor_filter_add_match_subsystem_devtype(mon, "drm", "drm_minor") < 0) 857 goto err_monitor; 858 859 if (udev_monitor_enable_receiving(mon) < 0) 860 goto err_monitor; 861 862 sna->uevent_handler = xf86AddGeneralHandler(udev_monitor_get_fd(mon), 863 sna_handle_uevents, sna); 864 if (!sna->uevent_handler) 865 goto err_monitor; 866 867 sna->uevent_monitor = mon; 868out: 869 xf86DrvMsg(sna->scrn->scrnIndex, from, "display hotplug detection %s\n", 870 sna->uevent_monitor ? "enabled" : "disabled"); 871 return; 872 873err_monitor: 874 udev_monitor_unref(mon); 875err_dev: 876 udev_unref(u); 877 goto out; 878} 879 880static bool sna_uevent_poll(struct sna *sna) 881{ 882 struct pollfd pfd; 883 884 if (sna->uevent_monitor == NULL) 885 return false; 886 887 pfd.fd = udev_monitor_get_fd(sna->uevent_monitor); 888 pfd.events = POLLIN; 889 890 while (poll(&pfd, 1, 0) > 0) 891 sna_handle_uevents(pfd.fd, sna); 892 893 return true; 894} 895 896static void 897sna_uevent_fini(struct sna *sna) 898{ 899 struct udev *u; 900 901 if (sna->uevent_handler == NULL) 902 return; 903 904 xf86RemoveGeneralHandler(sna->uevent_handler); 905 906 u = udev_monitor_get_udev(sna->uevent_monitor); 907 udev_monitor_unref(sna->uevent_monitor); 908 udev_unref(u); 909 910 sna->uevent_handler = NULL; 911 sna->uevent_monitor = NULL; 912 913 DBG(("%s: removed uvent handler\n", __FUNCTION__)); 914} 915#else 916static void sna_uevent_init(struct sna *sna) { } 917static bool sna_uevent_poll(struct sna *sna) { return false; } 918static void sna_uevent_fini(struct sna *sna) { } 919#endif /* HAVE_UDEV */ 920 921static Bool 922sna_randr_getinfo(ScreenPtr screen, Rotation *rotations) 923{ 924 struct sna *sna = to_sna_from_screen(screen); 925 926 if (!sna_uevent_poll(sna)) 927 sna_mode_discover(sna); 928 929 return sna->mode.rrGetInfo(screen, rotations); 930} 931 932static void sna_leave_vt(VT_FUNC_ARGS_DECL) 933{ 934 SCRN_INFO_PTR(arg); 935 struct sna *sna = to_sna(scrn); 936 937 DBG(("%s\n", __FUNCTION__)); 938 939 sna_accel_leave(sna); 940 sna_mode_reset(sna); 941 942 if (intel_put_master(sna->dev)) 943 xf86DrvMsg(scrn->scrnIndex, X_WARNING, 944 "drmDropMaster failed: %s\n", strerror(errno)); 945} 946 947static Bool sna_early_close_screen(CLOSE_SCREEN_ARGS_DECL) 948{ 949 ScrnInfoPtr scrn = xf86ScreenToScrn(screen); 950 struct sna *sna = to_sna(scrn); 951 952 DBG(("%s\n", __FUNCTION__)); 953 954 /* XXX Note that we will leak kernel resources if !vtSema */ 955 956 sna_uevent_fini(sna); 957 sna_mode_close(sna); 958 959 if (sna->present.open) { 960 sna_present_close(sna, screen); 961 sna->present.open = false; 962 } 963 964 if (sna->dri3.open) { 965 sna_dri3_close(sna, screen); 966 sna->dri3.open = false; 967 } 968 969 if (sna->dri2.open) { 970 sna_dri2_close(sna, screen); 971 sna->dri2.open = false; 972 } 973 974 if (sna->front) { 975 screen->DestroyPixmap(sna->front); 976 sna->front = NULL; 977 } 978 979 if (scrn->vtSema) { 980 intel_put_master(sna->dev); 981 scrn->vtSema = FALSE; 982 } 983 984 return sna->CloseScreen(CLOSE_SCREEN_ARGS); 985} 986 987static Bool sna_late_close_screen(CLOSE_SCREEN_ARGS_DECL) 988{ 989 struct sna *sna = to_sna_from_screen(screen); 990 DepthPtr depths; 991 int d; 992 993 DBG(("%s\n", __FUNCTION__)); 994 995 sna_accel_close(sna); 996 sna_video_close(sna); 997 998 depths = screen->allowedDepths; 999 for (d = 0; d < screen->numDepths; d++) 1000 free(depths[d].vids); 1001 free(depths); 1002 1003 free(screen->visuals); 1004 1005 return TRUE; 1006} 1007 1008static Bool 1009sna_register_all_privates(void) 1010{ 1011#if HAS_DIXREGISTERPRIVATEKEY 1012 if (!dixRegisterPrivateKey(&sna_pixmap_key, PRIVATE_PIXMAP, 1013 3*sizeof(void *))) 1014 return FALSE; 1015 1016 if (!dixRegisterPrivateKey(&sna_gc_key, PRIVATE_GC, 1017 sizeof(FbGCPrivate))) 1018 return FALSE; 1019 1020 if (!dixRegisterPrivateKey(&sna_glyph_key, PRIVATE_GLYPH, 1021 sizeof(struct sna_glyph))) 1022 return FALSE; 1023 1024 if (!dixRegisterPrivateKey(&sna_window_key, PRIVATE_WINDOW, 1025 3*sizeof(void *))) 1026 return FALSE; 1027 1028 if (!dixRegisterPrivateKey(&sna_client_key, PRIVATE_CLIENT, 1029 sizeof(struct sna_client))) 1030 return FALSE; 1031#else 1032 if (!dixRequestPrivate(&sna_pixmap_key, 3*sizeof(void *))) 1033 return FALSE; 1034 1035 if (!dixRequestPrivate(&sna_gc_key, sizeof(FbGCPrivate))) 1036 return FALSE; 1037 1038 if (!dixRequestPrivate(&sna_glyph_key, sizeof(struct sna_glyph))) 1039 return FALSE; 1040 1041 if (!dixRequestPrivate(&sna_window_key, 3*sizeof(void *))) 1042 return FALSE; 1043 1044 if (!dixRequestPrivate(&sna_client_key, sizeof(struct sna_client))) 1045 return FALSE; 1046#endif 1047 1048 return TRUE; 1049} 1050 1051static void sna_dri_init(struct sna *sna, ScreenPtr screen) 1052{ 1053 char str[128] = ""; 1054 1055 if (sna->dri2.available) 1056 sna->dri2.open = sna_dri2_open(sna, screen); 1057 if (sna->dri2.open) 1058 strcat(str, "DRI2 "); 1059 1060 if (sna->dri3.available) 1061 sna->dri3.open = sna_dri3_open(sna, screen); 1062 if (sna->dri3.open) 1063 strcat(str, "DRI3 "); 1064 1065 if (*str) 1066 xf86DrvMsg(sna->scrn->scrnIndex, X_INFO, 1067 "direct rendering: %senabled\n", str); 1068} 1069 1070static Bool 1071sna_mode_init(struct sna *sna, ScreenPtr screen) 1072{ 1073 rrScrPrivPtr rp; 1074 1075 if (!xf86CrtcScreenInit(screen)) 1076 return FALSE; 1077 1078 xf86RandR12SetRotations(screen, RR_Rotate_All | RR_Reflect_All); 1079 xf86RandR12SetTransformSupport(screen, TRUE); 1080 1081 /* Wrap RR queries to catch pending MST topology changes */ 1082 rp = rrGetScrPriv(screen); 1083 if (rp) { 1084 sna->mode.rrGetInfo = rp->rrGetInfo; 1085 rp->rrGetInfo = sna_randr_getinfo; 1086 } 1087 1088 return TRUE; 1089} 1090 1091static Bool 1092sna_screen_init(SCREEN_INIT_ARGS_DECL) 1093{ 1094 ScrnInfoPtr scrn = xf86ScreenToScrn(screen); 1095 struct sna *sna = to_sna(scrn); 1096 VisualPtr visuals; 1097 DepthPtr depths; 1098 int nvisuals; 1099 int ndepths; 1100 int rootdepth; 1101 VisualID defaultVisual; 1102 1103 DBG(("%s\n", __FUNCTION__)); 1104 1105 assert(sna->scrn == scrn); 1106 assert(scrn->pScreen == NULL); /* set afterwards */ 1107 1108 assert(sna->freed_pixmap == NULL); 1109 1110 if (!sna_register_all_privates()) 1111 return FALSE; 1112 1113 scrn->videoRam = sna->kgem.aperture_mappable * 4; /* Page to KiB */ 1114 1115 miClearVisualTypes(); 1116 if (!miSetVisualTypes(scrn->depth, 1117 miGetDefaultVisualMask(scrn->depth), 1118 scrn->rgbBits, scrn->defaultVisual)) 1119 return FALSE; 1120 if (!miSetPixmapDepths()) 1121 return FALSE; 1122 1123 rootdepth = 0; 1124 if (!miInitVisuals(&visuals, &depths, &nvisuals, &ndepths, &rootdepth, 1125 &defaultVisual, 1126 ((unsigned long)1 << (scrn->bitsPerPixel - 1)), 1127 8, -1)) 1128 return FALSE; 1129 1130 if (!miScreenInit(screen, NULL, 1131 scrn->virtualX, scrn->virtualY, 1132 scrn->xDpi, scrn->yDpi, 0, 1133 rootdepth, ndepths, depths, 1134 defaultVisual, nvisuals, visuals)) 1135 return FALSE; 1136 1137 if (scrn->bitsPerPixel > 8) { 1138 /* Fixup RGB ordering */ 1139 VisualPtr visual = screen->visuals + screen->numVisuals; 1140 while (--visual >= screen->visuals) { 1141 if ((visual->class | DynamicClass) == DirectColor) { 1142 visual->offsetRed = scrn->offset.red; 1143 visual->offsetGreen = scrn->offset.green; 1144 visual->offsetBlue = scrn->offset.blue; 1145 visual->redMask = scrn->mask.red; 1146 visual->greenMask = scrn->mask.green; 1147 visual->blueMask = scrn->mask.blue; 1148 } 1149 } 1150 } 1151 1152 assert(screen->CloseScreen == NULL); 1153 screen->CloseScreen = sna_late_close_screen; 1154 if (!sna_accel_init(screen, sna)) { 1155 xf86DrvMsg(scrn->scrnIndex, X_ERROR, 1156 "Hardware acceleration initialization failed\n"); 1157 return FALSE; 1158 } 1159 1160 xf86SetBlackWhitePixels(screen); 1161 1162 xf86SetBackingStore(screen); 1163 xf86SetSilkenMouse(screen); 1164 if (!miDCInitialize(screen, xf86GetPointerScreenFuncs())) 1165 return FALSE; 1166 1167 if (sna_cursors_init(screen, sna)) 1168 xf86DrvMsg(scrn->scrnIndex, X_INFO, "HW Cursor enabled\n"); 1169 1170 /* Must force it before EnterVT, so we are in control of VT and 1171 * later memory should be bound when allocating, e.g rotate_mem */ 1172 scrn->vtSema = TRUE; 1173 1174 sna->BlockHandler = screen->BlockHandler; 1175 screen->BlockHandler = sna_block_handler; 1176 1177 sna->WakeupHandler = screen->WakeupHandler; 1178 screen->WakeupHandler = sna_wakeup_handler; 1179 1180 screen->SaveScreen = sna_save_screen; 1181 screen->CreateScreenResources = sna_create_screen_resources; 1182 1183 sna->CloseScreen = screen->CloseScreen; 1184 screen->CloseScreen = sna_early_close_screen; 1185 1186 if (!sna_mode_init(sna, screen)) 1187 return FALSE; 1188 1189 if (!miCreateDefColormap(screen)) 1190 return FALSE; 1191 1192 if (sna->mode.num_real_crtc && 1193 !xf86HandleColormaps(screen, 256, 8, sna_load_palette, NULL, 1194 CMAP_RELOAD_ON_MODE_SWITCH | 1195 CMAP_PALETTED_TRUECOLOR)) 1196 return FALSE; 1197 1198 xf86DPMSInit(screen, sna_dpms_set, 0); 1199 1200 sna_uevent_init(sna); 1201 sna_video_init(sna, screen); 1202 sna_dri_init(sna, screen); 1203 1204 if (sna->present.available) 1205 sna->present.open = sna_present_open(sna, screen); 1206 if (sna->present.open) 1207 xf86DrvMsg(sna->scrn->scrnIndex, X_INFO, 1208 "hardware support for Present enabled\n"); 1209 1210 if (serverGeneration == 1) 1211 xf86ShowUnusedOptions(scrn->scrnIndex, scrn->options); 1212 1213 sna->suspended = FALSE; 1214 1215 return TRUE; 1216} 1217 1218static void sna_adjust_frame(ADJUST_FRAME_ARGS_DECL) 1219{ 1220 SCRN_INFO_PTR(arg); 1221 DBG(("%s(%d, %d)\n", __FUNCTION__, x, y)); 1222 sna_mode_adjust_frame(to_sna(scrn), x, y); 1223} 1224 1225static void sna_free_screen(FREE_SCREEN_ARGS_DECL) 1226{ 1227 SCRN_INFO_PTR(arg); 1228 struct sna *sna = to_sna(scrn); 1229 1230 DBG(("%s [scrn=%p, sna=%p]\n", __FUNCTION__, scrn, sna)); 1231 if (sna == NULL || (uintptr_t)sna & 3) /* beware thieves */ 1232 return; 1233 1234 scrn->driverPrivate = (void *)((uintptr_t)sna->info | (sna->flags & SNA_IS_SLAVED) | 2); 1235 1236 sna_mode_fini(sna); 1237 sna_acpi_fini(sna); 1238 1239 intel_put_device(sna->dev); 1240 free(sna); 1241} 1242 1243static Bool sna_enter_vt(VT_FUNC_ARGS_DECL) 1244{ 1245 SCRN_INFO_PTR(arg); 1246 struct sna *sna = to_sna(scrn); 1247 1248 DBG(("%s\n", __FUNCTION__)); 1249 if (intel_get_master(sna->dev)) 1250 return FALSE; 1251 1252 if (sna->flags & SNA_REPROBE) { 1253 DBG(("%s: reporting deferred hotplug event\n", 1254 __FUNCTION__)); 1255 sna_mode_discover(sna); 1256 RRGetInfo(xf86ScrnToScreen(scrn), TRUE); 1257 sna->flags &= ~SNA_REPROBE; 1258 } 1259 1260 if (!sna_set_desired_mode(sna)) { 1261 intel_put_master(sna->dev); 1262 return FALSE; 1263 } 1264 1265 sna_accel_enter(sna); 1266 return TRUE; 1267} 1268 1269static Bool sna_switch_mode(SWITCH_MODE_ARGS_DECL) 1270{ 1271 SCRN_INFO_PTR(arg); 1272 DBG(("%s\n", __FUNCTION__)); 1273 return xf86SetSingleMode(scrn, mode, RR_Rotate_0); 1274} 1275 1276static ModeStatus 1277sna_valid_mode(SCRN_ARG_TYPE arg, DisplayModePtr mode, Bool verbose, int flags) 1278{ 1279 return MODE_OK; 1280} 1281 1282#ifndef SUSPEND_SLEEP 1283#define SUSPEND_SLEEP 0 1284#endif 1285#ifndef RESUME_SLEEP 1286#define RESUME_SLEEP 0 1287#endif 1288 1289/* 1290 * This function is only required if we need to do anything differently from 1291 * DoApmEvent() in common/xf86PM.c, including if we want to see events other 1292 * than suspend/resume. 1293 */ 1294static Bool sna_pm_event(SCRN_ARG_TYPE arg, pmEvent event, Bool undo) 1295{ 1296 SCRN_INFO_PTR(arg); 1297 struct sna *sna = to_sna(scrn); 1298 1299 DBG(("%s\n", __FUNCTION__)); 1300 1301 switch (event) { 1302 case XF86_APM_SYS_SUSPEND: 1303 case XF86_APM_CRITICAL_SUSPEND: /*do we want to delay a critical suspend? */ 1304 case XF86_APM_USER_SUSPEND: 1305 case XF86_APM_SYS_STANDBY: 1306 case XF86_APM_USER_STANDBY: 1307 if (!undo && !sna->suspended) { 1308 scrn->LeaveVT(VT_FUNC_ARGS(0)); 1309 sna->suspended = TRUE; 1310 sleep(SUSPEND_SLEEP); 1311 } else if (undo && sna->suspended) { 1312 sleep(RESUME_SLEEP); 1313 scrn->EnterVT(VT_FUNC_ARGS(0)); 1314 sna->suspended = FALSE; 1315 } 1316 break; 1317 case XF86_APM_STANDBY_RESUME: 1318 case XF86_APM_NORMAL_RESUME: 1319 case XF86_APM_CRITICAL_RESUME: 1320 if (sna->suspended) { 1321 sleep(RESUME_SLEEP); 1322 scrn->EnterVT(VT_FUNC_ARGS(0)); 1323 sna->suspended = FALSE; 1324 /* 1325 * Turn the screen saver off when resuming. This seems to be 1326 * needed to stop xscreensaver kicking in (when used). 1327 * 1328 * XXX DoApmEvent() should probably call this just like 1329 * xf86VTSwitch() does. Maybe do it here only in 4.2 1330 * compatibility mode. 1331 */ 1332 SaveScreens(SCREEN_SAVER_FORCER, ScreenSaverReset); 1333 } 1334 break; 1335 /* This is currently used for ACPI */ 1336 case XF86_APM_CAPABILITY_CHANGED: 1337 SaveScreens(SCREEN_SAVER_FORCER, ScreenSaverReset); 1338 break; 1339 1340 default: 1341 ERR(("sna_pm_event: received APM event %d\n", event)); 1342 } 1343 return TRUE; 1344} 1345 1346static Bool sna_enter_vt__hosted(VT_FUNC_ARGS_DECL) 1347{ 1348 return TRUE; 1349} 1350 1351static void sna_leave_vt__hosted(VT_FUNC_ARGS_DECL) 1352{ 1353} 1354 1355static void describe_kms(ScrnInfoPtr scrn) 1356{ 1357 int fd = __intel_peek_fd(scrn); 1358 drm_version_t version; 1359 char name[128] = ""; 1360 char date[128] = ""; 1361 1362 memset(&version, 0, sizeof(version)); 1363 version.name_len = sizeof(name) - 1; 1364 version.name = name; 1365 version.date_len = sizeof(date) - 1; 1366 version.date = date; 1367 1368 if (drmIoctl(fd, DRM_IOCTL_VERSION, &version)) 1369 return; 1370 1371 xf86DrvMsg(scrn->scrnIndex, X_INFO, 1372 "Using Kernel Mode Setting driver: %s, version %d.%d.%d %s\n", 1373 version.name, 1374 version.version_major, version.version_minor, version.version_patchlevel, 1375 version.date); 1376} 1377 1378static void describe_sna(ScrnInfoPtr scrn) 1379{ 1380#if defined(USE_GIT_DESCRIBE) 1381 xf86DrvMsg(scrn->scrnIndex, X_INFO, 1382 "SNA compiled from %s\n", git_version); 1383#elif defined(BUILDER_DESCRIPTION) 1384 xf86DrvMsg(scrn->scrnIndex, X_INFO, 1385 "SNA compiled: %s\n", BUILDER_DESCRIPTION); 1386#endif 1387#if !NDEBUG 1388 xf86DrvMsg(scrn->scrnIndex, X_INFO, 1389 "SNA compiled with assertions enabled\n"); 1390#endif 1391#if DEBUG_SYNC 1392 xf86DrvMsg(scrn->scrnIndex, X_INFO, 1393 "SNA compiled with synchronous rendering\n"); 1394#endif 1395#if DEBUG_MEMORY 1396 xf86DrvMsg(scrn->scrnIndex, X_INFO, 1397 "SNA compiled with memory allocation reporting enabled\n"); 1398#endif 1399#if DEBUG_PIXMAP 1400 xf86DrvMsg(scrn->scrnIndex, X_INFO, 1401 "SNA compiled with extra pixmap/damage validation\n"); 1402#endif 1403#ifdef HAVE_VALGRIND 1404 xf86DrvMsg(scrn->scrnIndex, X_INFO, 1405 "SNA compiled for use with valgrind\n"); 1406 VALGRIND_PRINTF("SNA compiled for use with valgrind\n"); 1407#endif 1408 DBG(("pixman version: %s\n", pixman_version_string())); 1409} 1410 1411Bool sna_init_scrn(ScrnInfoPtr scrn, int entity_num) 1412{ 1413 DBG(("%s: entity_num=%d\n", __FUNCTION__, entity_num)); 1414 describe_kms(scrn); 1415 describe_sna(scrn); 1416 1417 scrn->PreInit = sna_pre_init; 1418 scrn->ScreenInit = sna_screen_init; 1419 if (!hosted()) { 1420 scrn->SwitchMode = sna_switch_mode; 1421 scrn->AdjustFrame = sna_adjust_frame; 1422 scrn->EnterVT = sna_enter_vt; 1423 scrn->LeaveVT = sna_leave_vt; 1424 scrn->ValidMode = sna_valid_mode; 1425 scrn->PMEvent = sna_pm_event; 1426 } else { 1427 scrn->EnterVT = sna_enter_vt__hosted; 1428 scrn->LeaveVT = sna_leave_vt__hosted; 1429 } 1430 scrn->FreeScreen = sna_free_screen; 1431 1432 xf86SetEntitySharable(entity_num); 1433 xf86SetEntityInstanceForScreen(scrn, entity_num, 1434 xf86GetNumEntityInstances(entity_num)-1); 1435 1436 sna_threads_init(); 1437 1438 return TRUE; 1439} 1440 1441#if HAS_DEBUG_FULL 1442_X_ATTRIBUTE_PRINTF(1, 0) void LogF(const char *f, ...) 1443{ 1444 va_list ap; 1445 1446 /* As we not only may be called from any context, we may also 1447 * be called from a thread whilst the main thread is handling 1448 * signals, therefore we have to use the signal-safe variants 1449 * or else we trip over false positive assertions. 1450 */ 1451 1452 va_start(ap, f); 1453#if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,12,99,901,0) 1454 LogVMessageVerbSigSafe(X_NONE, 1, f, ap); 1455#else 1456 LogVMessageVerb(X_NONE, 1, f, ap); 1457#endif 1458 va_end(ap); 1459} 1460#endif 1461