~ubuntu-branches/ubuntu/gutsy/vnc4/gutsy

« back to all changes in this revision

Viewing changes to unix/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_storm.c

  • Committer: Bazaar Package Importer
  • Author(s): Ola Lundqvist
  • Date: 2006-05-15 20:35:17 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20060515203517-l4lre1ku942mn26k
Tags: 4.1.1+X4.3.0-10
* Correction of critical security issue. Thanks to Martin Kogler
  <e9925248@student.tuwien.ac.at> that informed me about the issue,
  and provided the patch.
  This flaw was originally found by Steve Wiseman of intelliadmin.com.
* Applied patch from Javier Kohen <jkohen@users.sourceforge.net> that
  inform the user that only 8 first characters of the password will
  actually be used when typing more than 8 characters, closes:
  #355619.

Show diffs side-by-side

added added

removed removed

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