diff options
author | Michel Dänzer <michel@tungstengraphics.com> | 2008-08-14 15:21:51 -0400 |
---|---|---|
committer | Alex Deucher <alexdeucher@gmail.com> | 2008-08-14 15:21:51 -0400 |
commit | a55e85f742d1334bf88e4681e553f025d2de38df (patch) | |
tree | 52e2b38e8bfe82884181c6b16e6b2a415e4e2153 /src | |
parent | 92ee21df344a989778e37369c7beb3904a00ead6 (diff) |
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 .
Diffstat (limited to 'src')
-rw-r--r-- | src/radeon_video.c | 21 |
1 files changed, 21 insertions, 0 deletions
diff --git a/src/radeon_video.c b/src/radeon_video.c index ac601663..57dcd8ac 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); |