[Intel-gfx] [PATCH] drm/i915: Asynchronously wait for the overlay to finish
Chris Wilson
chris at chris-wilson.co.uk
Wed Dec 7 18:45:45 UTC 2016
Treat the overlay as another wait-source, just like other rendering to
the fb, and asynchronously wait upon it before doing an atomic modeset.
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
---
This is half the solution, it should prevent the wait before disabling
the overlay, but we still need to remove the wait from inside
intel_overlay_off() itself, preferably by switching to mmio instead of
CS here.
---
drivers/gpu/drm/i915/intel_display.c | 9 +++++++++
drivers/gpu/drm/i915/intel_drv.h | 2 ++
drivers/gpu/drm/i915/intel_overlay.c | 19 +++++++++++++++++++
3 files changed, 30 insertions(+)
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index bfcd368ebf6f..6c51b0f2a96e 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -14183,9 +14183,18 @@ intel_prepare_plane_fb(struct drm_plane *plane,
int ret;
if (plane->state->fb && old_plane_needs_modeset(plane, new_state)) {
+ struct intel_crtc *crtc = to_intel_crtc(plane->state->crtc);
struct drm_i915_gem_object *old_obj =
intel_fb_obj(plane->state->fb);
+ /* Queue this update after a previous old-school overlay flip */
+ if (crtc->overlay) {
+ ret = intel_overlay_await(crtc->overlay,
+ &intel_state->commit_ready);
+ if (ret)
+ return ret;
+ }
+
/* Big Hammer, we also need to ensure that any pending
* MI_WAIT_FOR_EVENT inside a user batch buffer on the
* current scanout is retired before unpinning the old
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 5c521065dc3b..87fd544339d9 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1566,6 +1566,8 @@ void intel_attach_aspect_ratio_property(struct drm_connector *connector);
/* intel_overlay.c */
void intel_setup_overlay(struct drm_i915_private *dev_priv);
void intel_cleanup_overlay(struct drm_i915_private *dev_priv);
+int intel_overlay_await(struct intel_overlay *overlay,
+ struct i915_sw_fence *fence);
int intel_overlay_switch_off(struct intel_overlay *overlay);
int intel_overlay_put_image_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv);
diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c
index 79f93e7d699d..476a25961f34 100644
--- a/drivers/gpu/drm/i915/intel_overlay.c
+++ b/drivers/gpu/drm/i915/intel_overlay.c
@@ -855,6 +855,25 @@ static int intel_overlay_do_put_image(struct intel_overlay *overlay,
return ret;
}
+int intel_overlay_await(struct intel_overlay *overlay,
+ struct i915_sw_fence *fence)
+{
+ struct drm_i915_gem_request *request;
+ int err;
+
+ request = i915_gem_active_peek(&overlay->last_flip,
+ &overlay->i915->drm.struct_mutex);
+ if (!request)
+ return 0;
+
+ err = i915_sw_fence_await_dma_fence(fence,
+ &request->fence, 0, GFP_KERNEL);
+ if (err < 0)
+ return err;
+
+ return 0;
+}
+
int intel_overlay_switch_off(struct intel_overlay *overlay)
{
struct drm_i915_private *dev_priv = overlay->i915;
--
2.11.0
More information about the Intel-gfx
mailing list