summaryrefslogtreecommitdiff
path: root/src/radeon_textured_video.c
diff options
context:
space:
mode:
authorAlex Deucher <alexdeucher@gmail.com>2009-03-04 19:04:34 -0500
committerAlex Deucher <alexdeucher@gmail.com>2009-03-04 19:04:34 -0500
commit3b0fc22ad9e5c0f120a74c4f3d8e48c270f0ff29 (patch)
tree88b8955d582697192344f8b09e5ec38b3bcfb64d /src/radeon_textured_video.c
parent52f06ace04ad8141effc45fb6a0107a05bb46a73 (diff)
R6xx/R7xx: wire up DMAForXv option like older asics
Select between SW and HW-assisted uploads
Diffstat (limited to 'src/radeon_textured_video.c')
-rw-r--r--src/radeon_textured_video.c139
1 files changed, 116 insertions, 23 deletions
diff --git a/src/radeon_textured_video.c b/src/radeon_textured_video.c
index dad77957..2df299f5 100644
--- a/src/radeon_textured_video.c
+++ b/src/radeon_textured_video.c
@@ -160,11 +160,11 @@ static __inline__ uint32_t F_TO_24(float val)
#endif /* XF86DRI */
static void
-R600CopyPlanar(ScrnInfoPtr pScrn,
- unsigned char *y_src, unsigned char *u_src, unsigned char *v_src,
- uint32_t dst_mc_addr,
- int srcPitch, int srcPitch2, int dstPitch,
- int w, int h)
+R600CopyPlanarHW(ScrnInfoPtr pScrn,
+ unsigned char *y_src, unsigned char *u_src, unsigned char *v_src,
+ uint32_t dst_mc_addr,
+ int srcPitch, int srcPitch2, int dstPitch,
+ int w, int h)
{
int dstPitch2 = dstPitch >> 1;
int h2 = h >> 1;
@@ -195,10 +195,10 @@ R600CopyPlanar(ScrnInfoPtr pScrn,
}
static void
-R600CopyPacked(ScrnInfoPtr pScrn,
- unsigned char *src, uint32_t dst_mc_addr,
- int srcPitch, int dstPitch,
- int w, int h)
+R600CopyPackedHW(ScrnInfoPtr pScrn,
+ unsigned char *src, uint32_t dst_mc_addr,
+ int srcPitch, int dstPitch,
+ int w, int h)
{
/* YUV */
@@ -209,6 +209,82 @@ R600CopyPacked(ScrnInfoPtr pScrn,
}
+static void
+R600CopyPlanarSW(ScrnInfoPtr pScrn,
+ unsigned char *y_src, unsigned char *u_src, unsigned char *v_src,
+ unsigned char *dst,
+ int srcPitch, int srcPitch2, int dstPitch,
+ int w, int h)
+{
+ int i;
+ int dstPitch2 = dstPitch >> 1;
+ int h2 = h >> 1;
+
+ /* Y */
+ if (srcPitch == dstPitch) {
+ memcpy(dst, y_src, srcPitch * h);
+ dst += (dstPitch * h);
+ } else {
+ for (i = 0; i < h; i++) {
+ memcpy(dst, y_src, srcPitch);
+ y_src += srcPitch;
+ dst += dstPitch;
+ }
+ }
+
+ /* tex base need 256B alignment */
+ if (h & 1)
+ dst += dstPitch;
+
+ /* V */
+ if (srcPitch2 == dstPitch2) {
+ memcpy(dst, v_src, srcPitch2 * h2);
+ dst += (dstPitch2 * h2);
+ } else {
+ for (i = 0; i < h2; i++) {
+ memcpy(dst, v_src, srcPitch2);
+ v_src += srcPitch2;
+ dst += dstPitch2;
+ }
+ }
+
+ /* tex base need 256B alignment */
+ if (h2 & 1)
+ dst += dstPitch2;
+
+ /* U */
+ if (srcPitch2 == dstPitch2) {
+ memcpy(dst, u_src, srcPitch2 * h2);
+ dst += (dstPitch2 * h2);
+ } else {
+ for (i = 0; i < h2; i++) {
+ memcpy(dst, u_src, srcPitch2);
+ u_src += srcPitch2;
+ dst += dstPitch2;
+ }
+ }
+}
+
+static void
+R600CopyPackedSW(ScrnInfoPtr pScrn,
+ unsigned char *src, unsigned char *dst,
+ int srcPitch, int dstPitch,
+ int w, int h)
+{
+ int i;
+
+ if (srcPitch == dstPitch) {
+ memcpy(dst, src, srcPitch * h);
+ dst += (dstPitch * h);
+ } else {
+ for (i = 0; i < h; i++) {
+ memcpy(dst, src, srcPitch);
+ src += srcPitch;
+ dst += dstPitch;
+ }
+ }
+}
+
static int
RADEONPutImageTextured(ScrnInfoPtr pScrn,
short src_x, short src_y,
@@ -371,17 +447,29 @@ RADEONPutImageTextured(ScrnInfoPtr pScrn,
if (info->ChipFamily >= CHIP_FAMILY_R600) {
s2offset = srcPitch * height;
s3offset = (srcPitch2 * (height >> 1)) + s2offset;
- if (id == FOURCC_YV12)
- R600CopyPlanar(pScrn, buf, buf + s3offset, buf + s2offset,
- pPriv->src_offset,
- srcPitch, srcPitch2, pPriv->src_pitch,
- width, height);
- else
- R600CopyPlanar(pScrn, buf, buf + s2offset, buf + s3offset,
- pPriv->src_offset,
- srcPitch, srcPitch2, pPriv->src_pitch,
- width, height);
-
+ if (info->DMAForXv) {
+ if (id == FOURCC_YV12)
+ R600CopyPlanarHW(pScrn, buf, buf + s3offset, buf + s2offset,
+ pPriv->src_offset,
+ srcPitch, srcPitch2, pPriv->src_pitch,
+ width, height);
+ else
+ R600CopyPlanarHW(pScrn, buf, buf + s2offset, buf + s3offset,
+ pPriv->src_offset,
+ srcPitch, srcPitch2, pPriv->src_pitch,
+ width, height);
+ } else {
+ if (id == FOURCC_YV12)
+ R600CopyPlanarSW(pScrn, buf, buf + s3offset, buf + s2offset,
+ pPriv->src_addr,
+ srcPitch, srcPitch2, pPriv->src_pitch,
+ width, height);
+ else
+ R600CopyPlanarSW(pScrn, buf, buf + s2offset, buf + s3offset,
+ pPriv->src_addr,
+ srcPitch, srcPitch2, pPriv->src_pitch,
+ width, height);
+ }
} else {
top &= ~1;
nlines = ((((y2 + 0xffff) >> 16) + 1) & ~1) - top;
@@ -406,9 +494,14 @@ RADEONPutImageTextured(ScrnInfoPtr pScrn,
case FOURCC_YUY2:
default:
if (info->ChipFamily >= CHIP_FAMILY_R600) {
- R600CopyPacked(pScrn, buf, pPriv->src_offset,
- 2 * width, pPriv->src_pitch,
- width, height);
+ if (info->DMAForXv)
+ R600CopyPackedHW(pScrn, buf, pPriv->src_offset,
+ 2 * width, pPriv->src_pitch,
+ width, height);
+ else
+ R600CopyPackedSW(pScrn, buf, pPriv->src_addr,
+ 2 * width, pPriv->src_pitch,
+ width, height);
} else {
nlines = ((y2 + 0xffff) >> 16) - top;
RADEONCopyData(pScrn, buf, pPriv->src_addr, srcPitch, dstPitch, nlines, npixels, 2);