[PATCH 11/11] drm/i915: add sprite scaling support

Jesse Barnes jbarnes at virtuousgeek.org
Tue Oct 25 02:47:06 PDT 2011


If the source and destination size are different, try to scale the sprite on the
corresponding CRTC.

Signed-off-by: Jesse Barnes <jbarnes at virtuousgeek.org>
---
 drivers/gpu/drm/i915/i915_reg.h       |    5 +++++
 drivers/gpu/drm/i915/intel_overlay2.c |   14 ++++++++++++--
 2 files changed, 17 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 71496b8..8cbda0b 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -2695,6 +2695,11 @@
 #define _DVSATILEOFF		0x721a4
 #define _DVSASURFLIVE		0x721ac
 #define _DVSASCALE		0x72204
+#define   DVS_SCALE_ENABLE	(1<<31)
+#define   DVS_FILTER_MASK	(3<<29)
+#define   DVS_FILTER_MEDIUM	(0<<29)
+#define   DVS_FILTER_ENHANCING	(1<<29)
+#define   DVS_FILTER_SOFTENING	(2<<29)
 #define _DVSAGAMC		0x72300
 
 #define _DVSBCNTR		0x73180
diff --git a/drivers/gpu/drm/i915/intel_overlay2.c b/drivers/gpu/drm/i915/intel_overlay2.c
index 90c4f59..61594b6 100644
--- a/drivers/gpu/drm/i915/intel_overlay2.c
+++ b/drivers/gpu/drm/i915/intel_overlay2.c
@@ -169,7 +169,7 @@ snb_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
 	struct drm_i915_gem_object *obj, *old_obj;
 	int pipe = intel_plane->pipe;
 	unsigned long start, offset;
-	u32 dvscntr;
+	u32 dvscntr, dvsscale = 0;
 	u32 reg = DVSCNTR(pipe);
 	int ret = 0;
 	int x = src_x >> 16, y = src_y >> 16;
@@ -185,6 +185,13 @@ snb_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
 	if (crtc_x >= active_w || crtc_y >= active_h)
 		return -EINVAL;
 
+	/*
+	 * We can take a larger source and scale it down, but
+	 * only so much...  16x is the max on SNB.
+	 */
+	if (((src_w * src_h) / (crtc_w * crtc_h)) > 16)
+		return -EINVAL;
+
 	/* Clamp the width & height into the visible area */
 	if (crtc_x + crtc_w > active_w)
 		crtc_w = active_w - crtc_x - 1;
@@ -249,11 +256,14 @@ snb_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
 	start = obj->gtt_offset;
 	offset = y * fb->pitch + x * (fb->bits_per_pixel / 8);
 
+	if (crtc_w != src_w || crtc_h != src_h)
+		dvsscale = DVS_SCALE_ENABLE | (src_h << 16) | src_w;
+
 	I915_WRITE(DVSSTRIDE(pipe), fb->pitch);
 	I915_WRITE(DVSPOS(pipe), (crtc_y << 16) | crtc_x);
 	I915_WRITE(DVSTILEOFF(pipe), (y << 16) | x);
 	I915_WRITE(DVSSIZE(pipe), (crtc_h << 16) | crtc_w);
-	I915_WRITE(DVSSCALE(pipe), 0);
+	I915_WRITE(DVSSCALE(pipe), dvsscale);
 	I915_WRITE(reg, dvscntr);
 	I915_WRITE(DVSSURF(pipe), start);
 	POSTING_READ(DVSSURF(pipe));
-- 
1.7.4.1



More information about the dri-devel mailing list