Mercurial > sdl-ios-xcode
comparison src/video/fbcon/SDL_fbmatrox.c @ 0:74212992fb08
Initial revision
author | Sam Lantinga <slouken@lokigames.com> |
---|---|
date | Thu, 26 Apr 2001 16:45:43 +0000 |
parents | |
children | 3dc008dc229d |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:74212992fb08 |
---|---|
1 /* | |
2 SDL - Simple DirectMedia Layer | |
3 Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga | |
4 | |
5 This library is free software; you can redistribute it and/or | |
6 modify it under the terms of the GNU Library General Public | |
7 License as published by the Free Software Foundation; either | |
8 version 2 of the License, or (at your option) any later version. | |
9 | |
10 This library is distributed in the hope that it will be useful, | |
11 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
13 Library General Public License for more details. | |
14 | |
15 You should have received a copy of the GNU Library General Public | |
16 License along with this library; if not, write to the Free | |
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
18 | |
19 Sam Lantinga | |
20 slouken@devolution.com | |
21 */ | |
22 | |
23 #ifdef SAVE_RCSID | |
24 static char rcsid = | |
25 "@(#) $Id$"; | |
26 #endif | |
27 | |
28 #include "SDL_types.h" | |
29 #include "SDL_video.h" | |
30 #include "SDL_blit.h" | |
31 #include "SDL_fbmatrox.h" | |
32 #include "matrox_mmio.h" | |
33 | |
34 | |
35 static int LockHWSurface(_THIS, SDL_Surface *surface) | |
36 { | |
37 if ( surface == SDL_VideoSurface ) { | |
38 mga_waitidle(); | |
39 } | |
40 return(0); | |
41 } | |
42 static void UnlockHWSurface(_THIS, SDL_Surface *surface) | |
43 { | |
44 return; | |
45 } | |
46 | |
47 /* Wait for vertical retrace - taken from the XFree86 Matrox driver */ | |
48 static void WaitVBL(_THIS) | |
49 { | |
50 int count; | |
51 | |
52 /* find start of retrace */ | |
53 mga_waitidle(); | |
54 while ( (mga_in8(0x1FDA) & 0x08) ) | |
55 ; | |
56 while ( !(mga_in8(0x1FDA) & 0x08) ) | |
57 ; | |
58 /* wait until we're past the start */ | |
59 count = mga_in32(0x1E20) + 2; | |
60 while ( mga_in32(0x1E20) < count ) | |
61 ; | |
62 } | |
63 | |
64 /* Sets video mem colorkey and accelerated blit function */ | |
65 static int SetHWColorKey(_THIS, SDL_Surface *surface, Uint32 key) | |
66 { | |
67 return(0); | |
68 } | |
69 | |
70 /* Sets per surface hardware alpha value */ | |
71 static int SetHWAlpha(_THIS, SDL_Surface *surface, Uint8 value) | |
72 { | |
73 return(0); | |
74 } | |
75 | |
76 static int FillHWRect(_THIS, SDL_Surface *dst, SDL_Rect *rect, Uint32 color) | |
77 { | |
78 int dstX, dstY; | |
79 Uint32 fxbndry; | |
80 Uint32 ydstlen; | |
81 Uint32 fillop; | |
82 | |
83 switch (dst->format->BytesPerPixel) { | |
84 case 1: | |
85 color |= (color<<8); | |
86 case 2: | |
87 color |= (color<<16); | |
88 break; | |
89 } | |
90 | |
91 /* Set up the X/Y base coordinates */ | |
92 dstX = 0; | |
93 dstY = ((char *)dst->pixels - mapped_mem) / SDL_VideoSurface->pitch; | |
94 | |
95 /* Adjust for the current rectangle */ | |
96 dstX += rect->x; | |
97 dstY += rect->y; | |
98 | |
99 /* Set up the X boundaries */ | |
100 fxbndry = (dstX | ((dstX+rect->w) << 16)); | |
101 | |
102 /* Set up the Y boundaries */ | |
103 ydstlen = (rect->h | (dstY << 16)); | |
104 | |
105 #if 0 /* This old way doesn't work on the Matrox G450 */ | |
106 /* Set up for color fill operation */ | |
107 fillop = MGADWG_TRAP | MGADWG_SOLID | | |
108 MGADWG_ARZERO | MGADWG_SGNZERO | MGADWG_SHIFTZERO | | |
109 MGADWG_BFCOL | MGADWG_BLK; | |
110 | |
111 /* Execute the operations! */ | |
112 mga_wait(4); | |
113 mga_out32(MGAREG_FCOL, color); | |
114 mga_out32(MGAREG_FXBNDRY, fxbndry); | |
115 mga_out32(MGAREG_YDSTLEN, ydstlen); | |
116 mga_out32(MGAREG_DWGCTL + MGAREG_EXEC, fillop); | |
117 #else | |
118 /* Set up for color fill operation */ | |
119 fillop = MGADWG_TRAP | MGADWG_SOLID | | |
120 MGADWG_ARZERO | MGADWG_SGNZERO | MGADWG_SHIFTZERO; | |
121 | |
122 /* Execute the operations! */ | |
123 mga_wait(5); | |
124 mga_out32(MGAREG_DWGCTL, fillop | MGADWG_REPLACE); | |
125 mga_out32(MGAREG_FCOL, color); | |
126 mga_out32(MGAREG_FXBNDRY, fxbndry); | |
127 mga_out32(MGAREG_YDSTLEN + MGAREG_EXEC, ydstlen); | |
128 #endif | |
129 | |
130 return(0); | |
131 } | |
132 | |
133 static int HWAccelBlit(SDL_Surface *src, SDL_Rect *srcrect, | |
134 SDL_Surface *dst, SDL_Rect *dstrect) | |
135 { | |
136 SDL_VideoDevice *this; | |
137 int bpp; | |
138 int srcX, srcY; | |
139 int dstX, dstY; | |
140 Uint32 sign; | |
141 Uint32 sstart, sstop; | |
142 int sskip; | |
143 Uint32 blitop; | |
144 | |
145 /* FIXME: For now, only blit to display surface */ | |
146 if ( dst->pitch != SDL_VideoSurface->pitch ) { | |
147 return(src->map->sw_blit(src, srcrect, dst, dstrect)); | |
148 } | |
149 | |
150 /* Calculate source and destination base coordinates (in pixels) */ | |
151 this = current_video; | |
152 srcX= 0; /* FIXME: Calculate this from memory offset */ | |
153 srcY = ((char *)src->pixels - mapped_mem) / SDL_VideoSurface->pitch; | |
154 dstX = 0; /* FIXME: Calculate this from memory offset */ | |
155 dstY = ((char *)dst->pixels - mapped_mem) / SDL_VideoSurface->pitch; | |
156 | |
157 /* Adjust for the current blit rectangles */ | |
158 srcX += srcrect->x; | |
159 srcY += srcrect->y; | |
160 dstX += dstrect->x; | |
161 dstY += dstrect->y; | |
162 | |
163 /* Set up the blit direction (sign) flags */ | |
164 sign = 0; | |
165 if ( srcX < dstX ) { | |
166 sign |= 1; | |
167 } | |
168 if ( srcY < dstY ) { | |
169 sign |= 4; | |
170 } | |
171 | |
172 /* Set up the blit source row start, end, and skip (in pixels) */ | |
173 bpp = src->format->BytesPerPixel; | |
174 sstop = sstart = ((srcY * SDL_VideoSurface->pitch)/bpp) + srcX; | |
175 if ( srcX < dstX ) { | |
176 sstart += (dstrect->w - 1); | |
177 } else { | |
178 sstop += (dstrect->w - 1); | |
179 } | |
180 sskip = src->pitch/bpp; | |
181 if ( srcY < dstY ) { | |
182 sskip = -sskip; | |
183 } | |
184 | |
185 /* Set up the blit operation */ | |
186 if ( (src->flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY ) { | |
187 Uint32 colorkey; | |
188 | |
189 blitop = MGADWG_BFCOL | MGADWG_BITBLT | | |
190 MGADWG_SHIFTZERO | MGADWG_RSTR | (0x0C << 16) | | |
191 MGADWG_TRANSC; | |
192 | |
193 colorkey = src->format->colorkey; | |
194 switch (dst->format->BytesPerPixel) { | |
195 case 1: | |
196 colorkey |= (colorkey<<8); | |
197 case 2: | |
198 colorkey |= (colorkey<<16); | |
199 break; | |
200 } | |
201 mga_wait(2); | |
202 mga_out32(MGAREG_FCOL, colorkey); | |
203 mga_out32(MGAREG_BCOL, 0xFFFFFFFF); | |
204 } else { | |
205 blitop = MGADWG_BFCOL | MGADWG_BITBLT | | |
206 MGADWG_SHIFTZERO | MGADWG_RSTR | (0x0C << 16); | |
207 } | |
208 mga_wait(7); | |
209 mga_out32(MGAREG_SGN, sign); | |
210 mga_out32(MGAREG_AR3, sstart); | |
211 mga_out32(MGAREG_AR0, sstop); | |
212 mga_out32(MGAREG_AR5, sskip); | |
213 mga_out32(MGAREG_FXBNDRY, (dstX | ((dstX + dstrect->w-1) << 16))); | |
214 mga_out32(MGAREG_YDSTLEN, (dstY << 16) | dstrect->h); | |
215 mga_out32(MGAREG_DWGCTL + MGAREG_EXEC, blitop); | |
216 | |
217 return(0); | |
218 } | |
219 | |
220 static int CheckHWBlit(_THIS, SDL_Surface *src, SDL_Surface *dst) | |
221 { | |
222 int accelerated; | |
223 | |
224 /* Set initial acceleration on */ | |
225 src->flags |= SDL_HWACCEL; | |
226 | |
227 /* Set the surface attributes */ | |
228 if ( (src->flags & SDL_SRCALPHA) == SDL_SRCALPHA ) { | |
229 if ( ! this->info.blit_hw_A ) { | |
230 src->flags &= ~SDL_HWACCEL; | |
231 } | |
232 } | |
233 if ( (src->flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY ) { | |
234 if ( ! this->info.blit_hw_CC ) { | |
235 src->flags &= ~SDL_HWACCEL; | |
236 } | |
237 } | |
238 | |
239 /* Check to see if final surface blit is accelerated */ | |
240 accelerated = !!(src->flags & SDL_HWACCEL); | |
241 if ( accelerated ) { | |
242 src->map->hw_blit = HWAccelBlit; | |
243 } | |
244 return(accelerated); | |
245 } | |
246 | |
247 void FB_MatroxAccel(_THIS, __u32 card) | |
248 { | |
249 /* We have hardware accelerated surface functions */ | |
250 this->CheckHWBlit = CheckHWBlit; | |
251 this->LockHWSurface = LockHWSurface; | |
252 this->UnlockHWSurface = UnlockHWSurface; | |
253 wait_vbl = WaitVBL; | |
254 | |
255 /* The Matrox has an accelerated color fill */ | |
256 this->info.blit_fill = 1; | |
257 this->FillHWRect = FillHWRect; | |
258 | |
259 /* The Matrox has accelerated normal and colorkey blits. */ | |
260 this->info.blit_hw = 1; | |
261 /* The Millenium I appears to do the colorkey test a word | |
262 at a time, and the transparency is intverted. (?) | |
263 */ | |
264 if ( card != FB_ACCEL_MATROX_MGA2064W ) { | |
265 this->info.blit_hw_CC = 1; | |
266 this->SetHWColorKey = SetHWColorKey; | |
267 } | |
268 | |
269 #if 0 /* Not yet implemented? */ | |
270 /* The Matrox G200/G400 has an accelerated alpha blit */ | |
271 if ( (card == FB_ACCEL_MATROX_MGAG200) | |
272 || (card == FB_ACCEL_MATROX_MGAG400) | |
273 ) { | |
274 this->info.blit_hw_A = 1; | |
275 this->SetHWAlpha = SetHWAlpha; | |
276 } | |
277 #endif | |
278 } |