From mboxrd@z Thu Jan 1 00:00:00 1970 From: Jesse Barnes Subject: [PATCH] drm/i915: add color key support v4 Date: Tue, 13 Dec 2011 14:09:11 -0800 Message-ID: <20111213140911.2cba6c96@jbarnes-desktop> References: <1323811180-17581-1-git-send-email-jbarnes@virtuousgeek.org> <1323811180-17581-3-git-send-email-jbarnes@virtuousgeek.org> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="===============1168056769==" Return-path: Received: from oproxy7-pub.bluehost.com (oproxy7-pub.bluehost.com [67.222.55.9]) by gabe.freedesktop.org (Postfix) with SMTP id C7914A08D0 for ; Tue, 13 Dec 2011 14:09:13 -0800 (PST) Received: from c-67-161-37-189.hsd1.ca.comcast.net ([67.161.37.189] helo=jbarnes-desktop) by box514.bluehost.com with esmtpsa (TLSv1:AES128-SHA:128) (Exim 4.76) (envelope-from ) id 1RaaXB-0002Kt-34 for intel-gfx@lists.freedesktop.org; Tue, 13 Dec 2011 15:09:13 -0700 In-Reply-To: <1323811180-17581-3-git-send-email-jbarnes@virtuousgeek.org> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: intel-gfx-bounces+gcfxdi-intel-gfx=m.gmane.org@lists.freedesktop.org Errors-To: intel-gfx-bounces+gcfxdi-intel-gfx=m.gmane.org@lists.freedesktop.org To: intel-gfx@lists.freedesktop.org List-Id: intel-gfx@lists.freedesktop.org --===============1168056769== Content-Type: multipart/signed; micalg=PGP-SHA1; boundary="Sig_/4EDNg.WXf8zJt1RqbojJU8R"; protocol="application/pgp-signature" --Sig_/4EDNg.WXf8zJt1RqbojJU8R Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: quoted-printable Add new ioctls for getting and setting the current destination color key. This allows for simple overlay display control by matching a color key value in the primary plane before blending the overlay on top. v2: remove unnecessary mutex acquire/release around reg accesses v3: add support for full color key management v4: fix copy & paste bug in snb_get_colorkey don't bother checking min/max values against docs as the docs are likely wrong (how could we handle 10bpc surface formats?) Reviewed-by: Daniel Vetter Signed-off-by: Jesse Barnes --- drivers/gpu/drm/i915/i915_dma.c | 2 + drivers/gpu/drm/i915/i915_reg.h | 3 + drivers/gpu/drm/i915/intel_drv.h | 11 ++ drivers/gpu/drm/i915/intel_sprite.c | 177 +++++++++++++++++++++++++++++++= ++++ include/drm/i915_drm.h | 36 +++++++ 5 files changed, 229 insertions(+), 0 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dm= a.c index a9533c5..12615eb 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -2295,6 +2295,8 @@ struct drm_ioctl_desc i915_ioctls[] =3D { DRM_IOCTL_DEF_DRV(I915_GEM_MADVISE, i915_gem_madvise_ioctl, DRM_UNLOCKED), DRM_IOCTL_DEF_DRV(I915_OVERLAY_PUT_IMAGE, intel_overlay_put_image, DRM_MA= STER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), DRM_IOCTL_DEF_DRV(I915_OVERLAY_ATTRS, intel_overlay_attrs, DRM_MASTER|DRM= _CONTROL_ALLOW|DRM_UNLOCKED), + DRM_IOCTL_DEF_DRV(I915_SET_SPRITE_COLORKEY, intel_sprite_set_colorkey, DR= M_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), + DRM_IOCTL_DEF_DRV(I915_GET_SPRITE_COLORKEY, intel_sprite_get_colorkey, DR= M_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), }; =20 int i915_max_ioctl =3D DRM_ARRAY_SIZE(i915_ioctls); diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_re= g.h index f872ba2..25ec240 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -2726,9 +2726,12 @@ #define DVSSTRIDE(pipe) _PIPE(pipe, _DVSASTRIDE, _DVSBSTRIDE) #define DVSPOS(pipe) _PIPE(pipe, _DVSAPOS, _DVSBPOS) #define DVSSURF(pipe) _PIPE(pipe, _DVSASURF, _DVSBSURF) +#define DVSKEYMAX(pipe) _PIPE(pipe, _DVSAKEYMAXVAL, _DVSBKEYMAXVAL) #define DVSSIZE(pipe) _PIPE(pipe, _DVSASIZE, _DVSBSIZE) #define DVSSCALE(pipe) _PIPE(pipe, _DVSASCALE, _DVSBSCALE) #define DVSTILEOFF(pipe) _PIPE(pipe, _DVSATILEOFF, _DVSBTILEOFF) +#define DVSKEYVAL(pipe) _PIPE(pipe, _DVSAKEYVAL, _DVSBKEYVAL) +#define DVSKEYMSK(pipe) _PIPE(pipe, _DVSAKEYMSK, _DVSBKEYMSK) =20 #define _SPRA_CTL 0x70280 #define SPRITE_ENABLE (1<<31) diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_= drv.h index 97bbbc5..fd1a2cc 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -26,6 +26,7 @@ #define __INTEL_DRV_H__ =20 #include +#include "i915_drm.h" #include "i915_drv.h" #include "drm_crtc.h" #include "drm_crtc_helper.h" @@ -191,6 +192,10 @@ struct intel_plane { uint32_t x, uint32_t y, uint32_t src_w, uint32_t src_h); void (*disable_plane)(struct drm_plane *plane); + int (*update_colorkey)(struct drm_plane *plane, + struct drm_intel_sprite_colorkey *key); + void (*get_colorkey)(struct drm_plane *plane, + struct drm_intel_sprite_colorkey *key); }; =20 #define to_intel_crtc(x) container_of(x, struct intel_crtc, base) @@ -413,4 +418,10 @@ extern void sandybridge_update_wm(struct drm_device *d= ev); extern void intel_update_sprite_watermarks(struct drm_device *dev, int pip= e, uint32_t sprite_width, int pixel_size); + +extern int intel_sprite_set_colorkey(struct drm_device *dev, void *data, + struct drm_file *file_priv); +extern int intel_sprite_get_colorkey(struct drm_device *dev, void *data, + struct drm_file *file_priv); + #endif /* __INTEL_DRV_H__ */ diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/int= el_sprite.c index 735c8ab..2273173 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c @@ -95,6 +95,7 @@ ivb_update_plane(struct drm_plane *plane, struct drm_fram= ebuffer *fb, /* must disable */ sprctl |=3D SPRITE_TRICKLE_FEED_DISABLE; sprctl |=3D SPRITE_ENABLE; + sprctl |=3D SPRITE_DEST_KEY; =20 /* Sizes are 0 based */ src_w--; @@ -153,6 +154,60 @@ ivb_disable_plane(struct drm_plane *plane) POSTING_READ(SPRSURF(pipe)); } =20 +static int +ivb_update_colorkey(struct drm_plane *plane, + struct drm_intel_sprite_colorkey *key) +{ + struct drm_device *dev =3D plane->dev; + struct drm_i915_private *dev_priv =3D dev->dev_private; + struct intel_plane *intel_plane; + u32 sprctl; + int ret =3D 0; + + intel_plane =3D to_intel_plane(plane); + + I915_WRITE(SPRKEYVAL(intel_plane->pipe), key->min_value); + I915_WRITE(SPRKEYMAX(intel_plane->pipe), key->max_value); + I915_WRITE(SPRKEYMSK(intel_plane->pipe), key->channel_mask); + + sprctl =3D I915_READ(SPRCTL(intel_plane->pipe)); + sprctl &=3D ~(SPRITE_SOURCE_KEY | SPRITE_DEST_KEY); + if (key->flags & I915_SET_COLORKEY_DESTINATION) + sprctl |=3D SPRITE_DEST_KEY; + else if (key->flags & I915_SET_COLORKEY_SOURCE) + sprctl |=3D SPRITE_SOURCE_KEY; + I915_WRITE(SPRCTL(intel_plane->pipe), sprctl); + + POSTING_READ(SPRKEYMSK(intel_plane->pipe)); + + return ret; +} + +static void +ivb_get_colorkey(struct drm_plane *plane, struct drm_intel_sprite_colorkey= *key) +{ + struct drm_device *dev =3D plane->dev; + struct drm_i915_private *dev_priv =3D dev->dev_private; + struct intel_plane *intel_plane; + u32 sprctl; + + intel_plane =3D to_intel_plane(plane); + + key->min_value =3D I915_READ(SPRKEYVAL(intel_plane->pipe)); + key->max_value =3D I915_READ(SPRKEYMAX(intel_plane->pipe)); + key->channel_mask =3D I915_READ(SPRKEYMSK(intel_plane->pipe)); + key->flags =3D 0; + + sprctl =3D I915_READ(SPRCTL(intel_plane->pipe)); + + if (sprctl & SPRITE_DEST_KEY) + key->flags =3D I915_SET_COLORKEY_DESTINATION; + else if (sprctl & SPRITE_SOURCE_KEY) + key->flags =3D I915_SET_COLORKEY_SOURCE; + else + key->flags =3D I915_SET_COLORKEY_NONE; +} + static void snb_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb, struct drm_i915_gem_object *obj, int crtc_x, int crtc_y, @@ -279,6 +334,60 @@ intel_disable_primary(struct drm_crtc *crtc) } =20 static int +snb_update_colorkey(struct drm_plane *plane, + struct drm_intel_sprite_colorkey *key) +{ + struct drm_device *dev =3D plane->dev; + struct drm_i915_private *dev_priv =3D dev->dev_private; + struct intel_plane *intel_plane; + u32 dvscntr; + int ret =3D 0; + + intel_plane =3D to_intel_plane(plane); + + I915_WRITE(DVSKEYVAL(intel_plane->pipe), key->min_value); + I915_WRITE(DVSKEYMAX(intel_plane->pipe), key->max_value); + I915_WRITE(DVSKEYMSK(intel_plane->pipe), key->channel_mask); + + dvscntr =3D I915_READ(DVSCNTR(intel_plane->pipe)); + dvscntr &=3D ~(DVS_SOURCE_KEY | DVS_DEST_KEY); + if (key->flags & I915_SET_COLORKEY_DESTINATION) + dvscntr |=3D DVS_DEST_KEY; + else if (key->flags & I915_SET_COLORKEY_SOURCE) + dvscntr |=3D DVS_SOURCE_KEY; + I915_WRITE(DVSCNTR(intel_plane->pipe), dvscntr); + + POSTING_READ(DVSKEYMSK(intel_plane->pipe)); + + return ret; +} + +static void +snb_get_colorkey(struct drm_plane *plane, struct drm_intel_sprite_colorkey= *key) +{ + struct drm_device *dev =3D plane->dev; + struct drm_i915_private *dev_priv =3D dev->dev_private; + struct intel_plane *intel_plane; + u32 dvscntr; + + intel_plane =3D to_intel_plane(plane); + + key->min_value =3D I915_READ(DVSKEYVAL(intel_plane->pipe)); + key->max_value =3D I915_READ(DVSKEYMAX(intel_plane->pipe)); + key->channel_mask =3D I915_READ(DVSKEYMSK(intel_plane->pipe)); + key->flags =3D 0; + + dvscntr =3D I915_READ(DVSCNTR(intel_plane->pipe)); + + if (dvscntr & DVS_DEST_KEY) + key->flags =3D I915_SET_COLORKEY_DESTINATION; + else if (dvscntr & DVS_SOURCE_KEY) + key->flags =3D I915_SET_COLORKEY_SOURCE; + else + key->flags =3D I915_SET_COLORKEY_NONE; +} + +static int intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, struct drm_framebuffer *fb, int crtc_x, int crtc_y, unsigned int crtc_w, unsigned int crtc_h, @@ -437,6 +546,70 @@ static void intel_destroy_plane(struct drm_plane *plan= e) kfree(intel_plane); } =20 +int intel_sprite_set_colorkey(struct drm_device *dev, void *data, + struct drm_file *file_priv) +{ + struct drm_intel_sprite_colorkey *set =3D data; + struct drm_i915_private *dev_priv =3D dev->dev_private; + struct drm_mode_object *obj; + struct drm_plane *plane; + struct intel_plane *intel_plane; + int ret =3D 0; + + if (!dev_priv) + return -EINVAL; + + /* Make sure we don't try to enable both src & dest simultaneously */ + if ((set->flags & (I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOUR= CE)) =3D=3D (I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE)) + return -EINVAL; + + mutex_lock(&dev->mode_config.mutex); + + obj =3D drm_mode_object_find(dev, set->plane_id, DRM_MODE_OBJECT_PLANE); + if (!obj) { + ret =3D -EINVAL; + goto out_unlock; + } + + plane =3D obj_to_plane(obj); + intel_plane =3D to_intel_plane(plane); + ret =3D intel_plane->update_colorkey(plane, set); + +out_unlock: + mutex_unlock(&dev->mode_config.mutex); + return ret; +} + +int intel_sprite_get_colorkey(struct drm_device *dev, void *data, + struct drm_file *file_priv) +{ + struct drm_intel_sprite_colorkey *get =3D data; + struct drm_i915_private *dev_priv =3D dev->dev_private; + struct drm_mode_object *obj; + struct drm_plane *plane; + struct intel_plane *intel_plane; + int ret =3D 0; + + if (!dev_priv) + return -EINVAL; + + mutex_lock(&dev->mode_config.mutex); + + obj =3D drm_mode_object_find(dev, get->plane_id, DRM_MODE_OBJECT_PLANE); + if (!obj) { + ret =3D -EINVAL; + goto out_unlock; + } + + plane =3D obj_to_plane(obj); + intel_plane =3D to_intel_plane(plane); + intel_plane->get_colorkey(plane, get); + +out_unlock: + mutex_unlock(&dev->mode_config.mutex); + return ret; +} + static const struct drm_plane_funcs intel_plane_funcs =3D { .update_plane =3D intel_update_plane, .disable_plane =3D intel_disable_plane, @@ -472,10 +645,14 @@ intel_plane_init(struct drm_device *dev, enum pipe pi= pe) intel_plane->max_downscale =3D 16; intel_plane->update_plane =3D snb_update_plane; intel_plane->disable_plane =3D snb_disable_plane; + intel_plane->update_colorkey =3D snb_update_colorkey; + intel_plane->get_colorkey =3D snb_get_colorkey; } else if (IS_GEN7(dev)) { intel_plane->max_downscale =3D 2; intel_plane->update_plane =3D ivb_update_plane; intel_plane->disable_plane =3D ivb_disable_plane; + intel_plane->update_colorkey =3D ivb_update_colorkey; + intel_plane->get_colorkey =3D ivb_get_colorkey; } =20 intel_plane->pipe =3D pipe; diff --git a/include/drm/i915_drm.h b/include/drm/i915_drm.h index 28c0d11..1b4da1a 100644 --- a/include/drm/i915_drm.h +++ b/include/drm/i915_drm.h @@ -198,6 +198,8 @@ typedef struct _drm_i915_sarea { #define DRM_I915_OVERLAY_PUT_IMAGE 0x27 #define DRM_I915_OVERLAY_ATTRS 0x28 #define DRM_I915_GEM_EXECBUFFER2 0x29 +#define DRM_I915_GET_SPRITE_COLORKEY 0x2a +#define DRM_I915_SET_SPRITE_COLORKEY 0x2b =20 #define DRM_IOCTL_I915_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT, dr= m_i915_init_t) #define DRM_IOCTL_I915_FLUSH DRM_IO ( DRM_COMMAND_BASE + DRM_I915_FLUSH) @@ -239,6 +241,8 @@ typedef struct _drm_i915_sarea { #define DRM_IOCTL_I915_GEM_MADVISE DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GE= M_MADVISE, struct drm_i915_gem_madvise) #define DRM_IOCTL_I915_OVERLAY_PUT_IMAGE DRM_IOW(DRM_COMMAND_BASE + DRM_I9= 15_OVERLAY_PUT_IMAGE, struct drm_intel_overlay_put_image) #define DRM_IOCTL_I915_OVERLAY_ATTRS DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_= OVERLAY_ATTRS, struct drm_intel_overlay_attrs) +#define DRM_IOCTL_I915_SET_SPRITE_COLORKEY DRM_IOWR(DRM_COMMAND_BASE + DRM= _I915_SET_SPRITE_COLORKEY, struct drm_intel_sprite_colorkey) +#define DRM_IOCTL_I915_GET_SPRITE_COLORKEY DRM_IOWR(DRM_COMMAND_BASE + DRM= _I915_SET_SPRITE_COLORKEY, struct drm_intel_sprite_colorkey) =20 /* Allow drivers to submit batchbuffers directly to hardware, relying * on the security mechanisms provided by hardware. @@ -844,4 +848,36 @@ struct drm_intel_overlay_attrs { __u32 gamma5; }; =20 +/* + * Intel sprite handling + * + * Color keying works with a min/mask/max tuple. Both source and destinat= ion + * color keying is allowed. + * + * Source keying: + * Sprite pixels within the min & max values, masked against the color cha= nnels + * specified in the mask field, will be transparent. All other pixels will + * be displayed on top of the primary plane. For RGB surfaces, only the m= in + * and mask fields will be used; ranged compares are not allowed. + * + * Destination keying: + * Primary plane pixels that match the min value, masked against the color + * channels specified in the mask field, will be replaced by corresponding + * pixels from the sprite plane. + * + * Note that source & destination keying are exclusive; only one can be + * active on a given plane. + */ + +#define I915_SET_COLORKEY_NONE (1<<0) /* disable color key matching */ +#define I915_SET_COLORKEY_DESTINATION (1<<1) +#define I915_SET_COLORKEY_SOURCE (1<<2) +struct drm_intel_sprite_colorkey { + __u32 plane_id; + __u32 min_value; + __u32 channel_mask; + __u32 max_value; + __u32 flags; +}; + #endif /* _I915_DRM_H_ */ --=20 1.7.4.1 --Sig_/4EDNg.WXf8zJt1RqbojJU8R Content-Type: application/pgp-signature; name=signature.asc Content-Disposition: attachment; filename=signature.asc -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.10 (GNU/Linux) iQIcBAEBAgAGBQJO580HAAoJEIEoDkX4Qk9h/rAQALoV2pXraBMy0J2BTP10+b9X KnHAtzlt9bsL75/Xvy4jC0r1M4mg5wqNvwPeT+7o3ozBwyL83hRK8yuLf13IqJVa azjoXXhZFnO/mQZ5NoRxddugyA1UEfFZa+K4oaYnPQ95XPFbJkKGu9Akbw0PdTfP iOOxznDsQFzCEAQQytkxW3KfcrYokWIpzQdWMq7tn3NX04VZrH7K6weL08q0FFzy UfZ/YhupIrIim93iHkBz9TWG+QQpTB0Cn6EiWA+b1pju0u0LzTw+QsxkGm2sqvM2 AcoBYTNKTd1okjXYuWqeaoEc38NIHjnjPhgjly2TbHcqSPQvCxgdWeG+28UrAn40 AdNuAjnjXlA7E+z/7r/x5wmmz7xm7NjmDV+I4LlixeUd71KqmM1qUB2PVTgWBbUy UkBcW8wPd18pLjkeUC2c9AzJhE2ma3yQAXGid8d4RimiL9/PojvAhUOa55b2Q59i XjD/0g+1Nq7zAnK0hc7GOxan8qh5EjLdHYUpSoKvWhV/qpoGB1xu6XX0u2Y/G16T f1RVdWiArmeDFHYggxazdRRwMAYHsBNJkakgh66KxJMxUM+xTuTGSypBEcqlqj7e svr+ZBPcl5HfTCV+fT8qSt0HVHJWSzF0RKxJiJI5aM+w8yITFdZgkOz5dzmrkNh6 2q6T1vPnd5dAf+n9B9dq =nB7W -----END PGP SIGNATURE----- --Sig_/4EDNg.WXf8zJt1RqbojJU8R-- --===============1168056769== Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline _______________________________________________ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx --===============1168056769==--