summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2011-06-21 12:28:13 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2011-06-22 11:04:56 +0100
commitea71133da78632d4cfee5b0b4c96e8dddd6cdf44 (patch)
tree9dd464de5258f6287e9a550b7db9dbcd8d83f99e
parent2f6afb5b1f02cc448da1b342627108ceddda4f0d (diff)
sna/video: Use pwrite for upload of unclipped, unrotated frames
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r--src/sna/gen3_render.c4
-rw-r--r--src/sna/gen4_render.c4
-rw-r--r--src/sna/gen5_render.c4
-rw-r--r--src/sna/gen6_render.c4
-rw-r--r--src/sna/kgem.h6
-rw-r--r--src/sna/sna_video.c138
-rw-r--r--src/sna/sna_video.h9
-rw-r--r--src/sna/sna_video_overlay.c2
8 files changed, 97 insertions, 74 deletions
diff --git a/src/sna/gen3_render.c b/src/sna/gen3_render.c
index 542856d1..c40718b7 100644
--- a/src/sna/gen3_render.c
+++ b/src/sna/gen3_render.c
@@ -2837,7 +2837,7 @@ gen3_emit_video_state(struct sna *sna,
OUT_BATCH(kgem_add_reloc(&sna->kgem, sna->kgem.nbatch,
frame->bo,
I915_GEM_DOMAIN_SAMPLER << 16,
- frame->YBufOffset));
+ 0));
ms3 = MAPSURF_422;
switch (frame->id) {
@@ -2951,7 +2951,7 @@ gen3_emit_video_state(struct sna *sna,
OUT_BATCH(kgem_add_reloc(&sna->kgem, sna->kgem.nbatch,
frame->bo,
I915_GEM_DOMAIN_SAMPLER << 16,
- frame->YBufOffset));
+ 0));
ms3 = MAPSURF_8BIT | MT_8BIT_I8;
ms3 |= (frame->height - 1) << MS3_HEIGHT_SHIFT;
diff --git a/src/sna/gen4_render.c b/src/sna/gen4_render.c
index 20f8bf09..2a2ecab9 100644
--- a/src/sna/gen4_render.c
+++ b/src/sna/gen4_render.c
@@ -1546,8 +1546,8 @@ static void gen4_video_bind_surfaces(struct sna *sna,
uint16_t offset;
int n_src, n;
- src_surf_base[0] = frame->YBufOffset;
- src_surf_base[1] = frame->YBufOffset;
+ src_surf_base[0] = 0;
+ src_surf_base[1] = 0;
src_surf_base[2] = frame->VBufOffset;
src_surf_base[3] = frame->VBufOffset;
src_surf_base[4] = frame->UBufOffset;
diff --git a/src/sna/gen5_render.c b/src/sna/gen5_render.c
index 69c71f5d..77ad1bba 100644
--- a/src/sna/gen5_render.c
+++ b/src/sna/gen5_render.c
@@ -1559,8 +1559,8 @@ static void gen5_video_bind_surfaces(struct sna *sna,
uint16_t offset;
- src_surf_base[0] = frame->YBufOffset;
- src_surf_base[1] = frame->YBufOffset;
+ src_surf_base[0] = 0;
+ src_surf_base[1] = 0;
src_surf_base[2] = frame->VBufOffset;
src_surf_base[3] = frame->VBufOffset;
src_surf_base[4] = frame->UBufOffset;
diff --git a/src/sna/gen6_render.c b/src/sna/gen6_render.c
index 80d1f3d7..4f3e41a4 100644
--- a/src/sna/gen6_render.c
+++ b/src/sna/gen6_render.c
@@ -1735,8 +1735,8 @@ static void gen6_emit_video_state(struct sna *sna,
gen6_get_batch(sna);
- src_surf_base[0] = frame->YBufOffset;
- src_surf_base[1] = frame->YBufOffset;
+ src_surf_base[0] = 0;
+ src_surf_base[1] = 0;
src_surf_base[2] = frame->VBufOffset;
src_surf_base[3] = frame->VBufOffset;
src_surf_base[4] = frame->UBufOffset;
diff --git a/src/sna/kgem.h b/src/sna/kgem.h
index b2179968..6b3fe7ea 100644
--- a/src/sna/kgem.h
+++ b/src/sna/kgem.h
@@ -274,10 +274,8 @@ uint32_t kgem_add_reloc(struct kgem *kgem,
void *kgem_bo_map(struct kgem *kgem, struct kgem_bo *bo, int prot);
uint32_t kgem_bo_flink(struct kgem *kgem, struct kgem_bo *bo);
-Bool kgem_bo_write(struct kgem *kgem,
- struct kgem_bo *bo,
- const void *data,
- int length);
+Bool kgem_bo_write(struct kgem *kgem, struct kgem_bo *bo,
+ const void *data, int length);
static inline bool kgem_bo_is_busy(struct kgem *kgem, struct kgem_bo *bo)
{
diff --git a/src/sna/sna_video.c b/src/sna/sna_video.c
index 8839ab74..7f520da2 100644
--- a/src/sna/sna_video.c
+++ b/src/sna/sna_video.c
@@ -236,16 +236,12 @@ sna_video_frame_init(struct sna *sna,
frame->pitch[1] = 0;
}
- frame->YBufOffset = 0;
-
if (video->rotation & (RR_Rotate_90 | RR_Rotate_270)) {
- frame->UBufOffset =
- frame->YBufOffset + frame->pitch[1] * width;
+ frame->UBufOffset = frame->pitch[1] * width;
frame->VBufOffset =
frame->UBufOffset + frame->pitch[0] * width / 2;
} else {
- frame->UBufOffset =
- frame->YBufOffset + frame->pitch[1] * height;
+ frame->UBufOffset = frame->pitch[1] * height;
frame->VBufOffset =
frame->UBufOffset + frame->pitch[0] * height / 2;
}
@@ -319,52 +315,50 @@ static void sna_memcpy_plane(unsigned char *dst, unsigned char *src,
static void
sna_copy_planar_data(struct sna *sna,
struct sna_video *video,
- struct sna_video_frame *frame,
- unsigned char *buf,
+ const struct sna_video_frame *frame,
+ unsigned char *src,
unsigned char *dst,
int srcPitch, int srcPitch2,
int srcH, int top, int left)
{
- unsigned char *src1, *src2, *src3, *dst1, *dst2, *dst3;
+ unsigned char *src1, *dst1;
/* Copy Y data */
- src1 = buf + (top * srcPitch) + left;
+ src1 = src + (top * srcPitch) + left;
- dst1 = dst + frame->YBufOffset;
-
- sna_memcpy_plane(dst1, src1,
+ sna_memcpy_plane(dst, src1,
frame->height, frame->width,
frame->pitch[1], srcPitch,
video->rotation);
/* Copy V data for YV12, or U data for I420 */
- src2 = buf + /* start of YUV data */
+ src1 = src + /* start of YUV data */
(srcH * srcPitch) + /* move over Luma plane */
((top >> 1) * srcPitch2) + /* move down from by top lines */
(left >> 1); /* move left by left pixels */
if (frame->id == FOURCC_I420)
- dst2 = dst + frame->UBufOffset;
+ dst1 = dst + frame->UBufOffset;
else
- dst2 = dst + frame->VBufOffset;
+ dst1 = dst + frame->VBufOffset;
- sna_memcpy_plane(dst2, src2,
+ sna_memcpy_plane(dst1, src1,
frame->height / 2, frame->width / 2,
frame->pitch[0], srcPitch2,
video->rotation);
/* Copy U data for YV12, or V data for I420 */
- src3 = buf + /* start of YUV data */
+ src1 = src + /* start of YUV data */
(srcH * srcPitch) + /* move over Luma plane */
((srcH >> 1) * srcPitch2) + /* move over Chroma plane */
((top >> 1) * srcPitch2) + /* move down from by top lines */
(left >> 1); /* move left by left pixels */
if (frame->id == FOURCC_I420)
- dst3 = dst + frame->VBufOffset;
+ dst1 = dst + frame->VBufOffset;
else
- dst3 = dst + frame->UBufOffset;
+ dst1 = dst + frame->UBufOffset;
- sna_memcpy_plane(dst3, src3,
+ sna_memcpy_plane(dst1, src1,
frame->height / 2, frame->width / 2,
frame->pitch[0], srcPitch2,
video->rotation);
@@ -373,99 +367,99 @@ sna_copy_planar_data(struct sna *sna,
static void
sna_copy_packed_data(struct sna *sna,
struct sna_video *video,
- struct sna_video_frame *frame,
+ const struct sna_video_frame *frame,
unsigned char *buf,
unsigned char *dst,
int srcPitch,
int top, int left)
{
+ int w = frame->width;
+ int h = frame->height;
unsigned char *src;
unsigned char *s;
int i, j;
src = buf + (top * srcPitch) + (left << 1);
- dst += frame->YBufOffset;
-
switch (video->rotation) {
case RR_Rotate_0:
- frame->width <<= 1;
- for (i = 0; i < frame->height; i++) {
- memcpy(dst, src, frame->width);
+ w <<= 1;
+ for (i = 0; i < h; i++) {
+ memcpy(dst, src, w);
src += srcPitch;
dst += frame->pitch[0];
}
break;
case RR_Rotate_90:
- frame->height <<= 1;
- for (i = 0; i < frame->height; i += 2) {
+ h <<= 1;
+ for (i = 0; i < h; i += 2) {
s = src;
- for (j = 0; j < frame->width; j++) {
+ for (j = 0; j < w; j++) {
/* Copy Y */
- dst[(i + 0) + ((frame->width - j - 1) * frame->pitch[0])] = *s++;
+ dst[(i + 0) + ((w - j - 1) * frame->pitch[0])] = *s++;
(void)*s++;
}
src += srcPitch;
}
- frame->height >>= 1;
+ h >>= 1;
src = buf + (top * srcPitch) + (left << 1);
- for (i = 0; i < frame->height; i += 2) {
- for (j = 0; j < frame->width; j += 2) {
+ for (i = 0; i < h; i += 2) {
+ for (j = 0; j < w; j += 2) {
/* Copy U */
- dst[((i * 2) + 1) + ((frame->width - j - 1) * frame->pitch[0])] =
+ dst[((i * 2) + 1) + ((w - j - 1) * frame->pitch[0])] =
src[(j * 2) + 1 + (i * srcPitch)];
- dst[((i * 2) + 1) + ((frame->width - j - 2) * frame->pitch[0])] =
+ dst[((i * 2) + 1) + ((w - j - 2) * frame->pitch[0])] =
src[(j * 2) + 1 + ((i + 1) * srcPitch)];
/* Copy V */
- dst[((i * 2) + 3) + ((frame->width - j - 1) * frame->pitch[0])] =
+ dst[((i * 2) + 3) + ((w - j - 1) * frame->pitch[0])] =
src[(j * 2) + 3 + (i * srcPitch)];
- dst[((i * 2) + 3) + ((frame->width - j - 2) * frame->pitch[0])] =
+ dst[((i * 2) + 3) + ((w - j - 2) * frame->pitch[0])] =
src[(j * 2) + 3 + ((i + 1) * srcPitch)];
}
}
break;
case RR_Rotate_180:
- frame->width <<= 1;
- for (i = 0; i < frame->height; i++) {
+ w <<= 1;
+ for (i = 0; i < h; i++) {
s = src;
- for (j = 0; j < frame->width; j += 4) {
- dst[(frame->width - j - 4) + ((frame->height - i - 1) * frame->pitch[0])] =
+ for (j = 0; j < w; j += 4) {
+ dst[(w - j - 4) + ((h - i - 1) * frame->pitch[0])] =
*s++;
- dst[(frame->width - j - 3) + ((frame->height - i - 1) * frame->pitch[0])] =
+ dst[(w - j - 3) + ((h - i - 1) * frame->pitch[0])] =
*s++;
- dst[(frame->width - j - 2) + ((frame->height - i - 1) * frame->pitch[0])] =
+ dst[(w - j - 2) + ((h - i - 1) * frame->pitch[0])] =
*s++;
- dst[(frame->width - j - 1) + ((frame->height - i - 1) * frame->pitch[0])] =
+ dst[(w - j - 1) + ((h - i - 1) * frame->pitch[0])] =
*s++;
}
src += srcPitch;
}
break;
case RR_Rotate_270:
- frame->height <<= 1;
- for (i = 0; i < frame->height; i += 2) {
+ h <<= 1;
+ for (i = 0; i < h; i += 2) {
s = src;
- for (j = 0; j < frame->width; j++) {
+ for (j = 0; j < w; j++) {
/* Copy Y */
- dst[(frame->height - i - 2) + (j * frame->pitch[0])] = *s++;
+ dst[(h - i - 2) + (j * frame->pitch[0])] = *s++;
(void)*s++;
}
src += srcPitch;
}
- frame->height >>= 1;
+ h >>= 1;
src = buf + (top * srcPitch) + (left << 1);
- for (i = 0; i < frame->height; i += 2) {
- for (j = 0; j < frame->width; j += 2) {
+ for (i = 0; i < h; i += 2) {
+ for (j = 0; j < w; j += 2) {
/* Copy U */
- dst[(((frame->height - i) * 2) - 3) + (j * frame->pitch[0])] =
+ dst[(((h - i) * 2) - 3) + (j * frame->pitch[0])] =
src[(j * 2) + 1 + (i * srcPitch)];
- dst[(((frame->height - i) * 2) - 3) +
+ dst[(((h - i) * 2) - 3) +
((j + 1) * frame->pitch[0])] =
src[(j * 2) + 1 + ((i + 1) * srcPitch)];
/* Copy V */
- dst[(((frame->height - i) * 2) - 1) + (j * frame->pitch[0])] =
+ dst[(((h - i) * 2) - 1) + (j * frame->pitch[0])] =
src[(j * 2) + 3 + (i * srcPitch)];
- dst[(((frame->height - i) * 2) - 1) +
+ dst[(((h - i) * 2) - 1) +
((j + 1) * frame->pitch[0])] =
src[(j * 2) + 3 + ((i + 1) * srcPitch)];
}
@@ -488,6 +482,38 @@ sna_video_copy_data(struct sna *sna,
if (frame->bo == NULL)
return FALSE;
+ /* In the common case, we can simply the upload to a single pwrite */
+ if (video->rotation == RR_Rotate_0) {
+ if (is_planar_fourcc(frame->id)) {
+ uint16_t pitch[2] = {
+ ALIGN((frame->width >> 1), 0x4),
+ ALIGN(frame->width, 0x4),
+ };
+ if (pitch[0] == frame->pitch[0] &&
+ pitch[1] == frame->pitch[1] &&
+ top == 0 && left == 0) {
+ kgem_bo_write(&sna->kgem, frame->bo,
+ buf,
+ pitch[1]*frame->height +
+ pitch[0]*frame->height);
+ if (frame->id != FOURCC_I420) {
+ uint32_t tmp;
+ tmp = frame->VBufOffset;
+ frame->VBufOffset = frame->UBufOffset;
+ frame->UBufOffset = tmp;
+ }
+ return TRUE;
+ }
+ } else {
+ if (frame->width*2 == frame->pitch[0]) {
+ kgem_bo_write(&sna->kgem, frame->bo,
+ buf + (top * frame->width*2) + (left << 1),
+ frame->height*frame->width*2);
+ return TRUE;
+ }
+ }
+ }
+
/* copy data */
dst = kgem_bo_map(&sna->kgem, frame->bo, PROT_READ | PROT_WRITE);
if (dst == NULL)
diff --git a/src/sna/sna_video.h b/src/sna/sna_video.h
index f66a6977..bf4f6a49 100644
--- a/src/sna/sna_video.h
+++ b/src/sna/sna_video.h
@@ -64,13 +64,12 @@ struct sna_video {
struct sna_video_frame {
struct kgem_bo *bo;
- int id;
- int width, height;
- int pitch[2];
- int size;
- uint32_t YBufOffset;
+ uint32_t id;
+ uint32_t size;
uint32_t UBufOffset;
uint32_t VBufOffset;
+ uint16_t width, height;
+ uint16_t pitch[2];
};
void sna_video_init(struct sna *sna, ScreenPtr screen);
diff --git a/src/sna/sna_video_overlay.c b/src/sna/sna_video_overlay.c
index 3f7d9557..c4838c2d 100644
--- a/src/sna/sna_video_overlay.c
+++ b/src/sna/sna_video_overlay.c
@@ -398,7 +398,7 @@ sna_video_overlay_show(struct sna *sna,
request.stride_Y = frame->pitch[0];
request.stride_UV = 0;
}
- request.offset_Y = frame->YBufOffset;
+ request.offset_Y = 0;
request.offset_U = frame->UBufOffset;
request.offset_V = frame->VBufOffset;
DBG(("%s: handle=%d, stride_Y=%d, stride_UV=%d, off_Y: %i, off_U: %i, off_V: %i\n",