summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichel Dänzer <michel@tungstengraphics.com>2008-08-14 15:21:51 -0400
committerBrice Goglin <bgoglin@debian.org>2008-08-26 21:21:05 +0200
commit96ff37226ef6f06a05535f3a6f73a4c104f4024d (patch)
treee5bfc9f3d5c7ba20406f6488b8989ec530ec1ef7
parentcaad65eee3124af2a3d4c005707a621ad8420e15 (diff)
downloadxf86-video-ati-frc-96ff37226ef6f06a05535f3a6f73a4c104f4024d.tar.gz
xf86-video-ati-frc-96ff37226ef6f06a05535f3a6f73a4c104f4024d.tar.bz2
Make sure video offerlay offsets don't exceed the hardware limit of 128 MB.
Always set the overlay base address such that the buffer offsets are as small as possible. This could still break in theory if the buffers were more than 128 MB apart, but in reality this can't happen ATM because we always allocate a single memory area for all buffers. Fixes http://bugs.freedesktop.org/show_bug.cgi?id=16845 . (cherry picked from commit a55e85f742d1334bf88e4681e553f025d2de38df)
-rw-r--r--src/radeon_video.c21
1 files changed, 21 insertions, 0 deletions
diff --git a/src/radeon_video.c b/src/radeon_video.c
index ac60166..57dcd8a 100644
--- a/src/radeon_video.c
+++ b/src/radeon_video.c
@@ -2586,6 +2586,7 @@ RADEONDisplayVideo(
RADEONOutputPrivatePtr radeon_output;
xf86OutputPtr output;
RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
+ int base_offset;
is_rgb=0; is_planar=0;
switch(id){
@@ -2715,6 +2716,22 @@ RADEONDisplayVideo(
}
#endif
+ /* Make the overlay base address as close to the buffers as possible to
+ * prevent the buffer offsets from exceeding the hardware limit of 128 MB.
+ * The base address must be aligned to a multiple of 4 MB.
+ */
+ base_offset = ((info->fbLocation +
+ min(offset1, min(offset2, min(offset3, min(offset4,
+ min(offset5, offset6)))))) & (~0 << 22)) -
+ info->fbLocation;
+
+ offset1 -= base_offset;
+ offset2 -= base_offset;
+ offset3 -= base_offset;
+ offset4 -= base_offset;
+ offset5 -= base_offset;
+ offset6 -= base_offset;
+
/* keep everything in 16.16 */
if (is_planar) {
@@ -2846,6 +2863,10 @@ RADEONDisplayVideo(
src_w >>= 1;
OUTREG(RADEON_OV0_P2_X_START_END, (src_w + leftuv - 1) | (leftuv << 16));
OUTREG(RADEON_OV0_P3_X_START_END, (src_w + leftuv - 1) | (leftuv << 16));
+ if (info->ModeReg->ov0_base_addr != (info->fbLocation + base_offset)) {
+ info->ModeReg->ov0_base_addr = info->fbLocation + base_offset;
+ OUTREG(RADEON_OV0_BASE_ADDR, info->ModeReg->ov0_base_addr);
+ }
OUTREG(RADEON_OV0_VID_BUF0_BASE_ADRS, offset1);
OUTREG(RADEON_OV0_VID_BUF1_BASE_ADRS, offset2);
OUTREG(RADEON_OV0_VID_BUF2_BASE_ADRS, offset3);