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

Signed-off-by: Jesse Barnes <jbar...@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

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

Reply via email to