summaryrefslogtreecommitdiff
path: root/src/sna
diff options
context:
space:
mode:
Diffstat (limited to 'src/sna')
-rw-r--r--src/sna/gen9_render.c23
-rw-r--r--src/sna/sna_render.h3
-rw-r--r--src/sna/sna_video.c72
-rw-r--r--src/sna/sna_video.h19
-rw-r--r--src/sna/sna_video_sprite.c20
-rw-r--r--src/sna/sna_video_textured.c21
6 files changed, 153 insertions, 5 deletions
diff --git a/src/sna/gen9_render.c b/src/sna/gen9_render.c
index eb22b642..3ed2eb3b 100644
--- a/src/sna/gen9_render.c
+++ b/src/sna/gen9_render.c
@@ -129,6 +129,20 @@ static const uint32_t ps_kernel_planar_bt709[][4] = {
#include "exa_wm_write.g8b"
};
+static const uint32_t ps_kernel_ayuv_bt601[][4] = {
+#include "exa_wm_src_affine.g8b"
+#include "exa_wm_src_sample_argb_ayuv.g8b"
+#include "exa_wm_yuv_rgb_bt601.g8b"
+#include "exa_wm_write.g8b"
+};
+
+static const uint32_t ps_kernel_ayuv_bt709[][4] = {
+#include "exa_wm_src_affine.g8b"
+#include "exa_wm_src_sample_argb_ayuv.g8b"
+#include "exa_wm_yuv_rgb_bt709.g8b"
+#include "exa_wm_write.g8b"
+};
+
static const uint32_t ps_kernel_nv12_bt709[][4] = {
#include "exa_wm_src_affine.g8b"
#include "exa_wm_src_sample_nv12.g8b"
@@ -177,6 +191,8 @@ static const struct wm_kernel_info {
KERNEL(VIDEO_PLANAR_BT709, ps_kernel_planar_bt709, 7),
KERNEL(VIDEO_NV12_BT709, ps_kernel_nv12_bt709, 7),
KERNEL(VIDEO_PACKED_BT709, ps_kernel_packed_bt709, 2),
+ KERNEL(VIDEO_AYUV_BT601, ps_kernel_ayuv_bt601, 2),
+ KERNEL(VIDEO_AYUV_BT709, ps_kernel_ayuv_bt709, 2),
KERNEL(VIDEO_RGB, ps_kernel_rgb, 2),
#endif
};
@@ -3853,6 +3869,8 @@ static void gen9_emit_video_state(struct sna *sna,
src_surf_format[0] = SURFACEFORMAT_B8G8R8X8_UNORM;
else if (frame->id == FOURCC_UYVY)
src_surf_format[0] = SURFACEFORMAT_YCRCB_SWAPY;
+ else if (is_ayuv_fourcc(frame->id))
+ src_surf_format[0] = SURFACEFORMAT_B8G8R8X8_UNORM;
else
src_surf_format[0] = SURFACEFORMAT_YCRCB_NORMAL;
@@ -3903,6 +3921,11 @@ static unsigned select_video_kernel(const struct sna_video *video,
case FOURCC_RGB565:
return GEN9_WM_KERNEL_VIDEO_RGB;
+ case FOURCC_AYUV:
+ return video->colorspace ?
+ GEN9_WM_KERNEL_VIDEO_AYUV_BT709 :
+ GEN9_WM_KERNEL_VIDEO_AYUV_BT601;
+
default:
return video->colorspace ?
GEN9_WM_KERNEL_VIDEO_PACKED_BT709 :
diff --git a/src/sna/sna_render.h b/src/sna/sna_render.h
index a4e5b56a..891fc905 100644
--- a/src/sna/sna_render.h
+++ b/src/sna/sna_render.h
@@ -617,6 +617,9 @@ enum {
GEN9_WM_KERNEL_VIDEO_NV12_BT709,
GEN9_WM_KERNEL_VIDEO_PACKED_BT709,
+ GEN9_WM_KERNEL_VIDEO_AYUV_BT601,
+ GEN9_WM_KERNEL_VIDEO_AYUV_BT709,
+
GEN9_WM_KERNEL_VIDEO_RGB,
GEN9_WM_KERNEL_COUNT
};
diff --git a/src/sna/sna_video.c b/src/sna/sna_video.c
index 55405f81..cf284975 100644
--- a/src/sna/sna_video.c
+++ b/src/sna/sna_video.c
@@ -59,6 +59,7 @@
#include "intel_options.h"
#include <xf86xv.h>
+#include <byteswap.h>
#ifdef SNA_XVMC
#define _SNA_XVMC_SERVER_
@@ -281,6 +282,7 @@ sna_video_frame_set_rotation(struct sna_video *video,
} else {
switch (frame->id) {
case FOURCC_RGB888:
+ case FOURCC_AYUV:
if (rotation & (RR_Rotate_90 | RR_Rotate_270)) {
frame->pitch[0] = ALIGN((height << 2), align);
frame->size = (int)frame->pitch[0] * width;
@@ -584,6 +586,72 @@ sna_copy_packed_data(struct sna_video *video,
}
}
+static void
+sna_copy_ayuv_data(struct sna_video *video,
+ const struct sna_video_frame *frame,
+ const uint8_t *buf,
+ uint8_t *dst)
+{
+ int pitch = frame->width << 2;
+ const uint32_t *src_dw;
+ const uint8_t *src;
+ uint32_t *dst_dw = (uint32_t *)dst;
+ int x, y, w, h;
+ int i, j;
+
+ if (video->textured) {
+ /* XXX support copying cropped extents */
+ x = y = 0;
+ w = frame->width;
+ h = frame->height;
+ } else {
+ x = frame->image.x1;
+ y = frame->image.y1;
+ w = frame->image.x2 - frame->image.x1;
+ h = frame->image.y2 - frame->image.y1;
+ }
+
+ src = buf + (y * pitch) + (x << 2);
+ src_dw = (uint32_t *)src;
+
+ switch (frame->rotation) {
+ case RR_Rotate_0:
+ for (i = 0; i < h; i++) {
+ for (j = 0; j < w; j++) {
+ /*
+ * Have to reverse bytes order, because the only
+ * player which supports AYUV format currently is
+ * Gstreamer and it supports in bad way, even though
+ * spec says MSB:AYUV, we get the bytes opposite way.
+ */
+ dst_dw[i * w + j] = bswap_32(src_dw[i * w + j]);
+ }
+ }
+ break;
+ case RR_Rotate_90:
+ for (i = 0; i < h; i++) {
+ for (j = 0; j < w; j++) {
+ dst_dw[(w - j - 1) * h + i] = bswap_32(src_dw[i * w + j]);
+ }
+ }
+ break;
+ case RR_Rotate_180:
+ for (i = 0; i < h; i++) {
+ for (j = 0; j < w; j++) {
+ dst_dw[(h - i - 1) * w + w - j - 1] = bswap_32(src_dw[i * w + j]);
+ }
+ }
+ break;
+ case RR_Rotate_270:
+ for (i = 0; i < h; i++) {
+ for (j = 0; j < w; j++) {
+ dst_dw[(w - j - 1) * h + i] = bswap_32(src_dw[i * w + j]);
+ }
+ }
+ break;
+ }
+}
+
bool
sna_video_copy_data(struct sna_video *video,
struct sna_video_frame *frame,
@@ -604,7 +672,7 @@ sna_video_copy_data(struct sna_video *video,
assert(frame->size);
/* In the common case, we can simply the upload in a single pwrite */
- if (frame->rotation == RR_Rotate_0 && !video->tiled) {
+ if (frame->rotation == RR_Rotate_0 && !video->tiled && !is_ayuv_fourcc(frame->id)) {
DBG(("%s: unrotated, untiled fast paths: is-planar?=%d\n",
__FUNCTION__, is_planar_fourcc(frame->id)));
if (is_nv12_fourcc(frame->id)) {
@@ -709,6 +777,8 @@ use_gtt: /* copy data, must use GTT so that we keep the overlay uncached */
sna_copy_nv12_data(video, frame, buf, dst);
else if (is_planar_fourcc(frame->id))
sna_copy_planar_data(video, frame, buf, dst);
+ else if (is_ayuv_fourcc(frame->id))
+ sna_copy_ayuv_data(video, frame, buf, dst);
else
sna_copy_packed_data(video, frame, buf, dst);
diff --git a/src/sna/sna_video.h b/src/sna/sna_video.h
index bbd3f0fd..06d43796 100644
--- a/src/sna/sna_video.h
+++ b/src/sna/sna_video.h
@@ -39,6 +39,7 @@ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define FOURCC_RGB565 ((16 << 24) + ('B' << 16) + ('G' << 8) + 'R')
#define FOURCC_RGB888 ((24 << 24) + ('B' << 16) + ('G' << 8) + 'R')
#define FOURCC_NV12 (('2' << 24) + ('1' << 16) + ('V' << 8) + 'N')
+#define FOURCC_AYUV (('V' << 24) + ('U' << 16) + ('Y' << 8) + 'A')
/*
* Below, a dummy picture type that is used in XvPutImage
@@ -79,6 +80,14 @@ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
XvTopToBottom \
}
+#define XVIMAGE_AYUV { \
+ FOURCC_AYUV, XvYUV, LSBFirst, \
+ {'A', 'Y', 'U', 'V', 0x00, 0x00, 0x00, 0x10, 0x80, 0x00, 0x00, 0xAA, 0x00, 0x38, 0x9B, 0x71}, \
+ 32, XvPacked, 1, 0, 0, 0, 0, 8, 8, 8, 1, 1, 1, 1, 1, 1, \
+ {'A', 'Y', 'U', 'V', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, \
+ XvTopToBottom \
+}
+
struct sna_video {
struct sna *sna;
@@ -189,6 +198,16 @@ static inline int is_nv12_fourcc(int id)
}
}
+static inline int is_ayuv_fourcc(int id)
+{
+ switch (id) {
+ case FOURCC_AYUV:
+ return 1;
+ default:
+ return 0;
+ }
+}
+
bool
sna_video_clip_helper(struct sna_video *video,
struct sna_video_frame *frame,
diff --git a/src/sna/sna_video_sprite.c b/src/sna/sna_video_sprite.c
index d3d722d4..da676ad6 100644
--- a/src/sna/sna_video_sprite.c
+++ b/src/sna/sna_video_sprite.c
@@ -47,11 +47,11 @@
#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 DRM_FORMAT_XYUV8888 fourcc_code('X', 'Y', 'U', 'V') /* [31:0] x:Y:U:V 8:8:8:8 little endian */
#define has_hw_scaling(sna, video) ((sna)->kgem.gen < 071 || \
(sna)->kgem.gen >= 0110)
-
#define LOCAL_IOCTL_MODE_SETPLANE DRM_IOWR(0xB7, struct local_mode_set_plane)
struct local_mode_set_plane {
uint32_t plane_id;
@@ -79,6 +79,8 @@ 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 XvImageRec images_ayuv[] = { XVIMAGE_AYUV, 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" },
@@ -410,6 +412,10 @@ sna_video_sprite_show(struct sna *sna,
case FOURCC_UYVY:
f.pixel_format = DRM_FORMAT_UYVY;
break;
+ case FOURCC_AYUV:
+ /* i915 doesn't support alpha, so we use XYUV */
+ f.pixel_format = DRM_FORMAT_XYUV8888;
+ break;
case FOURCC_YUY2:
default:
f.pixel_format = DRM_FORMAT_YUYV;
@@ -751,7 +757,12 @@ static int sna_video_sprite_query(ddQueryImageAttributes_ARGS)
tmp *= (*h >> 1);
size += tmp;
break;
-
+ case FOURCC_AYUV:
+ tmp = *w << 2;
+ if (pitches)
+ pitches[0] = tmp;
+ size = *h * tmp;
+ break;
default:
*w = (*w + 1) & ~1;
*h = (*h + 1) & ~1;
@@ -851,7 +862,10 @@ void sna_video_sprite_setup(struct sna *sna, ScreenPtr screen)
adaptor->nAttributes = ARRAY_SIZE(attribs);
adaptor->pAttributes = (XvAttributeRec *)attribs;
- if (sna_has_sprite_format(sna, DRM_FORMAT_NV12)) {
+ if (sna_has_sprite_format(sna, DRM_FORMAT_XYUV8888)) {
+ adaptor->pImages = (XvImageRec *)images_ayuv;
+ adaptor->nImages = ARRAY_SIZE(images_ayuv);
+ } else 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)) {
diff --git a/src/sna/sna_video_textured.c b/src/sna/sna_video_textured.c
index 115cbea4..06da36d0 100644
--- a/src/sna/sna_video_textured.c
+++ b/src/sna/sna_video_textured.c
@@ -71,6 +71,16 @@ static const XvImageRec gen4_Images[] = {
XVMC_YUV,
};
+static const XvImageRec gen9_Images[] = {
+ XVIMAGE_YUY2,
+ XVIMAGE_YV12,
+ XVIMAGE_I420,
+ XVIMAGE_NV12,
+ XVIMAGE_UYVY,
+ XVIMAGE_AYUV,
+ XVMC_YUV,
+};
+
static int sna_video_textured_stop(ddStopVideo_ARGS)
{
struct sna_video *video = port->devPriv.ptr;
@@ -337,6 +347,12 @@ sna_video_textured_query(ddQueryImageAttributes_ARGS)
pitches[0] = size;
size *= *h;
break;
+ case FOURCC_AYUV:
+ size = *w << 2;
+ if (pitches)
+ pitches[0] = size;
+ size *= *h;
+ break;
case FOURCC_XVMC:
*h = (*h + 1) & ~1;
size = sizeof(uint32_t);
@@ -414,9 +430,12 @@ void sna_video_textured_setup(struct sna *sna, ScreenPtr screen)
} else if (sna->kgem.gen < 040) {
adaptor->nImages = ARRAY_SIZE(gen3_Images);
adaptor->pImages = (XvImageRec *)gen3_Images;
- } else {
+ } else if (sna->kgem.gen < 0110) {
adaptor->nImages = ARRAY_SIZE(gen4_Images);
adaptor->pImages = (XvImageRec *)gen4_Images;
+ } else {
+ adaptor->nImages = ARRAY_SIZE(gen9_Images);
+ adaptor->pImages = (XvImageRec *)gen9_Images;
}
#if XORG_XV_VERSION < 2
adaptor->ddAllocatePort = sna_xv_alloc_port;