[PATCH] drm/i915: Asynchronously wait for the overlay to finish

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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@xxxxxxxxxxxxxxxxxx>
---
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

_______________________________________________
Intel-gfx mailing list
Intel-gfx@xxxxxxxxxxxxxxxxxxxxx
https://lists.freedesktop.org/mailman/listinfo/intel-gfx




[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]
  Powered by Linux