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. Hook up the dirtyfb ioctl to do just that. Signed-off-by: Ville Syrjälä <ville.syrjala@xxxxxxxxxxxxxxx> --- drivers/gpu/drm/i915/intel_display.c | 19 +++++++++++++++++++ drivers/gpu/drm/i915/intel_drv.h | 1 + drivers/gpu/drm/i915/intel_pm.c | 30 ++++++++++++++++++++++++++++++ 3 files changed, 50 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index af0eafe..e5de929 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -10385,8 +10385,27 @@ static int intel_user_framebuffer_create_handle(struct drm_framebuffer *fb, return drm_gem_handle_create(file, &obj->base, handle); } +static int intel_user_framebuffer_dirty(struct drm_framebuffer *fb, + struct drm_file *file_priv, + unsigned flags, unsigned color, + struct drm_clip_rect *clips, + unsigned num_clips) +{ + struct drm_device *dev = fb->dev; + + if (!I915_HAS_FBC(dev)) + return 0; + + mutex_lock(&dev->struct_mutex); + intel_fbc_nuke(fb); + mutex_unlock(&dev->struct_mutex); + + return 0; +} + static const struct drm_framebuffer_funcs intel_fb_funcs = { .destroy = intel_user_framebuffer_destroy, + .dirty = intel_user_framebuffer_dirty, .create_handle = intel_user_framebuffer_create_handle, }; diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index f9e9ca0..c11ef8a 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -840,6 +840,7 @@ void intel_fbc_flip_start(struct drm_crtc *crtc, struct drm_framebuffer *fb); void intel_fbc_flip_end(struct drm_crtc *crtc, struct drm_framebuffer *fb); +void intel_fbc_nuke(struct drm_framebuffer *fb); 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 2a613ac..d84630a 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -508,6 +508,36 @@ void intel_fbc_flip_end(struct drm_crtc *crtc, intel_update_fbc_fb(crtc, fb); } +void intel_fbc_nuke(struct drm_framebuffer *fb) +{ + struct drm_device *dev = fb->dev; + struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_crtc *crtc; + + if (dev_priv->fbc.fbc_work) { + if (dev_priv->fbc.fbc_work->fb != fb) + return; + + crtc = dev_priv->fbc.fbc_work->crtc; + } else { + if (dev_priv->fbc.fb != fb) + 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