i965: Make sure we don't use CPU maps for the scanout buffer.
authorKenneth Graunke <kenneth@whitecape.org>
Mon, 3 Apr 2017 07:03:01 +0000 (00:03 -0700)
committerKenneth Graunke <kenneth@whitecape.org>
Mon, 10 Apr 2017 21:30:49 +0000 (14:30 -0700)
Using an incoherent CPU map on the active scanout buffer is really
sketchy - we may need extra flushing via GEM_SW_FINISH, or using
drmModeDirtyFB() and kernel commit a6a7cc4b7db6d (4.10+).

Chris suggests "never ever do that", which seems like a wise plan!

intel_miptree_map_raw() uses CPU maps on linear buffers.

Having a linear scanout buffer should be really rare, and mapping the
front buffer should be similarly rare.  Together, it should basically
never happen.  But, in case it does somehow...make sure that mapping
the scanout buffer always goes through an uncached GTT map.

v2: Add a giant comment written by Chris Wilson.

Reviewed-by: Jason Ekstrand <jason@jlekstrand.net>
Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
src/mesa/drivers/dri/i965/intel_mipmap_tree.c

index 467ada5079b8300037ca3b6bd774d447160f20a3..a775d5589d5d3f5a83f1096259382296a8d6b914 100644 (file)
@@ -2460,7 +2460,19 @@ intel_miptree_map_raw(struct brw_context *brw, struct intel_mipmap_tree *mt)
    if (drm_intel_bo_references(brw->batch.bo, bo))
       intel_batchbuffer_flush(brw);
 
-   if (mt->tiling != I915_TILING_NONE)
+   /* brw_bo_map() uses a WB mmaping of the buffer's backing storage. It
+    * will utilize the CPU cache even if the buffer is incoherent with the
+    * GPU (i.e. any writes will be stored in the cache and not flushed to
+    * memory and so will be invisible to the GPU or display engine). This
+    * is the majority of buffers on a !llc machine, but even on a llc
+    * almost all scanouts are incoherent with the CPU. A WB write into the
+    * backing storage of the current scanout will not be immediately
+    * visible on the screen. The transfer from cache to screen is slow and
+    * indeterministic causing visible glitching on the screen. Never use
+    * this WB mapping for writes to an active scanout (reads are fine, so
+    * long as cache consistency is maintained).
+    */
+   if (mt->tiling != I915_TILING_NONE || mt->is_scanout)
       brw_bo_map_gtt(brw, bo, "miptree");
    else
       brw_bo_map(brw, bo, true, "miptree");