From: Ville Syrjälä <ville.syrj...@linux.intel.com>

Starting from ~KBL planes can do NV12. Let's make use that
capability in the sprite Xv adaptor.

Signed-off-by: Ville Syrjälä <ville.syrj...@linux.intel.com>
---
 src/sna/sna_video_sprite.c | 57 +++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 49 insertions(+), 8 deletions(-)

diff --git a/src/sna/sna_video_sprite.c b/src/sna/sna_video_sprite.c
index a4f3205b6fc9..f6d6f0b45b6c 100644
--- a/src/sna/sna_video_sprite.c
+++ b/src/sna/sna_video_sprite.c
@@ -46,6 +46,7 @@
 #define DRM_FORMAT_XRGB8888     fourcc_code('X', 'R', '2', '4') /* [31:0] 
x:R:G:B 8:8:8:8 little endian */
 #define DRM_FORMAT_YUYV         fourcc_code('Y', 'U', 'Y', 'V') /* [31:0] 
Cr0:Y1:Cb0:Y0 8:8:8:8 little endian */
 #define DRM_FORMAT_UYVY         fourcc_code('U', 'Y', 'V', 'Y') /* [31:0] 
Y1:Cr0:Y0:Cb0 8:8:8:8 little endian */
+#define DRM_FORMAT_NV12         fourcc_code('N', 'V', '1', '2') /* 2x2 
subsampled Cr:Cb plane */
 
 #define has_hw_scaling(sna, video) ((sna)->kgem.gen < 071 || \
                                    ((sna)->kgem.gen >= 0110 && 
(video)->AlwaysOnTop))
@@ -72,7 +73,12 @@ struct local_mode_set_plane {
 static Atom xvColorKey, xvAlwaysOnTop, xvSyncToVblank, xvColorspace;
 
 static XvFormatRec formats[] = { {15}, {16}, {24} };
-static const XvImageRec images[] = { XVIMAGE_YUY2, XVIMAGE_UYVY, XVMC_RGB888, 
XVMC_RGB565 };
+static const XvImageRec images[] = { XVIMAGE_YUY2, XVIMAGE_UYVY,
+                                    XVMC_RGB888 };
+static const XvImageRec images_rgb565[] = { XVIMAGE_YUY2, XVIMAGE_UYVY,
+                                           XVMC_RGB888, XVMC_RGB565 };
+static const XvImageRec images_nv12[] = { XVIMAGE_YUY2, XVIMAGE_UYVY,
+                                         XVIMAGE_NV12, XVMC_RGB888, 
XVMC_RGB565 };
 static const XvAttributeRec attribs[] = {
        { XvSettable | XvGettable, 0, 1, (char *)"XV_COLORSPACE" }, /* BT.601, 
BT.709 */
        { XvSettable | XvGettable, 0, 0xffffff, (char *)"XV_COLORKEY" },
@@ -307,8 +313,6 @@ sna_video_sprite_show(struct sna *sna,
                f.width = frame->width;
                f.height = frame->height;
                f.flags = 1 << 1; /* +modifiers */
-               f.handles[0] = frame->bo->handle;
-               f.pitches[0] = frame->pitch[0];
 
                switch (frame->bo->tiling) {
                case I915_TILING_NONE:
@@ -323,6 +327,18 @@ sna_video_sprite_show(struct sna *sna,
                        break;
                }
 
+               if (is_nv12_fourcc(frame->id)) {
+                       f.handles[0] = frame->bo->handle;
+                       f.handles[1] = frame->bo->handle;
+                       f.pitches[0] = frame->pitch[1];
+                       f.pitches[1] = frame->pitch[0];
+                       f.offsets[0] = 0;
+                       f.offsets[1] = frame->UBufOffset;
+               } else {
+                       f.handles[0] = frame->bo->handle;
+                       f.pitches[0] = frame->pitch[0];
+               }
+
                switch (frame->id) {
                case FOURCC_RGB565:
                        f.pixel_format = DRM_FORMAT_RGB565;
@@ -332,6 +348,9 @@ sna_video_sprite_show(struct sna *sna,
                        f.pixel_format = DRM_FORMAT_XRGB8888;
                        purged = sna->scrn->depth != 24;
                        break;
+               case FOURCC_NV12:
+                       f.pixel_format = DRM_FORMAT_NV12;
+                       break;
                case FOURCC_UYVY:
                        f.pixel_format = DRM_FORMAT_UYVY;
                        break;
@@ -633,7 +652,7 @@ static int 
sna_video_sprite_query(ddQueryImageAttributes_ARGS)
 {
        struct sna_video *video = port->devPriv.ptr;
        struct sna_video_frame frame;
-       int size;
+       int size, tmp;
 
        if (*w > video->sna->mode.max_crtc_width)
                *w = video->sna->mode.max_crtc_width;
@@ -654,6 +673,21 @@ static int 
sna_video_sprite_query(ddQueryImageAttributes_ARGS)
                size = 4;
                break;
 
+       case FOURCC_NV12:
+               *h = (*h + 1) & ~1;
+               size = (*w + 3) & ~3;
+               if (pitches)
+                       pitches[0] = size;
+               size *= *h;
+               if (offsets)
+                       offsets[1] = size;
+               tmp = (*w + 3) & ~3;
+               if (pitches)
+                       pitches[1] = tmp;
+               tmp *= (*h >> 1);
+               size += tmp;
+               break;
+
        default:
                *w = (*w + 1) & ~1;
                *h = (*h + 1) & ~1;
@@ -752,10 +786,17 @@ void sna_video_sprite_setup(struct sna *sna, ScreenPtr 
screen)
                                                 ARRAY_SIZE(formats));
        adaptor->nAttributes = ARRAY_SIZE(attribs);
        adaptor->pAttributes = (XvAttributeRec *)attribs;
-       adaptor->pImages = (XvImageRec *)images;
-       adaptor->nImages = 3;
-       if (sna_has_sprite_format(sna, DRM_FORMAT_RGB565))
-               adaptor->nImages = 4;
+
+       if (sna_has_sprite_format(sna, DRM_FORMAT_NV12)) {
+               adaptor->pImages = (XvImageRec *)images_nv12;
+               adaptor->nImages = ARRAY_SIZE(images_nv12);
+       } else if (sna_has_sprite_format(sna, DRM_FORMAT_RGB565)) {
+               adaptor->pImages = (XvImageRec *)images_rgb565;
+               adaptor->nImages = ARRAY_SIZE(images_rgb565);
+       } else {
+               adaptor->pImages = (XvImageRec *)images;
+               adaptor->nImages = ARRAY_SIZE(images);
+       }
 
 #if XORG_XV_VERSION < 2
        adaptor->ddAllocatePort = sna_xv_alloc_port;
-- 
2.16.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

Reply via email to