From patchwork Wed Mar 23 02:15:52 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ilija Hadzic X-Patchwork-Id: 654071 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by demeter1.kernel.org (8.14.4/8.14.3) with ESMTP id p2N2GFKB017502 for ; Wed, 23 Mar 2011 02:16:38 GMT Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id D80E19E971 for ; Tue, 22 Mar 2011 19:16:14 -0700 (PDT) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from ihemail4.lucent.com (ihemail4.lucent.com [135.245.0.39]) by gabe.freedesktop.org (Postfix) with ESMTP id 72ABC9E74B for ; Tue, 22 Mar 2011 19:16:04 -0700 (PDT) Received: from umail.lucent.com (h135-3-40-63.lucent.com [135.3.40.63]) by ihemail4.lucent.com (8.13.8/IER-o) with ESMTP id p2N2FvWY001458 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Tue, 22 Mar 2011 21:15:58 -0500 (CDT) Received: from charon.research.bell-labs.com (charon.research.bell-labs.com [135.104.120.113]) by umail.lucent.com (8.13.8/TPES) with ESMTP id p2N2FtWW026824; Tue, 22 Mar 2011 21:15:56 -0500 (CDT) From: Ilija Hadzic To: alexdeucher@gmail.com, dri-devel@lists.freedesktop.org, xorg-driver-ati@lists.x.org Subject: [PATCH] (revised) xf86-video-ati: add support for vblank on crtc > 1 Date: Tue, 22 Mar 2011 22:15:52 -0400 Message-Id: <1300846552-3444-1-git-send-email-ihadzic@research.bell-labs.com> X-Mailer: git-send-email 1.7.4.1 X-Scanned-By: MIMEDefang 2.57 on 135.245.2.39 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.11 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: dri-devel-bounces+patchwork-dri-devel=patchwork.kernel.org@lists.freedesktop.org Errors-To: dri-devel-bounces+patchwork-dri-devel=patchwork.kernel.org@lists.freedesktop.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.6 (demeter1.kernel.org [140.211.167.41]); Wed, 23 Mar 2011 02:17:27 +0000 (UTC) diff --git a/src/radeon.h b/src/radeon.h index a6d20d7..1a746c7 100644 --- a/src/radeon.h +++ b/src/radeon.h @@ -931,6 +931,9 @@ typedef struct { RADEONFBLayout CurrentLayout; +#ifdef RADEON_DRI2 + Bool high_crtc_works; +#endif #ifdef XF86DRI Bool directRenderingEnabled; Bool directRenderingInited; diff --git a/src/radeon_dri2.c b/src/radeon_dri2.c index 66df03c..5605f99 100644 --- a/src/radeon_dri2.c +++ b/src/radeon_dri2.c @@ -771,6 +771,22 @@ cleanup: free(event); } +static drmVBlankSeqType populate_vbl_request_type(RADEONInfoPtr info, int crtc) +{ + drmVBlankSeqType type = 0; + + if (crtc == 1) + type |= DRM_VBLANK_SECONDARY; + else if (crtc > 1) { + if (info->high_crtc_works) { + type |= (crtc << DRM_VBLANK_HIGH_CRTC_SHIFT) & + DRM_VBLANK_HIGH_CRTC_MASK; + } else + type |= DRM_VBLANK_SECONDARY; + } + return type; +} + /* * Get current frame count and frame count timestamp, based on drawable's * crtc. @@ -791,8 +807,7 @@ static int radeon_dri2_get_msc(DrawablePtr draw, CARD64 *ust, CARD64 *msc) return TRUE; } vbl.request.type = DRM_VBLANK_RELATIVE; - if (crtc > 0) - vbl.request.type |= DRM_VBLANK_SECONDARY; + vbl.request.type |= populate_vbl_request_type(info, crtc); vbl.request.sequence = 0; ret = drmWaitVBlank(info->dri2.drm_fd, &vbl); @@ -855,8 +870,7 @@ static int radeon_dri2_schedule_wait_msc(ClientPtr client, DrawablePtr draw, /* Get current count */ vbl.request.type = DRM_VBLANK_RELATIVE; - if (crtc > 0) - vbl.request.type |= DRM_VBLANK_SECONDARY; + vbl.request.type |= populate_vbl_request_type(info, crtc); vbl.request.sequence = 0; ret = drmWaitVBlank(info->dri2.drm_fd, &vbl); if (ret) { @@ -882,8 +896,7 @@ static int radeon_dri2_schedule_wait_msc(ClientPtr client, DrawablePtr draw, 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.type |= populate_vbl_request_type(info, crtc); vbl.request.sequence = target_msc; vbl.request.signal = (unsigned long)wait_info; ret = drmWaitVBlank(info->dri2.drm_fd, &vbl); @@ -903,8 +916,7 @@ static int radeon_dri2_schedule_wait_msc(ClientPtr client, DrawablePtr draw, * 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.type |= populate_vbl_request_type(info, crtc); vbl.request.sequence = current_msc - (current_msc % divisor) + remainder; @@ -1068,8 +1080,7 @@ static int radeon_dri2_schedule_swap(ClientPtr client, DrawablePtr draw, /* Get current count */ vbl.request.type = DRM_VBLANK_RELATIVE; - if (crtc > 0) - vbl.request.type |= DRM_VBLANK_SECONDARY; + vbl.request.type |= populate_vbl_request_type(info, crtc); vbl.request.sequence = 0; ret = drmWaitVBlank(info->dri2.drm_fd, &vbl); if (ret) { @@ -1111,8 +1122,7 @@ static int radeon_dri2_schedule_swap(ClientPtr client, DrawablePtr draw, */ if (flip == 0) vbl.request.type |= DRM_VBLANK_NEXTONMISS; - if (crtc > 0) - vbl.request.type |= DRM_VBLANK_SECONDARY; + vbl.request.type |= populate_vbl_request_type(info, crtc); /* If target_msc already reached or passed, set it to * current_msc to ensure we return a reasonable value back @@ -1145,8 +1155,7 @@ static int radeon_dri2_schedule_swap(ClientPtr client, DrawablePtr draw, 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.type |= populate_vbl_request_type(info, crtc); vbl.request.sequence = current_msc - (current_msc % divisor) + remainder; @@ -1217,6 +1226,7 @@ radeon_dri2_screen_init(ScreenPtr pScreen) DRI2InfoRec dri2_info = { 0 }; #ifdef USE_DRI2_SCHEDULING const char *driverNames[1]; + uint64_t cap_value; #endif if (!info->useEXA) { @@ -1248,6 +1258,7 @@ radeon_dri2_screen_init(ScreenPtr pScreen) #endif dri2_info.CopyRegion = radeon_dri2_copy_region; + info->high_crtc_works = FALSE; #ifdef USE_DRI2_SCHEDULING if (info->dri->pKernelDRMVersion->version_minor >= 4) { dri2_info.version = 4; @@ -1261,6 +1272,20 @@ radeon_dri2_screen_init(ScreenPtr pScreen) xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "You need a newer kernel for sync extension\n"); } + if (info->drmmode.mode_res->count_crtcs > 2) { + if (drmGetCap(info->dri2.drm_fd, DRM_CAP_HIGH_CRTC, &cap_value)) { + info->high_crtc_works = FALSE; + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "You need a newer kernel for VBLANKs on CRTC > 1\n"); + } else { + if (cap_value) { + info->high_crtc_works = TRUE; + } else { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Your kernel does not handle VBLANKs on CRTC > 1\n"); + info->high_crtc_works = FALSE; + } + } + } + if (pRADEONEnt->dri2_info_cnt == 0) { #if HAS_DIXREGISTERPRIVATEKEY if (!dixRegisterPrivateKey(DRI2ClientEventsPrivateKey, PRIVATE_CLIENT, sizeof(DRI2ClientEventsRec))) {