Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » fastest bliting method

Credits go to Billybob, Chris Katko, decsonic, Gnatinator, Kris Allen, Krzysztof Kluczek, ReyBrujo, Richard Phipps, and Steve Terry for helping out!
This thread is locked; no one can reply to it. rss feed Print
 1   2 
fastest bliting method
Steve Terry
Member #1,989
March 2002
avatar

Can someone explain to me what the hell is going on? Optimize blit or optimize your code, if you need to optimize your code then it has nothing to do with blit, make your algorithms faster, not blit.

___________________________________
[ Facebook ]
Microsoft is not the Borg collective. The Borg collective has got proper networking. - planetspace.de
Bill Gates is in fact Shawn Hargreaves' ßî+çh. - Gideon Weems

Billybob
Member #3,136
January 2003

Fastest blitting method is, as KK said, your video card's video ram->video ram accelerated blit.

End of story!
And as far as actual time is concerned, the fastest blitting method is:

blit(something);

because you don't start a thread like this, waste time debating things, and blit is only 4 letters! :o

lucaz
Member #4,194
January 2004

1 said:

what is the fast method?, 1)use iterative loops 2)memcpy 3)other.

2 said:

direct line access is the first option right?.
When Im mean iterative loops is:
for(int x=0; x<bmp1->w ;x++)for(int y=0; y<bmp1->h ;y++) bmp1->line[x][y] = bmp2->line[x][y];

3 said:

is is the fastest method?, ¬_¬ ....

4 said:

are you sure this is the fastest method?, memcpy seems more useful, it dont iterate... just take a block of memory a copy it to another-

5 said:

I dont know its code. but at least it just does one for(), not 2

6 said:

who likes to optimise blit?

Ive never said that Im trying to optimise.
I just like to know, like my topic says, what is the fastest.

ReyBrujo explained me why is better memcpy() than use loops, that was what I like to know.
Thanks!.

ReyBrujo
Moderator
January 2001
avatar

Here is the code I used to optimize. Note that, if the processor does not have MMX support, it just copied with memcpy. Of course, the bitmaps must be aligned, and you cannot use these with the screen bitmap. I tried it a couple of times with that old project (DRS system), and worked quite fine. I can tell you it won't crash unless you don't meet the requirements :P

1// //
2// The MMX optimization code is here. Hmm... I don't really know if this //
3// should be public for everyone (I mean, as a header, and not as another //
4// source file), but anyway, it is easier this way. //
5// //
6// ----------------------------------------------------------------------- //
7// //
8// This file is a part of DRS (alpha) package. //
9// Copyright (C) 2002 Roberto Alfonso (aka ReyBrujo) //
10// reybrujo@hotmail.com //
11// //
12// This package is free software; you can redistribute it and/or //
13// modify it under the terms of the GNU General Public License as //
14// published by the Free Software Foundation; either version 2, //
15// or (at your option) any later version. //
16// //
17// This package is distributed in the hope that it will be useful, //
18// but WITHOUT ANY WARRANTY; without even the implied warranty of //
19// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
20// GNU General Public License for more details. //
21// //
22// You should have received a copy of the GNU General Public //
23// License along with this package (see the file COPYING). If not, //
24// write to the Free Software Foundation, Inc., 59 Temple Place, //
25// Suite 330, Bostom, MA 02111-1307 USA //
26// //
27// ----------------------------------------------------------------------- //
28// //
29#ifndef _MMXCODE_H_INCLUDED
30#define _MMXCODE_H_INCLUDED 0xDEAD
31 
32 
33 
34#ifdef __cplusplus
35extern "C" {
36#endif
37 
38// //
39// Whenever I needed to update the internal bitmap I just used blit(). But //
40// I noticed it was very slow, so I tried just (since the background and //
41// the internal bitmap have the same size) memcpy() the 'line' pointers of //
42// the bitmap struct. But that gave some boost, but not enough. //
43// //
44// Now, and since it was still slow, I decided to try MMX. I defined a new //
45// macro, MMX_MEMCPY, which checks if your hardware support MMX set (by //
46// checking Allegro cpu_capabilities global variable). If so, it uses the //
47// movq instruction to copy 32 bytes each cycle. //
48// //
49// WARNING! //
50// Though it increases the frame rate (with 25 objects and seed 55555555 //
51// increases +30FPS here), be careful! This is still a hack, and I did not //
52// even care about aligning. The code expects to find a '_size' multiple //
53// of 32 (like 640x480, 320x200, etc, etc, etc). But with odd sizes (maybe //
54// you have set a bitmap of 319x111, which is not multiple of 32), there //
55// will be some bytes that are not going to be copied. //
56// //
57// Why I just copy 32 each cycle and not 8x8 = 64 bytes each cycle? Well, //
58// the redirection from memory (first you copy from [esi], then [esi+8], //
59// then [esi+16], etc) takes some time, and will drain all advantage we //
60// get by copying several bytes at once. According to my tests, 32 bytes //
61// each cycle gives a good speed. //
62// //
63// Since the object creates the internal and background bitmaps taking the //
64// screen width and size, and since I haven't seen any odd resolution, the //
65// object itself shouldn't have problems at all. But if you take this code //
66// to implement your own fast_copy_bitmap() function, be warned: you need //
67// to align the data and manually copy the bytes that are not copied using //
68// the cycle. //
69// //
70 
71 
72 
73// //
74// The user should not include this header directly. It is for his safety, //
75// I don't really care if he deletes the #error directive and hack this by //
76// him/herself. //
77// //
78#ifndef _DRS_H_INCLUDED
79 #error You should not include this file directly!
80#endif
81 
82 
83 
84#ifdef USE_MMX
85#ifdef __GNUC__
86 //
87 // MMX code for DJGPP, MingW32 and probably Linux. Sorry, but cannot test
88 // Linux version for now until getting a new harddisk :(
89 //
90 
91 #define MMX_MEMCPY(_t, _s, _size) \
92 if (cpu_capabilities & CPU_MMX) { \
93 asm( \
94 "0: \n\t" \
95 "movq (%%esi), %%mm0 \n\t" \
96 "movq 8(%%esi), %%mm1 \n\t" \
97 "movq 16(%%esi), %%mm2 \n\t" \
98 "movq 24(%%esi), %%mm3 \n\t" \
99 "movq %%mm0, (%%edi) \n\t" \
100 "movq %%mm1, 8(%%edi) \n\t" \
101 "movq %%mm2, 16(%%edi) \n\t" \
102 "movq %%mm3, 24(%%edi) \n\t" \
103 "addl $32, %%esi \n\t" \
104 "addl $32, %%edi \n\t" \
105 "decl %%ecx \n\t" \
106 "jnz 0b \n\t" \
107 "emms \n\t" \
108 : : "c" ((_size) >> 5), \
109 "S" (_s->line[0]), \
110 "D" (_t->line[0]) \
111 ); \
112 } \
113 else \
114 memcpy(_t->line[0], _s->line[0], (_size))
115#else // !__GNUC__
116 
117 //
118 // MMX code for MSVC and, probably, BCC. MSVC doesn't understand the code
119 // as a macro, so I set it as an inline function.
120 //
121 inline void mmx_memcpy(unsigned char *target,
122 unsigned char *source, long amount) {
123 if (cpu_capabilities & CPU_MMX) {
124 __asm {
125 mov ecx, amount
126 mov esi, source
127 mov edi, target
128 again:
129 movq mm0, [esi ]
130 movq mm1, [esi+ 8]
131 movq mm2, [esi+16]
132 movq mm3, [esi+24]
133 movq [edi ], mm0
134 movq [edi+ 8], mm1
135 movq [edi+16], mm2
136 movq [edi+24], mm3
137 add esi, 32
138 add edi, 32
139 dec ecx
140 jnz again
141 emms
142 }
143 }
144 else
145 memcpy(target, source, amount);
146 }
147 
148 #define MMX_MEMCPY(_t, _s, _sz) \
149 mmx_memcpy(_t->line[0], _s->line[0], (_sz) >> 5)
150#endif
151#else // ! USE_MMX
152 #define MMX_MEMCPY(_t, _s, _sz) \
153 memcpy(_t->line[0], _s->line[0], (_sz))
154#endif
155 
156 
157#ifdef __cplusplus
158}
159#endif
160 
161 
162 
163#endif // _MMXCODE_H_INCLUDED

--
RB
光子「あたしただ…奪う側に回ろうと思っただけよ」
Mitsuko's last words, Battle Royale

lucaz
Member #4,194
January 2004

thanks one more time reybrujo!.
Im not trying to optimise, my idea is try to make my own blit, so I can use it in a machine without allegro.

Paul whoknows
Member #5,081
September 2004
avatar

I agree with Richard, make your game first, make it run faster later.
But of course, all of us want to own the faster blitter ever made. 8-)

____

"The unlimited potential has been replaced by the concrete reality of what I programmed today." - Jordan Mechner.

lucaz
Member #4,194
January 2004

:o people you are crazy!, Im not trying to optimise!!!!!!!!, ahhhhhhhhhhhhhhhhhhhhhhhhh

Steve Terry
Member #1,989
March 2002
avatar

Then say that you are writing your own blitter, it makes more sense now. Since you are not using allegro I'm not sure what you are using, if it's good ol mode 13h then memcpy would work best since you probably have your bitmap stored linear anyway as well as the screen, just beware the screen "wraps" around :)

___________________________________
[ Facebook ]
Microsoft is not the Borg collective. The Borg collective has got proper networking. - planetspace.de
Bill Gates is in fact Shawn Hargreaves' ßî+çh. - Gideon Weems

 1   2 


Go to: