diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2012-02-21 13:16:43 +0000 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2012-02-21 16:41:53 +0000 |
commit | 168c87a340119e65b1d7ccbbf59da820044ca936 (patch) | |
tree | eb57841d26db0e7a4cadf926f8879d317fab7e77 | |
parent | d7415742a5f78958489216f450411603b1eff9a7 (diff) |
sna: Clear the scanout flag after releasing the scanout pixmap
In the future, this will be a good place to restore the cache level of
the bo as well.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r-- | src/sna/kgem.c | 14 | ||||
-rw-r--r-- | src/sna/kgem.h | 2 | ||||
-rw-r--r-- | src/sna/sna_display.c | 17 | ||||
-rw-r--r-- | src/sna/sna_dri.c | 16 |
4 files changed, 32 insertions, 17 deletions
diff --git a/src/sna/kgem.c b/src/sna/kgem.c index e7c49874..f79deff9 100644 --- a/src/sna/kgem.c +++ b/src/sna/kgem.c @@ -1067,8 +1067,9 @@ static void __kgem_bo_destroy(struct kgem *kgem, struct kgem_bo *bo) assert(list_is_empty(&bo->list)); assert(bo->vmap == false && bo->sync == false); assert(bo->io == false); + assert(bo->scanout == false); + assert(bo->flush == false); - bo->scanout = bo->flush = false; if (bo->rq) { struct list *cache; @@ -3660,6 +3661,17 @@ 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->reusable = true; + + if (!bo->scanout) + return; + + bo->scanout = false; +} + 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 f3a7b94e..30303ce0 100644 --- a/src/sna/kgem.h +++ b/src/sna/kgem.h @@ -499,6 +499,8 @@ struct kgem_bo *kgem_create_buffer_2d(struct kgem *kgem, void **ret); 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_display.c b/src/sna/sna_display.c index b2779aa1..ae5bec6f 100644 --- a/src/sna/sna_display.c +++ b/src/sna/sna_display.c @@ -648,7 +648,6 @@ sna_crtc_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode, scrn->depth, scrn->bitsPerPixel)); assert(bo->tiling != I915_TILING_Y); - bo->scanout = true; ret = drmModeAddFB(sna->kgem.fd, scrn->virtualX, scrn->virtualY, scrn->depth, scrn->bitsPerPixel, @@ -664,6 +663,7 @@ sna_crtc_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode, DBG(("%s: handle %d attached to fb %d\n", __FUNCTION__, bo->handle, sna_mode->fb_id)); + bo->scanout = true; sna_mode->fb_pixmap = sna->front->drawable.serialNumber; } @@ -765,7 +765,6 @@ sna_crtc_shadow_allocate(xf86CrtcPtr crtc, int width, int height) } assert(bo->tiling != I915_TILING_Y); - bo->scanout = true; if (drmModeAddFB(sna->kgem.fd, width, height, scrn->depth, scrn->bitsPerPixel, bo->pitch, bo->handle, @@ -780,6 +779,7 @@ sna_crtc_shadow_allocate(xf86CrtcPtr crtc, int width, int height) DBG(("%s: attached handle %d to fb %d\n", __FUNCTION__, bo->handle, sna_crtc->shadow_fb_id)); + bo->scanout = true; return sna_crtc->shadow = shadow; } @@ -806,6 +806,7 @@ sna_crtc_shadow_destroy(xf86CrtcPtr crtc, PixmapPtr pixmap, void *data) 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; } @@ -1674,7 +1675,6 @@ sna_crtc_resize(ScrnInfoPtr scrn, int width, int height) goto fail; assert(bo->tiling != I915_TILING_Y); - bo->scanout = true; if (drmModeAddFB(sna->kgem.fd, width, height, scrn->depth, scrn->bitsPerPixel, bo->pitch, bo->handle, @@ -1690,6 +1690,7 @@ sna_crtc_resize(ScrnInfoPtr scrn, int width, int height) __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]; @@ -1711,7 +1712,7 @@ sna_crtc_resize(ScrnInfoPtr scrn, int width, int height) if (old_fb_id) drmModeRmFB(sna->kgem.fd, old_fb_id); - sna_pixmap_get_bo(old_front)->needs_flush = true; + kgem_bo_clear_scanout(&sna->kgem, sna_pixmap_get_bo(old_front)); scrn->pScreen->DestroyPixmap(old_front); return TRUE; @@ -1842,13 +1843,7 @@ 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) { - /* Although the kernel performs an implicit flush upon - * page-flipping, marking the bo as requiring a flush - * here ensures that the buffer goes into the active cache - * upon release. - */ - bo->needs_flush = true; - bo->reusable = true; + bo->scanout = true; } else { drmModeRmFB(sna->kgem.fd, mode->fb_id); mode->fb_id = *old_fb; diff --git a/src/sna/sna_dri.c b/src/sna/sna_dri.c index 1def8336..fe3d1cf8 100644 --- a/src/sna/sna_dri.c +++ b/src/sna/sna_dri.c @@ -717,12 +717,18 @@ 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) { - bo->needs_flush = true; /* has been used externally, reset domains */ - bo->reusable = true; /* No longer in use by an external client */ + 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__, @@ -1028,12 +1034,12 @@ static void sna_dri_flip_event(struct sna *sna, flip->event_data); } - sna_mode_delete_fb(flip->sna, flip->old_fb); + sna_dri_frame_event_finish(flip); sna_dri_frame_event_info_free(flip); break; case DRI2_FLIP_THROTTLE: - sna_mode_delete_fb(sna, flip->old_fb); + sna_dri_frame_event_finish(flip); assert(sna->dri.flip_pending[flip->pipe] == flip); sna->dri.flip_pending[flip->pipe] = NULL; @@ -1071,7 +1077,7 @@ 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_mode_delete_fb(flip->sna, flip->old_fb); + sna_dri_frame_event_finish(flip); if (flip->front->name != flip->next_front.name) { DBG(("%s: async flip continuing\n", __FUNCTION__)); |