Doing mixed rendering into the front/back scanout buffers lead to the interesting rediscovery of clflushing when page-flipping. A painful experience indeed. Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk> --- drivers/gpu/drm/i915/i915_drv.h | 1 + drivers/gpu/drm/i915/i915_gem.c | 7 +++++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 4eee0bf..569475b 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -865,6 +865,7 @@ struct drm_i915_gem_object { unsigned int fenced_gpu_access:1; unsigned int cache_level:2; + unsigned int cache_dirty:2; unsigned int has_aliasing_ppgtt_mapping:1; diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index eb63c69..8e547dd 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -2907,12 +2907,15 @@ i915_gem_clflush_object(struct drm_i915_gem_object *obj) * snooping behaviour occurs naturally as the result of our domain * tracking. */ - if (obj->cache_level != I915_CACHE_NONE) + if (obj->cache_level != I915_CACHE_NONE) { + obj->cache_dirty = obj->cache_level; return; + } trace_i915_gem_object_clflush(obj); drm_clflush_pages(obj->pages, obj->base.size / PAGE_SIZE); + obj->cache_dirty = I915_CACHE_NONE; } /** Flushes any GPU write domain for the object if it's dirty. */ @@ -3066,7 +3069,7 @@ int i915_gem_object_set_cache_level(struct drm_i915_gem_object *obj, obj, cache_level); } - if (cache_level == I915_CACHE_NONE) { + if (obj->cache_dirty) { u32 old_read_domains, old_write_domain; /* If we're coming from LLC cached, then we haven't -- 1.7.9.1