diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2011-06-21 12:28:13 +0100 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2011-06-22 11:04:56 +0100 |
commit | ea71133da78632d4cfee5b0b4c96e8dddd6cdf44 (patch) | |
tree | 9dd464de5258f6287e9a550b7db9dbcd8d83f99e | |
parent | 2f6afb5b1f02cc448da1b342627108ceddda4f0d (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.c | 4 | ||||
-rw-r--r-- | src/sna/gen4_render.c | 4 | ||||
-rw-r--r-- | src/sna/gen5_render.c | 4 | ||||
-rw-r--r-- | src/sna/gen6_render.c | 4 | ||||
-rw-r--r-- | src/sna/kgem.h | 6 | ||||
-rw-r--r-- | src/sna/sna_video.c | 138 | ||||
-rw-r--r-- | src/sna/sna_video.h | 9 | ||||
-rw-r--r-- | src/sna/sna_video_overlay.c | 2 |
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", |