summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2015-04-17 23:45:20 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2015-04-18 12:37:42 +0100
commit7eaf593640d4479f850227252fd793bcb55be8d3 (patch)
tree7479780f4bd8c4125135d87c3bec25cde5cdcf8d
parent75d87762471e195dddd73056fc6a06e17db1c8b0 (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.h46
-rw-r--r--src/sna/sna_display.c239
-rw-r--r--src/sna/sna_dri2.c26
-rw-r--r--src/sna/sna_present.c77
-rw-r--r--src/sna/sna_video_sprite.c18
-rw-r--r--test/present-speed.c1
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) {