xf86-video-intel: 3 commits - src/intel_uxa.c src/sna/kgem.c src/sna/kgem.h src/sna/sna_display.c src/sna/sna_dri.c

Chris Wilson ickle at kemper.freedesktop.org
Tue Feb 21 09:45:22 PST 2012


 src/intel_uxa.c       |    7 +++++++
 src/sna/kgem.c        |   14 +++++++++++++-
 src/sna/kgem.h        |    2 ++
 src/sna/sna_display.c |   17 ++++++-----------
 src/sna/sna_dri.c     |   17 ++++++++++++-----
 5 files changed, 40 insertions(+), 17 deletions(-)

New commits:
commit 168c87a340119e65b1d7ccbbf59da820044ca936
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Tue Feb 21 13:16:43 2012 +0000

    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 at chris-wilson.co.uk>

diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index e7c4987..f79deff 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 f3a7b94..30303ce 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 b2779aa..ae5bec6 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 1def833..fe3d1cf 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__));
commit d7415742a5f78958489216f450411603b1eff9a7
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Tue Feb 21 16:33:26 2012 +0000

    sna/dri: Queue a flush on the back DRI2 when enqueing a flip
    
    As we may wait upon the bo having finished rendering before we can
    execute the flip, flushing the render cache as early as possible is
    beneficial
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_dri.c b/src/sna/sna_dri.c
index 78d9a6e..1def833 100644
--- a/src/sna/sna_dri.c
+++ b/src/sna/sna_dri.c
@@ -1636,6 +1636,7 @@ 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) {
commit 2715a455f7bfbecd7a6977184dc6180a09d06e1f
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Tue Feb 21 14:49:30 2012 +0000

    uxa: Prevent laggy applications by throttling after rendering
    
    Before blocking and waiting for further input, we need to make sure that
    we have not developed too large a queue of outstanding rendering. As we
    rendering to the front-buffer with no natural throttling and allow X
    clients to render as fast as they wish, it is entirely possible for a
    large queue of outstanding rendering to develop. For such an example,
    watch firefox rendering the fishietank demo and notice the delay that
    can build up before the tooltips appear.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/intel_uxa.c b/src/intel_uxa.c
index 0cb8df3..ed4f375 100644
--- a/src/intel_uxa.c
+++ b/src/intel_uxa.c
@@ -32,6 +32,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #endif
 
 #include <xf86.h>
+#include <xf86drm.h>
 #include <xaarop.h>
 #include <string.h>
 #include <errno.h>
@@ -1001,6 +1002,11 @@ static void intel_flush_rendering(intel_screen_private *intel)
 	intel->needs_flush = 0;
 }
 
+static void intel_throttle(intel_screen_private *intel)
+{
+	drmCommandNone(intel->drmSubFD, DRM_I915_GEM_THROTTLE);
+}
+
 void intel_uxa_block_handler(intel_screen_private *intel)
 {
 	if (intel->shadow_damage &&
@@ -1015,6 +1021,7 @@ void intel_uxa_block_handler(intel_screen_private *intel)
 	 */
 	intel_glamor_flush(intel);
 	intel_flush_rendering(intel);
+	intel_throttle(intel);
 }
 
 static PixmapPtr


More information about the xorg-commit mailing list