From 22b2b935be6e1c7dee99eed5e661fe9bf9bdc685 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Wed, 14 Jul 2010 13:13:37 +0200 Subject: [PATCH] Revert "kms: add support for the MSC swap & sync API" This reverts commit 30591320ec46e491ba20904cc64f3405b51c6505. Conflicts: src/radeon_dri2.c src/radeon_kms.c --- src/drmmode_display.c | 57 +------ src/drmmode_display.h | 3 - src/radeon_dri2.c | 451 ------------------------------------------------- src/radeon_dri2.h | 6 - src/radeon_kms.c | 9 +- 5 files changed, 5 insertions(+), 521 deletions(-) diff --git a/src/drmmode_display.c b/src/drmmode_display.c index 1366b36..9acc52f 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -522,32 +522,6 @@ static const xf86CrtcFuncsRec drmmode_crtc_funcs = { .destroy = NULL, /* XXX */ }; -int drmmode_get_crtc_id(xf86CrtcPtr crtc) -{ - drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; - return drmmode_crtc->hw_id; -} - -void drmmode_crtc_hw_id(xf86CrtcPtr crtc) -{ - drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; - ScrnInfoPtr pScrn = crtc->scrn; - RADEONInfoPtr info = RADEONPTR(pScrn); - struct drm_radeon_info ginfo; - int r; - uint32_t tmp; - - memset(&ginfo, 0, sizeof(ginfo)); - ginfo.request = 0x4; - tmp = drmmode_crtc->mode_crtc->crtc_id; - ginfo.value = (uintptr_t)&tmp; - r = drmCommandWriteRead(info->dri->drmFD, DRM_RADEON_INFO, &ginfo, sizeof(ginfo)); - if (r) { - drmmode_crtc->hw_id = -1; - return; - } - drmmode_crtc->hw_id = tmp; -} static void drmmode_crtc_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int num) @@ -563,7 +537,6 @@ drmmode_crtc_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int num) drmmode_crtc->mode_crtc = drmModeGetCrtc(drmmode->fd, drmmode->mode_res->crtcs[num]); drmmode_crtc->drmmode = drmmode; crtc->driver_private = drmmode_crtc; - drmmode_crtc_hw_id(crtc); return; } @@ -1178,28 +1151,10 @@ static const xf86CrtcConfigFuncsRec drmmode_xf86crtc_config_funcs = { drmmode_xf86crtc_resize }; -static void -drmmode_vblank_handler(int fd, unsigned int frame, unsigned int tv_sec, - unsigned int tv_usec, void *event_data) -{ - radeon_dri2_frame_event_handler(frame, tv_sec, tv_usec, event_data); -} - -static void -drm_wakeup_handler(pointer data, int err, pointer p) -{ - drmmode_ptr drmmode = data; - fd_set *read_mask = p; - - if (err >= 0 && FD_ISSET(drmmode->fd, read_mask)) { - drmHandleEvent(drmmode->fd, &drmmode->event_context); - } -} Bool drmmode_pre_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int cpp) { - xf86CrtcConfigPtr xf86_config; - RADEONInfoPtr info = RADEONPTR(pScrn); + xf86CrtcConfigPtr xf86_config; int i; xf86CrtcConfigInit(pScrn, &drmmode_xf86crtc_config_funcs); @@ -1224,16 +1179,6 @@ Bool drmmode_pre_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int cpp) xf86InitialConfiguration(pScrn, TRUE); - drmmode->flip_count = 0; - drmmode->event_context.version = DRM_EVENT_CONTEXT_VERSION; - drmmode->event_context.vblank_handler = drmmode_vblank_handler; - drmmode->event_context.page_flip_handler = NULL; - if (info->dri->pKernelDRMVersion->version_minor >= 4) { - AddGeneralSocket(drmmode->fd); - RegisterBlockAndWakeupHandlers((BlockHandlerProcPtr)NoopDDA, - drm_wakeup_handler, drmmode); - } - return TRUE; } diff --git a/src/drmmode_display.h b/src/drmmode_display.h index a9891b2..86caabb 100644 --- a/src/drmmode_display.h +++ b/src/drmmode_display.h @@ -48,14 +48,11 @@ typedef struct { struct udev_monitor *uevent_monitor; InputHandlerProc uevent_handler; #endif - drmEventContext event_context; - int flip_count; } drmmode_rec, *drmmode_ptr; typedef struct { drmmode_ptr drmmode; drmModeCrtcPtr mode_crtc; - int hw_id; struct radeon_bo *cursor_bo; struct radeon_bo *rotate_bo; unsigned rotate_fb_id; diff --git a/src/radeon_dri2.c b/src/radeon_dri2.c index a0ed085..568f3ab 100644 --- a/src/radeon_dri2.c +++ b/src/radeon_dri2.c @@ -326,448 +326,12 @@ radeon_dri2_copy_region(DrawablePtr drawable, radeon_cs_flush_indirect(pScrn); } - -#if DRI2INFOREC_VERSION >= 4 - -enum DRI2FrameEventType { - DRI2_SWAP, - DRI2_FLIP, - DRI2_WAITMSC, -}; - -typedef struct _DRI2FrameEvent { - XID drawable_id; - ClientPtr client; - enum DRI2FrameEventType type; - int frame; - - /* for swaps & flips only */ - DRI2SwapEventPtr event_complete; - void *event_data; - DRI2BufferPtr front; - DRI2BufferPtr back; -} DRI2FrameEventRec, *DRI2FrameEventPtr; - -void radeon_dri2_frame_event_handler(unsigned int frame, unsigned int tv_sec, - unsigned int tv_usec, void *event_data) -{ - DRI2FrameEventPtr event = event_data; - DrawablePtr drawable; - ScreenPtr screen; - ScrnInfoPtr scrn; - int status; - int swap_type; - BoxRec box; - RegionRec region; - - status = dixLookupDrawable(&drawable, event->drawable_id, serverClient, - M_ANY, DixWriteAccess); - if (status != Success) { - free(event); - return; - } - - screen = drawable->pScreen; - scrn = xf86Screens[screen->myNum]; - - switch (event->type) { - case DRI2_FLIP: - case DRI2_SWAP: - box.x1 = 0; - box.y1 = 0; - box.x2 = drawable->width; - box.y2 = drawable->height; - REGION_INIT(pScreen, ®ion, &box, 0); - radeon_dri2_copy_region(drawable, ®ion, event->front, event->back); - swap_type = DRI2_BLIT_COMPLETE; - - DRI2SwapComplete(event->client, drawable, frame, tv_sec, tv_usec, - swap_type, event->event_complete, event->event_data); - break; - case DRI2_WAITMSC: - DRI2WaitMSCComplete(event->client, drawable, frame, tv_sec, tv_usec); - break; - default: - /* Unknown type */ - xf86DrvMsg(scrn->scrnIndex, X_WARNING, - "%s: unknown vblank event received\n", __func__); - break; - } - - free(event); -} - -static int radeon_dri2_drawable_crtc(DrawablePtr pDraw) -{ - ScreenPtr pScreen = pDraw->pScreen; - ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; - xf86CrtcPtr crtc; - int crtc_id = -1; - - crtc = radeon_pick_best_crtc(pScrn, - pDraw->x, - pDraw->x + pDraw->width, - pDraw->y, - pDraw->y + pDraw->height); - - /* Make sure the CRTC is valid and this is the real front buffer */ - if (crtc != NULL && !crtc->rotatedData) { - crtc_id = drmmode_get_crtc_id(crtc); - } - return crtc_id; -} - -/* - * Get current frame count and frame count timestamp, based on drawable's - * crtc. - */ -static int radeon_dri2_get_msc(DrawablePtr draw, CARD64 *ust, CARD64 *msc) -{ - ScreenPtr screen = draw->pScreen; - ScrnInfoPtr scrn = xf86Screens[screen->myNum]; - RADEONInfoPtr info = RADEONPTR(scrn); - drmVBlank vbl; - int ret; - int crtc= radeon_dri2_drawable_crtc(draw); - - /* Drawable not displayed, make up a value */ - if (crtc == -1) { - *ust = 0; - *msc = 0; - return TRUE; - } - vbl.request.type = DRM_VBLANK_RELATIVE; - if (crtc > 0) - vbl.request.type |= DRM_VBLANK_SECONDARY; - vbl.request.sequence = 0; - - ret = drmWaitVBlank(info->dri2.drm_fd, &vbl); - if (ret) { - xf86DrvMsg(scrn->scrnIndex, X_WARNING, - "get vblank counter failed: %s\n", strerror(errno)); - return FALSE; - } - - *ust = ((CARD64)vbl.reply.tval_sec * 1000000) + vbl.reply.tval_usec; - *msc = vbl.reply.sequence; - - return TRUE; -} - -/* - * Request a DRM event when the requested conditions will be satisfied. - * - * We need to handle the event and ask the server to wake up the client when - * we receive it. - */ -static int radeon_dri2_schedule_wait_msc(ClientPtr client, DrawablePtr draw, - CARD64 target_msc, CARD64 divisor, - CARD64 remainder) -{ - ScreenPtr screen = draw->pScreen; - ScrnInfoPtr scrn = xf86Screens[screen->myNum]; - RADEONInfoPtr info = RADEONPTR(scrn); - DRI2FrameEventPtr wait_info; - drmVBlank vbl; - int ret, crtc = radeon_dri2_drawable_crtc(draw); - CARD64 current_msc; - - /* Truncate to match kernel interfaces; means occasional overflow - * misses, but that's generally not a big deal */ - target_msc &= 0xffffffff; - divisor &= 0xffffffff; - remainder &= 0xffffffff; - - /* Drawable not visible, return immediately */ - if (crtc == -1) - goto out_complete; - - wait_info = calloc(1, sizeof(DRI2FrameEventRec)); - if (!wait_info) - goto out_complete; - - wait_info->drawable_id = draw->id; - wait_info->client = client; - wait_info->type = DRI2_WAITMSC; - - /* Get current count */ - vbl.request.type = DRM_VBLANK_RELATIVE; - if (crtc > 0) - vbl.request.type |= DRM_VBLANK_SECONDARY; - vbl.request.sequence = 0; - ret = drmWaitVBlank(info->dri2.drm_fd, &vbl); - if (ret) { - xf86DrvMsg(scrn->scrnIndex, X_WARNING, - "get vblank counter failed: %s\n", strerror(errno)); - goto out_complete; - } - - current_msc = vbl.reply.sequence; - - /* - * If divisor is zero, or current_msc is smaller than target_msc, - * we just need to make sure target_msc passes before waking up the - * client. - */ - if (divisor == 0 || current_msc < target_msc) { - /* If target_msc already reached or passed, set it to - * current_msc to ensure we return a reasonable value back - * to the caller. This keeps the client from continually - * sending us MSC targets from the past by forcibly updating - * their count on this call. - */ - if (current_msc >= target_msc) - target_msc = current_msc; - vbl.request.type = DRM_VBLANK_ABSOLUTE | DRM_VBLANK_EVENT; - if (crtc > 0) - vbl.request.type |= DRM_VBLANK_SECONDARY; - vbl.request.sequence = target_msc; - vbl.request.signal = (unsigned long)wait_info; - ret = drmWaitVBlank(info->dri2.drm_fd, &vbl); - if (ret) { - xf86DrvMsg(scrn->scrnIndex, X_WARNING, - "get vblank counter failed: %s\n", strerror(errno)); - goto out_complete; - } - - wait_info->frame = vbl.reply.sequence; - DRI2BlockClient(client, draw); - return TRUE; - } - - /* - * If we get here, target_msc has already passed or we don't have one, - * so we queue an event that will satisfy the divisor/remainder equation. - */ - vbl.request.type = DRM_VBLANK_ABSOLUTE | DRM_VBLANK_EVENT; - if (crtc > 0) - vbl.request.type |= DRM_VBLANK_SECONDARY; - - vbl.request.sequence = current_msc - (current_msc % divisor) + - remainder; - - /* - * If calculated remainder is larger than requested remainder, - * it means we've passed the last point where - * seq % divisor == remainder, so we need to wait for the next time - * that will happen. - */ - if ((current_msc % divisor) >= remainder) - vbl.request.sequence += divisor; - - vbl.request.signal = (unsigned long)wait_info; - ret = drmWaitVBlank(info->dri2.drm_fd, &vbl); - if (ret) { - xf86DrvMsg(scrn->scrnIndex, X_WARNING, - "get vblank counter failed: %s\n", strerror(errno)); - goto out_complete; - } - - wait_info->frame = vbl.reply.sequence; - DRI2BlockClient(client, draw); - - return TRUE; - -out_complete: - DRI2WaitMSCComplete(client, draw, target_msc, 0, 0); - return TRUE; -} - -/* - * ScheduleSwap is responsible for requesting a DRM vblank event for the - * appropriate frame. - * - * In the case of a blit (e.g. for a windowed swap) or buffer exchange, - * the vblank requested can simply be the last queued swap frame + the swap - * interval for the drawable. - * - * In the case of a page flip, we request an event for the last queued swap - * frame + swap interval - 1, since we'll need to queue the flip for the frame - * immediately following the received event. - * - * The client will be blocked if it tries to perform further GL commands - * after queueing a swap, though in the Intel case after queueing a flip, the - * client is free to queue more commands; they'll block in the kernel if - * they access buffers busy with the flip. - * - * When the swap is complete, the driver should call into the server so it - * can send any swap complete events that have been requested. - */ -static int radeon_dri2_schedule_swap(ClientPtr client, DrawablePtr draw, - DRI2BufferPtr front, DRI2BufferPtr back, - CARD64 *target_msc, CARD64 divisor, - CARD64 remainder, DRI2SwapEventPtr func, - void *data) -{ - ScreenPtr screen = draw->pScreen; - ScrnInfoPtr scrn = xf86Screens[screen->myNum]; - RADEONInfoPtr info = RADEONPTR(scrn); - drmVBlank vbl; - int ret, crtc= radeon_dri2_drawable_crtc(draw), flip = 0; - DRI2FrameEventPtr swap_info; - enum DRI2FrameEventType swap_type = DRI2_SWAP; - CARD64 current_msc; - BoxRec box; - RegionRec region; - - /* Truncate to match kernel interfaces; means occasional overflow - * misses, but that's generally not a big deal */ - *target_msc &= 0xffffffff; - divisor &= 0xffffffff; - remainder &= 0xffffffff; - - swap_info = calloc(1, sizeof(DRI2FrameEventRec)); - - /* Drawable not displayed... just complete the swap */ - if (crtc == -1 || !swap_info) - goto blit_fallback; - - swap_info->drawable_id = draw->id; - swap_info->client = client; - swap_info->event_complete = func; - swap_info->event_data = data; - swap_info->front = front; - swap_info->back = back; - - /* Get current count */ - vbl.request.type = DRM_VBLANK_RELATIVE; - if (crtc > 0) - vbl.request.type |= DRM_VBLANK_SECONDARY; - vbl.request.sequence = 0; - ret = drmWaitVBlank(info->dri2.drm_fd, &vbl); - if (ret) { - xf86DrvMsg(scrn->scrnIndex, X_WARNING, - "first get vblank counter failed: %s\n", - strerror(errno)); - goto blit_fallback; - } - - current_msc = vbl.reply.sequence; - swap_info->type = swap_type; - - /* Correct target_msc by 'flip' if swap_type == DRI2_FLIP. - * Do it early, so handling of different timing constraints - * for divisor, remainder and msc vs. target_msc works. - */ - if (*target_msc > 0) - *target_msc -= flip; - - /* - * If divisor is zero, or current_msc is smaller than target_msc - * we just need to make sure target_msc passes before initiating - * the swap. - */ - if (divisor == 0 || current_msc < *target_msc) { - vbl.request.type = DRM_VBLANK_ABSOLUTE | DRM_VBLANK_EVENT; - if (crtc > 0) - vbl.request.type |= DRM_VBLANK_SECONDARY; - - /* If non-pageflipping, but blitting/exchanging, we need to use - * DRM_VBLANK_NEXTONMISS to avoid unreliable timestamping later - * on. - */ - if (flip == 0) - vbl.request.type |= DRM_VBLANK_NEXTONMISS; - if (crtc > 0) - vbl.request.type |= DRM_VBLANK_SECONDARY; - - /* If target_msc already reached or passed, set it to - * current_msc to ensure we return a reasonable value back - * to the caller. This makes swap_interval logic more robust. - */ - if (current_msc >= *target_msc) - *target_msc = current_msc; - - vbl.request.sequence = *target_msc; - vbl.request.signal = (unsigned long)swap_info; - ret = drmWaitVBlank(info->dri2.drm_fd, &vbl); - if (ret) { - xf86DrvMsg(scrn->scrnIndex, X_WARNING, - "divisor 0 get vblank counter failed: %s\n", - strerror(errno)); - goto blit_fallback; - } - - *target_msc = vbl.reply.sequence + flip; - swap_info->frame = *target_msc; - - return TRUE; - } - - /* - * If we get here, target_msc has already passed or we don't have one, - * and we need to queue an event that will satisfy the divisor/remainder - * equation. - */ - vbl.request.type = DRM_VBLANK_ABSOLUTE | DRM_VBLANK_EVENT; - if (flip == 0) - vbl.request.type |= DRM_VBLANK_NEXTONMISS; - if (crtc > 0) - vbl.request.type |= DRM_VBLANK_SECONDARY; - - vbl.request.sequence = current_msc - (current_msc % divisor) + - remainder; - - /* - * If the calculated deadline vbl.request.sequence is smaller than - * or equal to current_msc, it means we've passed the last point - * when effective onset frame seq could satisfy - * seq % divisor == remainder, so we need to wait for the next time - * this will happen. - - * This comparison takes the 1 frame swap delay in pageflipping mode - * into account, as well as a potential DRM_VBLANK_NEXTONMISS delay - * if we are blitting/exchanging instead of flipping. - */ - if (vbl.request.sequence <= current_msc) - vbl.request.sequence += divisor; - - /* Account for 1 frame extra pageflip delay if flip > 0 */ - vbl.request.sequence -= flip; - - vbl.request.signal = (unsigned long)swap_info; - ret = drmWaitVBlank(info->dri2.drm_fd, &vbl); - if (ret) { - xf86DrvMsg(scrn->scrnIndex, X_WARNING, - "final get vblank counter failed: %s\n", - strerror(errno)); - goto blit_fallback; - } - - /* Adjust returned value for 1 fame pageflip offset of flip > 0 */ - *target_msc = vbl.reply.sequence + flip; - swap_info->frame = *target_msc; - - return TRUE; - -blit_fallback: - box.x1 = 0; - box.y1 = 0; - box.x2 = draw->width; - box.y2 = draw->height; - REGION_INIT(pScreen, ®ion, &box, 0); - - radeon_dri2_copy_region(draw, ®ion, front, back); - - DRI2SwapComplete(client, draw, 0, 0, 0, DRI2_BLIT_COMPLETE, func, data); - if (swap_info) - free(swap_info); - *target_msc = 0; /* offscreen, so zero out target vblank count */ - return TRUE; -} - -#endif /* DRI2INFOREC_VERSION >= 4 */ - - Bool radeon_dri2_screen_init(ScreenPtr pScreen) { ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; RADEONInfoPtr info = RADEONPTR(pScrn); DRI2InfoRec dri2_info = { 0 }; -#if DRI2INFOREC_VERSION >= 4 - const char *driverNames[1]; -#endif if (!info->useEXA) { xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "DRI2 requires EXA\n"); @@ -797,21 +361,6 @@ radeon_dri2_screen_init(ScreenPtr pScreen) dri2_info.DestroyBuffer = radeon_dri2_destroy_buffer; #endif dri2_info.CopyRegion = radeon_dri2_copy_region; - -#if DRI2INFOREC_VERSION >= 4 - if (info->dri->pKernelDRMVersion->version_minor >= 4) { - dri2_info.version = 4; - dri2_info.ScheduleSwap = radeon_dri2_schedule_swap; - dri2_info.GetMSC = radeon_dri2_get_msc; - dri2_info.ScheduleWaitMSC = radeon_dri2_schedule_wait_msc; - dri2_info.numDrivers = 1; - dri2_info.driverNames = driverNames; - driverNames[0] = dri2_info.driverName; - } else { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "You need a newer kernel for sync extension\n"); - } -#endif - info->dri2.enabled = DRI2ScreenInit(pScreen, &dri2_info); return info->dri2.enabled; } diff --git a/src/radeon_dri2.h b/src/radeon_dri2.h index 688530f..c391e73 100644 --- a/src/radeon_dri2.h +++ b/src/radeon_dri2.h @@ -39,10 +39,4 @@ Bool radeon_dri2_screen_init(ScreenPtr pScreen); void radeon_dri2_close_screen(ScreenPtr pScreen); #endif -int drmmode_get_crtc_id(xf86CrtcPtr crtc); -xf86CrtcPtr radeon_covering_crtc(ScrnInfoPtr pScrn, BoxPtr box, - xf86CrtcPtr desired, BoxPtr crtc_box_ret); -void radeon_dri2_frame_event_handler(unsigned int frame, unsigned int tv_sec, - unsigned int tv_usec, void *event_data); - #endif diff --git a/src/radeon_kms.c b/src/radeon_kms.c index c0d2ae6..faa18b0 100644 --- a/src/radeon_kms.c +++ b/src/radeon_kms.c @@ -503,6 +503,10 @@ Bool RADEONPreInit_KMS(ScrnInfoPtr pScrn, int flags) xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Kernel modesetting setup failed\n"); goto fail; } + if (drmmode_pre_init(pScrn, &info->drmmode, pScrn->bitsPerPixel / 8) == FALSE) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Kernel modesetting setup failed\n"); + goto fail; + } info->dri2.enabled = FALSE; info->dri->pKernelDRMVersion = drmGetVersion(info->dri->drmFD); @@ -512,11 +516,6 @@ Bool RADEONPreInit_KMS(ScrnInfoPtr pScrn, int flags) goto fail; } - if (drmmode_pre_init(pScrn, &info->drmmode, pScrn->bitsPerPixel / 8) == FALSE) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Kernel modesetting setup failed\n"); - goto fail; - } - if (info->drmmode.mode_res->count_crtcs == 1) pRADEONEnt->HasCRTC2 = FALSE; else -- 1.7.1