comparison src/video/fbcon/SDL_fbmatrox.c @ 1895:c121d94672cb

SDL 1.2 is moving to a branch, and SDL 1.3 is becoming the head.
author Sam Lantinga <slouken@libsdl.org>
date Mon, 10 Jul 2006 21:04:37 +0000
parents 7a36f01acf71
children e1da92da346c
comparison
equal deleted inserted replaced
1894:c69cee13dd76 1895:c121d94672cb
26 #include "SDL_fbmatrox.h" 26 #include "SDL_fbmatrox.h"
27 #include "matrox_mmio.h" 27 #include "matrox_mmio.h"
28 28
29 29
30 /* Wait for vertical retrace - taken from the XFree86 Matrox driver */ 30 /* Wait for vertical retrace - taken from the XFree86 Matrox driver */
31 static void WaitVBL(_THIS) 31 static void
32 { 32 WaitVBL(_THIS)
33 int count; 33 {
34 34 int count;
35 /* find start of retrace */ 35
36 mga_waitidle(); 36 /* find start of retrace */
37 while ( (mga_in8(0x1FDA) & 0x08) ) 37 mga_waitidle();
38 ; 38 while ((mga_in8(0x1FDA) & 0x08));
39 while ( !(mga_in8(0x1FDA) & 0x08) ) 39 while (!(mga_in8(0x1FDA) & 0x08));
40 ; 40 /* wait until we're past the start */
41 /* wait until we're past the start */ 41 count = mga_in32(0x1E20) + 2;
42 count = mga_in32(0x1E20) + 2; 42 while (mga_in32(0x1E20) < count);
43 while ( mga_in32(0x1E20) < count ) 43 }
44 ; 44 static void
45 } 45 WaitIdle(_THIS)
46 static void WaitIdle(_THIS) 46 {
47 { 47 mga_waitidle();
48 mga_waitidle();
49 } 48 }
50 49
51 /* Sets video mem colorkey and accelerated blit function */ 50 /* Sets video mem colorkey and accelerated blit function */
52 static int SetHWColorKey(_THIS, SDL_Surface *surface, Uint32 key) 51 static int
53 { 52 SetHWColorKey(_THIS, SDL_Surface * surface, Uint32 key)
54 return(0); 53 {
54 return (0);
55 } 55 }
56 56
57 /* Sets per surface hardware alpha value */ 57 /* Sets per surface hardware alpha value */
58 #if 0 58 #if 0
59 static int SetHWAlpha(_THIS, SDL_Surface *surface, Uint8 value) 59 static int
60 { 60 SetHWAlpha(_THIS, SDL_Surface * surface, Uint8 value)
61 return(0); 61 {
62 return (0);
62 } 63 }
63 #endif 64 #endif
64 65
65 static int FillHWRect(_THIS, SDL_Surface *dst, SDL_Rect *rect, Uint32 color) 66 static int
66 { 67 FillHWRect(_THIS, SDL_Surface * dst, SDL_Rect * rect, Uint32 color)
67 int dstX, dstY; 68 {
68 Uint32 fxbndry; 69 int dstX, dstY;
69 Uint32 ydstlen; 70 Uint32 fxbndry;
70 Uint32 fillop; 71 Uint32 ydstlen;
71 72 Uint32 fillop;
72 /* Don't blit to the display surface when switched away */ 73
73 if ( switched_away ) { 74 /* Don't blit to the display surface when switched away */
74 return -2; /* no hardware access */ 75 if (switched_away) {
75 } 76 return -2; /* no hardware access */
76 if ( dst == this->screen ) { 77 }
77 SDL_mutexP(hw_lock); 78 if (dst == this->screen) {
78 } 79 SDL_mutexP(hw_lock);
79 80 }
80 switch (dst->format->BytesPerPixel) { 81
81 case 1: 82 switch (dst->format->BytesPerPixel) {
82 color |= (color<<8); 83 case 1:
83 case 2: 84 color |= (color << 8);
84 color |= (color<<16); 85 case 2:
85 break; 86 color |= (color << 16);
86 } 87 break;
87 88 }
88 /* Set up the X/Y base coordinates */ 89
89 FB_dst_to_xy(this, dst, &dstX, &dstY); 90 /* Set up the X/Y base coordinates */
90 91 FB_dst_to_xy(this, dst, &dstX, &dstY);
91 /* Adjust for the current rectangle */ 92
92 dstX += rect->x; 93 /* Adjust for the current rectangle */
93 dstY += rect->y; 94 dstX += rect->x;
94 95 dstY += rect->y;
95 /* Set up the X boundaries */ 96
96 fxbndry = (dstX | ((dstX+rect->w) << 16)); 97 /* Set up the X boundaries */
97 98 fxbndry = (dstX | ((dstX + rect->w) << 16));
98 /* Set up the Y boundaries */ 99
99 ydstlen = (rect->h | (dstY << 16)); 100 /* Set up the Y boundaries */
100 101 ydstlen = (rect->h | (dstY << 16));
101 /* Set up for color fill operation */ 102
102 fillop = MGADWG_TRAP | MGADWG_SOLID | 103 /* Set up for color fill operation */
103 MGADWG_ARZERO | MGADWG_SGNZERO | MGADWG_SHIFTZERO; 104 fillop = MGADWG_TRAP | MGADWG_SOLID |
104 105 MGADWG_ARZERO | MGADWG_SGNZERO | MGADWG_SHIFTZERO;
105 /* Execute the operations! */ 106
106 mga_wait(5); 107 /* Execute the operations! */
107 mga_out32(MGAREG_DWGCTL, fillop | MGADWG_REPLACE); 108 mga_wait(5);
108 mga_out32(MGAREG_FCOL, color); 109 mga_out32(MGAREG_DWGCTL, fillop | MGADWG_REPLACE);
109 mga_out32(MGAREG_FXBNDRY, fxbndry); 110 mga_out32(MGAREG_FCOL, color);
110 mga_out32(MGAREG_YDSTLEN + MGAREG_EXEC, ydstlen); 111 mga_out32(MGAREG_FXBNDRY, fxbndry);
111 112 mga_out32(MGAREG_YDSTLEN + MGAREG_EXEC, ydstlen);
112 FB_AddBusySurface(dst); 113
113 114 FB_AddBusySurface(dst);
114 if ( dst == this->screen ) { 115
115 SDL_mutexV(hw_lock); 116 if (dst == this->screen) {
116 } 117 SDL_mutexV(hw_lock);
117 return(0); 118 }
118 } 119 return (0);
119 120 }
120 static int HWAccelBlit(SDL_Surface *src, SDL_Rect *srcrect, 121
121 SDL_Surface *dst, SDL_Rect *dstrect) 122 static int
122 { 123 HWAccelBlit(SDL_Surface * src, SDL_Rect * srcrect,
123 SDL_VideoDevice *this = current_video; 124 SDL_Surface * dst, SDL_Rect * dstrect)
124 int pitch, w, h; 125 {
125 int srcX, srcY; 126 SDL_VideoDevice *this = current_video;
126 int dstX, dstY; 127 int pitch, w, h;
127 Uint32 sign; 128 int srcX, srcY;
128 Uint32 start, stop; 129 int dstX, dstY;
129 int skip; 130 Uint32 sign;
130 Uint32 blitop; 131 Uint32 start, stop;
131 132 int skip;
132 /* FIXME: For now, only blit to display surface */ 133 Uint32 blitop;
133 if ( dst->pitch != SDL_VideoSurface->pitch ) { 134
134 return(src->map->sw_blit(src, srcrect, dst, dstrect)); 135 /* FIXME: For now, only blit to display surface */
135 } 136 if (dst->pitch != SDL_VideoSurface->pitch) {
136 137 return (src->map->sw_blit(src, srcrect, dst, dstrect));
137 /* Don't blit to the display surface when switched away */ 138 }
138 if ( switched_away ) { 139
139 return -2; /* no hardware access */ 140 /* Don't blit to the display surface when switched away */
140 } 141 if (switched_away) {
141 if ( dst == this->screen ) { 142 return -2; /* no hardware access */
142 SDL_mutexP(hw_lock); 143 }
143 } 144 if (dst == this->screen) {
144 145 SDL_mutexP(hw_lock);
145 /* Calculate source and destination base coordinates (in pixels) */ 146 }
146 w = dstrect->w; 147
147 h = dstrect->h; 148 /* Calculate source and destination base coordinates (in pixels) */
148 FB_dst_to_xy(this, src, &srcX, &srcY); 149 w = dstrect->w;
149 FB_dst_to_xy(this, dst, &dstX, &dstY); 150 h = dstrect->h;
150 151 FB_dst_to_xy(this, src, &srcX, &srcY);
151 /* Adjust for the current blit rectangles */ 152 FB_dst_to_xy(this, dst, &dstX, &dstY);
152 srcX += srcrect->x; 153
153 srcY += srcrect->y; 154 /* Adjust for the current blit rectangles */
154 dstX += dstrect->x; 155 srcX += srcrect->x;
155 dstY += dstrect->y; 156 srcY += srcrect->y;
156 pitch = dst->pitch/dst->format->BytesPerPixel; 157 dstX += dstrect->x;
157 158 dstY += dstrect->y;
158 /* Set up the blit direction (sign) flags */ 159 pitch = dst->pitch / dst->format->BytesPerPixel;
159 sign = 0; 160
160 if ( srcX < dstX ) { 161 /* Set up the blit direction (sign) flags */
161 sign |= 1; 162 sign = 0;
162 } 163 if (srcX < dstX) {
163 if ( srcY < dstY ) { 164 sign |= 1;
164 sign |= 4; 165 }
165 srcY += (h - 1); 166 if (srcY < dstY) {
166 dstY += (h - 1); 167 sign |= 4;
167 } 168 srcY += (h - 1);
168 169 dstY += (h - 1);
169 /* Set up the blit source row start, end, and skip (in pixels) */ 170 }
170 stop = start = (srcY * pitch) + srcX; 171
171 if ( srcX < dstX ) { 172 /* Set up the blit source row start, end, and skip (in pixels) */
172 start += (w - 1); 173 stop = start = (srcY * pitch) + srcX;
173 } else { 174 if (srcX < dstX) {
174 stop += (w - 1); 175 start += (w - 1);
175 } 176 } else {
176 if ( srcY < dstY ) { 177 stop += (w - 1);
177 skip = -pitch; 178 }
178 } else { 179 if (srcY < dstY) {
179 skip = pitch; 180 skip = -pitch;
180 } 181 } else {
181 182 skip = pitch;
182 /* Set up the blit operation */ 183 }
183 if ( (src->flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY ) { 184
184 Uint32 colorkey; 185 /* Set up the blit operation */
185 186 if ((src->flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY) {
186 blitop = MGADWG_BFCOL | MGADWG_BITBLT | 187 Uint32 colorkey;
187 MGADWG_SHIFTZERO | MGADWG_RSTR | (0x0C << 16) | 188
188 MGADWG_TRANSC; 189 blitop = MGADWG_BFCOL | MGADWG_BITBLT |
189 190 MGADWG_SHIFTZERO | MGADWG_RSTR | (0x0C << 16) | MGADWG_TRANSC;
190 colorkey = src->format->colorkey; 191
191 switch (dst->format->BytesPerPixel) { 192 colorkey = src->format->colorkey;
192 case 1: 193 switch (dst->format->BytesPerPixel) {
193 colorkey |= (colorkey<<8); 194 case 1:
194 case 2: 195 colorkey |= (colorkey << 8);
195 colorkey |= (colorkey<<16); 196 case 2:
196 break; 197 colorkey |= (colorkey << 16);
197 } 198 break;
198 mga_wait(2); 199 }
199 mga_out32(MGAREG_FCOL, colorkey); 200 mga_wait(2);
200 mga_out32(MGAREG_BCOL, 0xFFFFFFFF); 201 mga_out32(MGAREG_FCOL, colorkey);
201 } else { 202 mga_out32(MGAREG_BCOL, 0xFFFFFFFF);
202 blitop = MGADWG_BFCOL | MGADWG_BITBLT | 203 } else {
203 MGADWG_SHIFTZERO | MGADWG_RSTR | (0x0C << 16); 204 blitop = MGADWG_BFCOL | MGADWG_BITBLT |
204 } 205 MGADWG_SHIFTZERO | MGADWG_RSTR | (0x0C << 16);
205 mga_wait(7); 206 }
206 mga_out32(MGAREG_SGN, sign); 207 mga_wait(7);
207 mga_out32(MGAREG_AR3, start); 208 mga_out32(MGAREG_SGN, sign);
208 mga_out32(MGAREG_AR0, stop); 209 mga_out32(MGAREG_AR3, start);
209 mga_out32(MGAREG_AR5, skip); 210 mga_out32(MGAREG_AR0, stop);
210 mga_out32(MGAREG_FXBNDRY, (dstX | ((dstX + w-1) << 16))); 211 mga_out32(MGAREG_AR5, skip);
211 mga_out32(MGAREG_YDSTLEN, (dstY << 16) | h); 212 mga_out32(MGAREG_FXBNDRY, (dstX | ((dstX + w - 1) << 16)));
212 mga_out32(MGAREG_DWGCTL + MGAREG_EXEC, blitop); 213 mga_out32(MGAREG_YDSTLEN, (dstY << 16) | h);
213 214 mga_out32(MGAREG_DWGCTL + MGAREG_EXEC, blitop);
214 FB_AddBusySurface(src); 215
215 FB_AddBusySurface(dst); 216 FB_AddBusySurface(src);
216 217 FB_AddBusySurface(dst);
217 if ( dst == this->screen ) { 218
218 SDL_mutexV(hw_lock); 219 if (dst == this->screen) {
219 } 220 SDL_mutexV(hw_lock);
220 return(0); 221 }
221 } 222 return (0);
222 223 }
223 static int CheckHWBlit(_THIS, SDL_Surface *src, SDL_Surface *dst) 224
224 { 225 static int
225 int accelerated; 226 CheckHWBlit(_THIS, SDL_Surface * src, SDL_Surface * dst)
226 227 {
227 /* Set initial acceleration on */ 228 int accelerated;
228 src->flags |= SDL_HWACCEL; 229
229 230 /* Set initial acceleration on */
230 /* Set the surface attributes */ 231 src->flags |= SDL_HWACCEL;
231 if ( (src->flags & SDL_SRCALPHA) == SDL_SRCALPHA ) { 232
232 if ( ! this->info.blit_hw_A ) { 233 /* Set the surface attributes */
233 src->flags &= ~SDL_HWACCEL; 234 if ((src->flags & SDL_SRCALPHA) == SDL_SRCALPHA) {
234 } 235 if (!this->info.blit_hw_A) {
235 } 236 src->flags &= ~SDL_HWACCEL;
236 if ( (src->flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY ) { 237 }
237 if ( ! this->info.blit_hw_CC ) { 238 }
238 src->flags &= ~SDL_HWACCEL; 239 if ((src->flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY) {
239 } 240 if (!this->info.blit_hw_CC) {
240 } 241 src->flags &= ~SDL_HWACCEL;
241 242 }
242 /* Check to see if final surface blit is accelerated */ 243 }
243 accelerated = !!(src->flags & SDL_HWACCEL); 244
244 if ( accelerated ) { 245 /* Check to see if final surface blit is accelerated */
245 src->map->hw_blit = HWAccelBlit; 246 accelerated = !!(src->flags & SDL_HWACCEL);
246 } 247 if (accelerated) {
247 return(accelerated); 248 src->map->hw_blit = HWAccelBlit;
248 } 249 }
249 250 return (accelerated);
250 void FB_MatroxAccel(_THIS, __u32 card) 251 }
251 { 252
252 /* We have hardware accelerated surface functions */ 253 void
253 this->CheckHWBlit = CheckHWBlit; 254 FB_MatroxAccel(_THIS, __u32 card)
254 wait_vbl = WaitVBL; 255 {
255 wait_idle = WaitIdle; 256 /* We have hardware accelerated surface functions */
256 257 this->CheckHWBlit = CheckHWBlit;
257 /* The Matrox has an accelerated color fill */ 258 wait_vbl = WaitVBL;
258 this->info.blit_fill = 1; 259 wait_idle = WaitIdle;
259 this->FillHWRect = FillHWRect; 260
260 261 /* The Matrox has an accelerated color fill */
261 /* The Matrox has accelerated normal and colorkey blits. */ 262 this->info.blit_fill = 1;
262 this->info.blit_hw = 1; 263 this->FillHWRect = FillHWRect;
263 /* The Millenium I appears to do the colorkey test a word 264
264 at a time, and the transparency is intverted. (?) 265 /* The Matrox has accelerated normal and colorkey blits. */
265 */ 266 this->info.blit_hw = 1;
266 if ( card != FB_ACCEL_MATROX_MGA2064W ) { 267 /* The Millenium I appears to do the colorkey test a word
267 this->info.blit_hw_CC = 1; 268 at a time, and the transparency is intverted. (?)
268 this->SetHWColorKey = SetHWColorKey; 269 */
269 } 270 if (card != FB_ACCEL_MATROX_MGA2064W) {
270 271 this->info.blit_hw_CC = 1;
271 #if 0 /* Not yet implemented? */ 272 this->SetHWColorKey = SetHWColorKey;
272 /* The Matrox G200/G400 has an accelerated alpha blit */ 273 }
273 if ( (card == FB_ACCEL_MATROX_MGAG200) 274 #if 0 /* Not yet implemented? */
274 || (card == FB_ACCEL_MATROX_MGAG400) 275 /* The Matrox G200/G400 has an accelerated alpha blit */
275 ) { 276 if ((card == FB_ACCEL_MATROX_MGAG200)
276 this->info.blit_hw_A = 1; 277 || (card == FB_ACCEL_MATROX_MGAG400)) {
277 this->SetHWAlpha = SetHWAlpha; 278 this->info.blit_hw_A = 1;
278 } 279 this->SetHWAlpha = SetHWAlpha;
280 }
279 #endif 281 #endif
280 } 282 }
283
284 /* vi: set ts=4 sw=4 expandtab: */