xf86-video-intel: 5 commits - src/sna/gen2_render.c src/sna/gen3_render.c src/sna/gen4_render.c src/sna/gen5_render.c src/sna/gen6_render.c src/sna/gen7_render.c src/sna/kgem.c src/sna/kgem.h src/sna/sna_display.c src/sna/sna_dri.c src/sna/sna_driver.c src/sna/sna.h src/sna/sna_render.c
Chris Wilson
ickle at kemper.freedesktop.org
Sun May 6 06:25:19 PDT 2012
src/sna/gen2_render.c | 8 +-
src/sna/gen3_render.c | 8 +-
src/sna/gen4_render.c | 8 +-
src/sna/gen5_render.c | 8 +-
src/sna/gen6_render.c | 8 +-
src/sna/gen7_render.c | 8 +-
src/sna/kgem.c | 32 +++++++----
src/sna/kgem.h | 2
src/sna/sna.h | 7 +-
src/sna/sna_display.c | 141 ++++++++++++++++++++------------------------------
src/sna/sna_dri.c | 87 +++++++++++++++---------------
src/sna/sna_driver.c | 3 -
src/sna/sna_render.c | 2
13 files changed, 151 insertions(+), 171 deletions(-)
New commits:
commit c5b6741d3729c6867702ab64a6c59cb8052c0ef3
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Sun May 6 12:40:54 2012 +0100
sna/gen2+: Fix typo for computing redirected extents for render copy
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/sna/gen2_render.c b/src/sna/gen2_render.c
index 0ad346e..9717aac 100644
--- a/src/sna/gen2_render.c
+++ b/src/sna/gen2_render.c
@@ -2909,14 +2909,14 @@ fallback:
int i;
for (i = 1; i < n; i++) {
- if (extents.x1 < box[i].x1)
+ if (box[i].x1 < extents.x1)
extents.x1 = box[i].x1;
- if (extents.y1 < box[i].y1)
+ if (box[i].y1 < extents.y1)
extents.y1 = box[i].y1;
- if (extents.x2 > box[i].x2)
+ if (box[i].x2 > extents.x2)
extents.x2 = box[i].x2;
- if (extents.y2 > box[i].y2)
+ if (box[i].y2 > extents.y2)
extents.y2 = box[i].y2;
}
if (!sna_render_composite_redirect(sna, &tmp,
diff --git a/src/sna/gen3_render.c b/src/sna/gen3_render.c
index 680d36f..e73c707 100644
--- a/src/sna/gen3_render.c
+++ b/src/sna/gen3_render.c
@@ -4069,14 +4069,14 @@ fallback_blt:
int i;
for (i = 1; i < n; i++) {
- if (extents.x1 < box[i].x1)
+ if (box[i].x1 < extents.x1)
extents.x1 = box[i].x1;
- if (extents.y1 < box[i].y1)
+ if (box[i].y1 < extents.y1)
extents.y1 = box[i].y1;
- if (extents.x2 > box[i].x2)
+ if (box[i].x2 > extents.x2)
extents.x2 = box[i].x2;
- if (extents.y2 > box[i].y2)
+ if (box[i].y2 > extents.y2)
extents.y2 = box[i].y2;
}
if (!sna_render_composite_redirect(sna, &tmp,
diff --git a/src/sna/gen4_render.c b/src/sna/gen4_render.c
index b8a2459..9cad75e 100644
--- a/src/sna/gen4_render.c
+++ b/src/sna/gen4_render.c
@@ -2655,14 +2655,14 @@ fallback_blt:
int i;
for (i = 1; i < n; i++) {
- if (extents.x1 < box[i].x1)
+ if (box[i].x1 < extents.x1)
extents.x1 = box[i].x1;
- if (extents.y1 < box[i].y1)
+ if (box[i].y1 < extents.y1)
extents.y1 = box[i].y1;
- if (extents.x2 > box[i].x2)
+ if (box[i].x2 > extents.x2)
extents.x2 = box[i].x2;
- if (extents.y2 > box[i].y2)
+ if (box[i].y2 > extents.y2)
extents.y2 = box[i].y2;
}
if (!sna_render_composite_redirect(sna, &tmp,
diff --git a/src/sna/gen5_render.c b/src/sna/gen5_render.c
index 1fb7f65..54d0b22 100644
--- a/src/sna/gen5_render.c
+++ b/src/sna/gen5_render.c
@@ -2962,14 +2962,14 @@ fallback_blt:
int i;
for (i = 1; i < n; i++) {
- if (extents.x1 < box[i].x1)
+ if (box[i].x1 < extents.x1)
extents.x1 = box[i].x1;
- if (extents.y1 < box[i].y1)
+ if (box[i].y1 < extents.y1)
extents.y1 = box[i].y1;
- if (extents.x2 > box[i].x2)
+ if (box[i].x2 > extents.x2)
extents.x2 = box[i].x2;
- if (extents.y2 > box[i].y2)
+ if (box[i].y2 > extents.y2)
extents.y2 = box[i].y2;
}
diff --git a/src/sna/gen6_render.c b/src/sna/gen6_render.c
index 38fb024..55673bf 100644
--- a/src/sna/gen6_render.c
+++ b/src/sna/gen6_render.c
@@ -3339,14 +3339,14 @@ fallback_blt:
int i;
for (i = 1; i < n; i++) {
- if (extents.x1 < box[i].x1)
+ if (box[i].x1 < extents.x1)
extents.x1 = box[i].x1;
- if (extents.y1 < box[i].y1)
+ if (box[i].y1 < extents.y1)
extents.y1 = box[i].y1;
- if (extents.x2 > box[i].x2)
+ if (box[i].x2 > extents.x2)
extents.x2 = box[i].x2;
- if (extents.y2 > box[i].y2)
+ if (box[i].y2 > extents.y2)
extents.y2 = box[i].y2;
}
if (!sna_render_composite_redirect(sna, &tmp,
diff --git a/src/sna/gen7_render.c b/src/sna/gen7_render.c
index 6c9a833..e128f5c 100644
--- a/src/sna/gen7_render.c
+++ b/src/sna/gen7_render.c
@@ -3422,14 +3422,14 @@ fallback_blt:
int i;
for (i = 1; i < n; i++) {
- if (extents.x1 < box[i].x1)
+ if (box[i].x1 < extents.x1)
extents.x1 = box[i].x1;
- if (extents.y1 < box[i].y1)
+ if (box[i].y1 < extents.y1)
extents.y1 = box[i].y1;
- if (extents.x2 > box[i].x2)
+ if (box[i].x2 > extents.x2)
extents.x2 = box[i].x2;
- if (extents.y2 > box[i].y2)
+ if (box[i].y2 > extents.y2)
extents.y2 = box[i].y2;
}
if (!sna_render_composite_redirect(sna, &tmp,
commit 771090f25db702d25ebbd3f2b44429cf0acfe8fd
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Fri May 4 20:56:37 2012 +0100
sna: Add a pair of asserts to track down a NULL pointer dereference
Looks like the assumption for the location of the data is invalid,
allocation failure, perhaps?
References: https://bugs.freedesktop.org/show_bug.cgi?id=47597
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/sna/sna_render.c b/src/sna/sna_render.c
index dee6608..880e173 100644
--- a/src/sna/sna_render.c
+++ b/src/sna/sna_render.c
@@ -460,6 +460,8 @@ static struct kgem_bo *upload(struct sna *sna,
priv->mapped = false;
}
if (pixmap->devPrivate.ptr == NULL) {
+ assert(priv->ptr);
+ assert(priv->stride);
pixmap->devPrivate.ptr = priv->ptr;
pixmap->devKind = priv->stride;
}
commit d376a960df7a081a5d449f77b81ae13223b98929
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Fri May 4 10:09:46 2012 +0100
sna/dri: Only track a single pending flip across all pipes
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/sna/sna.h b/src/sna/sna.h
index e07a115..3e4b8ec 100644
--- a/src/sna/sna.h
+++ b/src/sna/sna.h
@@ -249,7 +249,7 @@ struct sna {
} mode;
struct sna_dri {
- void *flip_pending[2];
+ void *flip_pending;
} dri;
unsigned int tiling;
diff --git a/src/sna/sna_dri.c b/src/sna/sna_dri.c
index 32602d5..2b97e68 100644
--- a/src/sna/sna_dri.c
+++ b/src/sna/sna_dri.c
@@ -937,6 +937,9 @@ can_flip(struct sna * sna,
WindowPtr win = (WindowPtr)draw;
PixmapPtr pixmap;
+ if (!sna->scrn->vtSema)
+ return FALSE;
+
if (draw->type == DRAWABLE_PIXMAP)
return FALSE;
@@ -1109,7 +1112,7 @@ sna_dri_flip_continue(struct sna *sna,
info->next_front.name = 0;
- sna->dri.flip_pending[info->pipe] = info;
+ sna->dri.flip_pending = info;
return TRUE;
}
@@ -1171,8 +1174,8 @@ static void sna_dri_flip_event(struct sna *sna,
break;
case DRI2_FLIP_THROTTLE:
- assert(sna->dri.flip_pending[flip->pipe] == flip);
- sna->dri.flip_pending[flip->pipe] = NULL;
+ assert(sna->dri.flip_pending == flip);
+ sna->dri.flip_pending = NULL;
if (flip->next_front.name &&
flip->drawable_id &&
@@ -1204,9 +1207,9 @@ static void sna_dri_flip_event(struct sna *sna,
case DRI2_ASYNC_FLIP:
DBG(("%s: async swap flip completed on pipe %d, pending? %d, new? %d\n",
__FUNCTION__, flip->pipe,
- sna->dri.flip_pending[flip->pipe] != NULL,
+ sna->dri.flip_pending != NULL,
flip->front->name != flip->old_front.name));
- assert(sna->dri.flip_pending[flip->pipe] == flip);
+ assert(sna->dri.flip_pending == flip);
if (flip->front->name != flip->next_front.name) {
DBG(("%s: async flip continuing\n", __FUNCTION__));
@@ -1240,7 +1243,7 @@ finish_async_flip:
flip->next_front.bo = NULL;
DBG(("%s: async flip completed\n", __FUNCTION__));
- sna->dri.flip_pending[flip->pipe] = NULL;
+ sna->dri.flip_pending = NULL;
sna_dri_frame_event_info_free(flip);
}
break;
@@ -1326,9 +1329,9 @@ sna_dri_schedule_flip(ClientPtr client, DrawablePtr draw, DRI2BufferPtr front,
int type = DRI2_FLIP_THROTTLE;
DBG(("%s: performing immediate swap on pipe %d, pending? %d\n",
- __FUNCTION__, pipe, sna->dri.flip_pending[pipe] != NULL));
+ __FUNCTION__, pipe, sna->dri.flip_pending != NULL));
- info = sna->dri.flip_pending[pipe];
+ info = sna->dri.flip_pending;
if (info) {
if (info->drawable_id == draw->id) {
DBG(("%s: chaining flip\n", __FUNCTION__));
@@ -1382,7 +1385,7 @@ sna_dri_schedule_flip(ClientPtr client, DrawablePtr draw, DRI2BufferPtr front,
CREATE_EXACT);
info->back->name = kgem_bo_flink(&sna->kgem,
get_private(info->back)->bo);
- sna->dri.flip_pending[info->pipe] = info;
+ sna->dri.flip_pending = info;
DRI2SwapComplete(info->client, draw, 0, 0, 0,
DRI2_EXCHANGE_COMPLETE,
@@ -1697,16 +1700,17 @@ sna_dri_async_swap(ClientPtr client, DrawablePtr draw,
struct sna *sna = to_sna_from_drawable(draw);
struct sna_dri_frame_event *info;
struct kgem_bo *bo;
- int name, pipe;
+ int name;
DBG(("%s()\n", __FUNCTION__));
- pipe = sna_dri_get_pipe(draw);
- if (pipe == -1) {
- PixmapPtr pixmap = get_drawable_pixmap(draw);
+ if (!sna->scrn->vtSema) {
+ PixmapPtr pixmap;
+exchange:
DBG(("%s: unattached, exchange pixmaps\n", __FUNCTION__));
+ pixmap = get_drawable_pixmap(draw);
set_bo(pixmap, get_private(back)->bo);
sna_dri_exchange_attachment(front, back);
get_private(back)->pixmap = pixmap;
@@ -1733,10 +1737,14 @@ blit:
bo = NULL;
name = 0;
- info = sna->dri.flip_pending[pipe];
+ info = sna->dri.flip_pending;
if (info == NULL) {
- DBG(("%s: no pending flip on pipe %d, so updating scanout\n",
- __FUNCTION__, pipe));
+ int pipe = sna_dri_get_pipe(draw);
+ if (pipe == -1)
+ goto exchange;
+
+ DBG(("%s: no pending flip, so updating scanout\n",
+ __FUNCTION__));
info = calloc(1, sizeof(struct sna_dri_frame_event));
if (!info)
@@ -1801,7 +1809,7 @@ blit:
info->back->name = name;
set_bo(sna->front, get_private(info->front)->bo);
- sna->dri.flip_pending[info->pipe] = info;
+ sna->dri.flip_pending = info;
DRI2SwapComplete(client, draw, 0, 0, 0,
DRI2_EXCHANGE_COMPLETE, func, data);
commit 450592f989efd0d3bc9ef2de245fce0a180e91a2
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Fri May 4 09:50:19 2012 +0100
sna: Cache the framebuffer id
Also fixup a weakness of only tracking scanout with a single bit, as we
used to clear it forcibly after every flip.
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index 666a23f..6e0c3d0 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -1088,6 +1088,25 @@ inline static void kgem_bo_remove_from_active(struct kgem *kgem,
assert(list_is_empty(&bo->vma));
}
+static void kgem_bo_clear_scanout(struct kgem *kgem, struct kgem_bo *bo)
+{
+ if (!bo->scanout)
+ return;
+
+ assert(bo->proxy == NULL);
+
+ DBG(("%s: handle=%d, fb=%d\n", __FUNCTION__, bo->handle, bo->delta));
+ if (bo->delta) {
+ drmModeRmFB(kgem->fd, bo->delta);
+ bo->delta = 0;
+ }
+
+ bo->scanout = false;
+ bo->needs_flush = true;
+ bo->flush = false;
+ bo->reusable = true;
+}
+
static void __kgem_bo_destroy(struct kgem *kgem, struct kgem_bo *bo)
{
DBG(("%s: handle=%d\n", __FUNCTION__, bo->handle));
@@ -1096,6 +1115,7 @@ static void __kgem_bo_destroy(struct kgem *kgem, struct kgem_bo *bo)
assert(bo->refcnt == 0);
bo->binding.offset = 0;
+ kgem_bo_clear_scanout(kgem, bo);
if (NO_CACHE)
goto destroy;
@@ -4151,18 +4171,6 @@ void kgem_bo_set_binding(struct kgem_bo *bo, uint32_t format, uint16_t offset)
}
}
-void kgem_bo_clear_scanout(struct kgem *kgem, struct kgem_bo *bo)
-{
- bo->needs_flush = true;
- bo->flush = false;
-
- if (!bo->scanout)
- return;
-
- bo->scanout = false;
- bo->reusable = true;
-}
-
struct kgem_bo *
kgem_replace_bo(struct kgem *kgem,
struct kgem_bo *src,
diff --git a/src/sna/kgem.h b/src/sna/kgem.h
index 9eac68e..186eaa0 100644
--- a/src/sna/kgem.h
+++ b/src/sna/kgem.h
@@ -509,8 +509,6 @@ struct kgem_bo *kgem_create_buffer_2d(struct kgem *kgem,
bool kgem_buffer_is_inplace(struct kgem_bo *bo);
void kgem_buffer_read_sync(struct kgem *kgem, struct kgem_bo *bo);
-void kgem_bo_clear_scanout(struct kgem *kgem, struct kgem_bo *bo);
-
void kgem_throttle(struct kgem *kgem);
#define MAX_INACTIVE_TIME 10
bool kgem_expire_cache(struct kgem *kgem);
diff --git a/src/sna/sna.h b/src/sna/sna.h
index 5272a08..e07a115 100644
--- a/src/sna/sna.h
+++ b/src/sna/sna.h
@@ -318,8 +318,6 @@ extern int sna_page_flip(struct sna *sna,
extern PixmapPtr sna_set_screen_pixmap(struct sna *sna, PixmapPtr pixmap);
-void sna_mode_delete_fb(struct sna *sna, uint32_t fb);
-
constant static inline struct sna *
to_sna(ScrnInfoPtr scrn)
{
diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
index 5275d4a..6287cd9 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -151,6 +151,40 @@ int sna_crtc_to_plane(xf86CrtcPtr crtc)
return sna_crtc->plane;
}
+static unsigned get_fb(struct sna *sna, struct kgem_bo *bo,
+ int width, int height)
+{
+ ScrnInfoPtr scrn = sna->scrn;
+ int ret;
+
+ assert(bo->proxy == NULL);
+ if (bo->delta) {
+ DBG(("%s: reusing fb=%d for handle=%d\n",
+ __FUNCTION__, bo->delta, bo->handle));
+ return bo->delta;
+ }
+
+ DBG(("%s: create fb %dx%d@%d/%d\n",
+ __FUNCTION__, width, height, scrn->depth, scrn->bitsPerPixel));
+
+ assert(bo->tiling != I915_TILING_Y);
+ ret = drmModeAddFB(sna->kgem.fd,
+ width, height,
+ scrn->depth, scrn->bitsPerPixel,
+ bo->pitch, bo->handle,
+ &bo->delta);
+ if (ret < 0) {
+ ErrorF("%s: failed to add fb: %dx%d depth=%d, bpp=%d, pitch=%d\n",
+ __FUNCTION__,
+ width, height,
+ scrn->depth, scrn->bitsPerPixel, bo->pitch);
+ return 0;
+ }
+
+ bo->scanout = true;
+ return bo->delta;
+}
+
static uint32_t gem_create(int fd, int size)
{
struct drm_i915_gem_create create;
@@ -434,10 +468,6 @@ sna_crtc_restore(struct sna *sna)
if (!bo)
return;
- assert(bo->tiling != I915_TILING_Y);
- bo->scanout = true;
- bo->domain = DOMAIN_NONE;
-
DBG(("%s: create fb %dx%d@%d/%d\n",
__FUNCTION__,
sna->front->drawable.width,
@@ -446,13 +476,10 @@ sna_crtc_restore(struct sna *sna)
sna->front->drawable.bitsPerPixel));
sna_mode_remove_fb(sna);
- if (drmModeAddFB(sna->kgem.fd,
- sna->front->drawable.width,
- sna->front->drawable.height,
- sna->front->drawable.depth,
- sna->front->drawable.bitsPerPixel,
- bo->pitch, bo->handle,
- &sna->mode.fb_id))
+ sna->mode.fb_id = get_fb(sna, bo,
+ sna->front->drawable.width,
+ sna->front->drawable.height);
+ if (sna->mode.fb_id == 0)
return;
DBG(("%s: handle %d attached to fb %d\n",
@@ -468,6 +495,7 @@ sna_crtc_restore(struct sna *sna)
return;
}
+ bo->domain = DOMAIN_NONE;
scrn->displayWidth = bo->pitch / sna->mode.cpp;
sna->mode.fb_pixmap = sna->front->drawable.serialNumber;
}
@@ -652,28 +680,16 @@ sna_crtc_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
if (!bo)
return FALSE;
- DBG(("%s: create fb %dx%d@%d/%d\n",
- __FUNCTION__,
- scrn->virtualX, scrn->virtualY,
- scrn->depth, scrn->bitsPerPixel));
-
- assert(bo->tiling != I915_TILING_Y);
- ret = drmModeAddFB(sna->kgem.fd,
- scrn->virtualX, scrn->virtualY,
- scrn->depth, scrn->bitsPerPixel,
- bo->pitch, bo->handle,
- &sna_mode->fb_id);
- if (ret < 0) {
- ErrorF("%s: failed to add fb: %dx%d depth=%d, bpp=%d, pitch=%d\n",
- __FUNCTION__,
- scrn->virtualX, scrn->virtualY,
- scrn->depth, scrn->bitsPerPixel, bo->pitch);
+ /* recreate the fb in case the size has changed */
+ assert(bo->delta == 0);
+ sna_mode->fb_id = get_fb(sna, bo,
+ scrn->virtualX, scrn->virtualY);
+ if (sna_mode->fb_id == 0)
return FALSE;
- }
DBG(("%s: handle %d attached to fb %d\n",
__FUNCTION__, bo->handle, sna_mode->fb_id));
- bo->scanout = true;
+
bo->domain = DOMAIN_NONE;
sna_mode->fb_pixmap = sna->front->drawable.serialNumber;
}
@@ -773,22 +789,14 @@ sna_crtc_shadow_allocate(xf86CrtcPtr crtc, int width, int height)
return NULL;
}
- assert(bo->tiling != I915_TILING_Y);
- if (drmModeAddFB(sna->kgem.fd,
- width, height, scrn->depth, scrn->bitsPerPixel,
- bo->pitch, bo->handle,
- &sna_crtc->shadow_fb_id)) {
- ErrorF("%s: failed to add rotate fb: %dx%d depth=%d, bpp=%d, pitch=%d\n",
- __FUNCTION__,
- width, height,
- scrn->depth, scrn->bitsPerPixel, bo->pitch);
+ sna_crtc->shadow_fb_id = get_fb(sna, bo, width, height);
+ if (sna_crtc->shadow_fb_id == 0) {
scrn->pScreen->DestroyPixmap(shadow);
return NULL;
}
DBG(("%s: attached handle %d to fb %d\n",
__FUNCTION__, bo->handle, sna_crtc->shadow_fb_id));
- bo->scanout = true;
bo->domain = DOMAIN_NONE;
return sna_crtc->shadow = shadow;
}
@@ -813,10 +821,8 @@ sna_crtc_shadow_destroy(xf86CrtcPtr crtc, PixmapPtr pixmap, void *data)
DBG(("%s(fb=%d, handle=%d)\n", __FUNCTION__,
sna_crtc->shadow_fb_id, sna_pixmap_get_bo(pixmap)->handle));
- drmModeRmFB(sna->kgem.fd, sna_crtc->shadow_fb_id);
sna_crtc->shadow_fb_id = 0;
- kgem_bo_clear_scanout(&sna->kgem, sna_pixmap_get_bo(pixmap));
pixmap->drawable.pScreen->DestroyPixmap(pixmap);
sna_crtc->shadow = NULL;
}
@@ -1702,23 +1708,16 @@ sna_crtc_resize(ScrnInfoPtr scrn, int width, int height)
if (!bo)
goto fail;
- assert(bo->tiling != I915_TILING_Y);
- if (drmModeAddFB(sna->kgem.fd, width, height,
- scrn->depth, scrn->bitsPerPixel,
- bo->pitch, bo->handle,
- &mode->fb_id)) {
- ErrorF("%s: failed to add fb: %dx%d depth=%d, bpp=%d, pitch=%d\n",
- __FUNCTION__,
- width, height,
- scrn->depth, scrn->bitsPerPixel, bo->pitch);
+ assert(bo->delta == 0);
+
+ mode->fb_id = get_fb(sna, bo, width, height);
+ if (mode->fb_id == 0)
goto fail;
- }
DBG(("%s: handle %d, pixmap serial %lu attached to fb %d\n",
__FUNCTION__, bo->handle,
sna->front->drawable.serialNumber, mode->fb_id));
- bo->scanout = true;
for (i = 0; i < xf86_config->num_crtc; i++) {
xf86CrtcPtr crtc = xf86_config->crtc[i];
@@ -1739,17 +1738,12 @@ sna_crtc_resize(ScrnInfoPtr scrn, int width, int height)
assert(scrn->pScreen->GetScreenPixmap(scrn->pScreen) == sna->front);
assert(scrn->pScreen->GetWindowPixmap(scrn->pScreen->root) == sna->front);
- if (old_fb_id)
- drmModeRmFB(sna->kgem.fd, old_fb_id);
- kgem_bo_clear_scanout(&sna->kgem, sna_pixmap_get_bo(old_front));
scrn->pScreen->DestroyPixmap(old_front);
return TRUE;
fail:
DBG(("%s: restoring original front pixmap and fb\n", __FUNCTION__));
- if (old_fb_id != mode->fb_id)
- drmModeRmFB(sna->kgem.fd, mode->fb_id);
mode->fb_id = old_fb_id;
if (sna->front)
@@ -1843,15 +1837,9 @@ sna_page_flip(struct sna *sna,
/*
* Create a new handle for the back buffer
*/
- assert(bo->tiling != I915_TILING_Y);
- if (drmModeAddFB(sna->kgem.fd, scrn->virtualX, scrn->virtualY,
- scrn->depth, scrn->bitsPerPixel,
- bo->pitch, bo->handle,
- &mode->fb_id)) {
- ErrorF("%s: failed to add fb: %dx%d depth=%d, bpp=%d, pitch=%d\n",
- __FUNCTION__,
- scrn->virtualX, scrn->virtualY,
- scrn->depth, scrn->bitsPerPixel, bo->pitch);
+ mode->fb_id = get_fb(sna, bo, scrn->virtualX, scrn->virtualY);
+ if (mode->fb_id == 0) {
+ mode->fb_id = *old_fb;
return 0;
}
@@ -1871,23 +1859,14 @@ sna_page_flip(struct sna *sna,
*/
count = do_page_flip(sna, data, ref_crtc_hw_id);
DBG(("%s: page flipped %d crtcs\n", __FUNCTION__, count));
- if (count) {
- bo->scanout = true;
+ if (count)
bo->domain = DOMAIN_NONE;
- } else {
- drmModeRmFB(sna->kgem.fd, mode->fb_id);
+ else
mode->fb_id = *old_fb;
- }
return count;
}
-void sna_mode_delete_fb(struct sna *sna, uint32_t fb)
-{
- if (fb)
- drmModeRmFB(sna->kgem.fd, fb);
-}
-
static const xf86CrtcConfigFuncsRec sna_crtc_config_funcs = {
sna_crtc_resize
};
@@ -1932,11 +1911,8 @@ sna_mode_remove_fb(struct sna *sna)
DBG(("%s: deleting fb id %d for pixmap serial %d\n",
__FUNCTION__, mode->fb_id,mode->fb_pixmap));
- if (mode->fb_id) {
- drmModeRmFB(sna->kgem.fd, mode->fb_id);
- mode->fb_id = 0;
- mode->fb_pixmap = 0;
- }
+ mode->fb_id = 0;
+ mode->fb_pixmap = 0;
}
void
@@ -1957,7 +1933,6 @@ sna_mode_fini(struct sna *sna)
#endif
sna_mode_remove_fb(sna);
- kgem_bo_clear_scanout(&sna->kgem, sna_pixmap_get_bo(sna->front));
/* mode->shadow_fb_id should have been destroyed already */
}
diff --git a/src/sna/sna_dri.c b/src/sna/sna_dri.c
index d5eefcb..32602d5 100644
--- a/src/sna/sna_dri.c
+++ b/src/sna/sna_dri.c
@@ -336,7 +336,6 @@ static void _sna_dri_destroy_buffer(struct sna *sna, DRI2Buffer2Ptr buffer)
}
private->bo->flush = 0;
- kgem_bo_clear_scanout(&sna->kgem, private->bo); /* paranoia */
kgem_bo_destroy(&sna->kgem, private->bo);
free(buffer);
@@ -392,7 +391,6 @@ static void set_bo(PixmapPtr pixmap, struct kgem_bo *bo)
sna_damage_destroy(&priv->cpu_damage);
priv->undamaged = false;
- kgem_bo_clear_scanout(&sna->kgem, priv->gpu_bo); /* paranoia */
kgem_bo_destroy(&sna->kgem, priv->gpu_bo);
priv->gpu_bo = ref(bo);
}
@@ -860,18 +858,10 @@ sna_dri_add_frame_event(struct sna_dri_frame_event *info)
static void
sna_dri_frame_event_release_bo(struct kgem *kgem, struct kgem_bo *bo)
{
- kgem_bo_clear_scanout(kgem, bo);
kgem_bo_destroy(kgem, bo);
}
static void
-sna_dri_frame_event_finish(struct sna_dri_frame_event *info)
-{
- sna_mode_delete_fb(info->sna, info->old_fb);
- kgem_bo_clear_scanout(&info->sna->kgem, info->old_front.bo);
-}
-
-static void
sna_dri_frame_event_info_free(struct sna_dri_frame_event *info)
{
DBG(("%s: del[%p] (%p, %ld)\n", __FUNCTION__,
@@ -1177,13 +1167,10 @@ static void sna_dri_flip_event(struct sna *sna,
flip->event_data);
}
- sna_dri_frame_event_finish(flip);
sna_dri_frame_event_info_free(flip);
break;
case DRI2_FLIP_THROTTLE:
- sna_dri_frame_event_finish(flip);
-
assert(sna->dri.flip_pending[flip->pipe] == flip);
sna->dri.flip_pending[flip->pipe] = NULL;
@@ -1221,8 +1208,6 @@ static void sna_dri_flip_event(struct sna *sna,
flip->front->name != flip->old_front.name));
assert(sna->dri.flip_pending[flip->pipe] == flip);
- sna_dri_frame_event_finish(flip);
-
if (flip->front->name != flip->next_front.name) {
DBG(("%s: async flip continuing\n", __FUNCTION__));
@@ -1801,7 +1786,6 @@ blit:
}
info->front->name = info->back->name;
get_private(info->front)->bo = get_private(info->back)->bo;
- __kgem_flush(&sna->kgem, get_private(info->back)->bo);
}
if (bo == NULL) {
diff --git a/src/sna/sna_driver.c b/src/sna/sna_driver.c
index 7b3cfce..150e973 100644
--- a/src/sna/sna_driver.c
+++ b/src/sna/sna_driver.c
@@ -784,9 +784,6 @@ static Bool sna_close_screen(int scrnIndex, ScreenPtr screen)
sna_mode_remove_fb(sna);
if (sna->front) {
- struct kgem_bo *bo = sna_pixmap_get_bo(sna->front);
- if (bo)
- kgem_bo_clear_scanout(&sna->kgem, bo); /* valgrind */
screen->DestroyPixmap(sna->front);
sna->front = NULL;
}
commit 29d035279b2fe98d5ba9cf01125faea34d36fb76
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Fri May 4 09:11:31 2012 +0100
sna/dri: pageflip unref debugging
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/sna/sna.h b/src/sna/sna.h
index 956a038..5272a08 100644
--- a/src/sna/sna.h
+++ b/src/sna/sna.h
@@ -130,6 +130,8 @@ struct sna_pixmap {
uint32_t stride;
uint32_t clear_color;
+ uint32_t flush;
+
#define SOURCE_BIAS 4
uint16_t source_count;
uint8_t pinned :1;
@@ -138,7 +140,6 @@ struct sna_pixmap {
uint8_t undamaged :1;
uint8_t create :3;
uint8_t header :1;
- uint8_t flush :1;
};
struct sna_glyph {
diff --git a/src/sna/sna_dri.c b/src/sna/sna_dri.c
index 1ad2ff1..d5eefcb 100644
--- a/src/sna/sna_dri.c
+++ b/src/sna/sna_dri.c
@@ -163,7 +163,7 @@ static struct kgem_bo *sna_pixmap_set_dri(struct sna *sna,
if (priv == NULL)
return NULL;
- if (priv->flush)
+ if (priv->flush++)
return priv->gpu_bo;
tiling = color_tiling(sna, &pixmap->drawable);
@@ -181,7 +181,6 @@ static struct kgem_bo *sna_pixmap_set_dri(struct sna *sna,
/* Don't allow this named buffer to be replaced */
priv->pinned = 1;
- priv->flush = true;
return priv->gpu_bo;
}
@@ -317,17 +316,21 @@ static void _sna_dri_destroy_buffer(struct sna *sna, DRI2Buffer2Ptr buffer)
if (buffer == NULL)
return;
+ DBG(("%s: %p [handle=%d] -- refcnt=%d, pixmap=%d\n",
+ __FUNCTION__, buffer, private->bo->handle, private->refcnt,
+ private->pixmap ? private->pixmap->drawable.serialNumber : 0));
+
if (--private->refcnt == 0) {
if (private->pixmap) {
ScreenPtr screen = private->pixmap->drawable.pScreen;
struct sna_pixmap *priv = sna_pixmap(private->pixmap);
/* Undo the DRI markings on this pixmap */
- assert(priv->flush);
- list_del(&priv->list);
- sna_accel_watch_flush(sna, -1);
- priv->pinned = private->pixmap == sna->front;
- priv->flush = false;
+ if (priv->flush && --priv->flush == 0) {
+ list_del(&priv->list);
+ sna_accel_watch_flush(sna, -1);
+ priv->pinned = private->pixmap == sna->front;
+ }
screen->DestroyPixmap(private->pixmap);
}
@@ -1238,6 +1241,8 @@ static void sna_dri_flip_event(struct sna *sna,
flip->next_front.name = flip->front->name;
flip->off_delay = 5;
} else if (--flip->off_delay) {
+ DBG(("%s: queuing no-flip [delay=%d]\n",
+ __FUNCTION__, flip->off_delay));
/* Just queue a no-op flip to trigger another event */
flip->count = sna_page_flip(sna,
get_private(flip->front)->bo,
@@ -1765,6 +1770,13 @@ blit:
goto blit;
}
+ DBG(("%s: referencing (%p:%d, %p:%d)\n",
+ __FUNCTION__,
+ front, get_private(front)->refcnt,
+ back, get_private(back)->refcnt));
+ sna_dri_reference_buffer(front);
+ sna_dri_reference_buffer(back);
+
if (!sna_dri_page_flip(sna, info)) {
sna_dri_frame_event_info_free(info);
goto blit;
@@ -1773,9 +1785,6 @@ blit:
info->next_front.name = info->front->name;
info->next_front.bo = get_private(info->front)->bo;
info->off_delay = 5;
-
- sna_dri_reference_buffer(front);
- sna_dri_reference_buffer(back);
} else if (info->type != DRI2_ASYNC_FLIP) {
/* A normal vsync'ed client is finishing, wait for it
* to unpin the old framebuffer before taking over.
More information about the xorg-commit
mailing list