xf86-video-intel: 3 commits - src/sna/sna_accel.c src/sna/sna_display.c
Chris Wilson
ickle at kemper.freedesktop.org
Sun Jun 22 09:57:57 PDT 2014
src/sna/sna_accel.c | 13 +++++++++---
src/sna/sna_display.c | 54 +++++++++++++++++++++++++++-----------------------
2 files changed, 40 insertions(+), 27 deletions(-)
New commits:
commit dca0f1c2ccf14df38764ed12b971dc491cf22608
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Sun Jun 22 17:53:59 2014 +0100
sna: Track CRTC mode changes and discard old flips
If we have a pending flip across a modeset we must be careful to drop
the stale flip_bo after the modeset.
Reported-by: Sree Harsha Totakura <freedesktop at h.totakura.in>
References: https://bugs.freedesktop.org/show_bug.cgi?id=80355#c8
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
index 91ec2cd..0cee970 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -121,6 +121,8 @@ struct sna_crtc {
uint32_t current;
} primary_rotation, sprite_rotation;
+ uint32_t mode_serial, flip_serial;
+
uint32_t last_seq, wrap_seq;
struct ust_msc swap;
@@ -969,7 +971,7 @@ sna_crtc_apply(xf86CrtcPtr crtc)
DBG(("%s CRTC:%d [pipe=%d], handle=%d\n", __FUNCTION__, sna_crtc->id, sna_crtc->pipe, sna_crtc->bo->handle));
- assert(config->num_output < ARRAY_SIZE(output_ids));
+ assert(sna->mode.num_real_output < ARRAY_SIZE(output_ids));
if (!rotation_set(sna, &sna_crtc->primary_rotation, sna_crtc->rotation)) {
ERR(("%s: set-primary-rotation failed (rotation-id=%d, rotation=%d) on CRTC:%d [pipe=%d], errno=%d\n",
@@ -979,7 +981,7 @@ sna_crtc_apply(xf86CrtcPtr crtc)
DBG(("%s: CRTC:%d [pipe=%d] primary rotation set to %x\n",
__FUNCTION__, sna_crtc->id, sna_crtc->pipe, sna_crtc->rotation));
- for (i = 0; i < config->num_output; i++) {
+ for (i = 0; i < sna->mode.num_real_output; i++) {
xf86OutputPtr output = config->output[i];
/* Make sure we mark the output as off (and save the backlight)
@@ -1038,6 +1040,7 @@ sna_crtc_apply(xf86CrtcPtr crtc)
if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_SETCRTC, &arg))
return false;
+ sna_crtc->mode_serial++;
sna_crtc_force_outputs_on(crtc);
return true;
}
@@ -1398,6 +1401,8 @@ sna_crtc_disable(xf86CrtcPtr crtc)
arg.crtc_id = sna_crtc->id;
(void)drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_SETCRTC, &arg);
+ sna_crtc->mode_serial++;
+
rotation_set(sna, &sna_crtc->primary_rotation, RR_Rotate_0);
sna_crtc_disable_shadow(sna, sna_crtc);
@@ -1927,10 +1932,11 @@ sna_crtc_damage(xf86CrtcPtr crtc)
static char *outputs_for_crtc(xf86CrtcPtr crtc, char *outputs, int max)
{
+ struct sna *sna = to_sna(crtc->scrn);
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(crtc->scrn);
int len, i;
- for (i = len = 0; i < config->num_output; i++) {
+ for (i = len = 0; i < sna->mode.num_real_output; i++) {
xf86OutputPtr output = config->output[i];
if (output->crtc != crtc)
@@ -4563,9 +4569,9 @@ sna_crtc_flip(struct sna *sna, struct sna_crtc *crtc, struct kgem_bo *bo, int x,
DBG(("%s CRTC:%d [pipe=%d], handle=%d\n", __FUNCTION__, crtc->id, crtc->pipe, bo->handle));
- assert(config->num_output < ARRAY_SIZE(output_ids));
+ assert(sna->mode.num_real_output < ARRAY_SIZE(output_ids));
- for (i = 0; i < config->num_output; i++) {
+ for (i = 0; i < sna->mode.num_real_output; i++) {
xf86OutputPtr output = config->output[i];
if (output->crtc != crtc->base)
@@ -4713,6 +4719,7 @@ fixup_flip:
crtc->flip_data = data;
crtc->flip_bo = kgem_bo_reference(bo);
crtc->flip_bo->active_scanout++;
+ crtc->flip_serial = crtc->mode_serial;
sna->mode.flip_active++;
}
@@ -4919,7 +4926,7 @@ static bool sna_probe_initial_configuration(struct sna *sna)
}
/* First scan through all outputs and look for user overrides */
- for (i = 0; i < config->num_output; i++) {
+ for (i = 0; i < sna->mode.num_real_output; i++) {
xf86OutputPtr output = config->output[i];
for (j = 0; j < ARRAY_SIZE(user_overrides); j++) {
@@ -4965,14 +4972,11 @@ static bool sna_probe_initial_configuration(struct sna *sna)
}
/* Reconstruct outputs pointing to active CRTC */
- for (i = 0; i < config->num_output; i++) {
+ for (i = 0; i < sna->mode.num_real_output; i++) {
xf86OutputPtr output = config->output[i];
uint32_t crtc_id;
- if (to_sna_output(output) == NULL) {
- assert(output->crtc == NULL);
- continue;
- }
+ assert(to_sna_output(output));
crtc_id = (uintptr_t)output->crtc;
output->crtc = NULL;
@@ -6287,6 +6291,7 @@ disable1:
sna_crtc->flip_handler = shadow_flip_handler;
sna_crtc->flip_bo = bo;
sna_crtc->flip_bo->active_scanout++;
+ sna_crtc->flip_serial = sna_crtc->mode_serial;
sna_crtc->shadow_bo = kgem_bo_reference(sna_crtc->bo);
} else {
@@ -6414,6 +6419,7 @@ fixup_flip:
crtc->flip_handler = shadow_flip_handler;
crtc->flip_bo = kgem_bo_reference(flip_bo);
crtc->flip_bo->active_scanout++;
+ crtc->flip_serial = crtc->mode_serial;
{
struct drm_i915_gem_busy busy = { flip_bo->handle };
@@ -6483,7 +6489,7 @@ void sna_mode_wakeup(struct sna *sna)
assert(crtc->flip_bo->active_scanout);
assert(crtc->flip_bo->refcnt >= crtc->flip_bo->active_scanout);
- if (crtc->bo) {
+ if (crtc->flip_serial == crtc->mode_serial) {
DBG(("%s: removing handle=%d from scanout, installing handle=%d\n",
__FUNCTION__, crtc->bo->handle, crtc->flip_bo->handle));
assert(crtc->bo->active_scanout);
commit dae370423ad85b9d9c576277da5a9fb92ab3d3df
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Sun Jun 22 11:45:35 2014 +0100
sna: Clean up CRTC on CloseScreen
We need to do this to stop any stray references escaping through kernel
events now that we are passing the CRTC through the event.
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
index 305bccf..91ec2cd 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -203,6 +203,10 @@ static inline bool event_pending(int fd)
static bool sna_mode_has_pending_events(struct sna *sna)
{
+ /* In order to workaround a kernel bug in not honouring O_NONBLOCK,
+ * check that the fd is readable before attempting to read the next
+ * event from drm.
+ */
return event_pending(sna->kgem.fd);
}
@@ -5266,26 +5270,18 @@ sna_mode_wants_tear_free(struct sna *sna)
void
sna_mode_close(struct sna *sna)
{
- xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn);
- int i;
-
- /* In order to workaround a kernel bug in not honouring O_NONBLOCK,
- * check that the fd is readable before attempting to read the next
- * event from drm.
- */
while (sna_mode_has_pending_events(sna))
sna_mode_wakeup(sna);
if (sna->flags & SNA_IS_HOSTED)
return;
- sna_backlight_close(sna);
- sna_cursor_close(sna);
-
- for (i = 0; i < sna->mode.num_real_crtc; i++)
- sna_crtc_disable_shadow(sna, to_sna_crtc(config->crtc[i]));
+ sna_mode_reset(sna);
+ sna_cursor_close(sna);
sna_cursors_fini(sna);
+
+ sna_backlight_close(sna);
}
void
@@ -5801,6 +5797,10 @@ void sna_mode_reset(struct sna *sna)
sna_output_backlight_set(sna_output,
sna_output->backlight.max);
}
+
+ /* drain the event queue */
+ while (sna_mode_has_pending_events(sna))
+ sna_mode_wakeup(sna);
}
static void transformed_box(BoxRec *box, xf86CrtcPtr crtc)
commit 923dc207df7b05c138c628983ccaf2493dd63b62
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Thu Jun 19 10:17:11 2014 +0100
sna: Discard write hint from a couple more move-to-gpu
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index 27bbc06..78f5fed 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -481,8 +481,10 @@ static void sna_pixmap_free_gpu(struct sna *sna, struct sna_pixmap *priv)
sna_pixmap_undo_cow(sna, priv, MOVE_WRITE);
assert(priv->cow == NULL);
- if (priv->move_to_gpu)
+ if (priv->move_to_gpu) {
+ sna_pixmap_discard_shadow_damage(priv, NULL);
priv->move_to_gpu(sna, priv, MOVE_WRITE);
+ }
sna_damage_destroy(&priv->gpu_damage);
priv->clear = false;
@@ -3170,13 +3172,18 @@ sna_pixmap_move_area_to_gpu(PixmapPtr pixmap, const BoxRec *box, unsigned int fl
if (priv->move_to_gpu) {
unsigned int hint;
- hint = flags | MOVE_READ | (priv->cpu_damage ? MOVE_WRITE : 0);
+ hint = flags | MOVE_READ;
if ((flags & MOVE_READ) == 0) {
RegionRec region;
region.extents = *box;
region.data = NULL;
sna_pixmap_discard_shadow_damage(priv, ®ion);
+ if (region_subsumes_pixmap(®ion, pixmap))
+ hint &= ~MOVE_READ;
+ } else {
+ if (priv->cpu_damage)
+ hint |= MOVE_WRITE;
}
if (!priv->move_to_gpu(sna, priv, hint)) {
DBG(("%s: move-to-gpu override failed\n", __FUNCTION__));
@@ -3947,7 +3954,7 @@ sna_pixmap_move_to_gpu(PixmapPtr pixmap, unsigned flags)
assert_pixmap_damage(pixmap);
if (priv->move_to_gpu &&
- !priv->move_to_gpu(sna, priv, flags | (priv->cpu_damage ? MOVE_WRITE : 0))) {
+ !priv->move_to_gpu(sna, priv, flags | ((priv->cpu_damage && (flags & MOVE_READ)) ? MOVE_WRITE : 0))) {
DBG(("%s: move-to-gpu override failed\n", __FUNCTION__));
return NULL;
}
More information about the xorg-commit
mailing list