radeon_dri2.c revision 0d2a5547
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 ScreenPtr screen = draw->pScreen; 732 RADEONInfoPtr info = RADEONPTR(xf86ScreenToScrn(screen)); 733 RegionRec region; 734 int tmp; 735 736 region.extents.x1 = region.extents.y1 = 0; 737 region.extents.x2 = front_priv->pixmap->drawable.width; 738 region.extents.y2 = front_priv->pixmap->drawable.height; 739 region.data = NULL; 740 DamageRegionAppend(&front_priv->pixmap->drawable, ®ion); 741 742 /* Swap BO names so DRI works */ 743 tmp = front->name; 744 front->name = back->name; 745 back->name = tmp; 746 747 /* Swap pixmap privates */ 748#ifdef USE_GLAMOR 749 if (info->use_glamor) { 750 struct radeon_pixmap *front_pix, *back_pix; 751 752 front_pix = radeon_get_pixmap_private(front_priv->pixmap); 753 back_pix = radeon_get_pixmap_private(back_priv->pixmap); 754 radeon_set_pixmap_private(front_priv->pixmap, back_pix); 755 radeon_set_pixmap_private(back_priv->pixmap, front_pix); 756 757 radeon_glamor_exchange_buffers(front_priv->pixmap, back_priv->pixmap); 758 } else 759#endif 760 { 761 struct radeon_exa_pixmap_priv driver_priv = *(struct radeon_exa_pixmap_priv*) 762 exaGetPixmapDriverPrivate(front_priv->pixmap); 763 764 *(struct radeon_exa_pixmap_priv*)exaGetPixmapDriverPrivate(front_priv->pixmap) = 765 *(struct radeon_exa_pixmap_priv*)exaGetPixmapDriverPrivate(back_priv->pixmap); 766 *(struct radeon_exa_pixmap_priv*)exaGetPixmapDriverPrivate(back_priv->pixmap) = 767 driver_priv; 768 } 769 770 DamageRegionProcessPending(&front_priv->pixmap->drawable); 771} 772 773static void radeon_dri2_frame_event_abort(xf86CrtcPtr crtc, void *event_data) 774{ 775 DRI2FrameEventPtr event = event_data; 776 777 TimerCancel(event->timer); 778 TimerFree(event->timer); 779 radeon_dri2_unref_buffer(event->front); 780 radeon_dri2_unref_buffer(event->back); 781 free(event); 782} 783 784static void radeon_dri2_frame_event_handler(xf86CrtcPtr crtc, uint32_t seq, 785 uint64_t usec, void *event_data) 786{ 787 DRI2FrameEventPtr event = event_data; 788 ScrnInfoPtr scrn = crtc->scrn; 789 DrawablePtr drawable; 790 int status; 791 int swap_type; 792 BoxRec box; 793 RegionRec region; 794 795 status = dixLookupDrawable(&drawable, event->drawable_id, serverClient, 796 M_ANY, DixWriteAccess); 797 if (status != Success) 798 goto cleanup; 799 800 seq += radeon_get_msc_delta(drawable, crtc); 801 802 switch (event->type) { 803 case DRI2_FLIP: 804 if (can_flip(crtc, drawable, event->front, event->back) && 805 radeon_dri2_schedule_flip(crtc, 806 event->client, 807 drawable, 808 event->front, 809 event->back, 810 event->event_complete, 811 event->event_data, 812 event->frame)) { 813 radeon_dri2_exchange_buffers(drawable, event->front, event->back); 814 break; 815 } 816 /* else fall through to exchange/blit */ 817 case DRI2_SWAP: 818 if (DRI2CanExchange(drawable) && 819 can_exchange(scrn, drawable, event->front, event->back)) { 820 radeon_dri2_exchange_buffers(drawable, event->front, event->back); 821 swap_type = DRI2_EXCHANGE_COMPLETE; 822 } else { 823 box.x1 = 0; 824 box.y1 = 0; 825 box.x2 = drawable->width; 826 box.y2 = drawable->height; 827 REGION_INIT(pScreen, ®ion, &box, 0); 828 radeon_dri2_copy_region2(drawable->pScreen, drawable, ®ion, 829 event->front, event->back); 830 swap_type = DRI2_BLIT_COMPLETE; 831 } 832 833 DRI2SwapComplete(event->client, drawable, seq, usec / 1000000, 834 usec % 1000000, swap_type, event->event_complete, 835 event->event_data); 836 837 break; 838 case DRI2_WAITMSC: 839 DRI2WaitMSCComplete(event->client, drawable, seq, usec / 1000000, 840 usec % 1000000); 841 break; 842 default: 843 /* Unknown type */ 844 xf86DrvMsg(scrn->scrnIndex, X_WARNING, 845 "%s: unknown vblank event received\n", __func__); 846 break; 847 } 848 849cleanup: 850 radeon_dri2_frame_event_abort(crtc, event_data); 851} 852 853/* 854 * This function should be called on a disabled CRTC only (i.e., CRTC 855 * in DPMS-off state). It will calculate the delay necessary to reach 856 * target_msc from present time if the CRTC were running. 857 */ 858static 859CARD32 radeon_dri2_extrapolate_msc_delay(xf86CrtcPtr crtc, CARD64 *target_msc, 860 CARD64 divisor, CARD64 remainder) 861{ 862 drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; 863 ScrnInfoPtr pScrn = crtc->scrn; 864 RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); 865 int nominal_frame_rate = drmmode_crtc->dpms_last_fps; 866 CARD64 last_vblank_ust = drmmode_crtc->dpms_last_ust; 867 uint32_t last_vblank_seq = drmmode_crtc->dpms_last_seq; 868 CARD64 now, target_time, delta_t; 869 int64_t d, delta_seq; 870 int ret; 871 CARD32 d_ms; 872 873 if (!last_vblank_ust) { 874 *target_msc = 0; 875 return FALLBACK_SWAP_DELAY; 876 } 877 ret = drmmode_get_current_ust(pRADEONEnt->fd, &now); 878 if (ret) { 879 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 880 "%s cannot get current time\n", __func__); 881 *target_msc = 0; 882 return FALLBACK_SWAP_DELAY; 883 } 884 delta_seq = *target_msc - last_vblank_seq; 885 delta_seq *= 1000000; 886 target_time = last_vblank_ust; 887 target_time += delta_seq / nominal_frame_rate; 888 d = target_time - now; 889 if (d < 0) { 890 /* we missed the event, adjust target_msc, do the divisor magic */ 891 CARD64 current_msc = last_vblank_seq; 892 893 delta_t = now - last_vblank_ust; 894 delta_seq = delta_t * nominal_frame_rate; 895 current_msc += delta_seq / 1000000; 896 current_msc &= 0xffffffff; 897 if (divisor == 0) { 898 *target_msc = current_msc; 899 d = 0; 900 } else { 901 *target_msc = current_msc - (current_msc % divisor) + remainder; 902 if ((current_msc % divisor) >= remainder) 903 *target_msc += divisor; 904 *target_msc &= 0xffffffff; 905 delta_seq = *target_msc - last_vblank_seq; 906 delta_seq *= 1000000; 907 target_time = last_vblank_ust; 908 target_time += delta_seq / nominal_frame_rate; 909 d = target_time - now; 910 } 911 } 912 /* 913 * convert delay to milliseconds and add margin to prevent the client 914 * from coming back early (due to timer granularity and rounding 915 * errors) and getting the same MSC it just got 916 */ 917 d_ms = (CARD32)d / 1000; 918 if ((CARD32)d - d_ms * 1000 > 0) 919 d_ms += 2; 920 else 921 d_ms++; 922 return d_ms; 923} 924 925/* 926 * Get current interpolated frame count and frame count timestamp, based on 927 * drawable's crtc. 928 */ 929static int radeon_dri2_get_msc(DrawablePtr draw, CARD64 *ust, CARD64 *msc) 930{ 931 xf86CrtcPtr crtc = radeon_dri2_drawable_crtc(draw); 932 933 /* Drawable not displayed, make up a value */ 934 if (!crtc) { 935 *ust = 0; 936 *msc = 0; 937 return TRUE; 938 } 939 940 if (!radeon_dri2_get_crtc_msc(crtc, ust, msc)) 941 return FALSE; 942 943 if (draw && draw->type == DRAWABLE_WINDOW) 944 *msc += get_dri2_window_priv((WindowPtr)draw)->vblank_delta; 945 *msc &= 0xffffffff; 946 return TRUE; 947} 948 949static 950CARD32 radeon_dri2_deferred_event(OsTimerPtr timer, CARD32 now, pointer data) 951{ 952 DRI2FrameEventPtr event_info = (DRI2FrameEventPtr)data; 953 xf86CrtcPtr crtc = event_info->crtc; 954 ScrnInfoPtr scrn; 955 RADEONEntPtr pRADEONEnt; 956 CARD64 drm_now; 957 int ret; 958 CARD64 delta_t, delta_seq, frame; 959 drmmode_crtc_private_ptr drmmode_crtc; 960 961 /* 962 * This is emulated event, so its time is current time, which we 963 * have to get in DRM-compatible form (which is a bit messy given 964 * the information that we have at this point). Can't use now argument 965 * because DRM event time may come from monotonic clock, while 966 * DIX timer facility uses real-time clock. 967 */ 968 if (!event_info->crtc) { 969 ErrorF("%s no crtc\n", __func__); 970 if (event_info->drm_queue_seq) 971 radeon_drm_abort_entry(event_info->drm_queue_seq); 972 else 973 radeon_dri2_frame_event_abort(NULL, data); 974 return 0; 975 } 976 977 scrn = crtc->scrn; 978 pRADEONEnt = RADEONEntPriv(scrn); 979 drmmode_crtc = event_info->crtc->driver_private; 980 ret = drmmode_get_current_ust(pRADEONEnt->fd, &drm_now); 981 if (ret) { 982 xf86DrvMsg(scrn->scrnIndex, X_ERROR, 983 "%s cannot get current time\n", __func__); 984 985 if (event_info->drm_queue_seq) { 986 drmmode_crtc->drmmode->event_context. 987 vblank_handler(pRADEONEnt->fd, 0, 0, 0, 988 (void*)event_info->drm_queue_seq); 989 drmmode_crtc->wait_flip_nesting_level++; 990 radeon_drm_queue_handle_deferred(crtc); 991 992 } else { 993 radeon_dri2_frame_event_handler(crtc, 0, 0, data); 994 } 995 996 return 0; 997 } 998 /* 999 * calculate the frame number from current time 1000 * that would come from CRTC if it were running 1001 */ 1002 delta_t = drm_now - (CARD64)drmmode_crtc->dpms_last_ust; 1003 delta_seq = delta_t * drmmode_crtc->dpms_last_fps; 1004 delta_seq /= 1000000; 1005 frame = (CARD64)drmmode_crtc->dpms_last_seq + delta_seq; 1006 1007 if (event_info->drm_queue_seq) { 1008 drmmode_crtc->drmmode->event_context. 1009 vblank_handler(pRADEONEnt->fd, frame, drm_now / 1000000, 1010 drm_now % 1000000, 1011 (void*)event_info->drm_queue_seq); 1012 drmmode_crtc->wait_flip_nesting_level++; 1013 radeon_drm_queue_handle_deferred(crtc); 1014 } else { 1015 radeon_dri2_frame_event_handler(crtc, frame, drm_now, data); 1016 } 1017 1018 return 0; 1019} 1020 1021static 1022void radeon_dri2_schedule_event(CARD32 delay, DRI2FrameEventPtr event_info) 1023{ 1024 event_info->timer = TimerSet(NULL, 0, delay, radeon_dri2_deferred_event, 1025 event_info); 1026 if (delay == 0) { 1027 CARD32 now = GetTimeInMillis(); 1028 radeon_dri2_deferred_event(event_info->timer, now, event_info); 1029 } 1030} 1031 1032/* 1033 * Request a DRM event when the requested conditions will be satisfied. 1034 * 1035 * We need to handle the event and ask the server to wake up the client when 1036 * we receive it. 1037 */ 1038static int radeon_dri2_schedule_wait_msc(ClientPtr client, DrawablePtr draw, 1039 CARD64 target_msc, CARD64 divisor, 1040 CARD64 remainder) 1041{ 1042 ScreenPtr screen = draw->pScreen; 1043 ScrnInfoPtr scrn = xf86ScreenToScrn(screen); 1044 DRI2FrameEventPtr wait_info = NULL; 1045 uintptr_t drm_queue_seq = 0; 1046 xf86CrtcPtr crtc = radeon_dri2_drawable_crtc(draw); 1047 uint32_t msc_delta; 1048 uint32_t seq; 1049 CARD64 current_msc; 1050 1051 /* Truncate to match kernel interfaces; means occasional overflow 1052 * misses, but that's generally not a big deal */ 1053 target_msc &= 0xffffffff; 1054 divisor &= 0xffffffff; 1055 remainder &= 0xffffffff; 1056 1057 /* Drawable not visible, return immediately */ 1058 if (!crtc) 1059 goto out_complete; 1060 1061 msc_delta = radeon_get_msc_delta(draw, crtc); 1062 1063 wait_info = calloc(1, sizeof(DRI2FrameEventRec)); 1064 if (!wait_info) 1065 goto out_complete; 1066 1067 wait_info->drawable_id = draw->id; 1068 wait_info->client = client; 1069 wait_info->type = DRI2_WAITMSC; 1070 wait_info->crtc = crtc; 1071 1072 /* 1073 * CRTC is in DPMS off state, calculate wait time from current time, 1074 * target_msc and last vblank time/sequence when CRTC was turned off 1075 */ 1076 if (!radeon_crtc_is_enabled(crtc)) { 1077 CARD32 delay; 1078 target_msc -= msc_delta; 1079 delay = radeon_dri2_extrapolate_msc_delay(crtc, &target_msc, 1080 divisor, remainder); 1081 radeon_dri2_schedule_event(delay, wait_info); 1082 DRI2BlockClient(client, draw); 1083 return TRUE; 1084 } 1085 1086 /* Get current count */ 1087 if (!drmmode_wait_vblank(crtc, DRM_VBLANK_RELATIVE, 0, 0, NULL, &seq)) { 1088 xf86DrvMsg(scrn->scrnIndex, X_WARNING, 1089 "get vblank counter failed: %s\n", strerror(errno)); 1090 goto out_complete; 1091 } 1092 1093 current_msc = seq + msc_delta; 1094 current_msc &= 0xffffffff; 1095 1096 drm_queue_seq = radeon_drm_queue_alloc(crtc, client, RADEON_DRM_QUEUE_ID_DEFAULT, 1097 wait_info, radeon_dri2_frame_event_handler, 1098 radeon_dri2_frame_event_abort, FALSE); 1099 if (drm_queue_seq == RADEON_DRM_QUEUE_ERROR) { 1100 xf86DrvMsg(scrn->scrnIndex, X_WARNING, 1101 "Allocating DRM queue event entry failed.\n"); 1102 goto out_complete; 1103 } 1104 wait_info->drm_queue_seq = drm_queue_seq; 1105 1106 /* 1107 * If divisor is zero, or current_msc is smaller than target_msc, 1108 * we just need to make sure target_msc passes before waking up the 1109 * client. 1110 */ 1111 if (divisor == 0 || current_msc < target_msc) { 1112 /* If target_msc already reached or passed, set it to 1113 * current_msc to ensure we return a reasonable value back 1114 * to the caller. This keeps the client from continually 1115 * sending us MSC targets from the past by forcibly updating 1116 * their count on this call. 1117 */ 1118 if (current_msc >= target_msc) 1119 target_msc = current_msc; 1120 if (!drmmode_wait_vblank(crtc, DRM_VBLANK_ABSOLUTE | DRM_VBLANK_EVENT, 1121 target_msc - msc_delta, drm_queue_seq, NULL, 1122 NULL)) { 1123 xf86DrvMsg(scrn->scrnIndex, X_WARNING, 1124 "get vblank counter failed: %s\n", strerror(errno)); 1125 goto out_complete; 1126 } 1127 1128 DRI2BlockClient(client, draw); 1129 return TRUE; 1130 } 1131 1132 /* 1133 * If we get here, target_msc has already passed or we don't have one, 1134 * so we queue an event that will satisfy the divisor/remainder equation. 1135 */ 1136 target_msc = current_msc - (current_msc % divisor) + remainder - msc_delta; 1137 1138 /* 1139 * If calculated remainder is larger than requested remainder, 1140 * it means we've passed the last point where 1141 * seq % divisor == remainder, so we need to wait for the next time 1142 * that will happen. 1143 */ 1144 if ((current_msc % divisor) >= remainder) 1145 target_msc += divisor; 1146 1147 if (!drmmode_wait_vblank(crtc, DRM_VBLANK_ABSOLUTE | DRM_VBLANK_EVENT, 1148 target_msc, drm_queue_seq, NULL, NULL)) { 1149 xf86DrvMsg(scrn->scrnIndex, X_WARNING, 1150 "get vblank counter failed: %s\n", strerror(errno)); 1151 goto out_complete; 1152 } 1153 1154 DRI2BlockClient(client, draw); 1155 1156 return TRUE; 1157 1158out_complete: 1159 if (wait_info) 1160 radeon_dri2_deferred_event(NULL, 0, wait_info); 1161 else 1162 DRI2WaitMSCComplete(client, draw, 0, 0, 0); 1163 1164 return TRUE; 1165} 1166 1167/* 1168 * ScheduleSwap is responsible for requesting a DRM vblank event for the 1169 * appropriate frame. 1170 * 1171 * In the case of a blit (e.g. for a windowed swap) or buffer exchange, 1172 * the vblank requested can simply be the last queued swap frame + the swap 1173 * interval for the drawable. 1174 * 1175 * In the case of a page flip, we request an event for the last queued swap 1176 * frame + swap interval - 1, since we'll need to queue the flip for the frame 1177 * immediately following the received event. 1178 * 1179 * The client will be blocked if it tries to perform further GL commands 1180 * after queueing a swap, though in the Intel case after queueing a flip, the 1181 * client is free to queue more commands; they'll block in the kernel if 1182 * they access buffers busy with the flip. 1183 * 1184 * When the swap is complete, the driver should call into the server so it 1185 * can send any swap complete events that have been requested. 1186 */ 1187static int radeon_dri2_schedule_swap(ClientPtr client, DrawablePtr draw, 1188 DRI2BufferPtr front, DRI2BufferPtr back, 1189 CARD64 *target_msc, CARD64 divisor, 1190 CARD64 remainder, DRI2SwapEventPtr func, 1191 void *data) 1192{ 1193 ScreenPtr screen = draw->pScreen; 1194 ScrnInfoPtr scrn = xf86ScreenToScrn(screen); 1195 xf86CrtcPtr crtc = radeon_dri2_drawable_crtc(draw); 1196 uint32_t msc_delta; 1197 drmVBlankSeqType type; 1198 uint32_t seq; 1199 int flip = 0; 1200 DRI2FrameEventPtr swap_info = NULL; 1201 uintptr_t drm_queue_seq; 1202 CARD64 current_msc, event_msc; 1203 BoxRec box; 1204 RegionRec region; 1205 1206 /* Truncate to match kernel interfaces; means occasional overflow 1207 * misses, but that's generally not a big deal */ 1208 *target_msc &= 0xffffffff; 1209 divisor &= 0xffffffff; 1210 remainder &= 0xffffffff; 1211 1212 /* radeon_dri2_frame_event_handler will get called some unknown time in the 1213 * future with these buffers. Take a reference to ensure that they won't 1214 * get destroyed before then. 1215 */ 1216 radeon_dri2_ref_buffer(front); 1217 radeon_dri2_ref_buffer(back); 1218 1219 /* either off-screen or CRTC not usable... just complete the swap */ 1220 if (!crtc) 1221 goto blit_fallback; 1222 1223 msc_delta = radeon_get_msc_delta(draw, crtc); 1224 1225 swap_info = calloc(1, sizeof(DRI2FrameEventRec)); 1226 if (!swap_info) 1227 goto blit_fallback; 1228 1229 swap_info->type = DRI2_SWAP; 1230 swap_info->drawable_id = draw->id; 1231 swap_info->client = client; 1232 swap_info->event_complete = func; 1233 swap_info->event_data = data; 1234 swap_info->front = front; 1235 swap_info->back = back; 1236 swap_info->crtc = crtc; 1237 1238 drm_queue_seq = radeon_drm_queue_alloc(crtc, client, RADEON_DRM_QUEUE_ID_DEFAULT, 1239 swap_info, radeon_dri2_frame_event_handler, 1240 radeon_dri2_frame_event_abort, FALSE); 1241 if (drm_queue_seq == RADEON_DRM_QUEUE_ERROR) { 1242 xf86DrvMsg(scrn->scrnIndex, X_WARNING, 1243 "Allocating DRM queue entry failed.\n"); 1244 goto blit_fallback; 1245 } 1246 swap_info->drm_queue_seq = drm_queue_seq; 1247 1248 /* 1249 * CRTC is in DPMS off state, fallback to blit, but calculate 1250 * wait time from current time, target_msc and last vblank 1251 * time/sequence when CRTC was turned off 1252 */ 1253 if (!radeon_crtc_is_enabled(crtc)) { 1254 CARD32 delay; 1255 *target_msc -= msc_delta; 1256 delay = radeon_dri2_extrapolate_msc_delay(crtc, target_msc, 1257 divisor, remainder); 1258 *target_msc += msc_delta; 1259 *target_msc &= 0xffffffff; 1260 radeon_dri2_schedule_event(delay, swap_info); 1261 return TRUE; 1262 } 1263 1264 /* Get current count */ 1265 if (!drmmode_wait_vblank(crtc, DRM_VBLANK_RELATIVE, 0, 0, NULL, &seq)) { 1266 xf86DrvMsg(scrn->scrnIndex, X_WARNING, 1267 "first get vblank counter failed: %s\n", 1268 strerror(errno)); 1269 goto blit_fallback; 1270 } 1271 1272 current_msc = seq + msc_delta; 1273 current_msc &= 0xffffffff; 1274 1275 /* Flips need to be submitted one frame before */ 1276 if (can_flip(crtc, draw, front, back)) { 1277 swap_info->type = DRI2_FLIP; 1278 flip = 1; 1279 } 1280 1281 /* Correct target_msc by 'flip' if swap_info->type == DRI2_FLIP. 1282 * Do it early, so handling of different timing constraints 1283 * for divisor, remainder and msc vs. target_msc works. 1284 */ 1285 if (*target_msc > 0) 1286 *target_msc -= flip; 1287 1288 /* 1289 * If divisor is zero, or current_msc is smaller than target_msc 1290 * we just need to make sure target_msc passes before initiating 1291 * the swap. 1292 */ 1293 if (divisor == 0 || current_msc < *target_msc) { 1294 type = DRM_VBLANK_ABSOLUTE | DRM_VBLANK_EVENT; 1295 /* If non-pageflipping, but blitting/exchanging, we need to use 1296 * DRM_VBLANK_NEXTONMISS to avoid unreliable timestamping later 1297 * on. 1298 */ 1299 if (flip == 0) 1300 type |= DRM_VBLANK_NEXTONMISS; 1301 1302 /* If target_msc already reached or passed, set it to 1303 * current_msc to ensure we return a reasonable value back 1304 * to the caller. This makes swap_interval logic more robust. 1305 */ 1306 if (current_msc >= *target_msc) 1307 *target_msc = current_msc; 1308 1309 if (!drmmode_wait_vblank(crtc, type, *target_msc - msc_delta, 1310 drm_queue_seq, NULL, &seq)) { 1311 xf86DrvMsg(scrn->scrnIndex, X_WARNING, 1312 "divisor 0 get vblank counter failed: %s\n", 1313 strerror(errno)); 1314 goto blit_fallback; 1315 } 1316 1317 *target_msc = seq + flip + msc_delta; 1318 swap_info->frame = *target_msc; 1319 1320 return TRUE; 1321 } 1322 1323 /* 1324 * If we get here, target_msc has already passed or we don't have one, 1325 * and we need to queue an event that will satisfy the divisor/remainder 1326 * equation. 1327 */ 1328 type = DRM_VBLANK_ABSOLUTE | DRM_VBLANK_EVENT; 1329 if (flip == 0) 1330 type |= DRM_VBLANK_NEXTONMISS; 1331 1332 event_msc = current_msc - (current_msc % divisor) + remainder - msc_delta; 1333 1334 /* 1335 * If the calculated deadline vbl.request.sequence is smaller than 1336 * or equal to current_msc, it means we've passed the last point 1337 * when effective onset frame seq could satisfy 1338 * seq % divisor == remainder, so we need to wait for the next time 1339 * this will happen. 1340 1341 * This comparison takes the 1 frame swap delay in pageflipping mode 1342 * into account, as well as a potential DRM_VBLANK_NEXTONMISS delay 1343 * if we are blitting/exchanging instead of flipping. 1344 */ 1345 if (event_msc <= current_msc) 1346 event_msc += divisor; 1347 1348 /* Account for 1 frame extra pageflip delay if flip > 0 */ 1349 event_msc -= flip; 1350 1351 if (!drmmode_wait_vblank(crtc, type, event_msc, drm_queue_seq, NULL, &seq)) { 1352 xf86DrvMsg(scrn->scrnIndex, X_WARNING, 1353 "final get vblank counter failed: %s\n", 1354 strerror(errno)); 1355 goto blit_fallback; 1356 } 1357 1358 /* Adjust returned value for 1 fame pageflip offset of flip > 0 */ 1359 *target_msc = seq + flip + msc_delta; 1360 *target_msc &= 0xffffffff; 1361 swap_info->frame = *target_msc; 1362 1363 return TRUE; 1364 1365blit_fallback: 1366 if (swap_info) { 1367 swap_info->type = DRI2_SWAP; 1368 radeon_dri2_schedule_event(FALLBACK_SWAP_DELAY, swap_info); 1369 } else { 1370 box.x1 = 0; 1371 box.y1 = 0; 1372 box.x2 = draw->width; 1373 box.y2 = draw->height; 1374 REGION_INIT(pScreen, ®ion, &box, 0); 1375 1376 radeon_dri2_copy_region2(draw->pScreen, draw, ®ion, front, back); 1377 1378 DRI2SwapComplete(client, draw, 0, 0, 0, DRI2_BLIT_COMPLETE, func, data); 1379 1380 radeon_dri2_unref_buffer(front); 1381 radeon_dri2_unref_buffer(back); 1382 } 1383 1384 *target_msc = 0; /* offscreen, so zero out target vblank count */ 1385 return TRUE; 1386} 1387 1388 1389Bool 1390radeon_dri2_screen_init(ScreenPtr pScreen) 1391{ 1392 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 1393 RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); 1394 RADEONInfoPtr info = RADEONPTR(pScrn); 1395 DRI2InfoRec dri2_info = { 0 }; 1396 const char *driverNames[2]; 1397 Bool scheduling_works = TRUE; 1398 1399 if (!info->dri2.available) 1400 return FALSE; 1401 1402 info->dri2.device_name = drmGetDeviceNameFromFd(pRADEONEnt->fd); 1403 1404 if ( (info->ChipFamily >= CHIP_FAMILY_TAHITI) ) { 1405 dri2_info.driverName = SI_DRIVER_NAME; 1406 } else if ( (info->ChipFamily >= CHIP_FAMILY_R600) ) { 1407 dri2_info.driverName = R600_DRIVER_NAME; 1408 } else if ( (info->ChipFamily >= CHIP_FAMILY_R300) ) { 1409 dri2_info.driverName = R300_DRIVER_NAME; 1410 } else if ( info->ChipFamily >= CHIP_FAMILY_R200 ) { 1411 dri2_info.driverName = R200_DRIVER_NAME; 1412 } else { 1413 dri2_info.driverName = RADEON_DRIVER_NAME; 1414 } 1415 dri2_info.fd = pRADEONEnt->fd; 1416 dri2_info.deviceName = info->dri2.device_name; 1417 1418 if (info->dri2.pKernelDRMVersion->version_minor < 4) { 1419 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "You need a newer kernel for " 1420 "sync extension\n"); 1421 scheduling_works = FALSE; 1422 } 1423 1424 if (scheduling_works && info->drmmode.count_crtcs > 2) { 1425#ifdef DRM_CAP_VBLANK_HIGH_CRTC 1426 uint64_t cap_value; 1427 1428 if (drmGetCap(pRADEONEnt->fd, DRM_CAP_VBLANK_HIGH_CRTC, &cap_value)) { 1429 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "You need a newer kernel " 1430 "for VBLANKs on CRTC > 1\n"); 1431 scheduling_works = FALSE; 1432 } else if (!cap_value) { 1433 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Your kernel does not " 1434 "handle VBLANKs on CRTC > 1\n"); 1435 scheduling_works = FALSE; 1436 } 1437#else 1438 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "You need to rebuild against a " 1439 "newer libdrm to handle VBLANKs on CRTC > 1\n"); 1440 scheduling_works = FALSE; 1441#endif 1442 } 1443 1444 if (scheduling_works) { 1445 dri2_info.ScheduleSwap = radeon_dri2_schedule_swap; 1446 dri2_info.GetMSC = radeon_dri2_get_msc; 1447 dri2_info.ScheduleWaitMSC = radeon_dri2_schedule_wait_msc; 1448 dri2_info.numDrivers = ARRAY_SIZE(driverNames); 1449 dri2_info.driverNames = driverNames; 1450 driverNames[0] = dri2_info.driverName; 1451 1452 if (info->ChipFamily >= CHIP_FAMILY_R300) 1453 driverNames[1] = driverNames[0]; 1454 else 1455 driverNames[1] = NULL; /* no VDPAU support */ 1456 1457 if (DRI2InfoCnt == 0) { 1458 if (!dixRegisterPrivateKey(dri2_window_private_key, 1459 PRIVATE_WINDOW, 1460 sizeof(struct dri2_window_priv))) { 1461 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 1462 "Failed to get DRI2 window private\n"); 1463 return FALSE; 1464 } 1465 1466 AddCallback(&ClientStateCallback, radeon_dri2_client_state_changed, 0); 1467 } 1468 1469 DRI2InfoCnt++; 1470 } 1471 1472 dri2_info.version = 9; 1473 dri2_info.CreateBuffer2 = radeon_dri2_create_buffer2; 1474 dri2_info.DestroyBuffer2 = radeon_dri2_destroy_buffer2; 1475 dri2_info.CopyRegion2 = radeon_dri2_copy_region2; 1476 1477 info->dri2.enabled = DRI2ScreenInit(pScreen, &dri2_info); 1478 return info->dri2.enabled; 1479} 1480 1481void radeon_dri2_close_screen(ScreenPtr pScreen) 1482{ 1483 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 1484 RADEONInfoPtr info = RADEONPTR(pScrn); 1485 1486 if (--DRI2InfoCnt == 0) 1487 DeleteCallback(&ClientStateCallback, radeon_dri2_client_state_changed, 0); 1488 1489 DRI2CloseScreen(pScreen); 1490 drmFree(info->dri2.device_name); 1491} 1492 1493#endif /* DRI2 */ 1494 1495