[PATCH 4/4] fb-changed

Chris Wilson chris at chris-wilson.co.uk
Sun Aug 21 12:36:24 UTC 2016


---
 drivers/gpu/drm/i915/intel_display.c | 57 ++++++++++++++++++++++--------------
 1 file changed, 35 insertions(+), 22 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 616d1991dcf6..9d693351327f 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -12317,9 +12317,6 @@ int intel_plane_atomic_calc_changes(struct drm_crtc_state *crtc_state,
 	if (!was_visible && !visible)
 		return 0;
 
-	if (fb != old_plane_state->base.fb)
-		pipe_config->fb_changed = true;
-
 	turn_off = was_visible && (!visible || mode_changed);
 	turn_on = visible && (!was_visible || mode_changed);
 
@@ -13906,6 +13903,17 @@ static int intel_atomic_check(struct drm_device *dev,
 	return calc_watermark_data(state);
 }
 
+static bool old_plane_needs_modeset(struct drm_plane *plane,
+				    struct drm_plane_state *new_state)
+{
+	struct drm_crtc_state *crtc_state;
+
+	crtc_state = drm_atomic_get_existing_crtc_state(new_state->state,
+							plane->state->crtc);
+
+	return needs_modeset(crtc_state);
+}
+
 /**
  * intel_prepare_plane_fb - Prepare fb for usage on plane
  * @plane: drm plane to prepare for
@@ -13927,16 +13935,12 @@ intel_prepare_plane_fb(struct drm_plane *plane,
 	struct drm_device *dev = plane->dev;
 	struct drm_framebuffer *fb = new_state->fb;
 	struct drm_i915_gem_object *obj = intel_fb_obj(fb);
-	struct drm_i915_gem_object *old_obj = intel_fb_obj(plane->state->fb);
 	struct reservation_object *resv;
-	int ret = 0;
-
-	if (!obj && !old_obj)
-		return 0;
+	int ret;
 
-	if (old_obj) {
-		struct drm_crtc_state *crtc_state =
-			drm_atomic_get_existing_crtc_state(new_state->state, plane->state->crtc);
+	if (plane->state->fb && old_plane_needs_modeset(plane, new_state)) {
+		struct drm_i915_gem_object *old_obj =
+			intel_fb_obj(plane->state->fb);
 
 		/* Big Hammer, we also need to ensure that any pending
 		 * MI_WAIT_FOR_EVENT inside a user batch buffer on the
@@ -13949,8 +13953,8 @@ intel_prepare_plane_fb(struct drm_plane *plane,
 		 * This should only fail upon a hung GPU, in which case we
 		 * can safely continue.
 		 */
-		if (needs_modeset(crtc_state))
-			ret = i915_gem_object_wait_rendering(old_obj, true);
+
+		ret = i915_gem_object_wait_rendering(old_obj, true);
 		if (ret) {
 			/* GPU hangs should have been swallowed by the wait */
 			WARN_ON(ret == -EIO);
@@ -13978,25 +13982,34 @@ intel_prepare_plane_fb(struct drm_plane *plane,
 	    INTEL_INFO(dev)->cursor_needs_physical) {
 		int align = IS_I830(dev) ? 16 * 1024 : 256;
 		ret = i915_gem_object_attach_phys(obj, align);
-		if (ret)
+		if (ret) {
 			DRM_DEBUG_KMS("failed to attach phys object\n");
+			return ret;
+		}
 	} else {
 		struct i915_vma *vma;
 
-		vma = intel_pin_and_fence_fb_obj(fb, new_state->rotation);
+		vma = intel_pin_and_fence_fb_obj(fb,
+						 new_state->rotation);
 		if (IS_ERR(vma))
-			ret = PTR_ERR(vma);
+			return PTR_ERR(vma);
 
 		to_intel_plane_state(new_state)->vma = vma;
-	}
+		if (to_intel_plane_state(plane->state)->vma != vma) {
+			struct intel_crtc_state *crtc_state;
 
-	if (ret == 0) {
-		new_state->fence =
-			&i915_gem_active_get(&obj->last_write,
-					     &obj->base.dev->struct_mutex)->fence;
+			crtc_state = intel_atomic_get_crtc_state(new_state->state,
+								 to_intel_crtc(new_state->crtc));
+			crtc_state->fb_changed = true;
+
+		}
 	}
 
-	return ret;
+	new_state->fence =
+		&i915_gem_active_get(&obj->last_write,
+				     &obj->base.dev->struct_mutex)->fence;
+
+	return 0;
 }
 
 /**
-- 
2.9.3



More information about the Intel-gfx-trybot mailing list