sna_display.c revision 428d7b3d
1/* 2 * Copyright © 2007 Red Hat, Inc. 3 * Copyright © 2013-2014 Intel Corporation 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining a 6 * copy of this software and associated documentation files (the "Software"), 7 * to deal in the Software without restriction, including without limitation 8 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 9 * and/or sell copies of the Software, and to permit persons to whom the 10 * Software is furnished to do so, subject to the following conditions: 11 * 12 * The above copyright notice and this permission notice (including the next 13 * paragraph) shall be included in all copies or substantial portions of the 14 * Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 * SOFTWARE. 23 * 24 * Authors: 25 * Dave Airlie <airlied@redhat.com> 26 * 27 */ 28 29#ifdef HAVE_CONFIG_H 30#include "config.h" 31#endif 32 33#include <stdint.h> 34#include <sys/types.h> 35#include <sys/stat.h> 36#include <sys/mman.h> 37#include <fcntl.h> 38#include <unistd.h> 39#include <errno.h> 40#include <poll.h> 41#include <ctype.h> 42 43#include "sna.h" 44#include "sna_reg.h" 45#include "fb/fbpict.h" 46#include "intel_options.h" 47#include "backlight.h" 48 49#include <xf86Crtc.h> 50#include <xf86RandR12.h> 51#include <cursorstr.h> 52 53#if XF86_CRTC_VERSION >= 3 54#define HAS_GAMMA 1 55#else 56#define HAS_GAMMA 0 57#endif 58 59#include <X11/Xatom.h> 60#if defined(HAVE_X11_EXTENSIONS_DPMSCONST_H) 61#include <X11/extensions/dpmsconst.h> 62#else 63#define DPMSModeOn 0 64#define DPMSModeOff 3 65#endif 66#include <xf86DDC.h> /* for xf86InterpretEDID */ 67 68#include <xf86drm.h> 69 70#ifdef HAVE_VALGRIND 71#include <valgrind.h> 72#include <memcheck.h> 73#endif 74 75/* Minor discrepancy between 32-bit/64-bit ABI in old kernels */ 76union compat_mode_get_connector{ 77 struct drm_mode_get_connector conn; 78 uint32_t pad[20]; 79}; 80 81#define KNOWN_MODE_FLAGS ((1<<14)-1) 82 83#ifndef MONITOR_EDID_COMPLETE_RAWDATA 84#define MONITOR_EDID_COMPLETE_RAWDATA 1 85#endif 86 87#ifndef DEFAULT_DPI 88#define DEFAULT_DPI 96 89#endif 90 91#define DRM_MODE_PAGE_FLIP_ASYNC 0x02 92 93#define DRM_CLIENT_CAP_UNIVERSAL_PLANES 2 94#define DRM_PLANE_TYPE_OVERLAY 0 95#define DRM_PLANE_TYPE_PRIMARY 1 96#define DRM_PLANE_TYPE_CURSOR 2 97 98#define LOCAL_IOCTL_MODE_OBJ_GETPROPERTIES DRM_IOWR(0xb9, struct local_mode_obj_get_properties) 99struct local_mode_obj_get_properties { 100 uint64_t props_ptr; 101 uint64_t prop_values_ptr; 102 uint32_t count_props; 103 uint32_t obj_id; 104 uint32_t obj_type; 105 uint32_t pad; 106}; 107#define LOCAL_MODE_OBJECT_PLANE 0xeeeeeeee 108 109#if 0 110#define __DBG DBG 111#else 112#define __DBG(x) 113#endif 114 115extern XF86ConfigPtr xf86configptr; 116 117struct sna_crtc { 118 xf86CrtcPtr base; 119 struct drm_mode_modeinfo kmode; 120 int dpms_mode; 121 PixmapPtr slave_pixmap; 122 DamagePtr slave_damage; 123 struct kgem_bo *bo, *shadow_bo, *client_bo; 124 struct sna_cursor *cursor; 125 unsigned int last_cursor_size; 126 uint32_t offset; 127 bool shadow; 128 bool fallback_shadow; 129 bool transform; 130 bool flip_pending; 131 uint8_t id; 132 uint8_t pipe; 133 134 RegionRec client_damage; /* XXX overlap with shadow damage? */ 135 136 uint16_t shadow_bo_width, shadow_bo_height; 137 138 uint32_t rotation; 139 struct plane { 140 uint32_t id; 141 struct { 142 uint32_t prop; 143 uint32_t supported; 144 uint32_t current; 145 } rotation; 146 } primary, sprite; 147 148 uint32_t mode_serial, flip_serial; 149 150 uint32_t last_seq, wrap_seq; 151 struct ust_msc swap; 152 153 sna_flip_handler_t flip_handler; 154 struct kgem_bo *flip_bo; 155 void *flip_data; 156 157 struct list shadow_link; 158}; 159 160struct sna_property { 161 drmModePropertyPtr kprop; 162 int num_atoms; /* if range prop, num_atoms == 1; if enum prop, num_atoms == num_enums + 1 */ 163 Atom *atoms; 164}; 165 166struct sna_output { 167 xf86OutputPtr base; 168 unsigned id; 169 unsigned serial; 170 171 unsigned possible_encoders; 172 unsigned attached_encoders; 173 174 unsigned int is_panel : 1; 175 unsigned int add_default_modes : 1; 176 177 uint32_t edid_idx; 178 uint32_t edid_blob_id; 179 uint32_t edid_len; 180 void *edid_raw; 181 182 bool has_panel_limits; 183 int panel_hdisplay; 184 int panel_vdisplay; 185 186 uint32_t dpms_id; 187 int dpms_mode; 188 struct backlight backlight; 189 int backlight_active_level; 190 191 int num_modes; 192 struct drm_mode_modeinfo *modes; 193 194 int num_props; 195 uint32_t *prop_ids; 196 uint64_t *prop_values; 197 struct sna_property *props; 198}; 199 200enum { /* XXX copied from hw/xfree86/modes/xf86Crtc.c */ 201 OPTION_PREFERRED_MODE, 202#if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,14,99,1,0) 203 OPTION_ZOOM_MODES, 204#endif 205 OPTION_POSITION, 206 OPTION_BELOW, 207 OPTION_RIGHT_OF, 208 OPTION_ABOVE, 209 OPTION_LEFT_OF, 210 OPTION_ENABLE, 211 OPTION_DISABLE, 212 OPTION_MIN_CLOCK, 213 OPTION_MAX_CLOCK, 214 OPTION_IGNORE, 215 OPTION_ROTATE, 216 OPTION_PANNING, 217 OPTION_PRIMARY, 218 OPTION_DEFAULT_MODES, 219}; 220 221static void sna_crtc_disable_cursor(struct sna *sna, struct sna_crtc *crtc); 222 223static bool is_zaphod(ScrnInfoPtr scrn) 224{ 225 return xf86IsEntityShared(scrn->entityList[0]); 226} 227 228inline static unsigned count_to_mask(int x) 229{ 230 return (1 << x) - 1; 231} 232 233static inline struct sna_output *to_sna_output(xf86OutputPtr output) 234{ 235 return output->driver_private; 236} 237 238static inline int to_connector_id(xf86OutputPtr output) 239{ 240 assert(to_sna_output(output)); 241 assert(to_sna_output(output)->id); 242 return to_sna_output(output)->id; 243} 244 245static inline struct sna_crtc *to_sna_crtc(xf86CrtcPtr crtc) 246{ 247 return crtc->driver_private; 248} 249 250static inline bool event_pending(int fd) 251{ 252 struct pollfd pfd; 253 pfd.fd = fd; 254 pfd.events = POLLIN; 255 return poll(&pfd, 1, 0) == 1; 256} 257 258static bool sna_mode_wait_for_event(struct sna *sna) 259{ 260 struct pollfd pfd; 261 pfd.fd = sna->kgem.fd; 262 pfd.events = POLLIN; 263 return poll(&pfd, 1, -1) == 1; 264} 265 266static inline uint32_t fb_id(struct kgem_bo *bo) 267{ 268 return bo->delta; 269} 270 271uint32_t sna_crtc_id(xf86CrtcPtr crtc) 272{ 273 if (to_sna_crtc(crtc) == NULL) 274 return 0; 275 return to_sna_crtc(crtc)->id; 276} 277 278int sna_crtc_to_pipe(xf86CrtcPtr crtc) 279{ 280 assert(to_sna_crtc(crtc)); 281 return to_sna_crtc(crtc)->pipe; 282} 283 284uint32_t sna_crtc_to_sprite(xf86CrtcPtr crtc) 285{ 286 assert(to_sna_crtc(crtc)); 287 return to_sna_crtc(crtc)->sprite.id; 288} 289 290bool sna_crtc_is_on(xf86CrtcPtr crtc) 291{ 292 assert(to_sna_crtc(crtc)); 293 return to_sna_crtc(crtc)->bo != NULL; 294} 295 296bool sna_crtc_is_transformed(xf86CrtcPtr crtc) 297{ 298 assert(to_sna_crtc(crtc)); 299 return to_sna_crtc(crtc)->transform; 300} 301 302static inline uint64_t msc64(struct sna_crtc *sna_crtc, uint32_t seq) 303{ 304 if (seq < sna_crtc->last_seq) { 305 if (sna_crtc->last_seq - seq > 0x40000000) { 306 sna_crtc->wrap_seq++; 307 DBG(("%s: pipe=%d wrapped; was %u, now %u, wraps=%u\n", 308 __FUNCTION__, sna_crtc->pipe, 309 sna_crtc->last_seq, seq, sna_crtc->wrap_seq)); 310 } else { 311 ERR(("%s: pipe=%d msc went backwards; was %u, now %u\n", 312 __FUNCTION__, sna_crtc->pipe, sna_crtc->last_seq, seq)); 313 seq = sna_crtc->last_seq; 314 } 315 } 316 sna_crtc->last_seq = seq; 317 return (uint64_t)sna_crtc->wrap_seq << 32 | seq; 318} 319 320uint64_t sna_crtc_record_swap(xf86CrtcPtr crtc, 321 int tv_sec, int tv_usec, unsigned seq) 322{ 323 struct sna_crtc *sna_crtc = to_sna_crtc(crtc); 324 assert(sna_crtc); 325 DBG(("%s: recording last swap on pipe=%d, frame %d, time %d.%06d\n", 326 __FUNCTION__, sna_crtc->pipe, seq, tv_sec, tv_usec)); 327 sna_crtc->swap.tv_sec = tv_sec; 328 sna_crtc->swap.tv_usec = tv_usec; 329 return sna_crtc->swap.msc = msc64(sna_crtc, seq); 330} 331 332const struct ust_msc *sna_crtc_last_swap(xf86CrtcPtr crtc) 333{ 334 static struct ust_msc zero; 335 336 if (crtc == NULL) { 337 return &zero; 338 } else { 339 struct sna_crtc *sna_crtc = to_sna_crtc(crtc); 340 assert(sna_crtc); 341 return &sna_crtc->swap; 342 } 343} 344 345xf86CrtcPtr sna_mode_first_crtc(struct sna *sna) 346{ 347 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn); 348 if (sna->mode.num_real_crtc) 349 return config->crtc[0]; 350 else 351 return NULL; 352} 353 354#ifndef NDEBUG 355static void gem_close(int fd, uint32_t handle); 356static void assert_scanout(struct kgem *kgem, struct kgem_bo *bo, 357 int width, int height) 358{ 359 struct drm_mode_fb_cmd info; 360 361 assert(bo->scanout); 362 363 VG_CLEAR(info); 364 info.fb_id = fb_id(bo); 365 366 assert(drmIoctl(kgem->fd, DRM_IOCTL_MODE_GETFB, &info) == 0); 367 gem_close(kgem->fd, info.handle); 368 369 assert(width == info.width && height == info.height); 370} 371#else 372#define assert_scanout(k, b, w, h) 373#endif 374 375static unsigned get_fb(struct sna *sna, struct kgem_bo *bo, 376 int width, int height) 377{ 378 ScrnInfoPtr scrn = sna->scrn; 379 struct drm_mode_fb_cmd arg; 380 381 assert(bo->refcnt); 382 assert(bo->proxy == NULL); 383 assert(!bo->snoop); 384 assert(8*bo->pitch >= width * scrn->bitsPerPixel); 385 assert(height * bo->pitch <= kgem_bo_size(bo)); /* XXX crtc offset */ 386 if (fb_id(bo)) { 387 DBG(("%s: reusing fb=%d for handle=%d\n", 388 __FUNCTION__, fb_id(bo), bo->handle)); 389 assert_scanout(&sna->kgem, bo, width, height); 390 return fb_id(bo); 391 } 392 393 DBG(("%s: create fb %dx%d@%d/%d\n", 394 __FUNCTION__, width, height, scrn->depth, scrn->bitsPerPixel)); 395 396 assert(bo->tiling != I915_TILING_Y); 397 assert((bo->pitch & 63) == 0); 398 399 VG_CLEAR(arg); 400 arg.width = width; 401 arg.height = height; 402 arg.pitch = bo->pitch; 403 arg.bpp = scrn->bitsPerPixel; 404 arg.depth = scrn->depth; 405 arg.handle = bo->handle; 406 407 assert(sna->scrn->vtSema); /* must be master */ 408 if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_ADDFB, &arg)) { 409 xf86DrvMsg(scrn->scrnIndex, X_ERROR, 410 "%s: failed to add fb: %dx%d depth=%d, bpp=%d, pitch=%d: %d\n", 411 __FUNCTION__, width, height, 412 scrn->depth, scrn->bitsPerPixel, bo->pitch, errno); 413 return 0; 414 } 415 assert(arg.fb_id != 0); 416 417 DBG(("%s: attached fb=%d to handle=%d\n", 418 __FUNCTION__, arg.fb_id, arg.handle)); 419 420 bo->scanout = true; 421 return bo->delta = arg.fb_id; 422} 423 424static uint32_t gem_create(int fd, int size) 425{ 426 struct drm_i915_gem_create create; 427 428 assert((size & 4095) == 0); 429 430 VG_CLEAR(create); 431 create.handle = 0; 432 create.size = size; 433 (void)drmIoctl(fd, DRM_IOCTL_I915_GEM_CREATE, &create); 434 435 return create.handle; 436} 437 438static void *gem_mmap(int fd, int handle, int size) 439{ 440 struct drm_i915_gem_mmap_gtt mmap_arg; 441 void *ptr; 442 443 VG_CLEAR(mmap_arg); 444 mmap_arg.handle = handle; 445 if (drmIoctl(fd, DRM_IOCTL_I915_GEM_MMAP_GTT, &mmap_arg)) 446 return NULL; 447 448 ptr = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, mmap_arg.offset); 449 if (ptr == MAP_FAILED) 450 return NULL; 451 452 return ptr; 453} 454 455static void gem_close(int fd, uint32_t handle) 456{ 457 struct drm_gem_close close; 458 459 VG_CLEAR(close); 460 close.handle = handle; 461 (void)drmIoctl(fd, DRM_IOCTL_GEM_CLOSE, &close); 462} 463 464#define BACKLIGHT_NAME "Backlight" 465#define BACKLIGHT_DEPRECATED_NAME "BACKLIGHT" 466static Atom backlight_atom, backlight_deprecated_atom; 467 468#if HAVE_UDEV 469static void 470sna_backlight_uevent(int fd, void *closure) 471{ 472 struct sna *sna = closure; 473 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn); 474 int i; 475 476 DBG(("%s()\n", __FUNCTION__)); 477 478 /* Drain the event queue */ 479 while (event_pending(fd)) { 480 struct udev_device *dev; 481 482 DBG(("%s: waiting for uevent\n", __FUNCTION__)); 483 dev = udev_monitor_receive_device(sna->mode.backlight_monitor); 484 if (dev == NULL) 485 break; 486 487 udev_device_unref(dev); 488 } 489 490 /* Query all backlights for any changes */ 491 DBG(("%s: probing backlights for changes\n", __FUNCTION__)); 492 for (i = 0; i < sna->mode.num_real_output; i++) { 493 xf86OutputPtr output = config->output[i]; 494 struct sna_output *sna_output = to_sna_output(output); 495 int val; 496 497 if (sna_output->dpms_mode != DPMSModeOn) 498 continue; 499 500 assert(output->randr_output); 501 502 val = backlight_get(&sna_output->backlight); 503 if (val < 0) 504 continue; 505 DBG(("%s(%s): backlight '%s' was %d, now %d\n", 506 __FUNCTION__, output->name, sna_output->backlight.iface, 507 sna_output->backlight_active_level, val)); 508 509 if (val == sna_output->backlight_active_level) 510 continue; 511 512 sna_output->backlight_active_level = val; 513 514 if (output->randr_output) { 515 DBG(("%s(%s): sending change notification\n", __FUNCTION__, output->name)); 516 RRChangeOutputProperty(output->randr_output, 517 backlight_atom, XA_INTEGER, 518 32, PropModeReplace, 1, &val, 519 TRUE, FALSE); 520 RRChangeOutputProperty(output->randr_output, 521 backlight_deprecated_atom, XA_INTEGER, 522 32, PropModeReplace, 1, &val, 523 TRUE, FALSE); 524 } 525 } 526} 527 528static void sna_backlight_pre_init(struct sna *sna) 529{ 530 struct udev *u; 531 struct udev_monitor *mon; 532 533#if !USE_BACKLIGHT 534 return; 535#endif 536 537 u = udev_new(); 538 if (!u) 539 return; 540 541 mon = udev_monitor_new_from_netlink(u, "udev"); 542 if (!mon) 543 goto free_udev; 544 545 if (udev_monitor_filter_add_match_subsystem_devtype(mon, "backlight", NULL)) 546 goto free_monitor; 547 548 if (udev_monitor_enable_receiving(mon)) 549 goto free_monitor; 550 551 sna->mode.backlight_handler = 552 xf86AddGeneralHandler(udev_monitor_get_fd(mon), 553 sna_backlight_uevent, sna); 554 if (!sna->mode.backlight_handler) 555 goto free_monitor; 556 557 DBG(("%s: installed backlight monitor\n", __FUNCTION__)); 558 sna->mode.backlight_monitor = mon; 559 560 return; 561 562free_monitor: 563 udev_monitor_unref(mon); 564free_udev: 565 udev_unref(u); 566} 567 568static void sna_backlight_drain_uevents(struct sna *sna) 569{ 570 if (sna->mode.backlight_monitor == NULL) 571 return; 572 573 sna_backlight_uevent(udev_monitor_get_fd(sna->mode.backlight_monitor), 574 sna); 575} 576 577static void sna_backlight_close(struct sna *sna) 578{ 579 struct udev *u; 580 581 if (sna->mode.backlight_handler == NULL) 582 return; 583 584 xf86RemoveGeneralHandler(sna->mode.backlight_handler); 585 586 u = udev_monitor_get_udev(sna->mode.backlight_monitor); 587 udev_monitor_unref(sna->mode.backlight_monitor); 588 udev_unref(u); 589 590 sna->mode.backlight_handler = NULL; 591 sna->mode.backlight_monitor = NULL; 592} 593#else 594static void sna_backlight_pre_init(struct sna *sna) { } 595static void sna_backlight_drain_uevents(struct sna *sna) { } 596static void sna_backlight_close(struct sna *sna) { } 597#endif 598 599static void 600sna_output_backlight_disable(struct sna_output *sna_output) 601{ 602 xf86OutputPtr output = sna_output->base; 603 604 xf86DrvMsg(output->scrn->scrnIndex, X_ERROR, 605 "Failed to set backlight %s for output %s, disabling\n", 606 sna_output->backlight.iface, output->name); 607 backlight_disable(&sna_output->backlight); 608 if (output->randr_output) { 609 RRDeleteOutputProperty(output->randr_output, backlight_atom); 610 RRDeleteOutputProperty(output->randr_output, backlight_deprecated_atom); 611 } 612} 613 614static int 615sna_output_backlight_set(struct sna_output *sna_output, int level) 616{ 617 int ret = 0; 618 619 DBG(("%s(%s) level=%d, max=%d\n", __FUNCTION__, 620 sna_output->base->name, level, sna_output->backlight.max)); 621 622 if (backlight_set(&sna_output->backlight, level)) { 623 sna_output_backlight_disable(sna_output); 624 ret = -1; 625 } 626 627 /* Consume the uevent notification now so that we don't misconstrue 628 * the change latter when we wake up and the output is in a different 629 * state. 630 */ 631 sna_backlight_drain_uevents(to_sna(sna_output->base->scrn)); 632 return ret; 633} 634 635static void 636sna_output_backlight_off(struct sna_output *sna_output) 637{ 638 DBG(("%s(%s)\n", __FUNCTION__, sna_output->base->name)); 639 backlight_off(&sna_output->backlight); 640 sna_output_backlight_set(sna_output, 0); 641} 642 643static void 644sna_output_backlight_on(struct sna_output *sna_output) 645{ 646 DBG(("%s(%s)\n", __FUNCTION__, sna_output->base->name)); 647 sna_output_backlight_set(sna_output, 648 sna_output->backlight_active_level); 649 if (backlight_on(&sna_output->backlight) < 0) 650 sna_output_backlight_disable(sna_output); 651} 652 653static int 654sna_output_backlight_get(xf86OutputPtr output) 655{ 656 struct sna_output *sna_output = output->driver_private; 657 int level = backlight_get(&sna_output->backlight); 658 DBG(("%s(%s) level=%d, max=%d\n", __FUNCTION__, 659 output->name, level, sna_output->backlight.max)); 660 return level; 661} 662 663static char * 664has_user_backlight_override(xf86OutputPtr output) 665{ 666 struct sna *sna = to_sna(output->scrn); 667 const char *str; 668 669 str = xf86GetOptValString(sna->Options, OPTION_BACKLIGHT); 670 if (str == NULL) 671 return NULL; 672 673 DBG(("%s(%s) requested %s\n", __FUNCTION__, output->name, str)); 674 if (*str == '\0') 675 return (char *)str; 676 677 if (backlight_exists(str) == BL_NONE) { 678 xf86DrvMsg(output->scrn->scrnIndex, X_ERROR, 679 "Unrecognised backlight control interface '%s'\n", 680 str); 681 return NULL; 682 } 683 684 return strdup(str); 685} 686 687static void 688sna_output_backlight_init(xf86OutputPtr output) 689{ 690 struct sna_output *sna_output = output->driver_private; 691 struct pci_device *pci; 692 MessageType from; 693 char *best_iface; 694 695#if !USE_BACKLIGHT 696 return; 697#endif 698 699 from = X_CONFIG; 700 best_iface = has_user_backlight_override(output); 701 if (best_iface) 702 goto done; 703 704 /* XXX detect right backlight for multi-GPU/panels */ 705 from = X_PROBED; 706 pci = xf86GetPciInfoForEntity(to_sna(output->scrn)->pEnt->index); 707 if (pci != NULL) 708 best_iface = backlight_find_for_device(pci); 709 710done: 711 DBG(("%s(%s) opening backlight %s\n", __FUNCTION__, 712 output->name, best_iface ?: "none")); 713 sna_output->backlight_active_level = 714 backlight_open(&sna_output->backlight, best_iface); 715 DBG(("%s(%s): initial backlight value %d\n", 716 __FUNCTION__, output->name, sna_output->backlight_active_level)); 717 if (sna_output->backlight_active_level < 0) 718 return; 719 720 switch (sna_output->backlight.type) { 721 case BL_FIRMWARE: best_iface = (char *)"firmware"; break; 722 case BL_PLATFORM: best_iface = (char *)"platform"; break; 723 case BL_RAW: best_iface = (char *)"raw"; break; 724 default: best_iface = (char *)"unknown"; break; 725 } 726 xf86DrvMsg(output->scrn->scrnIndex, from, 727 "Found backlight control interface %s (type '%s') for output %s\n", 728 sna_output->backlight.iface, best_iface, output->name); 729} 730 731static char *canonical_kmode_name(const struct drm_mode_modeinfo *kmode) 732{ 733 char tmp[32], *buf; 734 int len; 735 736 len = sprintf(tmp, "%dx%d%s", 737 kmode->hdisplay, kmode->vdisplay, 738 kmode->flags & V_INTERLACE ? "i" : ""); 739 if ((unsigned)len >= sizeof(tmp)) 740 return NULL; 741 742 buf = malloc(len + 1); 743 if (buf == NULL) 744 return NULL; 745 746 return memcpy(buf, tmp, len + 1); 747} 748 749static char *get_kmode_name(const struct drm_mode_modeinfo *kmode) 750{ 751 if (*kmode->name == '\0') 752 return canonical_kmode_name(kmode); 753 754 return strdup(kmode->name); 755} 756 757static DisplayModePtr 758mode_from_kmode(ScrnInfoPtr scrn, 759 const struct drm_mode_modeinfo *kmode, 760 DisplayModePtr mode) 761{ 762 DBG(("kmode: %s, clock=%d, %d %d %d %d %d, %d %d %d %d %d, flags=%x, type=%x\n", 763 kmode->name, kmode->clock, 764 kmode->hdisplay, kmode->hsync_start, kmode->hsync_end, kmode->htotal, kmode->hskew, 765 kmode->vdisplay, kmode->vsync_start, kmode->vsync_end, kmode->vtotal, kmode->vscan, 766 kmode->flags, kmode->type)); 767 768 mode->status = MODE_OK; 769 770 mode->Clock = kmode->clock; 771 772 mode->HDisplay = kmode->hdisplay; 773 mode->HSyncStart = kmode->hsync_start; 774 mode->HSyncEnd = kmode->hsync_end; 775 mode->HTotal = kmode->htotal; 776 mode->HSkew = kmode->hskew; 777 778 mode->VDisplay = kmode->vdisplay; 779 mode->VSyncStart = kmode->vsync_start; 780 mode->VSyncEnd = kmode->vsync_end; 781 mode->VTotal = kmode->vtotal; 782 mode->VScan = kmode->vscan; 783 784 mode->Flags = kmode->flags; 785 mode->name = get_kmode_name(kmode); 786 787 if (kmode->type & DRM_MODE_TYPE_DRIVER) 788 mode->type = M_T_DRIVER; 789 if (kmode->type & DRM_MODE_TYPE_PREFERRED) 790 mode->type |= M_T_PREFERRED; 791 792 if (mode->status == MODE_OK && kmode->flags & ~KNOWN_MODE_FLAGS) 793 mode->status = MODE_BAD; /* unknown flags => unhandled */ 794 795 xf86SetModeCrtc(mode, scrn->adjustFlags); 796 return mode; 797} 798 799static void 800mode_to_kmode(struct drm_mode_modeinfo *kmode, DisplayModePtr mode) 801{ 802 memset(kmode, 0, sizeof(*kmode)); 803 804 kmode->clock = mode->Clock; 805 kmode->hdisplay = mode->HDisplay; 806 kmode->hsync_start = mode->HSyncStart; 807 kmode->hsync_end = mode->HSyncEnd; 808 kmode->htotal = mode->HTotal; 809 kmode->hskew = mode->HSkew; 810 811 kmode->vdisplay = mode->VDisplay; 812 kmode->vsync_start = mode->VSyncStart; 813 kmode->vsync_end = mode->VSyncEnd; 814 kmode->vtotal = mode->VTotal; 815 kmode->vscan = mode->VScan; 816 817 kmode->flags = mode->Flags; 818 if (mode->name) 819 strncpy(kmode->name, mode->name, DRM_DISPLAY_MODE_LEN); 820 kmode->name[DRM_DISPLAY_MODE_LEN-1] = 0; 821} 822 823static void 824sna_crtc_force_outputs_on(xf86CrtcPtr crtc) 825{ 826 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(crtc->scrn); 827 int i; 828 829 assert(to_sna_crtc(crtc)); 830 DBG(("%s(pipe=%d), currently? %d\n", __FUNCTION__, 831 to_sna_crtc(crtc)->pipe, to_sna_crtc(crtc)->dpms_mode)); 832 833 /* DPMS handling by the kernel is inconsistent, so after setting a 834 * mode on an output presume that we intend for it to be on, or that 835 * the kernel will force it on. 836 * 837 * So force DPMS to be on for all connected outputs, and restore 838 * the backlight. 839 */ 840 for (i = 0; i < config->num_output; i++) { 841 xf86OutputPtr output = config->output[i]; 842 843 if (output->crtc != crtc) 844 continue; 845 846 output->funcs->dpms(output, DPMSModeOn); 847 } 848 849 to_sna_crtc(crtc)->dpms_mode = DPMSModeOn; 850#if XF86_CRTC_VERSION >= 3 851 crtc->active = TRUE; 852#endif 853} 854 855static void 856sna_crtc_force_outputs_off(xf86CrtcPtr crtc) 857{ 858 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(crtc->scrn); 859 int i; 860 861 assert(to_sna_crtc(crtc)); 862 DBG(("%s(pipe=%d), currently? %d\n", __FUNCTION__, 863 to_sna_crtc(crtc)->pipe, to_sna_crtc(crtc)->dpms_mode)); 864 865 /* DPMS handling by the kernel is inconsistent, so after setting a 866 * mode on an output presume that we intend for it to be on, or that 867 * the kernel will force it on. 868 * 869 * So force DPMS to be on for all connected outputs, and restore 870 * the backlight. 871 */ 872 for (i = 0; i < config->num_output; i++) { 873 xf86OutputPtr output = config->output[i]; 874 875 if (output->crtc != crtc) 876 continue; 877 878 output->funcs->dpms(output, DPMSModeOff); 879 } 880 881 to_sna_crtc(crtc)->dpms_mode = DPMSModeOff; 882} 883 884static unsigned 885rotation_reduce(struct plane *p, unsigned rotation) 886{ 887 unsigned unsupported_rotations = rotation & ~p->rotation.supported; 888 889 if (unsupported_rotations == 0) 890 return rotation; 891 892#define RR_Reflect_XY (RR_Reflect_X | RR_Reflect_Y) 893 894 if ((unsupported_rotations & RR_Reflect_XY) == RR_Reflect_XY && 895 p->rotation.supported& RR_Rotate_180) { 896 rotation &= ~RR_Reflect_XY; 897 rotation ^= RR_Rotate_180; 898 } 899 900 if ((unsupported_rotations & RR_Rotate_180) && 901 (p->rotation.supported& RR_Reflect_XY) == RR_Reflect_XY) { 902 rotation ^= RR_Reflect_XY; 903 rotation &= ~RR_Rotate_180; 904 } 905 906#undef RR_Reflect_XY 907 908 return rotation; 909} 910 911static bool 912rotation_set(struct sna *sna, struct plane *p, uint32_t desired) 913{ 914#define LOCAL_IOCTL_MODE_OBJ_SETPROPERTY DRM_IOWR(0xbA, struct local_mode_obj_set_property) 915 struct local_mode_obj_set_property { 916 uint64_t value; 917 uint32_t prop_id; 918 uint32_t obj_id; 919 uint32_t obj_type; 920 uint32_t pad; 921 } prop; 922 923 if (desired == p->rotation.current) 924 return true; 925 926 if ((desired & p->rotation.supported) == 0) { 927 errno = EINVAL; 928 return false; 929 } 930 931 DBG(("%s: obj=%d, type=%x prop=%d set-rotation=%x\n", 932 __FUNCTION__, p->id, LOCAL_MODE_OBJECT_PLANE, p->rotation.prop, desired)); 933 934 assert(p->id); 935 assert(p->rotation.prop); 936 937 VG_CLEAR(prop); 938 prop.obj_id = p->id; 939 prop.obj_type = LOCAL_MODE_OBJECT_PLANE; 940 prop.prop_id = p->rotation.prop; 941 prop.value = desired; 942 943 if (drmIoctl(sna->kgem.fd, LOCAL_IOCTL_MODE_OBJ_SETPROPERTY, &prop)) 944 return false; 945 946 p->rotation.current = desired; 947 return true; 948} 949 950static void 951rotation_reset(struct plane *p) 952{ 953 if (p->rotation.prop == 0) 954 return; 955 956 p->rotation.current = 0; 957} 958 959bool sna_crtc_set_sprite_rotation(xf86CrtcPtr crtc, uint32_t rotation) 960{ 961 assert(to_sna_crtc(crtc)); 962 DBG(("%s: CRTC:%d [pipe=%d], sprite=%u set-rotation=%x\n", 963 __FUNCTION__, 964 to_sna_crtc(crtc)->id, to_sna_crtc(crtc)->pipe, to_sna_crtc(crtc)->sprite.id, 965 rotation)); 966 967 return rotation_set(to_sna(crtc->scrn), 968 &to_sna_crtc(crtc)->sprite, 969 rotation_reduce(&to_sna_crtc(crtc)->sprite, rotation)); 970} 971 972static bool 973sna_crtc_apply(xf86CrtcPtr crtc) 974{ 975 struct sna *sna = to_sna(crtc->scrn); 976 struct sna_crtc *sna_crtc = to_sna_crtc(crtc); 977 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(crtc->scrn); 978 struct drm_mode_crtc arg; 979 uint32_t output_ids[32]; 980 int output_count = 0; 981 int i; 982 983 DBG(("%s CRTC:%d [pipe=%d], handle=%d\n", __FUNCTION__, sna_crtc->id, sna_crtc->pipe, sna_crtc->bo->handle)); 984 if (!sna_crtc->kmode.clock) { 985 ERR(("%s(CRTC:%d [pipe=%d]): attempted to set an invalid mode\n", 986 __FUNCTION__, sna_crtc->id, sna_crtc->pipe)); 987 return false; 988 } 989 990 assert(sna->mode.num_real_output < ARRAY_SIZE(output_ids)); 991 sna_crtc_disable_cursor(sna, sna_crtc); 992 993 if (!rotation_set(sna, &sna_crtc->primary, sna_crtc->rotation)) { 994 ERR(("%s: set-primary-rotation failed (rotation-id=%d, rotation=%d) on CRTC:%d [pipe=%d], errno=%d\n", 995 __FUNCTION__, sna_crtc->primary.rotation.prop, sna_crtc->rotation, sna_crtc->id, sna_crtc->pipe, errno)); 996 sna_crtc->primary.rotation.supported &= ~sna_crtc->rotation; 997 return false; 998 } 999 DBG(("%s: CRTC:%d [pipe=%d] primary rotation set to %x\n", 1000 __FUNCTION__, sna_crtc->id, sna_crtc->pipe, sna_crtc->rotation)); 1001 1002 for (i = 0; i < sna->mode.num_real_output; i++) { 1003 xf86OutputPtr output = config->output[i]; 1004 1005 /* Make sure we mark the output as off (and save the backlight) 1006 * before the kernel turns it off due to changing the pipe. 1007 * This is necessary as the kernel may turn off the backlight 1008 * and we lose track of the user settings. 1009 */ 1010 if (output->crtc == NULL) 1011 output->funcs->dpms(output, DPMSModeOff); 1012 1013 if (output->crtc != crtc) 1014 continue; 1015 1016 /* Skip over any hotunplugged outputs so that we can 1017 * recover in cases where the previous mode is now 1018 * only partially valid. 1019 */ 1020 if (!to_sna_output(output)->id) 1021 continue; 1022 1023 DBG(("%s: attaching output '%s' %d [%d] to crtc:%d (pipe %d) (possible crtc:%x, possible clones:%x)\n", 1024 __FUNCTION__, output->name, i, to_connector_id(output), 1025 sna_crtc->id, sna_crtc->pipe, 1026 (uint32_t)output->possible_crtcs, 1027 (uint32_t)output->possible_clones)); 1028 1029 assert(output->possible_crtcs & (1 << sna_crtc->pipe) || 1030 is_zaphod(crtc->scrn)); 1031 1032 output_ids[output_count] = to_connector_id(output); 1033 if (++output_count == ARRAY_SIZE(output_ids)) { 1034 DBG(("%s: too many outputs (%d) for me!\n", 1035 __FUNCTION__, output_count)); 1036 errno = EINVAL; 1037 return false; 1038 } 1039 } 1040 if (output_count == 0) { 1041 DBG(("%s: no outputs\n", __FUNCTION__)); 1042 errno = EINVAL; 1043 return false; 1044 } 1045 1046 VG_CLEAR(arg); 1047 arg.crtc_id = sna_crtc->id; 1048 arg.fb_id = fb_id(sna_crtc->bo); 1049 if (sna_crtc->transform || sna_crtc->slave_pixmap) { 1050 arg.x = 0; 1051 arg.y = 0; 1052 sna_crtc->offset = 0; 1053 } else { 1054 arg.x = crtc->x; 1055 arg.y = crtc->y; 1056 sna_crtc->offset = arg.y << 16 | arg.x; 1057 } 1058 arg.set_connectors_ptr = (uintptr_t)output_ids; 1059 arg.count_connectors = output_count; 1060 arg.mode = sna_crtc->kmode; 1061 arg.mode_valid = 1; 1062 1063 DBG(("%s: applying crtc [%d, pipe=%d] mode=%dx%d+%d+%d@%d, fb=%d%s%s update to %d outputs [%d...]\n", 1064 __FUNCTION__, sna_crtc->id, sna_crtc->pipe, 1065 arg.mode.hdisplay, 1066 arg.mode.vdisplay, 1067 arg.x, arg.y, 1068 arg.mode.clock, 1069 arg.fb_id, 1070 sna_crtc->shadow ? " [shadow]" : "", 1071 sna_crtc->transform ? " [transformed]" : "", 1072 output_count, output_count ? output_ids[0] : 0)); 1073 1074 if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_SETCRTC, &arg)) 1075 return false; 1076 1077 sna_crtc->mode_serial++; 1078 sna_crtc_force_outputs_on(crtc); 1079 return true; 1080} 1081 1082static bool overlap(const BoxRec *a, const BoxRec *b) 1083{ 1084 if (a->x1 >= b->x2) 1085 return false; 1086 if (a->x2 <= b->x1) 1087 return false; 1088 1089 if (a->y1 >= b->y2) 1090 return false; 1091 if (a->y2 <= b->y1) 1092 return false; 1093 1094 return true; 1095} 1096 1097static bool wait_for_shadow(struct sna *sna, 1098 struct sna_pixmap *priv, 1099 unsigned flags) 1100{ 1101 PixmapPtr pixmap = priv->pixmap; 1102 DamagePtr damage; 1103 struct kgem_bo *bo, *tmp; 1104 int flip_active; 1105 bool ret = true; 1106 1107 DBG(("%s: flags=%x, flips=%d, handle=%d, shadow=%d\n", 1108 __FUNCTION__, flags, sna->mode.flip_active, 1109 priv->gpu_bo->handle, sna->mode.shadow->handle)); 1110 1111 assert(priv->move_to_gpu_data == sna); 1112 assert(sna->mode.shadow != priv->gpu_bo); 1113 1114 if (flags == 0 || pixmap != sna->front || !sna->mode.shadow_damage) 1115 goto done; 1116 1117 if ((flags & MOVE_WRITE) == 0) { 1118 if ((flags & __MOVE_SCANOUT) == 0) { 1119 struct sna_crtc *crtc; 1120 1121 list_for_each_entry(crtc, &sna->mode.shadow_crtc, shadow_link) { 1122 if (overlap(&sna->mode.shadow_region.extents, 1123 &crtc->base->bounds)) { 1124 DrawableRec draw; 1125 RegionRec region; 1126 1127 draw.width = crtc->base->mode.HDisplay; 1128 draw.height = crtc->base->mode.VDisplay; 1129 draw.depth = sna->front->drawable.depth; 1130 draw.bitsPerPixel = sna->front->drawable.bitsPerPixel; 1131 1132 DBG(("%s: copying replaced CRTC: (%d, %d), (%d, %d), handle=%d\n", 1133 __FUNCTION__, 1134 crtc->base->bounds.x1, 1135 crtc->base->bounds.y1, 1136 crtc->base->bounds.x2, 1137 crtc->base->bounds.y2, 1138 crtc->client_bo->handle)); 1139 1140 ret &= sna->render.copy_boxes(sna, GXcopy, 1141 &draw, crtc->client_bo, -crtc->base->bounds.x1, -crtc->base->bounds.y1, 1142 &pixmap->drawable, priv->gpu_bo, 0, 0, 1143 &crtc->base->bounds, 1, 1144 0); 1145 1146 region.extents = crtc->base->bounds; 1147 region.data = NULL; 1148 RegionSubtract(&sna->mode.shadow_region, &sna->mode.shadow_region, ®ion); 1149 } 1150 } 1151 } 1152 1153 return ret; 1154 } 1155 1156 assert(sna->mode.shadow_active); 1157 1158 damage = sna->mode.shadow_damage; 1159 sna->mode.shadow_damage = NULL; 1160 1161 flip_active = sna->mode.flip_active; 1162 if (flip_active) { 1163 struct sna_crtc *crtc; 1164 list_for_each_entry(crtc, &sna->mode.shadow_crtc, shadow_link) 1165 flip_active -= crtc->flip_pending; 1166 DBG(("%s: %d flips still pending, shadow flip_active=%d\n", 1167 __FUNCTION__, sna->mode.flip_active, flip_active)); 1168 } 1169 if (flip_active) { 1170 /* raw cmd to avoid setting wedged in the middle of an op */ 1171 drmIoctl(sna->kgem.fd, DRM_IOCTL_I915_GEM_THROTTLE, 0); 1172 sna->kgem.need_throttle = false; 1173 1174 while (flip_active && sna_mode_wakeup(sna)) { 1175 struct sna_crtc *crtc; 1176 1177 flip_active = sna->mode.flip_active; 1178 list_for_each_entry(crtc, &sna->mode.shadow_crtc, shadow_link) 1179 flip_active -= crtc->flip_pending; 1180 } 1181 DBG(("%s: after waiting %d flips outstanding, flip_active=%d\n", 1182 __FUNCTION__, sna->mode.flip_active, flip_active)); 1183 } 1184 1185 bo = sna->mode.shadow; 1186 if (flip_active) { 1187 bo = kgem_create_2d(&sna->kgem, 1188 pixmap->drawable.width, 1189 pixmap->drawable.height, 1190 pixmap->drawable.bitsPerPixel, 1191 priv->gpu_bo->tiling, 1192 CREATE_EXACT | CREATE_SCANOUT); 1193 if (bo != NULL) { 1194 DBG(("%s: replacing still-attached GPU bo handle=%d, flips=%d\n", 1195 __FUNCTION__, priv->gpu_bo->tiling, sna->mode.flip_active)); 1196 1197 RegionUninit(&sna->mode.shadow_region); 1198 sna->mode.shadow_region.extents.x1 = 0; 1199 sna->mode.shadow_region.extents.y1 = 0; 1200 sna->mode.shadow_region.extents.x2 = pixmap->drawable.width; 1201 sna->mode.shadow_region.extents.y2 = pixmap->drawable.height; 1202 sna->mode.shadow_region.data = NULL; 1203 } else { 1204 while (sna->mode.flip_active && 1205 sna_mode_wait_for_event(sna)) 1206 sna_mode_wakeup(sna); 1207 1208 bo = sna->mode.shadow; 1209 } 1210 } 1211 1212 if (bo->refcnt > 1) { 1213 bo = kgem_create_2d(&sna->kgem, 1214 pixmap->drawable.width, 1215 pixmap->drawable.height, 1216 pixmap->drawable.bitsPerPixel, 1217 priv->gpu_bo->tiling, 1218 CREATE_EXACT | CREATE_SCANOUT); 1219 if (bo != NULL) { 1220 DBG(("%s: replacing exported GPU bo\n", 1221 __FUNCTION__)); 1222 1223 RegionUninit(&sna->mode.shadow_region); 1224 sna->mode.shadow_region.extents.x1 = 0; 1225 sna->mode.shadow_region.extents.y1 = 0; 1226 sna->mode.shadow_region.extents.x2 = pixmap->drawable.width; 1227 sna->mode.shadow_region.extents.y2 = pixmap->drawable.height; 1228 sna->mode.shadow_region.data = NULL; 1229 } else 1230 bo = sna->mode.shadow; 1231 } 1232 1233 sna->mode.shadow_damage = damage; 1234 1235 RegionSubtract(&sna->mode.shadow_region, 1236 &sna->mode.shadow_region, 1237 &sna->mode.shadow_cancel); 1238 1239 while (!list_is_empty(&sna->mode.shadow_crtc)) { 1240 struct sna_crtc *crtc = 1241 list_first_entry(&sna->mode.shadow_crtc, struct sna_crtc, shadow_link); 1242 if (overlap(&crtc->base->bounds, 1243 &sna->mode.shadow_region.extents)) { 1244 RegionRec region; 1245 DrawableRec draw; 1246 1247 draw.width = crtc->base->mode.HDisplay; 1248 draw.height = crtc->base->mode.VDisplay; 1249 draw.depth = sna->front->drawable.depth; 1250 draw.bitsPerPixel = sna->front->drawable.bitsPerPixel; 1251 1252 DBG(("%s: copying replaced CRTC: (%d, %d), (%d, %d), handle=%d\n", 1253 __FUNCTION__, 1254 crtc->base->bounds.x1, 1255 crtc->base->bounds.y1, 1256 crtc->base->bounds.x2, 1257 crtc->base->bounds.y2, 1258 crtc->client_bo->handle)); 1259 1260 ret = sna->render.copy_boxes(sna, GXcopy, 1261 &draw, crtc->client_bo, -crtc->base->bounds.x1, -crtc->base->bounds.y1, 1262 &pixmap->drawable, bo, 0, 0, 1263 &crtc->base->bounds, 1, 1264 0); 1265 1266 1267 region.extents = crtc->base->bounds; 1268 region.data = NULL; 1269 RegionSubtract(&sna->mode.shadow_region, &sna->mode.shadow_region, ®ion); 1270 } 1271 1272 kgem_bo_destroy(&sna->kgem, crtc->client_bo); 1273 crtc->client_bo = NULL; 1274 list_del(&crtc->shadow_link); 1275 } 1276 1277 if (RegionNotEmpty(&sna->mode.shadow_region)) { 1278 DBG(("%s: copying existing GPU damage: %dx(%d, %d), (%d, %d)\n", 1279 __FUNCTION__, region_num_rects(&sna->mode.shadow_region), 1280 sna->mode.shadow_region.extents.x1, 1281 sna->mode.shadow_region.extents.y1, 1282 sna->mode.shadow_region.extents.x2, 1283 sna->mode.shadow_region.extents.y2)); 1284 ret = sna->render.copy_boxes(sna, GXcopy, 1285 &pixmap->drawable, priv->gpu_bo, 0, 0, 1286 &pixmap->drawable, bo, 0, 0, 1287 region_rects(&sna->mode.shadow_region), 1288 region_num_rects(&sna->mode.shadow_region), 1289 0); 1290 } 1291 1292 if (priv->cow) 1293 sna_pixmap_undo_cow(sna, priv, 0); 1294 1295 sna_pixmap_unmap(pixmap, priv); 1296 1297 DBG(("%s: setting front pixmap to handle=%d\n", __FUNCTION__, bo->handle)); 1298 tmp = priv->gpu_bo; 1299 priv->gpu_bo = bo; 1300 if (bo != sna->mode.shadow) 1301 kgem_bo_destroy(&sna->kgem, sna->mode.shadow); 1302 sna->mode.shadow = tmp; 1303 1304 sna_dri2_pixmap_update_bo(sna, pixmap, bo); 1305 1306done: 1307 RegionEmpty(&sna->mode.shadow_cancel); 1308 RegionEmpty(&sna->mode.shadow_region); 1309 sna->mode.shadow_dirty = false; 1310 1311 priv->move_to_gpu_data = NULL; 1312 priv->move_to_gpu = NULL; 1313 1314 return ret; 1315} 1316 1317bool sna_pixmap_discard_shadow_damage(struct sna_pixmap *priv, 1318 const RegionRec *region) 1319{ 1320 struct sna *sna; 1321 1322 if (priv->move_to_gpu != wait_for_shadow) 1323 return false; 1324 1325 sna = priv->move_to_gpu_data; 1326 if (region) { 1327 DBG(("%s: discarding region %dx[(%d, %d), (%d, %d)] from damage %dx[(%d, %d], (%d, %d)]\n", 1328 __FUNCTION__, 1329 region_num_rects(region), 1330 region->extents.x1, region->extents.y1, 1331 region->extents.x2, region->extents.y2, 1332 region_num_rects(&sna->mode.shadow_region), 1333 sna->mode.shadow_region.extents.x1, sna->mode.shadow_region.extents.y1, 1334 sna->mode.shadow_region.extents.x2, sna->mode.shadow_region.extents.y2)); 1335 1336 RegionSubtract(&sna->mode.shadow_region, 1337 &sna->mode.shadow_region, 1338 (RegionPtr)region); 1339 RegionUnion(&sna->mode.shadow_cancel, 1340 &sna->mode.shadow_cancel, 1341 (RegionPtr)region); 1342 } else { 1343 DBG(("%s: discarding all damage %dx[(%d, %d], (%d, %d)]\n", 1344 __FUNCTION__, 1345 region_num_rects(&sna->mode.shadow_region), 1346 sna->mode.shadow_region.extents.x1, sna->mode.shadow_region.extents.y1, 1347 sna->mode.shadow_region.extents.x2, sna->mode.shadow_region.extents.y2)); 1348 RegionEmpty(&sna->mode.shadow_region); 1349 1350 RegionUninit(&sna->mode.shadow_cancel); 1351 sna->mode.shadow_cancel.extents.x1 = 0; 1352 sna->mode.shadow_cancel.extents.y1 = 0; 1353 sna->mode.shadow_cancel.extents.x2 = sna->front->drawable.width; 1354 sna->mode.shadow_cancel.extents.y2 = sna->front->drawable.height; 1355 sna->mode.shadow_cancel.data = NULL; 1356 } 1357 1358 return RegionNil(&sna->mode.shadow_region); 1359} 1360 1361static bool sna_mode_enable_shadow(struct sna *sna) 1362{ 1363 ScreenPtr screen = sna->scrn->pScreen; 1364 1365 DBG(("%s\n", __FUNCTION__)); 1366 assert(sna->mode.shadow == NULL); 1367 assert(sna->mode.shadow_damage == NULL); 1368 assert(sna->mode.shadow_active == 0); 1369 1370 sna->mode.shadow_damage = DamageCreate(NULL, NULL, 1371 DamageReportNone, TRUE, 1372 screen, screen); 1373 if (!sna->mode.shadow_damage) 1374 return false; 1375 1376 DamageRegister(&sna->front->drawable, sna->mode.shadow_damage); 1377 return true; 1378} 1379 1380static void sna_mode_disable_shadow(struct sna *sna) 1381{ 1382 struct sna_pixmap *priv; 1383 1384 if (!sna->mode.shadow_damage) 1385 return; 1386 1387 DBG(("%s\n", __FUNCTION__)); 1388 1389 priv = sna_pixmap(sna->front); 1390 if (priv->move_to_gpu == wait_for_shadow) 1391 priv->move_to_gpu(sna, priv, 0); 1392 1393 DamageUnregister(&sna->front->drawable, sna->mode.shadow_damage); 1394 DamageDestroy(sna->mode.shadow_damage); 1395 sna->mode.shadow_damage = NULL; 1396 1397 if (sna->mode.shadow) { 1398 kgem_bo_destroy(&sna->kgem, sna->mode.shadow); 1399 sna->mode.shadow = NULL; 1400 } 1401 1402 assert(sna->mode.shadow_active == 0); 1403 sna->mode.shadow_dirty = false; 1404} 1405 1406static void sna_crtc_slave_damage(DamagePtr damage, RegionPtr region, void *closure) 1407{ 1408 struct sna_crtc *crtc = closure; 1409 struct sna *sna = to_sna(crtc->base->scrn); 1410 RegionPtr scr; 1411 1412 DBG(("%s: pushing damage [(%d, %d), (%d, %d) x %d] to CRTC [pipe=%d] (%d, %d)\n", 1413 __FUNCTION__, 1414 region->extents.x1, region->extents.y1, region->extents.x2, region->extents.y2, 1415 region_num_rects(region), 1416 crtc->pipe, crtc->base->x, crtc->base->y)); 1417 1418 assert(crtc->slave_damage == damage); 1419 assert(sna->mode.shadow_damage); 1420 1421 RegionTranslate(region, crtc->base->x, crtc->base->y); 1422 scr = DamageRegion(sna->mode.shadow_damage); 1423 RegionUnion(scr, scr, region); 1424 RegionTranslate(region, -crtc->base->x, -crtc->base->y); 1425} 1426 1427static bool sna_crtc_enable_shadow(struct sna *sna, struct sna_crtc *crtc) 1428{ 1429 if (crtc->shadow) { 1430 assert(sna->mode.shadow_damage && sna->mode.shadow_active); 1431 return true; 1432 } 1433 1434 DBG(("%s: enabling for crtc %d\n", __FUNCTION__, crtc->id)); 1435 1436 if (!sna->mode.shadow_active) { 1437 if (!sna_mode_enable_shadow(sna)) 1438 return false; 1439 assert(sna->mode.shadow_damage); 1440 assert(sna->mode.shadow == NULL); 1441 } 1442 1443 if (crtc->slave_pixmap) { 1444 assert(crtc->slave_damage == NULL); 1445 1446 crtc->slave_damage = DamageCreate(sna_crtc_slave_damage, NULL, 1447 DamageReportRawRegion, TRUE, 1448 sna->scrn->pScreen, crtc); 1449 if (crtc->slave_damage == NULL) { 1450 if (!--sna->mode.shadow_active) 1451 sna_mode_disable_shadow(sna); 1452 return false; 1453 } 1454 1455 DamageRegister(&crtc->slave_pixmap->drawable, crtc->slave_damage); 1456 } 1457 1458 crtc->shadow = true; 1459 sna->mode.shadow_active++; 1460 return true; 1461} 1462 1463static void sna_crtc_disable_override(struct sna *sna, struct sna_crtc *crtc) 1464{ 1465 if (crtc->client_bo == NULL) 1466 return; 1467 1468 if (!crtc->transform) { 1469 DrawableRec tmp; 1470 1471 tmp.width = crtc->base->mode.HDisplay; 1472 tmp.height = crtc->base->mode.VDisplay; 1473 tmp.depth = sna->front->drawable.depth; 1474 tmp.bitsPerPixel = sna->front->drawable.bitsPerPixel; 1475 1476 sna->render.copy_boxes(sna, GXcopy, 1477 &tmp, crtc->client_bo, -crtc->base->bounds.x1, -crtc->base->bounds.y1, 1478 &sna->front->drawable, __sna_pixmap_get_bo(sna->front), 0, 0, 1479 &crtc->base->bounds, 1, 0); 1480 list_del(&crtc->shadow_link); 1481 } 1482 kgem_bo_destroy(&sna->kgem, crtc->client_bo); 1483 crtc->client_bo = NULL; 1484} 1485 1486static void sna_crtc_disable_shadow(struct sna *sna, struct sna_crtc *crtc) 1487{ 1488 crtc->fallback_shadow = false; 1489 if (!crtc->shadow) 1490 return; 1491 1492 DBG(("%s: disabling for crtc %d\n", __FUNCTION__, crtc->id)); 1493 assert(sna->mode.shadow_active > 0); 1494 1495 if (crtc->slave_damage) { 1496 assert(crtc->slave_pixmap); 1497 DamageUnregister(&crtc->slave_pixmap->drawable, crtc->slave_damage); 1498 DamageDestroy(crtc->slave_damage); 1499 crtc->slave_damage = NULL; 1500 } 1501 1502 sna_crtc_disable_override(sna, crtc); 1503 1504 if (!--sna->mode.shadow_active) 1505 sna_mode_disable_shadow(sna); 1506 1507 crtc->shadow = false; 1508} 1509 1510static void 1511__sna_crtc_disable(struct sna *sna, struct sna_crtc *sna_crtc) 1512{ 1513 sna_crtc->mode_serial++; 1514 1515 sna_crtc_disable_cursor(sna, sna_crtc); 1516 rotation_set(sna, &sna_crtc->primary, RR_Rotate_0); 1517 sna_crtc_disable_shadow(sna, sna_crtc); 1518 1519 if (sna_crtc->bo) { 1520 assert(sna_crtc->bo->active_scanout); 1521 assert(sna_crtc->bo->refcnt >= sna_crtc->bo->active_scanout); 1522 sna_crtc->bo->active_scanout--; 1523 kgem_bo_destroy(&sna->kgem, sna_crtc->bo); 1524 sna_crtc->bo = NULL; 1525 1526 assert(sna->mode.front_active); 1527 sna->mode.front_active--; 1528 sna->mode.dirty = true; 1529 } 1530 1531 if (sna_crtc->shadow_bo) { 1532 kgem_bo_destroy(&sna->kgem, sna_crtc->shadow_bo); 1533 sna_crtc->shadow_bo = NULL; 1534 } 1535 sna_crtc->transform = false; 1536 1537 assert(!sna_crtc->shadow); 1538} 1539 1540static void 1541sna_crtc_disable(xf86CrtcPtr crtc) 1542{ 1543 struct sna *sna = to_sna(crtc->scrn); 1544 struct sna_crtc *sna_crtc = to_sna_crtc(crtc); 1545 struct drm_mode_crtc arg; 1546 1547 if (sna_crtc == NULL) 1548 return; 1549 1550 DBG(("%s: disabling crtc [%d, pipe=%d]\n", __FUNCTION__, 1551 sna_crtc->id, sna_crtc->pipe)); 1552 1553 sna_crtc_force_outputs_off(crtc); 1554 assert(sna_crtc->dpms_mode == DPMSModeOff); 1555 1556 memset(&arg, 0, sizeof(arg)); 1557 arg.crtc_id = sna_crtc->id; 1558 (void)drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_SETCRTC, &arg); 1559 1560 __sna_crtc_disable(sna, sna_crtc); 1561} 1562 1563static void update_flush_interval(struct sna *sna) 1564{ 1565 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn); 1566 int i, max_vrefresh = 0; 1567 1568 DBG(("%s: front_active=%d\n", __FUNCTION__, sna->mode.front_active)); 1569 1570 for (i = 0; i < sna->mode.num_real_crtc; i++) { 1571 xf86CrtcPtr crtc = config->crtc[i]; 1572 1573 assert(to_sna_crtc(crtc) != NULL); 1574 1575 if (!crtc->enabled) { 1576 DBG(("%s: CRTC:%d (pipe %d) disabled\n", 1577 __FUNCTION__,i, to_sna_crtc(crtc)->pipe)); 1578 assert(to_sna_crtc(crtc)->bo == NULL); 1579 continue; 1580 } 1581 1582 if (to_sna_crtc(crtc)->dpms_mode != DPMSModeOn) { 1583 DBG(("%s: CRTC:%d (pipe %d) turned off\n", 1584 __FUNCTION__,i, to_sna_crtc(crtc)->pipe)); 1585 continue; 1586 } 1587 1588 DBG(("%s: CRTC:%d (pipe %d) vrefresh=%f\n", 1589 __FUNCTION__, i, to_sna_crtc(crtc)->pipe, 1590 xf86ModeVRefresh(&crtc->mode))); 1591 max_vrefresh = max(max_vrefresh, xf86ModeVRefresh(&crtc->mode)); 1592 } 1593 1594 if (max_vrefresh == 0) { 1595 assert(sna->mode.front_active == 0); 1596 sna->vblank_interval = 0; 1597 } else 1598 sna->vblank_interval = 1000 / max_vrefresh; /* Hz -> ms */ 1599 1600 DBG(("max_vrefresh=%d, vblank_interval=%d ms\n", 1601 max_vrefresh, sna->vblank_interval)); 1602} 1603 1604static struct kgem_bo *sna_create_bo_for_fbcon(struct sna *sna, 1605 const struct drm_mode_fb_cmd *fbcon) 1606{ 1607 struct drm_gem_flink flink; 1608 struct kgem_bo *bo; 1609 int ret; 1610 1611 /* Create a new reference for the fbcon so that we can track it 1612 * using a normal bo and so that when we call gem_close on it we 1613 * delete our reference and not fbcon's! 1614 */ 1615 VG_CLEAR(flink); 1616 flink.handle = fbcon->handle; 1617 ret = drmIoctl(sna->kgem.fd, DRM_IOCTL_GEM_FLINK, &flink); 1618 if (ret) 1619 return NULL; 1620 1621 bo = kgem_create_for_name(&sna->kgem, flink.name); 1622 if (bo == NULL) 1623 return NULL; 1624 1625 bo->pitch = fbcon->pitch; 1626 return bo; 1627} 1628 1629/* Copy the current framebuffer contents into the front-buffer for a seamless 1630 * transition from e.g. plymouth. 1631 */ 1632void sna_copy_fbcon(struct sna *sna) 1633{ 1634 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn); 1635 struct drm_mode_fb_cmd fbcon; 1636 PixmapRec scratch; 1637 struct sna_pixmap *priv; 1638 struct kgem_bo *bo; 1639 BoxRec box; 1640 bool ok; 1641 int sx, sy; 1642 int dx, dy; 1643 int i; 1644 1645 if (wedged(sna)) 1646 return; 1647 1648 DBG(("%s\n", __FUNCTION__)); 1649 assert((sna->flags & SNA_IS_HOSTED) == 0); 1650 1651 priv = sna_pixmap_move_to_gpu(sna->front, MOVE_WRITE | __MOVE_SCANOUT); 1652 if (priv == NULL) 1653 return; 1654 1655 /* Scan the connectors for a framebuffer and assume that is the fbcon */ 1656 VG_CLEAR(fbcon); 1657 fbcon.fb_id = 0; 1658 for (i = 0; i < sna->mode.num_real_crtc; i++) { 1659 struct sna_crtc *crtc = to_sna_crtc(config->crtc[i]); 1660 struct drm_mode_crtc mode; 1661 1662 assert(crtc != NULL); 1663 1664 VG_CLEAR(mode); 1665 mode.crtc_id = crtc->id; 1666 if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETCRTC, &mode)) 1667 continue; 1668 if (!mode.fb_id) 1669 continue; 1670 1671 fbcon.fb_id = mode.fb_id; 1672 if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETFB, &fbcon)) { 1673 fbcon.fb_id = 0; 1674 continue; 1675 } 1676 break; 1677 } 1678 if (fbcon.fb_id == 0) { 1679 DBG(("%s: no fbcon found\n", __FUNCTION__)); 1680 return; 1681 } 1682 1683 if (fbcon.fb_id == fb_id(priv->gpu_bo)) { 1684 DBG(("%s: fb already installed as scanout\n", __FUNCTION__)); 1685 return; 1686 } 1687 1688 DBG(("%s: found fbcon, size=%dx%d, depth=%d, bpp=%d\n", 1689 __FUNCTION__, fbcon.width, fbcon.height, fbcon.depth, fbcon.bpp)); 1690 1691 bo = sna_create_bo_for_fbcon(sna, &fbcon); 1692 if (bo == NULL) 1693 return; 1694 1695 DBG(("%s: fbcon handle=%d\n", __FUNCTION__, bo->handle)); 1696 1697 scratch.drawable.width = fbcon.width; 1698 scratch.drawable.height = fbcon.height; 1699 scratch.drawable.depth = fbcon.depth; 1700 scratch.drawable.bitsPerPixel = fbcon.bpp; 1701 scratch.devPrivate.ptr = NULL; 1702 1703 box.x1 = box.y1 = 0; 1704 box.x2 = min(fbcon.width, sna->front->drawable.width); 1705 box.y2 = min(fbcon.height, sna->front->drawable.height); 1706 1707 sx = dx = 0; 1708 if (box.x2 < (uint16_t)fbcon.width) 1709 sx = (fbcon.width - box.x2) / 2; 1710 if (box.x2 < sna->front->drawable.width) 1711 dx = (sna->front->drawable.width - box.x2) / 2; 1712 1713 sy = dy = 0; 1714 if (box.y2 < (uint16_t)fbcon.height) 1715 sy = (fbcon.height - box.y2) / 2; 1716 if (box.y2 < sna->front->drawable.height) 1717 dy = (sna->front->drawable.height - box.y2) / 2; 1718 1719 ok = sna->render.copy_boxes(sna, GXcopy, 1720 &scratch.drawable, bo, sx, sy, 1721 &sna->front->drawable, priv->gpu_bo, dx, dy, 1722 &box, 1, 0); 1723 if (!DAMAGE_IS_ALL(priv->gpu_damage)) 1724 sna_damage_add_box(&priv->gpu_damage, &box); 1725 1726 kgem_bo_destroy(&sna->kgem, bo); 1727 1728#if ABI_VIDEODRV_VERSION >= SET_ABI_VERSION(10, 0) 1729 sna->scrn->pScreen->canDoBGNoneRoot = ok; 1730#endif 1731} 1732 1733static bool use_shadow(struct sna *sna, xf86CrtcPtr crtc) 1734{ 1735 RRTransformPtr transform; 1736 PictTransform crtc_to_fb; 1737 struct pict_f_transform f_crtc_to_fb, f_fb_to_crtc; 1738 unsigned pitch_limit; 1739 struct sna_pixmap *priv; 1740 BoxRec b; 1741 1742 assert(sna->scrn->virtualX && sna->scrn->virtualY); 1743 1744 if (sna->flags & SNA_FORCE_SHADOW) { 1745 DBG(("%s: forcing shadow\n", __FUNCTION__)); 1746 return true; 1747 } 1748 1749 if (to_sna_crtc(crtc)->fallback_shadow) { 1750 DBG(("%s: fallback shadow\n", __FUNCTION__)); 1751 return true; 1752 } 1753 1754 if (sna->flags & SNA_TEAR_FREE && to_sna_crtc(crtc)->slave_pixmap) { 1755 DBG(("%s: TearFree shadow required\n", __FUNCTION__)); 1756 return true; 1757 } 1758 1759 if (sna->scrn->virtualX > sna->mode.max_crtc_width || 1760 sna->scrn->virtualY > sna->mode.max_crtc_height) { 1761 DBG(("%s: framebuffer too large (%dx%d) > (%dx%d)\n", 1762 __FUNCTION__, 1763 sna->scrn->virtualX, sna->scrn->virtualY, 1764 sna->mode.max_crtc_width, sna->mode.max_crtc_height)); 1765 return true; 1766 } 1767 1768 priv = sna_pixmap_force_to_gpu(sna->front, MOVE_READ | __MOVE_SCANOUT); 1769 if (priv == NULL) 1770 return true; /* maybe we can create a bo for the scanout? */ 1771 1772 if (sna->kgem.gen == 071) 1773 pitch_limit = priv->gpu_bo->tiling ? 16 * 1024 : 32 * 1024; 1774 else if ((sna->kgem.gen >> 3) > 4) 1775 pitch_limit = 32 * 1024; 1776 else if ((sna->kgem.gen >> 3) == 4) 1777 pitch_limit = priv->gpu_bo->tiling ? 16 * 1024 : 32 * 1024; 1778 else if ((sna->kgem.gen >> 3) == 3) 1779 pitch_limit = priv->gpu_bo->tiling ? 8 * 1024 : 16 * 1024; 1780 else 1781 pitch_limit = 8 * 1024; 1782 DBG(("%s: gpu bo handle=%d tiling=%d pitch=%d, limit=%d\n", __FUNCTION__, priv->gpu_bo->handle, priv->gpu_bo->tiling, priv->gpu_bo->pitch, pitch_limit)); 1783 if (priv->gpu_bo->pitch > pitch_limit) 1784 return true; 1785 1786 if (priv->gpu_bo->tiling && sna->flags & SNA_LINEAR_FB) { 1787 DBG(("%s: gpu bo is tiled, need linear, forcing shadow\n", __FUNCTION__)); 1788 return true; 1789 } 1790 1791 transform = NULL; 1792 if (crtc->transformPresent) 1793 transform = &crtc->transform; 1794 if (RRTransformCompute(crtc->x, crtc->y, 1795 crtc->mode.HDisplay, crtc->mode.VDisplay, 1796 crtc->rotation, transform, 1797 &crtc_to_fb, 1798 &f_crtc_to_fb, 1799 &f_fb_to_crtc)) { 1800 bool needs_transform = true; 1801 unsigned rotation = rotation_reduce(&to_sna_crtc(crtc)->primary, crtc->rotation); 1802 DBG(("%s: natively supported rotation? rotation=%x & supported=%x == %d\n", 1803 __FUNCTION__, crtc->rotation, to_sna_crtc(crtc)->primary.rotation.supported, 1804 !!(crtc->rotation & to_sna_crtc(crtc)->primary.rotation.supported))); 1805 if (to_sna_crtc(crtc)->primary.rotation.supported & rotation) 1806 needs_transform = RRTransformCompute(crtc->x, crtc->y, 1807 crtc->mode.HDisplay, crtc->mode.VDisplay, 1808 RR_Rotate_0, transform, 1809 NULL, NULL, NULL); 1810 if (needs_transform) { 1811 DBG(("%s: RandR transform present\n", __FUNCTION__)); 1812 return true; 1813 } 1814 } 1815 1816 /* And finally check that it is entirely visible */ 1817 b.x1 = b.y1 = 0; 1818 b.x2 = crtc->mode.HDisplay; 1819 b.y2 = crtc->mode.VDisplay; 1820 pixman_f_transform_bounds(&f_crtc_to_fb, &b); 1821 DBG(("%s? bounds (%d, %d), (%d, %d), framebufer %dx%d\n", 1822 __FUNCTION__, b.x1, b.y1, b.x2, b.y2, 1823 sna->scrn->virtualX, sna->scrn->virtualY)); 1824 1825 if (b.x1 < 0 || b.y1 < 0 || 1826 b.x2 > sna->scrn->virtualX || 1827 b.y2 > sna->scrn->virtualY) { 1828 DBG(("%s: scanout is partly outside the framebuffer\n", 1829 __FUNCTION__)); 1830 return true; 1831 } 1832 1833 return false; 1834} 1835 1836static void set_shadow(struct sna *sna, RegionPtr region) 1837{ 1838 struct sna_pixmap *priv = sna_pixmap(sna->front); 1839 1840 assert(priv->gpu_bo); 1841 assert(sna->mode.shadow); 1842 1843 DBG(("%s: waiting for region %dx[(%d, %d), (%d, %d)], front handle=%d, shadow handle=%d\n", 1844 __FUNCTION__, 1845 region_num_rects(region), 1846 region->extents.x1, region->extents.y1, 1847 region->extents.x2, region->extents.y2, 1848 priv->gpu_bo->handle, sna->mode.shadow->handle)); 1849 1850 assert(priv->pinned & PIN_SCANOUT); 1851 assert((priv->pinned & PIN_PRIME) == 0); 1852 assert(sna->mode.shadow != priv->gpu_bo); 1853 1854 RegionCopy(&sna->mode.shadow_region, region); 1855 1856 priv->move_to_gpu = wait_for_shadow; 1857 priv->move_to_gpu_data = sna; 1858} 1859 1860static struct kgem_bo * 1861get_scanout_bo(struct sna *sna, PixmapPtr pixmap) 1862{ 1863 struct sna_pixmap *priv; 1864 1865 priv = sna_pixmap_force_to_gpu(pixmap, MOVE_READ | __MOVE_SCANOUT); 1866 if (!priv) 1867 return NULL; 1868 1869 if (priv->gpu_bo->pitch & 63) { 1870 struct kgem_bo *tmp; 1871 BoxRec b; 1872 1873 DBG(("%s: converting to scanout bo due to bad pitch [%d]\n", 1874 __FUNCTION__, priv->gpu_bo->pitch)); 1875 1876 if (priv->pinned) { 1877 DBG(("%s: failed as the Pixmap is already pinned [%x]\n", 1878 __FUNCTION__, priv->pinned)); 1879 return NULL; 1880 } 1881 1882 tmp = kgem_create_2d(&sna->kgem, 1883 pixmap->drawable.width, 1884 pixmap->drawable.height, 1885 sna->scrn->bitsPerPixel, 1886 priv->gpu_bo->tiling, 1887 CREATE_EXACT | CREATE_SCANOUT); 1888 if (tmp == NULL) { 1889 DBG(("%s: allocation failed\n", __FUNCTION__)); 1890 return NULL; 1891 } 1892 1893 b.x1 = 0; 1894 b.y1 = 0; 1895 b.x2 = pixmap->drawable.width; 1896 b.y2 = pixmap->drawable.height; 1897 1898 if (sna->render.copy_boxes(sna, GXcopy, 1899 &pixmap->drawable, priv->gpu_bo, 0, 0, 1900 &pixmap->drawable, tmp, 0, 0, 1901 &b, 1, COPY_LAST)) { 1902 DBG(("%s: copy failed\n", __FUNCTION__)); 1903 kgem_bo_destroy(&sna->kgem, tmp); 1904 return NULL; 1905 } 1906 1907 kgem_bo_destroy(&sna->kgem, priv->gpu_bo); 1908 priv->gpu_bo = tmp; 1909 } 1910 1911 priv->pinned |= PIN_SCANOUT; 1912 return priv->gpu_bo; 1913} 1914 1915static struct kgem_bo *sna_crtc_attach(xf86CrtcPtr crtc) 1916{ 1917 struct sna_crtc *sna_crtc = to_sna_crtc(crtc); 1918 ScrnInfoPtr scrn = crtc->scrn; 1919 struct sna *sna = to_sna(scrn); 1920 struct kgem_bo *bo; 1921 1922 sna_crtc->transform = false; 1923 sna_crtc->rotation = RR_Rotate_0; 1924 1925 if (use_shadow(sna, crtc)) { 1926 unsigned long tiled_limit; 1927 int tiling; 1928 1929force_shadow: 1930 if (!sna_crtc_enable_shadow(sna, sna_crtc)) { 1931 DBG(("%s: failed to enable crtc shadow\n", __FUNCTION__)); 1932 return NULL; 1933 } 1934 1935 DBG(("%s: attaching to per-crtc pixmap %dx%d\n", 1936 __FUNCTION__, crtc->mode.HDisplay, crtc->mode.VDisplay)); 1937 1938 bo = sna_crtc->shadow_bo; 1939 if (bo) { 1940 if (sna_crtc->shadow_bo_width == crtc->mode.HDisplay && 1941 sna_crtc->shadow_bo_height == crtc->mode.VDisplay) { 1942 DBG(("%s: reusing current shadow bo handle=%d\n", 1943 __FUNCTION__, bo->handle)); 1944 goto out_shadow; 1945 } 1946 1947 kgem_bo_destroy(&sna->kgem, bo); 1948 sna_crtc->shadow_bo = NULL; 1949 } 1950 1951 tiling = I915_TILING_X; 1952 if (sna->kgem.gen == 071) 1953 tiled_limit = 16 * 1024 * 8; 1954 else if ((sna->kgem.gen >> 3) > 4) 1955 tiled_limit = 32 * 1024 * 8; 1956 else if ((sna->kgem.gen >> 3) == 4) 1957 tiled_limit = 16 * 1024 * 8; 1958 else 1959 tiled_limit = 8 * 1024 * 8; 1960 if ((unsigned long)crtc->mode.HDisplay * scrn->bitsPerPixel > tiled_limit) 1961 tiling = I915_TILING_NONE; 1962 if (sna->flags & SNA_LINEAR_FB) 1963 tiling = I915_TILING_NONE; 1964 1965 bo = kgem_create_2d(&sna->kgem, 1966 crtc->mode.HDisplay, crtc->mode.VDisplay, 1967 scrn->bitsPerPixel, 1968 tiling, CREATE_SCANOUT); 1969 if (bo == NULL) { 1970 DBG(("%s: failed to allocate crtc scanout\n", __FUNCTION__)); 1971 return NULL; 1972 } 1973 1974 if (!get_fb(sna, bo, crtc->mode.HDisplay, crtc->mode.VDisplay)) { 1975 DBG(("%s: failed to bind fb for crtc scanout\n", __FUNCTION__)); 1976 kgem_bo_destroy(&sna->kgem, bo); 1977 return NULL; 1978 } 1979 1980 if (__sna_pixmap_get_bo(sna->front) && !crtc->transformPresent) { 1981 DrawableRec tmp; 1982 BoxRec b; 1983 1984 b.x1 = crtc->x; 1985 b.y1 = crtc->y; 1986 b.x2 = crtc->x + crtc->mode.HDisplay; 1987 b.y2 = crtc->y + crtc->mode.VDisplay; 1988 1989 DBG(("%s: copying onto shadow CRTC: (%d, %d)x(%d, %d), handle=%d\n", 1990 __FUNCTION__, 1991 b.x1, b.y1, 1992 b.x2, b.y2, 1993 bo->handle)); 1994 1995 tmp.width = crtc->mode.HDisplay; 1996 tmp.height = crtc->mode.VDisplay; 1997 tmp.depth = sna->front->drawable.depth; 1998 tmp.bitsPerPixel = sna->front->drawable.bitsPerPixel; 1999 2000 (void)sna->render.copy_boxes(sna, GXcopy, 2001 &sna->front->drawable, __sna_pixmap_get_bo(sna->front), 0, 0, 2002 &tmp, bo, -b.x1, -b.y1, 2003 &b, 1, 0); 2004 } 2005 2006 sna_crtc->shadow_bo_width = crtc->mode.HDisplay; 2007 sna_crtc->shadow_bo_height = crtc->mode.VDisplay; 2008 sna_crtc->shadow_bo = bo; 2009out_shadow: 2010 sna_crtc->transform = true; 2011 return kgem_bo_reference(bo); 2012 } else { 2013 if (sna_crtc->shadow_bo) { 2014 kgem_bo_destroy(&sna->kgem, sna_crtc->shadow_bo); 2015 sna_crtc->shadow_bo = NULL; 2016 } 2017 2018 if (sna_crtc->slave_pixmap) { 2019 DBG(("%s: attaching to scanout pixmap\n", __FUNCTION__)); 2020 bo = get_scanout_bo(sna, sna_crtc->slave_pixmap); 2021 if (bo == NULL) { 2022 DBG(("%s: failed to pin crtc scanout\n", __FUNCTION__)); 2023 sna_crtc->fallback_shadow = true; 2024 goto force_shadow; 2025 } 2026 2027 if (!get_fb(sna, bo, 2028 sna_crtc->slave_pixmap->drawable.width, 2029 sna_crtc->slave_pixmap->drawable.height)) { 2030 DBG(("%s: failed to bind fb for crtc scanout\n", __FUNCTION__)); 2031 sna_crtc->fallback_shadow = true; 2032 goto force_shadow; 2033 } 2034 } else { 2035 DBG(("%s: attaching to framebuffer\n", __FUNCTION__)); 2036 bo = get_scanout_bo(sna, sna->front); 2037 if (bo == NULL) { 2038 DBG(("%s: failed to pin framebuffer\n", __FUNCTION__)); 2039 sna_crtc->fallback_shadow = true; 2040 goto force_shadow; 2041 } 2042 2043 if (!get_fb(sna, bo, scrn->virtualX, scrn->virtualY)) { 2044 DBG(("%s: failed to bind fb for crtc scanout\n", __FUNCTION__)); 2045 sna_crtc->fallback_shadow = true; 2046 goto force_shadow; 2047 } 2048 } 2049 2050 if (sna->flags & SNA_TEAR_FREE) { 2051 assert(sna_crtc->slave_pixmap == NULL); 2052 2053 DBG(("%s: enabling TearFree shadow\n", __FUNCTION__)); 2054 if (!sna_crtc_enable_shadow(sna, sna_crtc)) { 2055 DBG(("%s: failed to enable crtc shadow\n", __FUNCTION__)); 2056 return NULL; 2057 } 2058 2059 if (sna->mode.shadow == NULL && !wedged(sna)) { 2060 RegionRec region; 2061 struct kgem_bo *shadow; 2062 2063 DBG(("%s: creating TearFree shadow bo\n", __FUNCTION__)); 2064 2065 region.extents.x1 = 0; 2066 region.extents.y1 = 0; 2067 region.extents.x2 = sna->scrn->virtualX; 2068 region.extents.y2 = sna->scrn->virtualY; 2069 region.data = NULL; 2070 2071 shadow = kgem_create_2d(&sna->kgem, 2072 region.extents.x2, 2073 region.extents.y2, 2074 scrn->bitsPerPixel, 2075 kgem_choose_tiling(&sna->kgem, 2076 I915_TILING_X, 2077 region.extents.x2, 2078 region.extents.y2, 2079 sna->scrn->bitsPerPixel), 2080 CREATE_SCANOUT); 2081 if (shadow == NULL) { 2082 DBG(("%s: failed to allocate TearFree shadow bo\n", __FUNCTION__)); 2083 sna_crtc->fallback_shadow = true; 2084 goto force_shadow; 2085 } 2086 2087 if (!get_fb(sna, shadow, 2088 region.extents.x2, 2089 region.extents.y2)) { 2090 DBG(("%s: failed to bind fb for TearFeee shadow\n", __FUNCTION__)); 2091 kgem_bo_destroy(&sna->kgem, shadow); 2092 sna_crtc->fallback_shadow = true; 2093 goto force_shadow; 2094 } 2095 2096 sna->mode.shadow = shadow; 2097 set_shadow(sna, ®ion); 2098 } 2099 2100 sna_crtc_disable_override(sna, sna_crtc); 2101 } else 2102 sna_crtc_disable_shadow(sna, sna_crtc); 2103 2104 sna_crtc->rotation = rotation_reduce(&sna_crtc->primary, crtc->rotation); 2105 assert(sna_crtc->primary.rotation.supported & sna_crtc->rotation); 2106 return kgem_bo_reference(bo); 2107 } 2108} 2109 2110static void sna_crtc_randr(xf86CrtcPtr crtc) 2111{ 2112 struct sna_crtc *sna_crtc = to_sna_crtc(crtc); 2113 struct pict_f_transform f_crtc_to_fb, f_fb_to_crtc; 2114 PictTransform crtc_to_fb; 2115 PictFilterPtr filter; 2116 xFixed *params; 2117 int nparams; 2118 RRTransformPtr transform; 2119 int needs_transform; 2120 2121 transform = NULL; 2122 if (crtc->transformPresent) 2123 transform = &crtc->transform; 2124 2125 needs_transform = 2126 RRTransformCompute(crtc->x, crtc->y, 2127 crtc->mode.HDisplay, crtc->mode.VDisplay, 2128 crtc->rotation, transform, 2129 &crtc_to_fb, 2130 &f_crtc_to_fb, 2131 &f_fb_to_crtc); 2132 2133 filter = NULL; 2134 params = NULL; 2135 nparams = 0; 2136 if (sna_crtc->transform) { 2137#ifdef RANDR_12_INTERFACE 2138 if (transform) { 2139 if (transform->nparams) { 2140 params = malloc(transform->nparams * sizeof(xFixed)); 2141 if (params) { 2142 memcpy(params, transform->params, 2143 transform->nparams * sizeof(xFixed)); 2144 nparams = transform->nparams; 2145 filter = transform->filter; 2146 } 2147 } else 2148 filter = transform->filter; 2149 } 2150#endif 2151 crtc->transform_in_use = needs_transform; 2152 } else 2153 crtc->transform_in_use = sna_crtc->rotation != RR_Rotate_0; 2154 2155 crtc->crtc_to_framebuffer = crtc_to_fb; 2156 crtc->f_crtc_to_framebuffer = f_crtc_to_fb; 2157 crtc->f_framebuffer_to_crtc = f_fb_to_crtc; 2158 2159 free(crtc->params); 2160 crtc->params = params; 2161 crtc->nparams = nparams; 2162 2163 crtc->filter = filter; 2164 if (filter) { 2165 crtc->filter_width = filter->width; 2166 crtc->filter_height = filter->height; 2167 } else { 2168 crtc->filter_width = 0; 2169 crtc->filter_height = 0; 2170 } 2171 2172 crtc->bounds.x1 = 0; 2173 crtc->bounds.x2 = crtc->mode.HDisplay; 2174 crtc->bounds.y1 = 0; 2175 crtc->bounds.y2 = crtc->mode.VDisplay; 2176 pixman_f_transform_bounds(&f_crtc_to_fb, &crtc->bounds); 2177 2178 DBG(("%s: transform? %d, bounds (%d, %d), (%d, %d)\n", 2179 __FUNCTION__, crtc->transform_in_use, 2180 crtc->bounds.x1, crtc->bounds.y1, 2181 crtc->bounds.x2, crtc->bounds.y2)); 2182} 2183 2184static void 2185sna_crtc_damage(xf86CrtcPtr crtc) 2186{ 2187 ScreenPtr screen = crtc->scrn->pScreen; 2188 struct sna *sna = to_sna(crtc->scrn); 2189 RegionRec region, *damage; 2190 2191 region.extents = crtc->bounds; 2192 region.data = NULL; 2193 2194 if (region.extents.x1 < 0) 2195 region.extents.x1 = 0; 2196 if (region.extents.y1 < 0) 2197 region.extents.y1 = 0; 2198 if (region.extents.x2 > screen->width) 2199 region.extents.x2 = screen->width; 2200 if (region.extents.y2 > screen->height) 2201 region.extents.y2 = screen->height; 2202 2203 DBG(("%s: marking crtc %d as completely damaged (%d, %d), (%d, %d)\n", 2204 __FUNCTION__, to_sna_crtc(crtc)->id, 2205 region.extents.x1, region.extents.y1, 2206 region.extents.x2, region.extents.y2)); 2207 to_sna_crtc(crtc)->client_damage = region; 2208 2209 assert(sna->mode.shadow_damage && sna->mode.shadow_active); 2210 damage = DamageRegion(sna->mode.shadow_damage); 2211 RegionUnion(damage, damage, ®ion); 2212 2213 DBG(("%s: damage now %dx[(%d, %d), (%d, %d)]\n", 2214 __FUNCTION__, 2215 region_num_rects(damage), 2216 damage->extents.x1, damage->extents.y1, 2217 damage->extents.x2, damage->extents.y2)); 2218} 2219 2220static char *outputs_for_crtc(xf86CrtcPtr crtc, char *outputs, int max) 2221{ 2222 struct sna *sna = to_sna(crtc->scrn); 2223 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(crtc->scrn); 2224 int len, i; 2225 2226 for (i = len = 0; i < sna->mode.num_real_output; i++) { 2227 xf86OutputPtr output = config->output[i]; 2228 2229 if (output->crtc != crtc) 2230 continue; 2231 2232 len += snprintf(outputs+len, max-len, "%s, ", output->name); 2233 } 2234 assert(len >= 2); 2235 outputs[len-2] = '\0'; 2236 2237 return outputs; 2238} 2239 2240static const char *rotation_to_str(Rotation rotation) 2241{ 2242 switch (rotation & RR_Rotate_All) { 2243 case 0: 2244 case RR_Rotate_0: return "normal"; 2245 case RR_Rotate_90: return "left"; 2246 case RR_Rotate_180: return "inverted"; 2247 case RR_Rotate_270: return "right"; 2248 default: return "unknown"; 2249 } 2250} 2251 2252static const char *reflection_to_str(Rotation rotation) 2253{ 2254 switch (rotation & RR_Reflect_All) { 2255 case 0: return "none"; 2256 case RR_Reflect_X: return "X axis"; 2257 case RR_Reflect_Y: return "Y axis"; 2258 case RR_Reflect_X | RR_Reflect_Y: return "X and Y axes"; 2259 default: return "invalid"; 2260 } 2261} 2262 2263static Bool 2264__sna_crtc_set_mode(xf86CrtcPtr crtc) 2265{ 2266 struct sna *sna = to_sna(crtc->scrn); 2267 struct sna_crtc *sna_crtc = to_sna_crtc(crtc); 2268 struct kgem_bo *saved_bo, *bo; 2269 uint32_t saved_offset; 2270 bool saved_transform; 2271 2272 DBG(("%s\n", __FUNCTION__)); 2273 2274 saved_bo = sna_crtc->bo; 2275 saved_transform = sna_crtc->transform; 2276 saved_offset = sna_crtc->offset; 2277 2278 sna_crtc->fallback_shadow = false; 2279retry: /* Attach per-crtc pixmap or direct */ 2280 bo = sna_crtc_attach(crtc); 2281 if (bo == NULL) { 2282 xf86DrvMsg(crtc->scrn->scrnIndex, X_ERROR, 2283 "unable to attach scanout\n"); 2284 goto error; 2285 } 2286 2287 /* Prevent recursion when enabling outputs during execbuffer */ 2288 if (bo->exec && RQ(bo->rq)->bo == NULL) 2289 _kgem_submit(&sna->kgem); 2290 2291 sna_crtc->bo = bo; 2292 if (!sna_crtc_apply(crtc)) { 2293 int err = errno; 2294 2295 kgem_bo_destroy(&sna->kgem, bo); 2296 2297 if (!sna_crtc->shadow) { 2298 sna_crtc->fallback_shadow = true; 2299 goto retry; 2300 } 2301 2302 xf86DrvMsg(crtc->scrn->scrnIndex, X_ERROR, 2303 "failed to set mode: %s [%d]\n", strerror(err), err); 2304 goto error; 2305 } 2306 2307 bo->active_scanout++; 2308 if (saved_bo) { 2309 assert(saved_bo->active_scanout); 2310 assert(saved_bo->refcnt >= saved_bo->active_scanout); 2311 saved_bo->active_scanout--; 2312 kgem_bo_destroy(&sna->kgem, saved_bo); 2313 } 2314 2315 sna_crtc_randr(crtc); 2316 if (sna_crtc->transform) 2317 sna_crtc_damage(crtc); 2318 sna->mode.front_active += saved_bo == NULL; 2319 sna->mode.dirty = true; 2320 DBG(("%s: front_active=%d\n", __FUNCTION__, sna->mode.front_active)); 2321 2322 return TRUE; 2323 2324error: 2325 sna_crtc->offset = saved_offset; 2326 sna_crtc->transform = saved_transform; 2327 sna_crtc->bo = saved_bo; 2328 sna_mode_discover(sna); 2329 return FALSE; 2330} 2331 2332static Bool 2333sna_crtc_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode, 2334 Rotation rotation, int x, int y) 2335{ 2336 struct sna *sna = to_sna(crtc->scrn); 2337 struct sna_crtc *sna_crtc = to_sna_crtc(crtc); 2338 struct drm_mode_modeinfo saved_kmode; 2339 char outputs[256]; 2340 2341 if (mode->HDisplay == 0 || mode->VDisplay == 0) 2342 return FALSE; 2343 2344 assert(sna_crtc); 2345 2346 xf86DrvMsg(crtc->scrn->scrnIndex, X_INFO, 2347 "switch to mode %dx%d@%.1f on %s using pipe %d, position (%d, %d), rotation %s, reflection %s\n", 2348 mode->HDisplay, mode->VDisplay, xf86ModeVRefresh(mode), 2349 outputs_for_crtc(crtc, outputs, sizeof(outputs)), sna_crtc->pipe, 2350 x, y, rotation_to_str(rotation), reflection_to_str(rotation)); 2351 2352 assert(mode->HDisplay <= sna->mode.max_crtc_width && 2353 mode->VDisplay <= sna->mode.max_crtc_height); 2354 2355#if HAS_GAMMA 2356 drmModeCrtcSetGamma(sna->kgem.fd, sna_crtc->id, 2357 crtc->gamma_size, 2358 crtc->gamma_red, 2359 crtc->gamma_green, 2360 crtc->gamma_blue); 2361#endif 2362 2363 saved_kmode = sna_crtc->kmode; 2364 mode_to_kmode(&sna_crtc->kmode, mode); 2365 if (__sna_crtc_set_mode(crtc)) 2366 return TRUE; 2367 2368 sna_crtc->kmode = saved_kmode; 2369 return FALSE; 2370} 2371 2372static void 2373sna_crtc_dpms(xf86CrtcPtr crtc, int mode) 2374{ 2375 struct sna_crtc *priv = to_sna_crtc(crtc); 2376 2377 DBG(("%s(pipe %d, dpms mode -> %d):= active=%d\n", 2378 __FUNCTION__, priv->pipe, mode, mode == DPMSModeOn)); 2379 if (priv->dpms_mode == mode) 2380 return; 2381 2382 assert(priv); 2383 priv->dpms_mode = mode; 2384 2385 if (mode == DPMSModeOn && crtc->enabled && priv->bo == NULL) { 2386 if (__sna_crtc_set_mode(crtc)) 2387 update_flush_interval(to_sna(crtc->scrn)); 2388 else 2389 mode = DPMSModeOff; 2390 } 2391 2392 if (mode != DPMSModeOn) 2393 sna_crtc_disable(crtc); 2394} 2395 2396void sna_mode_adjust_frame(struct sna *sna, int x, int y) 2397{ 2398 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn); 2399 xf86CrtcPtr crtc; 2400 int saved_x, saved_y; 2401 2402 if ((unsigned)config->compat_output >= config->num_output) 2403 return; 2404 2405 crtc = config->output[config->compat_output]->crtc; 2406 if (crtc == NULL || !crtc->enabled) 2407 return; 2408 2409 if (crtc->x == x && crtc->y == y) 2410 return; 2411 2412 saved_x = crtc->x; 2413 saved_y = crtc->y; 2414 2415 crtc->x = x; 2416 crtc->y = y; 2417 if (to_sna_crtc(crtc) && !__sna_crtc_set_mode(crtc)) { 2418 crtc->x = saved_x; 2419 crtc->y = saved_y; 2420 } 2421} 2422 2423static void 2424sna_crtc_gamma_set(xf86CrtcPtr crtc, 2425 CARD16 *red, CARD16 *green, CARD16 *blue, int size) 2426{ 2427 assert(to_sna_crtc(crtc)); 2428 drmModeCrtcSetGamma(to_sna(crtc->scrn)->kgem.fd, 2429 to_sna_crtc(crtc)->id, 2430 size, red, green, blue); 2431} 2432 2433static void 2434sna_crtc_destroy(xf86CrtcPtr crtc) 2435{ 2436 struct sna_crtc *sna_crtc = to_sna_crtc(crtc); 2437 2438 if (sna_crtc == NULL) 2439 return; 2440 2441 free(sna_crtc); 2442 crtc->driver_private = NULL; 2443} 2444 2445#if HAS_PIXMAP_SHARING 2446static Bool 2447sna_crtc_set_scanout_pixmap(xf86CrtcPtr crtc, PixmapPtr pixmap) 2448{ 2449 struct sna_crtc *sna_crtc = to_sna_crtc(crtc); 2450 2451 if (sna_crtc == NULL) 2452 return FALSE; 2453 2454 if (pixmap == sna_crtc->slave_pixmap) 2455 return TRUE; 2456 2457 DBG(("%s: CRTC:%d, pipe=%d setting scanout pixmap=%ld\n", 2458 __FUNCTION__, sna_crtc->id, sna_crtc->pipe, 2459 pixmap ? pixmap->drawable.serialNumber : 0)); 2460 2461 /* Disable first so that we can unregister the damage tracking */ 2462 sna_crtc_disable_shadow(to_sna(crtc->scrn), sna_crtc); 2463 2464 sna_crtc->slave_pixmap = pixmap; 2465 2466 return TRUE; 2467} 2468#endif 2469 2470static const xf86CrtcFuncsRec sna_crtc_funcs = { 2471#if XF86_CRTC_VERSION >= 1 2472 .dpms = sna_crtc_dpms, 2473#endif 2474 .set_mode_major = sna_crtc_set_mode_major, 2475 .gamma_set = sna_crtc_gamma_set, 2476 .destroy = sna_crtc_destroy, 2477#if HAS_PIXMAP_SHARING 2478 .set_scanout_pixmap = sna_crtc_set_scanout_pixmap, 2479#endif 2480}; 2481 2482inline static bool prop_is_rotation(struct drm_mode_get_property *prop) 2483{ 2484 if ((prop->flags & (1 << 5)) == 0) 2485 return false; 2486 2487 if (strcmp(prop->name, "rotation")) 2488 return false; 2489 2490 return true; 2491} 2492 2493static int plane_details(struct sna *sna, struct plane *p) 2494{ 2495 struct local_mode_obj_get_properties arg; 2496 uint64_t stack_props[24]; 2497 uint32_t *props = (uint32_t *)stack_props; 2498 uint64_t *values = stack_props + 8; 2499 int i, type = DRM_PLANE_TYPE_OVERLAY; 2500 2501 memset(&arg, 0, sizeof(struct local_mode_obj_get_properties)); 2502 arg.obj_id = p->id; 2503 arg.obj_type = LOCAL_MODE_OBJECT_PLANE; 2504 2505 arg.props_ptr = (uintptr_t)props; 2506 arg.prop_values_ptr = (uintptr_t)values; 2507 arg.count_props = 16; 2508 2509 if (drmIoctl(sna->kgem.fd, LOCAL_IOCTL_MODE_OBJ_GETPROPERTIES, &arg)) 2510 return -1; 2511 2512 DBG(("%s: object %d (type %x) has %d props\n", __FUNCTION__, 2513 p->id, LOCAL_MODE_OBJECT_PLANE, arg.count_props)); 2514 2515 if (arg.count_props > 16) { 2516 props = malloc(2*sizeof(uint64_t)*arg.count_props); 2517 if (props == NULL) 2518 return -1; 2519 2520 values = (uint64_t *)props + arg.count_props; 2521 2522 arg.props_ptr = (uintptr_t)props; 2523 arg.prop_values_ptr = (uintptr_t)values; 2524 2525 if (drmIoctl(sna->kgem.fd, LOCAL_IOCTL_MODE_OBJ_GETPROPERTIES, &arg)) 2526 arg.count_props = 0; 2527 } 2528 VG(VALGRIND_MAKE_MEM_DEFINED(arg.props_ptr, sizeof(uint32_t)*arg.count_props)); 2529 VG(VALGRIND_MAKE_MEM_DEFINED(arg.prop_values_ptr, sizeof(uint64_t)*arg.count_props)); 2530 2531 for (i = 0; i < arg.count_props; i++) { 2532 struct drm_mode_get_property prop; 2533 2534 memset(&prop, 0, sizeof(prop)); 2535 prop.prop_id = props[i]; 2536 if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETPROPERTY, &prop)) { 2537 ERR(("%s: prop[%d].id=%d GETPROPERTY failed with errno=%d\n", 2538 __FUNCTION__, i, props[i], errno)); 2539 continue; 2540 } 2541 2542 DBG(("%s: prop[%d] .id=%ld, .name=%s, .flags=%x, .value=%ld\n", __FUNCTION__, i, 2543 (long)props[i], prop.name, (unsigned)prop.flags, (long)values[i])); 2544 2545 if (strcmp(prop.name, "type") == 0) { 2546 type = values[i]; 2547 } else if (prop_is_rotation(&prop)) { 2548 struct drm_mode_property_enum *enums; 2549 2550 p->rotation.prop = props[i]; 2551 p->rotation.current = values[i]; 2552 2553 DBG(("%s: found rotation property .id=%d, value=%ld, num_enums=%d\n", 2554 __FUNCTION__, prop.prop_id, (long)values[i], prop.count_enum_blobs)); 2555 enums = malloc(prop.count_enum_blobs * sizeof(struct drm_mode_property_enum)); 2556 if (enums != NULL) { 2557 prop.count_values = 0; 2558 prop.enum_blob_ptr = (uintptr_t)enums; 2559 2560 if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETPROPERTY, &prop) == 0) { 2561 int j; 2562 2563 /* XXX we assume that the mapping between kernel enum and 2564 * RandR remains fixed for our lifetimes. 2565 */ 2566 VG(VALGRIND_MAKE_MEM_DEFINED(enums, sizeof(*enums)*prop.count_enum_blobs)); 2567 for (j = 0; j < prop.count_enum_blobs; j++) { 2568 DBG(("%s: rotation[%d] = %s [%lx]\n", __FUNCTION__, 2569 j, enums[j].name, (long)enums[j].value)); 2570 p->rotation.supported |= 1 << enums[j].value; 2571 } 2572 } 2573 2574 free(enums); 2575 } 2576 } 2577 } 2578 2579 if (props != (uint32_t *)stack_props) 2580 free(props); 2581 2582 DBG(("%s: plane=%d type=%d\n", __FUNCTION__, p->id, type)); 2583 return type; 2584} 2585 2586static void 2587sna_crtc_find_planes(struct sna *sna, struct sna_crtc *crtc) 2588{ 2589#define LOCAL_IOCTL_SET_CAP DRM_IOWR(0x0d, struct local_set_cap) 2590#define LOCAL_IOCTL_MODE_GETPLANERESOURCES DRM_IOWR(0xb5, struct local_mode_get_plane_res) 2591#define LOCAL_IOCTL_MODE_GETPLANE DRM_IOWR(0xb6, struct local_mode_get_plane) 2592 struct local_set_cap { 2593 uint64_t name; 2594 uint64_t value; 2595 } cap; 2596 struct local_mode_get_plane_res { 2597 uint64_t plane_id_ptr; 2598 uint64_t count_planes; 2599 } r; 2600 uint32_t stack_planes[32]; 2601 uint32_t *planes = stack_planes; 2602 int i; 2603 2604 VG_CLEAR(cap); 2605 cap.name = DRM_CLIENT_CAP_UNIVERSAL_PLANES; 2606 cap.value = 1; 2607 (void)drmIoctl(sna->kgem.fd, LOCAL_IOCTL_SET_CAP, &cap); 2608 2609 VG_CLEAR(r); 2610 r.plane_id_ptr = (uintptr_t)planes; 2611 r.count_planes = ARRAY_SIZE(stack_planes); 2612 if (drmIoctl(sna->kgem.fd, LOCAL_IOCTL_MODE_GETPLANERESOURCES, &r)) { 2613 ERR(("%s: GETPLANERESOURCES failed with errno=%d\n", __FUNCTION__, errno)); 2614 return; 2615 } 2616 2617 DBG(("%s: %d planes\n", __FUNCTION__, (int)r.count_planes)); 2618 2619 if (r.count_planes > ARRAY_SIZE(stack_planes)) { 2620 planes = malloc(sizeof(uint32_t)*r.count_planes); 2621 if (planes == NULL) 2622 return; 2623 2624 r.plane_id_ptr = (uintptr_t)planes; 2625 if (drmIoctl(sna->kgem.fd, LOCAL_IOCTL_MODE_GETPLANERESOURCES, &r)) 2626 r.count_planes = 0; 2627 } 2628 2629 VG(VALGRIND_MAKE_MEM_DEFINED(planes, sizeof(uint32_t)*r.count_planes)); 2630 2631 for (i = 0; i < r.count_planes; i++) { 2632 struct local_mode_get_plane { 2633 uint32_t plane_id; 2634 2635 uint32_t crtc_id; 2636 uint32_t fb_id; 2637 2638 uint32_t possible_crtcs; 2639 uint32_t gamma_size; 2640 2641 uint32_t count_format_types; 2642 uint64_t format_type_ptr; 2643 } p; 2644 struct plane details; 2645 2646 VG_CLEAR(p); 2647 p.plane_id = planes[i]; 2648 p.count_format_types = 0; 2649 if (drmIoctl(sna->kgem.fd, LOCAL_IOCTL_MODE_GETPLANE, &p)) 2650 continue; 2651 2652 if ((p.possible_crtcs & (1 << crtc->pipe)) == 0) 2653 continue; 2654 2655 DBG(("%s: plane %d is attached to our pipe=%d\n", 2656 __FUNCTION__, planes[i], crtc->pipe)); 2657 2658 details.id = p.plane_id; 2659 details.rotation.prop = 0; 2660 details.rotation.supported = RR_Rotate_0; 2661 details.rotation.current = RR_Rotate_0; 2662 2663 switch (plane_details(sna, &details)) { 2664 default: 2665 break; 2666 2667 case DRM_PLANE_TYPE_PRIMARY: 2668 crtc->primary = details; 2669 break; 2670 2671 case DRM_PLANE_TYPE_CURSOR: 2672 break; 2673 2674 case DRM_PLANE_TYPE_OVERLAY: 2675 if (crtc->sprite.id == 0) 2676 crtc->sprite = details; 2677 break; 2678 } 2679 } 2680 2681 if (planes != stack_planes) 2682 free(planes); 2683} 2684 2685static void 2686sna_crtc_init__rotation(struct sna *sna, struct sna_crtc *crtc) 2687{ 2688 crtc->rotation = RR_Rotate_0; 2689 crtc->primary.rotation.supported = RR_Rotate_0; 2690 crtc->primary.rotation.current = RR_Rotate_0; 2691 crtc->sprite.rotation = crtc->primary.rotation; 2692} 2693 2694static void 2695sna_crtc_init__cursor(struct sna *sna, struct sna_crtc *crtc) 2696{ 2697 struct drm_mode_cursor arg; 2698 2699 VG_CLEAR(arg); 2700 arg.flags = DRM_MODE_CURSOR_BO; 2701 arg.crtc_id = crtc->id; 2702 arg.width = arg.height = 0; 2703 arg.handle = 0; 2704 2705 (void)drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_CURSOR, &arg); 2706} 2707 2708static bool 2709sna_crtc_add(ScrnInfoPtr scrn, int id) 2710{ 2711 struct sna *sna = to_sna(scrn); 2712 xf86CrtcPtr crtc; 2713 struct sna_crtc *sna_crtc; 2714 struct drm_i915_get_pipe_from_crtc_id get_pipe; 2715 2716 DBG(("%s(%d)\n", __FUNCTION__, id)); 2717 2718 sna_crtc = calloc(sizeof(struct sna_crtc), 1); 2719 if (sna_crtc == NULL) 2720 return false; 2721 2722 sna_crtc->id = id; 2723 sna_crtc->dpms_mode = -1; 2724 2725 VG_CLEAR(get_pipe); 2726 get_pipe.pipe = 0; 2727 get_pipe.crtc_id = sna_crtc->id; 2728 if (drmIoctl(sna->kgem.fd, 2729 DRM_IOCTL_I915_GET_PIPE_FROM_CRTC_ID, 2730 &get_pipe)) { 2731 free(sna_crtc); 2732 return false; 2733 } 2734 sna_crtc->pipe = get_pipe.pipe; 2735 2736 if (is_zaphod(scrn) && 2737 scrn->confScreen->device->screen != sna_crtc->pipe) { 2738 free(sna_crtc); 2739 return true; 2740 } 2741 2742 sna_crtc_init__rotation(sna, sna_crtc); 2743 2744 sna_crtc_find_planes(sna, sna_crtc); 2745 2746 DBG(("%s: CRTC:%d [pipe=%d], primary id=%x: supported-rotations=%x, current-rotation=%x, sprite id=%x: supported-rotations=%x, current-rotation=%x\n", 2747 __FUNCTION__, sna_crtc->id, sna_crtc->pipe, 2748 sna_crtc->primary.id, sna_crtc->primary.rotation.supported, sna_crtc->primary.rotation.current, 2749 sna_crtc->sprite.id, sna_crtc->sprite.rotation.supported, sna_crtc->sprite.rotation.current)); 2750 2751 list_init(&sna_crtc->shadow_link); 2752 2753 crtc = xf86CrtcCreate(scrn, &sna_crtc_funcs); 2754 if (crtc == NULL) { 2755 free(sna_crtc); 2756 return false; 2757 } 2758 2759 sna_crtc_init__cursor(sna, sna_crtc); 2760 2761 crtc->driver_private = sna_crtc; 2762 sna_crtc->base = crtc; 2763 DBG(("%s: attached crtc[%d] pipe=%d\n", 2764 __FUNCTION__, id, sna_crtc->pipe)); 2765 2766 return true; 2767} 2768 2769static bool 2770is_panel(int type) 2771{ 2772#define DRM_MODE_CONNECTOR_LVDS 7 2773#define DRM_MODE_CONNECTOR_eDP 14 2774#define DRM_MODE_CONNECTOR_DSI 16 2775 return (type == DRM_MODE_CONNECTOR_LVDS || 2776 type == DRM_MODE_CONNECTOR_eDP || 2777 type == DRM_MODE_CONNECTOR_DSI); 2778} 2779 2780static int 2781find_property(struct sna *sna, struct sna_output *output, const char *name) 2782{ 2783 struct drm_mode_get_property prop; 2784 int i; 2785 2786 VG_CLEAR(prop); 2787 for (i = 0; i < output->num_props; i++) { 2788 prop.prop_id = output->prop_ids[i]; 2789 prop.count_values = 0; 2790 prop.count_enum_blobs = 0; 2791 if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETPROPERTY, &prop)) 2792 continue; 2793 2794 if (strcmp(prop.name, name) == 0) 2795 return i; 2796 } 2797 2798 return -1; 2799} 2800 2801static xf86OutputStatus 2802sna_output_detect(xf86OutputPtr output) 2803{ 2804 struct sna *sna = to_sna(output->scrn); 2805 struct sna_output *sna_output = output->driver_private; 2806 union compat_mode_get_connector compat_conn; 2807 2808 DBG(("%s(%s:%d)\n", __FUNCTION__, output->name, sna_output->id)); 2809 2810 if (!sna_output->id) { 2811 DBG(("%s(%s) hiding due to lost connection\n", __FUNCTION__, output->name)); 2812 return XF86OutputStatusDisconnected; 2813 } 2814 2815 VG_CLEAR(compat_conn); 2816 compat_conn.conn.connector_id = sna_output->id; 2817 sna_output->num_modes = compat_conn.conn.count_modes = 0; /* reprobe */ 2818 compat_conn.conn.count_encoders = 0; 2819 compat_conn.conn.count_props = sna_output->num_props; 2820 compat_conn.conn.props_ptr = (uintptr_t)sna_output->prop_ids; 2821 compat_conn.conn.prop_values_ptr = (uintptr_t)sna_output->prop_values; 2822 2823 if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETCONNECTOR, &compat_conn.conn)) 2824 return XF86OutputStatusUnknown; 2825 DBG(("%s(%s): num modes %d -> %d, num props %d -> %d\n", 2826 __FUNCTION__, output->name, 2827 sna_output->num_modes, compat_conn.conn.count_modes, 2828 sna_output->num_props, compat_conn.conn.count_props)); 2829 2830 assert(compat_conn.conn.count_props == sna_output->num_props); 2831 2832 while (compat_conn.conn.count_modes && compat_conn.conn.count_modes != sna_output->num_modes) { 2833 struct drm_mode_modeinfo *new_modes; 2834 int old_count; 2835 2836 old_count = sna_output->num_modes; 2837 new_modes = realloc(sna_output->modes, 2838 sizeof(*sna_output->modes)*compat_conn.conn.count_modes); 2839 if (new_modes == NULL) 2840 break; 2841 2842 sna_output->modes = new_modes; 2843 sna_output->num_modes = compat_conn.conn.count_modes; 2844 compat_conn.conn.modes_ptr = (uintptr_t)sna_output->modes; 2845 compat_conn.conn.count_encoders = 0; 2846 compat_conn.conn.count_props = 0; 2847 if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETCONNECTOR, &compat_conn.conn)) { 2848 sna_output->num_modes = min(old_count, sna_output->num_modes); 2849 break; 2850 } 2851 VG(VALGRIND_MAKE_MEM_DEFINED(sna_output->modes, sizeof(*sna_output->modes)*sna_output->num_modes)); 2852 } 2853 2854 DBG(("%s(%s): found %d modes, connection status=%d\n", 2855 __FUNCTION__, output->name, sna_output->num_modes, compat_conn.conn.connection)); 2856 2857 switch (compat_conn.conn.connection) { 2858 case DRM_MODE_CONNECTED: 2859 return XF86OutputStatusConnected; 2860 case DRM_MODE_DISCONNECTED: 2861 return XF86OutputStatusDisconnected; 2862 default: 2863 case DRM_MODE_UNKNOWNCONNECTION: 2864 return XF86OutputStatusUnknown; 2865 } 2866} 2867 2868static Bool 2869sna_output_mode_valid(xf86OutputPtr output, DisplayModePtr mode) 2870{ 2871 struct sna_output *sna_output = output->driver_private; 2872 struct sna *sna = to_sna(output->scrn); 2873 2874 if (mode->HDisplay > sna->mode.max_crtc_width) 2875 return MODE_VIRTUAL_X; 2876 if (mode->VDisplay > sna->mode.max_crtc_height) 2877 return MODE_VIRTUAL_Y; 2878 2879 /* Check that we can successfully pin this into the global GTT */ 2880 if ((kgem_can_create_2d(&sna->kgem, 2881 mode->HDisplay, mode->VDisplay, 2882 sna->scrn->bitsPerPixel) & KGEM_CAN_CREATE_GTT) == 0) 2883 return MODE_MEM_VIRT; 2884 2885 /* 2886 * If the connector type is a panel, we will use the panel limit to 2887 * verfiy whether the mode is valid. 2888 */ 2889 if (sna_output->has_panel_limits) { 2890 if (mode->HDisplay > sna_output->panel_hdisplay || 2891 mode->VDisplay > sna_output->panel_vdisplay) 2892 return MODE_PANEL; 2893 } 2894 2895 return MODE_OK; 2896} 2897 2898static void 2899sna_output_attach_edid(xf86OutputPtr output) 2900{ 2901 struct sna *sna = to_sna(output->scrn); 2902 struct sna_output *sna_output = output->driver_private; 2903 struct drm_mode_get_blob blob; 2904 void *old, *raw = NULL; 2905 xf86MonPtr mon = NULL; 2906 2907 if (sna_output->edid_idx == -1) 2908 return; 2909 2910 raw = sna_output->edid_raw; 2911 blob.length = sna_output->edid_len; 2912 2913 if (blob.length && output->MonInfo) { 2914 old = alloca(blob.length); 2915 memcpy(old, raw, blob.length); 2916 } else 2917 old = NULL; 2918 2919 blob.blob_id = sna_output->prop_values[sna_output->edid_idx]; 2920 DBG(("%s: attaching EDID id=%d, current=%d\n", 2921 __FUNCTION__, blob.blob_id, sna_output->edid_blob_id)); 2922 if (blob.blob_id == sna_output->edid_blob_id && 0) { /* sigh */ 2923 if (output->MonInfo) { 2924 /* XXX the property keeps on disappearing... */ 2925 RRChangeOutputProperty(output->randr_output, 2926 MakeAtom("EDID", strlen("EDID"), TRUE), 2927 XA_INTEGER, 8, PropModeReplace, 2928 sna_output->edid_len, 2929 sna_output->edid_raw, 2930 FALSE, FALSE); 2931 2932 return; 2933 } 2934 2935 goto skip_read; 2936 } 2937 2938 blob.data = (uintptr_t)raw; 2939 if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETPROPBLOB, &blob)) 2940 goto done; 2941 2942 DBG(("%s: retrieving blob id=%d, length=%d\n", 2943 __FUNCTION__, blob.blob_id, blob.length)); 2944 2945 if (blob.length > sna_output->edid_len) { 2946 raw = realloc(raw, blob.length); 2947 if (raw == NULL) 2948 goto done; 2949 2950 VG(memset(raw, 0, blob.length)); 2951 blob.data = (uintptr_t)raw; 2952 if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETPROPBLOB, &blob)) 2953 goto done; 2954 } 2955 2956 if (old && 2957 blob.length == sna_output->edid_len && 2958 memcmp(old, raw, blob.length) == 0) { 2959 assert(sna_output->edid_raw == raw); 2960 sna_output->edid_blob_id = blob.blob_id; 2961 RRChangeOutputProperty(output->randr_output, 2962 MakeAtom("EDID", strlen("EDID"), TRUE), 2963 XA_INTEGER, 8, PropModeReplace, 2964 sna_output->edid_len, 2965 sna_output->edid_raw, 2966 FALSE, FALSE); 2967 return; 2968 } 2969 2970skip_read: 2971 if (raw) { 2972 mon = xf86InterpretEDID(output->scrn->scrnIndex, raw); 2973 if (mon && blob.length > 128) 2974 mon->flags |= MONITOR_EDID_COMPLETE_RAWDATA; 2975 } 2976 2977done: 2978 xf86OutputSetEDID(output, mon); 2979 if (raw) { 2980 sna_output->edid_raw = raw; 2981 sna_output->edid_len = blob.length; 2982 sna_output->edid_blob_id = blob.blob_id; 2983 } 2984} 2985 2986static DisplayModePtr 2987default_modes(void) 2988{ 2989#if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,6,99,900,0) 2990 return xf86GetDefaultModes(); 2991#else 2992 return xf86GetDefaultModes(0, 0); 2993#endif 2994} 2995 2996static DisplayModePtr 2997sna_output_panel_edid(xf86OutputPtr output, DisplayModePtr modes) 2998{ 2999 xf86MonPtr mon = output->MonInfo; 3000 DisplayModePtr i, m, preferred = NULL; 3001 int max_x = 0, max_y = 0; 3002 float max_vrefresh = 0.0; 3003 3004 if (mon && GTF_SUPPORTED(mon->features.msc)) 3005 return modes; 3006 3007 for (m = modes; m; m = m->next) { 3008 if (m->type & M_T_PREFERRED) 3009 preferred = m; 3010 max_x = max(max_x, m->HDisplay); 3011 max_y = max(max_y, m->VDisplay); 3012 max_vrefresh = max(max_vrefresh, xf86ModeVRefresh(m)); 3013 } 3014 3015 max_vrefresh = max(max_vrefresh, 60.0); 3016 max_vrefresh *= (1 + SYNC_TOLERANCE); 3017 3018 m = default_modes(); 3019 xf86ValidateModesSize(output->scrn, m, max_x, max_y, 0); 3020 3021 for (i = m; i; i = i->next) { 3022 if (xf86ModeVRefresh(i) > max_vrefresh) 3023 i->status = MODE_VSYNC; 3024 if (preferred && 3025 i->HDisplay >= preferred->HDisplay && 3026 i->VDisplay >= preferred->VDisplay && 3027 xf86ModeVRefresh(i) >= xf86ModeVRefresh(preferred)) 3028 i->status = MODE_PANEL; 3029 } 3030 3031 xf86PruneInvalidModes(output->scrn, &m, FALSE); 3032 3033 return xf86ModesAdd(modes, m); 3034} 3035 3036static DisplayModePtr 3037sna_output_get_modes(xf86OutputPtr output) 3038{ 3039 struct sna_output *sna_output = output->driver_private; 3040 DisplayModePtr Modes = NULL, current = NULL; 3041 int i; 3042 3043 DBG(("%s(%s:%d)\n", __FUNCTION__, output->name, sna_output->id)); 3044 assert(sna_output->id); 3045 3046 sna_output_attach_edid(output); 3047 3048 if (output->crtc) { 3049 struct drm_mode_crtc mode; 3050 3051 VG_CLEAR(mode); 3052 assert(to_sna_crtc(output->crtc)); 3053 mode.crtc_id = to_sna_crtc(output->crtc)->id; 3054 3055 if (drmIoctl(to_sna(output->scrn)->kgem.fd, DRM_IOCTL_MODE_GETCRTC, &mode) == 0) { 3056 DBG(("%s: CRTC:%d, pipe=%d: has mode?=%d\n", __FUNCTION__, 3057 to_sna_crtc(output->crtc)->id, 3058 to_sna_crtc(output->crtc)->pipe, 3059 mode.mode_valid && mode.mode.clock)); 3060 3061 if (mode.mode_valid && mode.mode.clock) { 3062 current = calloc(1, sizeof(DisplayModeRec)); 3063 if (current) { 3064 mode_from_kmode(output->scrn, &mode.mode, current); 3065 current->type |= M_T_DRIVER | M_T_PREFERRED; 3066 } 3067 } 3068 } 3069 } 3070 3071 DBG(("%s: adding %d probed modes\n", __FUNCTION__, sna_output->num_modes)); 3072 3073 for (i = 0; i < sna_output->num_modes; i++) { 3074 DisplayModePtr mode; 3075 3076 mode = calloc(1, sizeof(DisplayModeRec)); 3077 if (mode == NULL) 3078 continue; 3079 3080 mode = mode_from_kmode(output->scrn, 3081 &sna_output->modes[i], 3082 mode); 3083 Modes = xf86ModesAdd(Modes, mode); 3084 if (current && xf86ModesEqual(mode, current)) { 3085 free((void*)current->name); 3086 free(current); 3087 current = NULL; 3088 } 3089 if (current && mode->type & M_T_PREFERRED) 3090 current->type &= ~M_T_PREFERRED; 3091 } 3092 3093 if (current) 3094 Modes = xf86ModesAdd(current, Modes); 3095 3096 /* 3097 * If the connector type is a panel, we will traverse the kernel mode to 3098 * get the panel limit. And then add all the standard modes to fake 3099 * the fullscreen experience. 3100 * If it is incorrect, please fix me. 3101 */ 3102 sna_output->has_panel_limits = false; 3103 if (sna_output->is_panel) { 3104 sna_output->panel_hdisplay = sna_output->panel_vdisplay = 0; 3105 for (i = 0; i < sna_output->num_modes; i++) { 3106 struct drm_mode_modeinfo *m; 3107 3108 m = &sna_output->modes[i]; 3109 if (m->hdisplay > sna_output->panel_hdisplay) 3110 sna_output->panel_hdisplay = m->hdisplay; 3111 if (m->vdisplay > sna_output->panel_vdisplay) 3112 sna_output->panel_vdisplay = m->vdisplay; 3113 } 3114 sna_output->has_panel_limits = 3115 sna_output->panel_hdisplay && 3116 sna_output->panel_vdisplay; 3117 } 3118 3119 if (sna_output->add_default_modes) 3120 Modes = sna_output_panel_edid(output, Modes); 3121 3122 return Modes; 3123} 3124 3125static void 3126sna_output_destroy(xf86OutputPtr output) 3127{ 3128 struct sna_output *sna_output = output->driver_private; 3129 int i; 3130 3131 if (sna_output == NULL) 3132 return; 3133 3134 free(sna_output->edid_raw); 3135 for (i = 0; i < sna_output->num_props; i++) { 3136 if (sna_output->props[i].kprop == NULL) 3137 continue; 3138 3139 if (sna_output->props[i].atoms) { 3140 if (output->randr_output) 3141 RRDeleteOutputProperty(output->randr_output, sna_output->props[i].atoms[0]); 3142 free(sna_output->props[i].atoms); 3143 } 3144 3145 drmModeFreeProperty(sna_output->props[i].kprop); 3146 } 3147 free(sna_output->props); 3148 free(sna_output->prop_ids); 3149 free(sna_output->prop_values); 3150 3151 backlight_close(&sna_output->backlight); 3152 3153 free(sna_output); 3154 output->driver_private = NULL; 3155} 3156 3157static void 3158sna_output_dpms(xf86OutputPtr output, int dpms) 3159{ 3160 struct sna *sna = to_sna(output->scrn); 3161 struct sna_output *sna_output = output->driver_private; 3162 int old_dpms = sna_output->dpms_mode; 3163 3164 DBG(("%s(%s:%d): dpms=%d (current: %d), active? %d\n", 3165 __FUNCTION__, output->name, sna_output->id, 3166 dpms, sna_output->dpms_mode, 3167 output->crtc != NULL)); 3168 3169 if (!sna_output->id) 3170 return; 3171 3172 if (old_dpms == dpms) 3173 return; 3174 3175 /* Record the value of the backlight before turning 3176 * off the display, and reset if after turning it on. 3177 * Order is important as the kernel may record and also 3178 * reset the backlight across DPMS. Hence we need to 3179 * record the value before the kernel modifies it 3180 * and reapply it afterwards. 3181 */ 3182 if (sna_output->backlight.iface && dpms != DPMSModeOn) { 3183 if (old_dpms == DPMSModeOn) { 3184 sna_output->backlight_active_level = sna_output_backlight_get(output); 3185 DBG(("%s: saving current backlight %d\n", 3186 __FUNCTION__, sna_output->backlight_active_level)); 3187 } 3188 sna_output->dpms_mode = dpms; 3189 sna_output_backlight_off(sna_output); 3190 } 3191 3192 if (output->crtc && 3193 drmModeConnectorSetProperty(sna->kgem.fd, 3194 sna_output->id, 3195 sna_output->dpms_id, 3196 dpms)) 3197 dpms = old_dpms; 3198 3199 if (sna_output->backlight.iface && dpms == DPMSModeOn) { 3200 DBG(("%s: restoring previous backlight %d\n", 3201 __FUNCTION__, sna_output->backlight_active_level)); 3202 sna_output_backlight_on(sna_output); 3203 } 3204 3205 sna_output->dpms_mode = dpms; 3206} 3207 3208static bool 3209sna_property_ignore(drmModePropertyPtr prop) 3210{ 3211 if (!prop) 3212 return true; 3213 3214 /* ignore blob prop */ 3215 if (prop->flags & DRM_MODE_PROP_BLOB) 3216 return true; 3217 3218 /* ignore standard property */ 3219 if (!strcmp(prop->name, "EDID") || 3220 !strcmp(prop->name, "DPMS")) 3221 return true; 3222 3223 return false; 3224} 3225 3226static void 3227sna_output_create_ranged_atom(xf86OutputPtr output, Atom *atom, 3228 const char *name, INT32 min, INT32 max, 3229 uint64_t value, Bool immutable) 3230{ 3231 int err; 3232 INT32 atom_range[2]; 3233 3234 atom_range[0] = min; 3235 atom_range[1] = max; 3236 3237 *atom = MakeAtom(name, strlen(name), TRUE); 3238 3239 err = RRConfigureOutputProperty(output->randr_output, *atom, FALSE, 3240 TRUE, immutable, 2, atom_range); 3241 if (err != 0) 3242 xf86DrvMsg(output->scrn->scrnIndex, X_ERROR, 3243 "RRConfigureOutputProperty error, %d\n", err); 3244 3245 err = RRChangeOutputProperty(output->randr_output, *atom, XA_INTEGER, 3246 32, PropModeReplace, 1, &value, 3247 FALSE, FALSE); 3248 if (err != 0) 3249 xf86DrvMsg(output->scrn->scrnIndex, X_ERROR, 3250 "RRChangeOutputProperty error, %d\n", err); 3251} 3252 3253static void 3254sna_output_create_resources(xf86OutputPtr output) 3255{ 3256 struct sna *sna = to_sna(output->scrn); 3257 struct sna_output *sna_output = output->driver_private; 3258 int i, j, err; 3259 3260 sna_output->props = calloc(sna_output->num_props, 3261 sizeof(struct sna_property)); 3262 if (!sna_output->props) 3263 return; 3264 3265 for (i = 0; i < sna_output->num_props; i++) { 3266 struct sna_property *p = &sna_output->props[i]; 3267 3268 p->kprop = drmModeGetProperty(sna->kgem.fd, 3269 sna_output->prop_ids[i]); 3270 if (sna_property_ignore(p->kprop)) { 3271 drmModeFreeProperty(p->kprop); 3272 p->kprop = NULL; 3273 continue; 3274 } 3275 3276 if (p->kprop->flags & DRM_MODE_PROP_RANGE) { 3277 p->num_atoms = 1; 3278 p->atoms = calloc(p->num_atoms, sizeof(Atom)); 3279 if (!p->atoms) 3280 continue; 3281 3282 sna_output_create_ranged_atom(output, &p->atoms[0], 3283 p->kprop->name, 3284 p->kprop->values[0], 3285 p->kprop->values[1], 3286 sna_output->prop_values[i], 3287 p->kprop->flags & DRM_MODE_PROP_IMMUTABLE ? TRUE : FALSE); 3288 3289 } else if (p->kprop->flags & DRM_MODE_PROP_ENUM) { 3290 p->num_atoms = p->kprop->count_enums + 1; 3291 p->atoms = calloc(p->num_atoms, sizeof(Atom)); 3292 if (!p->atoms) 3293 continue; 3294 3295 p->atoms[0] = MakeAtom(p->kprop->name, strlen(p->kprop->name), TRUE); 3296 for (j = 1; j <= p->kprop->count_enums; j++) { 3297 struct drm_mode_property_enum *e = &p->kprop->enums[j-1]; 3298 p->atoms[j] = MakeAtom(e->name, strlen(e->name), TRUE); 3299 } 3300 3301 err = RRConfigureOutputProperty(output->randr_output, p->atoms[0], 3302 FALSE, FALSE, 3303 p->kprop->flags & DRM_MODE_PROP_IMMUTABLE ? TRUE : FALSE, 3304 p->num_atoms - 1, (INT32 *)&p->atoms[1]); 3305 if (err != 0) { 3306 xf86DrvMsg(output->scrn->scrnIndex, X_ERROR, 3307 "RRConfigureOutputProperty error, %d\n", err); 3308 } 3309 3310 for (j = 0; j < p->kprop->count_enums; j++) 3311 if (p->kprop->enums[j].value == sna_output->prop_values[i]) 3312 break; 3313 /* there's always a matching value */ 3314 err = RRChangeOutputProperty(output->randr_output, p->atoms[0], 3315 XA_ATOM, 32, PropModeReplace, 1, &p->atoms[j+1], 3316 FALSE, FALSE); 3317 if (err != 0) { 3318 xf86DrvMsg(output->scrn->scrnIndex, X_ERROR, 3319 "RRChangeOutputProperty error, %d\n", err); 3320 } 3321 } 3322 } 3323 3324 if (sna_output->backlight.iface) { 3325 /* Set up the backlight property, which takes effect 3326 * immediately and accepts values only within the 3327 * backlight_range. 3328 */ 3329 sna_output_create_ranged_atom(output, &backlight_atom, 3330 BACKLIGHT_NAME, 0, 3331 sna_output->backlight.max, 3332 sna_output->backlight_active_level, 3333 FALSE); 3334 sna_output_create_ranged_atom(output, 3335 &backlight_deprecated_atom, 3336 BACKLIGHT_DEPRECATED_NAME, 0, 3337 sna_output->backlight.max, 3338 sna_output->backlight_active_level, 3339 FALSE); 3340 } 3341} 3342 3343static Bool 3344sna_output_set_property(xf86OutputPtr output, Atom property, 3345 RRPropertyValuePtr value) 3346{ 3347 struct sna *sna = to_sna(output->scrn); 3348 struct sna_output *sna_output = output->driver_private; 3349 int i; 3350 3351 if (property == backlight_atom || property == backlight_deprecated_atom) { 3352 INT32 val; 3353 int ret = 0; 3354 3355 if (value->type != XA_INTEGER || value->format != 32 || 3356 value->size != 1) 3357 { 3358 return FALSE; 3359 } 3360 3361 val = *(INT32 *)value->data; 3362 DBG(("%s: setting backlight to %d (max=%d)\n", 3363 __FUNCTION__, (int)val, sna_output->backlight.max)); 3364 if (val < 0 || val > sna_output->backlight.max) 3365 return FALSE; 3366 3367 sna_output->backlight_active_level = val; 3368 if (sna_output->dpms_mode == DPMSModeOn) 3369 ret = sna_output_backlight_set(sna_output, val); 3370 return ret == 0; 3371 } 3372 3373 if (!sna_output->id) 3374 return TRUE; 3375 3376 for (i = 0; i < sna_output->num_props; i++) { 3377 struct sna_property *p = &sna_output->props[i]; 3378 3379 if (p->atoms == NULL || p->atoms[0] != property) 3380 continue; 3381 3382 if (p->kprop->flags & DRM_MODE_PROP_RANGE) { 3383 uint32_t val; 3384 3385 if (value->type != XA_INTEGER || value->format != 32 || 3386 value->size != 1) 3387 return FALSE; 3388 val = *(uint32_t *)value->data; 3389 3390 drmModeConnectorSetProperty(sna->kgem.fd, sna_output->id, 3391 p->kprop->prop_id, (uint64_t)val); 3392 return TRUE; 3393 } else if (p->kprop->flags & DRM_MODE_PROP_ENUM) { 3394 Atom atom; 3395 const char *name; 3396 int j; 3397 3398 if (value->type != XA_ATOM || value->format != 32 || value->size != 1) 3399 return FALSE; 3400 memcpy(&atom, value->data, 4); 3401 name = NameForAtom(atom); 3402 if (name == NULL) 3403 return FALSE; 3404 3405 /* search for matching name string, then set its value down */ 3406 for (j = 0; j < p->kprop->count_enums; j++) { 3407 if (!strcmp(p->kprop->enums[j].name, name)) { 3408 drmModeConnectorSetProperty(sna->kgem.fd, sna_output->id, 3409 p->kprop->prop_id, p->kprop->enums[j].value); 3410 return TRUE; 3411 } 3412 } 3413 return FALSE; 3414 } 3415 } 3416 3417 /* We didn't recognise this property, just report success in order 3418 * to allow the set to continue, otherwise we break setting of 3419 * common properties like EDID. 3420 */ 3421 return TRUE; 3422} 3423 3424static Bool 3425sna_output_get_property(xf86OutputPtr output, Atom property) 3426{ 3427 struct sna_output *sna_output = output->driver_private; 3428 int err; 3429 3430 if (property == backlight_atom || property == backlight_deprecated_atom) { 3431 INT32 val; 3432 3433 if (!sna_output->backlight.iface) 3434 return FALSE; 3435 3436 if (sna_output->dpms_mode == DPMSModeOn) { 3437 val = sna_output_backlight_get(output); 3438 if (val < 0) 3439 return FALSE; 3440 DBG(("%s(%s): output on, reporting actual backlight value [%d]\n", 3441 __FUNCTION__, output->name, val)); 3442 } else { 3443 val = sna_output->backlight_active_level; 3444 DBG(("%s(%s): output off, reporting cached backlight value [%d]\n", 3445 __FUNCTION__, output->name, val)); 3446 } 3447 3448 err = RRChangeOutputProperty(output->randr_output, property, 3449 XA_INTEGER, 32, PropModeReplace, 1, &val, 3450 FALSE, FALSE); 3451 if (err != 0) { 3452 xf86DrvMsg(output->scrn->scrnIndex, X_ERROR, 3453 "RRChangeOutputProperty error, %d\n", err); 3454 return FALSE; 3455 } 3456 3457 return TRUE; 3458 } 3459 3460 return FALSE; 3461} 3462 3463static const xf86OutputFuncsRec sna_output_funcs = { 3464 .create_resources = sna_output_create_resources, 3465#ifdef RANDR_12_INTERFACE 3466 .set_property = sna_output_set_property, 3467 .get_property = sna_output_get_property, 3468#endif 3469 .dpms = sna_output_dpms, 3470 .detect = sna_output_detect, 3471 .mode_valid = sna_output_mode_valid, 3472 3473 .get_modes = sna_output_get_modes, 3474 .destroy = sna_output_destroy 3475}; 3476 3477static const int subpixel_conv_table[] = { 3478 SubPixelUnknown, 3479 SubPixelHorizontalRGB, 3480 SubPixelHorizontalBGR, 3481 SubPixelVerticalRGB, 3482 SubPixelVerticalBGR, 3483 SubPixelNone 3484}; 3485 3486static const char * const output_names[] = { 3487 /* DRM_MODE_CONNECTOR_Unknown */ "None", 3488 /* DRM_MODE_CONNECTOR_VGA */ "VGA", 3489 /* DRM_MODE_CONNECTOR_DVII */ "DVI", 3490 /* DRM_MODE_CONNECTOR_DVID */ "DVI", 3491 /* DRM_MODE_CONNECTOR_DVIA */ "DVI", 3492 /* DRM_MODE_CONNECTOR_Composite */ "Composite", 3493 /* DRM_MODE_CONNECTOR_SVIDEO */ "TV", 3494 /* DRM_MODE_CONNECTOR_LVDS */ "LVDS", 3495 /* DRM_MODE_CONNECTOR_Component */ "CTV", 3496 /* DRM_MODE_CONNECTOR_9PinDIN */ "DIN", 3497 /* DRM_MODE_CONNECTOR_DisplayPort */ "DP", 3498 /* DRM_MODE_CONNECTOR_HDMIA */ "HDMI", 3499 /* DRM_MODE_CONNECTOR_HDMIB */ "HDMI", 3500 /* DRM_MODE_CONNECTOR_TV */ "TV", 3501 /* DRM_MODE_CONNECTOR_eDP */ "eDP", 3502 /* DRM_MODE_CONNECTOR_VIRTUAL */ "Virtual", 3503 /* DRM_MODE_CONNECTOR_DSI */ "DSI" 3504}; 3505 3506static bool 3507sna_zaphod_match(const char *s, const char *output) 3508{ 3509 char t[20]; 3510 unsigned int i = 0; 3511 3512 do { 3513 /* match any outputs in a comma list, stopping at whitespace */ 3514 switch (*s) { 3515 case '\0': 3516 t[i] = '\0'; 3517 return strcmp(t, output) == 0; 3518 3519 case ',': 3520 t[i] ='\0'; 3521 if (strcmp(t, output) == 0) 3522 return TRUE; 3523 i = 0; 3524 break; 3525 3526 case ' ': 3527 case '\t': 3528 case '\n': 3529 case '\r': 3530 break; 3531 3532 default: 3533 t[i++] = *s; 3534 break; 3535 } 3536 3537 s++; 3538 } while (i < sizeof(t)); 3539 3540 return false; 3541} 3542 3543static bool 3544output_ignored(ScrnInfoPtr scrn, const char *name) 3545{ 3546 char monitor_name[64]; 3547 const char *monitor; 3548 XF86ConfMonitorPtr conf; 3549 3550 snprintf(monitor_name, sizeof(monitor_name), "monitor-%s", name); 3551 monitor = xf86findOptionValue(scrn->options, monitor_name); 3552 if (!monitor) 3553 monitor = name; 3554 3555 conf = xf86findMonitor(monitor, 3556 xf86configptr->conf_monitor_lst); 3557 if (conf == NULL && XF86_CRTC_CONFIG_PTR(scrn)->num_output == 0) 3558 conf = xf86findMonitor(scrn->monitor->id, 3559 xf86configptr->conf_monitor_lst); 3560 if (conf == NULL) 3561 return false; 3562 3563 return xf86CheckBoolOption(conf->mon_option_lst, "Ignore", 0); 3564} 3565 3566static bool 3567gather_encoders(struct sna *sna, uint32_t id, int count, 3568 struct drm_mode_get_encoder *out) 3569{ 3570 union compat_mode_get_connector compat_conn; 3571 struct drm_mode_modeinfo dummy; 3572 struct drm_mode_get_encoder enc; 3573 uint32_t *ids = NULL; 3574 3575 VG_CLEAR(compat_conn); 3576 memset(out, 0, sizeof(*out)); 3577 3578 do { 3579 free(ids); 3580 ids = malloc(sizeof(*ids) * count); 3581 if (ids == 0) 3582 return false; 3583 3584 compat_conn.conn.connector_id = id; 3585 compat_conn.conn.count_props = 0; 3586 compat_conn.conn.count_modes = 1; /* skip detect */ 3587 compat_conn.conn.modes_ptr = (uintptr_t)&dummy; 3588 compat_conn.conn.count_encoders = count; 3589 compat_conn.conn.encoders_ptr = (uintptr_t)ids; 3590 3591 if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETCONNECTOR, &compat_conn.conn)) { 3592 DBG(("%s: GETCONNECTOR[%d] failed, ret=%d\n", __FUNCTION__, id, errno)); 3593 compat_conn.conn.count_encoders = count = 0; 3594 } 3595 3596 if (count == compat_conn.conn.count_encoders) 3597 break; 3598 3599 count = compat_conn.conn.count_encoders; 3600 } while (1); 3601 3602 for (count = 0; count < compat_conn.conn.count_encoders; count++) { 3603 enc.encoder_id = ids[count]; 3604 if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETENCODER, &enc)) { 3605 DBG(("%s: GETENCODER[%d] failed, ret=%d\n", __FUNCTION__, ids[count], errno)); 3606 count = 0; 3607 break; 3608 } 3609 out->possible_crtcs |= enc.possible_crtcs; 3610 out->possible_clones |= enc.possible_clones; 3611 3612 for (id = 0; id < sna->mode.num_real_encoder; id++) { 3613 if (enc.encoder_id == sna->mode.encoders[id]) { 3614 out->crtc_id |= 1 << id; 3615 break; 3616 } 3617 } 3618 } 3619 3620 free(ids); 3621 return count > 0; 3622} 3623 3624/* We need to map from kms encoder based possible_clones mask to X output based 3625 * possible clones masking. Note that for SDVO and on Haswell with DP/HDMI we 3626 * can have more than one output hanging off the same encoder. 3627 */ 3628static void 3629sna_mode_compute_possible_outputs(struct sna *sna) 3630{ 3631 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn); 3632 int encoder_mask[32]; 3633 int i, j; 3634 3635 assert(sna->mode.num_real_output < 32); 3636 assert(sna->mode.num_real_crtc < 32); 3637 3638 for (i = 0; i < sna->mode.num_real_output; i++) { 3639 xf86OutputPtr output = config->output[i]; 3640 struct sna_output *sna_output = to_sna_output(output); 3641 3642 assert(sna_output); 3643 3644 if (sna_output->id) { 3645 output->possible_clones = sna_output->possible_encoders; 3646 encoder_mask[i] = sna_output->attached_encoders; 3647 } else { 3648 output->possible_clones = 0; 3649 encoder_mask[i] = 0; 3650 } 3651 } 3652 3653 /* Convert from encoder numbering to output numbering */ 3654 for (i = 0; i < sna->mode.num_real_output; i++) { 3655 xf86OutputPtr output = config->output[i]; 3656 unsigned clones; 3657 3658 if (output->possible_clones == 0) 3659 continue; 3660 3661 clones = 0; 3662 for (j = 0; j < sna->mode.num_real_output; j++) 3663 if (i != j && output->possible_clones & encoder_mask[j]) 3664 clones |= 1 << j; 3665 output->possible_clones = clones; 3666 3667 DBG(("%s: updated output '%s' %d [%d] (possible crtc:%x, possible clones:%x)\n", 3668 __FUNCTION__, output->name, i, to_connector_id(output), 3669 (uint32_t)output->possible_crtcs, 3670 (uint32_t)output->possible_clones)); 3671 } 3672} 3673 3674static int name_from_path(struct sna *sna, 3675 struct sna_output *sna_output, 3676 char *name) 3677{ 3678 struct drm_mode_get_blob blob; 3679 char *path; 3680 int id; 3681 3682 id = find_property(sna, sna_output, "PATH"); 3683 DBG(("%s: found? PATH=%d\n", __FUNCTION__, id)); 3684 if (id == -1) 3685 return 0; 3686 3687 VG_CLEAR(blob); 3688 blob.blob_id = sna_output->prop_values[id]; 3689 blob.length = 0; 3690 if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETPROPBLOB, &blob)) 3691 return 0; 3692 3693 do { 3694 id = blob.length; 3695 path = alloca(id + 1); 3696 blob.data = (uintptr_t)path; 3697 VG(memset(path, 0, id)); 3698 DBG(("%s: reading %d bytes for path blob\n", __FUNCTION__, id)); 3699 if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETPROPBLOB, &blob)) 3700 return 0; 3701 } while (id != blob.length); 3702 3703 path[blob.length] = '\0'; /* paranoia */ 3704 DBG(("%s: PATH='%s'\n", __FUNCTION__, path)); 3705 3706 /* we only handle MST paths for now */ 3707 if (strncmp(path, "mst:", 4) == 0) { 3708 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn); 3709 char tmp[5], *c; 3710 int n; 3711 3712 c = strchr(path + 4, '-'); 3713 if (c == NULL) 3714 return 0; 3715 3716 id = c - (path + 4); 3717 if (id + 1> 5) 3718 return 0; 3719 3720 memcpy(tmp, path + 4, id); 3721 tmp[id] = '\0'; 3722 id = strtoul(tmp, NULL, 0); 3723 3724 for (n = 0; n < sna->mode.num_real_output; n++) { 3725 if (to_sna_output(config->output[n])->id == id) 3726 return snprintf(name, 32, "%s-%s", 3727 config->output[n]->name, c + 1); 3728 } 3729 } 3730 3731 return 0; 3732} 3733 3734static int 3735sna_output_add(struct sna *sna, unsigned id, unsigned serial) 3736{ 3737 ScrnInfoPtr scrn = sna->scrn; 3738 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn); 3739 union compat_mode_get_connector compat_conn; 3740 struct drm_mode_get_encoder enc; 3741 struct drm_mode_modeinfo dummy; 3742 struct sna_output *sna_output; 3743 xf86OutputPtr *outputs, output; 3744 unsigned possible_encoders, attached_encoders, possible_crtcs; 3745 const char *output_name; 3746 char name[32]; 3747 int path, len, i; 3748 3749 DBG(("%s(%d): serial=%d\n", __FUNCTION__, id, serial)); 3750 3751 COMPILE_TIME_ASSERT(sizeof(struct drm_mode_get_connector) <= sizeof(compat_conn.pad)); 3752 3753 VG_CLEAR(compat_conn); 3754 memset(&enc, 0, sizeof(enc)); 3755 3756 compat_conn.conn.connector_id = id; 3757 compat_conn.conn.count_props = 0; 3758 compat_conn.conn.count_modes = 1; /* skip detect */ 3759 compat_conn.conn.modes_ptr = (uintptr_t)&dummy; 3760 compat_conn.conn.count_encoders = 1; 3761 compat_conn.conn.encoders_ptr = (uintptr_t)&enc.encoder_id; 3762 3763 if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETCONNECTOR, &compat_conn.conn)) { 3764 DBG(("%s: GETCONNECTOR[%d] failed, ret=%d\n", __FUNCTION__, id, errno)); 3765 return -1; 3766 } 3767 assert(compat_conn.conn.connector_id == id); 3768 3769 if (compat_conn.conn.connector_type < ARRAY_SIZE(output_names)) 3770 output_name = output_names[compat_conn.conn.connector_type]; 3771 else 3772 output_name = "UNKNOWN"; 3773 len = snprintf(name, 32, "%s%d", output_name, compat_conn.conn.connector_type_id); 3774 if (output_ignored(scrn, name)) 3775 return 0; 3776 3777 if (enc.encoder_id) { 3778 if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETENCODER, &enc)) { 3779 DBG(("%s: GETENCODER[%d] failed, ret=%d\n", __FUNCTION__, enc.encoder_id, errno)); 3780 return 0; 3781 } 3782 3783 possible_encoders = enc.possible_clones; 3784 attached_encoders = 0; 3785 for (i = 0; i < sna->mode.num_real_encoder; i++) { 3786 if (enc.encoder_id == sna->mode.encoders[i]) { 3787 attached_encoders = 1 << i; 3788 break; 3789 } 3790 } 3791 3792 if (attached_encoders == 0) { 3793 DBG(("%s: failed to find attached encoder\n", __FUNCTION__)); 3794 return 0; 3795 } 3796 3797 possible_crtcs = enc.possible_crtcs; 3798 assert(enc.encoder_id == compat_conn.conn.encoder_id || compat_conn.conn.encoder_id == 0); 3799 } else { 3800 DBG(("%s: unexpected number [%d] of encoders attached\n", 3801 __FUNCTION__, compat_conn.conn.count_encoders)); 3802 if (!gather_encoders(sna, id, compat_conn.conn.count_encoders, &enc)) { 3803 DBG(("%s: gather encoders failed\n", __FUNCTION__)); 3804 return 0; 3805 } 3806 possible_encoders = enc.possible_clones; 3807 attached_encoders = enc.crtc_id; 3808 possible_crtcs = enc.possible_crtcs; 3809 3810 memset(&enc, 0, sizeof(enc)); 3811 enc.encoder_id = compat_conn.conn.encoder_id; 3812 (void)drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETENCODER, &enc); 3813 } 3814 3815 if (is_zaphod(scrn)) { 3816 const char *str; 3817 3818 str = xf86GetOptValString(sna->Options, OPTION_ZAPHOD); 3819 if (str && !sna_zaphod_match(str, name)) { 3820 DBG(("%s: zaphod mismatch, want %s, have %s\n", __FUNCTION__, str, name)); 3821 return 0; 3822 } 3823 3824 if ((possible_crtcs & (1 << scrn->confScreen->device->screen)) == 0) { 3825 if (str) { 3826 xf86DrvMsg(scrn->scrnIndex, X_ERROR, 3827 "%s is an invalid output for screen (pipe) %d\n", 3828 name, scrn->confScreen->device->screen); 3829 return -1; 3830 } else 3831 return 0; 3832 } 3833 3834 possible_crtcs = 1; 3835 } 3836 3837 sna_output = calloc(sizeof(struct sna_output), 1); 3838 if (!sna_output) 3839 return -1; 3840 3841 sna_output->num_props = compat_conn.conn.count_props; 3842 sna_output->prop_ids = malloc(sizeof(uint32_t)*compat_conn.conn.count_props); 3843 sna_output->prop_values = malloc(sizeof(uint64_t)*compat_conn.conn.count_props); 3844 3845 compat_conn.conn.count_encoders = 0; 3846 3847 compat_conn.conn.count_modes = 1; 3848 compat_conn.conn.modes_ptr = (uintptr_t)&dummy; 3849 3850 compat_conn.conn.count_props = sna_output->num_props; 3851 compat_conn.conn.props_ptr = (uintptr_t)sna_output->prop_ids; 3852 compat_conn.conn.prop_values_ptr = (uintptr_t)sna_output->prop_values; 3853 3854 if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETCONNECTOR, &compat_conn.conn)) { 3855 DBG(("%s: second! GETCONNECTOR failed, ret=%d\n", __FUNCTION__, errno)); 3856 goto cleanup; 3857 } 3858 assert(compat_conn.conn.connector_id == id); 3859 3860 /* statically constructed property list */ 3861 assert(sna_output->num_props == compat_conn.conn.count_props); 3862 VG(VALGRIND_MAKE_MEM_DEFINED(sna_output->prop_ids, sizeof(uint32_t)*sna_output->num_props)); 3863 VG(VALGRIND_MAKE_MEM_DEFINED(sna_output->prop_values, sizeof(uint64_t)*sna_output->num_props)); 3864 3865 /* Construct name from topology, and recheck if output is acceptable */ 3866 path = name_from_path(sna, sna_output, name); 3867 if (path) { 3868 const char *str; 3869 3870 if (output_ignored(scrn, name)) { 3871 len = 0; 3872 goto skip; 3873 } 3874 3875 str = xf86GetOptValString(sna->Options, OPTION_ZAPHOD); 3876 if (str && !sna_zaphod_match(str, name)) { 3877 DBG(("%s: zaphod mismatch, want %s, have %s\n", __FUNCTION__, str, name)); 3878 len = 0; 3879 goto skip; 3880 } 3881 3882 len = path; 3883 } 3884 3885 /* Check if we are dynamically reattaching an old connector */ 3886 if (serial) { 3887 for (i = 0; i < sna->mode.num_real_output; i++) { 3888 output = config->output[i]; 3889 if (strcmp(output->name, name) == 0) { 3890 assert(output->scrn == scrn); 3891 assert(output->funcs == &sna_output_funcs); 3892 assert(to_sna_output(output)->id == 0); 3893 sna_output_destroy(output); 3894 goto reset; 3895 } 3896 } 3897 } 3898 3899 output = calloc(1, sizeof(*output) + len + 1); 3900 if (!output) 3901 goto cleanup; 3902 3903 outputs = realloc(config->output, (config->num_output + 1) * sizeof(output)); 3904 if (outputs == NULL) { 3905 free(output); 3906 goto cleanup; 3907 } 3908 3909 output->scrn = scrn; 3910 output->funcs = &sna_output_funcs; 3911 output->name = (char *)(output + 1); 3912 memcpy(output->name, name, len + 1); 3913 3914 output->use_screen_monitor = config->num_output != 0; 3915 xf86OutputUseScreenMonitor(output, !output->use_screen_monitor); 3916 assert(output->options); 3917 3918 DBG(("%s: inserting output #%d of %d\n", __FUNCTION__, sna->mode.num_real_output, config->num_output)); 3919 for (i = config->num_output; i > sna->mode.num_real_output; i--) { 3920 outputs[i] = outputs[i-1]; 3921 assert(outputs[i]->driver_private == NULL); 3922 outputs[i]->possible_clones <<= 1; 3923 } 3924 3925 if (xf86ReturnOptValBool(output->options, OPTION_PRIMARY, FALSE)) { 3926 memmove(outputs + 1, outputs, sizeof(output)*config->num_output); 3927 outputs[0] = output; 3928 } else 3929 outputs[i] = output; 3930 sna->mode.num_real_output++; 3931 config->num_output++; 3932 config->output = outputs; 3933 3934reset: 3935 sna_output->id = compat_conn.conn.connector_id; 3936 sna_output->is_panel = is_panel(compat_conn.conn.connector_type); 3937 sna_output->edid_idx = find_property(sna, sna_output, "EDID"); 3938 if (find_property(sna, sna_output, "scaling mode") != -1) 3939 sna_output->add_default_modes = 3940 xf86ReturnOptValBool(output->options, OPTION_DEFAULT_MODES, TRUE); 3941 3942 i = find_property(sna, sna_output, "DPMS"); 3943 if (i != -1) { 3944 sna_output->dpms_id = sna_output->prop_ids[i]; 3945 sna_output->dpms_mode = sna_output->prop_values[i]; 3946 DBG(("%s: found 'DPMS' (idx=%d, id=%d), initial value=%d\n", 3947 __FUNCTION__, i, sna_output->dpms_id, sna_output->dpms_mode)); 3948 } else { 3949 sna_output->dpms_id = -1; 3950 sna_output->dpms_mode = DPMSModeOff; 3951 } 3952 3953 sna_output->possible_encoders = possible_encoders; 3954 sna_output->attached_encoders = attached_encoders; 3955 3956 output->mm_width = compat_conn.conn.mm_width; 3957 output->mm_height = compat_conn.conn.mm_height; 3958 3959 if (compat_conn.conn.subpixel >= ARRAY_SIZE(subpixel_conv_table)) 3960 compat_conn.conn.subpixel = 0; 3961 output->subpixel_order = subpixel_conv_table[compat_conn.conn.subpixel]; 3962 output->driver_private = sna_output; 3963 sna_output->base = output; 3964 3965 backlight_init(&sna_output->backlight); 3966 if (sna_output->is_panel) 3967 sna_output_backlight_init(output); 3968 3969 output->possible_crtcs = possible_crtcs & count_to_mask(sna->mode.num_real_crtc); 3970 output->interlaceAllowed = TRUE; 3971 3972 if (serial) { 3973 if (output->randr_output == NULL) { 3974 output->randr_output = RROutputCreate(xf86ScrnToScreen(scrn), name, len, output); 3975 if (output->randr_output == NULL) 3976 goto cleanup; 3977 } 3978 3979 sna_output_create_resources(output); 3980 RRPostPendingProperties(output->randr_output); 3981 3982 sna_output->serial = serial; 3983 } else { 3984 /* stash the active CRTC id for our probe function */ 3985 if (compat_conn.conn.connection != DRM_MODE_DISCONNECTED) 3986 output->crtc = (void *)(uintptr_t)enc.crtc_id; 3987 } 3988 3989 DBG(("%s: created output '%s' %d, encoder=%d (possible crtc:%x, attached encoders:%x, possible clones:%x), serial=%d, edid=%d, dpms=%d, crtc=%lu\n", 3990 __FUNCTION__, name, id, enc.encoder_id, 3991 (uint32_t)output->possible_crtcs, 3992 sna_output->attached_encoders, 3993 sna_output->possible_encoders, 3994 serial, sna_output->edid_idx, sna_output->dpms_id, 3995 (unsigned long)(uintptr_t)output->crtc)); 3996 assert(sna_output->id == id); 3997 3998 xf86DrvMsg(scrn->scrnIndex, X_INFO, 3999 "Enabled output %s\n", 4000 output->name); 4001 return 1; 4002 4003cleanup: 4004 len = -1; 4005skip: 4006 free(sna_output->prop_ids); 4007 free(sna_output->prop_values); 4008 free(sna_output); 4009 return len; 4010} 4011 4012static void sna_output_del(xf86OutputPtr output) 4013{ 4014 ScrnInfoPtr scrn = output->scrn; 4015 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn); 4016 int i; 4017 4018 DBG(("%s(%s)\n", __FUNCTION__, output->name)); 4019 assert(to_sna_output(output)); 4020 4021 RROutputDestroy(output->randr_output); 4022 sna_output_destroy(output); 4023 4024 while (output->probed_modes) 4025 xf86DeleteMode(&output->probed_modes, output->probed_modes); 4026 4027 free(output); 4028 4029 for (i = 0; i < config->num_output; i++) 4030 if (config->output[i] == output) 4031 break; 4032 assert(i < to_sna(scrn)->mode.num_real_output); 4033 DBG(("%s: removing output #%d of %d\n", 4034 __FUNCTION__, i, to_sna(scrn)->mode.num_real_output)); 4035 4036 for (; i < config->num_output; i++) { 4037 config->output[i] = config->output[i+1]; 4038 config->output[i]->possible_clones >>= 1; 4039 } 4040 config->num_output--; 4041 to_sna(scrn)->mode.num_real_output--; 4042} 4043 4044static int output_rank(const void *A, const void *B) 4045{ 4046 const xf86OutputPtr *a = A; 4047 const xf86OutputPtr *b = B; 4048 struct sna_output *sa = to_sna_output(*a); 4049 struct sna_output *sb = to_sna_output(*b); 4050 4051 if (sa->is_panel != sb->is_panel) 4052 return sb->is_panel - sa->is_panel; 4053 4054 return strcmp((*a)->name, (*b)->name); 4055} 4056 4057static void sort_config_outputs(struct sna *sna) 4058{ 4059 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn); 4060 qsort(config->output, sna->mode.num_real_output, sizeof(*config->output), output_rank); 4061 sna_mode_compute_possible_outputs(sna); 4062} 4063 4064static void sort_randr_outputs(struct sna *sna, ScreenPtr screen) 4065{ 4066 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn); 4067 rrScrPriv(screen); 4068 int i; 4069 4070 assert(pScrPriv->numOutputs == config->num_output); 4071 for (i = 0; i < config->num_output; i++) { 4072 assert(config->output[i]->randr_output); 4073 pScrPriv->outputs[i] = config->output[i]->randr_output; 4074 } 4075} 4076 4077static bool disable_unused_crtc(struct sna *sna) 4078{ 4079 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn); 4080 bool update = false; 4081 int o, c; 4082 4083 for (c = 0; c < sna->mode.num_real_crtc; c++) { 4084 xf86CrtcPtr crtc = config->crtc[c]; 4085 4086 if (!crtc->enabled) 4087 continue; 4088 4089 for (o = 0; o < sna->mode.num_real_output; o++) { 4090 xf86OutputPtr output = config->output[o]; 4091 if (output->crtc == crtc) 4092 break; 4093 } 4094 4095 if (o == sna->mode.num_real_output) { 4096 DBG(("%s: CRTC:%d was enabled with no outputs\n", 4097 __FUNCTION__, to_sna_crtc(crtc)->id)); 4098 crtc->enabled = false; 4099 update = true; 4100 } 4101 } 4102 4103 if (update) { 4104 DBG(("%s: disabling unused functions\n", __FUNCTION__)); 4105 xf86DisableUnusedFunctions(sna->scrn); 4106 } 4107 4108 return update; 4109} 4110 4111void sna_mode_discover(struct sna *sna) 4112{ 4113 ScreenPtr screen = xf86ScrnToScreen(sna->scrn); 4114 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn); 4115 struct drm_mode_card_res res; 4116 uint32_t connectors[32]; 4117 unsigned changed = 0; 4118 unsigned serial; 4119 int i, j; 4120 4121 DBG(("%s()\n", __FUNCTION__)); 4122 VG_CLEAR(connectors); 4123 4124 memset(&res, 0, sizeof(res)); 4125 res.count_connectors = 32; 4126 res.connector_id_ptr = (uintptr_t)connectors; 4127 4128 if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETRESOURCES, &res)) 4129 return; 4130 4131 DBG(("%s: now %d (was %d) connectors\n", __FUNCTION__, 4132 res.count_connectors, sna->mode.num_real_output)); 4133 if (res.count_connectors > 32) 4134 return; 4135 4136 assert(sna->mode.num_real_crtc == res.count_crtcs || is_zaphod(sna->scrn)); 4137 assert(sna->mode.max_crtc_width == res.max_width); 4138 assert(sna->mode.max_crtc_height == res.max_height); 4139 assert(sna->mode.num_real_encoder == res.count_encoders); 4140 4141 serial = ++sna->mode.serial; 4142 if (serial == 0) 4143 serial = ++sna->mode.serial; 4144 4145 for (i = 0; i < res.count_connectors; i++) { 4146 DBG(("%s: connector[%d] = %d\n", __FUNCTION__, i, connectors[i])); 4147 for (j = 0; j < sna->mode.num_real_output; j++) { 4148 xf86OutputPtr output = config->output[j]; 4149 if (to_sna_output(output)->id == connectors[i]) { 4150 DBG(("%s: found %s (id=%d)\n", __FUNCTION__, output->name, connectors[i])); 4151 assert(to_sna_output(output)->id); 4152 to_sna_output(output)->serial = serial; 4153 break; 4154 } 4155 } 4156 if (j == sna->mode.num_real_output) { 4157 DBG(("%s: adding id=%d\n", __FUNCTION__, connectors[i])); 4158 changed |= sna_output_add(sna, connectors[i], serial) > 0; 4159 } 4160 } 4161 4162 for (i = 0; i < sna->mode.num_real_output; i++) { 4163 xf86OutputPtr output = config->output[i]; 4164 4165 if (to_sna_output(output)->id == 0) 4166 continue; 4167 4168 if (to_sna_output(output)->serial == serial) 4169 continue; 4170 4171 DBG(("%s: removing output %s (id=%d), serial=%u [now %u]\n", 4172 __FUNCTION__, output->name, to_sna_output(output)->id, 4173 to_sna_output(output)->serial, serial)); 4174 4175 xf86DrvMsg(sna->scrn->scrnIndex, X_INFO, 4176 "%s output %s\n", 4177 sna->flags & SNA_REMOVE_OUTPUTS ? "Removed" : "Disabled", 4178 output->name); 4179 if (sna->flags & SNA_REMOVE_OUTPUTS) { 4180 sna_output_del(output); 4181 i--; 4182 } else { 4183 to_sna_output(output)->id = 0; 4184 output->crtc = NULL; 4185 } 4186 changed |= 2; 4187 } 4188 4189 if (changed) { 4190 DBG(("%s: outputs changed, broadcasting\n", __FUNCTION__)); 4191 4192 sna_mode_set_primary(sna); 4193 4194 /* Reorder user visible listing */ 4195 sort_config_outputs(sna); 4196 sort_randr_outputs(sna, screen); 4197 4198 if (changed & 2) 4199 disable_unused_crtc(sna); 4200 4201 xf86RandR12TellChanged(screen); 4202 } 4203} 4204 4205static void copy_front(struct sna *sna, PixmapPtr old, PixmapPtr new) 4206{ 4207 struct sna_pixmap *old_priv, *new_priv; 4208 4209 DBG(("%s\n", __FUNCTION__)); 4210 4211 if (wedged(sna)) 4212 return; 4213 4214 old_priv = sna_pixmap_force_to_gpu(old, MOVE_READ); 4215 if (!old_priv) 4216 return; 4217 4218 new_priv = sna_pixmap_force_to_gpu(new, MOVE_WRITE | __MOVE_SCANOUT); 4219 if (!new_priv) 4220 return; 4221 4222 if (old_priv->clear) { 4223 (void)sna->render.fill_one(sna, new, new_priv->gpu_bo, 4224 old_priv->clear_color, 4225 0, 0, 4226 new->drawable.width, 4227 new->drawable.height, 4228 GXcopy); 4229 new_priv->clear = true; 4230 new_priv->clear_color = old_priv->clear_color; 4231 } else { 4232 BoxRec box; 4233 int16_t sx, sy, dx, dy; 4234 4235 if (new->drawable.width >= old->drawable.width && 4236 new->drawable.height >= old->drawable.height) 4237 { 4238 int nx = (new->drawable.width + old->drawable.width - 1) / old->drawable.width; 4239 int ny = (new->drawable.height + old->drawable.height - 1) / old->drawable.height; 4240 4241 box.x1 = box.y1 = 0; 4242 4243 dy = 0; 4244 for (sy = 0; sy < ny; sy++) { 4245 box.y2 = old->drawable.height; 4246 if (box.y2 + dy > new->drawable.height) 4247 box.y2 = new->drawable.height - dy; 4248 4249 dx = 0; 4250 for (sx = 0; sx < nx; sx++) { 4251 box.x2 = old->drawable.width; 4252 if (box.x2 + dx > new->drawable.width) 4253 box.x2 = new->drawable.width - dx; 4254 4255 (void)sna->render.copy_boxes(sna, GXcopy, 4256 &old->drawable, old_priv->gpu_bo, 0, 0, 4257 &new->drawable, new_priv->gpu_bo, dx, dy, 4258 &box, 1, 0); 4259 dx += old->drawable.width; 4260 } 4261 dy += old->drawable.height; 4262 } 4263 } else { 4264 box.x1 = box.y1 = 0; 4265 box.x2 = min(old->drawable.width, new->drawable.width); 4266 box.y2 = min(old->drawable.height, new->drawable.height); 4267 4268 sx = dx = 0; 4269 if (box.x2 < old->drawable.width) 4270 sx = (old->drawable.width - box.x2) / 2; 4271 if (box.x2 < new->drawable.width) 4272 dx = (new->drawable.width - box.x2) / 2; 4273 4274 sy = dy = 0; 4275 if (box.y2 < old->drawable.height) 4276 sy = (old->drawable.height - box.y2) / 2; 4277 if (box.y2 < new->drawable.height) 4278 dy = (new->drawable.height - box.y2) / 2; 4279 4280 DBG(("%s: copying box (%dx%d) from (%d, %d) to (%d, %d)\n", 4281 __FUNCTION__, box.x2, box.y2, sx, sy, dx, dy)); 4282 4283 if (box.x2 != new->drawable.width || box.y2 != new->drawable.height) { 4284 (void)sna->render.fill_one(sna, new, new_priv->gpu_bo, 0, 4285 0, 0, 4286 new->drawable.width, 4287 new->drawable.height, 4288 GXclear); 4289 } 4290 (void)sna->render.copy_boxes(sna, GXcopy, 4291 &old->drawable, old_priv->gpu_bo, sx, sy, 4292 &new->drawable, new_priv->gpu_bo, dx, dy, 4293 &box, 1, 0); 4294 } 4295 } 4296 4297 sna_damage_all(&new_priv->gpu_damage, new); 4298} 4299 4300static Bool 4301sna_mode_resize(ScrnInfoPtr scrn, int width, int height) 4302{ 4303 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn); 4304 struct sna *sna = to_sna(scrn); 4305 ScreenPtr screen = scrn->pScreen; 4306 PixmapPtr new_front; 4307 int i; 4308 4309 DBG(("%s (%d, %d) -> (%d, %d)\n", __FUNCTION__, 4310 scrn->virtualX, scrn->virtualY, 4311 width, height)); 4312 assert((sna->flags & SNA_IS_HOSTED) == 0); 4313 4314 if (scrn->virtualX == width && scrn->virtualY == height) 4315 return TRUE; 4316 4317 /* Paranoid defense against rogue internal calls by Xorg */ 4318 if (width == 0 || height == 0) 4319 return FALSE; 4320 4321 assert(sna->front); 4322 assert(screen->GetScreenPixmap(screen) == sna->front); 4323 4324 DBG(("%s: creating new framebuffer %dx%d\n", 4325 __FUNCTION__, width, height)); 4326 4327 new_front = screen->CreatePixmap(screen, 4328 width, height, scrn->depth, 4329 SNA_CREATE_FB); 4330 if (!new_front) 4331 return FALSE; 4332 4333 xf86DrvMsg(scrn->scrnIndex, X_INFO, 4334 "resizing framebuffer to %dx%d\n", 4335 width, height); 4336 4337 for (i = 0; i < sna->mode.num_real_crtc; i++) 4338 sna_crtc_disable_shadow(sna, to_sna_crtc(config->crtc[i])); 4339 assert(sna->mode.shadow_active == 0); 4340 assert(sna->mode.shadow_damage == NULL); 4341 assert(sna->mode.shadow == NULL); 4342 4343 copy_front(sna, sna->front, new_front); 4344 4345 screen->SetScreenPixmap(new_front); 4346 assert(screen->GetScreenPixmap(screen) == new_front); 4347 assert(sna->front == new_front); 4348 screen->DestroyPixmap(new_front); /* owned by screen now */ 4349 4350 scrn->virtualX = width; 4351 scrn->virtualY = height; 4352 scrn->displayWidth = width; 4353 4354 /* Flush pending shadow updates */ 4355 if (sna->mode.flip_active) { 4356 DBG(("%s: waiting for %d outstanding TearFree flips\n", 4357 __FUNCTION__, sna->mode.flip_active)); 4358 while (sna->mode.flip_active && sna_mode_wait_for_event(sna)) 4359 sna_mode_wakeup(sna); 4360 } 4361 4362 /* Only update the CRTCs if we are in control */ 4363 if (!scrn->vtSema) 4364 return TRUE; 4365 4366 for (i = 0; i < sna->mode.num_real_crtc; i++) { 4367 xf86CrtcPtr crtc = config->crtc[i]; 4368 4369 assert(to_sna_crtc(crtc) != NULL); 4370 if (to_sna_crtc(crtc)->bo == NULL) 4371 continue; 4372 4373 if (!__sna_crtc_set_mode(crtc)) 4374 sna_crtc_disable(crtc); 4375 } 4376 4377 sna_mode_wakeup(sna); 4378 kgem_clean_scanout_cache(&sna->kgem); 4379 4380 return TRUE; 4381} 4382 4383/* cursor handling */ 4384struct sna_cursor { 4385 struct sna_cursor *next; 4386 uint32_t *image; 4387 Rotation rotation; 4388 int ref; 4389 int size; 4390 int last_width; 4391 int last_height; 4392 unsigned handle; 4393 unsigned serial; 4394 unsigned alloc; 4395}; 4396 4397static void 4398rotate_coord(Rotation rotation, int size, 4399 int x_dst, int y_dst, 4400 int *x_src, int *y_src) 4401{ 4402 int t; 4403 4404 switch (rotation & 0xf) { 4405 case RR_Rotate_0: 4406 break; 4407 case RR_Rotate_90: 4408 t = x_dst; 4409 x_dst = size - y_dst - 1; 4410 y_dst = t; 4411 break; 4412 case RR_Rotate_180: 4413 x_dst = size - x_dst - 1; 4414 y_dst = size - y_dst - 1; 4415 break; 4416 case RR_Rotate_270: 4417 t = x_dst; 4418 x_dst = y_dst; 4419 y_dst = size - t - 1; 4420 break; 4421 } 4422 4423 if (rotation & RR_Reflect_X) 4424 x_dst = size - x_dst - 1; 4425 if (rotation & RR_Reflect_Y) 4426 y_dst = size - y_dst - 1; 4427 4428 *x_src = x_dst; 4429 *y_src = y_dst; 4430} 4431 4432static void 4433rotate_coord_back(Rotation rotation, int size, int *x, int *y) 4434{ 4435 int t; 4436 4437 if (rotation & RR_Reflect_X) 4438 *x = size - *x - 1; 4439 if (rotation & RR_Reflect_Y) 4440 *y = size - *y - 1; 4441 4442 switch (rotation & 0xf) { 4443 case RR_Rotate_0: 4444 break; 4445 case RR_Rotate_90: 4446 t = *x; 4447 *x = *y; 4448 *y = size - t - 1; 4449 break; 4450 case RR_Rotate_180: 4451 *x = size - *x - 1; 4452 *y = size - *y - 1; 4453 break; 4454 case RR_Rotate_270: 4455 t = *x; 4456 *x = size - *y - 1; 4457 *y = t; 4458 break; 4459 } 4460} 4461 4462static struct sna_cursor *__sna_create_cursor(struct sna *sna, int size) 4463{ 4464 struct sna_cursor *c; 4465 4466 for (c = sna->cursor.cursors; c; c = c->next) { 4467 if (c->ref == 0 && c->alloc >= size) { 4468 __DBG(("%s: stealing handle=%d, serial=%d, rotation=%d, alloc=%d\n", 4469 __FUNCTION__, c->handle, c->serial, c->rotation, c->alloc)); 4470 return c; 4471 } 4472 } 4473 4474 __DBG(("%s(size=%d, num_stash=%d)\n", __FUNCTION__, size, sna->cursor.num_stash)); 4475 4476 c = sna->cursor.stash; 4477 assert(c); 4478 4479 c->alloc = ALIGN(size, 4096); 4480 c->handle = gem_create(sna->kgem.fd, c->alloc); 4481 if (c->handle == 0) 4482 return NULL; 4483 4484 /* Old hardware uses physical addresses, which the kernel 4485 * implements in an incoherent fashion requiring a pwrite. 4486 */ 4487 if (sna->cursor.use_gtt) { 4488 c->image = gem_mmap(sna->kgem.fd, c->handle, c->alloc); 4489 if (c->image == NULL) { 4490 gem_close(sna->kgem.fd, c->handle); 4491 return NULL; 4492 } 4493 } else 4494 c->image = NULL; 4495 4496 __DBG(("%s: handle=%d, allocated %d\n", __FUNCTION__, c->handle, size)); 4497 4498 c->ref = 0; 4499 c->serial = 0; 4500 c->rotation = 0; 4501 c->last_width = c->last_height = 0; /* all clear */ 4502 c->size = size; 4503 4504 sna->cursor.num_stash--; 4505 sna->cursor.stash = c->next; 4506 4507 c->next = sna->cursor.cursors; 4508 sna->cursor.cursors = c; 4509 4510 return c; 4511} 4512 4513static uint32_t *get_cursor_argb(CursorPtr c) 4514{ 4515#ifdef ARGB_CURSOR 4516 return (uint32_t *)c->bits->argb; 4517#else 4518 return NULL; 4519#endif 4520} 4521 4522static struct sna_cursor *__sna_get_cursor(struct sna *sna, xf86CrtcPtr crtc) 4523{ 4524 struct sna_cursor *cursor; 4525 const uint8_t *source, *mask; 4526 const uint32_t *argb; 4527 uint32_t *image; 4528 int width, height, pitch, size, x, y; 4529 Rotation rotation; 4530 4531 assert(sna->cursor.ref); 4532 4533 cursor = to_sna_crtc(crtc)->cursor; 4534 __DBG(("%s: current cursor handle=%d, serial=%d [expected %d]\n", 4535 __FUNCTION__, 4536 cursor ? cursor->handle : 0, 4537 cursor ? cursor->serial : 0, 4538 sna->cursor.serial)); 4539 if (cursor && cursor->serial == sna->cursor.serial) { 4540 assert(cursor->size == sna->cursor.size); 4541 assert(cursor->rotation == crtc->transform_in_use ? crtc->rotation : RR_Rotate_0); 4542 assert(cursor->ref); 4543 return cursor; 4544 } 4545 4546 __DBG(("%s: cursor=%dx%d, pitch=%d, serial=%d, argb?=%d\n", __FUNCTION__, 4547 sna->cursor.ref->bits->width, 4548 sna->cursor.ref->bits->height, 4549 get_cursor_argb(sna->cursor.ref) ? 4*sna->cursor.ref->bits->width : BitmapBytePad(sna->cursor.ref->bits->width), 4550 sna->cursor.serial, 4551 get_cursor_argb(sna->cursor.ref) != NULL)); 4552 4553 rotation = crtc->transform_in_use ? crtc->rotation : RR_Rotate_0; 4554 4555 if (sna->cursor.use_gtt) { /* Don't allow phys cursor sharing */ 4556 for (cursor = sna->cursor.cursors; cursor; cursor = cursor->next) { 4557 if (cursor->serial == sna->cursor.serial && cursor->rotation == rotation) { 4558 __DBG(("%s: reusing handle=%d, serial=%d, rotation=%d, size=%d\n", 4559 __FUNCTION__, cursor->handle, cursor->serial, cursor->rotation, cursor->size)); 4560 assert(cursor->size == sna->cursor.size); 4561 return cursor; 4562 } 4563 } 4564 4565 cursor = to_sna_crtc(crtc)->cursor; 4566 } 4567 4568 size = sna->cursor.size; 4569 if (cursor && cursor->alloc < 4*size*size) 4570 cursor = NULL; 4571 4572 if (cursor == NULL) { 4573 cursor = __sna_create_cursor(sna, 4*size*size); 4574 if (cursor == NULL) { 4575 DBG(("%s: failed to allocate cursor\n", __FUNCTION__)); 4576 return NULL; 4577 } 4578 } 4579 4580 width = sna->cursor.ref->bits->width; 4581 height = sna->cursor.ref->bits->height; 4582 source = sna->cursor.ref->bits->source; 4583 mask = sna->cursor.ref->bits->mask; 4584 argb = get_cursor_argb(sna->cursor.ref); 4585 pitch = BitmapBytePad(width); 4586 4587 image = cursor->image; 4588 if (image == NULL) { 4589 image = sna->cursor.scratch; 4590 cursor->last_width = cursor->last_height = size; 4591 } 4592 if (size > cursor->size || 4593 width < cursor->last_width || 4594 height < cursor->last_height || 4595 rotation != cursor->rotation) 4596 memset(image, 0, 4*size*size); 4597 if (rotation == RR_Rotate_0) { 4598 if (argb == NULL) { 4599 for (y = 0; y < height; y++) { 4600 uint32_t *p = image + y*size; 4601 for (x = 0; x < width; x++) { 4602 int byte = x / 8; 4603 uint8_t bit = 1 << (x & 7); 4604 uint32_t pixel; 4605 4606 if (mask[byte] & bit) { 4607 if (source[byte] & bit) 4608 pixel = sna->cursor.fg; 4609 else 4610 pixel = sna->cursor.bg; 4611 } else 4612 pixel = 0; 4613 4614 *p++ = pixel; 4615 } 4616 mask += pitch; 4617 source += pitch; 4618 } 4619 } else 4620 memcpy_blt(argb, image, 32, 4621 width * 4, size * 4, 4622 0, 0, 4623 0, 0, 4624 width, height); 4625 } else { 4626 for (y = 0; y < size; y++) 4627 for (x = 0; x < size; x++) { 4628 uint32_t pixel; 4629 int xin, yin; 4630 4631 rotate_coord(rotation, size, x, y, &xin, &yin); 4632 if (xin < width && yin < height) 4633 if (argb == NULL) { 4634 int byte = xin / 8; 4635 int bit = xin & 7; 4636 if (mask[yin*pitch + byte] & (1 << bit)) { 4637 if (source[yin*pitch + byte] & (1 << bit)) 4638 pixel = sna->cursor.fg; 4639 else 4640 pixel = sna->cursor.bg; 4641 } else 4642 pixel = 0; 4643 } else 4644 pixel = argb[yin * width + xin]; 4645 else 4646 pixel = 0; 4647 image[y * size + x] = pixel; 4648 } 4649 } 4650 4651 if (image != cursor->image) { 4652 struct drm_i915_gem_pwrite pwrite; 4653 4654 VG_CLEAR(pwrite); 4655 pwrite.handle = cursor->handle; 4656 pwrite.offset = 0; 4657 pwrite.size = 4*size*size; 4658 pwrite.data_ptr = (uintptr_t)image; 4659 if (drmIoctl(sna->kgem.fd, DRM_IOCTL_I915_GEM_PWRITE, &pwrite)) 4660 __DBG(("%s: cursor update (pwrite) failed: %d\n", __FUNCTION__, errno)); 4661 } 4662 4663 cursor->size = size; 4664 cursor->rotation = rotation; 4665 cursor->serial = sna->cursor.serial; 4666 cursor->last_width = width; 4667 cursor->last_height = height; 4668 return cursor; 4669} 4670 4671static unsigned char * 4672sna_realize_cursor(xf86CursorInfoPtr info, CursorPtr cursor) 4673{ 4674 return NULL; 4675} 4676 4677/* XXXMRG OsBlockSIGIO() is gone gone, old one remains before porting */ 4678#if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,12,99,901,0) && 0 4679static inline int sigio_block(void) 4680{ 4681 OsBlockSIGIO(); 4682 return 0; 4683} 4684static inline void sigio_unblock(int was_blocked) 4685{ 4686 OsReleaseSIGIO(); 4687 (void)was_blocked; 4688} 4689#else 4690#include <xf86_OSproc.h> 4691static inline int sigio_block(void) 4692{ 4693 return xf86BlockSIGIO(); 4694} 4695static inline void sigio_unblock(int was_blocked) 4696{ 4697 xf86UnblockSIGIO(was_blocked); 4698} 4699#endif 4700 4701static void 4702sna_show_cursors(ScrnInfoPtr scrn) 4703{ 4704 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); 4705 struct sna *sna = to_sna(scrn); 4706 int sigio, c; 4707 4708 DBG(("%s: cursor?=%d\n", __FUNCTION__, sna->cursor.ref != NULL)); 4709 if (sna->cursor.ref == NULL) 4710 return; 4711 4712 sigio = sigio_block(); 4713 for (c = 0; c < sna->mode.num_real_crtc; c++) { 4714 xf86CrtcPtr crtc = xf86_config->crtc[c]; 4715 struct sna_crtc *sna_crtc = to_sna_crtc(crtc); 4716 struct drm_mode_cursor arg; 4717 struct sna_cursor *cursor; 4718 4719 assert(sna_crtc != NULL); 4720 if (sna_crtc->bo == NULL) 4721 continue; 4722 4723 if (!crtc->cursor_in_range) { 4724 DBG(("%s: skipping cursor outside CRTC (pipe=%d)\n", 4725 __FUNCTION__, sna_crtc->pipe)); 4726 continue; 4727 } 4728 4729 cursor = __sna_get_cursor(sna, crtc); 4730 if (cursor == NULL || 4731 (sna_crtc->cursor == cursor && sna_crtc->last_cursor_size == cursor->size)) { 4732 DBG(("%s: skipping cursor already show on CRTC (pipe=%d)\n", 4733 __FUNCTION__, sna_crtc->pipe)); 4734 continue; 4735 } 4736 4737 DBG(("%s: CRTC pipe=%d, handle->%d\n", __FUNCTION__, 4738 sna_crtc->pipe, cursor->handle)); 4739 4740 VG_CLEAR(arg); 4741 arg.flags = DRM_MODE_CURSOR_BO; 4742 arg.crtc_id = sna_crtc->id; 4743 arg.width = arg.height = cursor->size; 4744 arg.handle = cursor->handle; 4745 4746 if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_CURSOR, &arg) == 0) { 4747 if (sna_crtc->cursor) { 4748 assert(sna_crtc->cursor->ref > 0); 4749 sna_crtc->cursor->ref--; 4750 } 4751 cursor->ref++; 4752 sna_crtc->cursor = cursor; 4753 sna_crtc->last_cursor_size = cursor->size; 4754 } 4755 } 4756 sigio_unblock(sigio); 4757 sna->cursor.active = true; 4758} 4759 4760static void 4761sna_set_cursor_colors(ScrnInfoPtr scrn, int _bg, int _fg) 4762{ 4763 struct sna *sna = to_sna(scrn); 4764 uint32_t fg = _fg, bg = _bg; 4765 4766 __DBG(("%s(bg=%08x, fg=%08x)\n", __FUNCTION__, bg, fg)); 4767 4768 /* Save ARGB versions of these colors */ 4769 fg |= 0xff000000; 4770 bg |= 0xff000000; 4771 if (fg == sna->cursor.fg && bg == sna->cursor.bg) 4772 return; 4773 4774 sna->cursor.fg = fg; 4775 sna->cursor.bg = bg; 4776 4777 if (sna->cursor.ref == NULL) 4778 return; 4779 4780 if (get_cursor_argb(sna->cursor.ref)) 4781 return; 4782 4783 sna->cursor.serial++; 4784 __DBG(("%s: serial->%d\n", __FUNCTION__, sna->cursor.serial)); 4785 4786 sna_show_cursors(scrn); 4787} 4788 4789static void 4790sna_crtc_disable_cursor(struct sna *sna, struct sna_crtc *crtc) 4791{ 4792 struct drm_mode_cursor arg; 4793 4794 if (!crtc->cursor) 4795 return; 4796 4797 DBG(("%s: CRTC:%d, handle=%d\n", __FUNCTION__, crtc->id, crtc->cursor->handle)); 4798 assert(crtc->cursor->ref); 4799 4800 VG_CLEAR(arg); 4801 arg.flags = DRM_MODE_CURSOR_BO; 4802 arg.crtc_id = crtc->id; 4803 arg.width = arg.height = 0; 4804 arg.handle = 0; 4805 4806 (void)drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_CURSOR, &arg); 4807 assert(crtc->cursor->ref > 0); 4808 crtc->cursor->ref--; 4809 crtc->cursor = NULL; 4810 crtc->last_cursor_size = 0; 4811} 4812 4813static void 4814sna_hide_cursors(ScrnInfoPtr scrn) 4815{ 4816 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); 4817 struct sna *sna = to_sna(scrn); 4818 struct sna_cursor *cursor, **prev; 4819 int sigio, c; 4820 4821 DBG(("%s\n", __FUNCTION__)); 4822 sna->cursor.active = false; 4823 4824 sigio = sigio_block(); 4825 for (c = 0; c < sna->mode.num_real_crtc; c++) { 4826 assert(to_sna_crtc(xf86_config->crtc[c])); 4827 sna_crtc_disable_cursor(sna, to_sna_crtc(xf86_config->crtc[c])); 4828 } 4829 4830 for (prev = &sna->cursor.cursors; (cursor = *prev) != NULL; ) { 4831 assert(cursor->ref == 0); 4832 4833 if (cursor->serial == sna->cursor.serial) { 4834 prev = &cursor->next; 4835 continue; 4836 } 4837 4838 *prev = cursor->next; 4839 if (cursor->image) 4840 munmap(cursor->image, cursor->alloc); 4841 gem_close(sna->kgem.fd, cursor->handle); 4842 4843 cursor->next = sna->cursor.stash; 4844 sna->cursor.stash = cursor; 4845 sna->cursor.num_stash++; 4846 } 4847 4848 sigio_unblock(sigio); 4849} 4850 4851static void 4852sna_set_cursor_position(ScrnInfoPtr scrn, int x, int y) 4853{ 4854 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); 4855 struct sna *sna = to_sna(scrn); 4856 int sigio, c; 4857 4858 __DBG(("%s(%d, %d), cursor? %d\n", __FUNCTION__, 4859 x, y, sna->cursor.ref!=NULL)); 4860 if (sna->cursor.ref == NULL) 4861 return; 4862 4863 sigio = sigio_block(); 4864 sna->cursor.last_x = x; 4865 sna->cursor.last_y = y; 4866 4867 /* undo what xf86HWCurs did to the coordinates */ 4868 x += scrn->frameX0; 4869 y += scrn->frameY0; 4870 for (c = 0; c < sna->mode.num_real_crtc; c++) { 4871 xf86CrtcPtr crtc = xf86_config->crtc[c]; 4872 struct sna_crtc *sna_crtc = to_sna_crtc(crtc); 4873 struct sna_cursor *cursor = NULL; 4874 struct drm_mode_cursor arg; 4875 4876 assert(sna_crtc != NULL); 4877 4878 VG_CLEAR(arg); 4879 arg.flags = 0; 4880 arg.crtc_id = sna_crtc->id; 4881 arg.handle = 0; 4882 4883 if (sna_crtc->bo == NULL) 4884 goto disable; 4885 4886 if (crtc->transform_in_use) { 4887 int xhot = sna->cursor.ref->bits->xhot; 4888 int yhot = sna->cursor.ref->bits->yhot; 4889 struct pict_f_vector v; 4890 4891 v.v[0] = (x + xhot) + 0.5; 4892 v.v[1] = (y + yhot) + 0.5; 4893 v.v[2] = 1; 4894 pixman_f_transform_point(&crtc->f_framebuffer_to_crtc, &v); 4895 4896 rotate_coord_back(crtc->rotation, sna->cursor.size, &xhot, &yhot); 4897 4898 /* cursor will have 0.5 added to it already so floor is sufficent */ 4899 arg.x = floor(v.v[0]) - xhot; 4900 arg.y = floor(v.v[1]) - yhot; 4901 } else { 4902 arg.x = x - crtc->x; 4903 arg.y = y - crtc->y; 4904 } 4905 4906 if (arg.x < crtc->mode.HDisplay && arg.x > -sna->cursor.size && 4907 arg.y < crtc->mode.VDisplay && arg.y > -sna->cursor.size) { 4908 cursor = __sna_get_cursor(sna, crtc); 4909 if (cursor == NULL) 4910 cursor = sna_crtc->cursor; 4911 if (cursor == NULL) { 4912 __DBG(("%s: failed to grab cursor, disabling\n", 4913 __FUNCTION__)); 4914 goto disable; 4915 } 4916 4917 if (sna_crtc->cursor != cursor || sna_crtc->last_cursor_size != cursor->size) { 4918 arg.flags |= DRM_MODE_CURSOR_BO; 4919 arg.handle = cursor->handle; 4920 } 4921 4922 arg.width = arg.height = cursor->size; 4923 arg.flags |= DRM_MODE_CURSOR_MOVE; 4924 crtc->cursor_in_range = true; 4925 } else { 4926 crtc->cursor_in_range = false; 4927disable: 4928 if (sna_crtc->cursor) { 4929 arg.flags = DRM_MODE_CURSOR_BO; 4930 arg.width = arg.height = 0; 4931 } 4932 cursor = NULL; 4933 } 4934 4935 __DBG(("%s: CRTC:%d (%d, %d), handle=%d, flags=%x (old cursor handle=%d), move? %d, update handle? %d\n", 4936 __FUNCTION__, sna_crtc->id, arg.x, arg.y, arg.handle, arg.flags, sna_crtc->cursor ? sna_crtc->cursor->handle : 0, 4937 arg.flags & DRM_MODE_CURSOR_MOVE, arg.flags & DRM_MODE_CURSOR_BO)); 4938 4939 if (arg.flags && 4940 drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_CURSOR, &arg) == 0) { 4941 if (arg.flags & DRM_MODE_CURSOR_BO) { 4942 if (sna_crtc->cursor) { 4943 assert(sna_crtc->cursor->ref > 0); 4944 sna_crtc->cursor->ref--; 4945 } 4946 sna_crtc->cursor = cursor; 4947 if (cursor) { 4948 sna_crtc->last_cursor_size = cursor->size; 4949 cursor->ref++; 4950 } else 4951 sna_crtc->last_cursor_size = 0; 4952 } 4953 } 4954 } 4955 sigio_unblock(sigio); 4956} 4957 4958#if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,15,99,902,2) 4959static Bool 4960sna_load_cursor_argb2(ScrnInfoPtr scrn, CursorPtr cursor) 4961{ 4962 return TRUE; 4963} 4964 4965static Bool 4966sna_load_cursor_image2(ScrnInfoPtr scrn, unsigned char *src) 4967{ 4968 return TRUE; 4969} 4970#endif 4971 4972static void 4973sna_load_cursor_argb(ScrnInfoPtr scrn, CursorPtr cursor) 4974{ 4975} 4976 4977static void 4978sna_load_cursor_image(ScrnInfoPtr scrn, unsigned char *src) 4979{ 4980} 4981 4982static int __cursor_size(CursorPtr cursor) 4983{ 4984 int i, size; 4985 4986 i = MAX(cursor->bits->width, cursor->bits->height); 4987 for (size = 64; size < i; size <<= 1) 4988 ; 4989 4990 return size; 4991} 4992 4993static bool 4994sna_cursor_preallocate(struct sna *sna) 4995{ 4996 while (sna->cursor.num_stash < 0) { 4997 struct sna_cursor *cursor = malloc(sizeof(*cursor)); 4998 if (!cursor) 4999 return false; 5000 5001 cursor->next = sna->cursor.stash; 5002 sna->cursor.stash = cursor; 5003 5004 sna->cursor.num_stash++; 5005 } 5006 5007 return true; 5008} 5009 5010static Bool 5011sna_use_hw_cursor(ScreenPtr screen, CursorPtr cursor) 5012{ 5013 struct sna *sna = to_sna_from_screen(screen); 5014 5015 DBG(("%s (%dx%d)?\n", __FUNCTION__, 5016 cursor->bits->width, cursor->bits->height)); 5017 5018 /* cursors are invariant */ 5019 if (cursor == sna->cursor.ref) 5020 return TRUE; 5021 5022 if (sna->cursor.ref) { 5023 FreeCursor(sna->cursor.ref, None); 5024 sna->cursor.ref = NULL; 5025 } 5026 5027 sna->cursor.size = __cursor_size(cursor); 5028 if (sna->cursor.size > sna->cursor.max_size) 5029 return FALSE; 5030 5031 if (!sna_cursor_preallocate(sna)) 5032 return FALSE; 5033 5034 sna->cursor.ref = cursor; 5035 cursor->refcnt++; 5036 sna->cursor.serial++; 5037 5038 DBG(("%s(%dx%d): ARGB?=%d, serial->%d, size->%d\n", __FUNCTION__, 5039 cursor->bits->width, 5040 cursor->bits->height, 5041 get_cursor_argb(cursor) != NULL, 5042 sna->cursor.serial, 5043 sna->cursor.size)); 5044 return TRUE; 5045} 5046 5047static void 5048sna_cursor_pre_init(struct sna *sna) 5049{ 5050 struct local_get_cap { 5051 uint64_t name; 5052 uint64_t value; 5053 } cap; 5054 int v; 5055 5056 if (sna->mode.num_real_crtc == 0) 5057 return; 5058 5059#define LOCAL_IOCTL_GET_CAP DRM_IOWR(0x0c, struct local_get_cap) 5060#define DRM_CAP_CURSOR_WIDTH 0x8 5061#define DRM_CAP_CURSOR_HEIGHT 0x9 5062 5063#define I915_PARAM_HAS_COHERENT_PHYS_GTT 29 5064 5065 sna->cursor.max_size = 64; 5066 5067 cap.value = 0; 5068 cap.name = DRM_CAP_CURSOR_WIDTH; 5069 if (drmIoctl(sna->kgem.fd, LOCAL_IOCTL_GET_CAP, &cap) == 0) 5070 sna->cursor.max_size = cap.value; 5071 5072 cap.name = DRM_CAP_CURSOR_HEIGHT; 5073 if (drmIoctl(sna->kgem.fd, LOCAL_IOCTL_GET_CAP, &cap) == 0 && 5074 cap.value < sna->cursor.max_size) 5075 sna->cursor.max_size = cap.value; 5076 5077 v = -1; /* No param uses the sign bit, reserve it for errors */ 5078 if (sna->kgem.gen >= 033) { 5079 v = 1; 5080 } else { 5081 drm_i915_getparam_t gp = { 5082 I915_PARAM_HAS_COHERENT_PHYS_GTT, 5083 &v, 5084 }; 5085 (void)drmIoctl(sna->kgem.fd, DRM_IOCTL_I915_GETPARAM, &gp); 5086 } 5087 sna->cursor.use_gtt = v > 0; 5088 DBG(("%s: cursor updates use_gtt?=%d\n", 5089 __FUNCTION__, sna->cursor.use_gtt)); 5090 5091 if (!sna->cursor.use_gtt) { 5092 sna->cursor.scratch = malloc(sna->cursor.max_size * sna->cursor.max_size * 4); 5093 if (!sna->cursor.scratch) 5094 sna->cursor.max_size = 0; 5095 } 5096 5097 sna->cursor.num_stash = -sna->mode.num_real_crtc; 5098 5099 xf86DrvMsg(sna->scrn->scrnIndex, X_PROBED, 5100 "Using a maximum size of %dx%d for hardware cursors\n", 5101 sna->cursor.max_size, sna->cursor.max_size); 5102} 5103 5104static void 5105sna_cursor_close(struct sna *sna) 5106{ 5107 sna->cursor.serial = 0; 5108 sna_hide_cursors(sna->scrn); 5109 5110 while (sna->cursor.stash) { 5111 struct sna_cursor *cursor = sna->cursor.stash; 5112 sna->cursor.stash = cursor->next; 5113 free(cursor); 5114 } 5115 5116 sna->cursor.num_stash = -sna->mode.num_real_crtc; 5117} 5118 5119bool 5120sna_cursors_init(ScreenPtr screen, struct sna *sna) 5121{ 5122 xf86CursorInfoPtr cursor_info; 5123 5124 if (sna->cursor.max_size == 0) 5125 return false; 5126 5127 cursor_info = xf86CreateCursorInfoRec(); 5128 if (cursor_info == NULL) 5129 return false; 5130 5131 cursor_info->MaxWidth = sna->cursor.max_size; 5132 cursor_info->MaxHeight = sna->cursor.max_size; 5133 cursor_info->Flags = (HARDWARE_CURSOR_TRUECOLOR_AT_8BPP | 5134 HARDWARE_CURSOR_UPDATE_UNHIDDEN | 5135 HARDWARE_CURSOR_ARGB); 5136 5137 cursor_info->RealizeCursor = sna_realize_cursor; 5138 cursor_info->SetCursorColors = sna_set_cursor_colors; 5139 cursor_info->SetCursorPosition = sna_set_cursor_position; 5140 cursor_info->LoadCursorImage = sna_load_cursor_image; 5141 cursor_info->HideCursor = sna_hide_cursors; 5142 cursor_info->ShowCursor = sna_show_cursors; 5143 cursor_info->UseHWCursor = sna_use_hw_cursor; 5144#ifdef ARGB_CURSOR 5145 cursor_info->UseHWCursorARGB = sna_use_hw_cursor; 5146 cursor_info->LoadCursorARGB = sna_load_cursor_argb; 5147#endif 5148#if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,15,99,902,3) 5149 cursor_info->LoadCursorImageCheck = sna_load_cursor_image2; 5150#ifdef ARGB_CURSOR 5151 cursor_info->LoadCursorARGBCheck = sna_load_cursor_argb2; 5152#endif 5153#endif 5154 5155 if (!xf86InitCursor(screen, cursor_info)) { 5156 xf86DestroyCursorInfoRec(cursor_info); 5157 return false; 5158 } 5159 5160 sna->cursor.info = cursor_info; 5161 return true; 5162} 5163 5164static void 5165sna_cursors_reload(struct sna *sna) 5166{ 5167 DBG(("%s: active?=%d\n", __FUNCTION__, sna->cursor.active)); 5168 if (sna->cursor.active) 5169 sna_set_cursor_position(sna->scrn, 5170 sna->cursor.last_x, 5171 sna->cursor.last_y); 5172} 5173 5174static void 5175sna_cursors_fini(struct sna *sna) 5176{ 5177 if (sna->cursor.info) { 5178 xf86DestroyCursorInfoRec(sna->cursor.info); 5179 sna->cursor.info = NULL; 5180 } 5181 5182 if (sna->cursor.ref) { 5183 FreeCursor(sna->cursor.ref, None); 5184 sna->cursor.ref = NULL; 5185 } 5186} 5187 5188static bool 5189sna_crtc_flip(struct sna *sna, struct sna_crtc *crtc, struct kgem_bo *bo, int x, int y) 5190{ 5191 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn); 5192 struct drm_mode_crtc arg; 5193 uint32_t output_ids[32]; 5194 int output_count = 0; 5195 int i; 5196 5197 DBG(("%s CRTC:%d [pipe=%d], handle=%d\n", __FUNCTION__, crtc->id, crtc->pipe, bo->handle)); 5198 5199 assert(sna->mode.num_real_output < ARRAY_SIZE(output_ids)); 5200 assert(crtc->bo); 5201 assert(crtc->kmode.clock); 5202 5203 for (i = 0; i < sna->mode.num_real_output; i++) { 5204 xf86OutputPtr output = config->output[i]; 5205 5206 if (output->crtc != crtc->base) 5207 continue; 5208 5209 DBG(("%s: attaching output '%s' %d [%d] to crtc:%d (pipe %d) (possible crtc:%x, possible clones:%x)\n", 5210 __FUNCTION__, output->name, i, to_connector_id(output), 5211 crtc->id, crtc->pipe, 5212 (uint32_t)output->possible_crtcs, 5213 (uint32_t)output->possible_clones)); 5214 5215 assert(output->possible_crtcs & (1 << crtc->pipe) || 5216 is_zaphod(sna->scrn)); 5217 5218 output_ids[output_count] = to_connector_id(output); 5219 if (++output_count == ARRAY_SIZE(output_ids)) 5220 return false; 5221 } 5222 assert(output_count); 5223 5224 VG_CLEAR(arg); 5225 arg.crtc_id = crtc->id; 5226 arg.fb_id = fb_id(bo); 5227 assert(arg.fb_id); 5228 arg.x = x; 5229 arg.y = y; 5230 arg.set_connectors_ptr = (uintptr_t)output_ids; 5231 arg.count_connectors = output_count; 5232 arg.mode = crtc->kmode; 5233 arg.mode_valid = 1; 5234 5235 DBG(("%s: applying crtc [%d, pipe=%d] mode=%dx%d+%d+%d@%d, fb=%d across %d outputs [%d...]\n", 5236 __FUNCTION__, crtc->id, crtc->pipe, 5237 arg.mode.hdisplay, 5238 arg.mode.vdisplay, 5239 arg.x, arg.y, 5240 arg.mode.clock, 5241 arg.fb_id, 5242 output_count, output_count ? output_ids[0] : 0)); 5243 5244 if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_SETCRTC, &arg)) 5245 return false; 5246 5247 crtc->offset = y << 16 | x; 5248 return true; 5249} 5250 5251int 5252sna_page_flip(struct sna *sna, 5253 struct kgem_bo *bo, 5254 sna_flip_handler_t handler, 5255 void *data) 5256{ 5257 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn); 5258 const int width = sna->scrn->virtualX; 5259 const int height = sna->scrn->virtualY; 5260 int count = 0; 5261 int i; 5262 5263 DBG(("%s: handle %d attached\n", __FUNCTION__, bo->handle)); 5264 assert(bo->refcnt); 5265 5266 assert((sna->flags & SNA_IS_HOSTED) == 0); 5267 assert((sna->flags & SNA_TEAR_FREE) == 0); 5268 assert(sna->mode.flip_active == 0); 5269 assert(sna->mode.front_active); 5270 assert(sna->scrn->vtSema); 5271 5272 if ((sna->flags & (data ? SNA_HAS_FLIP : SNA_HAS_ASYNC_FLIP)) == 0) 5273 return 0; 5274 5275 kgem_bo_submit(&sna->kgem, bo); 5276 5277 for (i = 0; i < sna->mode.num_real_crtc; i++) { 5278 struct sna_crtc *crtc = config->crtc[i]->driver_private; 5279 struct drm_mode_crtc_page_flip arg; 5280 uint32_t crtc_offset; 5281 5282 DBG(("%s: crtc %d id=%d, pipe=%d active? %d\n", 5283 __FUNCTION__, i, crtc->id, crtc->pipe, crtc->bo != NULL)); 5284 if (crtc->bo == NULL) 5285 continue; 5286 assert(!crtc->transform); 5287 assert(!crtc->slave_pixmap); 5288 assert(crtc->bo->active_scanout); 5289 assert(crtc->bo->refcnt >= crtc->bo->active_scanout); 5290 assert(crtc->flip_bo == NULL); 5291 5292 arg.crtc_id = crtc->id; 5293 arg.fb_id = get_fb(sna, bo, width, height); 5294 if (arg.fb_id == 0) { 5295 assert(count == 0); 5296 return 0; 5297 } 5298 5299 crtc_offset = crtc->base->y << 16 | crtc->base->x; 5300 5301 if (bo->pitch != crtc->bo->pitch || crtc_offset != crtc->offset) { 5302 DBG(("%s: changing pitch (%d == %d) or offset (%x == %x)\n", 5303 __FUNCTION__, 5304 bo->pitch, crtc->bo->pitch, 5305 crtc_offset, crtc->offset)); 5306fixup_flip: 5307 if (crtc->bo != bo && sna_crtc_flip(sna, crtc, bo, crtc->base->x, crtc->base->y)) { 5308 assert(crtc->bo->active_scanout); 5309 assert(crtc->bo->refcnt >= crtc->bo->active_scanout); 5310 crtc->bo->active_scanout--; 5311 kgem_bo_destroy(&sna->kgem, crtc->bo); 5312 5313 if (crtc->shadow_bo) { 5314 kgem_bo_destroy(&sna->kgem, crtc->shadow_bo); 5315 crtc->shadow_bo = NULL; 5316 } 5317 5318 crtc->bo = kgem_bo_reference(bo); 5319 crtc->bo->active_scanout++; 5320 5321 if (data == NULL) 5322 goto next_crtc; 5323 5324 /* queue a flip in order to send the event */ 5325 } else { 5326 if (count && !xf86SetDesiredModes(sna->scrn)) { 5327 xf86DrvMsg(sna->scrn->scrnIndex, X_ERROR, 5328 "failed to restore display configuration\n"); 5329 for (; i < sna->mode.num_real_crtc; i++) 5330 sna_crtc_disable(config->crtc[i]); 5331 } 5332 return 0; 5333 } 5334 } 5335 5336 /* Only the reference crtc will finally deliver its page flip 5337 * completion event. All other crtc's events will be discarded. 5338 */ 5339 if (data) { 5340 arg.user_data = (uintptr_t)crtc; 5341 arg.flags = DRM_MODE_PAGE_FLIP_EVENT; 5342 } else { 5343 arg.user_data = 0; 5344 arg.flags = DRM_MODE_PAGE_FLIP_ASYNC; 5345 } 5346 arg.reserved = 0; 5347 5348retry_flip: 5349 DBG(("%s: crtc %d id=%d, pipe=%d --> fb %d\n", 5350 __FUNCTION__, i, crtc->id, crtc->pipe, arg.fb_id)); 5351 if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_PAGE_FLIP, &arg)) { 5352 ERR(("%s: pageflip failed with err=%d\n", __FUNCTION__, errno)); 5353 5354 if (errno == EBUSY) { 5355 struct drm_mode_crtc mode; 5356 5357 memset(&mode, 0, sizeof(mode)); 5358 mode.crtc_id = crtc->id; 5359 drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETCRTC, &mode); 5360 5361 DBG(("%s: crtc=%d, valid?=%d, fb attached?=%d, expected=%d\n", 5362 __FUNCTION__, 5363 mode.crtc_id, mode.mode_valid, 5364 mode.fb_id, fb_id(crtc->bo))); 5365 5366 if (mode.fb_id != fb_id(crtc->bo)) 5367 goto fixup_flip; 5368 5369 if (count == 0) 5370 return 0; 5371 5372 DBG(("%s: throttling on busy flip / waiting for kernel to catch up\n", __FUNCTION__)); 5373 drmIoctl(sna->kgem.fd, DRM_IOCTL_I915_GEM_THROTTLE, 0); 5374 sna->kgem.need_throttle = false; 5375 5376 goto retry_flip; 5377 } 5378 5379 xf86DrvMsg(sna->scrn->scrnIndex, X_ERROR, 5380 "page flipping failed, on CRTC:%d (pipe=%d), disabling %s page flips\n", 5381 crtc->id, crtc->pipe, data ? "synchronous": "asynchronous"); 5382 sna->flags &= ~(data ? SNA_HAS_FLIP : SNA_HAS_ASYNC_FLIP); 5383 goto fixup_flip; 5384 } 5385 5386 if (data) { 5387 assert(crtc->flip_bo == NULL); 5388 crtc->flip_handler = handler; 5389 crtc->flip_data = data; 5390 crtc->flip_bo = kgem_bo_reference(bo); 5391 crtc->flip_bo->active_scanout++; 5392 crtc->flip_serial = crtc->mode_serial; 5393 crtc->flip_pending = true; 5394 sna->mode.flip_active++; 5395 } 5396 5397next_crtc: 5398 count++; 5399 } 5400 5401 DBG(("%s: page flipped %d crtcs\n", __FUNCTION__, count)); 5402 return count; 5403} 5404 5405static const xf86CrtcConfigFuncsRec sna_mode_funcs = { 5406 sna_mode_resize 5407}; 5408 5409static void set_size_range(struct sna *sna) 5410{ 5411 /* We lie slightly as we expect no single monitor to exceed the 5412 * crtc limits, so if the mode exceeds the scanout restrictions, 5413 * we will quietly convert that to per-crtc pixmaps. 5414 */ 5415 xf86CrtcSetSizeRange(sna->scrn, 8, 8, INT16_MAX, INT16_MAX); 5416} 5417 5418#if HAS_GAMMA 5419static void set_gamma(uint16_t *curve, int size, double value) 5420{ 5421 int i; 5422 5423 value = 1/value; 5424 for (i = 0; i < size; i++) 5425 curve[i] = 256*(size-1)*pow(i/(double)(size-1), value); 5426} 5427 5428static void output_set_gamma(xf86OutputPtr output, xf86CrtcPtr crtc) 5429{ 5430 XF86ConfMonitorPtr mon = output->conf_monitor; 5431 5432 if (!mon) 5433 return; 5434 5435 DBG(("%s: red=%f\n", __FUNCTION__, mon->mon_gamma_red)); 5436 if (mon->mon_gamma_red >= GAMMA_MIN && 5437 mon->mon_gamma_red <= GAMMA_MAX && 5438 mon->mon_gamma_red != 1.0) 5439 set_gamma(crtc->gamma_red, crtc->gamma_size, 5440 mon->mon_gamma_red); 5441 5442 DBG(("%s: green=%f\n", __FUNCTION__, mon->mon_gamma_green)); 5443 if (mon->mon_gamma_green >= GAMMA_MIN && 5444 mon->mon_gamma_green <= GAMMA_MAX && 5445 mon->mon_gamma_green != 1.0) 5446 set_gamma(crtc->gamma_green, crtc->gamma_size, 5447 mon->mon_gamma_green); 5448 5449 DBG(("%s: blue=%f\n", __FUNCTION__, mon->mon_gamma_blue)); 5450 if (mon->mon_gamma_blue >= GAMMA_MIN && 5451 mon->mon_gamma_blue <= GAMMA_MAX && 5452 mon->mon_gamma_blue != 1.0) 5453 set_gamma(crtc->gamma_blue, crtc->gamma_size, 5454 mon->mon_gamma_blue); 5455} 5456 5457static void crtc_init_gamma(xf86CrtcPtr crtc) 5458{ 5459 uint16_t *gamma; 5460 5461 /* Initialize the gamma ramps */ 5462 gamma = NULL; 5463 if (crtc->gamma_size == 256) 5464 gamma = crtc->gamma_red; 5465 if (gamma == NULL) 5466 gamma = malloc(3 * 256 * sizeof(uint16_t)); 5467 if (gamma) { 5468 struct sna *sna = to_sna(crtc->scrn); 5469 struct sna_crtc *sna_crtc = to_sna_crtc(crtc); 5470 struct drm_mode_crtc_lut lut; 5471 bool gamma_set = false; 5472 5473 assert(sna_crtc); 5474 5475 lut.crtc_id = sna_crtc->id; 5476 lut.gamma_size = 256; 5477 lut.red = (uintptr_t)(gamma); 5478 lut.green = (uintptr_t)(gamma + 256); 5479 lut.blue = (uintptr_t)(gamma + 2 * 256); 5480 if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETGAMMA, &lut) == 0) { 5481 VG(VALGRIND_MAKE_MEM_DEFINED(gamma, 3*256*sizeof(gamma[0]))); 5482 gamma_set = 5483 gamma[256 - 1] && 5484 gamma[2*256 - 1] && 5485 gamma[3*256 - 1]; 5486 } 5487 5488 DBG(("%s: CRTC:%d, pipe=%d: gamma set?=%d\n", 5489 __FUNCTION__, sna_crtc->id, sna_crtc->pipe, 5490 gamma_set)); 5491 if (!gamma_set) { 5492 int i; 5493 5494 for (i = 0; i < 256; i++) { 5495 gamma[i] = i << 8; 5496 gamma[256 + i] = i << 8; 5497 gamma[2*256 + i] = i << 8; 5498 } 5499 } 5500 5501 if (gamma != crtc->gamma_red) { 5502 free(crtc->gamma_red); 5503 crtc->gamma_red = gamma; 5504 crtc->gamma_green = gamma + 256; 5505 crtc->gamma_blue = gamma + 2*256; 5506 } 5507 } 5508} 5509#else 5510static void output_set_gamma(xf86OutputPtr output, xf86CrtcPtr crtc) { } 5511static void crtc_init_gamma(xf86CrtcPtr crtc) { } 5512#endif 5513 5514static const char *preferred_mode(xf86OutputPtr output) 5515{ 5516 const char *mode; 5517 5518 mode = xf86GetOptValString(output->options, OPTION_PREFERRED_MODE); 5519 if (mode) 5520 return mode; 5521 5522 if (output->scrn->display->modes && *output->scrn->display->modes) 5523 return *output->scrn->display->modes; 5524 5525 return NULL; 5526} 5527 5528static bool sna_probe_initial_configuration(struct sna *sna) 5529{ 5530 ScrnInfoPtr scrn = sna->scrn; 5531 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn); 5532 int width, height; 5533 int i, j; 5534 5535 assert((sna->flags & SNA_IS_HOSTED) == 0); 5536 5537 if ((sna->flags & SNA_IS_SLAVED) == 0) { 5538 const int user_overrides[] = { 5539 OPTION_POSITION, 5540 OPTION_BELOW, 5541 OPTION_RIGHT_OF, 5542 OPTION_ABOVE, 5543 OPTION_LEFT_OF, 5544 OPTION_ROTATE, 5545 OPTION_PANNING, 5546 }; 5547 if (xf86ReturnOptValBool(sna->Options, OPTION_REPROBE, FALSE)) { 5548 DBG(("%s: user requests reprobing\n", __FUNCTION__)); 5549 return false; 5550 } 5551 5552 /* First scan through all outputs and look for user overrides */ 5553 for (i = 0; i < sna->mode.num_real_output; i++) { 5554 xf86OutputPtr output = config->output[i]; 5555 5556 for (j = 0; j < ARRAY_SIZE(user_overrides); j++) { 5557 if (xf86GetOptValString(output->options, user_overrides[j])) { 5558 DBG(("%s: user placement [%d] for %s\n", 5559 __FUNCTION__, 5560 user_overrides[j], 5561 output->name)); 5562 return false; 5563 } 5564 } 5565 } 5566 } 5567 5568 /* Copy the existing modes on each CRTCs */ 5569 for (i = 0; i < sna->mode.num_real_crtc; i++) { 5570 xf86CrtcPtr crtc = config->crtc[i]; 5571 struct sna_crtc *sna_crtc = to_sna_crtc(crtc); 5572 struct drm_mode_crtc mode; 5573 5574 crtc->enabled = FALSE; 5575 crtc->desiredMode.status = MODE_NOMODE; 5576 5577 crtc_init_gamma(crtc); 5578 5579 /* Retrieve the current mode */ 5580 VG_CLEAR(mode); 5581 mode.crtc_id = sna_crtc->id; 5582 if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETCRTC, &mode)) 5583 continue; 5584 5585 DBG(("%s: CRTC:%d, pipe=%d: has mode?=%d\n", __FUNCTION__, 5586 sna_crtc->id, sna_crtc->pipe, 5587 mode.mode_valid && mode.mode.clock)); 5588 5589 if (!mode.mode_valid || mode.mode.clock == 0) 5590 continue; 5591 5592 mode_from_kmode(scrn, &mode.mode, &crtc->desiredMode); 5593 crtc->desiredRotation = sna_crtc->primary.rotation.current; 5594 crtc->desiredX = mode.x; 5595 crtc->desiredY = mode.y; 5596 crtc->desiredTransformPresent = FALSE; 5597 } 5598 5599 /* Reconstruct outputs pointing to active CRTC */ 5600 for (i = 0; i < sna->mode.num_real_output; i++) { 5601 xf86OutputPtr output = config->output[i]; 5602 uint32_t crtc_id; 5603 5604 assert(to_sna_output(output)); 5605 5606 crtc_id = (uintptr_t)output->crtc; 5607 output->crtc = NULL; 5608 if (sna->flags & SNA_IS_SLAVED) 5609 continue; 5610 5611 if (crtc_id == 0) { 5612 DBG(("%s: not using output %s, disconnected\n", 5613 __FUNCTION__, output->name)); 5614 continue; 5615 } 5616 5617 if (xf86ReturnOptValBool(output->options, OPTION_DISABLE, 0)) { 5618 DBG(("%s: not using output %s, manually disabled\n", 5619 __FUNCTION__, output->name)); 5620 continue; 5621 } 5622 5623 for (j = 0; j < sna->mode.num_real_crtc; j++) { 5624 xf86CrtcPtr crtc = config->crtc[j]; 5625 5626 assert(to_sna_crtc(crtc)); 5627 if (to_sna_crtc(crtc)->id != crtc_id) 5628 continue; 5629 5630 if (crtc->desiredMode.status == MODE_OK) { 5631 DisplayModePtr M; 5632 const char *pref; 5633 5634 pref = preferred_mode(output); 5635 if (pref && strcmp(pref, crtc->desiredMode.name)) { 5636 DBG(("%s: output %s user requests a different preferred mode %s, found %s\n", 5637 __FUNCTION__, output->name, pref, crtc->desiredMode.name)); 5638 return false; 5639 } 5640 5641 xf86DrvMsg(scrn->scrnIndex, X_PROBED, 5642 "Output %s using initial mode %s on pipe %d\n", 5643 output->name, 5644 crtc->desiredMode.name, 5645 to_sna_crtc(crtc)->pipe); 5646 5647 output->crtc = crtc; 5648 crtc->enabled = TRUE; 5649 5650 if (output->mm_width == 0 || output->mm_height == 0) { 5651 output->mm_height = (crtc->desiredMode.VDisplay * 254) / (10*DEFAULT_DPI); 5652 output->mm_width = (crtc->desiredMode.HDisplay * 254) / (10*DEFAULT_DPI); 5653 } 5654 5655 output_set_gamma(output, crtc); 5656 5657 M = calloc(1, sizeof(DisplayModeRec)); 5658 if (M) { 5659 *M = crtc->desiredMode; 5660 M->name = strdup(M->name); 5661 output->probed_modes = 5662 xf86ModesAdd(output->probed_modes, M); 5663 } 5664 } 5665 5666 break; 5667 } 5668 5669 if (j == sna->mode.num_real_crtc) { 5670 /* Can not find the earlier associated CRTC, bail */ 5671 DBG(("%s: existing setup conflicts with output assignment (Zaphod), reprobing\n", 5672 __FUNCTION__)); 5673 return false; 5674 } 5675 } 5676 5677 width = height = 0; 5678 for (i = 0; i < sna->mode.num_real_crtc; i++) { 5679 xf86CrtcPtr crtc = config->crtc[i]; 5680 int w, h; 5681 5682 if (!crtc->enabled) 5683 continue; 5684 5685 w = crtc->desiredX + crtc->desiredMode.HDisplay; 5686 if (w > width) 5687 width = w; 5688 h = crtc->desiredY + crtc->desiredMode.VDisplay; 5689 if (h > height) 5690 height = h; 5691 } 5692 5693 /* Prefer the native panel size if any */ 5694 if (!width || !height) { 5695 for (i = 0; i < sna->mode.num_real_output; i++) { 5696 xf86OutputPtr output = config->output[i]; 5697 struct sna_output *sna_output = to_sna_output(output); 5698 5699 if (!sna_output->is_panel) 5700 continue; 5701 5702 DBG(("%s: querying panel '%s' for preferred unattached size\n", 5703 __FUNCTION__, output->name)); 5704 5705 if (sna_output_detect(output) != XF86OutputStatusConnected) 5706 continue; 5707 5708 if (sna_output->num_modes == 0) 5709 continue; 5710 5711 width = sna_output->modes[0].hdisplay; 5712 height= sna_output->modes[0].vdisplay; 5713 5714 DBG(("%s: panel '%s' is %dx%d\n", 5715 __FUNCTION__, output->name, width, height)); 5716 break; 5717 } 5718 } 5719 5720 if (!width || !height) { 5721 width = 1024; 5722 height = 768; 5723 } 5724 5725 scrn->display->frameX0 = 0; 5726 scrn->display->frameY0 = 0; 5727 scrn->display->virtualX = width; 5728 scrn->display->virtualY = height; 5729 5730 scrn->virtualX = width; 5731 scrn->virtualY = height; 5732 5733 xf86SetScrnInfoModes(sna->scrn); 5734 DBG(("%s: SetScrnInfoModes = %p\n", __FUNCTION__, scrn->modes)); 5735 return scrn->modes != NULL; 5736} 5737 5738static void 5739sanitize_outputs(struct sna *sna) 5740{ 5741 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn); 5742 int i; 5743 5744 for (i = 0; i < config->num_output; i++) 5745 config->output[i]->crtc = NULL; 5746} 5747 5748static bool has_flip(struct sna *sna) 5749{ 5750 drm_i915_getparam_t gp; 5751 int v; 5752 5753 if (sna->flags & SNA_NO_FLIP) 5754 return false; 5755 5756 v = 0; 5757 5758 VG_CLEAR(gp); 5759 gp.param = I915_PARAM_HAS_PAGEFLIPPING; 5760 gp.value = &v; 5761 5762 if (drmIoctl(sna->kgem.fd, DRM_IOCTL_I915_GETPARAM, &gp)) 5763 return false; 5764 5765 VG(VALGRIND_MAKE_MEM_DEFINED(&v, sizeof(v))); 5766 return v > 0; 5767} 5768 5769static bool has_flip__async(struct sna *sna) 5770{ 5771#define DRM_CAP_ASYNC_PAGE_FLIP 0x7 5772 struct local_get_cap { 5773 uint64_t name; 5774 uint64_t value; 5775 } cap = { DRM_CAP_ASYNC_PAGE_FLIP }; 5776 5777 if (sna->flags & SNA_NO_FLIP) 5778 return false; 5779 5780 if (drmIoctl(sna->kgem.fd, LOCAL_IOCTL_GET_CAP, &cap) == 0) 5781 return cap.value > 0; 5782 5783 return false; 5784} 5785 5786static void 5787probe_capabilities(struct sna *sna) 5788{ 5789 sna->flags &= ~(SNA_HAS_FLIP | SNA_HAS_ASYNC_FLIP); 5790 if (has_flip(sna)) 5791 sna->flags |= SNA_HAS_FLIP; 5792 if (has_flip__async(sna)) 5793 sna->flags |= SNA_HAS_ASYNC_FLIP; 5794 DBG(("%s: page flips? %s, async? %s\n", __FUNCTION__, 5795 sna->flags & SNA_HAS_FLIP ? "enabled" : "disabled", 5796 sna->flags & SNA_HAS_ASYNC_FLIP ? "enabled" : "disabled")); 5797} 5798 5799void 5800sna_crtc_config_notify(ScreenPtr screen) 5801{ 5802 struct sna *sna = to_sna_from_screen(screen); 5803 5804 DBG(("%s(dirty?=%d)\n", __FUNCTION__, sna->mode.dirty)); 5805 if (!sna->mode.dirty) 5806 return; 5807 5808 if (disable_unused_crtc(sna)) { 5809 /* This will have recursed, so simply bail at this point */ 5810 assert(sna->mode.dirty == false); 5811#ifdef RANDR_12_INTERFACE 5812 xf86RandR12TellChanged(screen); 5813#endif 5814 return; 5815 } 5816 5817 update_flush_interval(sna); 5818 sna_cursors_reload(sna); 5819 5820 probe_capabilities(sna); 5821 sna_present_update(sna); 5822 5823 sna->mode.dirty = false; 5824} 5825 5826#if HAS_PIXMAP_SHARING 5827#define sna_setup_provider(scrn) xf86ProviderSetup(scrn, NULL, "Intel") 5828#else 5829#define sna_setup_provider(scrn) 5830#endif 5831 5832bool sna_mode_pre_init(ScrnInfoPtr scrn, struct sna *sna) 5833{ 5834 drmModeResPtr res; 5835 int num_fake = 0; 5836 int i; 5837 5838 if (sna->flags & SNA_IS_HOSTED) { 5839 sna_setup_provider(scrn); 5840 return true; 5841 } 5842 5843 probe_capabilities(sna); 5844 5845 if (!xf86GetOptValInteger(sna->Options, OPTION_VIRTUAL, &num_fake)) 5846 num_fake = 1; 5847 5848 res = drmModeGetResources(sna->kgem.fd); 5849 if (res && 5850 (res->count_crtcs == 0 || 5851 res->count_encoders == 0 || 5852 res->count_connectors == 0)) { 5853 drmModeFreeResources(res); 5854 res = NULL; 5855 } 5856 if (res) { 5857 xf86CrtcConfigPtr xf86_config; 5858 5859 assert(res->count_crtcs); 5860 assert(res->count_connectors); 5861 5862 xf86CrtcConfigInit(scrn, &sna_mode_funcs); 5863 5864 xf86_config = XF86_CRTC_CONFIG_PTR(scrn); 5865 xf86_config->xf86_crtc_notify = sna_crtc_config_notify; 5866 5867 for (i = 0; i < res->count_crtcs; i++) 5868 if (!sna_crtc_add(scrn, res->crtcs[i])) 5869 return false; 5870 5871 sna->mode.num_real_crtc = xf86_config->num_crtc; 5872 5873 sna->mode.num_real_encoder = res->count_encoders; 5874 sna->mode.encoders = res->encoders; 5875 res->encoders = NULL; 5876 5877 for (i = 0; i < res->count_connectors; i++) 5878 if (sna_output_add(sna, res->connectors[i], 0) < 0) 5879 return false; 5880 5881 sna->mode.num_real_output = xf86_config->num_output; 5882 5883 sna->mode.max_crtc_width = res->max_width; 5884 sna->mode.max_crtc_height = res->max_height; 5885 5886 RegionEmpty(&sna->mode.shadow_region); 5887 RegionEmpty(&sna->mode.shadow_cancel); 5888 list_init(&sna->mode.shadow_crtc); 5889 5890 drmModeFreeResources(res); 5891 5892 sna_cursor_pre_init(sna); 5893 sna_backlight_pre_init(sna); 5894 5895 set_size_range(sna); 5896 } else { 5897 if (num_fake == 0) 5898 num_fake = 1; 5899 } 5900 5901 if (!sna_mode_fake_init(sna, num_fake)) 5902 return false; 5903 5904 if (!sna_probe_initial_configuration(sna)) { 5905 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn); 5906 5907 sanitize_outputs(sna); 5908 if (config->num_crtc && config->num_output) { 5909 if (!xf86ReturnOptValBool(config->output[0]->options, 5910 OPTION_PRIMARY, FALSE)) 5911 sort_config_outputs(sna); 5912 xf86InitialConfiguration(scrn, TRUE); 5913 } 5914 } 5915 sort_config_outputs(sna); 5916 5917 sna_setup_provider(scrn); 5918 return scrn->modes != NULL; 5919} 5920 5921bool 5922sna_mode_wants_tear_free(struct sna *sna) 5923{ 5924 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn); 5925 int i; 5926 5927 for (i = 0; i < sna->mode.num_real_output; i++) { 5928 struct sna_output *output = to_sna_output(config->output[i]); 5929 int id = find_property(sna, output, "Panel Self-Refresh"); 5930 if (id !=-1 && output->prop_values[id] != -1) { 5931 DBG(("%s: Panel Self-Refresh detected on %s\n", 5932 __FUNCTION__, config->output[i]->name)); 5933 return true; 5934 } 5935 } 5936 5937 return false; 5938} 5939 5940void 5941sna_mode_set_primary(struct sna *sna) 5942{ 5943#ifdef RANDR_12_INTERFACE 5944 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn); 5945 rrScrPrivPtr rr = rrGetScrPriv(xf86ScrnToScreen(sna->scrn)); 5946 int i; 5947 5948 if (rr == NULL || rr->primaryOutput) 5949 return; 5950 5951 for (i = 0; i < sna->mode.num_real_output; i++) { 5952 xf86OutputPtr output = config->output[i]; 5953 5954 if (!xf86ReturnOptValBool(output->options, OPTION_PRIMARY, FALSE)) 5955 continue; 5956 5957 DBG(("%s: setting PrimaryOutput %s\n", __FUNCTION__, output->name)); 5958 rr->primaryOutput = output->randr_output; 5959 RROutputChanged(rr->primaryOutput, 0); 5960 rr->layoutChanged = TRUE; 5961 break; 5962 } 5963#endif 5964} 5965 5966bool 5967sna_mode_disable(struct sna *sna) 5968{ 5969 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn); 5970 int i; 5971 5972 if (sna->flags & SNA_IS_HOSTED) 5973 return false; 5974 5975 if (!sna->scrn->vtSema) 5976 return false; 5977 5978 /* XXX we will cause previously hidden cursors to be reshown, but 5979 * this should be a rare fixup case for severe fragmentation. 5980 */ 5981 sna_hide_cursors(sna->scrn); 5982 for (i = 0; i < sna->mode.num_real_crtc; i++) 5983 sna_crtc_disable(config->crtc[i]); 5984 assert(sna->mode.front_active == 0); 5985 5986 sna_mode_wakeup(sna); 5987 kgem_clean_scanout_cache(&sna->kgem); 5988 return true; 5989} 5990 5991void 5992sna_mode_enable(struct sna *sna) 5993{ 5994 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn); 5995 int i; 5996 5997 DBG(("%s\n", __FUNCTION__)); 5998 5999 if (sna->flags & SNA_IS_HOSTED) 6000 return; 6001 6002 if (!sna->scrn->vtSema) 6003 return; 6004 6005 for (i = 0; i < sna->mode.num_real_crtc; i++) { 6006 xf86CrtcPtr crtc = config->crtc[i]; 6007 6008 DBG(("%s: crtc[%d].enabled?=%d\n", __FUNCTION__, i, crtc->enabled)); 6009 assert(to_sna_crtc(crtc) != NULL); 6010 if (!crtc->enabled) 6011 continue; 6012 6013 if (crtc->mode.Clock == 0) 6014 continue; 6015 6016 __sna_crtc_set_mode(crtc); 6017 } 6018 6019 update_flush_interval(sna); 6020 sna_show_cursors(sna->scrn); 6021 sna->mode.dirty = false; 6022} 6023 6024void 6025sna_mode_close(struct sna *sna) 6026{ 6027 sna_mode_wakeup(sna); 6028 6029 if (sna->flags & SNA_IS_HOSTED) 6030 return; 6031 6032 sna_mode_reset(sna); 6033 6034 sna_cursor_close(sna); 6035 sna_cursors_fini(sna); 6036 6037 sna_backlight_close(sna); 6038 sna->mode.dirty = false; 6039} 6040 6041void 6042sna_mode_fini(struct sna *sna) 6043{ 6044 free(sna->mode.encoders); 6045} 6046 6047static bool sna_box_intersect(BoxPtr r, const BoxRec *a, const BoxRec *b) 6048{ 6049 r->x1 = a->x1 > b->x1 ? a->x1 : b->x1; 6050 r->x2 = a->x2 < b->x2 ? a->x2 : b->x2; 6051 if (r->x1 >= r->x2) 6052 return false; 6053 6054 r->y1 = a->y1 > b->y1 ? a->y1 : b->y1; 6055 r->y2 = a->y2 < b->y2 ? a->y2 : b->y2; 6056 DBG(("%s: (%d, %d), (%d, %d) intersect (%d, %d), (%d, %d) = (%d, %d), (%d, %d)\n", 6057 __FUNCTION__, 6058 a->x1, a->y1, a->x2, a->y2, 6059 b->x1, b->y1, b->x2, b->y2, 6060 r->x1, r->y1, r->x2, r->y2)); 6061 if (r->y1 >= r->y2) 6062 return false; 6063 6064 return true; 6065} 6066 6067static int sna_box_area(const BoxRec *box) 6068{ 6069 return (int)(box->x2 - box->x1) * (int)(box->y2 - box->y1); 6070} 6071 6072/* 6073 * Return the crtc covering 'box'. If two crtcs cover a portion of 6074 * 'box', then prefer 'desired'. If 'desired' is NULL, then prefer the crtc 6075 * with greater coverage 6076 */ 6077xf86CrtcPtr 6078sna_covering_crtc(struct sna *sna, const BoxRec *box, xf86CrtcPtr desired) 6079{ 6080 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn); 6081 xf86CrtcPtr best_crtc; 6082 int best_coverage, c; 6083 6084 if (sna->flags & SNA_IS_HOSTED) 6085 return NULL; 6086 6087 /* If we do not own the VT, we do not own the CRTC either */ 6088 if (!sna->scrn->vtSema) 6089 return NULL; 6090 6091 DBG(("%s for box=(%d, %d), (%d, %d)\n", 6092 __FUNCTION__, box->x1, box->y1, box->x2, box->y2)); 6093 6094 if (desired == NULL) { 6095 rrScrPrivPtr rr = rrGetScrPriv(xf86ScrnToScreen(sna->scrn)); 6096 if (rr && rr->primaryOutput) { 6097 xf86OutputPtr output = rr->primaryOutput->devPrivate; 6098 DBG(("%s: have PrimaryOutput? %d marking as desired\n", __FUNCTION__, output->crtc != NULL)); 6099 desired = output->crtc; 6100 } 6101 } 6102 if (desired && to_sna_crtc(desired) && to_sna_crtc(desired)->bo) { 6103 BoxRec cover_box; 6104 if (sna_box_intersect(&cover_box, &desired->bounds, box)) { 6105 DBG(("%s: box overlaps desired crtc: (%d, %d), (%d, %d)\n", 6106 __FUNCTION__, 6107 cover_box.x1, cover_box.y1, 6108 cover_box.x2, cover_box.y2)); 6109 return desired; 6110 } 6111 } 6112 6113 best_crtc = NULL; 6114 best_coverage = 0; 6115 for (c = 0; c < sna->mode.num_real_crtc; c++) { 6116 xf86CrtcPtr crtc = config->crtc[c]; 6117 BoxRec cover_box; 6118 int coverage; 6119 6120 assert(to_sna_crtc(crtc)); 6121 6122 /* If the CRTC is off, treat it as not covering */ 6123 if (to_sna_crtc(crtc)->bo == NULL) { 6124 DBG(("%s: crtc %d off, skipping\n", __FUNCTION__, c)); 6125 continue; 6126 } 6127 6128 DBG(("%s: crtc %d: (%d, %d), (%d, %d)\n", 6129 __FUNCTION__, c, 6130 crtc->bounds.x1, crtc->bounds.y1, 6131 crtc->bounds.x2, crtc->bounds.y2)); 6132 if (*(const uint64_t *)box == *(uint64_t *)&crtc->bounds) { 6133 DBG(("%s: box exactly matches crtc [%d]\n", 6134 __FUNCTION__, c)); 6135 return crtc; 6136 } 6137 6138 if (!sna_box_intersect(&cover_box, &crtc->bounds, box)) 6139 continue; 6140 6141 DBG(("%s: box instersects (%d, %d), (%d, %d) of crtc %d\n", 6142 __FUNCTION__, 6143 cover_box.x1, cover_box.y1, 6144 cover_box.x2, cover_box.y2, 6145 c)); 6146 6147 coverage = sna_box_area(&cover_box); 6148 DBG(("%s: box covers %d of crtc %d\n", 6149 __FUNCTION__, coverage, c)); 6150 if (coverage > best_coverage) { 6151 best_crtc = crtc; 6152 best_coverage = coverage; 6153 } 6154 } 6155 DBG(("%s: best crtc = %p, coverage = %d\n", 6156 __FUNCTION__, best_crtc, best_coverage)); 6157 return best_crtc; 6158} 6159 6160#define MI_LOAD_REGISTER_IMM (0x22<<23) 6161 6162static bool sna_emit_wait_for_scanline_hsw(struct sna *sna, 6163 xf86CrtcPtr crtc, 6164 int pipe, int y1, int y2, 6165 bool full_height) 6166{ 6167 uint32_t event; 6168 uint32_t *b; 6169 6170 if (!sna->kgem.has_secure_batches) 6171 return false; 6172 6173 b = kgem_get_batch(&sna->kgem); 6174 sna->kgem.nbatch += 17; 6175 6176 switch (pipe) { 6177 default: assert(0); 6178 case 0: event = 1 << 0; break; 6179 case 1: event = 1 << 8; break; 6180 case 2: event = 1 << 14; break; 6181 } 6182 6183 b[0] = MI_LOAD_REGISTER_IMM | 1; 6184 b[1] = 0x44050; /* DERRMR */ 6185 b[2] = ~event; 6186 b[3] = MI_LOAD_REGISTER_IMM | 1; 6187 b[4] = 0xa188; /* FORCEWAKE_MT */ 6188 b[5] = 2 << 16 | 2; 6189 6190 /* The documentation says that the LOAD_SCAN_LINES command 6191 * always comes in pairs. Don't ask me why. */ 6192 switch (pipe) { 6193 default: assert(0); 6194 case 0: event = 0 << 19; break; 6195 case 1: event = 1 << 19; break; 6196 case 2: event = 4 << 19; break; 6197 } 6198 b[8] = b[6] = MI_LOAD_SCAN_LINES_INCL | event; 6199 b[9] = b[7] = (y1 << 16) | (y2-1); 6200 6201 switch (pipe) { 6202 default: assert(0); 6203 case 0: event = 1 << 0; break; 6204 case 1: event = 1 << 8; break; 6205 case 2: event = 1 << 14; break; 6206 } 6207 b[10] = MI_WAIT_FOR_EVENT | event; 6208 6209 b[11] = MI_LOAD_REGISTER_IMM | 1; 6210 b[12] = 0xa188; /* FORCEWAKE_MT */ 6211 b[13] = 2 << 16; 6212 b[14] = MI_LOAD_REGISTER_IMM | 1; 6213 b[15] = 0x44050; /* DERRMR */ 6214 b[16] = ~0; 6215 6216 sna->kgem.batch_flags |= I915_EXEC_SECURE; 6217 return true; 6218} 6219 6220static bool sna_emit_wait_for_scanline_ivb(struct sna *sna, 6221 xf86CrtcPtr crtc, 6222 int pipe, int y1, int y2, 6223 bool full_height) 6224{ 6225 uint32_t event, *b; 6226 6227 if (!sna->kgem.has_secure_batches) 6228 return false; 6229 6230 assert(y1 >= 0); 6231 assert(y2 > y1); 6232 assert(sna->kgem.mode); 6233 6234 /* Always program one less than the desired value */ 6235 if (--y1 < 0) 6236 y1 = crtc->bounds.y2; 6237 y2--; 6238 6239 switch (pipe) { 6240 default: 6241 assert(0); 6242 case 0: 6243 event = 1 << (full_height ? 3 : 0); 6244 break; 6245 case 1: 6246 event = 1 << (full_height ? 11 : 8); 6247 break; 6248 case 2: 6249 event = 1 << (full_height ? 21 : 14); 6250 break; 6251 } 6252 6253 b = kgem_get_batch(&sna->kgem); 6254 6255 /* Both the LRI and WAIT_FOR_EVENT must be in the same cacheline */ 6256 if (((sna->kgem.nbatch + 6) >> 4) != (sna->kgem.nbatch + 10) >> 4) { 6257 int dw = sna->kgem.nbatch + 6; 6258 dw = ALIGN(dw, 16) - dw; 6259 while (dw--) 6260 *b++ = MI_NOOP; 6261 } 6262 6263 b[0] = MI_LOAD_REGISTER_IMM | 1; 6264 b[1] = 0x44050; /* DERRMR */ 6265 b[2] = ~event; 6266 b[3] = MI_LOAD_REGISTER_IMM | 1; 6267 b[4] = 0xa188; /* FORCEWAKE_MT */ 6268 b[5] = 2 << 16 | 2; 6269 b[6] = MI_LOAD_REGISTER_IMM | 1; 6270 b[7] = 0x70068 + 0x1000 * pipe; 6271 b[8] = (1 << 31) | (1 << 30) | (y1 << 16) | y2; 6272 b[9] = MI_WAIT_FOR_EVENT | event; 6273 b[10] = MI_LOAD_REGISTER_IMM | 1; 6274 b[11] = 0xa188; /* FORCEWAKE_MT */ 6275 b[12] = 2 << 16; 6276 b[13] = MI_LOAD_REGISTER_IMM | 1; 6277 b[14] = 0x44050; /* DERRMR */ 6278 b[15] = ~0; 6279 6280 sna->kgem.nbatch = b - sna->kgem.batch + 16; 6281 6282 sna->kgem.batch_flags |= I915_EXEC_SECURE; 6283 return true; 6284} 6285 6286static bool sna_emit_wait_for_scanline_gen6(struct sna *sna, 6287 xf86CrtcPtr crtc, 6288 int pipe, int y1, int y2, 6289 bool full_height) 6290{ 6291 uint32_t *b; 6292 uint32_t event; 6293 6294 if (!sna->kgem.has_secure_batches) 6295 return false; 6296 6297 assert(y1 >= 0); 6298 assert(y2 > y1); 6299 assert(sna->kgem.mode == KGEM_RENDER); 6300 6301 /* Always program one less than the desired value */ 6302 if (--y1 < 0) 6303 y1 = crtc->bounds.y2; 6304 y2--; 6305 6306 /* The scanline granularity is 3 bits */ 6307 y1 &= ~7; 6308 y2 &= ~7; 6309 if (y2 == y1) 6310 return false; 6311 6312 event = 1 << (3*full_height + pipe*8); 6313 6314 b = kgem_get_batch(&sna->kgem); 6315 sna->kgem.nbatch += 16; 6316 6317 b[0] = MI_LOAD_REGISTER_IMM | 1; 6318 b[1] = 0x44050; /* DERRMR */ 6319 b[2] = ~event; 6320 b[3] = MI_LOAD_REGISTER_IMM | 1; 6321 b[4] = 0x4f100; /* magic */ 6322 b[5] = (1 << 31) | (1 << 30) | pipe << 29 | (y1 << 16) | y2; 6323 b[6] = MI_LOAD_REGISTER_IMM | 1; 6324 b[7] = 0x2050; /* PSMI_CTL(rcs) */ 6325 b[8] = 1 << 16 | 1; 6326 b[9] = MI_WAIT_FOR_EVENT | event; 6327 b[10] = MI_LOAD_REGISTER_IMM | 1; 6328 b[11] = 0x2050; /* PSMI_CTL(rcs) */ 6329 b[12] = 1 << 16; 6330 b[13] = MI_LOAD_REGISTER_IMM | 1; 6331 b[14] = 0x44050; /* DERRMR */ 6332 b[15] = ~0; 6333 6334 sna->kgem.batch_flags |= I915_EXEC_SECURE; 6335 return true; 6336} 6337 6338static bool sna_emit_wait_for_scanline_gen4(struct sna *sna, 6339 xf86CrtcPtr crtc, 6340 int pipe, int y1, int y2, 6341 bool full_height) 6342{ 6343 uint32_t event; 6344 uint32_t *b; 6345 6346 if (pipe == 0) { 6347 if (full_height) 6348 event = MI_WAIT_FOR_PIPEA_SVBLANK; 6349 else 6350 event = MI_WAIT_FOR_PIPEA_SCAN_LINE_WINDOW; 6351 } else { 6352 if (full_height) 6353 event = MI_WAIT_FOR_PIPEB_SVBLANK; 6354 else 6355 event = MI_WAIT_FOR_PIPEB_SCAN_LINE_WINDOW; 6356 } 6357 6358 b = kgem_get_batch(&sna->kgem); 6359 sna->kgem.nbatch += 5; 6360 6361 /* The documentation says that the LOAD_SCAN_LINES command 6362 * always comes in pairs. Don't ask me why. */ 6363 b[2] = b[0] = MI_LOAD_SCAN_LINES_INCL | pipe << 20; 6364 b[3] = b[1] = (y1 << 16) | (y2-1); 6365 b[4] = MI_WAIT_FOR_EVENT | event; 6366 6367 return true; 6368} 6369 6370static bool sna_emit_wait_for_scanline_gen2(struct sna *sna, 6371 xf86CrtcPtr crtc, 6372 int pipe, int y1, int y2, 6373 bool full_height) 6374{ 6375 uint32_t *b; 6376 6377 /* 6378 * Pre-965 doesn't have SVBLANK, so we need a bit 6379 * of extra time for the blitter to start up and 6380 * do its job for a full height blit 6381 */ 6382 if (full_height) 6383 y2 -= 2; 6384 6385 b = kgem_get_batch(&sna->kgem); 6386 sna->kgem.nbatch += 5; 6387 6388 /* The documentation says that the LOAD_SCAN_LINES command 6389 * always comes in pairs. Don't ask me why. */ 6390 b[2] = b[0] = MI_LOAD_SCAN_LINES_INCL | pipe << 20; 6391 b[3] = b[1] = (y1 << 16) | (y2-1); 6392 b[4] = MI_WAIT_FOR_EVENT | 1 << (1 + 4*pipe); 6393 6394 return true; 6395} 6396 6397bool 6398sna_wait_for_scanline(struct sna *sna, 6399 PixmapPtr pixmap, 6400 xf86CrtcPtr crtc, 6401 const BoxRec *clip) 6402{ 6403 bool full_height; 6404 int y1, y2, pipe; 6405 bool ret; 6406 6407 assert(crtc != NULL); 6408 assert(to_sna_crtc(crtc) != NULL); 6409 assert(to_sna_crtc(crtc)->bo != NULL); 6410 assert(pixmap == sna->front); 6411 6412 if (sna->flags & SNA_NO_VSYNC) 6413 return false; 6414 6415 /* 6416 * Make sure we don't wait for a scanline that will 6417 * never occur 6418 */ 6419 y1 = clip->y1 - crtc->bounds.y1; 6420 if (y1 < 0) 6421 y1 = 0; 6422 y2 = clip->y2 - crtc->bounds.y1; 6423 if (y2 > crtc->bounds.y2 - crtc->bounds.y1) 6424 y2 = crtc->bounds.y2 - crtc->bounds.y1; 6425 DBG(("%s: clipped range = %d, %d\n", __FUNCTION__, y1, y2)); 6426 if (y2 <= y1 + 4) 6427 return false; 6428 6429 full_height = y1 == 0 && y2 == crtc->bounds.y2 - crtc->bounds.y1; 6430 6431 if (crtc->mode.Flags & V_INTERLACE) { 6432 /* DSL count field lines */ 6433 y1 /= 2; 6434 y2 /= 2; 6435 } 6436 6437 pipe = sna_crtc_to_pipe(crtc); 6438 DBG(("%s: pipe=%d, y1=%d, y2=%d, full_height?=%d\n", 6439 __FUNCTION__, pipe, y1, y2, full_height)); 6440 6441 if (sna->kgem.gen >= 0110) 6442 ret = false; 6443 else if (sna->kgem.gen == 0101) 6444 ret = false; /* chv, vsync method unknown */ 6445 else if (sna->kgem.gen >= 075) 6446 ret = sna_emit_wait_for_scanline_hsw(sna, crtc, pipe, y1, y2, full_height); 6447 else if (sna->kgem.gen == 071) 6448 ret = false; /* vlv, vsync method unknown */ 6449 else if (sna->kgem.gen >= 070) 6450 ret = sna_emit_wait_for_scanline_ivb(sna, crtc, pipe, y1, y2, full_height); 6451 else if (sna->kgem.gen >= 060) 6452 ret =sna_emit_wait_for_scanline_gen6(sna, crtc, pipe, y1, y2, full_height); 6453 else if (sna->kgem.gen >= 040) 6454 ret = sna_emit_wait_for_scanline_gen4(sna, crtc, pipe, y1, y2, full_height); 6455 else 6456 ret = sna_emit_wait_for_scanline_gen2(sna, crtc, pipe, y1, y2, full_height); 6457 6458 return ret; 6459} 6460 6461void sna_mode_check(struct sna *sna) 6462{ 6463 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn); 6464 int i; 6465 6466 if (sna->flags & SNA_IS_HOSTED) 6467 return; 6468 6469 DBG(("%s\n", __FUNCTION__)); 6470 6471 /* Validate CRTC attachments and force consistency upon the kernel */ 6472 for (i = 0; i < sna->mode.num_real_crtc; i++) { 6473 xf86CrtcPtr crtc = config->crtc[i]; 6474 struct sna_crtc *sna_crtc = to_sna_crtc(crtc); 6475 struct drm_mode_crtc mode; 6476 uint32_t expected[2]; 6477 6478 assert(sna_crtc); 6479 6480#if XF86_CRTC_VERSION >= 3 6481 assert(sna_crtc->bo == NULL || crtc->active); 6482#endif 6483 expected[0] = sna_crtc->bo ? fb_id(sna_crtc->bo) : 0; 6484 expected[1] = sna_crtc->flip_bo ? fb_id(sna_crtc->flip_bo) : -1; 6485 6486 VG_CLEAR(mode); 6487 mode.crtc_id = sna_crtc->id; 6488 if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETCRTC, &mode)) 6489 continue; 6490 6491 DBG(("%s: crtc=%d, valid?=%d, fb attached?=%d, expected=(%d or %d)\n", 6492 __FUNCTION__, 6493 mode.crtc_id, mode.mode_valid, 6494 mode.fb_id, expected[0], expected[1])); 6495 6496 if (mode.fb_id != expected[0] && mode.fb_id != expected[1]) { 6497 xf86DrvMsg(crtc->scrn->scrnIndex, X_ERROR, 6498 "%s: invalid state found on pipe %d, disabling CRTC:%d\n", 6499 __FUNCTION__, sna_crtc->pipe, sna_crtc->id); 6500 sna_crtc_disable(crtc); 6501 } 6502 } 6503 6504 for (i = 0; i < config->num_output; i++) { 6505 xf86OutputPtr output = config->output[i]; 6506 struct sna_output *sna_output; 6507 6508 if (output->crtc) 6509 continue; 6510 6511 sna_output = to_sna_output(output); 6512 if (sna_output == NULL) 6513 continue; 6514 6515 sna_output->dpms_mode = DPMSModeOff; 6516 } 6517 6518 update_flush_interval(sna); 6519} 6520 6521static bool 6522sna_crtc_hide_planes(struct sna *sna, struct sna_crtc *crtc) 6523{ 6524#define LOCAL_IOCTL_MODE_SETPLANE DRM_IOWR(0xB7, struct local_mode_set_plane) 6525 struct local_mode_set_plane { 6526 uint32_t plane_id; 6527 uint32_t crtc_id; 6528 uint32_t fb_id; /* fb object contains surface format type */ 6529 uint32_t flags; 6530 6531 /* Signed dest location allows it to be partially off screen */ 6532 int32_t crtc_x, crtc_y; 6533 uint32_t crtc_w, crtc_h; 6534 6535 /* Source values are 16.16 fixed point */ 6536 uint32_t src_x, src_y; 6537 uint32_t src_h, src_w; 6538 } s; 6539 6540 if (crtc->primary.id == 0) 6541 return false; 6542 6543 memset(&s, 0, sizeof(s)); 6544 s.plane_id = crtc->primary.id; 6545 if (drmIoctl(sna->kgem.fd, LOCAL_IOCTL_MODE_SETPLANE, &s)) 6546 return false; 6547 6548 s.plane_id = crtc->sprite.id; 6549 (void)drmIoctl(sna->kgem.fd, LOCAL_IOCTL_MODE_SETPLANE, &s); 6550 6551 __sna_crtc_disable(sna, crtc); 6552 return true; 6553} 6554 6555void sna_mode_reset(struct sna *sna) 6556{ 6557 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn); 6558 int i; 6559 6560 if (sna->flags & SNA_IS_HOSTED) 6561 return; 6562 6563 DBG(("%s\n", __FUNCTION__)); 6564 6565 sna_hide_cursors(sna->scrn); 6566 for (i = 0; i < sna->mode.num_real_crtc; i++) 6567 if (!sna_crtc_hide_planes(sna, to_sna_crtc(config->crtc[i]))) 6568 sna_crtc_disable(config->crtc[i]); 6569 assert(sna->mode.front_active == 0); 6570 6571 for (i = 0; i < sna->mode.num_real_crtc; i++) { 6572 struct sna_crtc *sna_crtc = to_sna_crtc(config->crtc[i]); 6573 6574 assert(sna_crtc != NULL); 6575 sna_crtc->dpms_mode = -1; 6576 6577 /* Force the rotation property to be reset on next use */ 6578 rotation_reset(&sna_crtc->primary); 6579 rotation_reset(&sna_crtc->sprite); 6580 } 6581 6582 /* VT switching, likely to be fbcon so make the backlight usable */ 6583 for (i = 0; i < sna->mode.num_real_output; i++) { 6584 struct sna_output *sna_output = to_sna_output(config->output[i]); 6585 6586 assert(sna_output != NULL); 6587 if (sna_output->dpms_mode != DPMSModeOff) 6588 continue; 6589 6590 if (!sna_output->backlight.iface) 6591 continue; 6592 6593 sna_output_backlight_set(sna_output, 6594 sna_output->backlight_active_level); 6595 } 6596 6597 /* drain the event queue */ 6598 sna_mode_wakeup(sna); 6599} 6600 6601static void transformed_box(BoxRec *box, xf86CrtcPtr crtc) 6602{ 6603 box->x1 -= crtc->filter_width >> 1; 6604 box->x2 += crtc->filter_width >> 1; 6605 box->y1 -= crtc->filter_height >> 1; 6606 box->y2 += crtc->filter_height >> 1; 6607 6608 pixman_f_transform_bounds(&crtc->f_framebuffer_to_crtc, box); 6609 6610 if (box->x1 < 0) 6611 box->x1 = 0; 6612 if (box->y1 < 0) 6613 box->y1 = 0; 6614 if (box->x2 > crtc->mode.HDisplay) 6615 box->x2 = crtc->mode.HDisplay; 6616 if (box->y2 > crtc->mode.VDisplay) 6617 box->y2 = crtc->mode.VDisplay; 6618} 6619 6620inline static DrawablePtr crtc_source(xf86CrtcPtr crtc, int16_t *sx, int16_t *sy) 6621{ 6622 struct sna_crtc *sna_crtc = to_sna_crtc(crtc); 6623 if (sna_crtc->slave_pixmap) { 6624 DBG(("%s: using slave pixmap=%ld, offset (%d, %d)\n", 6625 __FUNCTION__, 6626 sna_crtc->slave_pixmap->drawable.serialNumber, 6627 -crtc->x, -crtc->y)); 6628 *sx = -crtc->x; 6629 *sy = -crtc->y; 6630 return &sna_crtc->slave_pixmap->drawable; 6631 } else { 6632 DBG(("%s: using Screen pixmap=%ld\n", 6633 __FUNCTION__, 6634 to_sna(crtc->scrn)->front->drawable.serialNumber)); 6635 *sx = *sy = 0; 6636 return &to_sna(crtc->scrn)->front->drawable; 6637 } 6638} 6639 6640static void 6641sna_crtc_redisplay__fallback(xf86CrtcPtr crtc, RegionPtr region, struct kgem_bo *bo) 6642{ 6643 int16_t sx, sy; 6644 struct sna *sna = to_sna(crtc->scrn); 6645 ScreenPtr screen = sna->scrn->pScreen; 6646 DrawablePtr draw = crtc_source(crtc, &sx, &sy); 6647 PictFormatPtr format; 6648 PicturePtr src, dst; 6649 PixmapPtr pixmap; 6650 int depth, error; 6651 void *ptr; 6652 6653 DBG(("%s: compositing transformed damage boxes, target handle=%d\n", __FUNCTION__, bo->handle)); 6654 6655 error = sna_render_format_for_depth(draw->depth); 6656 depth = PIXMAN_FORMAT_DEPTH(error); 6657 format = PictureMatchFormat(screen, depth, error); 6658 if (format == NULL) { 6659 DBG(("%s: can't find format for depth=%d [%08x]\n", 6660 __FUNCTION__, depth, error)); 6661 return; 6662 } 6663 6664 DBG(("%s: dst format=%08x, depth=%d, bpp=%d, pitch=%d, size=%dx%d\n", 6665 __FUNCTION__, format->format, depth, draw->bitsPerPixel, 6666 bo->pitch, crtc->mode.HDisplay, crtc->mode.VDisplay)); 6667 6668 ptr = kgem_bo_map__gtt(&sna->kgem, bo); 6669 if (ptr == NULL) 6670 return; 6671 6672 pixmap = sna_pixmap_create_unattached(screen, 0, 0, depth); 6673 if (pixmap == NullPixmap) 6674 return; 6675 6676 if (!screen->ModifyPixmapHeader(pixmap, 6677 crtc->mode.HDisplay, crtc->mode.VDisplay, 6678 depth, draw->bitsPerPixel, 6679 bo->pitch, ptr)) 6680 goto free_pixmap; 6681 6682 src = CreatePicture(None, draw, format, 6683 0, NULL, serverClient, &error); 6684 if (!src) 6685 goto free_pixmap; 6686 6687 error = SetPictureTransform(src, &crtc->crtc_to_framebuffer); 6688 if (error) 6689 goto free_src; 6690 6691 if (crtc->filter && crtc->transform_in_use) 6692 SetPicturePictFilter(src, crtc->filter, 6693 crtc->params, crtc->nparams); 6694 6695 dst = CreatePicture(None, &pixmap->drawable, format, 6696 0, NULL, serverClient, &error); 6697 if (!dst) 6698 goto free_src; 6699 6700 kgem_bo_sync__gtt(&sna->kgem, bo); 6701 6702 if (sigtrap_get() == 0) { /* paranoia */ 6703 const BoxRec *b = region_rects(region); 6704 int n = region_num_rects(region); 6705 do { 6706 BoxRec box; 6707 6708 box = *b++; 6709 transformed_box(&box, crtc); 6710 6711 DBG(("%s: (%d, %d)x(%d, %d) -> (%d, %d), (%d, %d)\n", 6712 __FUNCTION__, 6713 b[-1].x1, b[-1].y1, b[-1].x2-b[-1].x1, b[-1].y2-b[-1].y1, 6714 box.x1, box.y1, box.x2, box.y2)); 6715 6716 fbComposite(PictOpSrc, src, NULL, dst, 6717 box.x1 + sx, box.y1 + sy, 6718 0, 0, 6719 box.x1, box.y1, 6720 box.x2 - box.x1, box.y2 - box.y1); 6721 } while (--n); 6722 sigtrap_put(); 6723 } 6724 6725 FreePicture(dst, None); 6726free_src: 6727 FreePicture(src, None); 6728free_pixmap: 6729 screen->DestroyPixmap(pixmap); 6730} 6731 6732static void 6733sna_crtc_redisplay__composite(xf86CrtcPtr crtc, RegionPtr region, struct kgem_bo *bo) 6734{ 6735 int16_t sx, sy; 6736 struct sna *sna = to_sna(crtc->scrn); 6737 ScreenPtr screen = crtc->scrn->pScreen; 6738 DrawablePtr draw = crtc_source(crtc, &sx, &sy); 6739 struct sna_composite_op tmp; 6740 PictFormatPtr format; 6741 PicturePtr src, dst; 6742 PixmapPtr pixmap; 6743 const BoxRec *b; 6744 int n, depth, error; 6745 6746 DBG(("%s: compositing transformed damage boxes\n", __FUNCTION__)); 6747 6748 error = sna_render_format_for_depth(draw->depth); 6749 depth = PIXMAN_FORMAT_DEPTH(error); 6750 format = PictureMatchFormat(screen, depth, error); 6751 if (format == NULL) { 6752 DBG(("%s: can't find format for depth=%d [%08x]\n", 6753 __FUNCTION__, depth, error)); 6754 return; 6755 } 6756 6757 DBG(("%s: dst format=%08x, depth=%d, bpp=%d, pitch=%d, size=%dx%d\n", 6758 __FUNCTION__, format->format, depth, draw->bitsPerPixel, 6759 bo->pitch, crtc->mode.HDisplay, crtc->mode.VDisplay)); 6760 6761 pixmap = sna_pixmap_create_unattached(screen, 0, 0, depth); 6762 if (pixmap == NullPixmap) 6763 return; 6764 6765 if (!screen->ModifyPixmapHeader(pixmap, 6766 crtc->mode.HDisplay, crtc->mode.VDisplay, 6767 depth, draw->bitsPerPixel, 6768 bo->pitch, NULL)) 6769 goto free_pixmap; 6770 6771 if (!sna_pixmap_attach_to_bo(pixmap, kgem_bo_reference(bo))) { 6772 kgem_bo_destroy(&sna->kgem, bo); 6773 goto free_pixmap; 6774 } 6775 6776 src = CreatePicture(None, draw, format, 6777 0, NULL, serverClient, &error); 6778 if (!src) 6779 goto free_pixmap; 6780 6781 error = SetPictureTransform(src, &crtc->crtc_to_framebuffer); 6782 if (error) 6783 goto free_src; 6784 6785 if (crtc->filter && crtc->transform_in_use) 6786 SetPicturePictFilter(src, crtc->filter, 6787 crtc->params, crtc->nparams); 6788 6789 dst = CreatePicture(None, &pixmap->drawable, format, 6790 0, NULL, serverClient, &error); 6791 if (!dst) 6792 goto free_src; 6793 6794 ValidatePicture(src); 6795 ValidatePicture(dst); 6796 6797 if (!sna->render.composite(sna, 6798 PictOpSrc, src, NULL, dst, 6799 sx, sy, 6800 0, 0, 6801 0, 0, 6802 crtc->mode.HDisplay, crtc->mode.VDisplay, 6803 COMPOSITE_PARTIAL, memset(&tmp, 0, sizeof(tmp)))) { 6804 DBG(("%s: unsupported operation!\n", __FUNCTION__)); 6805 sna_crtc_redisplay__fallback(crtc, region, bo); 6806 goto free_dst; 6807 } 6808 6809 n = region_num_rects(region); 6810 b = region_rects(region); 6811 do { 6812 BoxRec box; 6813 6814 box = *b++; 6815 transformed_box(&box, crtc); 6816 6817 DBG(("%s: (%d, %d)x(%d, %d) -> (%d, %d), (%d, %d)\n", 6818 __FUNCTION__, 6819 b[-1].x1, b[-1].y1, b[-1].x2-b[-1].x1, b[-1].y2-b[-1].y1, 6820 box.x1, box.y1, box.x2, box.y2)); 6821 6822 tmp.box(sna, &tmp, &box); 6823 } while (--n); 6824 tmp.done(sna, &tmp); 6825 6826free_dst: 6827 FreePicture(dst, None); 6828free_src: 6829 FreePicture(src, None); 6830free_pixmap: 6831 screen->DestroyPixmap(pixmap); 6832} 6833 6834static void 6835sna_crtc_redisplay(xf86CrtcPtr crtc, RegionPtr region, struct kgem_bo *bo) 6836{ 6837 int16_t tx, ty, sx, sy; 6838 struct sna *sna = to_sna(crtc->scrn); 6839 DrawablePtr draw = crtc_source(crtc, &sx, &sy); 6840 struct sna_pixmap *priv = sna_pixmap((PixmapPtr)draw); 6841 6842 DBG(("%s: crtc %d [pipe=%d], damage (%d, %d), (%d, %d) x %d\n", 6843 __FUNCTION__, to_sna_crtc(crtc)->id, to_sna_crtc(crtc)->pipe, 6844 region->extents.x1, region->extents.y1, 6845 region->extents.x2, region->extents.y2, 6846 region_num_rects(region))); 6847 6848 assert(!wedged(sna)); 6849 6850 if (priv->clear) { 6851 RegionRec whole; 6852 6853 DBG(("%s: clear damage boxes\n", __FUNCTION__)); 6854 6855 if (sna_transform_is_integer_translation(&crtc->crtc_to_framebuffer, 6856 &tx, &ty)) { 6857 RegionTranslate(region, -tx, -ty); 6858 } else { 6859 whole.extents = region->extents; 6860 whole.data = NULL; 6861 transformed_box(&whole.extents, crtc); 6862 region = &whole; 6863 } 6864 if (sna_blt_fill_boxes(sna, GXcopy, 6865 bo, draw->bitsPerPixel, 6866 priv->clear_color, 6867 region_rects(region), 6868 region_num_rects(region))) 6869 return; 6870 } 6871 6872 if (crtc->filter == NULL && 6873 priv->gpu_bo && 6874 priv->cpu_damage == NULL && 6875 sna_transform_is_integer_translation(&crtc->crtc_to_framebuffer, 6876 &tx, &ty)) { 6877 DrawableRec tmp; 6878 6879 DBG(("%s: copy damage boxes\n", __FUNCTION__)); 6880 6881 tmp.width = crtc->mode.HDisplay; 6882 tmp.height = crtc->mode.VDisplay; 6883 tmp.depth = sna->front->drawable.depth; 6884 tmp.bitsPerPixel = sna->front->drawable.bitsPerPixel; 6885 6886 if (sna->render.copy_boxes(sna, GXcopy, 6887 draw, priv->gpu_bo, sx, sy, 6888 &tmp, bo, -tx, -ty, 6889 region_rects(region), region_num_rects(region), 0)) 6890 return; 6891 } 6892 6893 if (can_render(sna)) 6894 sna_crtc_redisplay__composite(crtc, region, bo); 6895 else 6896 sna_crtc_redisplay__fallback(crtc, region, bo); 6897} 6898 6899static void shadow_flip_handler(struct drm_event_vblank *e, 6900 void *data) 6901{ 6902 sna_mode_redisplay(data); 6903} 6904 6905void sna_shadow_set_crtc(struct sna *sna, 6906 xf86CrtcPtr crtc, 6907 struct kgem_bo *bo) 6908{ 6909 struct sna_crtc *sna_crtc = to_sna_crtc(crtc); 6910 struct sna_pixmap *priv; 6911 6912 DBG(("%s: setting shadow override for CRTC:%d to handle=%d\n", 6913 __FUNCTION__, sna_crtc->id, bo->handle)); 6914 6915 assert(sna->flags & SNA_TEAR_FREE); 6916 assert(sna_crtc); 6917 assert(!sna_crtc->transform); 6918 6919 if (sna_crtc->client_bo != bo) { 6920 if (sna_crtc->client_bo) 6921 kgem_bo_destroy(&sna->kgem, sna_crtc->client_bo); 6922 6923 sna_crtc->client_bo = kgem_bo_reference(bo); 6924 sna_crtc_damage(crtc); 6925 } 6926 6927 list_move(&sna_crtc->shadow_link, &sna->mode.shadow_crtc); 6928 sna->mode.shadow_dirty = true; 6929 6930 priv = sna_pixmap(sna->front); 6931 assert(priv->gpu_bo); 6932 priv->move_to_gpu = wait_for_shadow; 6933 priv->move_to_gpu_data = sna; 6934} 6935 6936void sna_shadow_steal_crtcs(struct sna *sna, struct list *list) 6937{ 6938 list_init(list); 6939 while (!list_is_empty(&sna->mode.shadow_crtc)) { 6940 RegionRec sub, *damage; 6941 struct sna_crtc *crtc = 6942 list_first_entry(&sna->mode.shadow_crtc, 6943 struct sna_crtc, 6944 shadow_link); 6945 6946 damage = DamageRegion(sna->mode.shadow_damage); 6947 sub.extents = crtc->base->bounds; 6948 sub.data = NULL; 6949 RegionSubtract(damage, damage, &sub); 6950 6951 list_move(&crtc->shadow_link, list); 6952 } 6953} 6954 6955void sna_shadow_unsteal_crtcs(struct sna *sna, struct list *list) 6956{ 6957 while (!list_is_empty(list)) { 6958 struct sna_crtc *crtc = 6959 list_first_entry(list, 6960 struct sna_crtc, 6961 shadow_link); 6962 assert(crtc->client_bo); 6963 sna_shadow_set_crtc(sna, crtc->base, crtc->client_bo); 6964 } 6965} 6966 6967void sna_shadow_unset_crtc(struct sna *sna, 6968 xf86CrtcPtr crtc) 6969{ 6970 struct sna_crtc *sna_crtc = to_sna_crtc(crtc); 6971 6972 DBG(("%s: clearin shadow override for CRTC:%d\n", 6973 __FUNCTION__, sna_crtc->id)); 6974 6975 if (sna_crtc->client_bo == NULL) 6976 return; 6977 6978 kgem_bo_destroy(&sna->kgem, sna_crtc->client_bo); 6979 sna_crtc->client_bo = NULL; 6980 list_del(&sna_crtc->shadow_link); 6981 sna->mode.shadow_dirty = true; 6982 6983 sna_crtc_damage(crtc); 6984} 6985 6986void sna_mode_redisplay(struct sna *sna) 6987{ 6988 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn); 6989 RegionPtr region; 6990 int i; 6991 6992 if (!sna->mode.shadow_damage) 6993 return; 6994 6995 DBG(("%s: posting shadow damage? %d (flips pending? %d, mode reconfiguration pending? %d)\n", 6996 __FUNCTION__, 6997 !RegionNil(DamageRegion(sna->mode.shadow_damage)), 6998 sna->mode.flip_active, 6999 sna->mode.dirty)); 7000 assert((sna->flags & SNA_IS_HOSTED) == 0); 7001 assert(sna->mode.shadow_active); 7002 7003 if (sna->mode.dirty) 7004 return; 7005 7006 region = DamageRegion(sna->mode.shadow_damage); 7007 if (RegionNil(region)) 7008 return; 7009 7010 DBG(("%s: damage: %dx(%d, %d), (%d, %d)\n", 7011 __FUNCTION__, region_num_rects(region), 7012 region->extents.x1, region->extents.y1, 7013 region->extents.x2, region->extents.y2)); 7014 7015 if (sna->mode.flip_active) { 7016 DamagePtr damage; 7017 7018 damage = sna->mode.shadow_damage; 7019 sna->mode.shadow_damage = NULL; 7020 7021 while (sna->mode.flip_active && sna_mode_wakeup(sna)) 7022 ; 7023 7024 sna->mode.shadow_damage = damage; 7025 } 7026 7027 if (sna->mode.flip_active) 7028 return; 7029 7030 if (wedged(sna) || !sna_pixmap_move_to_gpu(sna->front, MOVE_READ | MOVE_ASYNC_HINT | __MOVE_SCANOUT)) { 7031 DBG(("%s: forcing scanout update using the CPU\n", __FUNCTION__)); 7032 if (!sna_pixmap_move_to_cpu(sna->front, MOVE_READ)) 7033 return; 7034 7035 for (i = 0; i < sna->mode.num_real_crtc; i++) { 7036 xf86CrtcPtr crtc = config->crtc[i]; 7037 struct sna_crtc *sna_crtc = to_sna_crtc(crtc); 7038 RegionRec damage; 7039 7040 assert(sna_crtc != NULL); 7041 if (!sna_crtc->shadow) 7042 continue; 7043 7044 assert(crtc->enabled); 7045 assert(sna_crtc->transform || sna->flags & SNA_TEAR_FREE); 7046 7047 damage.extents = crtc->bounds; 7048 damage.data = NULL; 7049 RegionIntersect(&damage, &damage, region); 7050 if (!box_empty(&damage.extents)) { 7051 struct kgem_bo *bo = NULL; 7052 7053 DBG(("%s: fallback intersects pipe=%d [(%d, %d), (%d, %d)]\n", 7054 __FUNCTION__, sna_crtc->pipe, 7055 damage.extents.x1, damage.extents.y1, 7056 damage.extents.x2, damage.extents.y2)); 7057 7058 if (sna->flags & SNA_TEAR_FREE) { 7059 RegionRec new_damage; 7060 7061 RegionNull(&new_damage); 7062 RegionCopy(&new_damage, &damage); 7063 7064 bo = sna_crtc->client_bo; 7065 if (bo == NULL) { 7066 damage.extents = crtc->bounds; 7067 damage.data = NULL; 7068 bo = kgem_create_2d(&sna->kgem, 7069 crtc->mode.HDisplay, 7070 crtc->mode.VDisplay, 7071 crtc->scrn->bitsPerPixel, 7072 sna_crtc->bo->tiling, 7073 CREATE_SCANOUT); 7074 } else 7075 RegionUnion(&damage, &damage, &sna_crtc->client_damage); 7076 7077 DBG(("%s: TearFree fallback, shadow handle=%d, crtc handle=%d\n", __FUNCTION__, bo->handle, sna_crtc->bo->handle)); 7078 7079 sna_crtc->client_damage = new_damage; 7080 } 7081 7082 if (bo == NULL) 7083 bo = sna_crtc->bo; 7084 sna_crtc_redisplay__fallback(crtc, &damage, bo); 7085 7086 if (bo != sna_crtc->bo) { 7087 struct drm_mode_crtc_page_flip arg; 7088 7089 arg.crtc_id = sna_crtc->id; 7090 arg.fb_id = get_fb(sna, bo, 7091 crtc->mode.HDisplay, 7092 crtc->mode.VDisplay); 7093 7094 arg.user_data = (uintptr_t)sna_crtc; 7095 arg.flags = DRM_MODE_PAGE_FLIP_EVENT; 7096 arg.reserved = 0; 7097 7098 if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_PAGE_FLIP, &arg)) { 7099 if (sna_crtc_flip(sna, sna_crtc, bo, 0, 0)) { 7100 assert(sna_crtc->bo->active_scanout); 7101 assert(sna_crtc->bo->refcnt >= sna_crtc->bo->active_scanout); 7102 sna_crtc->bo->active_scanout--; 7103 kgem_bo_destroy(&sna->kgem, sna_crtc->bo); 7104 7105 sna_crtc->bo = bo; 7106 sna_crtc->bo->active_scanout++; 7107 sna_crtc->client_bo = NULL; 7108 } else { 7109 DBG(("%s: flip [fb=%d] on crtc %d [%d, pipe=%d] failed - %d\n", 7110 __FUNCTION__, arg.fb_id, i, sna_crtc->id, sna_crtc->pipe, errno)); 7111 xf86DrvMsg(sna->scrn->scrnIndex, X_ERROR, 7112 "Page flipping failed, disabling TearFree\n"); 7113 sna->flags &= ~SNA_TEAR_FREE; 7114 7115 damage.extents = crtc->bounds; 7116 damage.data = NULL; 7117 sna_crtc_redisplay__fallback(crtc, &damage, sna_crtc->bo); 7118 7119 kgem_bo_destroy(&sna->kgem, bo); 7120 sna_crtc->client_bo = NULL; 7121 } 7122 } else { 7123 sna->mode.flip_active++; 7124 7125 assert(sna_crtc->flip_bo == NULL); 7126 sna_crtc->flip_handler = shadow_flip_handler; 7127 sna_crtc->flip_data = sna; 7128 sna_crtc->flip_bo = bo; 7129 sna_crtc->flip_bo->active_scanout++; 7130 sna_crtc->flip_serial = sna_crtc->mode_serial; 7131 7132 sna_crtc->client_bo = kgem_bo_reference(sna_crtc->bo); 7133 } 7134 } 7135 } 7136 RegionUninit(&damage); 7137 7138 if (sna_crtc->slave_damage) 7139 DamageEmpty(sna_crtc->slave_damage); 7140 } 7141 7142 RegionEmpty(region); 7143 return; 7144 } 7145 7146 { 7147 struct sna_pixmap *priv; 7148 7149 priv = sna_pixmap(sna->front); 7150 assert(priv != NULL); 7151 7152 if (priv->move_to_gpu) { 7153 if (priv->move_to_gpu == wait_for_shadow && 7154 !sna->mode.shadow_dirty) { 7155 /* No damage written to new scanout 7156 * (backbuffer), ignore redisplay request 7157 * and continue with the current intact 7158 * scanout (frontbuffer). 7159 */ 7160 DBG(("%s: shadow idle, skipping update\n", __FUNCTION__)); 7161 RegionEmpty(region); 7162 return; 7163 } 7164 7165 (void)priv->move_to_gpu(sna, priv, 0); 7166 } 7167 7168 assert(priv->move_to_gpu == NULL); 7169 } 7170 7171 for (i = 0; i < sna->mode.num_real_crtc; i++) { 7172 xf86CrtcPtr crtc = config->crtc[i]; 7173 struct sna_crtc *sna_crtc = to_sna_crtc(crtc); 7174 RegionRec damage; 7175 7176 assert(sna_crtc != NULL); 7177 DBG(("%s: crtc[%d] transformed? %d\n", 7178 __FUNCTION__, i, sna_crtc->transform)); 7179 7180 if (!sna_crtc->transform) 7181 continue; 7182 7183 assert(crtc->enabled); 7184 assert(sna_crtc->bo); 7185 7186 damage.extents = crtc->bounds; 7187 damage.data = NULL; 7188 7189 RegionIntersect(&damage, &damage, region); 7190 DBG(("%s: crtc[%d] damage? %d[%d]: %dx[(%d, %d), (%d, %d)]\n", 7191 __FUNCTION__, i, 7192 !box_empty(&damage.extents), RegionNotEmpty(&damage), 7193 region_num_rects(&damage), 7194 damage.extents.x1, damage.extents.y1, 7195 damage.extents.x2, damage.extents.y2)); 7196 if (!box_empty(&damage.extents)) { 7197 if (sna->flags & SNA_TEAR_FREE) { 7198 struct drm_mode_crtc_page_flip arg; 7199 struct kgem_bo *bo; 7200 7201 RegionUninit(&damage); 7202 damage.extents = crtc->bounds; 7203 damage.data = NULL; 7204 7205 bo = sna_crtc->client_bo; 7206 if (bo == NULL) 7207 bo = kgem_create_2d(&sna->kgem, 7208 crtc->mode.HDisplay, 7209 crtc->mode.VDisplay, 7210 crtc->scrn->bitsPerPixel, 7211 sna_crtc->bo->tiling, 7212 CREATE_SCANOUT); 7213 if (bo == NULL) 7214 goto disable1; 7215 7216 sna_crtc_redisplay(crtc, &damage, bo); 7217 kgem_bo_submit(&sna->kgem, bo); 7218 7219 arg.crtc_id = sna_crtc->id; 7220 arg.fb_id = get_fb(sna, bo, 7221 crtc->mode.HDisplay, 7222 crtc->mode.VDisplay); 7223 if (arg.fb_id == 0) 7224 goto disable1; 7225 7226 arg.user_data = (uintptr_t)sna_crtc; 7227 arg.flags = DRM_MODE_PAGE_FLIP_EVENT; 7228 arg.reserved = 0; 7229 7230 if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_PAGE_FLIP, &arg)) { 7231 if (sna_crtc_flip(sna, sna_crtc, bo, 0, 0)) { 7232 assert(sna_crtc->bo->active_scanout); 7233 assert(sna_crtc->bo->refcnt >= sna_crtc->bo->active_scanout); 7234 sna_crtc->bo->active_scanout--; 7235 kgem_bo_destroy(&sna->kgem, sna_crtc->bo); 7236 7237 sna_crtc->bo = kgem_bo_reference(bo); 7238 sna_crtc->bo->active_scanout++; 7239 sna_crtc->client_bo = kgem_bo_reference(bo); 7240 } else { 7241 BoxRec box; 7242 DrawableRec tmp; 7243 7244 DBG(("%s: flip [fb=%d] on crtc %d [%d, pipe=%d] failed - %d\n", 7245 __FUNCTION__, arg.fb_id, i, sna_crtc->id, sna_crtc->pipe, errno)); 7246 xf86DrvMsg(sna->scrn->scrnIndex, X_ERROR, 7247 "Page flipping failed, disabling TearFree\n"); 7248 sna->flags &= ~SNA_TEAR_FREE; 7249 7250disable1: 7251 box.x1 = 0; 7252 box.y1 = 0; 7253 tmp.width = box.x2 = crtc->mode.HDisplay; 7254 tmp.height = box.y2 = crtc->mode.VDisplay; 7255 tmp.depth = sna->front->drawable.depth; 7256 tmp.bitsPerPixel = sna->front->drawable.bitsPerPixel; 7257 7258 if (!sna->render.copy_boxes(sna, GXcopy, 7259 &sna->front->drawable, bo, 0, 0, 7260 &tmp, sna_crtc->bo, 0, 0, 7261 &box, 1, COPY_LAST)) { 7262 xf86DrvMsg(crtc->scrn->scrnIndex, X_ERROR, 7263 "%s: page flipping failed, disabling CRTC:%d (pipe=%d)\n", 7264 __FUNCTION__, sna_crtc->id, sna_crtc->pipe); 7265 sna_crtc_disable(crtc); 7266 } 7267 7268 kgem_bo_destroy(&sna->kgem, bo); 7269 sna_crtc->client_bo = NULL; 7270 } 7271 continue; 7272 } 7273 sna->mode.flip_active++; 7274 7275 assert(sna_crtc->flip_bo == NULL); 7276 sna_crtc->flip_handler = shadow_flip_handler; 7277 sna_crtc->flip_data = sna; 7278 sna_crtc->flip_bo = bo; 7279 sna_crtc->flip_bo->active_scanout++; 7280 sna_crtc->flip_serial = sna_crtc->mode_serial; 7281 sna_crtc->flip_pending = true; 7282 7283 sna_crtc->client_bo = kgem_bo_reference(sna_crtc->bo); 7284 } else { 7285 sna_crtc_redisplay(crtc, &damage, sna_crtc->bo); 7286 kgem_scanout_flush(&sna->kgem, sna_crtc->bo); 7287 } 7288 } 7289 RegionUninit(&damage); 7290 7291 if (sna_crtc->slave_damage) 7292 DamageEmpty(sna_crtc->slave_damage); 7293 } 7294 7295 if (sna->mode.shadow) { 7296 struct kgem_bo *new = __sna_pixmap_get_bo(sna->front); 7297 struct kgem_bo *old = sna->mode.shadow; 7298 struct drm_mode_crtc_page_flip arg; 7299 uint32_t fb = 0; 7300 7301 DBG(("%s: flipping TearFree outputs, current scanout handle=%d [active?=%d], new handle=%d [active=%d]\n", 7302 __FUNCTION__, old->handle, old->active_scanout, new->handle, new->active_scanout)); 7303 7304 assert(new != old); 7305 assert(new->refcnt); 7306 7307 arg.flags = DRM_MODE_PAGE_FLIP_EVENT; 7308 arg.reserved = 0; 7309 7310 kgem_bo_submit(&sna->kgem, new); 7311 7312 for (i = 0; i < sna->mode.num_real_crtc; i++) { 7313 struct sna_crtc *crtc = config->crtc[i]->driver_private; 7314 struct kgem_bo *flip_bo; 7315 int x, y; 7316 7317 assert(crtc != NULL); 7318 DBG(("%s: crtc %d [%d, pipe=%d] active? %d, transformed? %d\n", 7319 __FUNCTION__, i, crtc->id, crtc->pipe, crtc->bo ? crtc->bo->handle : 0, crtc->transform)); 7320 if (crtc->bo == NULL || crtc->transform) 7321 continue; 7322 7323 assert(config->crtc[i]->enabled); 7324 assert(crtc->dpms_mode <= DPMSModeOn); 7325 assert(crtc->flip_bo == NULL); 7326 7327 arg.crtc_id = crtc->id; 7328 arg.user_data = (uintptr_t)crtc; 7329 7330 if (crtc->client_bo) { 7331 DBG(("%s: apply shadow override bo for CRTC:%d on pipe=%d, handle=%d\n", 7332 __FUNCTION__, crtc->id, crtc->pipe, crtc->client_bo->handle)); 7333 arg.fb_id = get_fb(sna, crtc->client_bo, 7334 crtc->base->mode.HDisplay, 7335 crtc->base->mode.VDisplay); 7336 assert(arg.fb_id != fb); 7337 flip_bo = crtc->client_bo; 7338 x = y = 0; 7339 } else { 7340 if (fb == 0) 7341 fb = get_fb(sna, new, sna->scrn->virtualX, sna->scrn->virtualY); 7342 if (fb == 0) { 7343fixup_shadow: 7344 if (sna_pixmap_move_to_gpu(sna->front, MOVE_READ | MOVE_ASYNC_HINT)) { 7345 BoxRec box; 7346 7347 box.x1 = 0; 7348 box.y1 = 0; 7349 box.x2 = sna->scrn->virtualX; 7350 box.y2 = sna->scrn->virtualY; 7351 if (sna->render.copy_boxes(sna, GXcopy, 7352 &sna->front->drawable, __sna_pixmap_get_bo(sna->front), 0, 0, 7353 &sna->front->drawable, old, 0, 0, 7354 &box, 1, COPY_LAST)) { 7355 kgem_submit(&sna->kgem); 7356 RegionEmpty(region); 7357 } 7358 } 7359 7360 return; 7361 } 7362 7363 arg.fb_id = fb; 7364 flip_bo = new; 7365 x = crtc->base->x; 7366 y = crtc->base->y; 7367 } 7368 7369 if (crtc->bo == flip_bo) 7370 continue; 7371 7372 if (flip_bo->pitch != crtc->bo->pitch || (y << 16 | x) != crtc->offset) { 7373 DBG(("%s: changing pitch (new %d =?= old %d) or offset (new %x =?= old %x)\n", 7374 __FUNCTION__, 7375 flip_bo->pitch, crtc->bo->pitch, 7376 y << 16 | x, crtc->offset)); 7377fixup_flip: 7378 if (sna_crtc_flip(sna, crtc, flip_bo, x, y)) { 7379 assert(flip_bo != crtc->bo); 7380 assert(crtc->bo->active_scanout); 7381 assert(crtc->bo->refcnt >= crtc->bo->active_scanout); 7382 crtc->bo->active_scanout--; 7383 kgem_bo_destroy(&sna->kgem, crtc->bo); 7384 7385 if (crtc->shadow_bo) { 7386 kgem_bo_destroy(&sna->kgem, crtc->shadow_bo); 7387 crtc->shadow_bo = NULL; 7388 } 7389 7390 crtc->bo = kgem_bo_reference(flip_bo); 7391 crtc->bo->active_scanout++; 7392 } else { 7393 xf86DrvMsg(sna->scrn->scrnIndex, X_ERROR, 7394 "Failed to prepare CRTC for page flipping, disabling TearFree\n"); 7395 sna->flags &= ~SNA_TEAR_FREE; 7396 7397 if (sna->mode.flip_active == 0) { 7398 DBG(("%s: abandoning flip attempt\n", __FUNCTION__)); 7399 goto fixup_shadow; 7400 } 7401 7402 xf86DrvMsg(sna->scrn->scrnIndex, X_ERROR, 7403 "%s: page flipping failed, disabling CRTC:%d (pipe=%d)\n", 7404 __FUNCTION__, crtc->id, crtc->pipe); 7405 sna_crtc_disable(crtc->base); 7406 } 7407 continue; 7408 } 7409 7410 if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_PAGE_FLIP, &arg)) { 7411 ERR(("%s: flip [fb=%d] on crtc %d [%d, pipe=%d] failed - %d\n", 7412 __FUNCTION__, arg.fb_id, i, crtc->id, crtc->pipe, errno)); 7413 goto fixup_flip; 7414 } 7415 sna->mode.flip_active++; 7416 7417 assert(crtc->flip_bo == NULL); 7418 crtc->flip_handler = shadow_flip_handler; 7419 crtc->flip_data = sna; 7420 crtc->flip_bo = kgem_bo_reference(flip_bo); 7421 crtc->flip_bo->active_scanout++; 7422 crtc->flip_serial = crtc->mode_serial; 7423 crtc->flip_pending = true; 7424 7425 { 7426 struct drm_i915_gem_busy busy = { flip_bo->handle }; 7427 if (drmIoctl(sna->kgem.fd, DRM_IOCTL_I915_GEM_BUSY, &busy) == 0) { 7428 if (busy.busy) { 7429 int mode = KGEM_RENDER; 7430 if (busy.busy & (0xfffe << 16)) 7431 mode = KGEM_BLT; 7432 DBG(("%s: marking flip bo as busy [%x -> mode=%d]\n", __FUNCTION__, busy.busy, mode)); 7433 kgem_bo_mark_busy(&sna->kgem, flip_bo, mode); 7434 } else 7435 __kgem_bo_clear_busy(flip_bo); 7436 } 7437 } 7438 } 7439 7440 DBG(("%s: flipped %d outputs, shadow active? %d\n", 7441 __FUNCTION__, 7442 sna->mode.flip_active, 7443 sna->mode.shadow ? sna->mode.shadow->handle : 0)); 7444 7445 if (sna->mode.flip_active) { 7446 assert(old == sna->mode.shadow); 7447 assert(old->refcnt >= 1); 7448 set_shadow(sna, region); 7449 } 7450 } else 7451 kgem_submit(&sna->kgem); 7452 7453 RegionEmpty(region); 7454} 7455 7456int sna_mode_wakeup(struct sna *sna) 7457{ 7458 char buffer[1024]; 7459 int len, i; 7460 int ret = 0; 7461 7462again: 7463 /* In order to workaround a kernel bug in not honouring O_NONBLOCK, 7464 * check that the fd is readable before attempting to read the next 7465 * event from drm. 7466 */ 7467 if (!event_pending(sna->kgem.fd)) 7468 return ret; 7469 7470 /* The DRM read semantics guarantees that we always get only 7471 * complete events. 7472 */ 7473 len = read(sna->kgem.fd, buffer, sizeof (buffer)); 7474 if (len < (int)sizeof(struct drm_event)) 7475 return ret; 7476 7477 /* Note that we cannot rely on the passed in struct sna matching 7478 * the struct sna used for the vblank event (in case it was submitted 7479 * by a different ZaphodHead). When processing the event, we must 7480 * ensure that we only use the pointer passed along with the event. 7481 */ 7482 7483 DBG(("%s: len=%d\n", __FUNCTION__, len)); 7484 7485 i = 0; 7486 while (i < len) { 7487 struct drm_event *e = (struct drm_event *)&buffer[i]; 7488 switch (e->type) { 7489 case DRM_EVENT_VBLANK: 7490 if (((uintptr_t)((struct drm_event_vblank *)e)->user_data) & 2) 7491 sna_present_vblank_handler((struct drm_event_vblank *)e); 7492 else 7493 sna_dri2_vblank_handler((struct drm_event_vblank *)e); 7494 break; 7495 case DRM_EVENT_FLIP_COMPLETE: 7496 { 7497 struct drm_event_vblank *vbl = (struct drm_event_vblank *)e; 7498 struct sna_crtc *crtc = (void *)(uintptr_t)vbl->user_data; 7499 7500 /* Beware Zaphod! */ 7501 sna = to_sna(crtc->base->scrn); 7502 7503 crtc->swap.tv_sec = vbl->tv_sec; 7504 crtc->swap.tv_usec = vbl->tv_usec; 7505 crtc->swap.msc = msc64(crtc, vbl->sequence); 7506 crtc->flip_pending = false; 7507 7508 assert(crtc->flip_bo); 7509 assert(crtc->flip_bo->active_scanout); 7510 assert(crtc->flip_bo->refcnt >= crtc->flip_bo->active_scanout); 7511 7512 if (crtc->flip_serial == crtc->mode_serial) { 7513 DBG(("%s: removing handle=%d from scanout, installing handle=%d\n", 7514 __FUNCTION__, crtc->bo->handle, crtc->flip_bo->handle)); 7515 assert(crtc->bo->active_scanout); 7516 assert(crtc->bo->refcnt >= crtc->bo->active_scanout); 7517 crtc->bo->active_scanout--; 7518 kgem_bo_destroy(&sna->kgem, crtc->bo); 7519 7520 if (crtc->shadow_bo) { 7521 kgem_bo_destroy(&sna->kgem, crtc->shadow_bo); 7522 crtc->shadow_bo = NULL; 7523 } 7524 7525 crtc->bo = crtc->flip_bo; 7526 crtc->flip_bo = NULL; 7527 } else { 7528 crtc->flip_bo->active_scanout--; 7529 kgem_bo_destroy(&sna->kgem, crtc->flip_bo); 7530 crtc->flip_bo = NULL; 7531 } 7532 7533 DBG(("%s: flip complete, pending? %d\n", __FUNCTION__, sna->mode.flip_active)); 7534 assert(sna->mode.flip_active); 7535 if (--sna->mode.flip_active == 0) 7536 crtc->flip_handler(vbl, crtc->flip_data); 7537 } 7538 break; 7539 default: 7540 break; 7541 } 7542 i += e->length; 7543 ret++; 7544 } 7545 7546 goto again; 7547} 7548