1 #define PSZ 8
2
3 #ifdef HAVE_CONFIG_H
4 #include "config.h"
5 #endif
6
7 /* All drivers should typically include these */
8 #include "xf86.h"
9 #include "xf86_OSproc.h"
10
11 /* For correct __inline__ usage */
12 #include "compiler.h"
13
14 /* Drivers that need to access the PCI config space directly need this */
15 #include "xf86Pci.h"
16
17 /* Drivers that use XAA need this */
18 #ifdef HAVE_XAA_H
19 #include "xaa.h"
20 #include "xaalocal.h"
21 #endif
22 #include "xf86fbman.h"
23 #include "miline.h"
24 #include "servermd.h"
25
26 #include "mga.h"
27 #include "mga_reg.h"
28 #include "mga_macros.h"
29
30 #ifdef MGADRI
31 #include "mga_dri.h"
32 #endif
33
34 #define REPLICATE_8(r) (((r) & 0x0ff) | (((r) & 0x0ff) << 8) \
35 | (((r) & 0x0ff) << 16) | (((r) & 0x0ff) << 24))
36 #define REPLICATE_16(r) (((r) & 0x0000ffff) | (((r) & 0x0000ffff) << 16))
37 #define REPLICATE_24(r) (((r) & 0x00ffffff) | (((r) & 0x00ffffff) << 24))
38 #define REPLICATE_32(r) (r)
39
40
41 #define SET_FOREGROUND_REPLICATED(c, rep_c) \
42 if((c) != pMga->FgColor) { \
43 pMga->FgColor = (c); \
44 OUTREG(MGAREG_FCOL,(rep_c)); \
45 }
46
47 #define SET_BACKGROUND_REPLICATED(c, rep_c) \
48 if((c) != pMga->BgColor) { \
49 pMga->BgColor = (c); \
50 OUTREG(MGAREG_BCOL,(rep_c)); \
51 }
52
53
54 #define MGAMoveDWORDS(d,s,c) \
55 do { \
56 write_mem_barrier(); \
57 XAAMoveDWORDS((d),(s),(c)); \
58 } while (0)
59
60 #ifdef USE_XAA
61 static void mgaSetupForSolidFill( ScrnInfoPtr pScrn, int color,
62 int rop, unsigned int planemask );
63
64 static void mgaSetupForScreenToScreenCopy( ScrnInfoPtr pScrn,
65 int xdir, int ydir, int rop, unsigned int planemask, int trans );
66
67 static void mgaSubsequentScreenToScreenCopy( ScrnInfoPtr pScrn,
68 int srcX, int srcY, int dstX, int dstY, int w, int h );
69
70 static void mgaSubsequentScreenToScreenCopy_FastBlit( ScrnInfoPtr pScrn,
71 int srcX, int srcY, int dstX, int dstY, int w, int h );
72
73 static void mgaSetupForScanlineCPUToScreenColorExpandFill( ScrnInfoPtr pScrn,
74 int fg, int bg, int rop, unsigned int planemask );
75
76 static void mgaSubsequentScanlineCPUToScreenColorExpandFill( ScrnInfoPtr pScrn,
77 int x, int y, int w, int h, int skipleft );
78
79 static void mgaSubsequentColorExpandScanline( ScrnInfoPtr pScrn, int bufno );
80
81 static void mgaSubsequentColorExpandScanlineIndirect( ScrnInfoPtr pScrn,
82 int bufno );
83
84 static void mgaSubsequentSolidFillRect( ScrnInfoPtr pScrn, int x, int y,
85 int w, int h );
86
87 static void mgaSubsequentSolidFillTrap( ScrnInfoPtr pScrn, int y, int h,
88 int left, int dxL, int dyL, int eL, int right, int dxR, int dyR, int eR );
89
90 static void mgaSubsequentSolidHorVertLine( ScrnInfoPtr pScrn, int x, int y,
91 int len, int dir );
92
93 static void mgaSubsequentSolidTwoPointLine( ScrnInfoPtr pScrn, int x1, int y1,
94 int x2, int y2, int flags );
95
96 static void mgaSetupForMono8x8PatternFill( ScrnInfoPtr pScrn,
97 int patx, int paty, int fg, int bg, int rop, unsigned int planemask );
98
99 static void mgaSubsequentMono8x8PatternFillRect( ScrnInfoPtr pScrn,
100 int patx, int paty, int x, int y, int w, int h );
101
102 static void mgaSubsequentMono8x8PatternFillRect_Additional( ScrnInfoPtr pScrn,
103 int patx, int paty, int x, int y, int w, int h );
104
105 static void mgaSubsequentMono8x8PatternFillTrap( ScrnInfoPtr pScrn,
106 int patx, int paty, int y, int h, int left, int dxL, int dyL, int eL,
107 int right, int dxR, int dyR, int eR );
108
109 static void mgaSetupForScanlineImageWrite( ScrnInfoPtr pScrn, int rop,
110 unsigned int planemask, int transparency_color, int bpp, int depth );
111
112 static void mgaSubsequentScanlineImageWriteRect( ScrnInfoPtr pScrn,
113 int x, int y, int w, int h, int skipleft );
114
115 static void mgaSubsequentImageWriteScanline( ScrnInfoPtr pScrn, int num );
116
117 static void mgaSetupForPlanarScreenToScreenColorExpandFill( ScrnInfoPtr pScrn,
118 int fg, int bg, int rop, unsigned int planemask );
119
120 static void mgaSubsequentPlanarScreenToScreenColorExpandFill( ScrnInfoPtr pScrn,
121 int x, int y, int w, int h, int srcx, int srcy, int skipleft );
122
123 static void mgaSetupForScreenToScreenColorExpandFill( ScrnInfoPtr pScrn,
124 int fg, int bg, int rop, unsigned int planemask );
125
126 static void mgaSubsequentScreenToScreenColorExpandFill( ScrnInfoPtr pScrn,
127 int x, int y, int w, int h, int srcx, int srcy, int skipleft );
128
129 #if X_BYTE_ORDER == X_LITTLE_ENDIAN
130 static void mgaSetupForDashedLine( ScrnInfoPtr pScrn, int fg, int bg,
131 int rop, unsigned int planemask, int length, unsigned char *pattern );
132
133 static void mgaSubsequentDashedTwoPointLine( ScrnInfoPtr pScrn,
134 int x1, int y1, int x2, int y2, int flags, int phase );
135 #endif
136
137 static void mgaRestoreAccelState( ScrnInfoPtr pScrn );
138
139 static void MGASetClippingRectangle(ScrnInfoPtr pScrn, int x1, int y1,
140 int x2, int y2);
141 static void MGADisableClipping(ScrnInfoPtr pScrn);
142 static void MGAFillSolidRectsDMA(ScrnInfoPtr pScrn, int fg, int rop,
143 unsigned int planemask, int nBox, BoxPtr pBox);
144 static void MGAFillSolidSpansDMA(ScrnInfoPtr pScrn, int fg, int rop,
145 unsigned int planemask, int n, DDXPointPtr ppt,
146 int *pwidth, int fSorted);
147 static void MGAFillMono8x8PatternRectsTwoPass(ScrnInfoPtr pScrn, int fg, int bg,
148 int rop, unsigned int planemask, int nBox,
149 BoxPtr pBox, int pattern0, int pattern1,
150 int xorigin, int yorigin);
151 static void MGAValidatePolyArc(GCPtr, unsigned long, DrawablePtr);
152 static void MGAValidatePolyPoint(GCPtr, unsigned long, DrawablePtr);
153 static void MGAFillCacheBltRects(ScrnInfoPtr, int, unsigned int, int, BoxPtr,
154 int, int, XAACacheInfoPtr);
155
156
157 static __inline__ void
common_replicate_colors_and_mask(unsigned int fg,unsigned int bg,unsigned int pm,unsigned int bpp,unsigned int * rep_fg,unsigned int * rep_bg,unsigned int * rep_pm)158 common_replicate_colors_and_mask( unsigned int fg, unsigned int bg,
159 unsigned int pm,
160 unsigned int bpp,
161 unsigned int * rep_fg,
162 unsigned int * rep_bg,
163 unsigned int * rep_pm )
164 {
165 switch( bpp ) {
166 case 8:
167 *rep_fg = REPLICATE_8( fg );
168 *rep_bg = REPLICATE_8( bg );
169 *rep_pm = REPLICATE_8( pm );
170 break;
171 case 16:
172 *rep_fg = REPLICATE_16( fg );
173 *rep_bg = REPLICATE_16( bg );
174 *rep_pm = REPLICATE_16( pm );
175 break;
176 case 24:
177 *rep_fg = REPLICATE_24( fg );
178 *rep_bg = REPLICATE_24( bg );
179 *rep_pm = REPLICATE_24( pm );
180 break;
181 case 32:
182 *rep_fg = REPLICATE_32( fg );
183 *rep_bg = REPLICATE_32( bg );
184 *rep_pm = REPLICATE_32( pm );
185 break;
186 }
187 }
188
189
190 #ifdef RENDER
191
192 static Bool MGASetupForCPUToScreenAlphaTexture(ScrnInfoPtr pScrn, int op,
193 CARD16 red, CARD16 green, CARD16 blue, CARD16 alpha, int alphaType,
194 CARD8 *alphaPtr, int alphaPitch, int width, int height, int flags);
195
196 static Bool MGASetupForCPUToScreenAlphaTextureFaked(ScrnInfoPtr Scrn, int op,
197 CARD16 red, CARD16 green, CARD16 blue, CARD16 alpha, int alphaType,
198 CARD8 *alphaPtr, int alphaPitch, int width, int height, int flags);
199
200 static Bool MGASetupForCPUToScreenTexture(ScrnInfoPtr pScrn, int op,
201 int texType, CARD8 *texPtr, int texPitch, int width, int height,
202 int flags);
203
204 static void MGASubsequentCPUToScreenTexture(ScrnInfoPtr pScrn, int dstx,
205 int dsty, int srcx, int srcy, int width, int height);
206
207 #include "mipict.h"
208 #include "dixstruct.h"
209
210 static CARD32 MGAAlphaTextureFormats[2] = {PICT_a8, 0};
211 static CARD32 MGATextureFormats[2] = {PICT_a8r8g8b8, 0};
212
213 static void
RemoveLinear(FBLinearPtr linear)214 RemoveLinear (FBLinearPtr linear)
215 {
216 MGAPtr pMga = (MGAPtr)(linear->devPrivate.ptr);
217
218 pMga->LinearScratch = NULL; /* just lost our scratch */
219 }
220
221 static void
RenderCallback(ScrnInfoPtr pScrn)222 RenderCallback (ScrnInfoPtr pScrn)
223 {
224 MGAPtr pMga = MGAPTR(pScrn);
225
226 if((currentTime.milliseconds > pMga->RenderTime) && pMga->LinearScratch) {
227 xf86FreeOffscreenLinear(pMga->LinearScratch);
228 pMga->LinearScratch = NULL;
229 }
230
231 if(!pMga->LinearScratch)
232 pMga->RenderCallback = NULL;
233 }
234
235 #define RENDER_DELAY 15000
236
237 static Bool
AllocateLinear(ScrnInfoPtr pScrn,int sizeNeeded)238 AllocateLinear (
239 ScrnInfoPtr pScrn,
240 int sizeNeeded
241 ){
242 MGAPtr pMga = MGAPTR(pScrn);
243
244 pMga->RenderTime = currentTime.milliseconds + RENDER_DELAY;
245 pMga->RenderCallback = RenderCallback;
246
247 if(pMga->LinearScratch) {
248 if(pMga->LinearScratch->size >= sizeNeeded)
249 return TRUE;
250 else {
251 if(xf86ResizeOffscreenLinear(pMga->LinearScratch, sizeNeeded))
252 return TRUE;
253
254 xf86FreeOffscreenLinear(pMga->LinearScratch);
255 pMga->LinearScratch = NULL;
256 }
257 }
258
259 pMga->LinearScratch = xf86AllocateOffscreenLinear(
260 pScrn->pScreen, sizeNeeded, 32,
261 NULL, RemoveLinear, pMga);
262
263 return (pMga->LinearScratch != NULL);
264 }
265
266 static int
GetPowerOfTwo(int w)267 GetPowerOfTwo(int w)
268 {
269 int Pof2 = 0;
270 int i = 12;
271
272 while(--i) {
273 if(w & (1 << i)) {
274 Pof2 = i;
275 if(w & ((1 << i) - 1))
276 Pof2++;
277 break;
278 }
279 }
280 return Pof2;
281 }
282
283
284 static int tex_padw, tex_padh;
285
MGASetupForCPUToScreenAlphaTextureFaked(ScrnInfoPtr pScrn,int op,CARD16 red,CARD16 green,CARD16 blue,CARD16 alpha,int alphaType,CARD8 * alphaPtr,int alphaPitch,int width,int height,int flags)286 Bool MGASetupForCPUToScreenAlphaTextureFaked( ScrnInfoPtr pScrn, int op,
287 CARD16 red, CARD16 green,
288 CARD16 blue, CARD16 alpha,
289 int alphaType, CARD8 *alphaPtr,
290 int alphaPitch, int width,
291 int height, int flags )
292 {
293 int log2w, log2h, pitch, sizeNeeded, offset;
294 unsigned int texctl, dwgctl, alphactrl;
295 MGAPtr pMga = MGAPTR(pScrn);
296
297 if(op != PictOpOver) /* only one tested */
298 return FALSE;
299
300 if((width > 2048) || (height > 2048))
301 return FALSE;
302
303 log2w = GetPowerOfTwo(width);
304 log2h = GetPowerOfTwo(height);
305
306 CHECK_DMA_QUIESCENT(pMga, pScrn);
307
308 pitch = (width + 15) & ~15;
309 sizeNeeded = pitch * height;
310 if(pScrn->bitsPerPixel == 16)
311 sizeNeeded <<= 1;
312
313 if(!AllocateLinear(pScrn, sizeNeeded))
314 return FALSE;
315
316 offset = pMga->LinearScratch->offset << 1;
317 if(pScrn->bitsPerPixel == 32)
318 offset <<= 1;
319
320 if(pMga->AccelInfoRec->NeedToSync)
321 MGAStormSync(pScrn);
322
323 XAA_888_plus_PICT_a8_to_8888(
324 (blue >> 8) | (green & 0xff00) | ((red & 0xff00) << 8),
325 alphaPtr, alphaPitch, (CARD32*)(pMga->FbStart + offset),
326 pitch, width, height);
327
328 tex_padw = 1 << log2w;
329 tex_padh = 1 << log2h;
330
331 WAITFIFO(15);
332 OUTREG(MGAREG_TMR0, (1 << 20) / tex_padw); /* sx inc */
333 OUTREG(MGAREG_TMR1, 0); /* sy inc */
334 OUTREG(MGAREG_TMR2, 0); /* tx inc */
335 OUTREG(MGAREG_TMR3, (1 << 20) / tex_padh); /* ty inc */
336 OUTREG(MGAREG_TMR4, 0x00000000);
337 OUTREG(MGAREG_TMR5, 0x00000000);
338 OUTREG(MGAREG_TMR8, 0x00010000);
339 OUTREG(MGAREG_TEXORG, offset);
340 OUTREG(MGAREG_TEXWIDTH, log2w | (((8 - log2w) & 63) << 9) |
341 ((width - 1) << 18));
342 OUTREG(MGAREG_TEXHEIGHT, log2h | (((8 - log2h) & 63) << 9) |
343 ((height - 1) << 18));
344
345 texctl = MGA_TW32 | MGA_PITCHLIN | MGA_TAKEY | MGA_CLAMPUV |
346 ((pitch & 0x07FF) << 9);
347 dwgctl = MGADWG_TEXTURE_TRAP | MGADWG_I | MGADWG_ARZERO |
348 MGADWG_SGNZERO | MGADWG_SHIFTZERO | 0xc0000;
349 alphactrl = MGA_SRC_ALPHA | MGA_DST_ONE_MINUS_SRC_ALPHA |
350 MGA_ALPHACHANNEL;
351
352 OUTREG(MGAREG_TEXCTL, texctl);
353 OUTREG(MGAREG_TEXCTL2, MGA_TC2_DECALDIS | MGA_TC2_CKSTRANSDIS);
354 OUTREG(MGAREG_DWGCTL, dwgctl);
355 OUTREG(MGAREG_TEXFILTER, ((0x1e << 20) | MGA_MAG_BILIN));
356 OUTREG(MGAREG_ALPHACTRL, alphactrl);
357
358 return TRUE;
359 }
360
361 Bool
MGASetupForCPUToScreenAlphaTexture(ScrnInfoPtr pScrn,int op,CARD16 red,CARD16 green,CARD16 blue,CARD16 alpha,int alphaType,CARD8 * alphaPtr,int alphaPitch,int width,int height,int flags)362 MGASetupForCPUToScreenAlphaTexture (
363 ScrnInfoPtr pScrn,
364 int op,
365 CARD16 red,
366 CARD16 green,
367 CARD16 blue,
368 CARD16 alpha,
369 int alphaType,
370 CARD8 *alphaPtr,
371 int alphaPitch,
372 int width,
373 int height,
374 int flags
375 ){
376 int log2w, log2h, i, pitch, sizeNeeded, offset;
377 unsigned int texctl, dwgctl, alphactrl;
378 CARD8 *dst;
379 MGAPtr pMga = MGAPTR(pScrn);
380
381 if(op != PictOpOver) /* only one tested */
382 return FALSE;
383
384 if((width > 2048) || (height > 2048))
385 return FALSE;
386
387 log2w = GetPowerOfTwo(width);
388 log2h = GetPowerOfTwo(height);
389
390 CHECK_DMA_QUIESCENT(pMga, pScrn);
391
392 pitch = (width + 15) & ~15;
393 sizeNeeded = (pitch * height) >> 1;
394 if(pScrn->bitsPerPixel == 32)
395 sizeNeeded >>= 1;
396
397 if(!AllocateLinear(pScrn, sizeNeeded))
398 return FALSE;
399
400 offset = pMga->LinearScratch->offset << 1;
401 if(pScrn->bitsPerPixel == 32)
402 offset <<= 1;
403
404 if(pMga->AccelInfoRec->NeedToSync)
405 MGAStormSync(pScrn);
406
407 i = height;
408 dst = pMga->FbStart + offset;
409 while(i--) {
410 memcpy(dst, alphaPtr, width);
411 dst += pitch;
412 alphaPtr += alphaPitch;
413 }
414
415 tex_padw = 1 << log2w;
416 tex_padh = 1 << log2h;
417
418
419 WAITFIFO(12);
420 OUTREG(MGAREG_DR4, red << 7); /* red start */
421 OUTREG(MGAREG_DR6, 0);
422 OUTREG(MGAREG_DR7, 0);
423 OUTREG(MGAREG_DR8, green << 7); /* green start */
424 OUTREG(MGAREG_DR10, 0);
425 OUTREG(MGAREG_DR11, 0);
426 OUTREG(MGAREG_DR12, blue << 7); /* blue start */
427 OUTREG(MGAREG_DR14, 0);
428 OUTREG(MGAREG_DR15, 0);
429 OUTREG(MGAREG_ALPHASTART, alpha << 7); /* alpha start */
430 OUTREG(MGAREG_ALPHAXINC, 0);
431 OUTREG(MGAREG_ALPHAYINC, 0);
432
433 WAITFIFO(15);
434 OUTREG(MGAREG_TMR0, (1 << 20) / tex_padw); /* sx inc */
435 OUTREG(MGAREG_TMR1, 0); /* sy inc */
436 OUTREG(MGAREG_TMR2, 0); /* tx inc */
437 OUTREG(MGAREG_TMR3, (1 << 20) / tex_padh); /* ty inc */
438 OUTREG(MGAREG_TMR4, 0x00000000);
439 OUTREG(MGAREG_TMR5, 0x00000000);
440 OUTREG(MGAREG_TMR8, 0x00010000);
441 OUTREG(MGAREG_TEXORG, offset);
442 OUTREG(MGAREG_TEXWIDTH, log2w | (((8 - log2w) & 63) << 9) |
443 ((width - 1) << 18));
444 OUTREG(MGAREG_TEXHEIGHT, log2h | (((8 - log2h) & 63) << 9) |
445 ((height - 1) << 18));
446
447 texctl = MGA_TW8A | MGA_PITCHLIN | MGA_TAKEY | MGA_CLAMPUV |
448 MGA_TEXMODULATE |
449 ((pitch & 0x07FF) << 9);
450 dwgctl = MGADWG_TEXTURE_TRAP | MGADWG_I | MGADWG_ARZERO |
451 MGADWG_SGNZERO | MGADWG_SHIFTZERO | 0xc0000;
452 alphactrl = MGA_SRC_ONE | MGA_DST_ONE_MINUS_SRC_ALPHA |
453 MGA_ALPHACHANNEL | MGA_MODULATEDALPHA;
454
455 OUTREG(MGAREG_TEXCTL, texctl);
456 OUTREG(MGAREG_TEXCTL2, MGA_TC2_DECALDIS | MGA_TC2_CKSTRANSDIS);
457 OUTREG(MGAREG_DWGCTL, dwgctl);
458 OUTREG(MGAREG_TEXFILTER, ((0x1e << 20) | MGA_MAG_BILIN));
459 OUTREG(MGAREG_ALPHACTRL, alphactrl);
460
461 return TRUE;
462 }
463
464
465 Bool
MGASetupForCPUToScreenTexture(ScrnInfoPtr pScrn,int op,int texType,CARD8 * texPtr,int texPitch,int width,int height,int flags)466 MGASetupForCPUToScreenTexture (
467 ScrnInfoPtr pScrn,
468 int op,
469 int texType,
470 CARD8 *texPtr,
471 int texPitch,
472 int width,
473 int height,
474 int flags
475 ){
476 int log2w, log2h, i, pitch, sizeNeeded, offset;
477 unsigned int texctl, dwgctl, alphactrl;
478 MGAPtr pMga = MGAPTR(pScrn);
479
480 if(op != PictOpOver) /* only one tested */
481 return FALSE;
482
483 if((width > 2048) || (height > 2048))
484 return FALSE;
485
486 log2w = GetPowerOfTwo(width);
487 log2h = GetPowerOfTwo(height);
488
489 CHECK_DMA_QUIESCENT(pMga, pScrn);
490
491 pitch = (width + 15) & ~15;
492 sizeNeeded = pitch * height;
493 if(pScrn->bitsPerPixel == 16)
494 sizeNeeded <<= 1;
495
496 if(!AllocateLinear(pScrn, sizeNeeded))
497 return FALSE;
498
499 offset = pMga->LinearScratch->offset << 1;
500 if(pScrn->bitsPerPixel == 32)
501 offset <<= 1;
502
503 if(pMga->AccelInfoRec->NeedToSync)
504 MGAStormSync(pScrn);
505
506 {
507 CARD8 *dst = (CARD8*)(pMga->FbStart + offset);
508 i = height;
509 while(i--) {
510 memcpy(dst, texPtr, width << 2);
511 texPtr += texPitch;
512 dst += pitch << 2;
513 }
514 }
515
516 tex_padw = 1 << log2w;
517 tex_padh = 1 << log2h;
518
519 WAITFIFO(15);
520 OUTREG(MGAREG_TMR0, (1 << 20) / tex_padw); /* sx inc */
521 OUTREG(MGAREG_TMR1, 0); /* sy inc */
522 OUTREG(MGAREG_TMR2, 0); /* tx inc */
523 OUTREG(MGAREG_TMR3, (1 << 20) / tex_padh); /* ty inc */
524 OUTREG(MGAREG_TMR4, 0x00000000);
525 OUTREG(MGAREG_TMR5, 0x00000000);
526 OUTREG(MGAREG_TMR8, 0x00010000);
527 OUTREG(MGAREG_TEXORG, offset);
528 OUTREG(MGAREG_TEXWIDTH, log2w | (((8 - log2w) & 63) << 9) |
529 ((width - 1) << 18));
530 OUTREG(MGAREG_TEXHEIGHT, log2h | (((8 - log2h) & 63) << 9) |
531 ((height - 1) << 18));
532
533 texctl = MGA_TW32 | MGA_PITCHLIN | MGA_TAKEY | MGA_CLAMPUV |
534 ((pitch & 0x07FF) << 9);
535 dwgctl = MGADWG_TEXTURE_TRAP | MGADWG_I | MGADWG_ARZERO |
536 MGADWG_SGNZERO | MGADWG_SHIFTZERO | 0xc0000;
537 alphactrl = MGA_SRC_ONE | MGA_DST_ONE_MINUS_SRC_ALPHA |
538 MGA_ALPHACHANNEL;
539
540 OUTREG(MGAREG_TEXCTL, texctl);
541 OUTREG(MGAREG_TEXCTL2, MGA_TC2_DECALDIS | MGA_TC2_CKSTRANSDIS);
542 OUTREG(MGAREG_DWGCTL, dwgctl);
543 OUTREG(MGAREG_TEXFILTER, ((0x1e << 20) | MGA_MAG_BILIN));
544 OUTREG(MGAREG_ALPHACTRL, alphactrl);
545
546 return TRUE;
547 }
548 void
MGASubsequentCPUToScreenTexture(ScrnInfoPtr pScrn,int dstx,int dsty,int srcx,int srcy,int width,int height)549 MGASubsequentCPUToScreenTexture (
550 ScrnInfoPtr pScrn,
551 int dstx,
552 int dsty,
553 int srcx,
554 int srcy,
555 int width,
556 int height
557 ){
558 MGAPtr pMga = MGAPTR(pScrn);
559
560 WAITFIFO(4);
561 OUTREG(MGAREG_TMR6, (srcx << 20) / tex_padw);
562 OUTREG(MGAREG_TMR7, (srcy << 20) / tex_padh);
563 OUTREG(MGAREG_FXBNDRY, ((dstx + width) << 16) | (dstx & 0xffff));
564 OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (dsty << 16) | height);
565
566 pMga->AccelInfoRec->NeedToSync = TRUE;
567 }
568
569
570 #endif /* defined(RENDER) */
571 #endif
572
mgaAccelInit(ScreenPtr pScreen)573 Bool mgaAccelInit( ScreenPtr pScreen )
574 {
575 #ifdef USE_XAA
576 XAAInfoRecPtr infoPtr;
577 #endif
578 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
579 MGAPtr pMga = MGAPTR(pScrn);
580 // int maxFastBlitMem, maxlines;
581 #ifdef USE_XAA
582 int maxFastBlitMem;
583 #endif /* USE_XAA */
584 int maxlines;
585
586 #if defined(USE_XAA) && defined(RENDER)
587 Bool doRender = FALSE;
588 #endif /* defined(USE_XAA) && defined(RENDER) */
589 BoxRec AvailFBArea;
590 #ifdef USE_XAA
591 int i;
592 #endif /* USE_XAA */
593
594 pMga->ScratchBuffer = malloc(((pScrn->displayWidth * pMga->CurrentLayout.bitsPerPixel) + 127) >> 3);
595 if(!pMga->ScratchBuffer) return FALSE;
596
597 #ifdef USE_XAA
598 pMga->AccelInfoRec = infoPtr = XAACreateInfoRec();
599 if(!infoPtr) return FALSE;
600 #endif
601
602 pMga->RenderTime = 0;
603 pMga->LinearScratch = 0;
604
605 pMga->MaxFastBlitY = 0;
606 pMga->MaxBlitDWORDS = 0x40000 >> 5;
607
608
609 /* Set initial acceleration flags.
610 */
611 pMga->AccelFlags = pMga->chip_attribs->accel_flags;
612
613 if ((pMga->FbMapSize > 8*1024*1024) && (pScrn->depth == 8)) {
614 pMga->AccelFlags |= LARGE_ADDRESSES;
615 }
616
617 if (pMga->CurrentLayout.bitsPerPixel == 24) {
618 pMga->AccelFlags |= MGA_NO_PLANEMASK;
619 }
620
621 if (pMga->SecondCrtc) {
622 pMga->HasFBitBlt = FALSE;
623 }
624
625 if(pMga->HasSDRAM) {
626 pMga->Atype = pMga->AtypeNoBLK = MGAAtypeNoBLK;
627 pMga->AccelFlags &= ~TWO_PASS_COLOR_EXPAND;
628 } else {
629 pMga->Atype = MGAAtype;
630 pMga->AtypeNoBLK = MGAAtypeNoBLK;
631 }
632
633 #ifdef USE_XAA
634 /* fill out infoPtr here */
635 infoPtr->Flags = PIXMAP_CACHE |
636 OFFSCREEN_PIXMAPS |
637 LINEAR_FRAMEBUFFER |
638 MICROSOFT_ZERO_LINE_BIAS;
639
640 /* sync */
641 infoPtr->Sync = MGAStormSync;
642
643 /* screen to screen copy */
644 infoPtr->ScreenToScreenCopyFlags = NO_TRANSPARENCY;
645 infoPtr->SetupForScreenToScreenCopy =
646 mgaSetupForScreenToScreenCopy;
647 infoPtr->SubsequentScreenToScreenCopy = mgaSubsequentScreenToScreenCopy;
648
649 if(pMga->HasFBitBlt) {
650 infoPtr->FillCacheBltRects = MGAFillCacheBltRects;
651 infoPtr->FillCacheBltRectsFlags = NO_TRANSPARENCY;
652 }
653 /* solid fills */
654 infoPtr->SetupForSolidFill = mgaSetupForSolidFill;
655 infoPtr->SubsequentSolidFillRect = mgaSubsequentSolidFillRect;
656 infoPtr->SubsequentSolidFillTrap = mgaSubsequentSolidFillTrap;
657
658 /* solid lines */
659 infoPtr->SetupForSolidLine = infoPtr->SetupForSolidFill;
660 infoPtr->SubsequentSolidHorVertLine = mgaSubsequentSolidHorVertLine;
661 infoPtr->SubsequentSolidTwoPointLine = mgaSubsequentSolidTwoPointLine;
662
663 /* clipping */
664 infoPtr->SetClippingRectangle = MGASetClippingRectangle;
665 infoPtr->DisableClipping = MGADisableClipping;
666 infoPtr->ClippingFlags = HARDWARE_CLIP_SOLID_LINE |
667 HARDWARE_CLIP_DASHED_LINE |
668 HARDWARE_CLIP_SOLID_FILL |
669 HARDWARE_CLIP_MONO_8x8_FILL;
670
671 #if X_BYTE_ORDER == X_LITTLE_ENDIAN
672 /* dashed lines */
673 infoPtr->DashedLineFlags = LINE_PATTERN_MSBFIRST_LSBJUSTIFIED;
674 infoPtr->SetupForDashedLine = mgaSetupForDashedLine;
675 infoPtr->SubsequentDashedTwoPointLine = mgaSubsequentDashedTwoPointLine;
676 infoPtr->DashPatternMaxLength = 128;
677 #endif
678
679 /* 8x8 mono patterns */
680 infoPtr->Mono8x8PatternFillFlags = HARDWARE_PATTERN_PROGRAMMED_BITS |
681 HARDWARE_PATTERN_PROGRAMMED_ORIGIN |
682 HARDWARE_PATTERN_SCREEN_ORIGIN |
683 BIT_ORDER_IN_BYTE_MSBFIRST;
684 infoPtr->SetupForMono8x8PatternFill = mgaSetupForMono8x8PatternFill;
685 infoPtr->SubsequentMono8x8PatternFillRect =
686 mgaSubsequentMono8x8PatternFillRect;
687 infoPtr->SubsequentMono8x8PatternFillTrap =
688 mgaSubsequentMono8x8PatternFillTrap;
689
690 /* cpu to screen color expansion */
691 infoPtr->ScanlineCPUToScreenColorExpandFillFlags =
692 CPU_TRANSFER_PAD_DWORD |
693 SCANLINE_PAD_DWORD |
694 #if X_BYTE_ORDER == X_BIG_ENDIAN
695 BIT_ORDER_IN_BYTE_MSBFIRST |
696 #else
697 BIT_ORDER_IN_BYTE_LSBFIRST |
698 #endif
699 LEFT_EDGE_CLIPPING |
700 LEFT_EDGE_CLIPPING_NEGATIVE_X;
701
702 if(pMga->ILOADBase) {
703 pMga->ColorExpandBase = pMga->ILOADBase;
704 } else {
705 pMga->ColorExpandBase = pMga->IOBase;
706 }
707 infoPtr->SetupForScanlineCPUToScreenColorExpandFill =
708 mgaSetupForScanlineCPUToScreenColorExpandFill;
709 infoPtr->SubsequentScanlineCPUToScreenColorExpandFill =
710 mgaSubsequentScanlineCPUToScreenColorExpandFill;
711 infoPtr->SubsequentColorExpandScanline = mgaSubsequentColorExpandScanline;
712 infoPtr->NumScanlineColorExpandBuffers = 1;
713 infoPtr->ScanlineColorExpandBuffers = &(pMga->ColorExpandBase);
714
715 /* screen to screen color expansion */
716 if(pMga->AccelFlags & USE_LINEAR_EXPANSION) {
717 infoPtr->ScreenToScreenColorExpandFillFlags =
718 #if X_BYTE_ORDER == X_BIG_ENDIAN
719 BIT_ORDER_IN_BYTE_MSBFIRST;
720 #else
721 BIT_ORDER_IN_BYTE_LSBFIRST;
722 #endif
723 infoPtr->SetupForScreenToScreenColorExpandFill =
724 mgaSetupForScreenToScreenColorExpandFill;
725 infoPtr->SubsequentScreenToScreenColorExpandFill =
726 mgaSubsequentScreenToScreenColorExpandFill;
727 }
728 else if ( pMga->CurrentLayout.bitsPerPixel != 24 ) {
729 /* Alternate (but slower) planar expansions */
730 infoPtr->SetupForScreenToScreenColorExpandFill =
731 mgaSetupForPlanarScreenToScreenColorExpandFill;
732 infoPtr->SubsequentScreenToScreenColorExpandFill =
733 mgaSubsequentPlanarScreenToScreenColorExpandFill;
734 infoPtr->CacheColorExpandDensity = pMga->CurrentLayout.bitsPerPixel;
735 infoPtr->CacheMonoStipple = XAAGetCachePlanarMonoStipple();
736
737 /* It's faster to blit the stipples if you have fastbilt
738 */
739 if(pMga->HasFBitBlt)
740 infoPtr->ScreenToScreenColorExpandFillFlags = TRANSPARENCY_ONLY;
741 }
742
743 /* image writes */
744 infoPtr->ScanlineImageWriteFlags = CPU_TRANSFER_PAD_DWORD |
745 SCANLINE_PAD_DWORD |
746 LEFT_EDGE_CLIPPING |
747 LEFT_EDGE_CLIPPING_NEGATIVE_X |
748 NO_TRANSPARENCY |
749 NO_GXCOPY;
750
751 infoPtr->SetupForScanlineImageWrite = mgaSetupForScanlineImageWrite;
752 infoPtr->SubsequentScanlineImageWriteRect =
753 mgaSubsequentScanlineImageWriteRect;
754 infoPtr->SubsequentImageWriteScanline = mgaSubsequentImageWriteScanline;
755 infoPtr->NumScanlineImageWriteBuffers = 1;
756 infoPtr->ScanlineImageWriteBuffers = &(pMga->ScratchBuffer);
757
758
759 /* midrange replacements */
760
761 if(pMga->ILOADBase && pMga->UsePCIRetry && infoPtr->SetupForSolidFill) {
762 infoPtr->FillSolidRects = MGAFillSolidRectsDMA;
763 infoPtr->FillSolidSpans = MGAFillSolidSpansDMA;
764 }
765
766 if(pMga->AccelFlags & TWO_PASS_COLOR_EXPAND) {
767 if(infoPtr->SetupForMono8x8PatternFill)
768 infoPtr->FillMono8x8PatternRects =
769 MGAFillMono8x8PatternRectsTwoPass;
770 }
771
772 if(infoPtr->SetupForSolidFill) {
773 infoPtr->ValidatePolyArc = MGAValidatePolyArc;
774 infoPtr->PolyArcMask = GCFunction | GCLineWidth | GCPlaneMask |
775 GCLineStyle | GCFillStyle;
776 infoPtr->ValidatePolyPoint = MGAValidatePolyPoint;
777 infoPtr->PolyPointMask = GCFunction | GCPlaneMask;
778 }
779 if(pMga->AccelFlags & MGA_NO_PLANEMASK) {
780 infoPtr->ScanlineImageWriteFlags |= NO_PLANEMASK;
781 infoPtr->ScreenToScreenCopyFlags |= NO_PLANEMASK;
782 infoPtr->ScanlineCPUToScreenColorExpandFillFlags |= NO_PLANEMASK;
783 infoPtr->SolidFillFlags |= NO_PLANEMASK;
784 infoPtr->SolidLineFlags |= NO_PLANEMASK;
785 #if X_BYTE_ORDER == X_LITTLE_ENDIAN
786 infoPtr->DashedLineFlags |= NO_PLANEMASK;
787 #endif
788 infoPtr->Mono8x8PatternFillFlags |= NO_PLANEMASK;
789 infoPtr->ScreenToScreenColorExpandFillFlags |= NO_PLANEMASK;
790 infoPtr->FillSolidRectsFlags |= NO_PLANEMASK;
791 infoPtr->FillSolidSpansFlags |= NO_PLANEMASK;
792 infoPtr->FillMono8x8PatternRectsFlags |= NO_PLANEMASK;
793 infoPtr->FillCacheBltRectsFlags |= NO_PLANEMASK;
794 }
795
796
797 maxFastBlitMem = (pMga->Interleave ? 4096 : 2048) * 1024;
798
799 if(pMga->FbMapSize > maxFastBlitMem) {
800 pMga->MaxFastBlitY = maxFastBlitMem / (pScrn->displayWidth * pMga->CurrentLayout.bitsPerPixel / 8);
801 }
802
803 #endif
804
805 switch (pMga->Chipset) {
806 case PCI_CHIP_MGAG200_SE_A_PCI:
807 case PCI_CHIP_MGAG200_SE_B_PCI:
808 maxlines = (min(pMga->FbUsableSize, 1*1024*1024)) /
809 (pScrn->displayWidth * pMga->CurrentLayout.bitsPerPixel / 8);
810 break;
811 default:
812 maxlines = (min(pMga->FbUsableSize, 16*1024*1024)) /
813 (pScrn->displayWidth * pMga->CurrentLayout.bitsPerPixel / 8);
814 break;
815 }
816
817 #ifdef MGADRI
818 if ( pMga->directRenderingEnabled ) {
819 MGADRIServerPrivatePtr pMGADRIServer = pMga->DRIServerInfo;
820 BoxRec MemBox;
821 int cpp = pScrn->bitsPerPixel / 8;
822 int widthBytes = pScrn->displayWidth * cpp;
823 int bufferSize = ((pScrn->virtualY * widthBytes + MGA_BUFFER_ALIGN)
824 & ~MGA_BUFFER_ALIGN);
825 int scanlines;
826
827 pMGADRIServer->frontOffset = 0;
828 pMGADRIServer->frontPitch = widthBytes;
829
830 /* Try for front, back, depth, and two framebuffers worth of
831 * pixmap cache. Should be enough for a fullscreen background
832 * image plus some leftovers.
833 */
834 pMGADRIServer->textureSize = pMga->FbMapSize - 5 * bufferSize;
835
836 /* If that gives us less than half the available memory, let's
837 * be greedy and grab some more. Sorry, I care more about 3D
838 * performance than playing nicely, and you'll get around a full
839 * framebuffer's worth of pixmap cache anyway.
840 */
841 if ( pMGADRIServer->textureSize < (int)pMga->FbMapSize / 2 ) {
842 pMGADRIServer->textureSize = pMga->FbMapSize - 4 * bufferSize;
843 }
844
845 /* Check to see if there is more room available after the maximum
846 * scanline for textures.
847 */
848 if ( (int)pMga->FbMapSize - maxlines * widthBytes - bufferSize * 2
849 > pMGADRIServer->textureSize ) {
850 pMGADRIServer->textureSize = (pMga->FbMapSize -
851 maxlines * widthBytes -
852 bufferSize * 2);
853 }
854
855 /* Set a minimum usable local texture heap size. This will fit
856 * two 256x256x32bpp textures.
857 */
858 if ( pMGADRIServer->textureSize < 512 * 1024 ) {
859 pMGADRIServer->textureOffset = 0;
860 pMGADRIServer->textureSize = 0;
861 }
862
863 /* Reserve space for textures */
864 pMGADRIServer->textureOffset = (pMga->FbMapSize -
865 pMGADRIServer->textureSize +
866 MGA_BUFFER_ALIGN) & ~MGA_BUFFER_ALIGN;
867
868 /* Reserve space for the shared depth buffer */
869 pMGADRIServer->depthOffset = (pMGADRIServer->textureOffset -
870 bufferSize +
871 MGA_BUFFER_ALIGN) & ~MGA_BUFFER_ALIGN;
872 pMGADRIServer->depthPitch = widthBytes;
873
874 /* Reserve space for the shared back buffer */
875 pMGADRIServer->backOffset = (pMGADRIServer->depthOffset - bufferSize +
876 MGA_BUFFER_ALIGN) & ~MGA_BUFFER_ALIGN;
877 pMGADRIServer->backPitch = widthBytes;
878
879 scanlines = pMGADRIServer->backOffset / widthBytes - 1;
880 if ( scanlines > maxlines ) scanlines = maxlines;
881
882 MemBox.x1 = 0;
883 MemBox.y1 = 0;
884 MemBox.x2 = pScrn->displayWidth;
885 MemBox.y2 = scanlines;
886
887 if ( !xf86InitFBManager( pScreen, &MemBox ) ) {
888 xf86DrvMsg( pScrn->scrnIndex, X_ERROR,
889 "Memory manager initialization to (%d,%d) (%d,%d) failed\n",
890 MemBox.x1, MemBox.y1, MemBox.x2, MemBox.y2 );
891 return FALSE;
892 } else {
893 int width, height;
894
895 xf86DrvMsg( pScrn->scrnIndex, X_INFO,
896 "Memory manager initialized to (%d,%d) (%d,%d)\n",
897 MemBox.x1, MemBox.y1, MemBox.x2, MemBox.y2 );
898
899 if ( xf86QueryLargestOffscreenArea( pScreen, &width,
900 &height, 0, 0, 0 ) ) {
901 xf86DrvMsg( pScrn->scrnIndex, X_INFO,
902 "Largest offscreen area available: %d x %d\n",
903 width, height );
904 }
905 }
906
907 xf86DrvMsg( pScrn->scrnIndex, X_INFO,
908 "Reserved back buffer at offset 0x%x\n",
909 pMGADRIServer->backOffset );
910 xf86DrvMsg( pScrn->scrnIndex, X_INFO,
911 "Reserved depth buffer at offset 0x%x\n",
912 pMGADRIServer->depthOffset );
913 xf86DrvMsg( pScrn->scrnIndex, X_INFO,
914 "Reserved %d kb for textures at offset 0x%x\n",
915 pMGADRIServer->textureSize/1024,
916 pMGADRIServer->textureOffset );
917 }
918 else
919 #endif /* defined(MGADRI) */
920 {
921 AvailFBArea.x1 = 0;
922 AvailFBArea.x2 = pScrn->displayWidth;
923 AvailFBArea.y1 = 0;
924 AvailFBArea.y2 = maxlines;
925
926 /*
927 * Need to keep a strip of memory to the right of screen to workaround
928 * a display problem with the second CRTC.
929 */
930 if (pMga->SecondCrtc)
931 AvailFBArea.x2 = pScrn->virtualX;
932
933 xf86InitFBManager(pScreen, &AvailFBArea);
934 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Using %d lines for offscreen "
935 "memory.\n",
936 maxlines - pScrn->virtualY);
937
938 }
939
940 #ifdef USE_XAA
941 for (i = 0; i < pScrn->numEntities; i++) {
942 if (xf86IsEntityShared(pScrn->entityList[i])) {
943 infoPtr->RestoreAccelState = mgaRestoreAccelState;
944 break;
945 }
946 }
947
948 #ifdef RENDER
949 if(doRender && ((pScrn->bitsPerPixel == 32) || (pScrn->bitsPerPixel == 16)))
950 {
951 if(pMga->Chipset == PCI_CHIP_MGAG400 || pMga->Chipset == PCI_CHIP_MGAG550) {
952 infoPtr->CPUToScreenAlphaTextureFlags = XAA_RENDER_NO_TILE;
953 infoPtr->SetupForCPUToScreenAlphaTexture =
954 MGASetupForCPUToScreenAlphaTexture;
955 } else {
956 infoPtr->CPUToScreenAlphaTextureFlags = XAA_RENDER_NO_TILE |
957 XAA_RENDER_NO_SRC_ALPHA;
958 infoPtr->SetupForCPUToScreenAlphaTexture =
959 MGASetupForCPUToScreenAlphaTextureFaked;
960 }
961 infoPtr->SubsequentCPUToScreenAlphaTexture =
962 MGASubsequentCPUToScreenTexture;
963 infoPtr->CPUToScreenAlphaTextureFormats = MGAAlphaTextureFormats;
964
965 infoPtr->SetupForCPUToScreenTexture = MGASetupForCPUToScreenTexture;
966 infoPtr->SubsequentCPUToScreenTexture = MGASubsequentCPUToScreenTexture;
967 infoPtr->CPUToScreenTextureFlags = XAA_RENDER_NO_TILE;
968 infoPtr->CPUToScreenTextureFormats = MGATextureFormats;
969 }
970 #endif /* defined(RENDER) */
971
972 return(XAAInit(pScreen, infoPtr));
973 #else
974 return TRUE;
975 #endif
976 }
977
978
979 #ifdef USE_XAA
980 /* Support for multiscreen */
mgaRestoreAccelState(ScrnInfoPtr pScrn)981 static void mgaRestoreAccelState(ScrnInfoPtr pScrn)
982 {
983 MGAPtr pMga = MGAPTR(pScrn);
984 MGAFBLayout *pLayout = &pMga->CurrentLayout;
985 unsigned int replicate_fg = 0;
986 unsigned int replicate_bg = 0;
987 unsigned int replicate_pm = 0;
988
989 MGAStormSync(pScrn);
990 WAITFIFO(12);
991 pMga->SrcOrg = 0;
992 OUTREG(MGAREG_MACCESS, pMga->MAccess);
993 OUTREG(MGAREG_PITCH, pLayout->displayWidth);
994 OUTREG(MGAREG_YDSTORG, pMga->YDstOrg);
995
996
997 common_replicate_colors_and_mask( pMga->FgColor, pMga->BgColor,
998 pMga->PlaneMask, pLayout->bitsPerPixel,
999 & replicate_fg, & replicate_bg,
1000 & replicate_pm );
1001
1002 if( (pLayout->bitsPerPixel != 24)
1003 && ((pMga->AccelFlags & MGA_NO_PLANEMASK) == 0) ) {
1004 OUTREG( MGAREG_PLNWT, replicate_pm );
1005 }
1006
1007 OUTREG( MGAREG_BCOL, replicate_bg );
1008 OUTREG( MGAREG_FCOL, replicate_fg );
1009
1010 OUTREG(MGAREG_SRCORG, pMga->realSrcOrg);
1011 OUTREG(MGAREG_DSTORG, pMga->DstOrg);
1012 #if X_BYTE_ORDER == X_LITTLE_ENDIAN
1013 OUTREG(MGAREG_OPMODE, MGAOPM_DMA_BLIT );
1014 #else
1015 OUTREG(MGAREG_OPMODE, MGAOPM_DMA_BLIT | 0x10000);
1016 #endif
1017 OUTREG(MGAREG_CXBNDRY, 0xFFFF0000); /* (maxX << 16) | minX */
1018 OUTREG(MGAREG_YTOP, 0x00000000); /* minPixelPointer */
1019 OUTREG(MGAREG_YBOT, 0x007FFFFF); /* maxPixelPointer */
1020 pMga->AccelFlags &= ~CLIPPER_ON;
1021 }
1022 #endif
1023
1024 CARD32 MGAAtype[16] = {
1025 MGADWG_RPL | 0x00000000, MGADWG_RSTR | 0x00080000,
1026 MGADWG_RSTR | 0x00040000, MGADWG_BLK | 0x000c0000,
1027 MGADWG_RSTR | 0x00020000, MGADWG_RSTR | 0x000a0000,
1028 MGADWG_RSTR | 0x00060000, MGADWG_RSTR | 0x000e0000,
1029 MGADWG_RSTR | 0x00010000, MGADWG_RSTR | 0x00090000,
1030 MGADWG_RSTR | 0x00050000, MGADWG_RSTR | 0x000d0000,
1031 MGADWG_RPL | 0x00030000, MGADWG_RSTR | 0x000b0000,
1032 MGADWG_RSTR | 0x00070000, MGADWG_RPL | 0x000f0000
1033 };
1034
1035
1036 CARD32 MGAAtypeNoBLK[16] = {
1037 MGADWG_RPL | 0x00000000, MGADWG_RSTR | 0x00080000,
1038 MGADWG_RSTR | 0x00040000, MGADWG_RPL | 0x000c0000,
1039 MGADWG_RSTR | 0x00020000, MGADWG_RSTR | 0x000a0000,
1040 MGADWG_RSTR | 0x00060000, MGADWG_RSTR | 0x000e0000,
1041 MGADWG_RSTR | 0x00010000, MGADWG_RSTR | 0x00090000,
1042 MGADWG_RSTR | 0x00050000, MGADWG_RSTR | 0x000d0000,
1043 MGADWG_RPL | 0x00030000, MGADWG_RSTR | 0x000b0000,
1044 MGADWG_RSTR | 0x00070000, MGADWG_RPL | 0x000f0000
1045 };
1046
1047
1048 Bool
MGAStormAccelInit(ScreenPtr pScreen)1049 MGAStormAccelInit(ScreenPtr pScreen)
1050 {
1051 return mgaAccelInit( pScreen );
1052 }
1053
1054
1055
1056 void
MGAStormSync(ScrnInfoPtr pScrn)1057 MGAStormSync(ScrnInfoPtr pScrn)
1058 {
1059 MGAPtr pMga = MGAPTR(pScrn);
1060
1061 CHECK_DMA_QUIESCENT(pMga, pScrn);
1062
1063 /* MGAISBUSY() reportedly causes a freeze for Mystique revisions 0 and 1 */
1064 if (!(pMga->Chipset == PCI_CHIP_MGA1064 && (pMga->ChipRev >= 0 && pMga->ChipRev <= 1)))
1065 while(MGAISBUSY());
1066 /* flush cache before a read (mga-1064g 5.1.6) */
1067 OUTREG8(MGAREG_CRTC_INDEX, 0);
1068 if(pMga->AccelFlags & CLIPPER_ON) {
1069 pMga->AccelFlags &= ~CLIPPER_ON;
1070 OUTREG(MGAREG_CXBNDRY, 0xFFFF0000);
1071 }
1072 }
1073
1074
MGAStormEngineInit(ScrnInfoPtr pScrn)1075 void MGAStormEngineInit( ScrnInfoPtr pScrn )
1076 {
1077 long maccess = 0;
1078 MGAPtr pMga = MGAPTR(pScrn);
1079 MGAFBLayout *pLayout = &pMga->CurrentLayout;
1080 CARD32 opmode;
1081 static const unsigned int maccess_table[5] = {
1082 /* bpp: 8 16 24 32 */
1083 0, 0, 1, 3, 2
1084 };
1085 static const unsigned int opmode_table[5] = {
1086 /* bpp: 8 16 24 32 */
1087 0x00000, 0x00000, 0x10000, 0x20000, 0x20000
1088 };
1089
1090 CHECK_DMA_QUIESCENT(pMga, pScrn);
1091
1092 if ((pMga->Chipset == PCI_CHIP_MGAG100)
1093 || (pMga->Chipset == PCI_CHIP_MGAG100_PCI))
1094 maccess = 1 << 14;
1095
1096 opmode = INREG(MGAREG_OPMODE);
1097
1098 maccess |= maccess_table[ pLayout->bitsPerPixel / 8 ];
1099 if ( pLayout->depth == 15 ) {
1100 maccess |= (1 << 31);
1101 }
1102
1103 opmode |= opmode_table[ pLayout->bitsPerPixel / 8 ];
1104 #if X_BYTE_ORDER == X_LITTLE_ENDIAN
1105 opmode &= ~0x30000;
1106 #endif
1107
1108 #ifdef USE_XAA
1109 pMga->SetupForSolidFill = mgaSetupForSolidFill;
1110 pMga->SubsequentSolidFillRect = mgaSubsequentSolidFillRect;
1111 pMga->RestoreAccelState = mgaRestoreAccelState;
1112 #endif
1113
1114
1115 pMga->fifoCount = 0;
1116
1117 while(MGAISBUSY());
1118
1119 if(!pMga->FifoSize) {
1120 pMga->FifoSize = INREG8(MGAREG_FIFOSTATUS);
1121 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "%i DWORD fifo\n",
1122 pMga->FifoSize);
1123 }
1124
1125 OUTREG(MGAREG_PITCH, pLayout->displayWidth);
1126 OUTREG(MGAREG_YDSTORG, pMga->YDstOrg);
1127 OUTREG(MGAREG_MACCESS, maccess);
1128 pMga->MAccess = maccess;
1129 pMga->PlaneMask = ~0;
1130 /* looks like this doesn't apply to mga g100 pci */
1131
1132 if ((pMga->Chipset != PCI_CHIP_MGAG100)
1133 && (pMga->Chipset != PCI_CHIP_MGAG100_PCI))
1134 OUTREG(MGAREG_PLNWT, pMga->PlaneMask);
1135
1136 pMga->FgColor = 0;
1137 OUTREG(MGAREG_FCOL, pMga->FgColor);
1138 pMga->BgColor = 0;
1139 OUTREG(MGAREG_BCOL, pMga->BgColor);
1140 OUTREG(MGAREG_OPMODE, MGAOPM_DMA_BLIT | opmode);
1141
1142 /* put clipping in a known state */
1143 OUTREG(MGAREG_CXBNDRY, 0xFFFF0000); /* (maxX << 16) | minX */
1144 OUTREG(MGAREG_YTOP, 0x00000000); /* minPixelPointer */
1145 OUTREG(MGAREG_YBOT, 0x007FFFFF); /* maxPixelPointer */
1146 pMga->AccelFlags &= ~CLIPPER_ON;
1147
1148 switch(pMga->Chipset) {
1149 case PCI_CHIP_MGAG550:
1150 case PCI_CHIP_MGAG400:
1151 case PCI_CHIP_MGAG200:
1152 case PCI_CHIP_MGAG200_PCI:
1153 case PCI_CHIP_MGAG200_SE_A_PCI:
1154 case PCI_CHIP_MGAG200_SE_B_PCI:
1155 case PCI_CHIP_MGAG200_WINBOND_PCI:
1156 case PCI_CHIP_MGAG200_EW3_PCI:
1157 case PCI_CHIP_MGAG200_EV_PCI:
1158 case PCI_CHIP_MGAG200_EH_PCI:
1159 case PCI_CHIP_MGAG200_ER_PCI:
1160 case PCI_CHIP_MGAG200_EH3_PCI:
1161 pMga->SrcOrg = 0;
1162 OUTREG(MGAREG_SRCORG, pMga->realSrcOrg);
1163 OUTREG(MGAREG_DSTORG, pMga->DstOrg);
1164 break;
1165 default:
1166 break;
1167 }
1168
1169 if (pMga->is_G200WB)
1170 {
1171 CARD32 dwgctl = MGADWG_RSTR | 0x00060000 | MGADWG_SHIFTZERO |
1172 MGADWG_BITBLT | MGADWG_BFCOL;
1173 WAITFIFO(7);
1174 OUTREG(MGAREG_DWGCTL, dwgctl);
1175 OUTREG(MGAREG_SGN, 0);
1176 OUTREG(MGAREG_AR5, 1);
1177 OUTREG(MGAREG_AR0, 1);
1178 OUTREG(MGAREG_AR3, 0);
1179 OUTREG(MGAREG_FXBNDRY, (1 << 16) | (1 & 0xffff));
1180 OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (1 << 16) | 1);
1181 }
1182
1183 xf86SetLastScrnFlag(pScrn->entityList[0], pScrn->scrnIndex);
1184 }
1185
1186
1187 #ifdef USE_XAA
1188 static void
MGASetClippingRectangle(ScrnInfoPtr pScrn,int x1,int y1,int x2,int y2)1189 MGASetClippingRectangle(
1190 ScrnInfoPtr pScrn,
1191 int x1, int y1, int x2, int y2
1192 ){
1193 MGAPtr pMga = MGAPTR(pScrn);
1194
1195 CHECK_DMA_QUIESCENT(pMga, pScrn);
1196
1197 WAITFIFO(3);
1198 OUTREG(MGAREG_CXBNDRY,(x2 << 16) | x1);
1199 OUTREG(MGAREG_YTOP, (y1 * pScrn->displayWidth) + pMga->YDstOrg);
1200 OUTREG(MGAREG_YBOT, (y2 * pScrn->displayWidth) + pMga->YDstOrg);
1201 pMga->AccelFlags |= CLIPPER_ON;
1202 }
1203
1204 static void
MGADisableClipping(ScrnInfoPtr pScrn)1205 MGADisableClipping(ScrnInfoPtr pScrn)
1206 {
1207 MGAPtr pMga = MGAPTR(pScrn);
1208
1209 CHECK_DMA_QUIESCENT(pMga, pScrn);
1210
1211 WAITFIFO(3);
1212 OUTREG(MGAREG_CXBNDRY, 0xFFFF0000); /* (maxX << 16) | minX */
1213 OUTREG(MGAREG_YTOP, 0x00000000); /* minPixelPointer */
1214 OUTREG(MGAREG_YBOT, 0x007FFFFF); /* maxPixelPointer */
1215 pMga->AccelFlags &= ~CLIPPER_ON;
1216 }
1217
1218
1219 static CARD32
common_setup_for_pattern_fill(MGAPtr pMga,int fg,int bg,int rop,int planemask,CARD32 * reg_data,unsigned int count,CARD32 cmd)1220 common_setup_for_pattern_fill( MGAPtr pMga, int fg, int bg, int rop,
1221 int planemask,
1222 CARD32 * reg_data, unsigned int count,
1223 CARD32 cmd )
1224 {
1225 unsigned int replicate_fg = 0;
1226 unsigned int replicate_bg = 0;
1227 unsigned int replicate_pm = 0;
1228 unsigned int i;
1229
1230
1231 common_replicate_colors_and_mask( fg, bg, planemask,
1232 pMga->CurrentLayout.bitsPerPixel,
1233 & replicate_fg, & replicate_bg,
1234 & replicate_pm );
1235
1236
1237 if( bg == -1 ) {
1238 if ( (pMga->CurrentLayout.bitsPerPixel == 24) && !RGBEQUAL(fg) ) {
1239 cmd |= MGADWG_TRANSC | pMga->AtypeNoBLK[rop];
1240 }
1241 else {
1242 cmd |= MGADWG_TRANSC | pMga->Atype[rop];
1243 }
1244
1245 WAITFIFO( count + 3 );
1246 }
1247 else {
1248 /* (Packed) 24-bit is a funky mode. We only use the Atype table in
1249 * 24-bit if the components of the foreground color and the components
1250 * of the background color are the same (e.g., fg = 0xf8f8f8 and bg =
1251 * 0x131313).
1252 */
1253
1254 if( ((pMga->AccelFlags & BLK_OPAQUE_EXPANSION) != 0)
1255 && ((pMga->CurrentLayout.bitsPerPixel != 24)
1256 || (RGBEQUAL(fg) && RGBEQUAL(bg))) ) {
1257 cmd |= pMga->Atype[rop];
1258 }
1259 else {
1260 cmd |= pMga->AtypeNoBLK[rop];
1261 }
1262
1263 WAITFIFO( count + 4 );
1264 SET_BACKGROUND_REPLICATED( bg, replicate_bg );
1265 }
1266
1267 SET_FOREGROUND_REPLICATED( fg, replicate_fg );
1268 SET_PLANEMASK_REPLICATED( planemask, replicate_pm,
1269 pMga->CurrentLayout.bitsPerPixel );
1270
1271 /* FIXME: Is this the right order? */
1272
1273 for ( i = 0 ; i < count ; i++ ) {
1274 OUTREG( reg_data[0], reg_data[1] );
1275 reg_data += 2;
1276 }
1277
1278 OUTREG(MGAREG_DWGCTL, cmd);
1279
1280 return cmd;
1281 }
1282
1283
1284 /*********************************************\
1285 | Screen-to-Screen Copy |
1286 \*********************************************/
1287
1288 #define BLIT_LEFT 1
1289 #define BLIT_UP 4
1290
mgaDoSetupForScreenToScreenCopy(ScrnInfoPtr pScrn,int xdir,int ydir,int rop,unsigned int planemask,int trans,unsigned bpp)1291 void mgaDoSetupForScreenToScreenCopy( ScrnInfoPtr pScrn, int xdir, int ydir,
1292 int rop, unsigned int planemask,
1293 int trans, unsigned bpp )
1294 {
1295 MGAPtr pMga = MGAPTR(pScrn);
1296 CARD32 dwgctl = pMga->AtypeNoBLK[rop] | MGADWG_SHIFTZERO |
1297 MGADWG_BITBLT | MGADWG_BFCOL;
1298 unsigned int tmp;
1299 unsigned int replicated_trans = 0;
1300 unsigned int replicated_mask = 0;
1301
1302
1303 CHECK_DMA_QUIESCENT(pMga, pScrn);
1304
1305 pMga->AccelInfoRec->SubsequentScreenToScreenCopy =
1306 mgaSubsequentScreenToScreenCopy;
1307
1308 pMga->BltScanDirection = 0;
1309 if(ydir == -1) pMga->BltScanDirection |= BLIT_UP;
1310 if(xdir == -1)
1311 pMga->BltScanDirection |= BLIT_LEFT;
1312 else if(pMga->HasFBitBlt && (rop == GXcopy) && !pMga->DrawTransparent)
1313 pMga->AccelInfoRec->SubsequentScreenToScreenCopy =
1314 mgaSubsequentScreenToScreenCopy_FastBlit;
1315
1316
1317 common_replicate_colors_and_mask( trans, 0, planemask, bpp,
1318 & replicated_trans, & tmp,
1319 & replicated_mask );
1320
1321 if(pMga->DrawTransparent) {
1322 dwgctl |= MGADWG_TRANSC;
1323 WAITFIFO(2);
1324
1325 SET_FOREGROUND_REPLICATED( trans, replicated_trans );
1326 SET_BACKGROUND_REPLICATED( ~0, ~0 );
1327 }
1328
1329 WAITFIFO(4);
1330 OUTREG(MGAREG_DWGCTL, dwgctl);
1331 OUTREG(MGAREG_SGN, pMga->BltScanDirection);
1332
1333 SET_PLANEMASK_REPLICATED( planemask, replicated_mask, bpp );
1334 OUTREG(MGAREG_AR5, ydir * pMga->CurrentLayout.displayWidth);
1335 }
1336
1337
mgaSetupForScreenToScreenCopy(ScrnInfoPtr pScrn,int xdir,int ydir,int rop,unsigned int planemask,int trans)1338 void mgaSetupForScreenToScreenCopy( ScrnInfoPtr pScrn, int xdir, int ydir,
1339 int rop, unsigned int planemask,
1340 int trans )
1341 {
1342 MGAPtr pMga = MGAPTR(pScrn);
1343
1344 mgaDoSetupForScreenToScreenCopy( pScrn, xdir, ydir, rop, planemask, trans,
1345 pMga->CurrentLayout.bitsPerPixel );
1346 }
1347
1348
mgaSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn,int srcX,int srcY,int dstX,int dstY,int w,int h)1349 void mgaSubsequentScreenToScreenCopy( ScrnInfoPtr pScrn,
1350 int srcX, int srcY, int dstX, int dstY,
1351 int w, int h )
1352 {
1353 int start, end, SrcOrg = 0, DstOrg = 0;
1354 MGAPtr pMga = MGAPTR(pScrn);
1355
1356 if (pMga->AccelFlags & LARGE_ADDRESSES) {
1357 const unsigned int display_bit_width =
1358 (pMga->CurrentLayout.displayWidth * pMga->CurrentLayout.bitsPerPixel);
1359
1360 SrcOrg = ((srcY & ~1023) * display_bit_width) >> 9;
1361 DstOrg = ((dstY & ~1023) * display_bit_width) >> 9;
1362 dstY &= 1023;
1363 }
1364
1365 if(pMga->BltScanDirection & BLIT_UP) {
1366 srcY += h - 1;
1367 dstY += h - 1;
1368 }
1369
1370 w--;
1371 start = end = XYADDRESS(srcX, srcY);
1372
1373 if(pMga->BltScanDirection & BLIT_LEFT) start += w;
1374 else end += w;
1375
1376 if (pMga->AccelFlags & LARGE_ADDRESSES) {
1377 WAITFIFO(7);
1378 if(DstOrg)
1379 OUTREG(MGAREG_DSTORG, (DstOrg << 6) + pMga->DstOrg);
1380 if(SrcOrg != pMga->SrcOrg) {
1381 pMga->SrcOrg = SrcOrg;
1382 OUTREG(MGAREG_SRCORG, (SrcOrg << 6) + pMga->realSrcOrg);
1383 }
1384 if(SrcOrg) {
1385 SrcOrg = (SrcOrg << 9) / pMga->CurrentLayout.bitsPerPixel;
1386 end -= SrcOrg;
1387 start -= SrcOrg;
1388 }
1389 OUTREG(MGAREG_AR0, end);
1390 OUTREG(MGAREG_AR3, start);
1391 OUTREG(MGAREG_FXBNDRY, ((dstX + w) << 16) | (dstX & 0xffff));
1392 OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (dstY << 16) | h);
1393 if(DstOrg)
1394 OUTREG(MGAREG_DSTORG, pMga->DstOrg);
1395 } else {
1396 WAITFIFO(4);
1397 OUTREG(MGAREG_AR0, end);
1398 OUTREG(MGAREG_AR3, start);
1399 OUTREG(MGAREG_FXBNDRY, ((dstX + w) << 16) | (dstX & 0xffff));
1400 OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (dstY << 16) | h);
1401 }
1402 }
1403
1404
mgaSubsequentScreenToScreenCopy_FastBlit(ScrnInfoPtr pScrn,int srcX,int srcY,int dstX,int dstY,int w,int h)1405 void mgaSubsequentScreenToScreenCopy_FastBlit( ScrnInfoPtr pScrn,
1406 int srcX, int srcY,
1407 int dstX, int dstY,
1408 int w, int h )
1409 {
1410 int start, end;
1411 MGAPtr pMga = MGAPTR(pScrn);
1412 static const unsigned int masks[5] = {
1413 0, 0x07f, 0x03f, 0x7f, 0x1f
1414 };
1415
1416 if(pMga->BltScanDirection & BLIT_UP) {
1417 srcY += h - 1;
1418 dstY += h - 1;
1419 }
1420
1421 w--;
1422 start = XYADDRESS(srcX, srcY);
1423 end = start + w;
1424
1425 /* we assume the driver asserts screen pitches such that
1426 we can always use fastblit for scrolling */
1427 if(((srcX ^ dstX) & masks[ pMga->CurrentLayout.bitsPerPixel / 8 ]) == 0) {
1428 if(pMga->MaxFastBlitY) {
1429 if(pMga->BltScanDirection & BLIT_UP) {
1430 if((srcY >= pMga->MaxFastBlitY) ||
1431 (dstY >= pMga->MaxFastBlitY))
1432 goto FASTBLIT_BAILOUT;
1433 } else {
1434 if(((srcY + h) > pMga->MaxFastBlitY) ||
1435 ((dstY + h) > pMga->MaxFastBlitY))
1436 goto FASTBLIT_BAILOUT;
1437 }
1438 }
1439
1440 /* Millennium 1 fastblit bug fix */
1441 if(pMga->AccelFlags & FASTBLT_BUG) {
1442 int fxright = dstX + w;
1443 int tmp_dstX = dstX;
1444 int tmp_fxright = fxright;
1445 static const unsigned shift_tab[5] = {
1446 0, 6, 5, 6, 4
1447 };
1448 const unsigned shift = shift_tab[pMga->CurrentLayout.bitsPerPixel / 8];
1449
1450 if (pMga->CurrentLayout.bitsPerPixel == 24) {
1451 tmp_dstX *= 3;
1452 tmp_fxright = fxright * 3 + 2;
1453 }
1454
1455 if( (tmp_dstX & (1 << shift))
1456 && (((tmp_fxright >> shift) - (tmp_dstX >> shift)) & 7) == 7) {
1457 fxright = (tmp_fxright | (1 << shift));
1458 if (pMga->CurrentLayout.bitsPerPixel == 24) {
1459 fxright /= 3;
1460 }
1461
1462 WAITFIFO(8);
1463 OUTREG(MGAREG_CXRIGHT, dstX + w);
1464 OUTREG(MGAREG_DWGCTL, 0x040A400C);
1465 OUTREG(MGAREG_AR0, end);
1466 OUTREG(MGAREG_AR3, start);
1467 OUTREG(MGAREG_FXBNDRY, (fxright << 16) | (dstX & 0xffff));
1468 OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (dstY << 16) | h);
1469 OUTREG(MGAREG_DWGCTL, pMga->AtypeNoBLK[GXcopy] |
1470 MGADWG_SHIFTZERO | MGADWG_BITBLT | MGADWG_BFCOL);
1471 OUTREG(MGAREG_CXRIGHT, 0xFFFF);
1472 return;
1473 }
1474 }
1475
1476 WAITFIFO(6);
1477 OUTREG(MGAREG_DWGCTL, 0x040A400C);
1478 OUTREG(MGAREG_AR0, end);
1479 OUTREG(MGAREG_AR3, start);
1480 OUTREG(MGAREG_FXBNDRY, ((dstX + w) << 16) | (dstX & 0xffff));
1481 OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (dstY << 16) | h);
1482 OUTREG(MGAREG_DWGCTL, pMga->AtypeNoBLK[GXcopy] | MGADWG_SHIFTZERO |
1483 MGADWG_BITBLT | MGADWG_BFCOL);
1484 return;
1485 }
1486
1487 FASTBLIT_BAILOUT:
1488
1489 WAITFIFO(4);
1490 OUTREG(MGAREG_AR0, end);
1491 OUTREG(MGAREG_AR3, start);
1492 OUTREG(MGAREG_FXBNDRY, ((dstX + w) << 16) | (dstX & 0xffff));
1493 OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (dstY << 16) | h);
1494 }
1495
1496 /******************\
1497 | Solid Fills |
1498 \******************/
1499
mgaDoSetupForSolidFill(ScrnInfoPtr pScrn,int color,int rop,unsigned int planemask,unsigned int bpp)1500 void mgaDoSetupForSolidFill( ScrnInfoPtr pScrn, int color, int rop,
1501 unsigned int planemask, unsigned int bpp )
1502 {
1503 MGAPtr pMga = MGAPTR(pScrn);
1504 unsigned int tmp;
1505 unsigned int replicated_color = 0;
1506 unsigned int replicated_planemask = 0;
1507
1508 common_replicate_colors_and_mask( color, 0, planemask, bpp,
1509 & replicated_color, & tmp,
1510 & replicated_planemask );
1511
1512 CHECK_DMA_QUIESCENT(pMga, pScrn);
1513
1514 if ( (bpp == 24) && !RGBEQUAL(color) ) {
1515 pMga->FilledRectCMD = MGADWG_TRAP | MGADWG_SOLID | MGADWG_ARZERO |
1516 MGADWG_SGNZERO | MGADWG_SHIFTZERO |
1517 MGADWG_BMONOLEF | pMga->AtypeNoBLK[rop];
1518 }
1519 else {
1520 pMga->FilledRectCMD = MGADWG_TRAP | MGADWG_SOLID | MGADWG_ARZERO |
1521 MGADWG_SGNZERO | MGADWG_SHIFTZERO |
1522 MGADWG_BMONOLEF | pMga->Atype[rop];
1523 }
1524
1525 pMga->SolidLineCMD = MGADWG_SOLID | MGADWG_SHIFTZERO | MGADWG_BFCOL |
1526 pMga->AtypeNoBLK[rop];
1527
1528 if(pMga->AccelFlags & TRANSC_SOLID_FILL)
1529 pMga->FilledRectCMD |= MGADWG_TRANSC;
1530
1531 WAITFIFO(3);
1532 if ( color != pMga->FgColor ) {
1533 pMga->FgColor = color;
1534 OUTREG( MGAREG_FCOL, replicated_color );
1535 }
1536
1537 if ( (bpp != 24)
1538 && !(pMga->AccelFlags & MGA_NO_PLANEMASK)
1539 && (planemask != pMga->PlaneMask) ) {
1540 pMga->PlaneMask = planemask;
1541 OUTREG( MGAREG_PLNWT, replicated_planemask );
1542 }
1543
1544 OUTREG(MGAREG_DWGCTL, pMga->FilledRectCMD);
1545 }
1546
mgaSetupForSolidFill(ScrnInfoPtr pScrn,int color,int rop,unsigned int planemask)1547 void mgaSetupForSolidFill( ScrnInfoPtr pScrn, int color, int rop,
1548 unsigned int planemask )
1549 {
1550 MGAPtr pMga = MGAPTR(pScrn);
1551
1552 mgaDoSetupForSolidFill( pScrn, color, rop, planemask,
1553 pMga->CurrentLayout.bitsPerPixel );
1554 }
1555
mgaSubsequentSolidFillRect(ScrnInfoPtr pScrn,int x,int y,int w,int h)1556 void mgaSubsequentSolidFillRect( ScrnInfoPtr pScrn,
1557 int x, int y, int w, int h )
1558 {
1559 MGAPtr pMga = MGAPTR(pScrn);
1560
1561 WAITFIFO(2);
1562 OUTREG(MGAREG_FXBNDRY, ((x + w) << 16) | (x & 0xffff));
1563 OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (y << 16) | h);
1564 }
1565
mgaSubsequentSolidFillTrap(ScrnInfoPtr pScrn,int y,int h,int left,int dxL,int dyL,int eL,int right,int dxR,int dyR,int eR)1566 void mgaSubsequentSolidFillTrap( ScrnInfoPtr pScrn, int y, int h,
1567 int left, int dxL, int dyL, int eL,
1568 int right, int dxR, int dyR, int eR )
1569 {
1570 MGAPtr pMga = MGAPTR(pScrn);
1571 int sdxl = (dxL < 0);
1572 int ar2 = sdxl? dxL : -dxL;
1573 int sdxr = (dxR < 0);
1574 int ar5 = sdxr? dxR : -dxR;
1575
1576 WAITFIFO(11);
1577 OUTREG(MGAREG_DWGCTL,
1578 pMga->FilledRectCMD & ~(MGADWG_ARZERO | MGADWG_SGNZERO));
1579 OUTREG(MGAREG_AR0, dyL);
1580 OUTREG(MGAREG_AR1, ar2 - eL);
1581 OUTREG(MGAREG_AR2, ar2);
1582 OUTREG(MGAREG_AR4, ar5 - eR);
1583 OUTREG(MGAREG_AR5, ar5);
1584 OUTREG(MGAREG_AR6, dyR);
1585 OUTREG(MGAREG_SGN, (sdxl << 1) | (sdxr << 5));
1586 OUTREG(MGAREG_FXBNDRY, ((right + 1) << 16) | (left & 0xffff));
1587 OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (y << 16) | h);
1588 OUTREG(MGAREG_DWGCTL, pMga->FilledRectCMD);
1589 }
1590
1591
1592 /***************\
1593 | Solid Lines |
1594 \***************/
1595
mgaSubsequentSolidHorVertLine(ScrnInfoPtr pScrn,int x,int y,int len,int dir)1596 void mgaSubsequentSolidHorVertLine( ScrnInfoPtr pScrn, int x, int y,
1597 int len, int dir )
1598 {
1599 MGAPtr pMga = MGAPTR(pScrn);
1600
1601 if(dir == DEGREES_0) {
1602 WAITFIFO(2);
1603 OUTREG(MGAREG_FXBNDRY, ((x + len) << 16) | (x & 0xffff));
1604 OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (y << 16) | 1);
1605 } else if(pMga->AccelFlags & USE_RECTS_FOR_LINES) {
1606 WAITFIFO(2);
1607 OUTREG(MGAREG_FXBNDRY, ((x + 1) << 16) | (x & 0xffff));
1608 OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (y << 16) | len);
1609 } else {
1610 WAITFIFO(4);
1611 OUTREG(MGAREG_DWGCTL, pMga->SolidLineCMD | MGADWG_AUTOLINE_OPEN);
1612 OUTREG(MGAREG_XYSTRT, (y << 16) | (x & 0xffff));
1613 OUTREG(MGAREG_XYEND + MGAREG_EXEC, ((y + len) << 16) | (x & 0xffff));
1614 OUTREG(MGAREG_DWGCTL, pMga->FilledRectCMD);
1615 }
1616 }
1617
1618
mgaSubsequentSolidTwoPointLine(ScrnInfoPtr pScrn,int x1,int y1,int x2,int y2,int flags)1619 void mgaSubsequentSolidTwoPointLine( ScrnInfoPtr pScrn, int x1, int y1,
1620 int x2, int y2, int flags )
1621 {
1622 MGAPtr pMga = MGAPTR(pScrn);
1623
1624 WAITFIFO(4);
1625 OUTREG(MGAREG_DWGCTL, pMga->SolidLineCMD |
1626 ((flags & OMIT_LAST) ? MGADWG_AUTOLINE_OPEN : MGADWG_AUTOLINE_CLOSE));
1627 OUTREG(MGAREG_XYSTRT, (y1 << 16) | (x1 & 0xFFFF));
1628 OUTREG(MGAREG_XYEND + MGAREG_EXEC, (y2 << 16) | (x2 & 0xFFFF));
1629 OUTREG(MGAREG_DWGCTL, pMga->FilledRectCMD);
1630 }
1631
1632
1633 /***************************\
1634 | 8x8 Mono Pattern Fills |
1635 \***************************/
1636
1637
mgaSetupForMono8x8PatternFill(ScrnInfoPtr pScrn,int patx,int paty,int fg,int bg,int rop,unsigned int planemask)1638 void mgaSetupForMono8x8PatternFill( ScrnInfoPtr pScrn,
1639 int patx, int paty, int fg, int bg,
1640 int rop, unsigned int planemask )
1641 {
1642 MGAPtr pMga = MGAPTR(pScrn);
1643 XAAInfoRecPtr infoRec = pMga->AccelInfoRec;
1644 CARD32 regs[4];
1645
1646 CHECK_DMA_QUIESCENT(pMga, pScrn);
1647
1648 infoRec->SubsequentMono8x8PatternFillRect =
1649 mgaSubsequentMono8x8PatternFillRect;
1650
1651 regs[0] = MGAREG_PAT0;
1652 regs[1] = patx;
1653 regs[2] = MGAREG_PAT1;
1654 regs[3] = paty;
1655
1656 pMga->PatternRectCMD = common_setup_for_pattern_fill( pMga, fg, bg, rop,
1657 planemask, regs, 2,
1658 (MGADWG_TRAP
1659 | MGADWG_ARZERO
1660 | MGADWG_SGNZERO
1661 | MGADWG_BMONOLEF) );
1662 }
1663
1664
mgaSubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn,int patx,int paty,int x,int y,int w,int h)1665 void mgaSubsequentMono8x8PatternFillRect( ScrnInfoPtr pScrn,
1666 int patx, int paty,
1667 int x, int y, int w, int h )
1668 {
1669 MGAPtr pMga = MGAPTR(pScrn);
1670
1671 WAITFIFO(3);
1672 OUTREG(MGAREG_SHIFT, (paty << 4) | patx);
1673 OUTREG(MGAREG_FXBNDRY, ((x + w) << 16) | (x & 0xffff));
1674 OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (y << 16) | h);
1675 pMga->AccelInfoRec->SubsequentMono8x8PatternFillRect =
1676 mgaSubsequentMono8x8PatternFillRect_Additional;
1677 }
1678
mgaSubsequentMono8x8PatternFillRect_Additional(ScrnInfoPtr pScrn,int patx,int paty,int x,int y,int w,int h)1679 static void mgaSubsequentMono8x8PatternFillRect_Additional( ScrnInfoPtr pScrn,
1680 int patx, int paty,
1681 int x, int y,
1682 int w, int h )
1683 {
1684 MGAPtr pMga = MGAPTR(pScrn);
1685
1686 WAITFIFO(2);
1687 OUTREG(MGAREG_FXBNDRY, ((x + w) << 16) | (x & 0xffff));
1688 OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (y << 16) | h);
1689 }
1690
1691
mgaSubsequentMono8x8PatternFillTrap(ScrnInfoPtr pScrn,int patx,int paty,int y,int h,int left,int dxL,int dyL,int eL,int right,int dxR,int dyR,int eR)1692 void mgaSubsequentMono8x8PatternFillTrap( ScrnInfoPtr pScrn,
1693 int patx, int paty,
1694 int y, int h,
1695 int left, int dxL, int dyL, int eL,
1696 int right, int dxR, int dyR, int eR )
1697 {
1698 MGAPtr pMga = MGAPTR(pScrn);
1699
1700 int sdxl = (dxL < 0) ? (1<<1) : 0;
1701 int ar2 = sdxl? dxL : -dxL;
1702 int sdxr = (dxR < 0) ? (1<<5) : 0;
1703 int ar5 = sdxr? dxR : -dxR;
1704
1705 WAITFIFO(12);
1706 OUTREG(MGAREG_SHIFT, (paty << 4) | patx);
1707 OUTREG(MGAREG_DWGCTL,
1708 pMga->PatternRectCMD & ~(MGADWG_ARZERO | MGADWG_SGNZERO));
1709 OUTREG(MGAREG_AR0, dyL);
1710 OUTREG(MGAREG_AR1, ar2 - eL);
1711 OUTREG(MGAREG_AR2, ar2);
1712 OUTREG(MGAREG_AR4, ar5 - eR);
1713 OUTREG(MGAREG_AR5, ar5);
1714 OUTREG(MGAREG_AR6, dyR);
1715 OUTREG(MGAREG_SGN, sdxl | sdxr);
1716 OUTREG(MGAREG_FXBNDRY, ((right + 1) << 16) | (left & 0xffff));
1717 OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (y << 16) | h);
1718 OUTREG(MGAREG_DWGCTL, pMga->PatternRectCMD);
1719 }
1720
1721 /***********************\
1722 | Color Expand Rect |
1723 \***********************/
1724
1725
mgaSetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,int fg,int bg,int rop,unsigned int planemask)1726 void mgaSetupForScanlineCPUToScreenColorExpandFill( ScrnInfoPtr pScrn,
1727 int fg, int bg,
1728 int rop,
1729 unsigned int planemask )
1730 {
1731 MGAPtr pMga = MGAPTR(pScrn);
1732
1733
1734 CHECK_DMA_QUIESCENT(pMga, pScrn);
1735
1736 (void) common_setup_for_pattern_fill( pMga, fg, bg, rop,
1737 planemask, NULL, 0,
1738 MGADWG_ILOAD | MGADWG_LINEAR
1739 | MGADWG_SGNZERO | MGADWG_SHIFTZERO
1740 | MGADWG_BMONOLEF );
1741 }
1742
1743
mgaSubsequentScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,int x,int y,int w,int h,int skipleft)1744 void mgaSubsequentScanlineCPUToScreenColorExpandFill( ScrnInfoPtr pScrn,
1745 int x, int y, int w, int h,
1746 int skipleft )
1747 {
1748 MGAPtr pMga = MGAPTR(pScrn);
1749
1750 pMga->AccelFlags |= CLIPPER_ON;
1751 pMga->expandDWORDs = (w + 31) >> 5;
1752 if((pMga->expandDWORDs * h) > pMga->MaxBlitDWORDS) {
1753 pMga->expandHeight = pMga->MaxBlitDWORDS / pMga->expandDWORDs;
1754 pMga->expandRemaining = h / pMga->expandHeight;
1755 if(!(h = h % pMga->expandHeight)) {
1756 pMga->expandRemaining--;
1757 h = pMga->expandHeight;
1758 }
1759 pMga->expandY = y + h;
1760 } else
1761 pMga->expandRemaining = 0;
1762 pMga->expandRows = h;
1763
1764 WAITFIFO(5);
1765 OUTREG(MGAREG_CXBNDRY, ((x + w - 1) << 16) | ((x + skipleft) & 0xFFFF));
1766 w = pMga->expandDWORDs << 5; /* source is dword padded */
1767 OUTREG(MGAREG_AR0, (w * h) - 1);
1768 OUTREG(MGAREG_AR3, 0); /* crashes occasionally without this */
1769 OUTREG(MGAREG_FXBNDRY, ((x + w - 1) << 16) | (x & 0xFFFF));
1770 OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (y << 16) | h);
1771
1772 #if defined(__alpha__)
1773 if(1) /* force indirect always on Alpha */
1774 #else
1775 if(pMga->expandDWORDs > pMga->FifoSize)
1776 #endif
1777 {
1778 pMga->AccelInfoRec->SubsequentColorExpandScanline =
1779 mgaSubsequentColorExpandScanlineIndirect;
1780 pMga->AccelInfoRec->ScanlineColorExpandBuffers =
1781 (unsigned char**)(&pMga->ScratchBuffer);
1782 } else {
1783 pMga->AccelInfoRec->SubsequentColorExpandScanline =
1784 mgaSubsequentColorExpandScanline;
1785 pMga->AccelInfoRec->ScanlineColorExpandBuffers =
1786 (unsigned char**)(&pMga->ColorExpandBase);
1787 WAITFIFO(pMga->expandDWORDs);
1788 }
1789 }
1790
1791
mgaSubsequentColorExpandScanlineIndirect(ScrnInfoPtr pScrn,int bufno)1792 void mgaSubsequentColorExpandScanlineIndirect( ScrnInfoPtr pScrn,
1793 int bufno )
1794 {
1795 MGAPtr pMga = MGAPTR(pScrn);
1796 int dwords = pMga->expandDWORDs;
1797 CARD32 *src = (CARD32*)(pMga->ScratchBuffer);
1798
1799 while(dwords > pMga->FifoSize) {
1800 WAITFIFO(pMga->FifoSize);
1801 MGAMoveDWORDS((CARD32*)(pMga->ColorExpandBase), src, pMga->FifoSize);
1802 src += pMga->FifoSize;
1803 dwords -= pMga->FifoSize;
1804 }
1805
1806 WAITFIFO(dwords);
1807 MGAMoveDWORDS((CARD32*)(pMga->ColorExpandBase), src, dwords);
1808
1809 if(!(--pMga->expandRows)) {
1810 if(pMga->expandRemaining) {
1811 WAITFIFO(3);
1812 OUTREG(MGAREG_AR0,((pMga->expandDWORDs<< 5)*pMga->expandHeight)-1);
1813 OUTREG(MGAREG_AR3, 0); /* crashes occasionally without this */
1814 OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (pMga->expandY << 16) |
1815 pMga->expandHeight);
1816 pMga->expandY += pMga->expandHeight;
1817 pMga->expandRows = pMga->expandHeight;
1818 pMga->expandRemaining--;
1819 } else {
1820 DISABLE_CLIP();
1821 }
1822 }
1823 }
1824
1825
mgaSubsequentColorExpandScanline(ScrnInfoPtr pScrn,int bufno)1826 void mgaSubsequentColorExpandScanline( ScrnInfoPtr pScrn,
1827 int bufno )
1828 {
1829 MGAPtr pMga = MGAPTR(pScrn);
1830
1831 if(--pMga->expandRows) {
1832 WAITFIFO(pMga->expandDWORDs);
1833 } else if(pMga->expandRemaining) {
1834 WAITFIFO(3);
1835 OUTREG(MGAREG_AR0,((pMga->expandDWORDs<<5)*pMga->expandHeight)-1);
1836 OUTREG(MGAREG_AR3, 0); /* crashes occasionally without this */
1837 OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (pMga->expandY << 16) |
1838 pMga->expandHeight);
1839 pMga->expandY += pMga->expandHeight;
1840 pMga->expandRows = pMga->expandHeight;
1841 pMga->expandRemaining--;
1842 WAITFIFO(pMga->expandDWORDs);
1843 } else {
1844 DISABLE_CLIP();
1845 }
1846 }
1847
1848
1849 /*******************\
1850 | Image Writes |
1851 \*******************/
1852
1853
mgaSetupForScanlineImageWrite(ScrnInfoPtr pScrn,int rop,unsigned int planemask,int transparency_color,int bpp,int depth)1854 void mgaSetupForScanlineImageWrite( ScrnInfoPtr pScrn, int rop,
1855 unsigned int planemask,
1856 int transparency_color,
1857 int bpp, int depth )
1858 {
1859 MGAPtr pMga = MGAPTR(pScrn);
1860 unsigned int replicate_pm = 0;
1861
1862 switch( pMga->CurrentLayout.bitsPerPixel ) {
1863 case 8:
1864 replicate_pm = REPLICATE_8( planemask );
1865 break;
1866 case 16:
1867 replicate_pm = REPLICATE_16( planemask );
1868 break;
1869 case 24:
1870 replicate_pm = REPLICATE_24( planemask );
1871 break;
1872 case 32:
1873 replicate_pm = REPLICATE_32( planemask );
1874 break;
1875 }
1876
1877 CHECK_DMA_QUIESCENT(pMga, pScrn);
1878
1879 WAITFIFO(3);
1880 OUTREG(MGAREG_AR5, 0);
1881 SET_PLANEMASK_REPLICATED( planemask, replicate_pm,
1882 pMga->CurrentLayout.bitsPerPixel );
1883 OUTREG(MGAREG_DWGCTL, MGADWG_ILOAD | MGADWG_BFCOL | MGADWG_SHIFTZERO |
1884 MGADWG_SGNZERO | pMga->AtypeNoBLK[rop]);
1885 }
1886
1887
mgaSubsequentScanlineImageWriteRect(ScrnInfoPtr pScrn,int x,int y,int w,int h,int skipleft)1888 void mgaSubsequentScanlineImageWriteRect( ScrnInfoPtr pScrn,
1889 int x, int y, int w, int h,
1890 int skipleft )
1891 {
1892 MGAPtr pMga = MGAPTR(pScrn);
1893
1894 pMga->AccelFlags |= CLIPPER_ON;
1895 pMga->expandRows = h;
1896 pMga->expandDWORDs = ((w * pMga->CurrentLayout.bitsPerPixel) + 31) >> 5;
1897
1898 WAITFIFO(5);
1899 OUTREG(MGAREG_CXBNDRY, 0xFFFF0000 | ((x + skipleft) & 0xFFFF));
1900 OUTREG(MGAREG_AR0, w - 1);
1901 OUTREG(MGAREG_AR3, 0);
1902 OUTREG(MGAREG_FXBNDRY, ((x + w - 1) << 16) | (x & 0xFFFF));
1903 OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (y << 16) | h);
1904 }
1905
1906
mgaSubsequentImageWriteScanline(ScrnInfoPtr pScrn,int bufno)1907 void mgaSubsequentImageWriteScanline( ScrnInfoPtr pScrn, int bufno )
1908 {
1909 MGAPtr pMga = MGAPTR(pScrn);
1910 int dwords = pMga->expandDWORDs;
1911 CARD32 *src = (CARD32*)(pMga->ScratchBuffer);
1912
1913 while(dwords > pMga->FifoSize) {
1914 WAITFIFO(pMga->FifoSize);
1915 MGAMoveDWORDS((CARD32*)(pMga->ColorExpandBase), src, pMga->FifoSize);
1916 src += pMga->FifoSize;
1917 dwords -= pMga->FifoSize;
1918 }
1919
1920 WAITFIFO(dwords);
1921 MGAMoveDWORDS((CARD32*)(pMga->ColorExpandBase), src, dwords);
1922
1923 if(!(--pMga->expandRows)) {
1924 DISABLE_CLIP();
1925 }
1926 }
1927
1928
1929 #if X_BYTE_ORDER == X_LITTLE_ENDIAN
1930
1931 /***************************\
1932 | Dashed Lines |
1933 \***************************/
1934
mgaSetupForDashedLine(ScrnInfoPtr pScrn,int fg,int bg,int rop,unsigned int planemask,int length,unsigned char * pattern)1935 void mgaSetupForDashedLine( ScrnInfoPtr pScrn,
1936 int fg, int bg, int rop,
1937 unsigned int planemask, int length,
1938 unsigned char *pattern )
1939 {
1940 MGAPtr pMga = MGAPTR(pScrn);
1941 CARD32 *DashPattern = (CARD32*)pattern;
1942 CARD32 NiceDashPattern = DashPattern[0];
1943 int dwords = (length + 31) >> 5;
1944 unsigned int replicate_fg = 0;
1945 unsigned int replicate_bg = 0;
1946 unsigned int replicate_pm = 0;
1947
1948
1949 common_replicate_colors_and_mask( fg, bg, planemask,
1950 pMga->CurrentLayout.bitsPerPixel,
1951 & replicate_fg, & replicate_bg,
1952 & replicate_pm );
1953
1954 CHECK_DMA_QUIESCENT(pMga, pScrn);
1955
1956 pMga->DashCMD = MGADWG_BFCOL | pMga->AtypeNoBLK[rop];
1957 pMga->StyleLen = length - 1;
1958
1959 if(bg == -1) {
1960 pMga->DashCMD |= MGADWG_TRANSC;
1961 WAITFIFO(dwords + 2);
1962 } else {
1963 WAITFIFO(dwords + 3);
1964 SET_BACKGROUND_REPLICATED( bg, replicate_bg );
1965 }
1966
1967 SET_PLANEMASK_REPLICATED( planemask, replicate_pm,
1968 pMga->CurrentLayout.bitsPerPixel );
1969 SET_FOREGROUND_REPLICATED( fg, replicate_fg );
1970
1971
1972 /* We see if we can draw horizontal lines as 8x8 pattern fills. This is
1973 * worthwhile since the pattern fills can use block mode and the default X
1974 * pattern is 8 pixels long. The forward pattern is the top scanline, the
1975 * backwards pattern is the next one.
1976 */
1977 switch(length) {
1978 case 2: NiceDashPattern |= NiceDashPattern << 2;
1979 case 4: NiceDashPattern |= NiceDashPattern << 4;
1980 case 8: {
1981 NiceDashPattern |= byte_reversed[NiceDashPattern] << 16;
1982 NiceDashPattern |= NiceDashPattern << 8;
1983 pMga->NiceDashCMD = MGADWG_TRAP | MGADWG_ARZERO |
1984 MGADWG_SGNZERO | MGADWG_BMONOLEF;
1985 pMga->AccelFlags |= NICE_DASH_PATTERN;
1986
1987 if( bg == -1 ) {
1988 if ( (pMga->CurrentLayout.bitsPerPixel == 24) && !RGBEQUAL(fg) ) {
1989 pMga->NiceDashCMD |= MGADWG_TRANSC | pMga->AtypeNoBLK[rop];
1990 }
1991 else {
1992 pMga->NiceDashCMD |= MGADWG_TRANSC | pMga->Atype[rop];
1993 }
1994 }
1995 else {
1996 /* (Packed) 24-bit is a funky mode. We only use the Atype table
1997 * in 24-bit if the components of the foreground color and the
1998 * components of the background color are the same (e.g., fg =
1999 * 0xf8f8f8 and bg = 0x131313).
2000 */
2001
2002 if( ((pMga->AccelFlags & BLK_OPAQUE_EXPANSION) != 0)
2003 && ((pMga->CurrentLayout.bitsPerPixel != 24)
2004 || (RGBEQUAL(fg) && RGBEQUAL(bg))) ) {
2005 pMga->NiceDashCMD |= pMga->Atype[rop];
2006 }
2007 else {
2008 pMga->NiceDashCMD |= pMga->AtypeNoBLK[rop];
2009 }
2010 }
2011 OUTREG(MGAREG_SRC0, NiceDashPattern);
2012 break;
2013 }
2014 default: {
2015 pMga->AccelFlags &= ~NICE_DASH_PATTERN;
2016 switch (dwords) {
2017 case 4: OUTREG(MGAREG_SRC3, DashPattern[3]);
2018 case 3: OUTREG(MGAREG_SRC2, DashPattern[2]);
2019 case 2: OUTREG(MGAREG_SRC1, DashPattern[1]);
2020 default: OUTREG(MGAREG_SRC0, DashPattern[0]);
2021 }
2022 }
2023 }
2024 }
2025
2026
mgaSubsequentDashedTwoPointLine(ScrnInfoPtr pScrn,int x1,int y1,int x2,int y2,int flags,int phase)2027 void mgaSubsequentDashedTwoPointLine( ScrnInfoPtr pScrn,
2028 int x1, int y1, int x2, int y2,
2029 int flags, int phase )
2030 {
2031 MGAPtr pMga = MGAPTR(pScrn);
2032
2033 WAITFIFO(4);
2034 if((pMga->AccelFlags & NICE_DASH_PATTERN) && (y1 == y2)) {
2035 OUTREG(MGAREG_DWGCTL, pMga->NiceDashCMD);
2036 if(x2 < x1) {
2037 if(flags & OMIT_LAST) x2++;
2038 OUTREG(MGAREG_SHIFT, ((-y1 & 0x07) << 4) |
2039 ((7 - phase - x1) & 0x07));
2040 OUTREG(MGAREG_FXBNDRY, ((x1 + 1) << 16) | (x2 & 0xffff));
2041 } else {
2042 if(!flags) x2++;
2043 OUTREG(MGAREG_SHIFT, (((1 - y1) & 0x07) << 4) |
2044 ((phase - x1) & 0x07));
2045 OUTREG(MGAREG_FXBNDRY, (x2 << 16) | (x1 & 0xffff));
2046 }
2047 OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (y1 << 16) | 1);
2048 } else {
2049 OUTREG(MGAREG_SHIFT, (pMga->StyleLen << 16 ) |
2050 (pMga->StyleLen - phase));
2051 OUTREG(MGAREG_DWGCTL, pMga->DashCMD | ((flags & OMIT_LAST) ?
2052 MGADWG_AUTOLINE_OPEN : MGADWG_AUTOLINE_CLOSE));
2053 OUTREG(MGAREG_XYSTRT, (y1 << 16) | (x1 & 0xFFFF));
2054 OUTREG(MGAREG_XYEND + MGAREG_EXEC, (y2 << 16) | (x2 & 0xFFFF));
2055 }
2056 }
2057 #endif /* X_BYTE_ORDER == X_LITTLE_ENDIAN */
2058
2059
2060 /******************************************\
2061 | Planar Screen to Screen Color Expansion |
2062 \******************************************/
2063
mgaSetupForPlanarScreenToScreenColorExpandFill(ScrnInfoPtr pScrn,int fg,int bg,int rop,unsigned int planemask)2064 void mgaSetupForPlanarScreenToScreenColorExpandFill( ScrnInfoPtr pScrn,
2065 int fg, int bg,
2066 int rop,
2067 unsigned int planemask )
2068 {
2069 MGAPtr pMga = MGAPTR(pScrn);
2070 CARD32 mgaCMD = pMga->AtypeNoBLK[rop] | MGADWG_BITBLT |
2071 MGADWG_SGNZERO | MGADWG_BPLAN;
2072 CARD32 regs[2];
2073
2074
2075 regs[0] = MGAREG_AR5;
2076 regs[1] = pScrn->displayWidth;
2077
2078 CHECK_DMA_QUIESCENT(pMga, pScrn);
2079
2080 (void) common_setup_for_pattern_fill( pMga, fg, bg, 0, planemask, regs, 1,
2081 mgaCMD );
2082 }
2083
2084
mgaSubsequentPlanarScreenToScreenColorExpandFill(ScrnInfoPtr pScrn,int x,int y,int w,int h,int srcx,int srcy,int skipleft)2085 void mgaSubsequentPlanarScreenToScreenColorExpandFill( ScrnInfoPtr pScrn,
2086 int x, int y, int w, int h,
2087 int srcx, int srcy,
2088 int skipleft )
2089 {
2090 MGAPtr pMga = MGAPTR(pScrn);
2091 int start, end;
2092
2093 w--;
2094 start = XYADDRESS(srcx, srcy) + skipleft;
2095 end = start + w;
2096
2097 WAITFIFO(4);
2098 OUTREG(MGAREG_AR3, start);
2099 OUTREG(MGAREG_AR0, end);
2100 OUTREG(MGAREG_FXBNDRY, ((x + w) << 16) | (x & 0xffff));
2101 OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (y << 16) | h);
2102 }
2103
2104
2105 /***********************************\
2106 | Screen to Screen Color Expansion |
2107 \***********************************/
2108
mgaSetupForScreenToScreenColorExpandFill(ScrnInfoPtr pScrn,int fg,int bg,int rop,unsigned int planemask)2109 void mgaSetupForScreenToScreenColorExpandFill( ScrnInfoPtr pScrn,
2110 int fg, int bg,
2111 int rop,
2112 unsigned int planemask )
2113 {
2114 MGAPtr pMga = MGAPTR(pScrn);
2115 CARD32 regs[2];
2116
2117 regs[0] = MGAREG_AR5;
2118 regs[1] = pScrn->displayWidth * pMga->CurrentLayout.bitsPerPixel;
2119
2120 CHECK_DMA_QUIESCENT(pMga, pScrn);
2121
2122 (void) common_setup_for_pattern_fill( pMga, fg, bg, rop, planemask,
2123 regs, 1,
2124 MGADWG_BITBLT | MGADWG_SGNZERO
2125 | MGADWG_SHIFTZERO );
2126 }
2127
2128
mgaSubsequentScreenToScreenColorExpandFill(ScrnInfoPtr pScrn,int x,int y,int w,int h,int srcx,int srcy,int skipleft)2129 void mgaSubsequentScreenToScreenColorExpandFill( ScrnInfoPtr pScrn,
2130 int x, int y, int w, int h,
2131 int srcx, int srcy,
2132 int skipleft )
2133 {
2134 MGAPtr pMga = MGAPTR(pScrn);
2135 const unsigned int display_bit_width =
2136 (pMga->CurrentLayout.displayWidth * pMga->CurrentLayout.bitsPerPixel);
2137 int start, end, next, num;
2138 Bool resetDstOrg = FALSE;
2139
2140 if (pMga->AccelFlags & LARGE_ADDRESSES) {
2141 const int DstOrg = ((y & ~1023) * display_bit_width) >> 9;
2142 const int SrcOrg = ((srcy & ~1023) * display_bit_width) >> 9;
2143
2144 y &= 1023;
2145 srcy &= 1023;
2146
2147 WAITFIFO(2);
2148 if(DstOrg) {
2149 OUTREG(MGAREG_DSTORG, (DstOrg << 6) + pMga->DstOrg);
2150 resetDstOrg = TRUE;
2151 }
2152 if(SrcOrg != pMga->SrcOrg) {
2153 pMga->SrcOrg = SrcOrg;
2154 OUTREG(MGAREG_SRCORG, (SrcOrg << 6) + pMga->realSrcOrg);
2155 }
2156 }
2157
2158 w--;
2159 start = (XYADDRESS(srcx, srcy) * pMga->CurrentLayout.bitsPerPixel)
2160 + skipleft;
2161 end = start + w + (display_bit_width * (h - 1));
2162
2163 /* src cannot split a 2 Meg boundary from SrcOrg */
2164 if(!((start ^ end) & 0xff000000)) {
2165 WAITFIFO(4);
2166 OUTREG(MGAREG_AR3, start);
2167 OUTREG(MGAREG_AR0, start + w);
2168 OUTREG(MGAREG_FXBNDRY, ((x + w) << 16) | (x & 0xffff));
2169 OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (y << 16) | h);
2170 } else {
2171 while(h) {
2172 next = (start + 0x00ffffff) & 0xff000000;
2173 if(next <= (start + w)) {
2174 num = next - start - 1;
2175
2176 WAITFIFO(7);
2177 OUTREG(MGAREG_AR3, start);
2178 OUTREG(MGAREG_AR0, start + num);
2179 OUTREG(MGAREG_FXBNDRY, ((x + num) << 16) | (x & 0xffff));
2180 OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (y << 16) | 1);
2181
2182 OUTREG(MGAREG_AR3, next);
2183 OUTREG(MGAREG_AR0, start + w );
2184 OUTREG(MGAREG_FXBNDRY + MGAREG_EXEC, ((x + w) << 16) |
2185 ((x + num + 1) & 0xffff));
2186 start += display_bit_width;
2187 h--; y++;
2188 } else {
2189 num = ((next - start - w)/display_bit_width) + 1;
2190 if(num > h) num = h;
2191
2192 WAITFIFO(4);
2193 OUTREG(MGAREG_AR3, start);
2194 OUTREG(MGAREG_AR0, start + w);
2195 OUTREG(MGAREG_FXBNDRY, ((x + w) << 16) | (x & 0xffff));
2196 OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (y << 16) | num);
2197
2198 start += num * display_bit_width;
2199 h -= num; y += num;
2200 }
2201 }
2202 }
2203
2204 if(resetDstOrg) {
2205 WAITFIFO(1);
2206 OUTREG(MGAREG_DSTORG, pMga->DstOrg);
2207 }
2208 }
2209
2210
2211 static void
MGAFillSolidRectsDMA(ScrnInfoPtr pScrn,int fg,int rop,unsigned int planemask,int nBox,BoxPtr pBox)2212 MGAFillSolidRectsDMA(
2213 ScrnInfoPtr pScrn,
2214 int fg, int rop,
2215 unsigned int planemask,
2216 int nBox, /* number of rectangles to fill */
2217 BoxPtr pBox /* Pointer to first rectangle to fill */
2218 ){
2219 MGAPtr pMga = MGAPTR(pScrn);
2220 XAAInfoRecPtr infoRec = pMga->AccelInfoRec;
2221 CARD32 *base = (CARD32*)pMga->ILOADBase;
2222
2223 CHECK_DMA_QUIESCENT(pMga, pScrn);
2224
2225 SET_SYNC_FLAG(infoRec);
2226 (*infoRec->SetupForSolidFill)(pScrn, fg, rop, planemask);
2227
2228 if(nBox & 1) {
2229 OUTREG(MGAREG_FXBNDRY, ((pBox->x2) << 16) | (pBox->x1 & 0xffff));
2230 OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC,
2231 (pBox->y1 << 16) | (pBox->y2 - pBox->y1));
2232 nBox--; pBox++;
2233 }
2234
2235 if(!nBox) return;
2236
2237 OUTREG(MGAREG_OPMODE, MGAOPM_DMA_GENERAL);
2238 while(nBox) {
2239 base[0] = DMAINDICES(MGAREG_FXBNDRY, MGAREG_YDSTLEN + MGAREG_EXEC,
2240 MGAREG_FXBNDRY, MGAREG_YDSTLEN + MGAREG_EXEC);
2241 base[1] = ((pBox->x2) << 16) | (pBox->x1 & 0xffff);
2242 base[2] = (pBox->y1 << 16) | (pBox->y2 - pBox->y1);
2243 pBox++;
2244 base[3] = ((pBox->x2) << 16) | (pBox->x1 & 0xffff);
2245 base[4] = (pBox->y1 << 16) | (pBox->y2 - pBox->y1);
2246 pBox++;
2247 base += 5; nBox -= 2;
2248 }
2249 OUTREG(MGAREG_OPMODE, MGAOPM_DMA_BLIT);
2250 }
2251
2252 static void
MGAFillSolidSpansDMA(ScrnInfoPtr pScrn,int fg,int rop,unsigned int planemask,int n,DDXPointPtr ppt,int * pwidth,int fSorted)2253 MGAFillSolidSpansDMA(
2254 ScrnInfoPtr pScrn,
2255 int fg, int rop,
2256 unsigned int planemask,
2257 int n,
2258 DDXPointPtr ppt,
2259 int *pwidth, int fSorted
2260 ){
2261 MGAPtr pMga = MGAPTR(pScrn);
2262 XAAInfoRecPtr infoRec = pMga->AccelInfoRec;
2263 CARD32 *base = (CARD32*)pMga->ILOADBase;
2264
2265 CHECK_DMA_QUIESCENT(pMga, pScrn);
2266 SET_SYNC_FLAG(infoRec);
2267
2268 if(infoRec->ClipBox) {
2269 OUTREG(MGAREG_CXBNDRY,
2270 ((infoRec->ClipBox->x2 - 1) << 16) | infoRec->ClipBox->x1);
2271 OUTREG(MGAREG_YTOP,
2272 (infoRec->ClipBox->y1 * pScrn->displayWidth) + pMga->YDstOrg);
2273 OUTREG(MGAREG_YBOT,
2274 ((infoRec->ClipBox->y2 - 1) * pScrn->displayWidth) + pMga->YDstOrg);
2275 }
2276
2277 (*infoRec->SetupForSolidFill)(pScrn, fg, rop, planemask);
2278
2279 if(n & 1) {
2280 OUTREG(MGAREG_FXBNDRY, ((ppt->x + *pwidth) << 16) | (ppt->x & 0xffff));
2281 OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (ppt->y << 16) | 1);
2282 ppt++; pwidth++; n--;
2283 }
2284
2285 if(n) {
2286 if(n > 838860) n = 838860; /* maximum number we have room for */
2287
2288 OUTREG(MGAREG_OPMODE, MGAOPM_DMA_GENERAL);
2289 while(n) {
2290 base[0] = DMAINDICES(MGAREG_FXBNDRY, MGAREG_YDSTLEN + MGAREG_EXEC,
2291 MGAREG_FXBNDRY, MGAREG_YDSTLEN + MGAREG_EXEC);
2292 base[1] = ((ppt->x + *(pwidth++)) << 16) | (ppt->x & 0xffff);
2293 base[2] = (ppt->y << 16) | 1;
2294 ppt++;
2295 base[3] = ((ppt->x + *(pwidth++)) << 16) | (ppt->x & 0xffff);
2296 base[4] = (ppt->y << 16) | 1;
2297 ppt++;
2298 base += 5; n -= 2;
2299 }
2300 OUTREG(MGAREG_OPMODE, MGAOPM_DMA_BLIT);
2301 }
2302
2303 if(infoRec->ClipBox) {
2304 OUTREG(MGAREG_CXBNDRY, 0xFFFF0000); /* (maxX << 16) | minX */
2305 OUTREG(MGAREG_YTOP, 0x00000000); /* minPixelPointer */
2306 OUTREG(MGAREG_YBOT, 0x007FFFFF); /* maxPixelPointer */
2307 }
2308 }
2309
2310
2311 static void
MGAFillMono8x8PatternRectsTwoPass(ScrnInfoPtr pScrn,int fg,int bg,int rop,unsigned int planemask,int nBoxInit,BoxPtr pBoxInit,int pattern0,int pattern1,int xorg,int yorg)2312 MGAFillMono8x8PatternRectsTwoPass(
2313 ScrnInfoPtr pScrn,
2314 int fg, int bg, int rop,
2315 unsigned int planemask,
2316 int nBoxInit,
2317 BoxPtr pBoxInit,
2318 int pattern0, int pattern1,
2319 int xorg, int yorg
2320 ){
2321 MGAPtr pMga = MGAPTR(pScrn);
2322 XAAInfoRecPtr infoRec = pMga->AccelInfoRec;
2323 int nBox, SecondPassColor;
2324 BoxPtr pBox;
2325
2326 CHECK_DMA_QUIESCENT(pMga, pScrn);
2327
2328 if((rop == GXcopy) && (bg != -1)) {
2329 SecondPassColor = bg;
2330 bg = -1;
2331 } else SecondPassColor = -1;
2332
2333 WAITFIFO(1);
2334 OUTREG(MGAREG_SHIFT, (((-yorg) & 0x07) << 4) | ((-xorg) & 0x07));
2335
2336 SECOND_PASS:
2337
2338 nBox = nBoxInit;
2339 pBox = pBoxInit;
2340
2341 (*infoRec->SetupForMono8x8PatternFill)(pScrn, pattern0, pattern1,
2342 fg, bg, rop, planemask);
2343
2344 while(nBox--) {
2345 WAITFIFO(2);
2346 OUTREG(MGAREG_FXBNDRY, ((pBox->x2) << 16) | (pBox->x1 & 0xffff));
2347 OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC,
2348 (pBox->y1 << 16) | (pBox->y2 - pBox->y1));
2349 pBox++;
2350 }
2351
2352 if(SecondPassColor != -1) {
2353 fg = SecondPassColor;
2354 SecondPassColor = -1;
2355 pattern0 = ~pattern0;
2356 pattern1 = ~pattern1;
2357 goto SECOND_PASS;
2358 }
2359
2360 SET_SYNC_FLAG(infoRec);
2361 }
2362
2363
2364 static void
MGAValidatePolyArc(GCPtr pGC,unsigned long changes,DrawablePtr pDraw)2365 MGAValidatePolyArc(
2366 GCPtr pGC,
2367 unsigned long changes,
2368 DrawablePtr pDraw
2369 ){
2370 ScrnInfoPtr pScrn = xf86ScreenToScrn(pGC->pScreen);
2371 MGAPtr pMga = MGAPTR(pScrn);
2372 Bool fullPlanemask = TRUE;
2373
2374 if((pGC->planemask & pMga->AccelInfoRec->FullPlanemask) !=
2375 pMga->AccelInfoRec->FullPlanemask)
2376 {
2377 if(pMga->AccelFlags & MGA_NO_PLANEMASK) return;
2378 fullPlanemask = FALSE;
2379 }
2380
2381 if(!pGC->lineWidth &&
2382 (pGC->fillStyle == FillSolid) &&
2383 (pGC->lineStyle == LineSolid) &&
2384 ((pGC->alu != GXcopy) || !fullPlanemask))
2385 {
2386 pGC->ops->PolyArc = MGAPolyArcThinSolid;
2387 }
2388 }
2389
2390 static void
MGAPolyPoint(DrawablePtr pDraw,GCPtr pGC,int mode,int npt,xPoint * ppt)2391 MGAPolyPoint (
2392 DrawablePtr pDraw,
2393 GCPtr pGC,
2394 int mode,
2395 int npt,
2396 xPoint *ppt
2397 ){
2398 int numRects = REGION_NUM_RECTS(pGC->pCompositeClip);
2399 XAAInfoRecPtr infoRec;
2400 BoxPtr pbox;
2401 MGAPtr pMga;
2402 int xorg, yorg;
2403 ScrnInfoPtr pScrn;
2404
2405 if(!numRects) return;
2406
2407 if(numRects != 1) {
2408 XAAGetFallbackOps()->PolyPoint(pDraw, pGC, mode, npt, ppt);
2409 return;
2410 }
2411
2412 infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
2413 pScrn = infoRec->pScrn;
2414 pMga = MGAPTR(pScrn);
2415 xorg = pDraw->x;
2416 yorg = pDraw->y;
2417
2418 pbox = REGION_RECTS(pGC->pCompositeClip);
2419
2420 (*infoRec->SetClippingRectangle)(infoRec->pScrn,
2421 pbox->x1, pbox->y1, pbox->x2 - 1, pbox->y2 - 1);
2422 (*infoRec->SetupForSolidFill)(infoRec->pScrn, pGC->fgPixel, pGC->alu,
2423 pGC->planemask);
2424
2425 if(mode == CoordModePrevious) {
2426 while(npt--) {
2427 xorg += ppt->x;
2428 yorg += ppt->y;
2429 WAITFIFO(2);
2430 OUTREG(MGAREG_FXBNDRY, ((xorg + 1) << 16) | (xorg & 0xffff));
2431 OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (yorg << 16) | 1);
2432 ppt++;
2433 }
2434 } else {
2435 int x;
2436 while(npt--) {
2437 x = ppt->x + xorg;
2438 WAITFIFO(2);
2439 OUTREG(MGAREG_FXBNDRY, ((x + 1) << 16) | (x & 0xffff));
2440 OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, ((ppt->y + yorg) << 16) | 1);
2441 ppt++;
2442 }
2443 }
2444
2445 (*infoRec->DisableClipping)(infoRec->pScrn);
2446
2447 SET_SYNC_FLAG(infoRec);
2448 }
2449
2450
2451 static void
MGAValidatePolyPoint(GCPtr pGC,unsigned long changes,DrawablePtr pDraw)2452 MGAValidatePolyPoint(
2453 GCPtr pGC,
2454 unsigned long changes,
2455 DrawablePtr pDraw
2456 ){
2457 ScrnInfoPtr pScrn = xf86ScreenToScrn(pGC->pScreen);
2458 MGAPtr pMga = MGAPTR(pScrn);
2459 Bool fullPlanemask = TRUE;
2460
2461 pGC->ops->PolyPoint = XAAGetFallbackOps()->PolyPoint;
2462
2463 if((pGC->planemask & pMga->AccelInfoRec->FullPlanemask) !=
2464 pMga->AccelInfoRec->FullPlanemask)
2465 {
2466 if(pMga->AccelFlags & MGA_NO_PLANEMASK) return;
2467 fullPlanemask = FALSE;
2468 }
2469
2470 if((pGC->alu != GXcopy) || !fullPlanemask)
2471 pGC->ops->PolyPoint = MGAPolyPoint;
2472 }
2473
2474
2475 static void
MGAFillCacheBltRects(ScrnInfoPtr pScrn,int rop,unsigned int planemask,int nBox,BoxPtr pBox,int xorg,int yorg,XAACacheInfoPtr pCache)2476 MGAFillCacheBltRects(
2477 ScrnInfoPtr pScrn,
2478 int rop,
2479 unsigned int planemask,
2480 int nBox,
2481 BoxPtr pBox,
2482 int xorg, int yorg,
2483 XAACacheInfoPtr pCache
2484 ){
2485 XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
2486 int x, y, phaseY, phaseX, skipleft, height, width, w, blit_w, blit_h, start;
2487
2488 CHECK_DMA_QUIESCENT(MGAPTR(pScrn), pScrn);
2489
2490 (*infoRec->SetupForScreenToScreenCopy)(pScrn, 1, 1, rop, planemask,
2491 pCache->trans_color);
2492
2493 while(nBox--) {
2494 y = pBox->y1;
2495 phaseY = (y - yorg) % pCache->orig_h;
2496 if(phaseY < 0) phaseY += pCache->orig_h;
2497 phaseX = (pBox->x1 - xorg) % pCache->orig_w;
2498 if(phaseX < 0) phaseX += pCache->orig_w;
2499 height = pBox->y2 - y;
2500 width = pBox->x2 - pBox->x1;
2501 start = phaseY ? (pCache->orig_h - phaseY) : 0;
2502
2503 /* This is optimized for WRAM */
2504
2505 if ((rop == GXcopy) && (height >= (pCache->orig_h + start))) {
2506 w = width; skipleft = phaseX; x = pBox->x1;
2507 blit_h = pCache->orig_h;
2508
2509 while(1) {
2510 blit_w = pCache->w - skipleft;
2511 if(blit_w > w) blit_w = w;
2512 (*infoRec->SubsequentScreenToScreenCopy)(pScrn,
2513 pCache->x + skipleft, pCache->y,
2514 x, y + start, blit_w, blit_h);
2515 w -= blit_w;
2516 if(!w) break;
2517 x += blit_w;
2518 skipleft = (skipleft + blit_w) % pCache->orig_w;
2519 }
2520 height -= blit_h;
2521
2522 if(start) {
2523 (*infoRec->SubsequentScreenToScreenCopy)(pScrn,
2524 pBox->x1, y + blit_h, pBox->x1, y, width, start);
2525 height -= start;
2526 y += start;
2527 }
2528 start = blit_h;
2529
2530 while(height) {
2531 if(blit_h > height) blit_h = height;
2532 (*infoRec->SubsequentScreenToScreenCopy)(pScrn,
2533 pBox->x1, y,
2534 pBox->x1, y + start, width, blit_h);
2535 height -= blit_h;
2536 start += blit_h;
2537 blit_h <<= 1;
2538 }
2539 } else {
2540 while(1) {
2541 w = width; skipleft = phaseX; x = pBox->x1;
2542 blit_h = pCache->h - phaseY;
2543 if(blit_h > height) blit_h = height;
2544
2545 while(1) {
2546 blit_w = pCache->w - skipleft;
2547 if(blit_w > w) blit_w = w;
2548 (*infoRec->SubsequentScreenToScreenCopy)(pScrn,
2549 pCache->x + skipleft, pCache->y + phaseY,
2550 x, y, blit_w, blit_h);
2551 w -= blit_w;
2552 if(!w) break;
2553 x += blit_w;
2554 skipleft = (skipleft + blit_w) % pCache->orig_w;
2555 }
2556 height -= blit_h;
2557 if(!height) break;
2558 y += blit_h;
2559 phaseY = (phaseY + blit_h) % pCache->orig_h;
2560 }
2561 }
2562 pBox++;
2563 }
2564
2565 SET_SYNC_FLAG(infoRec);
2566 }
2567 #endif
2568