GP2X Hardware Blitter?


Not fair you having updated docs Squidge :)

I'm happy that it wasn't a wasted night. I'd figured half of it out a few days ago, but had to go away before I could finish testing. Was driving me mad...
 
slygamer posted on Dec 18 2005 at 11:54 AM said:
What about malloc'ed memory? How do we find the physical address of that?

Simple answer: You can't.
More advanced answer: It's possible, but may not work all the time, so definitely not recommended.

If you want a physical memory chunk rather than a virtual chunk, then you have to use kalloc, but that's a kernel-only function and can't be used in user-programs. Also, Memory returned bby kalloc isn't guaranteed to be aligned in any way unless size is a multiple of the page size (in which case the memory is page-aligned). If you need to ensure alignment, you should allocate twice what you need and align the address you start with to the boundary you want. Memory returned via kalloc isn't guaranteed to be contained on the same physical page either, unless you allocate in multiples of the page size and keep track of the page location of addresses you use. Also, the page size is dynamic; there's currently no way to get its value from inside the kernel.

If you really want to use kalloc, then check out my post on doing it from user made here -> http://www.gp32x.de/board/index.php?showtopic=23328
 
Last edited by a moderator:
I got mine working now, hooray!
I'd done everything correctly but I hadn't set the MESGSTATUS bit, bloody docs!
I think it would be a good idea to set up a page in the wiki about this so that other people don't go through the problems we've had.

Has anyone put the blitter through it's paces to see how fast it is? Should be pretty swift as it's designed for a 1024x768 screen.
 
Just tried a basic test blitting a 32x32 16bit box 1000 times (basic src->dst copy), if I've got my numbers right...

non-optimized s/w = 0.46 seconds,
gcc -O3 s/w = 0.38 seconds.
non-optimized h/w = 0.03 seconds

gcc optimizes the h/w blit badly since it doesn't know the importance of setting MESGSTATUS last, but it was only a test run.

Code:
void blit_std(unsigned short *src,
     int xc, int yc,
     int w, int h) {
	unsigned int x, y;
	unsigned short *dst;
	
	dst = fb0 + (yc*320) + xc;
	for (y=0; y<h; y++) {
  for (x=0; x<w; x++) {
  	*dst++ = *src++;
  }
  dst += 320-w;
	}
}

void blit_accel(unsigned short *src,
     int xc, int yc,
     int w, int h) {
	unsigned short *dst;
	unsigned short offset;

	dst = (unsigned short*)0x3101000 + (yc*320) + xc;
	offset = (unsigned short)((unsigned long)dst & 2);
	ac[MESGDSTCTRL] = (1 << 5) | (0 << 6) | (offset << 3);
	ac[MESGDSTADDR] = (unsigned long)dst & 0xfffffffc;
	ac[MESGDSTSTRIDE] = 320*2;
	ac[MESGSRCCTRL] = (1 << 8) | (1 << 7) | (1 << 5);
	ac[MESGSRCADDR] = 0x3101000;
	ac[MESGSRCSTRIDE] = 64;
	ac[MESGPATCTRL] = 0;
	ac[MESGSIZE] = (h << 16) | (w << 0);
	ac[MESGCTRL] = (0 << 10) | (1 << 9) | (1 << 8) | 0xCC;
	ac[MESGSTATUS] = 0x0;
	do {} while (ac[MESGSTATUS] & 1);
}
 
I found a post by linus (yes, that linus) regarding making gcc serialize operations... http://www.ussg.iu.edu/hypermail/linux/ker...605.0/0214.html

so it looks like you should be able to leave optimizations on and still be able to tell gcc when the critical points are that you don't want memory accesses moved across. I don't know a whole lot about C, but it looks like you could...

#define mb() __asm__ __volatile__ ("" : : :"memory")

and then use mb() as a serializing point, ie right before you give the final go command to the 2d chip.
 
paeryn posted on Dec 18 2005 at 07:39 PM said:
Just tried a basic test blitting a 32x32 16bit box 1000 times (basic src->dst copy), if I've got my numbers right...

non-optimized s/w = 0.46 seconds,
gcc -O3 s/w = 0.38 seconds.
non-optimized h/w = 0.03 seconds

gcc optimizes the h/w blit badly since it doesn't know the importance of setting MESGSTATUS last, but it was only a test run.

That's great! For a 320x240 screen that's a large fill-rate.

In the manual it says that the blitter registers are double buffered so you should be able to put your 'wait' in just before you despatch the next blitter command.
 
Last edited by a moderator:
Who want's to help add 2D blitter code to SDL then :D.

SDL 1.2.9 is comming along well and I am trying to get hardware scalar support working, adding support for the blitter would be really great.

Drop me a PM if you want to help.
 
Yo DJ,

Will you be making linux developer releases of the SDL 1.2.9 code with H/W Blitter support (when it becomes available)???

Thanks.
 
timbobsteve posted on Dec 19 2005 at 12:28 AM said:
Will you be making linux developer releases of the SDL 1.2.9 code with H/W Blitter support (when it becomes available)???

That is the idea ;). The code will go into Open2x's CVS as soon as it builds cleanly (been keeping the big hacks out of CVS as people are using that code to make there own libs sets and nobody wants cutting edge flaky code in there libs). I will release the libs via the project when there in a fit state to be used by all.

SDL 1.2.9 for the GP2X is still a little rough for prime time but it's almost there, with support for some accelerated functions like SDL_BlitSurface, SDL_FillRect and friends it should start to look very tasty. Add in scalar support (more long term) and it's looking positively healthy (for SDL that is).
 
Last edited by a moderator:
DJWillis posted on Dec 18 2005 at 05:07 PM said:
timbobsteve posted on Dec 19 2005 at 12:28 AM said:
Will you be making linux developer releases of the SDL 1.2.9 code with H/W Blitter support (when it becomes available)???

That is the idea ;). The code will go into Open2x's CVS as soon as it builds cleanly (been keeping the big hacks out of CVS as people are using that code to make there own libs sets and nobody wants cutting edge flaky code in there libs). I will release the libs via the project when there in a fit state to be used by all.

SDL 1.2.9 for the GP2X is still a little rough for prime time but it's almost there, with support for some accelerated functions like SDL_BlitSurface, SDL_FillRect and friends it should start to look very tasty. Add in scalar support (more long term) and it's looking positively healthy (for SDL that is).

Will these SDL libs also be made to work with HH when it becomes available? Just curious, I don't think anything I ever do will require that sort of thing.
 
Last edited by a moderator:
Ravnos posted on Dec 19 2005 at 01:16 AM said:
Will these SDL libs also be made to work with HH when it becomes available? Just curious, I don't think anything I ever do will require that sort of thing.

If you wanted SDL on HH (ARM-ELF) then the best solution would be to port SDL over to use SDK2X (the HH SDK) and the raw underlying hardware. The concepts and a good chunk of the code should be portable from the GP2X Linux SDL given time. I.e. it’s a distinct maybe ;).
 
Last edited by a moderator:
Good to hear that SDL 1.2.9 will be released under Open2X in the future. Does Open2X only do releases over CVS or do you also do tarball releases?

I have never been to good with CVS or SVN so a tarball would be awsome.
 
keep in mind that sdk2x does not has any support for threads in it. There are some sdl stuff and extensions (like mixer) that will need threads. The only thing useful of sdl would be the gfx routines. . .
 
timbobsteve posted on Dec 19 2005 at 02:26 AM said:
Good to hear that SDL 1.2.9 will be released under Open2X in the future. Does Open2X only do releases over CVS or do you also do tarball releases?

I have never been to good with CVS or SVN so a tarball would be awsome.

When stuff is ready pre-built libs and source tars will be put up, what is in CVS (while it works) is not IMHO ready or good/funky enough ;).
 
Last edited by a moderator:
Squidge posted on Dec 18 2005 at 11:43 PM said:
slygamer posted on Dec 18 2005 at 11:54 AM said:
What about malloc'ed memory? How do we find the physical address of that?

Simple answer: You can't.
More advanced answer: It's possible, but may not work all the time, so definitely not recommended.
So we cannot use the hardware blitter for any image that has been malloc'ed. The image data must exist in the upper 32MB of memory.

I still cannot get the hardware blitter to work for me, so I'm obviously doing something stupidly wrong.
 
Last edited by a moderator:
paeryn posted on Dec 19 2005 at 05:39 AM said:
Just tried a basic test blitting a 32x32 16bit box 1000 times (basic src->dst copy), if I've got my numbers right...

non-optimized s/w = 0.46 seconds,
gcc -O3 s/w = 0.38 seconds.
non-optimized h/w = 0.03 seconds

gcc optimizes the h/w blit badly since it doesn't know the importance of setting MESGSTATUS last, but it was only a test run.


wait a second. Isn't that...

32x32x16x1000/0.03

=546 megabits per second fillrate.

That's rather fast.
 
Last edited by a moderator:
slygamer posted on Dec 19 2005 at 01:11 PM said:
So we cannot use the hardware blitter for any image that has been malloc'ed. The image data must exist in the upper 32MB of memory.
The problem is that the blitter needs to know the physical address of the source data. Stuff that get malloced through the OS goes through the virtual table so you can't find the physical address from the pointer.
Reserve some memory after the frame buffer and write an incremental malloc for you images. Make sure the region is mmapped too so you can write to it using the CPU.
slygamer posted on Dec 19 2005 at 01:11 PM said:
I still cannot get the hardware blitter to work for me, so I'm obviously doing something stupidly wrong.

You need to enable fast IO:
gp2XHardware.c000regss[0x0904>>1] |= 1<<10; // enable fast IO

And set MESGSTATUS to start it off
// activate!
gp2XHardware.e002regsl[0x0034 >> 2] = 1;

If they don't work, try going through you blitter settings, make sure your source & dest are correct, make sure you've told it to use the frame buffer area, make sure you're using the right ROP (0xCC).
 
Last edited by a moderator:
Galleon posted on Dec 15 2005 at 05:20 AM said:
Still is. What do you think a graphics card is?
Point is, the amiga was the first machine to incorporate hardware blitter ;)
 
Last edited by a moderator:
icurafu posted on Dec 19 2005 at 01:23 PM said:
paeryn posted on Dec 19 2005 at 05:39 AM said:
Just tried a basic test blitting a 32x32 16bit box 1000 times (basic src->dst copy), if I've got my numbers right...

non-optimized s/w = 0.46 seconds,
gcc -O3 s/w = 0.38 seconds.
non-optimized h/w = 0.03 seconds

gcc optimizes the h/w blit badly since it doesn't know the importance of setting MESGSTATUS last, but it was only a test run.


wait a second. Isn't that...

32x32x16x1000/0.03

=546 megabits per second fillrate.

That's rather fast.

34 million pixels/s, the CPU would have been running from cache so only the display and blitter should have been hitting the memory bus. Blitter accesses are 32bit so it _could_ be handling 2 pixels per clock (ie second pixel is read at same time as first - potential memory access saved). It's only doing a basic read/write so best case would be averaging 1 pixel per clock.

Then again those timings might be a bit off. Timing is from the MMSP's timer (7.3728MHz).
167440 ticks for the h/w and 3412159 ticks for the non-opt s/w.
 
Last edited by a moderator:
Back
Top