divineg@prism.CS.ORST.EDU (04/21/91)
Here's my situation: I've coded and coded and coded and finally found a way to crudely rotate 3 dimensional objects ... now all of you wizards out there, what's the quickest way to draw a line? I'd like to do it with the Blitter (I can use the processer to calculate while I draw lines) or is it better to use the 68'? By the way, I'm using C & asm (pretty original, huh?). Please post your responses, I'm interested in what kind of discussion follows..... Yenivid Edalg 8^) (E-Mail me at divineg@prism.cs.orst.edu)
morgan@cory.Berkeley.EDU (Alan Morgan) (04/22/91)
In article <1991Apr21.081925.4722@lynx.CS.ORST.EDU> divineg@prism.CS.ORST.EDU writes: > > Here's my situation: > >I've coded and coded and coded and finally found a way to crudely rotate >3 dimensional objects ... now all of you wizards out there, what's the >quickest way to draw a line? I'd like to do it with the Blitter (I can >use the processer to calculate while I draw lines) or is it better to use >the 68'? By the way, I'm using C & asm (pretty original, huh?). > Please post your responses, I'm interested in what kind of >discussion follows..... If you haven't already you should pick up a copy of Foley, van Dam, Feiner, and Hughes _Computer Graphics: Principles and Practice_ 2nd Ed. which tells you everything you ever wanted to know about 2D, 3D, 9D (haven't checked, but I'm sure its in there :) ) graphics. They list a line drawing method invented by a man named Bressenham which uses no floating point calculations, only integer multiplications by 2. Not being a Blitter guru (or even a Blitter incompetent, my knowledge is far less) I can't tell you if this is workable, but you should give it a try. Incidently, if you are trying to get blinding speed you probably don't want to spend your entire life juicing up the line drawing algorithm for a coupla reasons: 1. Other things, such as rotation and clipping are much slower and thus should be accorded more attention 2. If you do polygon fills (i.e. solid 3D objects) you will only ever need to draw horizontal lines. *THESE* you can make really fast using the Blitter. > >Yenivid Edalg 8^) >(E-Mail me at divineg@prism.cs.orst.edu) Alan Morgan
dillon@overload.Berkeley.CA.US (Matthew Dillon) (04/22/91)
In article <1991Apr21.081925.4722@lynx.CS.ORST.EDU> divineg@prism.CS.ORST.EDU writes: > > Here's my situation: > >I've coded and coded and coded and finally found a way to crudely rotate >3 dimensional objects ... now all of you wizards out there, what's the >quickest way to draw a line? I'd like to do it with the Blitter (I can >use the processer to calculate while I draw lines) or is it better to use >the 68'? By the way, I'm using C & asm (pretty original, huh?). > Please post your responses, I'm interested in what kind of >discussion follows..... > >Yenivid Edalg 8^) >(E-Mail me at divineg@prism.cs.orst.edu) Hmm. Well, 3D is actually easy if you use standard matrix theory, any good graphics book will have it. It is all extremely general and you can do practically *anything* with it (4x4 matrices). Once you get it working in the general sense you can optimize the *ell out of the code, remove whole chunks of calculations that do not apply. Word to the wise on 3D: stick with vectors instead of polar coordinates if you want to easily code arbitrary view points & movement. You also avoid arctan completely with vectors and sin/cos are not only relegated to table lookups, you can precalculate most of what you need once per frame instead of for each object. The problem with polar coordinates is that they are not uniform -- for example, the direction represented by phi=+/-90 degrees causes theta to go wild (theta can become anything without effecting the direction). Back to line drawing: It has been shown that the processor can draw short lines much faster than the blitter can due to blitter setup overhead. I believe the breakoff point is somewhere around 150 pixels. I'd stick with standard Move/Draw in a modular routine until you get to the point where you really need to optimize, unless you have already written optimized line drawing routines, in which case you just use those. -Matt -- Matthew Dillon dillon@Overload.Berkeley.CA.US 891 Regal Rd. uunet.uu.net!overload!dillon Berkeley, Ca. 94708 USA
dvljrt@cs.umu.se (Joakim Rosqvist) (04/22/91)
In article <1991Apr21.081925.4722@lynx.CS.ORST.EDU> divineg@prism.CS.ORST.EDU writes: > > Here's my situation: > >I've coded and coded and coded and finally found a way to crudely rotate >3 dimensional objects ... now all of you wizards out there, what's the >quickest way to draw a line? I'd like to do it with the Blitter (I can >use the processer to calculate while I draw lines) or is it better to use >the 68'? By the way, I'm using C & asm (pretty original, huh?). > Please post your responses, I'm interested in what kind of >discussion follows..... > Here is a part of the source i use when i want *fast* lines. It uses the blitter and writes directly to the DFF regs (no flames please, i *did* call Ownblitter first) There are som things left out, like where how to find the address of the bitplane to draw in, and where the coordinates comes from, but that should be easy to fill in. /$DR.HEX$ DMACONR=2 BLTCON0=$40 BLTCON1=$42 BLTAMOD=$64 BLTBMOD=$62 BLTCMOD=$60 BLTAPT=$50 BLTCPT=$48 BLTDPT=$54 BLTADAT=$74 BLTBDAT=$72 BLTAFWM=$44 BLTSIZE=$58 OwnBlitter=-456 DisownBlitter=-462 width=80 ;80 bytes = 640 pixels Draw_all_lines: move.l 4.w,a6 move.l (a6),a6 move.l (a6),a6 ;get base of Gfxlib jsr OwnBlitter(a6) lea $dff000,a6 move #$8000,BLTADAT(a6) move #-1,BLTAFWM(a6) move #width,BLTCMOD(a6) move #$FFFF,BLTBDAT(a6) ;$FFFF=draw , $0000=clear ;These values are the same for all lines, no need to tell ;the blitter about them more than once move.l <startaddress of bitplane>,a0 moveq #<numlines-1>,d7 bsr.s drawem move.l 4.w,a6 move.l (a6),a6 move.l (a6),a6 jmp DisOwnBlitter(a6) drawem: move <X0>,d0 move <Y0>,d1 move <X1>,d2 move <Y1>,d3 moveq #width,d4 mulu d1,d4 ;This could be sped up by reading a table with values ;0,width,width*2,width*3 etc. moveq #-16,d5 and d0,d5 lsr #3,d5 add d5,d4 add.l a0,d4 moveq #0,d5 sub d1,d3 roxl.b #1,d5 tst d3 bge.s y2gy1 neg d3 y2gy1: sub d0,d2 roxl.b #1,d5 tst d2 bge.s x2gx1 neg d2 x2gx1: move d3,d1 sub d2,d1 bge.s dygdx exg d2,d3 dygdx: roxl.b #1,d5 move.b table(pc,d5.w),d5 add d2,d2 wait: btst #6,DMACONR(a6) bne.s wait move d2,BLTBMOD(a6) sub d3,d2 bge.s signn1 or.b #$40,d5 signn1: move d2,BLTAPT+2(a6) sub d3,d2 move d2,BLTAMOD(a6) and #15,d0 ror #4,d0 or #$bca,d0 move d0,BLTCON0(a6) move d5,BLTCON1(a6) move.l d4,BLTCPT(a6) move.l d4,BLTDPT(a6) addq #1,d3 lsl #6,d3 addq #2,d3 move d3,BLTSIZE(a6) ;GO! dbra d7,drawem ;do next line rts table: dc.b 1,17,9,21,5,25,13,29
spence@cbmvax.commodore.com (Spencer Shanson) (04/23/91)
In article <1991Apr22.122442.25505@cs.umu.se> dvljrt@cs.umu.se (Joakim Rosqvist) writes: > [stuff deleted] >Here is a part of the source i use when i want *fast* lines. >It uses the blitter and writes directly to the DFF regs >(no flames please, i *did* call Ownblitter first) Great! But you also need to WaitBlit() after owning the blitter (just to be safe), and just before starting to write to any of the blitter registers. >[stuff deleted] > jsr OwnBlitter(a6) > > lea $dff000,a6 ** You need to WaitBlit() here > move #$8000,BLTADAT(a6) > [more stuff deleted] >wait: btst #6,DMACONR(a6) > bne.s wait ** Better to use WaitBlit(), which knows about various Agnus hardware bugs ** (see Autodocs for more details) -- --------------------------------------------------------------------------- Spencer Shanson - Amiga Software Engineer | email: spence@commodore.COM | or uunet!cbmvax!spence All opinions expressed are my own, and do not | "You know my methods. Apply (necessarily) represent those of Commodore. | them" -- Sir Arthur Conan | Doyle - 'The Sign of Four'
dvljrt@cs.umu.se (Joakim Rosqvist) (04/25/91)
In article <20884@cbmvax.commodore.com> spence@cbmvax.commodore.com (Spencer Shanson) writes: > > >In article <1991Apr22.122442.25505@cs.umu.se> dvljrt@cs.umu.se (Joakim Rosqvist) writes: >> [stuff deleted] >>Here is a part of the source i use when i want *fast* lines. >>It uses the blitter and writes directly to the DFF regs >>(no flames please, i *did* call Ownblitter first) > >Great! But you also need to WaitBlit() after owning the blitter (just to be >safe), and just before starting to write to any of the blitter registers. > >>[stuff deleted] >> jsr OwnBlitter(a6) >> >> lea $dff000,a6 > >** You need to WaitBlit() here Sorry, I though Ownblitter meant 'when you have called this function, you own the blitter' > >> move #$8000,BLTADAT(a6) >> [more stuff deleted] >>wait: btst #6,DMACONR(a6) >> bne.s wait > >** Better to use WaitBlit(), which knows about various Agnus hardware bugs >** (see Autodocs for more details) The issue here was fast lines, if I could consider calling a ROM-routine I could just as well have called 'drawline' (or sth, I've never used it) in gfxlib in the first place. BTW, i read in another article that using the blitter on short lines should be a disadvantage because of the long setup-time. The breakoff was given to about 150 pixels. I don't know what processor was intended but I made a little test in the following environment: Program ran from fastmem, 68000 used, 1 bitplane 640x256 shown and no interrupts enabled. With the blitter i got 738000 pixels/second and 23 microsecond startup-time which equals 17 extra pixels on every line. Lines between 1..25 pixels all take the same time. The is beacuse the setup-time was really 58 micros but for longer lines some of this could be done while the blitter was drawing the previous line. With the 68000 i could get about 150000 pixels/sec and 24 micros 'setup' (I clocked a MAC SE/30 using quickdraw to 110000 pix/sec giggle..) This means that the breakoff(=the number of pixels where using the blitter or the 68000 would take the same time) would be at 5 pixels. /$DR.HEX$
elg@elgamy.RAIDERNET.COM (Eric Lee Green) (04/26/91)
From article <1991Apr24.203219.22776@cs.umu.se>, by dvljrt@cs.umu.se (Joakim Rosqvist): > Sorry, I though Ownblitter meant > 'when you have called this function, you own the blitter' Right. The system will no longer try to use the blitter. However, the blitter might still be doing something itself. The fact that OwnBlitter doesn't try to WaitBlit means that you can overlap some of your own processing with the blitter's operation, i.e. do all your calculations before calling WaitBlit(). >>** Better to use WaitBlit(), which knows about various Agnus hardware bugs >>** (see Autodocs for more details) > The issue here was fast lines, if I could consider calling a ROM-routine WaitBlit() isn't *THAT* bad! > BTW, i read in another article that using the blitter on short lines > should be a disadvantage because of the long setup-time. The breakoff > was given to about 150 pixels. I don't know what processor was intended > but I made a little test in the following environment: > > Program ran from fastmem, 68000 used, 1 bitplane 640x256 shown and > no interrupts enabled. > With the blitter i got 738000 pixels/second and 23 microsecond startup-time > which equals 17 extra pixels on every line. Lines between 1..25 pixels > all take the same time. The is beacuse the setup-time was really 58 micros > but for longer lines some of this could be done while the blitter was > drawing the previous line. > With the 68000 i could get about 150000 pixels/sec and 24 micros 'setup' Note that using the blitter to draw lines into a four bitplane screen takes four times longer than into one bitplane. Four times the setup. Four times the drawing. Meanwhile, extending your one-bitplane CPU-driven whatzit to four bitplanes basically consists of putting in three more BSET instructions into your loop. Which does NOT increase the overhead by four times, and affects setup time very little (basically have to MOVEM four bitplane pointers into address registers, rather than a single bitplane pointer). You might end up with, say, 170000 pixels/second + 92 microsecond setup time for the blitter version, and 130000 pixels/sec with 25 us setup for the CPU version. The tradeoffs, for short lines, then become much more obvious, though the blitter is still fastest for long lines on unaccellerated Amigas. (on accelerated ones, no way!). I *DO* assume that you're using assembly language for all of this? And you can also unroll loops for faster drawing. But I suspect you already knew that. So -- if you're drawing into one bitplane, the speed advantage is obvious for all line lengths. If you were drawing into 4 or more bitplanes, though, things become quite different. I think Jez San has done some timings on BIX of the 4-bitplane situation. I'll try to fetch them for you. -- Eric Lee Green (318) 984-1820 P.O. Box 92191 Lafayette, LA 70509 elg@elgamy.RAIDERNET.COM uunet!mjbtn!raider!elgamy!elg Looking for a job... tips, leads appreciated... inquire within...
spence@cbmvax.commodore.com (Spencer Shanson) (04/26/91)
In article <1991Apr24.203219.22776@cs.umu.se> dvljrt@cs.umu.se (Joakim Rosqvist) writes: >In article <20884@cbmvax.commodore.com> spence@cbmvax.commodore.com (Spencer Shanson) writes: >> >> >>In article <1991Apr22.122442.25505@cs.umu.se> dvljrt@cs.umu.se (Joakim Rosqvist) writes: >>> [stuff deleted] >>Great! But you also need to WaitBlit() after owning the blitter (just to be >>safe), and just before starting to write to any of the blitter registers. >> >>** You need to WaitBlit() here > >Sorry, I though Ownblitter meant >'when you have called this function, you own the blitter' > You do own the blitter, but that does not mean that the last blit has finished yet. This will be especially true on a faster CPU and a large blit. Even your own code does its final blit and then disowns it. >>** Better to use WaitBlit(), which knows about various Agnus hardware bugs >>** (see Autodocs for more details) > >The issue here was fast lines, if I could consider calling a ROM-routine >I could just as well have called 'drawline' (or sth, I've never used it) >in gfxlib in the first place. > That's up to you, just don't expect the code to run on every Amiga. At the very least, take into account the hardware bugs described in the autodocs. >BTW, i read in another article that using the blitter on short lines >should be a disadvantage because of the long setup-time. The breakoff >was given to about 150 pixels. I don't know what processor was intended >but I made a little test in the following environment: > >Program ran from fastmem, 68000 used, 1 bitplane 640x256 shown and >no interrupts enabled. >With the blitter i got 738000 pixels/second and 23 microsecond startup-time >which equals 17 extra pixels on every line. Lines between 1..25 pixels >all take the same time. The is beacuse the setup-time was really 58 micros >but for longer lines some of this could be done while the blitter was >drawing the previous line. >With the 68000 i could get about 150000 pixels/sec and 24 micros 'setup' >(I clocked a MAC SE/30 using quickdraw to 110000 pix/sec giggle..) >This means that the breakoff(=the number of pixels where using the blitter >or the 68000 would take the same time) would be at 5 pixels. > You don't say if the lines are arbitrary direction. Sure, for short horizontal lines, you would be better off using the CPU, but I doubt that's the case for lines of any angle of more than a few pixels. >/$DR.HEX$ -- --------------------------------------------------------------------------- Spencer Shanson - Amiga Software Engineer | email: spence@commodore.COM | or uunet!cbmvax!spence All opinions expressed are my own, and do not | "You know my methods. Apply (necessarily) represent those of Commodore. | them" -- Sir Arthur Conan | Doyle - 'The Sign of Four'
dvljrt@cs.umu.se (Joakim Rosqvist) (04/28/91)
>>BTW, i read in another article that using the blitter on short lines >>should be a disadvantage because of the long setup-time. The breakoff >>was given to about 150 pixels. I don't know what processor was intended >>but I made a little test in the following environment: >> >>Program ran from fastmem, 68000 used, 1 bitplane 640x256 shown and >>no interrupts enabled. >>With the blitter i got 738000 pixels/second and 23 microsecond startup-time >>which equals 17 extra pixels on every line. Lines between 1..25 pixels >>all take the same time. The is beacuse the setup-time was really 58 micros >>but for longer lines some of this could be done while the blitter was >>drawing the previous line. >>With the 68000 i could get about 150000 pixels/sec and 24 micros 'setup' >>(I clocked a MAC SE/30 using quickdraw to 110000 pix/sec giggle..) >>This means that the breakoff(=the number of pixels where using the blitter >>or the 68000 would take the same time) would be at 5 pixels. >> > >You don't say if the lines are arbitrary direction. Sure, for short horizontal >lines, you would be better off using the CPU, but I doubt that's the case for >lines of any angle of more than a few pixels. > Of course, I gave you the figures to show that there really is no point in using the 68000. The value 150000 corresponds to an 22-degree line Lines that are 0 or 90 degress will be the fastest and 45 deg the slowest so i used 22 as an in-between. And.. the 68000 will always win over the blitter for horisontal lines. This is because it can do a: label: move.l d7,(a0)+ dbra d0,label Where a0 is a pointer in the bitplane and d7 is $FFFFFFFF. The poor blitter would read a word, set a bit, write it back then read it again.. 16 times without knowing it's the same word :-( /$DR.HEX$
dvljrt@cs.umu.se (Joakim Rosqvist) (04/29/91)
>WaitBlit() isn't *THAT* bad! The instructions jsr waitblit(a6) and the rts in the end of that routine takes 6 us to execute all by themselves and I had 23 us setup- It would at least double my setup-time to use waitblit. (I'll disassemble and see what it really does) >> With the blitter i got 738000 pixels/second and 23 microsecond startup-time >> all take the same time. The is beacuse the setup-time was really 58 micros >> but for longer lines some of this could be done while the blitter was >> drawing the previous line. >> With the 68000 i could get about 150000 pixels/sec and 24 micros 'setup' > >Note that using the blitter to draw lines into a four bitplane screen takes >four times longer than into one bitplane. Four times the setup. Four times >the drawing. Meanwhile, extending your one-bitplane CPU-driven whatzit to >four bitplanes basically consists of putting in three more BSET >instructions into your loop. Which does NOT increase the overhead by four >times, and affects setup time very little (basically have to MOVEM four >bitplane pointers into address registers, rather than a single bitplane >pointer). You might end up with, say, 170000 pixels/second + 92 microsecond >setup time for the blitter version, and 130000 pixels/sec with 25 us setup >for the CPU version. The tradeoffs, for short lines, then become much more >obvious, though the blitter is still fastest for long lines on >unaccellerated Amigas. (on accelerated ones, no way!). > >I *DO* assume that you're using assembly language for all of this? > Is there anything else :-) Interesting with 4-bitplane lines.. I find 738000/4=185000 pix/sec And for the CPU it will slow down much more than you say, ironically enough the reson is that the routines is so optimized that the BSET is actually a quite large piece in the inner loop. As for now I have about 45 cycles per pixel (292 degrees) It would increase to about 80 in 4 bitplanes giving 86000 pix/sec. Still big advantages using the blitter. Here is my inner loop: BSET d7,(a0) ;Plot pixel. 12 cycles ADD d6,a0 ;Go to the next scanline. 8 cycles SUB d3,d5 ;This routine always goes one pixel down and sometimes ;(every second time for 292 deg) one pixels right. ;d3 is MIN(dx,dy) that is dx in this case. 4 cycles BPL.S over ;See if it is time to go right. 9 cycles ;(8 or 10 depending on wheter it branches) ADD d4,d5 ;d4 is MAX(dx,dy)=dy in this case. 4/2=2 cycles SUBQ #1,d7 ;One pixel right 4/2=2 cycles BPL.S over ;If 0<d7<6 do next pixel 10/2=5 cycles MOVEQ #7,d7 ;restart from bit 7. 4/2/8=0.25 cycles ADDQ #1,a0 ;go to next byte. 8/2/8=0.5 cycles over: Then the same code repeated 3 more times + 1 dbra = 10/4= 2.5 cycles Total sum of 45.25 cycles. At 7.16Mhz this would be 158000 pix/sec but i said 150000 due to Murphy's law... Anybody knows what 2.0 thinks of this? Like "hmm.. this machine 's got a 25MHz '030 so I'll use that instead of the blitter to draw lines" Or are they just waiting for a new 25MHz blitter to show up? I'd want one. /$DR.HEX$
<BGT101@psuvm.psu.edu> (05/01/91)
Hi all I need some fast filled-polygon drawing functions, and was wondering if it's possible to write one that is considerably faster than the ones in ROM such as AreaDraw() or Flood(). If so, does anybody have some code that they wouldn't mind sharing? (I will probably be using 4 bit-planes) Thanks blaise
chrisg@cbmvax.commodore.com (Chris Green) (05/01/91)
In article <1991Apr29.110534.10198@cs.umu.se> dvljrt@cs.umu.se (Joakim Rosqvist) writes: >Here is my inner loop: > BSET d7,(a0) ;Plot pixel. 12 cycles > ADD d6,a0 ;Go to the next scanline. 8 cycles > SUB d3,d5 ;This routine always goes one pixel down and sometimes > ;(every second time for 292 deg) one pixels right. > ;d3 is MIN(dx,dy) that is dx in this case. 4 cycles > BPL.S over ;See if it is time to go right. 9 cycles > ;(8 or 10 depending on wheter it branches) > ADD d4,d5 ;d4 is MAX(dx,dy)=dy in this case. 4/2=2 cycles > SUBQ #1,d7 ;One pixel right 4/2=2 cycles > BPL.S over ;If 0<d7<6 do next pixel 10/2=5 cycles > MOVEQ #7,d7 ;restart from bit 7. 4/2/8=0.25 cycles > ADDQ #1,a0 ;go to next byte. 8/2/8=0.5 cycles >over: Another good optimization for CPU driven lines is to do further examination of the slope. For instance, suppose you are drawing a near vertical line. If DX<DY/n, then there are at least n-1 vertical steps (I think I've got this right..I don't have the code here) between each horizontal step. So, you can do, say 2 vertical steps at a time with no check in between: BSET d7,(a0) ADD d6,a0 BSET d7,(a0) SUB d3,d5 ; d3 contains twice the dx! BPL.s over The end conditions are a little hairy, but you can still win by doing this. For lines that are near horizontal or vertical, and are long, you win by doing a divide (at least on the 80xxx, you do), and using quick horizontal or vertical fills between each transition. -- *-------------------------------------------*---------------------------* |Chris Green - Graphics Software Engineer - chrisg@commodore.COM f | Commodore-Amiga - uunet!cbmvax!chrisg n |My opinions are my own, and do not - killyouridolssonicdeath o |necessarily represent those of my employer.- itstheendoftheworld r *-------------------------------------------*---------------------------d
rda184s@monu6.cc.monash.edu.au (Richard Jones) (05/03/91)
BGT101@psuvm.psu.edu writes: >Hi all >I need some fast filled-polygon drawing functions, and was wondering if it's >possible to write one that is considerably faster than the ones in ROM such >as AreaDraw() or Flood(). If so, does anybody have some code that they >wouldn't mind sharing? (I will probably be using 4 bit-planes) >Thanks >blaise Me too please. I have an abundance of faast line drawers, but I have been looking for a fast polygon drawing routine for ages! It should be able to handle *at least* 3 bit planes, but 4 would be nice. Thanks also Richard