[PATCH:xf86-video-ati] Make RADEONCopySwap deal with misaligned buffers.

Michel Dänzer michel at daenzer.net
Tue Feb 4 03:43:09 CET 2014


On Mon, 2014-02-03 at 20:36 +0100, Martin Husemann wrote:
> When using xvideo on alignement critical architectures (for example a sparc64
> with the XVR100 graphics adapter) some screen positions (easily reproducable
> with xfce and gmplayer by moving the video window partly out of the screen
> on the left side) cause misaligned pointers being passed to RADEONCopySwap -
> and cause the X server to crash.
> 
> This may be bugs in the calling code (e.g. RADEONPutImage), but it only
> seems to try to align to 16 bit anyway - and actually some calls end up
> even with only byte aligned buffers.
> 
> This change notices the misalignement and uses less efficient, smaller
> copies. But at least the X server does not crash (and all usual screen
> positions seem to end up in proper aligned buffers).
> 
> Signed-off-by: Martin Husemann <martin at NetBSD.org>
> ---
>  src/radeon_accel.c | 25 ++++++++++++++++++++++++-
>  1 file changed, 24 insertions(+), 1 deletion(-)
> 
> diff --git a/src/radeon_accel.c b/src/radeon_accel.c
> index 8eff5c5..bb8726f 100644
> --- a/src/radeon_accel.c
> +++ b/src/radeon_accel.c
> @@ -141,7 +141,30 @@ void RADEONCopySwap(uint8_t *dst, uint8_t *src, unsigned int size, int swap)
>  	    return;
>          }
>      case RADEON_HOST_DATA_SWAP_32BIT:
> -        {
> +	if (((uintptr_t)dst & 1) || ((uintptr_t)src & 1)) {
> +	    uint8_t *d = (uint8_t *)dst;
> +	    uint8_t *s = (uint8_t *)src;
> +	    unsigned int nwords = size >> 2;
> +
> +	    for (; nwords > 0; --nwords, d+=4, s+=4) {
> +	        d[0] = s[3];
> +		d[1] = s[2];
> +		d[2] = s[1];
> +		d[3] = s[0];
> +	    }
> +	    return;
> +        } else if (((uintptr_t)dst & 3) || ((uintptr_t)src & 3)) {
> +	    /* copy 16bit wise */
> +	    uint16_t *d = (uint16_t *)dst;
> +	    uint16_t *s = (uint16_t *)src;
> +	    unsigned int nwords = size >> 2;
> +
> +	    for (; nwords > 0; --nwords, d+=2, s+=2) {
> +	        d[0] = ((s[1] >> 8) & 0xff) | ((s[1] & 0xff) << 8);
> +	        d[1] = ((s[0] >> 8) & 0xff) | ((s[0] & 0xff) << 8);
> +	    }
> +	    return;
> +	} else {

Can this be limited to affected platforms?


-- 
Earthling Michel Dänzer            |                  http://www.amd.com
Libre software enthusiast          |                Mesa and X developer



More information about the xorg-devel mailing list