1/* 2 * Copyright 2008 Kristian Høgsberg 3 * Copyright 2008 Jérôme Glisse 4 * 5 * All Rights Reserved. 6 * 7 * Permission is hereby granted, free of charge, to any person obtaining 8 * a copy of this software and associated documentation files (the 9 * "Software"), to deal in the Software without restriction, including 10 * without limitation on the rights to use, copy, modify, merge, 11 * publish, distribute, sublicense, and/or sell copies of the Software, 12 * and to permit persons to whom the Software is furnished to do so, 13 * subject to the following conditions: 14 * 15 * The above copyright notice and this permission notice (including the 16 * next paragraph) shall be included in all copies or substantial 17 * portions of the Software. 18 * 19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 20 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 21 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 22 * NON-INFRINGEMENT. IN NO EVENT SHALL ATI, VA LINUX SYSTEMS AND/OR 23 * THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 24 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 26 * DEALINGS IN THE SOFTWARE. 27 */ 28#ifdef HAVE_CONFIG_H 29#include "config.h" 30#endif 31 32#include "radeon.h" 33#include "radeon_dri2.h" 34#include "radeon_video.h" 35 36#ifdef DRI2 37 38#include <sys/types.h> 39#include <sys/stat.h> 40#include <fcntl.h> 41#include <errno.h> 42 43#include "radeon_bo_helper.h" 44#include "radeon_version.h" 45 46#include "radeon_bo_gem.h" 47 48#include <list.h> 49#include <xf86Priv.h> 50#include <X11/extensions/dpmsconst.h> 51 52#define FALLBACK_SWAP_DELAY 16 53 54#include "radeon_glamor.h" 55 56typedef DRI2BufferPtr BufferPtr; 57 58struct dri2_buffer_priv { 59 PixmapPtr pixmap; 60 unsigned int attachment; 61 unsigned int refcnt; 62}; 63 64 65struct dri2_window_priv { 66 xf86CrtcPtr crtc; 67 int vblank_delta; 68}; 69 70static DevPrivateKeyRec dri2_window_private_key_rec; 71#define dri2_window_private_key (&dri2_window_private_key_rec) 72 73#define get_dri2_window_priv(window) \ 74 ((struct dri2_window_priv*) \ 75 dixLookupPrivate(&(window)->devPrivates, dri2_window_private_key)) 76 77 78/* Get GEM flink name for a pixmap */ 79static Bool 80radeon_get_flink_name(RADEONEntPtr pRADEONEnt, PixmapPtr pixmap, uint32_t *name) 81{ 82 struct radeon_buffer *bo = radeon_get_pixmap_bo(pixmap); 83 struct drm_gem_flink flink; 84 85 if (bo && !(bo->flags & RADEON_BO_FLAGS_GBM) && 86 radeon_gem_get_kernel_name(bo->bo.radeon, name) == 0) 87 return TRUE; 88 89 if (radeon_get_pixmap_handle(pixmap, &flink.handle)) { 90 if (drmIoctl(pRADEONEnt->fd, DRM_IOCTL_GEM_FLINK, &flink) != 0) 91 return FALSE; 92 93 *name = flink.name; 94 return TRUE; 95 } 96 97 return FALSE; 98} 99 100static BufferPtr 101radeon_dri2_create_buffer2(ScreenPtr pScreen, 102 DrawablePtr drawable, 103 unsigned int attachment, 104 unsigned int format) 105{ 106 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 107 RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); 108 RADEONInfoPtr info = RADEONPTR(pScrn); 109 BufferPtr buffers; 110 struct dri2_buffer_priv *privates; 111 PixmapPtr pixmap; 112 int flags; 113 unsigned front_width; 114 uint32_t tiling = 0; 115 unsigned aligned_width = drawable->width; 116 unsigned height = drawable->height; 117 Bool is_glamor_pixmap = FALSE; 118 int depth; 119 int cpp; 120 121 if (format) { 122 depth = format; 123 124 switch (depth) { 125 case 15: 126 cpp = 2; 127 break; 128 case 24: 129 case 30: 130 cpp = 4; 131 break; 132 default: 133 cpp = depth / 8; 134 } 135 } else { 136 depth = drawable->depth; 137 cpp = drawable->bitsPerPixel / 8; 138 } 139 140 front_width = pScreen->GetScreenPixmap(pScreen)->drawable.width; 141 142 pixmap = NULL; 143 144 if (attachment == DRI2BufferFrontLeft) { 145 uint32_t handle; 146 147 pixmap = get_drawable_pixmap(drawable); 148 if (pScreen != pixmap->drawable.pScreen) 149 pixmap = NULL; 150 else if (info->use_glamor && !radeon_get_pixmap_handle(pixmap, &handle)) { 151 is_glamor_pixmap = TRUE; 152 aligned_width = pixmap->drawable.width; 153 height = pixmap->drawable.height; 154 pixmap = NULL; 155 } else 156 pixmap->refcnt++; 157 } 158 159 if (!pixmap && (is_glamor_pixmap || attachment != DRI2BufferFrontLeft)) { 160 /* tile the back buffer */ 161 switch(attachment) { 162 case DRI2BufferDepth: 163 /* macro is the preferred setting, but the 2D detiling for software 164 * fallbacks in mesa still has issues on some configurations 165 */ 166 if (info->ChipFamily >= CHIP_FAMILY_R600) { 167 if (info->allowColorTiling2D) { 168 flags = RADEON_CREATE_PIXMAP_TILING_MACRO; 169 } else { 170 flags = RADEON_CREATE_PIXMAP_TILING_MICRO; 171 } 172 if (info->ChipFamily >= CHIP_FAMILY_CEDAR) 173 flags |= RADEON_CREATE_PIXMAP_SZBUFFER; 174 } else if (cpp == 2 && info->ChipFamily >= CHIP_FAMILY_R300) 175 flags = RADEON_CREATE_PIXMAP_TILING_MACRO | RADEON_CREATE_PIXMAP_TILING_MICRO_SQUARE; 176 else 177 flags = RADEON_CREATE_PIXMAP_TILING_MACRO | RADEON_CREATE_PIXMAP_TILING_MICRO; 178 if (IS_R200_3D || info->ChipFamily == CHIP_FAMILY_RV200 || info->ChipFamily == CHIP_FAMILY_RADEON) 179 flags |= RADEON_CREATE_PIXMAP_DEPTH; 180 break; 181 case DRI2BufferDepthStencil: 182 /* macro is the preferred setting, but the 2D detiling for software 183 * fallbacks in mesa still has issues on some configurations 184 */ 185 if (info->ChipFamily >= CHIP_FAMILY_R600) { 186 if (info->allowColorTiling2D) { 187 flags = RADEON_CREATE_PIXMAP_TILING_MACRO; 188 } else { 189 flags = RADEON_CREATE_PIXMAP_TILING_MICRO; 190 } 191 if (info->ChipFamily >= CHIP_FAMILY_CEDAR) 192 flags |= RADEON_CREATE_PIXMAP_SZBUFFER; 193 } else if (cpp == 2 && info->ChipFamily >= CHIP_FAMILY_R300) 194 flags = RADEON_CREATE_PIXMAP_TILING_MACRO | RADEON_CREATE_PIXMAP_TILING_MICRO_SQUARE; 195 else 196 flags = RADEON_CREATE_PIXMAP_TILING_MACRO | RADEON_CREATE_PIXMAP_TILING_MICRO; 197 if (IS_R200_3D || info->ChipFamily == CHIP_FAMILY_RV200 || info->ChipFamily == CHIP_FAMILY_RADEON) 198 flags |= RADEON_CREATE_PIXMAP_DEPTH; 199 200 break; 201 case DRI2BufferBackLeft: 202 case DRI2BufferBackRight: 203 case DRI2BufferFrontLeft: 204 case DRI2BufferFrontRight: 205 case DRI2BufferFakeFrontLeft: 206 case DRI2BufferFakeFrontRight: 207 if (info->ChipFamily >= CHIP_FAMILY_R600) { 208 if (info->allowColorTiling2D) { 209 flags = RADEON_CREATE_PIXMAP_TILING_MACRO; 210 } else { 211 flags = RADEON_CREATE_PIXMAP_TILING_MICRO; 212 } 213 } else 214 flags = RADEON_CREATE_PIXMAP_TILING_MACRO; 215 break; 216 default: 217 flags = 0; 218 } 219 220 if (flags & RADEON_CREATE_PIXMAP_TILING_MICRO) 221 tiling |= RADEON_TILING_MICRO; 222 if (flags & RADEON_CREATE_PIXMAP_TILING_MICRO_SQUARE) 223 tiling |= RADEON_TILING_MICRO_SQUARE; 224 if (flags & RADEON_CREATE_PIXMAP_TILING_MACRO) 225 tiling |= RADEON_TILING_MACRO; 226 227 if (aligned_width == front_width) 228 aligned_width = pScrn->virtualX; 229 230 pixmap = (*pScreen->CreatePixmap)(pScreen, 231 aligned_width, 232 height, 233 depth, 234 flags | RADEON_CREATE_PIXMAP_DRI2); 235 } 236 237 if (!pixmap) 238 return NULL; 239 240 buffers = calloc(1, sizeof *buffers); 241 if (!buffers) 242 goto error; 243 244 if (!info->use_glamor) { 245 info->exa_force_create = TRUE; 246 exaMoveInPixmap(pixmap); 247 info->exa_force_create = FALSE; 248 if (!exaGetPixmapDriverPrivate(pixmap)) { 249 /* this happen if pixmap is non accelerable */ 250 goto error; 251 } 252 } else if (is_glamor_pixmap) { 253 pixmap = radeon_glamor_set_pixmap_bo(drawable, pixmap); 254 pixmap->refcnt++; 255 256 /* The copy operation from radeon_glamor_set_pixmap_bo needs to 257 * be flushed to the kernel driver before the client starts 258 * using the pixmap storage for direct rendering. 259 */ 260 radeon_cs_flush_indirect(pScrn); 261 } 262 263 if (!radeon_get_flink_name(pRADEONEnt, pixmap, &buffers->name)) 264 goto error; 265 266 privates = calloc(1, sizeof(struct dri2_buffer_priv)); 267 if (!privates) 268 goto error; 269 270 buffers->attachment = attachment; 271 buffers->pitch = pixmap->devKind; 272 buffers->cpp = cpp; 273 buffers->driverPrivate = privates; 274 buffers->format = format; 275 buffers->flags = 0; /* not tiled */ 276 privates->pixmap = pixmap; 277 privates->attachment = attachment; 278 privates->refcnt = 1; 279 280 return buffers; 281 282error: 283 free(buffers); 284 (*pScreen->DestroyPixmap)(pixmap); 285 return NULL; 286} 287 288static void 289radeon_dri2_destroy_buffer2(ScreenPtr pScreen, 290 DrawablePtr drawable, BufferPtr buffers) 291{ 292 if(buffers) 293 { 294 struct dri2_buffer_priv *private = buffers->driverPrivate; 295 296 /* Trying to free an already freed buffer is unlikely to end well */ 297 if (private->refcnt == 0) { 298 ScrnInfoPtr scrn = xf86ScreenToScrn(pScreen); 299 300 xf86DrvMsg(scrn->scrnIndex, X_WARNING, 301 "Attempted to destroy previously destroyed buffer.\ 302 This is a programming error\n"); 303 return; 304 } 305 306 private->refcnt--; 307 if (private->refcnt == 0) 308 { 309 if (private->pixmap) 310 (*pScreen->DestroyPixmap)(private->pixmap); 311 312 free(buffers->driverPrivate); 313 free(buffers); 314 } 315 } 316} 317 318 319static inline PixmapPtr GetDrawablePixmap(DrawablePtr drawable) 320{ 321 if (drawable->type == DRAWABLE_PIXMAP) 322 return (PixmapPtr)drawable; 323 else { 324 struct _Window *pWin = (struct _Window *)drawable; 325 return drawable->pScreen->GetWindowPixmap(pWin); 326 } 327} 328static void 329radeon_dri2_copy_region2(ScreenPtr pScreen, 330 DrawablePtr drawable, 331 RegionPtr region, 332 BufferPtr dest_buffer, 333 BufferPtr src_buffer) 334{ 335 struct dri2_buffer_priv *src_private = src_buffer->driverPrivate; 336 struct dri2_buffer_priv *dst_private = dest_buffer->driverPrivate; 337 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 338 DrawablePtr src_drawable; 339 DrawablePtr dst_drawable; 340 RegionPtr copy_clip; 341 GCPtr gc; 342 RADEONInfoPtr info = RADEONPTR(pScrn); 343 Bool vsync; 344 Bool translate = FALSE; 345 int off_x = 0, off_y = 0; 346 347 src_drawable = &src_private->pixmap->drawable; 348 dst_drawable = &dst_private->pixmap->drawable; 349 350 if (src_private->attachment == DRI2BufferFrontLeft) { 351 if (drawable->pScreen != pScreen) { 352 src_drawable = DRI2UpdatePrime(drawable, src_buffer); 353 if (!src_drawable) 354 return; 355 } else 356 src_drawable = drawable; 357 } 358 if (dst_private->attachment == DRI2BufferFrontLeft) { 359 if (drawable->pScreen != pScreen) { 360 dst_drawable = DRI2UpdatePrime(drawable, dest_buffer); 361 if (!dst_drawable) 362 return; 363 if (dst_drawable != drawable) 364 translate = TRUE; 365 } else 366 dst_drawable = drawable; 367 } 368 369 if (translate && drawable->type == DRAWABLE_WINDOW) { 370 PixmapPtr pPix = GetDrawablePixmap(drawable); 371 372 off_x = drawable->x - pPix->screen_x; 373 off_y = drawable->y - pPix->screen_y; 374 } 375 gc = GetScratchGC(dst_drawable->depth, pScreen); 376 copy_clip = REGION_CREATE(pScreen, NULL, 0); 377 REGION_COPY(pScreen, copy_clip, region); 378 379 if (translate) { 380 REGION_TRANSLATE(pScreen, copy_clip, off_x, off_y); 381 } 382 383 (*gc->funcs->ChangeClip) (gc, CT_REGION, copy_clip, 0); 384 ValidateGC(dst_drawable, gc); 385 386 vsync = info->accel_state->vsync; 387 /* Driver option "SwapbuffersWait" defines if we vsync DRI2 copy-swaps. */ 388 info->accel_state->vsync = info->swapBuffersWait; 389 info->accel_state->force = TRUE; 390 391 (*gc->ops->CopyArea)(src_drawable, dst_drawable, gc, 392 0, 0, drawable->width, drawable->height, off_x, off_y); 393 394 info->accel_state->force = FALSE; 395 info->accel_state->vsync = vsync; 396 397 FreeScratchGC(gc); 398} 399 400enum DRI2FrameEventType { 401 DRI2_SWAP, 402 DRI2_FLIP, 403 DRI2_WAITMSC, 404}; 405 406typedef struct _DRI2FrameEvent { 407 XID drawable_id; 408 ClientPtr client; 409 enum DRI2FrameEventType type; 410 unsigned frame; 411 xf86CrtcPtr crtc; 412 OsTimerPtr timer; 413 uintptr_t drm_queue_seq; 414 415 /* for swaps & flips only */ 416 DRI2SwapEventPtr event_complete; 417 void *event_data; 418 DRI2BufferPtr front; 419 DRI2BufferPtr back; 420} DRI2FrameEventRec, *DRI2FrameEventPtr; 421 422static int DRI2InfoCnt; 423 424static void 425radeon_dri2_ref_buffer(BufferPtr buffer) 426{ 427 struct dri2_buffer_priv *private = buffer->driverPrivate; 428 private->refcnt++; 429} 430 431static void 432radeon_dri2_unref_buffer(BufferPtr buffer) 433{ 434 if (buffer) { 435 struct dri2_buffer_priv *private = buffer->driverPrivate; 436 DrawablePtr draw = &private->pixmap->drawable; 437 438 radeon_dri2_destroy_buffer2(draw->pScreen, draw, buffer); 439 } 440} 441 442static void 443radeon_dri2_client_state_changed(CallbackListPtr *ClientStateCallback, pointer data, pointer calldata) 444{ 445 NewClientInfoRec *clientinfo = calldata; 446 ClientPtr pClient = clientinfo->client; 447 448 switch (pClient->clientState) { 449 case ClientStateRetained: 450 case ClientStateGone: 451 radeon_drm_abort_client(pClient); 452 break; 453 default: 454 break; 455 } 456} 457 458/* 459 * Get current frame count delta for the specified drawable and CRTC 460 */ 461static uint32_t radeon_get_msc_delta(DrawablePtr pDraw, xf86CrtcPtr crtc) 462{ 463 drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; 464 465 if (pDraw && pDraw->type == DRAWABLE_WINDOW) 466 return drmmode_crtc->interpolated_vblanks + 467 get_dri2_window_priv((WindowPtr)pDraw)->vblank_delta; 468 469 return drmmode_crtc->interpolated_vblanks; 470} 471 472/* 473 * Get current frame count and timestamp of the specified CRTC 474 */ 475static Bool radeon_dri2_get_crtc_msc(xf86CrtcPtr crtc, CARD64 *ust, CARD64 *msc) 476{ 477 drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; 478 479 if (!radeon_crtc_is_enabled(crtc) || 480 drmmode_crtc_get_ust_msc(crtc, ust, msc) != Success) { 481 /* CRTC is not running, extrapolate MSC and timestamp */ 482 ScrnInfoPtr scrn = crtc->scrn; 483 RADEONEntPtr pRADEONEnt = RADEONEntPriv(scrn); 484 CARD64 now, delta_t, delta_seq; 485 486 if (!drmmode_crtc->dpms_last_ust) 487 return FALSE; 488 489 if (drmmode_get_current_ust(pRADEONEnt->fd, &now) != 0) { 490 xf86DrvMsg(scrn->scrnIndex, X_ERROR, 491 "%s cannot get current time\n", __func__); 492 return FALSE; 493 } 494 495 delta_t = now - drmmode_crtc->dpms_last_ust; 496 delta_seq = delta_t * drmmode_crtc->dpms_last_fps; 497 delta_seq /= 1000000; 498 *ust = drmmode_crtc->dpms_last_ust; 499 delta_t = delta_seq * 1000000; 500 delta_t /= drmmode_crtc->dpms_last_fps; 501 *ust += delta_t; 502 *msc = drmmode_crtc->dpms_last_seq; 503 *msc += delta_seq; 504 } 505 506 *msc += drmmode_crtc->interpolated_vblanks; 507 508 return TRUE; 509} 510 511static 512xf86CrtcPtr radeon_dri2_drawable_crtc(DrawablePtr pDraw) 513{ 514 ScreenPtr pScreen = pDraw->pScreen; 515 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 516 xf86CrtcPtr crtc = radeon_pick_best_crtc(pScrn, TRUE, 517 pDraw->x, pDraw->x + pDraw->width, 518 pDraw->y, pDraw->y + pDraw->height); 519 520 if (pDraw->type == DRAWABLE_WINDOW) { 521 struct dri2_window_priv *priv = get_dri2_window_priv((WindowPtr)pDraw); 522 523 if (!crtc) { 524 crtc = priv->crtc; 525 } else if (priv->crtc && priv->crtc != crtc) { 526 CARD64 ust, mscold, mscnew; 527 528 if (radeon_dri2_get_crtc_msc(priv->crtc, &ust, &mscold) && 529 radeon_dri2_get_crtc_msc(crtc, &ust, &mscnew)) 530 priv->vblank_delta += mscold - mscnew; 531 } 532 533 priv->crtc = crtc; 534 } 535 536 return crtc; 537} 538 539static void 540radeon_dri2_flip_event_abort(xf86CrtcPtr crtc, void *event_data) 541{ 542 if (crtc) 543 RADEONPTR(crtc->scrn)->drmmode.dri2_flipping = FALSE; 544 545 free(event_data); 546} 547 548static void 549radeon_dri2_flip_event_handler(xf86CrtcPtr crtc, uint32_t frame, uint64_t usec, 550 void *event_data) 551{ 552 DRI2FrameEventPtr flip = event_data; 553 ScrnInfoPtr scrn = crtc->scrn; 554 unsigned tv_sec, tv_usec; 555 DrawablePtr drawable; 556 ScreenPtr screen; 557 int status; 558 PixmapPtr pixmap; 559 560 status = dixLookupDrawable(&drawable, flip->drawable_id, serverClient, 561 M_ANY, DixWriteAccess); 562 if (status != Success) 563 goto abort; 564 565 frame += radeon_get_msc_delta(drawable, crtc); 566 567 screen = scrn->pScreen; 568 pixmap = screen->GetScreenPixmap(screen); 569 xf86DrvMsgVerb(scrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG, 570 "%s:%d fevent[%p] width %d pitch %d (/4 %d)\n", 571 __func__, __LINE__, flip, pixmap->drawable.width, pixmap->devKind, pixmap->devKind/4); 572 573 tv_sec = usec / 1000000; 574 tv_usec = usec % 1000000; 575 576 /* We assume our flips arrive in order, so we don't check the frame */ 577 switch (flip->type) { 578 case DRI2_SWAP: 579 /* Check for too small vblank count of pageflip completion, taking wraparound 580 * into account. This usually means some defective kms pageflip completion, 581 * causing wrong (msc, ust) return values and possible visual corruption. 582 */ 583 if ((frame < flip->frame) && (flip->frame - frame < 5)) { 584 xf86DrvMsg(scrn->scrnIndex, X_WARNING, 585 "%s: Pageflip completion event has impossible msc %u < target_msc %u\n", 586 __func__, frame, flip->frame); 587 /* All-Zero values signal failure of (msc, ust) timestamping to client. */ 588 frame = tv_sec = tv_usec = 0; 589 } 590 591 DRI2SwapComplete(flip->client, drawable, frame, tv_sec, tv_usec, 592 DRI2_FLIP_COMPLETE, flip->event_complete, 593 flip->event_data); 594 break; 595 default: 596 xf86DrvMsg(scrn->scrnIndex, X_WARNING, "%s: unknown vblank event received\n", __func__); 597 /* Unknown type */ 598 break; 599 } 600 601abort: 602 radeon_dri2_flip_event_abort(crtc, event_data); 603} 604 605static Bool 606radeon_dri2_schedule_flip(xf86CrtcPtr crtc, ClientPtr client, 607 DrawablePtr draw, DRI2BufferPtr front, 608 DRI2BufferPtr back, DRI2SwapEventPtr func, 609 void *data, unsigned int target_msc) 610{ 611 ScrnInfoPtr scrn = crtc->scrn; 612 RADEONInfoPtr info = RADEONPTR(scrn); 613 struct dri2_buffer_priv *back_priv; 614 DRI2FrameEventPtr flip_info; 615 616 flip_info = calloc(1, sizeof(DRI2FrameEventRec)); 617 if (!flip_info) 618 return FALSE; 619 620 flip_info->drawable_id = draw->id; 621 flip_info->client = client; 622 flip_info->type = DRI2_SWAP; 623 flip_info->event_complete = func; 624 flip_info->event_data = data; 625 flip_info->frame = target_msc; 626 flip_info->crtc = crtc; 627 628 xf86DrvMsgVerb(scrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG, 629 "%s:%d fevent[%p]\n", __func__, __LINE__, flip_info); 630 631 /* Page flip the full screen buffer */ 632 back_priv = back->driverPrivate; 633 if (radeon_do_pageflip(scrn, client, back_priv->pixmap, 634 RADEON_DRM_QUEUE_ID_DEFAULT, flip_info, crtc, 635 radeon_dri2_flip_event_handler, 636 radeon_dri2_flip_event_abort, FLIP_VSYNC, 637 target_msc - radeon_get_msc_delta(draw, crtc))) { 638 info->drmmode.dri2_flipping = TRUE; 639 return TRUE; 640 } 641 642 return FALSE; 643} 644 645static Bool 646update_front(DrawablePtr draw, DRI2BufferPtr front) 647{ 648 PixmapPtr pixmap; 649 ScrnInfoPtr scrn = xf86ScreenToScrn(draw->pScreen); 650 RADEONEntPtr pRADEONEnt = RADEONEntPriv(scrn); 651 RADEONInfoPtr info = RADEONPTR(scrn); 652 struct dri2_buffer_priv *priv = front->driverPrivate; 653 654 pixmap = get_drawable_pixmap(draw); 655 pixmap->refcnt++; 656 657 if (!info->use_glamor) 658 exaMoveInPixmap(pixmap); 659 if (!radeon_get_flink_name(pRADEONEnt, pixmap, &front->name)) { 660 (*draw->pScreen->DestroyPixmap)(pixmap); 661 return FALSE; 662 } 663 (*draw->pScreen->DestroyPixmap)(priv->pixmap); 664 front->pitch = pixmap->devKind; 665 front->cpp = pixmap->drawable.bitsPerPixel / 8; 666 priv->pixmap = pixmap; 667 668 return TRUE; 669} 670 671static Bool 672can_exchange(ScrnInfoPtr pScrn, DrawablePtr draw, 673 DRI2BufferPtr front, DRI2BufferPtr back) 674{ 675 struct dri2_buffer_priv *front_priv = front->driverPrivate; 676 struct dri2_buffer_priv *back_priv = back->driverPrivate; 677 PixmapPtr front_pixmap; 678 PixmapPtr back_pixmap = back_priv->pixmap; 679 680 if (!update_front(draw, front)) 681 return FALSE; 682 683 front_pixmap = front_priv->pixmap; 684 685 if (front_pixmap->drawable.width != back_pixmap->drawable.width) 686 return FALSE; 687 688 if (front_pixmap->drawable.height != back_pixmap->drawable.height) 689 return FALSE; 690 691 if (front_pixmap->drawable.bitsPerPixel != back_pixmap->drawable.bitsPerPixel) 692 return FALSE; 693 694 if (front_pixmap->devKind != back_pixmap->devKind) 695 return FALSE; 696 697 return TRUE; 698} 699 700static Bool 701can_flip(xf86CrtcPtr crtc, DrawablePtr draw, 702 DRI2BufferPtr front, DRI2BufferPtr back) 703{ 704 ScrnInfoPtr pScrn = crtc->scrn; 705 RADEONInfoPtr info = RADEONPTR(pScrn); 706 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); 707 int num_crtcs_on; 708 int i; 709 710 if (draw->type != DRAWABLE_WINDOW || 711 !info->allowPageFlip || 712 info->sprites_visible > 0 || 713 info->drmmode.present_flipping || 714 !pScrn->vtSema || 715 !DRI2CanFlip(draw)) 716 return FALSE; 717 718 for (i = 0, num_crtcs_on = 0; i < config->num_crtc; i++) { 719 if (drmmode_crtc_can_flip(config->crtc[i])) 720 num_crtcs_on++; 721 } 722 723 return num_crtcs_on > 0 && can_exchange(pScrn, draw, front, back); 724} 725 726static void 727radeon_dri2_exchange_buffers(DrawablePtr draw, DRI2BufferPtr front, DRI2BufferPtr back) 728{ 729 struct dri2_buffer_priv *front_priv = front->driverPrivate; 730 struct dri2_buffer_priv *back_priv = back->driverPrivate; 731#ifdef USE_GLAMOR 732 RADEONInfoPtr info = RADEONPTR(xf86ScreenToScrn(draw->pScreen)); 733#endif 734 RegionRec region; 735 int tmp; 736 737 region.extents.x1 = region.extents.y1 = 0; 738 region.extents.x2 = front_priv->pixmap->drawable.width; 739 region.extents.y2 = front_priv->pixmap->drawable.height; 740 region.data = NULL; 741 DamageRegionAppend(&front_priv->pixmap->drawable, ®ion); 742 743 /* Swap BO names so DRI works */ 744 tmp = front->name; 745 front->name = back->name; 746 back->name = tmp; 747 748 /* Swap pixmap privates */ 749#ifdef USE_GLAMOR 750 if (info->use_glamor) { 751 struct radeon_pixmap *front_pix, *back_pix; 752 753 front_pix = radeon_get_pixmap_private(front_priv->pixmap); 754 back_pix = radeon_get_pixmap_private(back_priv->pixmap); 755 radeon_set_pixmap_private(front_priv->pixmap, back_pix); 756 radeon_set_pixmap_private(back_priv->pixmap, front_pix); 757 758 radeon_glamor_exchange_buffers(front_priv->pixmap, back_priv->pixmap); 759 } else 760#endif 761 { 762 struct radeon_exa_pixmap_priv driver_priv = *(struct radeon_exa_pixmap_priv*) 763 exaGetPixmapDriverPrivate(front_priv->pixmap); 764 765 *(struct radeon_exa_pixmap_priv*)exaGetPixmapDriverPrivate(front_priv->pixmap) = 766 *(struct radeon_exa_pixmap_priv*)exaGetPixmapDriverPrivate(back_priv->pixmap); 767 *(struct radeon_exa_pixmap_priv*)exaGetPixmapDriverPrivate(back_priv->pixmap) = 768 driver_priv; 769 } 770 771 DamageRegionProcessPending(&front_priv->pixmap->drawable); 772} 773 774static void radeon_dri2_frame_event_abort(xf86CrtcPtr crtc, void *event_data) 775{ 776 DRI2FrameEventPtr event = event_data; 777 778 TimerCancel(event->timer); 779 TimerFree(event->timer); 780 radeon_dri2_unref_buffer(event->front); 781 radeon_dri2_unref_buffer(event->back); 782 free(event); 783} 784 785static void radeon_dri2_frame_event_handler(xf86CrtcPtr crtc, uint32_t seq, 786 uint64_t usec, void *event_data) 787{ 788 DRI2FrameEventPtr event = event_data; 789 ScrnInfoPtr scrn = crtc->scrn; 790 DrawablePtr drawable; 791 int status; 792 int swap_type; 793 BoxRec box; 794 RegionRec region; 795 796 status = dixLookupDrawable(&drawable, event->drawable_id, serverClient, 797 M_ANY, DixWriteAccess); 798 if (status != Success) 799 goto cleanup; 800 801 seq += radeon_get_msc_delta(drawable, crtc); 802 803 switch (event->type) { 804 case DRI2_FLIP: 805 if (can_flip(crtc, drawable, event->front, event->back) && 806 radeon_dri2_schedule_flip(crtc, 807 event->client, 808 drawable, 809 event->front, 810 event->back, 811 event->event_complete, 812 event->event_data, 813 event->frame)) { 814 radeon_dri2_exchange_buffers(drawable, event->front, event->back); 815 break; 816 } 817 /* else fall through to exchange/blit */ 818 case DRI2_SWAP: 819 if (DRI2CanExchange(drawable) && 820 can_exchange(scrn, drawable, event->front, event->back)) { 821 radeon_dri2_exchange_buffers(drawable, event->front, event->back); 822 swap_type = DRI2_EXCHANGE_COMPLETE; 823 } else { 824 box.x1 = 0; 825 box.y1 = 0; 826 box.x2 = drawable->width; 827 box.y2 = drawable->height; 828 REGION_INIT(pScreen, ®ion, &box, 0); 829 radeon_dri2_copy_region2(drawable->pScreen, drawable, ®ion, 830 event->front, event->back); 831 swap_type = DRI2_BLIT_COMPLETE; 832 } 833 834 DRI2SwapComplete(event->client, drawable, seq, usec / 1000000, 835 usec % 1000000, swap_type, event->event_complete, 836 event->event_data); 837 838 break; 839 case DRI2_WAITMSC: 840 DRI2WaitMSCComplete(event->client, drawable, seq, usec / 1000000, 841 usec % 1000000); 842 break; 843 default: 844 /* Unknown type */ 845 xf86DrvMsg(scrn->scrnIndex, X_WARNING, 846 "%s: unknown vblank event received\n", __func__); 847 break; 848 } 849 850cleanup: 851 radeon_dri2_frame_event_abort(crtc, event_data); 852} 853 854/* 855 * This function should be called on a disabled CRTC only (i.e., CRTC 856 * in DPMS-off state). It will calculate the delay necessary to reach 857 * target_msc from present time if the CRTC were running. 858 */ 859static 860CARD32 radeon_dri2_extrapolate_msc_delay(xf86CrtcPtr crtc, CARD64 *target_msc, 861 CARD64 divisor, CARD64 remainder) 862{ 863 drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; 864 ScrnInfoPtr pScrn = crtc->scrn; 865 RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); 866 int nominal_frame_rate = drmmode_crtc->dpms_last_fps; 867 CARD64 last_vblank_ust = drmmode_crtc->dpms_last_ust; 868 uint32_t last_vblank_seq = drmmode_crtc->dpms_last_seq; 869 CARD64 now, target_time, delta_t; 870 int64_t d, delta_seq; 871 int ret; 872 CARD32 d_ms; 873 874 if (!last_vblank_ust) { 875 *target_msc = 0; 876 return FALLBACK_SWAP_DELAY; 877 } 878 ret = drmmode_get_current_ust(pRADEONEnt->fd, &now); 879 if (ret) { 880 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 881 "%s cannot get current time\n", __func__); 882 *target_msc = 0; 883 return FALLBACK_SWAP_DELAY; 884 } 885 delta_seq = *target_msc - last_vblank_seq; 886 delta_seq *= 1000000; 887 target_time = last_vblank_ust; 888 target_time += delta_seq / nominal_frame_rate; 889 d = target_time - now; 890 if (d < 0) { 891 /* we missed the event, adjust target_msc, do the divisor magic */ 892 CARD64 current_msc = last_vblank_seq; 893 894 delta_t = now - last_vblank_ust; 895 delta_seq = delta_t * nominal_frame_rate; 896 current_msc += delta_seq / 1000000; 897 current_msc &= 0xffffffff; 898 if (divisor == 0) { 899 *target_msc = current_msc; 900 d = 0; 901 } else { 902 *target_msc = current_msc - (current_msc % divisor) + remainder; 903 if ((current_msc % divisor) >= remainder) 904 *target_msc += divisor; 905 *target_msc &= 0xffffffff; 906 delta_seq = *target_msc - last_vblank_seq; 907 delta_seq *= 1000000; 908 target_time = last_vblank_ust; 909 target_time += delta_seq / nominal_frame_rate; 910 d = target_time - now; 911 } 912 } 913 /* 914 * convert delay to milliseconds and add margin to prevent the client 915 * from coming back early (due to timer granularity and rounding 916 * errors) and getting the same MSC it just got 917 */ 918 d_ms = (CARD32)d / 1000; 919 if ((CARD32)d - d_ms * 1000 > 0) 920 d_ms += 2; 921 else 922 d_ms++; 923 return d_ms; 924} 925 926/* 927 * Get current interpolated frame count and frame count timestamp, based on 928 * drawable's crtc. 929 */ 930static int radeon_dri2_get_msc(DrawablePtr draw, CARD64 *ust, CARD64 *msc) 931{ 932 xf86CrtcPtr crtc = radeon_dri2_drawable_crtc(draw); 933 934 /* Drawable not displayed, make up a value */ 935 if (!crtc) { 936 *ust = 0; 937 *msc = 0; 938 return TRUE; 939 } 940 941 if (!radeon_dri2_get_crtc_msc(crtc, ust, msc)) 942 return FALSE; 943 944 if (draw && draw->type == DRAWABLE_WINDOW) 945 *msc += get_dri2_window_priv((WindowPtr)draw)->vblank_delta; 946 *msc &= 0xffffffff; 947 return TRUE; 948} 949 950static 951CARD32 radeon_dri2_deferred_event(OsTimerPtr timer, CARD32 now, pointer data) 952{ 953 DRI2FrameEventPtr event_info = (DRI2FrameEventPtr)data; 954 xf86CrtcPtr crtc = event_info->crtc; 955 ScrnInfoPtr scrn; 956 RADEONEntPtr pRADEONEnt; 957 CARD64 drm_now; 958 int ret; 959 CARD64 delta_t, delta_seq, frame; 960 drmmode_crtc_private_ptr drmmode_crtc; 961 962 /* 963 * This is emulated event, so its time is current time, which we 964 * have to get in DRM-compatible form (which is a bit messy given 965 * the information that we have at this point). Can't use now argument 966 * because DRM event time may come from monotonic clock, while 967 * DIX timer facility uses real-time clock. 968 */ 969 if (!event_info->crtc) { 970 ErrorF("%s no crtc\n", __func__); 971 if (event_info->drm_queue_seq) 972 radeon_drm_abort_entry(event_info->drm_queue_seq); 973 else 974 radeon_dri2_frame_event_abort(NULL, data); 975 return 0; 976 } 977 978 scrn = crtc->scrn; 979 pRADEONEnt = RADEONEntPriv(scrn); 980 drmmode_crtc = event_info->crtc->driver_private; 981 ret = drmmode_get_current_ust(pRADEONEnt->fd, &drm_now); 982 if (ret) { 983 xf86DrvMsg(scrn->scrnIndex, X_ERROR, 984 "%s cannot get current time\n", __func__); 985 986 if (event_info->drm_queue_seq) { 987 drmmode_crtc->drmmode->event_context. 988 vblank_handler(pRADEONEnt->fd, 0, 0, 0, 989 (void*)event_info->drm_queue_seq); 990 drmmode_crtc->wait_flip_nesting_level++; 991 radeon_drm_queue_handle_deferred(crtc); 992 993 } else { 994 radeon_dri2_frame_event_handler(crtc, 0, 0, data); 995 } 996 997 return 0; 998 } 999 /* 1000 * calculate the frame number from current time 1001 * that would come from CRTC if it were running 1002 */ 1003 delta_t = drm_now - (CARD64)drmmode_crtc->dpms_last_ust; 1004 delta_seq = delta_t * drmmode_crtc->dpms_last_fps; 1005 delta_seq /= 1000000; 1006 frame = (CARD64)drmmode_crtc->dpms_last_seq + delta_seq; 1007 1008 if (event_info->drm_queue_seq) { 1009 drmmode_crtc->drmmode->event_context. 1010 vblank_handler(pRADEONEnt->fd, frame, drm_now / 1000000, 1011 drm_now % 1000000, 1012 (void*)event_info->drm_queue_seq); 1013 drmmode_crtc->wait_flip_nesting_level++; 1014 radeon_drm_queue_handle_deferred(crtc); 1015 } else { 1016 radeon_dri2_frame_event_handler(crtc, frame, drm_now, data); 1017 } 1018 1019 return 0; 1020} 1021 1022static 1023void radeon_dri2_schedule_event(CARD32 delay, DRI2FrameEventPtr event_info) 1024{ 1025 event_info->timer = TimerSet(NULL, 0, delay, radeon_dri2_deferred_event, 1026 event_info); 1027 if (delay == 0) { 1028 CARD32 now = GetTimeInMillis(); 1029 radeon_dri2_deferred_event(event_info->timer, now, event_info); 1030 } 1031} 1032 1033/* 1034 * Request a DRM event when the requested conditions will be satisfied. 1035 * 1036 * We need to handle the event and ask the server to wake up the client when 1037 * we receive it. 1038 */ 1039static int radeon_dri2_schedule_wait_msc(ClientPtr client, DrawablePtr draw, 1040 CARD64 target_msc, CARD64 divisor, 1041 CARD64 remainder) 1042{ 1043 ScreenPtr screen = draw->pScreen; 1044 ScrnInfoPtr scrn = xf86ScreenToScrn(screen); 1045 DRI2FrameEventPtr wait_info = NULL; 1046 uintptr_t drm_queue_seq = 0; 1047 xf86CrtcPtr crtc = radeon_dri2_drawable_crtc(draw); 1048 uint32_t msc_delta; 1049 uint32_t seq; 1050 CARD64 current_msc; 1051 1052 /* Truncate to match kernel interfaces; means occasional overflow 1053 * misses, but that's generally not a big deal */ 1054 target_msc &= 0xffffffff; 1055 divisor &= 0xffffffff; 1056 remainder &= 0xffffffff; 1057 1058 /* Drawable not visible, return immediately */ 1059 if (!crtc) 1060 goto out_complete; 1061 1062 msc_delta = radeon_get_msc_delta(draw, crtc); 1063 1064 wait_info = calloc(1, sizeof(DRI2FrameEventRec)); 1065 if (!wait_info) 1066 goto out_complete; 1067 1068 wait_info->drawable_id = draw->id; 1069 wait_info->client = client; 1070 wait_info->type = DRI2_WAITMSC; 1071 wait_info->crtc = crtc; 1072 1073 /* 1074 * CRTC is in DPMS off state, calculate wait time from current time, 1075 * target_msc and last vblank time/sequence when CRTC was turned off 1076 */ 1077 if (!radeon_crtc_is_enabled(crtc)) { 1078 CARD32 delay; 1079 target_msc -= msc_delta; 1080 delay = radeon_dri2_extrapolate_msc_delay(crtc, &target_msc, 1081 divisor, remainder); 1082 radeon_dri2_schedule_event(delay, wait_info); 1083 DRI2BlockClient(client, draw); 1084 return TRUE; 1085 } 1086 1087 /* Get current count */ 1088 if (!drmmode_wait_vblank(crtc, DRM_VBLANK_RELATIVE, 0, 0, NULL, &seq)) { 1089 xf86DrvMsg(scrn->scrnIndex, X_WARNING, 1090 "get vblank counter failed: %s\n", strerror(errno)); 1091 goto out_complete; 1092 } 1093 1094 current_msc = seq + msc_delta; 1095 current_msc &= 0xffffffff; 1096 1097 drm_queue_seq = radeon_drm_queue_alloc(crtc, client, RADEON_DRM_QUEUE_ID_DEFAULT, 1098 wait_info, radeon_dri2_frame_event_handler, 1099 radeon_dri2_frame_event_abort, FALSE); 1100 if (drm_queue_seq == RADEON_DRM_QUEUE_ERROR) { 1101 xf86DrvMsg(scrn->scrnIndex, X_WARNING, 1102 "Allocating DRM queue event entry failed.\n"); 1103 goto out_complete; 1104 } 1105 wait_info->drm_queue_seq = drm_queue_seq; 1106 1107 /* 1108 * If divisor is zero, or current_msc is smaller than target_msc, 1109 * we just need to make sure target_msc passes before waking up the 1110 * client. 1111 */ 1112 if (divisor == 0 || current_msc < target_msc) { 1113 /* If target_msc already reached or passed, set it to 1114 * current_msc to ensure we return a reasonable value back 1115 * to the caller. This keeps the client from continually 1116 * sending us MSC targets from the past by forcibly updating 1117 * their count on this call. 1118 */ 1119 if (current_msc >= target_msc) 1120 target_msc = current_msc; 1121 if (!drmmode_wait_vblank(crtc, DRM_VBLANK_ABSOLUTE | DRM_VBLANK_EVENT, 1122 target_msc - msc_delta, drm_queue_seq, NULL, 1123 NULL)) { 1124 xf86DrvMsg(scrn->scrnIndex, X_WARNING, 1125 "get vblank counter failed: %s\n", strerror(errno)); 1126 goto out_complete; 1127 } 1128 1129 DRI2BlockClient(client, draw); 1130 return TRUE; 1131 } 1132 1133 /* 1134 * If we get here, target_msc has already passed or we don't have one, 1135 * so we queue an event that will satisfy the divisor/remainder equation. 1136 */ 1137 target_msc = current_msc - (current_msc % divisor) + remainder - msc_delta; 1138 1139 /* 1140 * If calculated remainder is larger than requested remainder, 1141 * it means we've passed the last point where 1142 * seq % divisor == remainder, so we need to wait for the next time 1143 * that will happen. 1144 */ 1145 if ((current_msc % divisor) >= remainder) 1146 target_msc += divisor; 1147 1148 if (!drmmode_wait_vblank(crtc, DRM_VBLANK_ABSOLUTE | DRM_VBLANK_EVENT, 1149 target_msc, drm_queue_seq, NULL, NULL)) { 1150 xf86DrvMsg(scrn->scrnIndex, X_WARNING, 1151 "get vblank counter failed: %s\n", strerror(errno)); 1152 goto out_complete; 1153 } 1154 1155 DRI2BlockClient(client, draw); 1156 1157 return TRUE; 1158 1159out_complete: 1160 if (wait_info) 1161 radeon_dri2_deferred_event(NULL, 0, wait_info); 1162 else 1163 DRI2WaitMSCComplete(client, draw, 0, 0, 0); 1164 1165 return TRUE; 1166} 1167 1168/* 1169 * ScheduleSwap is responsible for requesting a DRM vblank event for the 1170 * appropriate frame. 1171 * 1172 * In the case of a blit (e.g. for a windowed swap) or buffer exchange, 1173 * the vblank requested can simply be the last queued swap frame + the swap 1174 * interval for the drawable. 1175 * 1176 * In the case of a page flip, we request an event for the last queued swap 1177 * frame + swap interval - 1, since we'll need to queue the flip for the frame 1178 * immediately following the received event. 1179 * 1180 * The client will be blocked if it tries to perform further GL commands 1181 * after queueing a swap, though in the Intel case after queueing a flip, the 1182 * client is free to queue more commands; they'll block in the kernel if 1183 * they access buffers busy with the flip. 1184 * 1185 * When the swap is complete, the driver should call into the server so it 1186 * can send any swap complete events that have been requested. 1187 */ 1188static int radeon_dri2_schedule_swap(ClientPtr client, DrawablePtr draw, 1189 DRI2BufferPtr front, DRI2BufferPtr back, 1190 CARD64 *target_msc, CARD64 divisor, 1191 CARD64 remainder, DRI2SwapEventPtr func, 1192 void *data) 1193{ 1194 ScreenPtr screen = draw->pScreen; 1195 ScrnInfoPtr scrn = xf86ScreenToScrn(screen); 1196 xf86CrtcPtr crtc = radeon_dri2_drawable_crtc(draw); 1197 uint32_t msc_delta; 1198 drmVBlankSeqType type; 1199 uint32_t seq; 1200 int flip = 0; 1201 DRI2FrameEventPtr swap_info = NULL; 1202 uintptr_t drm_queue_seq; 1203 CARD64 current_msc, event_msc; 1204 BoxRec box; 1205 RegionRec region; 1206 1207 /* Truncate to match kernel interfaces; means occasional overflow 1208 * misses, but that's generally not a big deal */ 1209 *target_msc &= 0xffffffff; 1210 divisor &= 0xffffffff; 1211 remainder &= 0xffffffff; 1212 1213 /* radeon_dri2_frame_event_handler will get called some unknown time in the 1214 * future with these buffers. Take a reference to ensure that they won't 1215 * get destroyed before then. 1216 */ 1217 radeon_dri2_ref_buffer(front); 1218 radeon_dri2_ref_buffer(back); 1219 1220 /* either off-screen or CRTC not usable... just complete the swap */ 1221 if (!crtc) 1222 goto blit_fallback; 1223 1224 msc_delta = radeon_get_msc_delta(draw, crtc); 1225 1226 swap_info = calloc(1, sizeof(DRI2FrameEventRec)); 1227 if (!swap_info) 1228 goto blit_fallback; 1229 1230 swap_info->type = DRI2_SWAP; 1231 swap_info->drawable_id = draw->id; 1232 swap_info->client = client; 1233 swap_info->event_complete = func; 1234 swap_info->event_data = data; 1235 swap_info->front = front; 1236 swap_info->back = back; 1237 swap_info->crtc = crtc; 1238 1239 drm_queue_seq = radeon_drm_queue_alloc(crtc, client, RADEON_DRM_QUEUE_ID_DEFAULT, 1240 swap_info, radeon_dri2_frame_event_handler, 1241 radeon_dri2_frame_event_abort, FALSE); 1242 if (drm_queue_seq == RADEON_DRM_QUEUE_ERROR) { 1243 xf86DrvMsg(scrn->scrnIndex, X_WARNING, 1244 "Allocating DRM queue entry failed.\n"); 1245 goto blit_fallback; 1246 } 1247 swap_info->drm_queue_seq = drm_queue_seq; 1248 1249 /* 1250 * CRTC is in DPMS off state, fallback to blit, but calculate 1251 * wait time from current time, target_msc and last vblank 1252 * time/sequence when CRTC was turned off 1253 */ 1254 if (!radeon_crtc_is_enabled(crtc)) { 1255 CARD32 delay; 1256 *target_msc -= msc_delta; 1257 delay = radeon_dri2_extrapolate_msc_delay(crtc, target_msc, 1258 divisor, remainder); 1259 *target_msc += msc_delta; 1260 *target_msc &= 0xffffffff; 1261 radeon_dri2_schedule_event(delay, swap_info); 1262 return TRUE; 1263 } 1264 1265 /* Get current count */ 1266 if (!drmmode_wait_vblank(crtc, DRM_VBLANK_RELATIVE, 0, 0, NULL, &seq)) { 1267 xf86DrvMsg(scrn->scrnIndex, X_WARNING, 1268 "first get vblank counter failed: %s\n", 1269 strerror(errno)); 1270 goto blit_fallback; 1271 } 1272 1273 current_msc = seq + msc_delta; 1274 current_msc &= 0xffffffff; 1275 1276 /* Flips need to be submitted one frame before */ 1277 if (can_flip(crtc, draw, front, back)) { 1278 swap_info->type = DRI2_FLIP; 1279 flip = 1; 1280 } 1281 1282 /* Correct target_msc by 'flip' if swap_info->type == DRI2_FLIP. 1283 * Do it early, so handling of different timing constraints 1284 * for divisor, remainder and msc vs. target_msc works. 1285 */ 1286 if (*target_msc > 0) 1287 *target_msc -= flip; 1288 1289 /* 1290 * If divisor is zero, or current_msc is smaller than target_msc 1291 * we just need to make sure target_msc passes before initiating 1292 * the swap. 1293 */ 1294 if (divisor == 0 || current_msc < *target_msc) { 1295 type = DRM_VBLANK_ABSOLUTE | DRM_VBLANK_EVENT; 1296 /* If non-pageflipping, but blitting/exchanging, we need to use 1297 * DRM_VBLANK_NEXTONMISS to avoid unreliable timestamping later 1298 * on. 1299 */ 1300 if (flip == 0) 1301 type |= DRM_VBLANK_NEXTONMISS; 1302 1303 /* If target_msc already reached or passed, set it to 1304 * current_msc to ensure we return a reasonable value back 1305 * to the caller. This makes swap_interval logic more robust. 1306 */ 1307 if (current_msc >= *target_msc) 1308 *target_msc = current_msc; 1309 1310 if (!drmmode_wait_vblank(crtc, type, *target_msc - msc_delta, 1311 drm_queue_seq, NULL, &seq)) { 1312 xf86DrvMsg(scrn->scrnIndex, X_WARNING, 1313 "divisor 0 get vblank counter failed: %s\n", 1314 strerror(errno)); 1315 goto blit_fallback; 1316 } 1317 1318 *target_msc = seq + flip + msc_delta; 1319 swap_info->frame = *target_msc; 1320 1321 return TRUE; 1322 } 1323 1324 /* 1325 * If we get here, target_msc has already passed or we don't have one, 1326 * and we need to queue an event that will satisfy the divisor/remainder 1327 * equation. 1328 */ 1329 type = DRM_VBLANK_ABSOLUTE | DRM_VBLANK_EVENT; 1330 if (flip == 0) 1331 type |= DRM_VBLANK_NEXTONMISS; 1332 1333 event_msc = current_msc - (current_msc % divisor) + remainder - msc_delta; 1334 1335 /* 1336 * If the calculated deadline vbl.request.sequence is smaller than 1337 * or equal to current_msc, it means we've passed the last point 1338 * when effective onset frame seq could satisfy 1339 * seq % divisor == remainder, so we need to wait for the next time 1340 * this will happen. 1341 1342 * This comparison takes the 1 frame swap delay in pageflipping mode 1343 * into account, as well as a potential DRM_VBLANK_NEXTONMISS delay 1344 * if we are blitting/exchanging instead of flipping. 1345 */ 1346 if (event_msc <= current_msc) 1347 event_msc += divisor; 1348 1349 /* Account for 1 frame extra pageflip delay if flip > 0 */ 1350 event_msc -= flip; 1351 1352 if (!drmmode_wait_vblank(crtc, type, event_msc, drm_queue_seq, NULL, &seq)) { 1353 xf86DrvMsg(scrn->scrnIndex, X_WARNING, 1354 "final get vblank counter failed: %s\n", 1355 strerror(errno)); 1356 goto blit_fallback; 1357 } 1358 1359 /* Adjust returned value for 1 fame pageflip offset of flip > 0 */ 1360 *target_msc = seq + flip + msc_delta; 1361 *target_msc &= 0xffffffff; 1362 swap_info->frame = *target_msc; 1363 1364 return TRUE; 1365 1366blit_fallback: 1367 if (swap_info) { 1368 swap_info->type = DRI2_SWAP; 1369 radeon_dri2_schedule_event(FALLBACK_SWAP_DELAY, swap_info); 1370 } else { 1371 box.x1 = 0; 1372 box.y1 = 0; 1373 box.x2 = draw->width; 1374 box.y2 = draw->height; 1375 REGION_INIT(pScreen, ®ion, &box, 0); 1376 1377 radeon_dri2_copy_region2(draw->pScreen, draw, ®ion, front, back); 1378 1379 DRI2SwapComplete(client, draw, 0, 0, 0, DRI2_BLIT_COMPLETE, func, data); 1380 1381 radeon_dri2_unref_buffer(front); 1382 radeon_dri2_unref_buffer(back); 1383 } 1384 1385 *target_msc = 0; /* offscreen, so zero out target vblank count */ 1386 return TRUE; 1387} 1388 1389 1390Bool 1391radeon_dri2_screen_init(ScreenPtr pScreen) 1392{ 1393 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 1394 RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); 1395 RADEONInfoPtr info = RADEONPTR(pScrn); 1396 DRI2InfoRec dri2_info = { 0 }; 1397 const char *driverNames[2]; 1398 Bool scheduling_works = TRUE; 1399 1400 if (!info->dri2.available) 1401 return FALSE; 1402 1403 info->dri2.device_name = drmGetDeviceNameFromFd(pRADEONEnt->fd); 1404 1405 if ( (info->ChipFamily >= CHIP_FAMILY_TAHITI) ) { 1406 dri2_info.driverName = SI_DRIVER_NAME; 1407 } else if ( (info->ChipFamily >= CHIP_FAMILY_R600) ) { 1408 dri2_info.driverName = R600_DRIVER_NAME; 1409 } else if ( (info->ChipFamily >= CHIP_FAMILY_R300) ) { 1410 dri2_info.driverName = R300_DRIVER_NAME; 1411 } else if ( info->ChipFamily >= CHIP_FAMILY_R200 ) { 1412 dri2_info.driverName = R200_DRIVER_NAME; 1413 } else { 1414 dri2_info.driverName = RADEON_DRIVER_NAME; 1415 } 1416 dri2_info.fd = pRADEONEnt->fd; 1417 dri2_info.deviceName = info->dri2.device_name; 1418 1419 if (info->dri2.pKernelDRMVersion->version_minor < 4) { 1420 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "You need a newer kernel for " 1421 "sync extension\n"); 1422 scheduling_works = FALSE; 1423 } 1424 1425 if (scheduling_works && info->drmmode.count_crtcs > 2) { 1426#ifdef DRM_CAP_VBLANK_HIGH_CRTC 1427 uint64_t cap_value; 1428 1429 if (drmGetCap(pRADEONEnt->fd, DRM_CAP_VBLANK_HIGH_CRTC, &cap_value)) { 1430 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "You need a newer kernel " 1431 "for VBLANKs on CRTC > 1\n"); 1432 scheduling_works = FALSE; 1433 } else if (!cap_value) { 1434 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Your kernel does not " 1435 "handle VBLANKs on CRTC > 1\n"); 1436 scheduling_works = FALSE; 1437 } 1438#else 1439 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "You need to rebuild against a " 1440 "newer libdrm to handle VBLANKs on CRTC > 1\n"); 1441 scheduling_works = FALSE; 1442#endif 1443 } 1444 1445 if (scheduling_works) { 1446 dri2_info.ScheduleSwap = radeon_dri2_schedule_swap; 1447 dri2_info.GetMSC = radeon_dri2_get_msc; 1448 dri2_info.ScheduleWaitMSC = radeon_dri2_schedule_wait_msc; 1449 dri2_info.numDrivers = ARRAY_SIZE(driverNames); 1450 dri2_info.driverNames = driverNames; 1451 driverNames[0] = dri2_info.driverName; 1452 1453 if (info->ChipFamily >= CHIP_FAMILY_R300) 1454 driverNames[1] = driverNames[0]; 1455 else 1456 driverNames[1] = NULL; /* no VDPAU support */ 1457 1458 if (DRI2InfoCnt == 0) { 1459 if (!dixRegisterPrivateKey(dri2_window_private_key, 1460 PRIVATE_WINDOW, 1461 sizeof(struct dri2_window_priv))) { 1462 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 1463 "Failed to get DRI2 window private\n"); 1464 return FALSE; 1465 } 1466 1467 AddCallback(&ClientStateCallback, radeon_dri2_client_state_changed, 0); 1468 } 1469 1470 DRI2InfoCnt++; 1471 } 1472 1473 dri2_info.version = 9; 1474 dri2_info.CreateBuffer2 = radeon_dri2_create_buffer2; 1475 dri2_info.DestroyBuffer2 = radeon_dri2_destroy_buffer2; 1476 dri2_info.CopyRegion2 = radeon_dri2_copy_region2; 1477 1478 info->dri2.enabled = DRI2ScreenInit(pScreen, &dri2_info); 1479 return info->dri2.enabled; 1480} 1481 1482void radeon_dri2_close_screen(ScreenPtr pScreen) 1483{ 1484 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 1485 RADEONInfoPtr info = RADEONPTR(pScrn); 1486 1487 if (--DRI2InfoCnt == 0) 1488 DeleteCallback(&ClientStateCallback, radeon_dri2_client_state_changed, 0); 1489 1490 DRI2CloseScreen(pScreen); 1491 drmFree(info->dri2.device_name); 1492} 1493 1494#endif /* DRI2 */ 1495 1496