[Intel-gfx] [PATCH 1/3] drm/i915: Don't waste fences on sprite buffers

ville.syrjala at linux.intel.com ville.syrjala at linux.intel.com
Tue Jan 28 13:51:54 CET 2014


From: Ville Syrjälä <ville.syrjala at linux.intel.com>

Sprites never need fences for scanout, so let's not waste them where not
needed.

Renamed stuff a bit so that we have a nice set of functions for pinning
scanout buffers. intel_pin_fb_obj() and intel_unpin_fb_obj() are now the
versions that don't add fences, are intel_pin_fenced_fb_obj() and
intel_unpin_fenced_fb_obj() are the versions that do.

Signed-off-by: Ville Syrjälä <ville.syrjala at linux.intel.com>
---
 drivers/gpu/drm/i915/intel_display.c | 98 ++++++++++++++++++++++++------------
 drivers/gpu/drm/i915/intel_drv.h     | 10 ++--
 drivers/gpu/drm/i915/intel_fbdev.c   |  2 +-
 drivers/gpu/drm/i915/intel_sprite.c  |  2 +-
 4 files changed, 75 insertions(+), 37 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 122f871..fd48c2e 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -1929,27 +1929,22 @@ static bool need_vtd_wa(struct drm_device *dev)
 	return false;
 }
 
-int
-intel_pin_and_fence_fb_obj(struct drm_device *dev,
-			   struct drm_i915_gem_object *obj,
-			   struct intel_ring_buffer *pipelined)
+static int intel_fb_obj_alignment(struct drm_device *dev,
+				  struct drm_i915_gem_object *obj,
+				  u32 *alignment)
 {
-	struct drm_i915_private *dev_priv = dev->dev_private;
-	u32 alignment;
-	int ret;
-
 	switch (obj->tiling_mode) {
 	case I915_TILING_NONE:
 		if (IS_BROADWATER(dev) || IS_CRESTLINE(dev))
-			alignment = 128 * 1024;
+			*alignment = 128 * 1024;
 		else if (INTEL_INFO(dev)->gen >= 4)
-			alignment = 4 * 1024;
+			*alignment = 4 * 1024;
 		else
-			alignment = 64 * 1024;
+			*alignment = 64 * 1024;
 		break;
 	case I915_TILING_X:
 		/* pin() will align the object as required by fence */
-		alignment = 0;
+		*alignment = 0;
 		break;
 	case I915_TILING_Y:
 		WARN(1, "Y tiled bo slipped through, driver bug!\n");
@@ -1963,8 +1958,23 @@ intel_pin_and_fence_fb_obj(struct drm_device *dev,
 	 * we should always have valid PTE following the scanout preventing
 	 * the VT-d warning.
 	 */
-	if (need_vtd_wa(dev) && alignment < 256 * 1024)
-		alignment = 256 * 1024;
+	if (need_vtd_wa(dev) && *alignment < 256 * 1024)
+		*alignment = 256 * 1024;
+
+	return 0;
+}
+
+int intel_pin_fenced_fb_obj(struct drm_device *dev,
+			    struct drm_i915_gem_object *obj,
+			    struct intel_ring_buffer *pipelined)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	u32 alignment;
+	int ret;
+
+	ret = intel_fb_obj_alignment(dev, obj, &alignment);
+	if (ret)
+		return ret;
 
 	dev_priv->mm.interruptible = false;
 	ret = i915_gem_object_pin_to_display_plane(obj, alignment, pipelined);
@@ -1992,12 +2002,36 @@ err_interruptible:
 	return ret;
 }
 
-void intel_unpin_fb_obj(struct drm_i915_gem_object *obj)
+void intel_unpin_fenced_fb_obj(struct drm_i915_gem_object *obj)
 {
 	i915_gem_object_unpin_fence(obj);
 	i915_gem_object_unpin_from_display_plane(obj);
 }
 
+int intel_pin_fb_obj(struct drm_device *dev,
+		     struct drm_i915_gem_object *obj,
+		     struct intel_ring_buffer *pipelined)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	u32 alignment;
+	int ret;
+
+	ret = intel_fb_obj_alignment(dev, obj, &alignment);
+	if (ret)
+		return ret;
+
+	dev_priv->mm.interruptible = false;
+	ret = i915_gem_object_pin_to_display_plane(obj, alignment, pipelined);
+
+	dev_priv->mm.interruptible = true;
+	return ret;
+}
+
+void intel_unpin_fb_obj(struct drm_i915_gem_object *obj)
+{
+	i915_gem_object_unpin_from_display_plane(obj);
+}
+
 /* Computes the linear offset to the base tile and adjusts x, y. bytes per pixel
  * is assumed to be a power-of-two. */
 unsigned long intel_gen4_compute_page_offset(int *x, int *y,
@@ -2350,9 +2384,9 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
 	}
 
 	mutex_lock(&dev->struct_mutex);
-	ret = intel_pin_and_fence_fb_obj(dev,
-					 to_intel_framebuffer(fb)->obj,
-					 NULL);
+	ret = intel_pin_fenced_fb_obj(dev,
+				      to_intel_framebuffer(fb)->obj,
+				      NULL);
 	if (ret != 0) {
 		mutex_unlock(&dev->struct_mutex);
 		DRM_ERROR("pin & fence failed\n");
@@ -2392,7 +2426,7 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
 
 	ret = dev_priv->display.update_plane(crtc, fb, x, y);
 	if (ret) {
-		intel_unpin_fb_obj(to_intel_framebuffer(fb)->obj);
+		intel_unpin_fenced_fb_obj(to_intel_framebuffer(fb)->obj);
 		mutex_unlock(&dev->struct_mutex);
 		DRM_ERROR("failed to update base address\n");
 		return ret;
@@ -2406,7 +2440,7 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
 	if (old_fb) {
 		if (intel_crtc->active && old_fb != fb)
 			intel_wait_for_vblank(dev, intel_crtc->pipe);
-		intel_unpin_fb_obj(to_intel_framebuffer(old_fb)->obj);
+		intel_unpin_fenced_fb_obj(to_intel_framebuffer(old_fb)->obj);
 	}
 
 	intel_update_fbc(dev);
@@ -4364,7 +4398,7 @@ static void intel_crtc_disable(struct drm_crtc *crtc)
 
 	if (crtc->fb) {
 		mutex_lock(&dev->struct_mutex);
-		intel_unpin_fb_obj(to_intel_framebuffer(crtc->fb)->obj);
+		intel_unpin_fenced_fb_obj(to_intel_framebuffer(crtc->fb)->obj);
 		mutex_unlock(&dev->struct_mutex);
 		crtc->fb = NULL;
 	}
@@ -8277,7 +8311,7 @@ static void intel_unpin_work_fn(struct work_struct *__work)
 	struct drm_device *dev = work->crtc->dev;
 
 	mutex_lock(&dev->struct_mutex);
-	intel_unpin_fb_obj(work->old_fb_obj);
+	intel_unpin_fenced_fb_obj(work->old_fb_obj);
 	drm_gem_object_unreference(&work->pending_flip_obj->base);
 	drm_gem_object_unreference(&work->old_fb_obj->base);
 
@@ -8386,7 +8420,7 @@ static int intel_gen2_queue_flip(struct drm_device *dev,
 	struct intel_ring_buffer *ring = &dev_priv->ring[RCS];
 	int ret;
 
-	ret = intel_pin_and_fence_fb_obj(dev, obj, ring);
+	ret = intel_pin_fenced_fb_obj(dev, obj, ring);
 	if (ret)
 		goto err;
 
@@ -8414,7 +8448,7 @@ static int intel_gen2_queue_flip(struct drm_device *dev,
 	return 0;
 
 err_unpin:
-	intel_unpin_fb_obj(obj);
+	intel_unpin_fenced_fb_obj(obj);
 err:
 	return ret;
 }
@@ -8431,7 +8465,7 @@ static int intel_gen3_queue_flip(struct drm_device *dev,
 	struct intel_ring_buffer *ring = &dev_priv->ring[RCS];
 	int ret;
 
-	ret = intel_pin_and_fence_fb_obj(dev, obj, ring);
+	ret = intel_pin_fenced_fb_obj(dev, obj, ring);
 	if (ret)
 		goto err;
 
@@ -8456,7 +8490,7 @@ static int intel_gen3_queue_flip(struct drm_device *dev,
 	return 0;
 
 err_unpin:
-	intel_unpin_fb_obj(obj);
+	intel_unpin_fenced_fb_obj(obj);
 err:
 	return ret;
 }
@@ -8473,7 +8507,7 @@ static int intel_gen4_queue_flip(struct drm_device *dev,
 	struct intel_ring_buffer *ring = &dev_priv->ring[RCS];
 	int ret;
 
-	ret = intel_pin_and_fence_fb_obj(dev, obj, ring);
+	ret = intel_pin_fenced_fb_obj(dev, obj, ring);
 	if (ret)
 		goto err;
 
@@ -8505,7 +8539,7 @@ static int intel_gen4_queue_flip(struct drm_device *dev,
 	return 0;
 
 err_unpin:
-	intel_unpin_fb_obj(obj);
+	intel_unpin_fenced_fb_obj(obj);
 err:
 	return ret;
 }
@@ -8522,7 +8556,7 @@ static int intel_gen6_queue_flip(struct drm_device *dev,
 	uint32_t pf, pipesrc;
 	int ret;
 
-	ret = intel_pin_and_fence_fb_obj(dev, obj, ring);
+	ret = intel_pin_fenced_fb_obj(dev, obj, ring);
 	if (ret)
 		goto err;
 
@@ -8550,7 +8584,7 @@ static int intel_gen6_queue_flip(struct drm_device *dev,
 	return 0;
 
 err_unpin:
-	intel_unpin_fb_obj(obj);
+	intel_unpin_fenced_fb_obj(obj);
 err:
 	return ret;
 }
@@ -8571,7 +8605,7 @@ static int intel_gen7_queue_flip(struct drm_device *dev,
 	if (IS_VALLEYVIEW(dev) || ring == NULL || ring->id != RCS)
 		ring = &dev_priv->ring[BCS];
 
-	ret = intel_pin_and_fence_fb_obj(dev, obj, ring);
+	ret = intel_pin_fenced_fb_obj(dev, obj, ring);
 	if (ret)
 		goto err;
 
@@ -8630,7 +8664,7 @@ static int intel_gen7_queue_flip(struct drm_device *dev,
 	return 0;
 
 err_unpin:
-	intel_unpin_fb_obj(obj);
+	intel_unpin_fenced_fb_obj(obj);
 err:
 	return ret;
 }
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 44067bc..913fdeb 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -677,9 +677,13 @@ bool intel_get_load_detect_pipe(struct drm_connector *connector,
 				struct intel_load_detect_pipe *old);
 void intel_release_load_detect_pipe(struct drm_connector *connector,
 				    struct intel_load_detect_pipe *old);
-int intel_pin_and_fence_fb_obj(struct drm_device *dev,
-			       struct drm_i915_gem_object *obj,
-			       struct intel_ring_buffer *pipelined);
+int intel_pin_fenced_fb_obj(struct drm_device *dev,
+			    struct drm_i915_gem_object *obj,
+			    struct intel_ring_buffer *pipelined);
+void intel_unpin_fenced_fb_obj(struct drm_i915_gem_object *obj);
+int intel_pin_fb_obj(struct drm_device *dev,
+		     struct drm_i915_gem_object *obj,
+		     struct intel_ring_buffer *pipelined);
 void intel_unpin_fb_obj(struct drm_i915_gem_object *obj);
 int intel_framebuffer_init(struct drm_device *dev,
 			   struct intel_framebuffer *ifb,
diff --git a/drivers/gpu/drm/i915/intel_fbdev.c b/drivers/gpu/drm/i915/intel_fbdev.c
index d6a8a71..ea5ca6b 100644
--- a/drivers/gpu/drm/i915/intel_fbdev.c
+++ b/drivers/gpu/drm/i915/intel_fbdev.c
@@ -91,7 +91,7 @@ static int intelfb_alloc(struct drm_fb_helper *helper,
 	}
 
 	/* Flush everything out, we'll be doing GTT only from now on */
-	ret = intel_pin_and_fence_fb_obj(dev, obj, NULL);
+	ret = intel_pin_fenced_fb_obj(dev, obj, NULL);
 	if (ret) {
 		DRM_ERROR("failed to pin fb: %d\n", ret);
 		goto out_unref;
diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
index 336ae6c..ae316c9 100644
--- a/drivers/gpu/drm/i915/intel_sprite.c
+++ b/drivers/gpu/drm/i915/intel_sprite.c
@@ -852,7 +852,7 @@ intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
 	 * primary plane requires 256KiB alignment with 64 PTE padding,
 	 * the sprite planes only require 128KiB alignment and 32 PTE padding.
 	 */
-	ret = intel_pin_and_fence_fb_obj(dev, obj, NULL);
+	ret = intel_pin_fb_obj(dev, obj, NULL);
 
 	mutex_unlock(&dev->struct_mutex);
 
-- 
1.8.3.2




More information about the Intel-gfx mailing list