diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2015-04-17 23:45:20 +0100 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2015-04-18 12:37:42 +0100 |
commit | 7eaf593640d4479f850227252fd793bcb55be8d3 (patch) | |
tree | 7479780f4bd8c4125135d87c3bec25cde5cdcf8d | |
parent | 75d87762471e195dddd73056fc6a06e17db1c8b0 (diff) |
sna/present: Reuse last cached swap msc/ust during a flip chain
Querying the known swap values is much slower than not!
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r-- | src/sna/sna.h | 46 | ||||
-rw-r--r-- | src/sna/sna_display.c | 239 | ||||
-rw-r--r-- | src/sna/sna_dri2.c | 26 | ||||
-rw-r--r-- | src/sna/sna_present.c | 77 | ||||
-rw-r--r-- | src/sna/sna_video_sprite.c | 18 | ||||
-rw-r--r-- | test/present-speed.c | 1 |
6 files changed, 232 insertions, 175 deletions
diff --git a/src/sna/sna.h b/src/sna/sna.h index 51533995..e51ee14f 100644 --- a/src/sna/sna.h +++ b/src/sna/sna.h @@ -591,13 +591,51 @@ static inline void sna_present_vblank_handler(struct drm_event_vblank *event) { #endif extern bool sna_crtc_set_sprite_rotation(xf86CrtcPtr crtc, uint32_t rotation); -extern int sna_crtc_to_pipe(xf86CrtcPtr crtc); -extern int sna_crtc_to_pipe__safe(xf86CrtcPtr crtc); extern uint32_t sna_crtc_to_sprite(xf86CrtcPtr crtc); -extern uint32_t sna_crtc_id(xf86CrtcPtr crtc); -extern bool sna_crtc_is_on(xf86CrtcPtr crtc); extern bool sna_crtc_is_transformed(xf86CrtcPtr crtc); +#define CRTC_VBLANK 0x3 +#define CRTC_ON 0x80000000 + +static inline unsigned long *sna_crtc_flags(xf86CrtcPtr crtc) +{ + unsigned long *flags = crtc->driver_private; + assert(flags); + return flags; +} + +static inline unsigned sna_crtc_pipe(xf86CrtcPtr crtc) +{ + return *sna_crtc_flags(crtc) >> 8 & 0xff; +} + +static inline unsigned sna_crtc_id(xf86CrtcPtr crtc) +{ + return *sna_crtc_flags(crtc) >> 16 & 0xff; +} + +static inline bool sna_crtc_is_on(xf86CrtcPtr crtc) +{ + return *sna_crtc_flags(crtc) & CRTC_ON; +} + +static inline void sna_crtc_set_vblank(xf86CrtcPtr crtc) +{ + assert((*sna_crtc_flags(crtc) & CRTC_VBLANK) < 2); + ++*sna_crtc_flags(crtc); +} + +static inline void sna_crtc_clear_vblank(xf86CrtcPtr crtc) +{ + assert(*sna_crtc_flags(crtc) & CRTC_VBLANK); + --*sna_crtc_flags(crtc); +} + +static inline bool sna_crtc_has_vblank(xf86CrtcPtr crtc) +{ + return *sna_crtc_flags(crtc) & CRTC_VBLANK; +} + CARD32 sna_format_for_depth(int depth); CARD32 sna_render_format_for_depth(int depth); diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c index 6b2c3ef2..0183246d 100644 --- a/src/sna/sna_display.c +++ b/src/sna/sna_display.c @@ -144,6 +144,7 @@ struct sna_cursor { }; struct sna_crtc { + unsigned long flags; xf86CrtcPtr base; struct drm_mode_modeinfo kmode; PixmapPtr slave_pixmap; @@ -158,8 +159,6 @@ struct sna_crtc { bool cursor_transform; bool hwcursor; bool flip_pending; - uint8_t id; - uint8_t pipe; RegionRec client_damage; /* XXX overlap with shadow damage? */ @@ -281,6 +280,16 @@ static inline struct sna_crtc *to_sna_crtc(xf86CrtcPtr crtc) return crtc->driver_private; } +static inline unsigned __sna_crtc_pipe(struct sna_crtc *crtc) +{ + return crtc->flags >> 8 & 0xff; +} + +static inline unsigned __sna_crtc_id(struct sna_crtc *crtc) +{ + return crtc->flags >> 16 & 0xff; +} + static inline bool event_pending(int fd) { struct pollfd pfd; @@ -302,39 +311,12 @@ static inline uint32_t fb_id(struct kgem_bo *bo) return bo->delta; } -uint32_t sna_crtc_id(xf86CrtcPtr crtc) -{ - if (to_sna_crtc(crtc) == NULL) - return 0; - return to_sna_crtc(crtc)->id; -} - -int sna_crtc_to_pipe(xf86CrtcPtr crtc) -{ - assert(to_sna_crtc(crtc)); - return to_sna_crtc(crtc)->pipe; -} - -int sna_crtc_to_pipe__safe(xf86CrtcPtr crtc) -{ - if (to_sna_crtc(crtc)) - return sna_crtc_to_pipe(crtc); - else - return sna_crtc_to_pipe(sna_primary_crtc(to_sna(crtc->scrn))); -} - uint32_t sna_crtc_to_sprite(xf86CrtcPtr crtc) { assert(to_sna_crtc(crtc)); return to_sna_crtc(crtc)->sprite.id; } -bool sna_crtc_is_on(xf86CrtcPtr crtc) -{ - assert(to_sna_crtc(crtc)); - return to_sna_crtc(crtc)->bo != NULL; -} - bool sna_crtc_is_transformed(xf86CrtcPtr crtc) { assert(to_sna_crtc(crtc)); @@ -348,11 +330,11 @@ static inline bool msc64(struct sna_crtc *sna_crtc, uint32_t seq, uint64_t *msc) if (sna_crtc->last_seq - seq > 0x40000000) { sna_crtc->wrap_seq++; DBG(("%s: pipe=%d wrapped; was %u, now %u, wraps=%u\n", - __FUNCTION__, sna_crtc->pipe, + __FUNCTION__, __sna_crtc_pipe(sna_crtc), sna_crtc->last_seq, seq, sna_crtc->wrap_seq)); } else { DBG(("%s: pipe=%d msc went backwards; was %u, now %u; ignoring for last_swap\n", - __FUNCTION__, sna_crtc->pipe, sna_crtc->last_seq, seq)); + __FUNCTION__, __sna_crtc_pipe(sna_crtc), sna_crtc->last_seq, seq)); record = false; } @@ -371,14 +353,14 @@ uint64_t sna_crtc_record_swap(xf86CrtcPtr crtc, if (msc64(sna_crtc, seq, &msc)) { DBG(("%s: recording last swap on pipe=%d, frame %d [%08llx], time %d.%06d\n", - __FUNCTION__, sna_crtc->pipe, seq, (long long)msc, + __FUNCTION__, __sna_crtc_pipe(sna_crtc), seq, (long long)msc, tv_sec, tv_usec)); sna_crtc->swap.tv_sec = tv_sec; sna_crtc->swap.tv_usec = tv_usec; sna_crtc->swap.msc = msc; } else { DBG(("%s: swap event on pipe=%d, frame %d [%08llx], time %d.%06d\n", - __FUNCTION__, sna_crtc->pipe, seq, (long long)msc, + __FUNCTION__, __sna_crtc_pipe(sna_crtc), seq, (long long)msc, tv_sec, tv_usec)); } @@ -939,7 +921,7 @@ sna_crtc_force_outputs_on(xf86CrtcPtr crtc) int i; assert(to_sna_crtc(crtc)); - DBG(("%s(pipe=%d)\n", __FUNCTION__, to_sna_crtc(crtc)->pipe)); + DBG(("%s(pipe=%d)\n", __FUNCTION__, sna_crtc_pipe(crtc))); /* DPMS handling by the kernel is inconsistent, so after setting a * mode on an output presume that we intend for it to be on, or that @@ -969,7 +951,7 @@ sna_crtc_force_outputs_off(xf86CrtcPtr crtc) int i; assert(to_sna_crtc(crtc)); - DBG(("%s(pipe=%d)\n", __FUNCTION__, to_sna_crtc(crtc)->pipe)); + DBG(("%s(pipe=%d)\n", __FUNCTION__, sna_crtc_pipe(crtc))); /* DPMS handling by the kernel is inconsistent, so after setting a * mode on an output presume that we intend for it to be on, or that @@ -1068,8 +1050,8 @@ bool sna_crtc_set_sprite_rotation(xf86CrtcPtr crtc, uint32_t rotation) assert(to_sna_crtc(crtc)); DBG(("%s: CRTC:%d [pipe=%d], sprite=%u set-rotation=%x\n", __FUNCTION__, - to_sna_crtc(crtc)->id, to_sna_crtc(crtc)->pipe, to_sna_crtc(crtc)->sprite.id, - rotation)); + sna_crtc_id(crtc), sna_crtc_pipe(crtc), + to_sna_crtc(crtc)->sprite.id, rotation)); return rotation_set(to_sna(crtc->scrn), &to_sna_crtc(crtc)->sprite, @@ -1087,10 +1069,12 @@ sna_crtc_apply(xf86CrtcPtr crtc) int output_count = 0; int i; - DBG(("%s CRTC:%d [pipe=%d], handle=%d\n", __FUNCTION__, sna_crtc->id, sna_crtc->pipe, sna_crtc->bo->handle)); + DBG(("%s CRTC:%d [pipe=%d], handle=%d\n", __FUNCTION__, + __sna_crtc_id(sna_crtc), __sna_crtc_pipe(sna_crtc), + sna_crtc->bo->handle)); if (!sna_crtc->kmode.clock) { ERR(("%s(CRTC:%d [pipe=%d]): attempted to set an invalid mode\n", - __FUNCTION__, sna_crtc->id, sna_crtc->pipe)); + __FUNCTION__, __sna_crtc_id(sna_crtc), __sna_crtc_pipe(sna_crtc))); return false; } @@ -1099,12 +1083,12 @@ sna_crtc_apply(xf86CrtcPtr crtc) if (!rotation_set(sna, &sna_crtc->primary, sna_crtc->rotation)) { ERR(("%s: set-primary-rotation failed (rotation-id=%d, rotation=%d) on CRTC:%d [pipe=%d], errno=%d\n", - __FUNCTION__, sna_crtc->primary.rotation.prop, sna_crtc->rotation, sna_crtc->id, sna_crtc->pipe, errno)); + __FUNCTION__, sna_crtc->primary.rotation.prop, sna_crtc->rotation, __sna_crtc_id(sna_crtc), __sna_crtc_pipe(sna_crtc), errno)); sna_crtc->primary.rotation.supported &= ~sna_crtc->rotation; return false; } DBG(("%s: CRTC:%d [pipe=%d] primary rotation set to %x\n", - __FUNCTION__, sna_crtc->id, sna_crtc->pipe, sna_crtc->rotation)); + __FUNCTION__, __sna_crtc_id(sna_crtc), __sna_crtc_pipe(sna_crtc), sna_crtc->rotation)); for (i = 0; i < sna->mode.num_real_output; i++) { xf86OutputPtr output = config->output[i]; @@ -1129,11 +1113,11 @@ sna_crtc_apply(xf86CrtcPtr crtc) DBG(("%s: attaching output '%s' %d [%d] to crtc:%d (pipe %d) (possible crtc:%x, possible clones:%x)\n", __FUNCTION__, output->name, i, to_connector_id(output), - sna_crtc->id, sna_crtc->pipe, + __sna_crtc_id(sna_crtc), __sna_crtc_pipe(sna_crtc), (uint32_t)output->possible_crtcs, (uint32_t)output->possible_clones)); - assert(output->possible_crtcs & (1 << sna_crtc->pipe) || + assert(output->possible_crtcs & (1 << __sna_crtc_pipe(sna_crtc)) || is_zaphod(crtc->scrn)); output_ids[output_count] = to_connector_id(output); @@ -1151,7 +1135,7 @@ sna_crtc_apply(xf86CrtcPtr crtc) } VG_CLEAR(arg); - arg.crtc_id = sna_crtc->id; + arg.crtc_id = __sna_crtc_id(sna_crtc); arg.fb_id = fb_id(sna_crtc->bo); if (sna_crtc->transform || sna_crtc->slave_pixmap) { arg.x = 0; @@ -1168,7 +1152,7 @@ sna_crtc_apply(xf86CrtcPtr crtc) arg.mode_valid = 1; DBG(("%s: applying crtc [%d, pipe=%d] mode=%dx%d+%d+%d@%d, fb=%d%s%s update to %d outputs [%d...]\n", - __FUNCTION__, sna_crtc->id, sna_crtc->pipe, + __FUNCTION__, __sna_crtc_id(sna_crtc), __sna_crtc_pipe(sna_crtc), arg.mode.hdisplay, arg.mode.vdisplay, arg.x, arg.y, @@ -1535,7 +1519,7 @@ static void sna_crtc_slave_damage(DamagePtr damage, RegionPtr region, void *clos __FUNCTION__, region->extents.x1, region->extents.y1, region->extents.x2, region->extents.y2, region_num_rects(region), - crtc->pipe, crtc->base->x, crtc->base->y)); + __sna_crtc_pipe(crtc), crtc->base->x, crtc->base->y)); assert(crtc->slave_damage == damage); assert(sna->mode.shadow_damage); @@ -1553,7 +1537,7 @@ static bool sna_crtc_enable_shadow(struct sna *sna, struct sna_crtc *crtc) return true; } - DBG(("%s: enabling for crtc %d\n", __FUNCTION__, crtc->id)); + DBG(("%s: enabling for crtc %d\n", __FUNCTION__, __sna_crtc_id(crtc))); if (!sna->mode.shadow_active) { if (!sna_mode_enable_shadow(sna)) @@ -1566,7 +1550,7 @@ static bool sna_crtc_enable_shadow(struct sna *sna, struct sna_crtc *crtc) assert(crtc->slave_damage == NULL); DBG(("%s: enabling PRIME slave tracking on CRTC %d [pipe=%d], pixmap=%ld\n", - __FUNCTION__, crtc->id, crtc->pipe, crtc->slave_pixmap->drawable.serialNumber)); + __FUNCTION__, __sna_crtc_id(crtc), __sna_crtc_pipe(crtc), crtc->slave_pixmap->drawable.serialNumber)); crtc->slave_damage = DamageCreate(sna_crtc_slave_damage, NULL, DamageReportRawRegion, TRUE, to_screen_from_sna(sna), @@ -1616,7 +1600,7 @@ static void sna_crtc_disable_shadow(struct sna *sna, struct sna_crtc *crtc) if (!crtc->shadow) return; - DBG(("%s: disabling for crtc %d\n", __FUNCTION__, crtc->id)); + DBG(("%s: disabling for crtc %d\n", __FUNCTION__, __sna_crtc_id(crtc))); assert(sna->mode.shadow_active > 0); if (crtc->slave_damage) { @@ -1646,11 +1630,13 @@ __sna_crtc_disable(struct sna *sna, struct sna_crtc *sna_crtc) if (sna_crtc->bo) { DBG(("%s: releasing handle=%d from scanout, active=%d\n", __FUNCTION__,sna_crtc->bo->handle, sna_crtc->bo->active_scanout-1)); + assert(sna_crtc->flags & CRTC_ON); assert(sna_crtc->bo->active_scanout); assert(sna_crtc->bo->refcnt >= sna_crtc->bo->active_scanout); sna_crtc->bo->active_scanout--; kgem_bo_destroy(&sna->kgem, sna_crtc->bo); sna_crtc->bo = NULL; + sna_crtc->flags &= ~CRTC_ON; if (sna->mode.hidden) { sna->mode.hidden--; @@ -1692,12 +1678,12 @@ sna_crtc_disable(xf86CrtcPtr crtc, bool force) return; DBG(("%s: disabling crtc [%d, pipe=%d], force?=%d\n", __FUNCTION__, - sna_crtc->id, sna_crtc->pipe, force)); + __sna_crtc_id(sna_crtc), __sna_crtc_pipe(sna_crtc), force)); sna_crtc_force_outputs_off(crtc); memset(&arg, 0, sizeof(arg)); - arg.crtc_id = sna_crtc->id; + arg.crtc_id = __sna_crtc_id(sna_crtc); (void)drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_SETCRTC, &arg); __sna_crtc_disable(sna, sna_crtc); @@ -1717,19 +1703,19 @@ static void update_flush_interval(struct sna *sna) if (!crtc->enabled) { DBG(("%s: CRTC:%d (pipe %d) disabled\n", - __FUNCTION__,i, to_sna_crtc(crtc)->pipe)); + __FUNCTION__,i, sna_crtc_pipe(crtc))); assert(to_sna_crtc(crtc)->bo == NULL); continue; } if (to_sna_crtc(crtc)->bo == NULL) { DBG(("%s: CRTC:%d (pipe %d) turned off\n", - __FUNCTION__,i, to_sna_crtc(crtc)->pipe)); + __FUNCTION__,i, sna_crtc_pipe(crtc))); continue; } DBG(("%s: CRTC:%d (pipe %d) vrefresh=%f\n", - __FUNCTION__, i, to_sna_crtc(crtc)->pipe, + __FUNCTION__, i, sna_crtc_pipe(crtc), xf86ModeVRefresh(&crtc->mode))); max_vrefresh = max(max_vrefresh, xf86ModeVRefresh(&crtc->mode)); } @@ -1805,7 +1791,7 @@ void sna_copy_fbcon(struct sna *sna) assert(crtc != NULL); VG_CLEAR(mode); - mode.crtc_id = crtc->id; + mode.crtc_id = __sna_crtc_id(crtc); if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETCRTC, &mode)) continue; if (!mode.fb_id) @@ -2445,7 +2431,7 @@ sna_crtc_damage(xf86CrtcPtr crtc) } DBG(("%s: marking crtc %d as completely damaged (%d, %d), (%d, %d)\n", - __FUNCTION__, to_sna_crtc(crtc)->id, + __FUNCTION__, sna_crtc_id(crtc), region.extents.x1, region.extents.y1, region.extents.x2, region.extents.y2)); to_sna_crtc(crtc)->client_damage = region; @@ -2516,7 +2502,7 @@ __sna_crtc_set_mode(xf86CrtcPtr crtc) bool saved_cursor_transform; DBG(("%s: CRTC=%d, pipe=%d, hidden?=%d\n", __FUNCTION__, - sna_crtc->id, sna_crtc->pipe, sna->mode.hidden)); + __sna_crtc_id(sna_crtc), __sna_crtc_pipe(sna_crtc), sna->mode.hidden)); if (sna->mode.hidden) return TRUE; @@ -2555,6 +2541,7 @@ retry: /* Attach per-crtc pixmap or direct */ goto error; } + sna_crtc->flags |= CRTC_ON; bo->active_scanout++; DBG(("%s: marking handle=%d as active=%d (removing %d from scanout, active=%d)\n", __FUNCTION__, bo->handle, bo->active_scanout, @@ -2616,14 +2603,14 @@ sna_crtc_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode, xf86DrvMsg(crtc->scrn->scrnIndex, X_INFO, "switch to mode %dx%d@%.1f on %s using pipe %d, position (%d, %d), rotation %s, reflection %s\n", mode->HDisplay, mode->VDisplay, xf86ModeVRefresh(mode), - outputs_for_crtc(crtc, outputs, sizeof(outputs)), sna_crtc->pipe, + outputs_for_crtc(crtc, outputs, sizeof(outputs)), __sna_crtc_pipe(sna_crtc), x, y, rotation_to_str(rotation), reflection_to_str(rotation)); assert(mode->HDisplay <= sna->mode.max_crtc_width && mode->VDisplay <= sna->mode.max_crtc_height); #if HAS_GAMMA - drmModeCrtcSetGamma(sna->kgem.fd, sna_crtc->id, + drmModeCrtcSetGamma(sna->kgem.fd, __sna_crtc_id(sna_crtc), crtc->gamma_size, crtc->gamma_red, crtc->gamma_green, @@ -2643,7 +2630,7 @@ static void sna_crtc_dpms(xf86CrtcPtr crtc, int mode) { DBG(("%s(pipe %d, dpms mode -> %d):= active=%d\n", - __FUNCTION__, to_sna_crtc(crtc)->pipe, mode, mode == DPMSModeOn)); + __FUNCTION__, sna_crtc_pipe(crtc), mode, mode == DPMSModeOn)); if (mode == DPMSModeOn && crtc->enabled) { if (__sna_crtc_set_mode(crtc)) @@ -2689,7 +2676,7 @@ sna_crtc_gamma_set(xf86CrtcPtr crtc, { assert(to_sna_crtc(crtc)); drmModeCrtcSetGamma(to_sna(crtc->scrn)->kgem.fd, - to_sna_crtc(crtc)->id, + sna_crtc_id(crtc), size, red, green, blue); } @@ -2718,7 +2705,7 @@ sna_crtc_set_scanout_pixmap(xf86CrtcPtr crtc, PixmapPtr pixmap) return TRUE; DBG(("%s: CRTC:%d, pipe=%d setting scanout pixmap=%ld\n", - __FUNCTION__, sna_crtc->id, sna_crtc->pipe, + __FUNCTION__, __sna_crtc_id(sna_crtc), __sna_crtc_pipe(sna_crtc), pixmap ? pixmap->drawable.serialNumber : 0)); /* Disable first so that we can unregister the damage tracking */ @@ -2912,11 +2899,11 @@ sna_crtc_find_planes(struct sna *sna, struct sna_crtc *crtc) if (drmIoctl(sna->kgem.fd, LOCAL_IOCTL_MODE_GETPLANE, &p)) continue; - if ((p.possible_crtcs & (1 << crtc->pipe)) == 0) + if ((p.possible_crtcs & (1 << __sna_crtc_pipe(crtc))) == 0) continue; DBG(("%s: plane %d is attached to our pipe=%d\n", - __FUNCTION__, planes[i], crtc->pipe)); + __FUNCTION__, planes[i], __sna_crtc_pipe(crtc))); details.id = p.plane_id; details.rotation.prop = 0; @@ -2961,7 +2948,7 @@ sna_crtc_init__cursor(struct sna *sna, struct sna_crtc *crtc) VG_CLEAR(arg); arg.flags = DRM_MODE_CURSOR_BO; - arg.crtc_id = crtc->id; + arg.crtc_id = __sna_crtc_id(crtc); arg.width = arg.height = 0; arg.handle = 0; @@ -2970,7 +2957,7 @@ sna_crtc_init__cursor(struct sna *sna, struct sna_crtc *crtc) } static bool -sna_crtc_add(ScrnInfoPtr scrn, int id) +sna_crtc_add(ScrnInfoPtr scrn, unsigned id) { struct sna *sna = to_sna(scrn); xf86CrtcPtr crtc; @@ -2983,21 +2970,23 @@ sna_crtc_add(ScrnInfoPtr scrn, int id) if (sna_crtc == NULL) return false; - sna_crtc->id = id; + assert(id < 256); + sna_crtc->flags = id << 16; VG_CLEAR(get_pipe); get_pipe.pipe = 0; - get_pipe.crtc_id = sna_crtc->id; + get_pipe.crtc_id = id; if (drmIoctl(sna->kgem.fd, DRM_IOCTL_I915_GET_PIPE_FROM_CRTC_ID, &get_pipe)) { free(sna_crtc); return false; } - sna_crtc->pipe = get_pipe.pipe; + assert((unsigned)get_pipe.pipe < 256); + sna_crtc->flags |= get_pipe.pipe << 8; if (is_zaphod(scrn) && - scrn->confScreen->device->screen != sna_crtc->pipe) { + scrn->confScreen->device->screen != get_pipe.pipe) { free(sna_crtc); return true; } @@ -3007,7 +2996,7 @@ sna_crtc_add(ScrnInfoPtr scrn, int id) sna_crtc_find_planes(sna, sna_crtc); DBG(("%s: CRTC:%d [pipe=%d], primary id=%x: supported-rotations=%x, current-rotation=%x, sprite id=%x: supported-rotations=%x, current-rotation=%x\n", - __FUNCTION__, sna_crtc->id, sna_crtc->pipe, + __FUNCTION__, id, get_pipe.pipe, sna_crtc->primary.id, sna_crtc->primary.rotation.supported, sna_crtc->primary.rotation.current, sna_crtc->sprite.id, sna_crtc->sprite.rotation.supported, sna_crtc->sprite.rotation.current)); @@ -3024,7 +3013,7 @@ sna_crtc_add(ScrnInfoPtr scrn, int id) crtc->driver_private = sna_crtc; sna_crtc->base = crtc; DBG(("%s: attached crtc[%d] pipe=%d\n", - __FUNCTION__, id, sna_crtc->pipe)); + __FUNCTION__, id, __sna_crtc_pipe(sna_crtc))); return true; } @@ -3486,12 +3475,12 @@ sna_output_get_modes(xf86OutputPtr output) VG_CLEAR(mode); assert(to_sna_crtc(output->crtc)); - mode.crtc_id = to_sna_crtc(output->crtc)->id; + mode.crtc_id = sna_crtc_id(output->crtc); if (drmIoctl(to_sna(output->scrn)->kgem.fd, DRM_IOCTL_MODE_GETCRTC, &mode) == 0) { DBG(("%s: CRTC:%d, pipe=%d: has mode?=%d\n", __FUNCTION__, - to_sna_crtc(output->crtc)->id, - to_sna_crtc(output->crtc)->pipe, + sna_crtc_id(output->crtc), + sna_crtc_pipe(output->crtc), mode.mode_valid && mode.mode.clock)); if (mode.mode_valid && mode.mode.clock) { @@ -4600,7 +4589,7 @@ static bool disable_unused_crtc(struct sna *sna) if (o == sna->mode.num_real_output) { DBG(("%s: CRTC:%d was enabled with no outputs\n", - __FUNCTION__, to_sna_crtc(crtc)->id)); + __FUNCTION__, sna_crtc_id(crtc))); crtc->enabled = false; update = true; } @@ -5288,7 +5277,7 @@ sna_show_cursors(ScrnInfoPtr scrn) if (!crtc->cursor_in_range) { DBG(("%s: skipping cursor outside CRTC (pipe=%d)\n", - __FUNCTION__, sna_crtc->pipe)); + __FUNCTION__, sna_crtc_pipe(crtc))); continue; } @@ -5296,16 +5285,16 @@ sna_show_cursors(ScrnInfoPtr scrn) if (cursor == NULL || (sna_crtc->cursor == cursor && sna_crtc->last_cursor_size == cursor->size)) { DBG(("%s: skipping cursor already show on CRTC (pipe=%d)\n", - __FUNCTION__, sna_crtc->pipe)); + __FUNCTION__, sna_crtc_pipe(crtc))); continue; } DBG(("%s: CRTC pipe=%d, handle->%d\n", __FUNCTION__, - sna_crtc->pipe, cursor->handle)); + sna_crtc_pipe(crtc), cursor->handle)); VG_CLEAR(arg); arg.flags = DRM_MODE_CURSOR_BO; - arg.crtc_id = sna_crtc->id; + arg.crtc_id = __sna_crtc_id(sna_crtc); arg.width = arg.height = cursor->size; arg.handle = cursor->handle; @@ -5363,7 +5352,7 @@ sna_crtc_disable_cursor(struct sna *sna, struct sna_crtc *crtc) sigio = sigio_block(); if (crtc->cursor) { - DBG(("%s: CRTC:%d, handle=%d\n", __FUNCTION__, crtc->id, crtc->cursor->handle)); + DBG(("%s: CRTC:%d, handle=%d\n", __FUNCTION__, __sna_crtc_id(crtc), crtc->cursor->handle)); assert(crtc->cursor->ref > 0); crtc->cursor->ref--; crtc->cursor = NULL; @@ -5371,7 +5360,7 @@ sna_crtc_disable_cursor(struct sna *sna, struct sna_crtc *crtc) VG_CLEAR(arg); arg.flags = DRM_MODE_CURSOR_BO; - arg.crtc_id = crtc->id; + arg.crtc_id = __sna_crtc_id(crtc); arg.width = arg.height = 0; arg.handle = 0; @@ -5464,7 +5453,7 @@ sna_set_cursor_position(ScrnInfoPtr scrn, int x, int y) VG_CLEAR(arg); arg.flags = 0; - arg.crtc_id = sna_crtc->id; + arg.crtc_id = __sna_crtc_id(sna_crtc); arg.handle = 0; if (sna_crtc->bo == NULL) @@ -5520,7 +5509,7 @@ disable: } __DBG(("%s: CRTC:%d (%d, %d), handle=%d, flags=%x (old cursor handle=%d), move? %d, update handle? %d\n", - __FUNCTION__, sna_crtc->id, arg.x, arg.y, arg.handle, arg.flags, sna_crtc->cursor ? sna_crtc->cursor->handle : 0, + __FUNCTION__, __sna_crtc_id(sna_crtc), arg.x, arg.y, arg.handle, arg.flags, sna_crtc->cursor ? sna_crtc->cursor->handle : 0, arg.flags & DRM_MODE_CURSOR_MOVE, arg.flags & DRM_MODE_CURSOR_BO)); if (arg.flags && @@ -5596,7 +5585,7 @@ transformable_cursor(struct sna *sna, CursorPtr cursor) if (!to_sna_crtc(crtc)->hwcursor) { DBG(("%s: hwcursor disabled on CRTC:%d [pipe=%d]\n", - __FUNCTION__, to_sna_crtc(crtc)->id, to_sna_crtc(crtc)->pipe)); + __FUNCTION__, sna_crtc_id(crtc), sna_crtc_pipe(crtc))); return false; } @@ -5824,7 +5813,7 @@ sna_crtc_flip(struct sna *sna, struct sna_crtc *crtc, struct kgem_bo *bo, int x, int output_count = 0; int i; - DBG(("%s CRTC:%d [pipe=%d], handle=%d\n", __FUNCTION__, crtc->id, crtc->pipe, bo->handle)); + DBG(("%s CRTC:%d [pipe=%d], handle=%d\n", __FUNCTION__, __sna_crtc_id(crtc), __sna_crtc_pipe(crtc), bo->handle)); assert(sna->mode.num_real_output < ARRAY_SIZE(output_ids)); assert(crtc->bo); @@ -5838,11 +5827,11 @@ sna_crtc_flip(struct sna *sna, struct sna_crtc *crtc, struct kgem_bo *bo, int x, DBG(("%s: attaching output '%s' %d [%d] to crtc:%d (pipe %d) (possible crtc:%x, possible clones:%x)\n", __FUNCTION__, output->name, i, to_connector_id(output), - crtc->id, crtc->pipe, + __sna_crtc_id(crtc), __sna_crtc_pipe(crtc), (uint32_t)output->possible_crtcs, (uint32_t)output->possible_clones)); - assert(output->possible_crtcs & (1 << crtc->pipe) || + assert(output->possible_crtcs & (1 << __sna_crtc_pipe(crtc)) || is_zaphod(sna->scrn)); output_ids[output_count] = to_connector_id(output); @@ -5852,7 +5841,7 @@ sna_crtc_flip(struct sna *sna, struct sna_crtc *crtc, struct kgem_bo *bo, int x, assert(output_count); VG_CLEAR(arg); - arg.crtc_id = crtc->id; + arg.crtc_id = __sna_crtc_id(crtc); arg.fb_id = fb_id(bo); assert(arg.fb_id); arg.x = x; @@ -5863,7 +5852,7 @@ sna_crtc_flip(struct sna *sna, struct sna_crtc *crtc, struct kgem_bo *bo, int x, arg.mode_valid = 1; DBG(("%s: applying crtc [%d, pipe=%d] mode=%dx%d+%d+%d@%d, fb=%d across %d outputs [%d...]\n", - __FUNCTION__, crtc->id, crtc->pipe, + __FUNCTION__, __sna_crtc_id(crtc), __sna_crtc_pipe(crtc), arg.mode.hdisplay, arg.mode.vdisplay, arg.x, arg.y, @@ -5941,7 +5930,7 @@ sna_page_flip(struct sna *sna, uint32_t crtc_offset; DBG(("%s: crtc %d id=%d, pipe=%d active? %d\n", - __FUNCTION__, i, crtc->id, crtc->pipe, crtc->bo != NULL)); + __FUNCTION__, i, __sna_crtc_id(crtc), __sna_crtc_pipe(crtc), crtc->bo != NULL)); if (crtc->bo == NULL) continue; assert(!crtc->transform); @@ -5953,7 +5942,7 @@ sna_page_flip(struct sna *sna, if (data == NULL && crtc->bo == bo) goto next_crtc; - arg.crtc_id = crtc->id; + arg.crtc_id = __sna_crtc_id(crtc); arg.fb_id = get_fb(sna, bo, width, height); if (arg.fb_id == 0) { assert(count == 0); @@ -6011,7 +6000,7 @@ update_scanout: retry_flip: DBG(("%s: crtc %d id=%d, pipe=%d --> fb %d\n", - __FUNCTION__, i, crtc->id, crtc->pipe, arg.fb_id)); + __FUNCTION__, i, __sna_crtc_id(crtc), __sna_crtc_pipe(crtc), arg.fb_id)); if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_PAGE_FLIP, &arg)) { ERR(("%s: pageflip failed with err=%d\n", __FUNCTION__, errno)); @@ -6019,7 +6008,7 @@ retry_flip: struct drm_mode_crtc mode; memset(&mode, 0, sizeof(mode)); - mode.crtc_id = crtc->id; + mode.crtc_id = __sna_crtc_id(crtc); drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETCRTC, &mode); DBG(("%s: crtc=%d, valid?=%d, fb attached?=%d, expected=%d\n", @@ -6043,7 +6032,7 @@ retry_flip: if (sna->flags & (data ? SNA_HAS_FLIP : SNA_HAS_ASYNC_FLIP)) { xf86DrvMsg(sna->scrn->scrnIndex, X_ERROR, "page flipping failed, on CRTC:%d (pipe=%d), disabling %s page flips\n", - crtc->id, crtc->pipe, data ? "synchronous": "asynchronous"); + __sna_crtc_id(crtc), __sna_crtc_pipe(crtc), data ? "synchronous": "asynchronous"); sna->flags &= ~(data ? SNA_HAS_FLIP : SNA_HAS_ASYNC_FLIP); goto fixup_flip; } @@ -6064,7 +6053,7 @@ retry_flip: sna->mode.flip_active++; DBG(("%s: recording flip on CRTC:%d handle=%d, active_scanout=%d, serial=%d\n", - __FUNCTION__, crtc->id, crtc->flip_bo->handle, crtc->flip_bo->active_scanout, crtc->flip_serial)); + __FUNCTION__, __sna_crtc_id(crtc), crtc->flip_bo->handle, crtc->flip_bo->active_scanout, crtc->flip_serial)); } else goto update_scanout; next_crtc: @@ -6145,7 +6134,7 @@ static void crtc_init_gamma(xf86CrtcPtr crtc) assert(sna_crtc); - lut.crtc_id = sna_crtc->id; + lut.crtc_id = __sna_crtc_id(sna_crtc); lut.gamma_size = 256; lut.red = (uintptr_t)(gamma); lut.green = (uintptr_t)(gamma + 256); @@ -6159,7 +6148,7 @@ static void crtc_init_gamma(xf86CrtcPtr crtc) } DBG(("%s: CRTC:%d, pipe=%d: gamma set?=%d\n", - __FUNCTION__, sna_crtc->id, sna_crtc->pipe, + __FUNCTION__, __sna_crtc_id(sna_crtc), __sna_crtc_pipe(sna_crtc), gamma_set)); if (!gamma_set) { int i; @@ -6251,12 +6240,12 @@ static bool sna_probe_initial_configuration(struct sna *sna) /* Retrieve the current mode */ VG_CLEAR(mode); - mode.crtc_id = sna_crtc->id; + mode.crtc_id = __sna_crtc_id(sna_crtc); if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETCRTC, &mode)) continue; DBG(("%s: CRTC:%d, pipe=%d: has mode?=%d\n", __FUNCTION__, - sna_crtc->id, sna_crtc->pipe, + __sna_crtc_id(sna_crtc), __sna_crtc_pipe(sna_crtc), mode.mode_valid && mode.mode.clock)); if (!mode.mode_valid || mode.mode.clock == 0) @@ -6298,7 +6287,7 @@ static bool sna_probe_initial_configuration(struct sna *sna) xf86CrtcPtr crtc = config->crtc[j]; assert(to_sna_crtc(crtc)); - if (to_sna_crtc(crtc)->id != crtc_id) + if (sna_crtc_id(crtc) != crtc_id) continue; if (crtc->desiredMode.status == MODE_OK) { @@ -6316,7 +6305,7 @@ static bool sna_probe_initial_configuration(struct sna *sna) "Output %s using initial mode %s on pipe %d\n", output->name, crtc->desiredMode.name, - to_sna_crtc(crtc)->pipe); + sna_crtc_pipe(crtc)); output->crtc = crtc; output->status = XF86OutputStatusConnected; @@ -7154,7 +7143,7 @@ sna_wait_for_scanline(struct sna *sna, y2 /= 2; } - pipe = sna_crtc_to_pipe(crtc); + pipe = sna_crtc_pipe(crtc); DBG(("%s: pipe=%d, y1=%d, y2=%d, full_height?=%d\n", __FUNCTION__, pipe, y1, y2, full_height)); @@ -7206,7 +7195,7 @@ void sna_mode_check(struct sna *sna) expected[1] = sna_crtc->flip_bo ? fb_id(sna_crtc->flip_bo) : -1; VG_CLEAR(mode); - mode.crtc_id = sna_crtc->id; + mode.crtc_id = __sna_crtc_id(sna_crtc); if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETCRTC, &mode)) continue; @@ -7218,7 +7207,7 @@ void sna_mode_check(struct sna *sna) if (mode.fb_id != expected[0] && mode.fb_id != expected[1]) { xf86DrvMsg(crtc->scrn->scrnIndex, X_ERROR, "%s: invalid state found on pipe %d, disabling CRTC:%d\n", - __FUNCTION__, sna_crtc->pipe, sna_crtc->id); + __FUNCTION__, __sna_crtc_pipe(sna_crtc), __sna_crtc_id(sna_crtc)); sna_crtc_disable(crtc, true); } } @@ -7604,7 +7593,7 @@ sna_crtc_redisplay(xf86CrtcPtr crtc, RegionPtr region, struct kgem_bo *bo) struct sna_pixmap *priv = sna_pixmap((PixmapPtr)draw); DBG(("%s: crtc %d [pipe=%d], damage (%d, %d), (%d, %d) x %d\n", - __FUNCTION__, to_sna_crtc(crtc)->id, to_sna_crtc(crtc)->pipe, + __FUNCTION__, sna_crtc_id(crtc), sna_crtc_pipe(crtc), region->extents.x1, region->extents.y1, region->extents.x2, region->extents.y2, region_num_rects(region))); @@ -7673,11 +7662,11 @@ void sna_shadow_set_crtc(struct sna *sna, struct sna_crtc *sna_crtc = to_sna_crtc(crtc); struct sna_pixmap *priv; + assert(sna_crtc); DBG(("%s: setting shadow override for CRTC:%d to handle=%d\n", - __FUNCTION__, sna_crtc->id, bo->handle)); + __FUNCTION__, __sna_crtc_id(sna_crtc), bo->handle)); assert(sna->flags & SNA_TEAR_FREE); - assert(sna_crtc); assert(!sna_crtc->transform); if (sna_crtc->client_bo != bo) { @@ -7737,7 +7726,7 @@ void sna_shadow_unset_crtc(struct sna *sna, struct sna_crtc *sna_crtc = to_sna_crtc(crtc); DBG(("%s: clearin shadow override for CRTC:%d\n", - __FUNCTION__, sna_crtc->id)); + __FUNCTION__, __sna_crtc_id(sna_crtc))); if (sna_crtc->client_bo == NULL) return; @@ -7771,7 +7760,7 @@ static bool move_crtc_to_gpu(struct sna *sna) continue; DBG(("%s: CRTC %d [pipe=%d] requires frontbuffer\n", - __FUNCTION__, crtc->id, crtc->pipe)); + __FUNCTION__, __sna_crtc_id(crtc), __sna_crtc_pipe(crtc))); return sna_pixmap_move_to_gpu(sna->front, MOVE_READ | MOVE_ASYNC_HINT | __MOVE_SCANOUT); } @@ -7849,7 +7838,7 @@ void sna_mode_redisplay(struct sna *sna) struct kgem_bo *bo = NULL; DBG(("%s: fallback intersects pipe=%d [(%d, %d), (%d, %d)]\n", - __FUNCTION__, sna_crtc->pipe, + __FUNCTION__, __sna_crtc_pipe(sna_crtc), damage.extents.x1, damage.extents.y1, damage.extents.x2, damage.extents.y2)); @@ -7884,7 +7873,7 @@ void sna_mode_redisplay(struct sna *sna) if (bo != sna_crtc->bo) { struct drm_mode_crtc_page_flip arg; - arg.crtc_id = sna_crtc->id; + arg.crtc_id = __sna_crtc_id(sna_crtc); arg.fb_id = get_fb(sna, bo, crtc->mode.HDisplay, crtc->mode.VDisplay); @@ -7908,7 +7897,7 @@ void sna_mode_redisplay(struct sna *sna) sna_crtc->cache_bo = NULL; } else { DBG(("%s: flip [fb=%d] on crtc %d [%d, pipe=%d] failed - %d\n", - __FUNCTION__, arg.fb_id, i, sna_crtc->id, sna_crtc->pipe, errno)); + __FUNCTION__, arg.fb_id, i, __sna_crtc_id(sna_crtc), __sna_crtc_pipe(sna_crtc), errno)); xf86DrvMsg(sna->scrn->scrnIndex, X_ERROR, "Page flipping failed, disabling TearFree\n"); sna->flags &= ~SNA_TEAR_FREE; @@ -7934,7 +7923,7 @@ void sna_mode_redisplay(struct sna *sna) sna_crtc->cache_bo = kgem_bo_reference(sna_crtc->bo); DBG(("%s: recording flip on CRTC:%d handle=%d, active_scanout=%d, serial=%d\n", - __FUNCTION__, sna_crtc->id, sna_crtc->flip_bo->handle, sna_crtc->flip_bo->active_scanout, sna_crtc->flip_serial)); + __FUNCTION__, __sna_crtc_id(sna_crtc), sna_crtc->flip_bo->handle, sna_crtc->flip_bo->active_scanout, sna_crtc->flip_serial)); } } } @@ -8021,7 +8010,7 @@ void sna_mode_redisplay(struct sna *sna) sna_crtc_redisplay(crtc, &damage, bo); kgem_bo_submit(&sna->kgem, bo); - arg.crtc_id = sna_crtc->id; + arg.crtc_id = __sna_crtc_id(sna_crtc); arg.fb_id = get_fb(sna, bo, crtc->mode.HDisplay, crtc->mode.VDisplay); @@ -8050,7 +8039,7 @@ void sna_mode_redisplay(struct sna *sna) DrawableRec tmp; DBG(("%s: flip [fb=%d] on crtc %d [%d, pipe=%d] failed - %d\n", - __FUNCTION__, arg.fb_id, i, sna_crtc->id, sna_crtc->pipe, errno)); + __FUNCTION__, arg.fb_id, i, __sna_crtc_id(sna_crtc), __sna_crtc_pipe(sna_crtc), errno)); xf86DrvMsg(sna->scrn->scrnIndex, X_ERROR, "Page flipping failed, disabling TearFree\n"); sna->flags &= ~SNA_TEAR_FREE; @@ -8069,7 +8058,7 @@ disable1: &box, 1, COPY_LAST)) { xf86DrvMsg(crtc->scrn->scrnIndex, X_ERROR, "%s: page flipping failed, disabling CRTC:%d (pipe=%d)\n", - __FUNCTION__, sna_crtc->id, sna_crtc->pipe); + __FUNCTION__, __sna_crtc_id(sna_crtc), __sna_crtc_pipe(sna_crtc)); sna_crtc_disable(crtc, false); } @@ -8090,7 +8079,7 @@ disable1: sna_crtc->cache_bo = kgem_bo_reference(sna_crtc->bo); DBG(("%s: recording flip on CRTC:%d handle=%d, active_scanout=%d, serial=%d\n", - __FUNCTION__, sna_crtc->id, sna_crtc->flip_bo->handle, sna_crtc->flip_bo->active_scanout, sna_crtc->flip_serial)); + __FUNCTION__, __sna_crtc_id(sna_crtc), sna_crtc->flip_bo->handle, sna_crtc->flip_bo->active_scanout, sna_crtc->flip_serial)); } else { sna_crtc_redisplay(crtc, &damage, sna_crtc->bo); kgem_scanout_flush(&sna->kgem, sna_crtc->bo); @@ -8126,19 +8115,19 @@ disable1: assert(crtc != NULL); DBG(("%s: crtc %d [%d, pipe=%d] active? %d, transformed? %d\n", - __FUNCTION__, i, crtc->id, crtc->pipe, crtc->bo ? crtc->bo->handle : 0, crtc->transform)); + __FUNCTION__, i, __sna_crtc_id(crtc), crtc->bo ? crtc->bo->handle : 0, crtc->transform)); if (crtc->bo == NULL || crtc->transform) continue; assert(config->crtc[i]->enabled); assert(crtc->flip_bo == NULL); - arg.crtc_id = crtc->id; + arg.crtc_id = __sna_crtc_id(crtc); arg.user_data = (uintptr_t)crtc; if (crtc->client_bo) { DBG(("%s: apply shadow override bo for CRTC:%d on pipe=%d, handle=%d\n", - __FUNCTION__, crtc->id, crtc->pipe, crtc->client_bo->handle)); + __FUNCTION__, __sna_crtc_id(crtc), __sna_crtc_pipe(crtc), crtc->client_bo->handle)); arg.fb_id = get_fb(sna, crtc->client_bo, crtc->base->mode.HDisplay, crtc->base->mode.VDisplay); @@ -8215,7 +8204,7 @@ fixup_flip: xf86DrvMsg(sna->scrn->scrnIndex, X_ERROR, "%s: page flipping failed, disabling CRTC:%d (pipe=%d)\n", - __FUNCTION__, crtc->id, crtc->pipe); + __FUNCTION__, __sna_crtc_id(crtc), __sna_crtc_pipe(crtc)); sna_crtc_disable(crtc->base, false); } continue; @@ -8223,7 +8212,7 @@ fixup_flip: if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_PAGE_FLIP, &arg)) { ERR(("%s: flip [fb=%d] on crtc %d [%d, pipe=%d] failed - %d\n", - __FUNCTION__, arg.fb_id, i, crtc->id, crtc->pipe, errno)); + __FUNCTION__, arg.fb_id, i, __sna_crtc_id(crtc), __sna_crtc_pipe(crtc), errno)); goto fixup_flip; } sna->mode.flip_active++; @@ -8237,7 +8226,7 @@ fixup_flip: crtc->flip_pending = true; DBG(("%s: recording flip on CRTC:%d handle=%d, active_scanout=%d, serial=%d\n", - __FUNCTION__, crtc->id, crtc->flip_bo->handle, crtc->flip_bo->active_scanout, crtc->flip_serial)); + __FUNCTION__, __sna_crtc_id(crtc), crtc->flip_bo->handle, crtc->flip_bo->active_scanout, crtc->flip_serial)); { struct drm_i915_gem_busy busy = { flip_bo->handle }; @@ -8320,7 +8309,7 @@ again: if (msc64(crtc, vbl->sequence, &msc)) { DBG(("%s: recording last swap on pipe=%d, frame %d [%08llx], time %d.%06d\n", - __FUNCTION__, crtc->pipe, vbl->sequence, (long long)msc, vbl->tv_sec, vbl->tv_usec)); + __FUNCTION__, __sna_crtc_pipe(crtc), vbl->sequence, (long long)msc, vbl->tv_sec, vbl->tv_usec)); crtc->swap.tv_sec = vbl->tv_sec; crtc->swap.tv_usec = vbl->tv_usec; crtc->swap.msc = msc; diff --git a/src/sna/sna_dri2.c b/src/sna/sna_dri2.c index 43d47015..9ee7e998 100644 --- a/src/sna/sna_dri2.c +++ b/src/sna/sna_dri2.c @@ -1312,8 +1312,8 @@ draw_current_msc(DrawablePtr draw, xf86CrtcPtr crtc, uint64_t msc) const struct ust_msc *this = sna_crtc_last_swap(crtc); DBG(("%s: Window transferring from pipe=%d [msc=%llu] to pipe=%d [msc=%llu], delta now %lld\n", __FUNCTION__, - sna_crtc_to_pipe(priv->crtc), (long long)last->msc, - sna_crtc_to_pipe(crtc), (long long)this->msc, + sna_crtc_pipe(priv->crtc), (long long)last->msc, + sna_crtc_pipe(crtc), (long long)this->msc, (long long)(priv->msc_delta + this->msc - last->msc))); priv->msc_delta += this->msc - last->msc; priv->crtc = crtc; @@ -1491,7 +1491,7 @@ sna_dri2_add_event(struct sna *sna, info->sna = sna; info->draw = draw; info->crtc = crtc; - info->pipe = sna_crtc_to_pipe(crtc); + info->pipe = sna_crtc_pipe(crtc); if (!add_event_to_client(info, sna, client)) { free(info); @@ -1685,7 +1685,7 @@ can_flip(struct sna * sna, } if (!sna_crtc_is_on(crtc)) { - DBG(("%s: ref-pipe=%d is disabled\n", __FUNCTION__, sna_crtc_to_pipe(crtc))); + DBG(("%s: ref-pipe=%d is disabled\n", __FUNCTION__, sna_crtc_pipe(crtc))); return false; } @@ -2137,7 +2137,7 @@ static void fake_swap_complete(struct sna *sna, ClientPtr client, swap = sna_crtc_last_swap(crtc); DBG(("%s(type=%d): draw=%ld, pipe=%d, frame=%lld [msc %lld], tv=%d.%06d\n", - __FUNCTION__, type, (long)draw->id, crtc ? sna_crtc_to_pipe(crtc) : -1, + __FUNCTION__, type, (long)draw->id, crtc ? sna_crtc_pipe(crtc) : -1, (long long)swap->msc, (long long)draw_current_msc(draw, crtc, swap->msc), swap->tv_sec, swap->tv_usec)); @@ -2587,7 +2587,7 @@ get_current_msc(struct sna *sna, DrawablePtr draw, xf86CrtcPtr crtc) VG_CLEAR(vbl); vbl.request.type = _DRM_VBLANK_RELATIVE; vbl.request.sequence = 0; - if (sna_wait_vblank(sna, &vbl, sna_crtc_to_pipe(crtc)) == 0) + if (sna_wait_vblank(sna, &vbl, sna_crtc_pipe(crtc)) == 0) ret = sna_crtc_record_vblank(crtc, &vbl); else ret = sna_crtc_last_swap(crtc)->msc; @@ -2704,7 +2704,7 @@ sna_dri2_schedule_flip(ClientPtr client, DrawablePtr draw, xf86CrtcPtr crtc, if (immediate) { info = sna->dri2.flip_pending; DBG(("%s: performing immediate swap on pipe %d, pending? %d, mode: %d, continuation? %d\n", - __FUNCTION__, sna_crtc_to_pipe(crtc), + __FUNCTION__, sna_crtc_pipe(crtc), info != NULL, info ? info->flip_continue : 0, info && info->draw == draw)); @@ -2844,7 +2844,7 @@ sna_dri2_schedule_xchg(ClientPtr client, DrawablePtr draw, xf86CrtcPtr crtc, DBG(("%s: synchronous?=%d, send-event?=%d\n", __FUNCTION__, sync, event)); if (!sync || event) { DBG(("%s: performing immediate xchg on pipe %d\n", - __FUNCTION__, sna_crtc_to_pipe(crtc))); + __FUNCTION__, sna_crtc_pipe(crtc))); sna_dri2_xchg(draw, front, back); } if (sync) { @@ -2906,7 +2906,7 @@ sna_dri2_schedule_xchg_crtc(ClientPtr client, DrawablePtr draw, xf86CrtcPtr crtc DBG(("%s: synchronous?=%d, send-event?=%d\n", __FUNCTION__, sync, event)); if (!sync || event) { DBG(("%s: performing immediate xchg only on pipe %d\n", - __FUNCTION__, sna_crtc_to_pipe(crtc))); + __FUNCTION__, sna_crtc_pipe(crtc))); sna_dri2_xchg_crtc(sna, draw, crtc, front, back); } if (sync) { @@ -3173,7 +3173,7 @@ sna_dri2_get_msc(DrawablePtr draw, CARD64 *ust, CARD64 *msc) const struct ust_msc *swap; DBG(("%s(draw=%ld, pipe=%d)\n", __FUNCTION__, draw->id, - crtc ? sna_crtc_to_pipe(crtc) : -1)); + crtc ? sna_crtc_pipe(crtc) : -1)); if (crtc != NULL) { union drm_wait_vblank vbl; @@ -3181,7 +3181,7 @@ sna_dri2_get_msc(DrawablePtr draw, CARD64 *ust, CARD64 *msc) VG_CLEAR(vbl); vbl.request.type = _DRM_VBLANK_RELATIVE; vbl.request.sequence = 0; - if (sna_wait_vblank(sna, &vbl, sna_crtc_to_pipe(crtc)) == 0) + if (sna_wait_vblank(sna, &vbl, sna_crtc_pipe(crtc)) == 0) sna_crtc_record_vblank(crtc, &vbl); } else /* Drawable not displayed, make up a *monotonic* value */ @@ -3215,7 +3215,7 @@ sna_dri2_schedule_wait_msc(ClientPtr client, DrawablePtr draw, CARD64 target_msc crtc = sna_dri2_get_crtc(draw); DBG(("%s(pipe=%d, target_msc=%llu, divisor=%llu, rem=%llu)\n", - __FUNCTION__, crtc ? sna_crtc_to_pipe(crtc) : -1, + __FUNCTION__, crtc ? sna_crtc_pipe(crtc) : -1, (long long)target_msc, (long long)divisor, (long long)remainder)); @@ -3224,7 +3224,7 @@ sna_dri2_schedule_wait_msc(ClientPtr client, DrawablePtr draw, CARD64 target_msc if (crtc == NULL) goto out_complete; - pipe = sna_crtc_to_pipe(crtc); + pipe = sna_crtc_pipe(crtc); VG_CLEAR(vbl); diff --git a/src/sna/sna_present.c b/src/sna/sna_present.c index a344dac8..2b3468da 100644 --- a/src/sna/sna_present.c +++ b/src/sna/sna_present.c @@ -56,9 +56,24 @@ to_present_event(uintptr_t data) #define MARK_PRESENT(x) ((void *)((uintptr_t)(x) | 2)) -static int pipe_from_crtc(RRCrtcPtr crtc) +static inline xf86CrtcPtr unmask_crtc(xf86CrtcPtr crtc) { - return crtc ? sna_crtc_to_pipe__safe(crtc->devPrivate) : -1; + return (xf86CrtcPtr)((uintptr_t)crtc & ~1); +} + +static inline xf86CrtcPtr mark_crtc(xf86CrtcPtr crtc) +{ + return (xf86CrtcPtr)((uintptr_t)crtc | 1); +} + +static inline bool has_vblank(xf86CrtcPtr crtc) +{ + return (uintptr_t)crtc & 1; +} + +static inline int pipe_from_crtc(RRCrtcPtr crtc) +{ + return crtc ? sna_crtc_pipe(crtc->devPrivate) : -1; } static uint32_t pipe_select(int pipe) @@ -98,7 +113,7 @@ static void vblank_complete(struct sna_present_event *info, DBG(("%s: %d events complete\n", __FUNCTION__, info->n_event_id)); for (n = 0; n < info->n_event_id; n++) { DBG(("%s: pipe=%d tv=%d.%06d msc=%lld (target=%lld), event=%lld complete%s\n", __FUNCTION__, - sna_crtc_to_pipe(info->crtc), + sna_crtc_pipe(unmask_crtc(info->crtc)), (int)(ust / 1000000), (int)(ust % 1000000), (long long)msc, (long long)info->target_msc, (long long)info->event_id[n], @@ -142,7 +157,7 @@ static CARD32 sna_fake_vblank_handler(OsTimerPtr timer, CARD32 now, void *data) VG_CLEAR(vbl); vbl.request.type = DRM_VBLANK_RELATIVE; vbl.request.sequence = 0; - if (sna_wait_vblank(info->sna, &vbl, sna_crtc_to_pipe(info->crtc)) == 0) { + if (sna_wait_vblank(info->sna, &vbl, sna_crtc_pipe(info->crtc)) == 0) { ust = ust64(vbl.reply.tval_sec, vbl.reply.tval_usec); msc = sna_crtc_record_vblank(info->crtc, &vbl); DBG(("%s: event=%lld, target msc=%lld, now %lld\n", @@ -155,7 +170,7 @@ static CARD32 sna_fake_vblank_handler(OsTimerPtr timer, CARD32 now, void *data) vbl.request.type = DRM_VBLANK_ABSOLUTE | DRM_VBLANK_EVENT; vbl.request.sequence = info->target_msc; vbl.request.signal = (uintptr_t)MARK_PRESENT(info); - if (sna_wait_vblank(info->sna, &vbl, sna_crtc_to_pipe(info->crtc)) == 0) { + if (sna_wait_vblank(info->sna, &vbl, sna_crtc_pipe(info->crtc)) == 0) { DBG(("%s: scheduled new vblank event for %lld\n", __FUNCTION__, (long long)info->target_msc)); free(timer); return 0; @@ -173,7 +188,7 @@ static CARD32 sna_fake_vblank_handler(OsTimerPtr timer, CARD32 now, void *data) DBG(("%s: blocking wait!\n", __FUNCTION__)); vbl.request.type = DRM_VBLANK_ABSOLUTE; vbl.request.sequence = info->target_msc; - (void)sna_wait_vblank(info->sna, &vbl, sna_crtc_to_pipe(info->crtc)); + (void)sna_wait_vblank(info->sna, &vbl, sna_crtc_pipe(info->crtc)); } } else { const struct ust_msc *swap = sna_crtc_last_swap(info->crtc); @@ -241,24 +256,31 @@ 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)); + DBG(("%s(pipe=%d)\n", __FUNCTION__, sna_crtc_pipe(crtc->devPrivate))); + if (sna_crtc_has_vblank(crtc->devPrivate)) { + DBG(("%s: vblank active, reusing last swap msc/ust\n", + __FUNCTION__)); + goto last; + } VG_CLEAR(vbl); vbl.request.type = DRM_VBLANK_RELATIVE; vbl.request.sequence = 0; - if (sna_wait_vblank(sna, &vbl, pipe) == 0) { + if (sna_wait_vblank(sna, &vbl, sna_crtc_pipe(crtc->devPrivate)) == 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); + const struct ust_msc *swap; +last: + swap = sna_crtc_last_swap(crtc->devPrivate); *ust = swap_ust(swap); *msc = swap->msc; } - DBG(("%s: pipe=%d, tv=%d.%06d msc=%lld\n", __FUNCTION__, pipe, + DBG(("%s: pipe=%d, tv=%d.%06d msc=%lld\n", __FUNCTION__, + sna_crtc_pipe(crtc->devPrivate), (int)(*ust / 1000000), (int)(*ust % 1000000), (long long)*msc)); @@ -269,10 +291,13 @@ void sna_present_vblank_handler(struct drm_event_vblank *event) { struct sna_present_event *info = to_present_event(event->user_data); + xf86CrtcPtr crtc = info->crtc; vblank_complete(info, ust64(event->tv_sec, event->tv_usec), - sna_crtc_record_event(info->crtc, event)); + sna_crtc_record_event(unmask_crtc(crtc), event)); + if (has_vblank(crtc)) + sna_crtc_clear_vblank(unmask_crtc(crtc)); } static int @@ -284,14 +309,14 @@ sna_present_queue_vblank(RRCrtcPtr crtc, uint64_t event_id, uint64_t msc) union drm_wait_vblank vbl; DBG(("%s(pipe=%d, event=%lld, msc=%lld)\n", - __FUNCTION__, pipe_from_crtc(crtc), + __FUNCTION__, sna_crtc_pipe(crtc->devPrivate), (long long)event_id, (long long)msc)); swap = sna_crtc_last_swap(crtc->devPrivate); assert((int64_t)(msc - swap->msc) >= 0); if ((int64_t)(msc - swap->msc) <= 0) { DBG(("%s: pipe=%d tv=%d.%06d msc=%lld (target=%lld), event=%lld complete\n", __FUNCTION__, - pipe_from_crtc(crtc), + sna_crtc_pipe(crtc->devPrivate), swap->tv_sec, swap->tv_usec, (long long)swap->msc, (long long)msc, (long long)event_id)); @@ -300,13 +325,14 @@ sna_present_queue_vblank(RRCrtcPtr crtc, uint64_t event_id, uint64_t msc) } list_for_each_entry(tmp, &sna->present.vblank_queue, link) { - if (tmp->target_msc == msc && tmp->crtc == crtc->devPrivate) { + if (tmp->target_msc == msc && + unmask_crtc(tmp->crtc) == crtc->devPrivate) { uint64_t *events = tmp->event_id; if (is_power_of_two(tmp->n_event_id)) { events = malloc(2*sizeof(uint64_t)*tmp->n_event_id); if (events == NULL) - goto fail; + return BadAlloc; memcpy(events, tmp->event_id, @@ -321,11 +347,13 @@ sna_present_queue_vblank(RRCrtcPtr crtc, uint64_t event_id, uint64_t msc) events[tmp->n_event_id++] = event_id; return Success; } - if ((int64_t)(tmp->target_msc - msc) > 0) + if ((int64_t)(tmp->target_msc - msc) > 0) { + DBG(("%s: previous target_msc=%lld invalid for coalescing\n", + __FUNCTION__, (long long)tmp->target_msc)); break; + } } -fail: info = malloc(sizeof(struct sna_present_event) + sizeof(uint64_t)); if (info == NULL) return BadAlloc; @@ -342,13 +370,18 @@ fail: vbl.request.type = DRM_VBLANK_ABSOLUTE | DRM_VBLANK_EVENT; vbl.request.sequence = msc; vbl.request.signal = (uintptr_t)MARK_PRESENT(info); - if (sna_wait_vblank(sna, &vbl, sna_crtc_to_pipe(info->crtc))) { + if (sna_wait_vblank(sna, &vbl, sna_crtc_pipe(info->crtc))) { DBG(("%s: vblank enqueue failed\n", __FUNCTION__)); if (!sna_fake_vblank(info)) { list_del(&info->link); free(info); return BadAlloc; } + } else { + if (msc - swap->msc == 1) { + sna_crtc_set_vblank(info->crtc); + info->crtc = mark_crtc(info->crtc); + } } return Success; @@ -510,12 +543,14 @@ present_flip_handler(struct drm_event_vblank *event, void *data) swap = *sna_crtc_last_swap(info->crtc); DBG(("%s: pipe=%d, tv=%d.%06d msc=%lld (target %lld), event=%lld complete%s\n", __FUNCTION__, - info->crtc ? sna_crtc_to_pipe(info->crtc) : -1, + info->crtc ? sna_crtc_pipe(info->crtc) : -1, swap.tv_sec, swap.tv_usec, (long long)swap.msc, (long long)info->target_msc, (long long)info->event_id[0], info->target_msc && info->target_msc == swap.msc ? "" : ": MISS")); present_event_notify(info->event_id[0], swap_ust(&swap), swap.msc); + if (info->crtc) + sna_crtc_clear_vblank(info->crtc); if (info->sna->present.unflip) { DBG(("%s: executing queued unflip (event=%lld)\n", __FUNCTION__, (long long)info->sna->present.unflip)); @@ -558,6 +593,8 @@ flip(struct sna *sna, return FALSE; } + if (info->crtc) + sna_crtc_set_vblank(info->crtc); return TRUE; } diff --git a/src/sna/sna_video_sprite.c b/src/sna/sna_video_sprite.c index 9ce98798..7c8a73f2 100644 --- a/src/sna/sna_video_sprite.c +++ b/src/sna/sna_video_sprite.c @@ -81,14 +81,11 @@ static int sna_video_sprite_stop(ddStopVideo_ARGS) xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(video->sna->scrn); int i; - for (i = 0; i < config->num_crtc; i++) { + for (i = 0; i < video->sna->mode.num_real_crtc; i++) { xf86CrtcPtr crtc = config->crtc[i]; int pipe; - if (sna_crtc_id(crtc) == 0) - break; - - pipe = sna_crtc_to_pipe(crtc); + pipe = sna_crtc_pipe(crtc); if (video->bo[pipe] == NULL) continue; @@ -221,7 +218,7 @@ sna_video_sprite_show(struct sna *sna, BoxPtr dstBox) { struct local_mode_set_plane s; - int pipe = sna_crtc_to_pipe(crtc); + int pipe = sna_crtc_pipe(crtc); /* XXX handle video spanning multiple CRTC */ @@ -402,7 +399,7 @@ static int sna_video_sprite_put_image(ddPutImage_ARGS) goto err; } - for (i = 0; i < config->num_crtc; i++) { + for (i = 0; i < video->sna->mode.num_real_crtc; i++) { xf86CrtcPtr crtc = config->crtc[i]; struct sna_video_frame frame; int pipe; @@ -411,10 +408,7 @@ static int sna_video_sprite_put_image(ddPutImage_ARGS) RegionRec reg; Rotation rotation; - if (sna_crtc_id(crtc) == 0) - break; - - pipe = sna_crtc_to_pipe(crtc); + pipe = sna_crtc_pipe(crtc); sna_video_frame_init(video, format->id, width, height, &frame); @@ -611,7 +605,7 @@ static bool sna_video_has_sprites(struct sna *sna) for (i = 0; i < sna->mode.num_real_crtc; i++) { if (!sna_crtc_to_sprite(config->crtc[i])) { - DBG(("%s: no sprite found on pipe %d\n", __FUNCTION__, sna_crtc_to_pipe(config->crtc[i]))); + DBG(("%s: no sprite found on pipe %d\n", __FUNCTION__, sna_crtc_pipe(config->crtc[i]))); return false; } } diff --git a/test/present-speed.c b/test/present-speed.c index ba062646..4d339041 100644 --- a/test/present-speed.c +++ b/test/present-speed.c @@ -249,7 +249,6 @@ static void run(Display *dpy, Window win, const char *name, unsigned options) free(ev); } while ((ev = (xcb_present_generic_event_t *)xcb_poll_for_special_event(c, Q))); } - assert(p); b->busy = (options & NOCOPY) == 0; if (b->fence.xid) { |