GP2X 3d Engine Demonstration Challenge


How did you deal with sprites that were bigger than your safe area off the side of the screen comming back on the opposite side? ( I suppose if its big enough then you don't )

Did you also use the protection unit to stop drawing off the bottom?
 
MadDog posted on May 24 2006 at 10:47 AM said:
Dzz, do you know if the display width value register has to be the same as the physical width or if its a stride? If its a stride value then your be able give your self a gardband cutting down on required clipping, not sure if that would help. Also do you know the cost of a memory exception? You could setup the protection unit to stop the rendering of the current tri on the bottom edge, removing a clip plane you need to worry about. Just some crazy ideas of the top of my head. :)

The display width can be larger than the physicall width, but I don't think this is evry relevant to clipping, at least in a general purpose renderer : clipping is here to save you from rendering things that are not usefull. It's cost is not important compared to the cost of computing so much points (especially when the polygones are near the camera : the projection can give you very _big_ polygons - you don't want to draw so many pixels).

Also, you need clipping for polygons that can be both behind and before the camera, anyway.

So, using this trick is only OK for a spinning cube, I guess.

As to relying on the protection unit, despite the fact that it would be very slow, this is not techniaclly feasable to clip in the X direction (it would require a bound 'segment' for each scanline).

Cmon guys, clipping is our friend ! :)
 
Last edited by a moderator:
MadDog posted on May 24 2006 at 10:43 AM said:
How did you deal with sprites that were bigger than your safe area off the side of the screen comming back on the opposite side? ( I suppose if its big enough then you don't )

Did you also use the protection unit to stop drawing off the bottom?

I've never used the protection unit for such things, no. The only thing I've done is said "well, maximum sprite size is X, so screen size+(X*2) = virtual screen width" and the same with the height.

I suppose an assembler sprite blitter would be quicker when the sprite is only partially on screen, but being able to just draw the complete sprite everytime made the code a *lot* simpler, and probably speeded up the code for the case when the sprite was fully on the screen, as it didn't have to do loads of bounds checking.

For 3D code however, I must agree with rixed - unless what your drawing is incredibly simple, then clipping is going to be faster the calculating all those pixels that your not going to draw.
 
Last edited by a moderator:
As the other guys said, having a larger render buffer can take care of this. It has a couple of other advantages as well: First, if you make its width a power of 2 (say 512 or even 1024 since there's lots of memory to work with), you get a tiny speedup when computing a pixel location because you can use a shift instead of a multiply. Second, if this buffer is in cacheable memory some rendering operations can be speeded up. The disadavantage of course is the cost per frame of copying the off-screen buffer to the real "video" memory, which is something like two milliseconds.

I had been working on triangle clipping for quite a while but the code got so long and ugly that I put it on hold for now. In these demos I'm doing the clipping in the rasterizer, with a special case triangle rasterizer version for triangles that "need clipping". Basically, just adjusting the top scanline if needed, adjusting the left pixel and width of a scanline, then stopping when the bottom is hit. It's probably not as efficient as doing it earlier but it was pretty easy.
 
Dzz posted on May 24 2006 at 03:35 PM said:
I had been working on triangle clipping for quite a while but the code got so long and ugly that I put it on hold for now. In these demos I'm doing the clipping in the rasterizer, with a special case triangle rasterizer version for triangles that "need clipping". Basically, just adjusting the top scanline if needed, adjusting the left pixel and width of a scanline, then stopping when the bottom is hit. It's probably not as efficient as doing it earlier but it was pretty easy.


You should give a try to clipping in 3D : this is very easy (just do a 'clip_by_plane' function, and use it for each frame edge), and you don't have to project vertex that are not seen.
 
Last edited by a moderator:
Hey are you guys doing Divides using Subtraction method or Newton-Raphson ? I ask because NR on the ARM is upto 3 times faster than trail sub method but I am having problems understanding the error bounds theory of NR.. I have the basic theory down for iterating and initial estimate but correcting error is a bit tricky.

Anyway any hints or suggestions?

Cheers.

Matt
 
MSweeney posted on May 24 2006 at 02:47 PM said:
Hey are you guys doing Divides using Subtraction method or Newton-Raphson ? I ask because NR on the ARM is upto 3 times faster than trail sub method but I am having problems understanding the error bounds theory of NR.. I have the basic theory down for iterating and initial estimate but correcting error is a bit tricky.

Anyway any hints or suggestions?

Cheers.

Matt
I'm using a subtraction method. There's a sweet-looking approximate one-over-z implementation in the Vincent stuff that uses two iterations of NR that I'm thinking of stealing for perspective-correct mapping needs.

I'm not sure what method the divide routine supplied by gcc uses.
 
Last edited by a moderator:
Dzz posted on May 24 2006 at 02:40 PM said:
MSweeney posted on May 24 2006 at 02:47 PM said:
Hey are you guys doing Divides using Subtraction method or Newton-Raphson ? I ask because NR on the ARM is upto 3 times faster than trail sub method but I am having problems understanding the error bounds theory of NR.. I have the basic theory down for iterating and initial estimate but correcting error is a bit tricky.

Anyway any hints or suggestions?

Cheers.

Matt
I'm using a subtraction method. There's a sweet-looking approximate one-over-z implementation in the Vincent stuff that uses two iterations of NR that I'm thinking of stealing for perspective-correct mapping needs.

I'm not sure what method the divide routine supplied by gcc uses.

Hey thanks, whats the 'Vincent stuff?' something I can download from the site?

Matt
 
Last edited by a moderator:
Just to let you know that my little gpu940 project is now workable : it compile both on PC and GP2X, and on GP2X all rendering, clipping and projections are done by the 940. video buffer swapping is done under interrupt, and the OSD display some perf meters.

Those are badly needed, sadly, because the whole thing is very slow : for a single true-perspective textured polygone (size of the screen), it needs 2 VBL to render a frame (75% of CPU time into ploting functions).

So, after the advertising, a question : the 920 is clocked at 100Mhz under gp2xmenu. What about the default clocking of the 940 ? Is it 100MHz by default also ?

URL with CVS browsing here : http://gna.org/projects/gpu940
 
rixed posted on May 25 2006 at 03:38 PM said:
Just to let you know that my little gpu940 project is now workable : it compile both on PC and GP2X, and on GP2X all rendering, clipping and projections are done by the 940. video buffer swapping is done under interrupt, and the OSD display some perf meters.

Those are badly needed, sadly, because the whole thing is very slow : for a single true-perspective textured polygone (size of the screen), it needs 2 VBL to render a frame (75% of CPU time into ploting functions).

So, after the advertising, a question : the 920 is clocked at 100Mhz under gp2xmenu. What about the default clocking of the 940 ? Is it 100MHz by default also ?

URL with CVS browsing here : http://gna.org/projects/gpu940
Hey, getting something working is a great starting point!

What file has the scanline inner loop?
 
Last edited by a moderator:
Dzz posted on May 26 2006 at 12:01 AM said:
What file has the scanline inner loop?

Depends on the rendering type.
Most of it is in bin/poly.c

draw_line_uv perform uv texturing, draw_line_uvi does uv texturing + lighting, etc...

Only the flat rendering type (draw_line_c) is done in bin/draw_line.gp2x.S

Anyway, I measured the time consumed by the division routine : when rendering flat polygons, divs eats nearly 70% of cpu time. When texturing, divs eats 20%.

So, as soon as I have rewritten all line drawing routines into assembly, I dig myself into division algorithms (I don't even remember how to do a division by hand).

For a start I took your div routine, and extended it to 64 bits. Then all div routines are using this all purpose 64 bits division. Yes, this is weird, but it's not that easy to replace all libgcc divisions by a single one :)
 
Last edited by a moderator:
Dzz posted on May 25 2006 at 12:47 PM said:
MSweeney posted on May 25 2006 at 01:41 PM said:
Hey thanks, whats the 'Vincent stuff?' something I can download from the site?

Matt
Vincent is a software library; the author is working on porting it to the gp2x. See:

http://ogl-es.sourceforge.net/
That's me, BTW... ;) ...in case you have questions or so...
 
Last edited by a moderator:
About SDGL

You don't have to change anything except the Makefile to make it work for GP2X, as it runs on top of SDL. But by some strange reason lighting is brighter than in Mesa or in hardware OpenGL and I've been too lazy those days to check out the reason.
 
Hi, so how is everyone doing with thier code? Here is a little update on mine.
Been slowed down a bit as I was ill the past couple weeks and been busy at work.

( GPU == 940 cpu )

Most of the work has been on my GPU code.....
Lost texturing as i'm coding my own tri rendering, dumping the code I found on the net.
All the upper 32megs is now cached with a protection hole at 16megs to stop me from killing the 940 code the OS has there. This 32megs is managed now by a vram mem man on the 920.

At startup I create a mem block of 32megs, pop a hole at the start for the GPU code and stack and another hole at 16megs to stop me from allocating that mem for textures, fonts or anything else I put there. When the GPU starts up it sets up the protection unit so that all 32megs is cached and the mem hole at 16megs is protected so that any bugs can't scribble over it. Also set the HW regs address to be uncached. The rest of the mem range is not setup and so I beleave will be protected by default.

When I flip the display I now have to drain the cache, seems to be ok. Means that my FB ops should be a lot quicker.

Written my own untextured no shading tri renderer, the easiest type to do. Nice little trick on rendering the scan lines, I have 320 mov instructions to render the scanline. I tweek the start address then jump in to the block of code so that only the required pixels are written. This means I have only one jmp per scanline instead of one every pixel. :)

Sorted out my transform code so i've now got a propper camera.
No clipping yet, i'm going to do this proper instead of in the tri renderer. Not sure if to do the clipping on the 920 before I pass the tri to the GPU. I'm using the GPU as a 2d renderer only, T&L is on the 920. This should give me a good balance. The 920 was spending most of its time waiting for the GPU to catch up.

Here is a link to the box demo. Runs at 60fps, most of the time. Its a debug build with no optimisation, although most of the bits that would be slow on the GPU is in hand coded asm.

cube.zip
 
Even if it's maybe too late, I decided to post here some links to my old 3d engine ported from GP32 to my brand new GP2X these days:

http://www.gp2x.de/cgi-bin/cfiles.cgi?0,0,0,0,38,1619
http://www.freewebs.com/optimus6128/ZeEngineGP2X.htm

Optimus
p.s. I have also posted this in the news section.

Thats very impressive! Way better than mine! Cool, i was slowing down a bit, you've given me a boot up the arse to get back to it. :)

Is it 16bit or palletised?
 
Last edited by a moderator:
Thats very impressive! Way better than mine! Cool, i was slowing down a bit, you've given me a boot up the arse to get back to it. :)

Is it 16bit or palletised?

Thanks!

It's 16bit. The gouraud shading uses look up tables of 256 shades of colors that are actually 16bit. I did the last one instead of a full featured RGB gouraud shading, because it was the first I thought, would be faster and I could also precalculate some nifty color palletes for the gouraud. I am wondering if 8bit could be faster, but you know something? Recently I realized that writting integers would be quite faster for this machine, than shorts or bytes. In some other 2d effects I have in my code, calculating the colors of two 16bit pixels in two variables that I ORed them in one 32bit integer which I write directly to the vram, gave some great speed boost! I was thinking if I could the same with the polygon rasterizer, though it might need a bit diferrent and more complicated approach because one raster line might not be start or end alligned. Another thing that I might do to optimize the rasterizer. If I am too brave to rewrite it from scratch :p

I couldn't download your cube.zip demo but now I think I can.

Also, I am really wondering (because I am new in the GP2X) and maybe you could tell me:

1) Can the additional gfx copprocesor be used to run any code? Would it be benefficial for gfx code (to rasterize and send directly to the lcd)? I didn't knew it can be used this way. I guess there will be needed some low level programm to check it. Any docs?

2) How do I know in which clock speed my code runs. In my current engine, I guess it must be 200Mhz because the speed of the preview is already double than in my GP32. But I have to know and know how to overclock through my code. Any references for this one?

3) Am I sure that my arrays and variables are 32bit alligned? Should I have some switch in my makefile or compiler to be sure everything is alligned? I just want to be sure I am not making anything wrong and this engine doesn't receive it's full potentional.

Maybe I'll post these questions as a new thread in the coders area too..
 
Last edited by a moderator:
From reading other posts, the 940 can run whatever code you want, and can write to the framebuffer (as well as interface with the blitter and associated video acceleration hardware), but the main restriction is that it has no MMU, so it can't access memory < 32MB with the same virtual mapping as the linux program you'd be running there, so in practice, only memory > 32MB is usable. Also, you can't use linux system calls or anything like that from it, so interfacing with your main program is usually done with some shared memory above the 32MB mark that both processors can access.

Just keep in mind it only has 4K+4K cache compared to 16+16 on the 920, so it would be best to design algorithms to fit in the reduced cache as much as possible. I think there's the ability to lock sections of the cache, which may be beneficial to avoid flushing more important contents with one-time accesses when things get tight.
 
1) Can the additional gfx copprocesor be used to run any code? Would it be benefficial for gfx code (to rasterize and send directly to the lcd)? I didn't knew it can be used this way. I guess there will be needed some low level programm to check it. Any docs?

2) How do I know in which clock speed my code runs. In my current engine, I guess it must be 200Mhz because the speed of the preview is already double than in my GP32. But I have to know and know how to overclock through my code. Any references for this one?

3) Am I sure that my arrays and variables are 32bit alligned? Should I have some switch in my makefile or compiler to be sure everything is alligned? I just want to be sure I am not making anything wrong and this engine doesn't receive it's full potentional.

Maybe I'll post these questions as a new thread in the coders area too..

What gfx coprocessor do you speak about ? If it's the 940, there already is many tutos in these forums.
If your are speacking about the MMSP 2d coprocessor, there are some raster-ops hardwared but I never digged this, although there certainly have some usefull features.

To set your clockspeed, you can use the code given in the wiki, it works out of the box. You should run at 200MHz on the 920 already, but you can easily set it up to 250MHz.

Your arrays and variables should be properly aligned, except if you use 'clever' GCC tricks.

Sory for such a crude answer, but I can't stand web text-areas.

:)
 
Last edited by a moderator:
Back
Top