From: Ville Syrjälä <ville.syrjala@xxxxxxxxxxxxxxx> FBC host modification tracking only works through GTT mmaps, so any direct CPU access needs to manually nuke the compressed framebuffer on modifications. Do the nuking from the SW_FINISH ioctl. v2: nuke from SW_FINISH insted of DIRTYFB ioctl v3: Call intel_fbc_nuke() only when pin_display is true v4: Don't oops if dev_priv->fbc.fb is NULL Reviewed-by: Chris Wilson <chris@xxxxxxxxxxxxxxxxxx> Signed-off-by: Ville Syrjälä <ville.syrjala@xxxxxxxxxxxxxxx> --- drivers/gpu/drm/i915/i915_gem.c | 4 +++- drivers/gpu/drm/i915/intel_drv.h | 1 + drivers/gpu/drm/i915/intel_pm.c | 33 +++++++++++++++++++++++++++++++++ 3 files changed, 37 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 0ecc735..b5395aa 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1306,8 +1306,10 @@ i915_gem_sw_finish_ioctl(struct drm_device *dev, void *data, } /* Pinned buffers may be scanout, so flush the cache */ - if (obj->pin_display) + if (obj->pin_display) { i915_gem_object_flush_cpu_write_domain(obj, true); + intel_fbc_nuke(obj); + } drm_gem_object_unreference(&obj->base); unlock: diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 2fa843f..2baf0dd 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -836,6 +836,7 @@ void intel_update_sprite_watermarks(struct drm_plane *plane, bool enabled, bool scaled); void intel_init_pm(struct drm_device *dev); bool intel_fbc_enabled(struct drm_device *dev); +void intel_fbc_nuke(struct drm_i915_gem_object *obj); void intel_update_fbc(struct drm_device *dev); void intel_gpu_ips_init(struct drm_i915_private *dev_priv); void intel_gpu_ips_teardown(void); diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 4f274ca..f46bc36 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -418,6 +418,39 @@ void intel_disable_fbc(struct drm_device *dev) } } +void intel_fbc_nuke(struct drm_i915_gem_object *obj) +{ + struct drm_device *dev = obj->base.dev; + struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_crtc *crtc; + + if (dev_priv->fbc.fbc_work) { + if (to_intel_framebuffer(dev_priv->fbc.fbc_work->fb)->obj != obj) + return; + + crtc = dev_priv->fbc.fbc_work->crtc; + } else { + if (!dev_priv->fbc.fb) + return; + + if (to_intel_framebuffer(dev_priv->fbc.fb)->obj != obj) + return; + + if (WARN_ON(dev_priv->fbc.plane < 0)) + return; + + crtc = dev_priv->plane_to_crtc_mapping[dev_priv->fbc.plane]; + } + + intel_disable_fbc(dev); + + /* + * Must wait until the next vblank before re-enabling + * otherwise the nuking won't actually happen. + */ + intel_enable_fbc(crtc, 500); +} + static bool set_no_fbc_reason(struct drm_i915_private *dev_priv, enum no_fbc_reason reason) { -- 1.8.3.2 _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/intel-gfx