Thread (9 messages) 9 messages, 3 authors, 2004-06-17

Re: accelerated radeonfb produces artifacts on scrolling in 2.6.7

From: Jurriaan <hidden>
Date: 2004-06-16 19:52:43
Also in: lkml

From: Timothy Miller <redacted>
Date: Wed, Jun 16, 2004 at 03:55:32PM -0400

David Eger wrote:
quoted
On Wed, Jun 16, 2004 at 08:24:15PM +0200, Jurriaan wrote:
quoted
The radeonfb driver in 2.6.7 produces some interesting artifacts on
scrolling, both scrolling horizontally and vertically.

The corruption you are talking about is, I believe, caused by a couple of 
things:

(1) we're not issuing enough fifo_wait()'s around our accel engine
   and pan register writes.
(2) there's some disconnect between writing to fb memory, panning, and
   copyarea()/fillrect() calls

I sent a hack of a fix for this to Ben a week ago, adding a call to 
radeonfb_sync()
at the end of radeonfb_copyarea() and radeonfb_fillrect().  This seems to 
fix the
problem for me, but you *shouldn't* have to do this.  

I haven't tracked it any further than this.  My next guess would be 
auditing register writes and making sure there are enough fifo_wait()'s...

Is this the case even with the off-by-one error in the bitblt code 
fixed?  In the 2.4 kernel, I got rid of all artifacts by fixing the 
off-by-one error.

In case, you don't know what I'm talking about, when you bitblt up or to 
the left on Radeon, x and y need to be adjusted by (w-1) and/or (h-1), 
respectively.  The code there, however, adjusted by w and/or h, which is 
off-by-one.
You mean this code? I see (w-1) and (h-1) in there.

static void radeonfb_prim_copyarea(struct radeonfb_info *rinfo, 
				   const struct fb_copyarea *area)
{
	int xdir, ydir;
	u32 sx, sy, dx, dy, w, h;

	w = area->width; h = area->height;
	dx = area->dx; dy = area->dy;
	sx = area->sx; sy = area->sy;
	xdir = sx - dx;
	ydir = sy - dy;

	if ( xdir < 0 ) { sx += w-1; dx += w-1; }
	if ( ydir < 0 ) { sy += h-1; dy += h-1; }

	radeon_fifo_wait(3);
	OUTREG(DP_GUI_MASTER_CNTL,
		rinfo->dp_gui_master_cntl /* i.e. GMC_DST_32BPP */
		| GMC_SRC_DSTCOLOR
		| ROP3_S 
		| DP_SRC_RECT );
	OUTREG(DP_WRITE_MSK, 0xffffffff);
	OUTREG(DP_CNTL, (xdir>=0 ? DST_X_LEFT_TO_RIGHT : 0)
			| (ydir>=0 ? DST_Y_TOP_TO_BOTTOM : 0));

	radeon_fifo_wait(3);
	OUTREG(SRC_Y_X, (sy << 16) | sx);
	OUTREG(DST_Y_X, (dy << 16) | dx);
	OUTREG(DST_HEIGHT_WIDTH, (h << 16) | w);
}


void radeonfb_copyarea(struct fb_info *info, const struct fb_copyarea *area)
{
	struct radeonfb_info *rinfo = info->par;
	struct fb_copyarea modded;
	u32 vxres, vyres;
	modded.sx = area->sx;
	modded.sy = area->sy;
	modded.dx = area->dx;
	modded.dy = area->dy;
	modded.width  = area->width;
	modded.height = area->height;
  
	if (info->state != FBINFO_STATE_RUNNING)
		return;
	if (radeon_accel_disabled()) {
		cfb_copyarea(info, area);
		return;
	}

	vxres = info->var.xres;
	vyres = info->var.yres;

	if(!modded.width || !modded.height ||
	   modded.sx >= vxres || modded.sy >= vyres ||
	   modded.dx >= vxres || modded.dy >= vyres)
		return;
  
	if(modded.sx + modded.width > vxres)  modded.width = vxres - modded.sx;
	if(modded.dx + modded.width > vxres)  modded.width = vxres - modded.dx;
	if(modded.sy + modded.height > vyres) modded.height = vyres - modded.sy;
	if(modded.dy + modded.height > vyres) modded.height = vyres - modded.dy;
  
	radeonfb_prim_copyarea(rinfo, &modded);
}

HTH,
Jurriaan
-- 
hundred-and-one symptoms of being an internet addict:
17. You turn on your intercom when leaving the room so you can hear if new
e-mail arrives.
Debian (Unstable) GNU/Linux 2.6.7 2x6078 bogomips load 1.90


-------------------------------------------------------
This SF.Net email is sponsored by The 2004 JavaOne(SM) Conference
Learn from the experts at JavaOne(SM), Sun's Worldwide Java Developer
Conference, June 28 - July 1 at the Moscone Center in San Francisco, CA
REGISTER AND SAVE! http://java.sun.com/javaone/sf Priority Code NWMGYKND
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help