summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2009-11-29 21:12:07 +0000
committerChris Wilson <chris@chris-wilson.co.uk>2009-11-29 22:42:07 +0000
commitf7540f06090753cba1190aa9e8cdea05a9512077 (patch)
tree0a67c791694d04b2c4c7ec608b11de56f34d9ccc
parent9a2c18fb92659d57741bfdcacbe4f69aab361532 (diff)
Only flush batch during prepare access if it may modify the pixmap.
As we track when a pixmap is active inside a batch buffer, we can avoid unnecessary flushes of the batch when mapping a pixmap back to the CPU. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r--src/i830_uxa.c26
1 files changed, 18 insertions, 8 deletions
diff --git a/src/i830_uxa.c b/src/i830_uxa.c
index 8f8c5e9c..b11f2f75 100644
--- a/src/i830_uxa.c
+++ b/src/i830_uxa.c
@@ -558,22 +558,20 @@ void i830_set_pixmap_bo(PixmapPtr pixmap, dri_bo * bo)
static Bool i830_uxa_prepare_access(PixmapPtr pixmap, uxa_access_t access)
{
- dri_bo *bo = i830_get_pixmap_bo(pixmap);
ScrnInfoPtr scrn = xf86Screens[pixmap->drawable.pScreen->myNum];
intel_screen_private *intel = intel_get_screen_private(scrn);
+ struct intel_pixmap *priv = i830_get_pixmap_intel(pixmap);
+ dri_bo *bo = priv->bo;
- intel_batch_flush(scrn, FALSE);
+ if (!list_is_empty(&priv->batch) &&
+ (access == UXA_ACCESS_RW || priv->batch_write_domain))
+ intel_batch_flush(scrn, TRUE);
/* No VT sema or GEM? No GTT mapping. */
if (!scrn->vtSema) {
if (dri_bo_map(bo, access == UXA_ACCESS_RW) != 0)
return FALSE;
- pixmap->devPrivate.ptr = bo->virtual;
- return TRUE;
- }
-
- /* Kernel manages fences at GTT map/fault time */
- if (bo->size < intel->max_gtt_map_size) {
+ } else if (bo->size < intel->max_gtt_map_size) {
if (drm_intel_gem_bo_map_gtt(bo)) {
xf86DrvMsg(scrn->scrnIndex, X_WARNING,
"%s: bo map failed\n", __FUNCTION__);
@@ -588,6 +586,18 @@ static Bool i830_uxa_prepare_access(PixmapPtr pixmap, uxa_access_t access)
}
pixmap->devPrivate.ptr = bo->virtual;
+ /* This acts as a synchronisation point. */
+ while (!list_is_empty(&intel->flush_pixmaps)) {
+ struct intel_pixmap *entry;
+
+ entry = list_first_entry(&intel->flush_pixmaps,
+ struct intel_pixmap,
+ flush);
+
+ entry->flush_read_domains = entry->flush_write_domain = 0;
+ list_del(&entry->flush);
+ }
+
return TRUE;
}