static int sna_present_get_ust_msc(RRCrtcPtr crtc, CARD64 *ust, CARD64 *msc) { struct sna *sna = to_sna_from_screen(crtc->pScreen); int pipe = pipe_from_crtc(crtc); union drm_wait_vblank vbl; DBG(("%s(pipe=%d)\n", __FUNCTION__, pipe)); VG_CLEAR(vbl); vbl.request.type = DRM_VBLANK_RELATIVE; vbl.request.sequence = 0; if (sna_wait_vblank(sna, &vbl, pipe) == 0) { *ust = ust64(vbl.reply.tval_sec, vbl.reply.tval_usec); *msc = sna_crtc_record_vblank(crtc->devPrivate, &vbl); } else { const struct ust_msc *swap = sna_crtc_last_swap(crtc->devPrivate); *ust = ust64(swap->tv_sec, swap->tv_usec); *msc = swap->msc; } DBG(("%s: pipe=%d, tv=%d.%06d msc=%lld\n", __FUNCTION__, pipe, (int)(*ust / 1000000), (int)(*ust % 1000000), (long long)*msc)); return Success; }
static void sna_present_unflip(ScreenPtr screen, uint64_t event_id) { struct sna *sna = to_sna_from_screen(screen); struct kgem_bo *bo; DBG(("%s(event=%lld)\n", __FUNCTION__, (long long)event_id)); if (sna->mode.front_active == 0 || sna->mode.shadow_active) { const struct ust_msc *swap; DBG(("%s: no CRTC active, perform no-op flip\n", __FUNCTION__)); notify: swap = sna_crtc_last_swap(sna_mode_first_crtc(sna)); DBG(("%s: pipe=%d, tv=%d.%06d msc %lld, event %lld complete\n", __FUNCTION__, -1, swap->tv_sec, swap->tv_usec, (long long)swap->msc, (long long)event_id)); present_event_notify(event_id, ust64(swap->tv_sec, swap->tv_usec), swap->msc); return; } bo = get_flip_bo(screen->GetScreenPixmap(screen)); if (bo == NULL || !page_flip(screen, NULL, event_id, bo)) { DBG(("%s: failed, trying to restore original mode\n", __FUNCTION__)); xf86SetDesiredModes(sna->scrn); goto notify; } }
static Bool page_flip(ScreenPtr screen, RRCrtcPtr crtc, uint64_t event_id, struct kgem_bo *bo) { struct sna *sna = to_sna_from_screen(screen); struct sna_present_event *event; DBG(("%s(pipe=%d, event=%lld, handle=%d)\n", __FUNCTION__, pipe_from_crtc(crtc), (long long)event_id, bo->handle)); event = malloc(sizeof(struct sna_present_event)); if (event == NULL) return FALSE; event->event_id = event_id; event->crtc = crtc ? crtc->devPrivate : NULL; if (!sna_page_flip(sna, bo, present_flip_handler, event)) { DBG(("%s: pageflip failed\n", __FUNCTION__)); free(event); return FALSE; } return TRUE; }
static Bool page_flip__async(RRCrtcPtr crtc, uint64_t event_id, uint64_t target_msc, struct kgem_bo *bo) { DBG(("%s(pipe=%d, event=%lld, handle=%d)\n", __FUNCTION__, pipe_from_crtc(crtc), (long long)event_id, bo->handle)); if (!sna_page_flip(to_sna_from_screen(crtc->pScreen), bo, NULL, NULL)) { DBG(("%s: async pageflip failed\n", __FUNCTION__)); present_info.capabilities &= ~PresentCapabilityAsync; return FALSE; } DBG(("%s: pipe=%d tv=%d.%06d msc=%d, event %lld complete\n", __FUNCTION__, pipe_from_crtc(crtc), gettime_ust64() / 1000000, gettime_ust64() % 1000000, sna_crtc_last_swap(crtc->devPrivate)->msc, (long long)event_id)); present_event_notify(event_id, gettime_ust64(), target_msc); return TRUE; }
static int sna_present_queue_vblank(RRCrtcPtr crtc, uint64_t event_id, uint64_t msc) { struct sna *sna = to_sna_from_screen(crtc->pScreen); struct sna_present_event *event; union drm_wait_vblank vbl; DBG(("%s(pipe=%d, event=%lld, msc=%lld)\n", __FUNCTION__, pipe_from_crtc(crtc), (long long)event_id, (long long)msc)); event = malloc(sizeof(struct sna_present_event)); if (event == NULL) return BadAlloc; event->event_id = event_id; event->crtc = crtc->devPrivate; VG_CLEAR(vbl); vbl.request.type = DRM_VBLANK_ABSOLUTE | DRM_VBLANK_EVENT; vbl.request.sequence = msc; vbl.request.signal = (uintptr_t)MARK_PRESENT(event); if (sna_wait_vblank(sna, &vbl, sna_crtc_to_pipe(event->crtc))) { DBG(("%s: vblank enqueue failed\n", __FUNCTION__)); free(event); return BadMatch; } return Success; }
static int create_context(XvPortPtr port, XvMCContextPtr ctx, int *size, CARD32 **out) { struct sna *sna = to_sna_from_screen(ctx->pScreen); struct intel_xvmc_hw_context { unsigned int type; union { struct { unsigned int use_phys_addr : 1; } i915; struct { unsigned int is_g4x:1; unsigned int is_965_q:1; unsigned int is_igdng:1; } i965; }; } *priv; ctx->port_priv = port->devPriv.ptr; priv = calloc(1, sizeof(*priv)); if (priv == NULL) return BadAlloc; if (sna->kgem.gen >= 040) { int devid = intel_get_device_id(sna->dev); if (sna->kgem.gen >= 045) priv->type = XVMC_I965_MPEG2_VLD; else priv->type = XVMC_I965_MPEG2_MC; priv->i965.is_g4x = sna->kgem.gen == 045; priv->i965.is_965_q = devid == PCI_CHIP_I965_Q; priv->i965.is_igdng = sna->kgem.gen == 050; } else priv->type = XVMC_I915_MPEG2_MC; *size = sizeof(*priv) >> 2; *out = (CARD32 *)priv; return Success; }