|
|
1.1 root 1: /******************************Module*Header*******************************\
2: * Module Name: bitblt.c
3: *
4: * Banked Frame Buffer bitblit
5: *
6: * Copyright (c) 1992 Microsoft Corporation
7: *
8: \**************************************************************************/
9:
10: #include "driver.h"
11:
12: #define SRCBM_CACHE 1
13:
14: BOOL bTest = FALSE;
15:
16: ULONG nColorBrushes,
17: nColorBrushCacheHit,
18: nColorBrushExpansionCacheHit,
19: nColorBrushCacheInvalidations;
20:
21: ULONG nMonoBrushes,
22: nMonoBrushCacheHit,
23: nMonoBrushExpansionCacheHit,
24: nMonoBrushCacheInvalidations;
25:
26: ULONG n8BppBitmaps,
27: n8BppBmCacheHits;
28:
29: ULONG n1BppBitmaps,
30: n1BppBmCacheHits;
31:
32:
33: extern ULONG nSsbMovedToHostFromSrcBmCache;
34:
35: BYTE ajMonoPatPlanes[] = {0x1, 0x2, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80};
36:
37:
38: /// Define the A vector polynomial bits
39: //
40: // Each bit corresponds to one of the terms in the polynomial
41: //
42: // Rop(D,S,P) = a + a D + a S + a P + a DS + a DP + a SP + a DSP
43: // 0 d s p ds dp sp dsp
44:
45: #define AVEC_NOT 0x01
46: #define AVEC_D 0x02
47: #define AVEC_S 0x04
48: #define AVEC_P 0x08
49: #define AVEC_DS 0x10
50: #define AVEC_DP 0x20
51: #define AVEC_SP 0x40
52: #define AVEC_DSP 0x80
53:
54: #define AVEC_NEED_SOURCE (AVEC_S | AVEC_DS | AVEC_SP | AVEC_DSP)
55: #define AVEC_NEED_PATTERN (AVEC_P | AVEC_DP | AVEC_SP | AVEC_DSP)
56:
57: #define BB_TARGET_SCREEN 0x0001
58: #define BB_TARGET_ONLY 0x0002
59: #define BB_SOURCE_COPY 0x0004
60: #define BB_PATTERN_COPY 0x0008
61:
62:
63: /******************************Public*Data*********************************\
64: * ROP translation table
65: *
66: * Translates the usual ternary rop into A-vector notation. Each bit in
67: * this new notation corresponds to a term in a polynomial translation of
68: * the rop.
69: *
70: * Rop(D,S,P) = a + a D + a S + a P + a DS + a DP + a SP + a DSP
71: * 0 d s p ds dp sp dsp
72: \**************************************************************************/
73:
74: BYTE gajRop[] =
75: {
76: 0x00, 0xff, 0xb2, 0x4d, 0xd4, 0x2b, 0x66, 0x99,
77: 0x90, 0x6f, 0x22, 0xdd, 0x44, 0xbb, 0xf6, 0x09,
78: 0xe8, 0x17, 0x5a, 0xa5, 0x3c, 0xc3, 0x8e, 0x71,
79: 0x78, 0x87, 0xca, 0x35, 0xac, 0x53, 0x1e, 0xe1,
80: 0xa0, 0x5f, 0x12, 0xed, 0x74, 0x8b, 0xc6, 0x39,
81: 0x30, 0xcf, 0x82, 0x7d, 0xe4, 0x1b, 0x56, 0xa9,
82: 0x48, 0xb7, 0xfa, 0x05, 0x9c, 0x63, 0x2e, 0xd1,
83: 0xd8, 0x27, 0x6a, 0x95, 0x0c, 0xf3, 0xbe, 0x41,
84: 0xc0, 0x3f, 0x72, 0x8d, 0x14, 0xeb, 0xa6, 0x59,
85: 0x50, 0xaf, 0xe2, 0x1d, 0x84, 0x7b, 0x36, 0xc9,
86: 0x28, 0xd7, 0x9a, 0x65, 0xfc, 0x03, 0x4e, 0xb1,
87: 0xb8, 0x47, 0x0a, 0xf5, 0x6c, 0x93, 0xde, 0x21,
88: 0x60, 0x9f, 0xd2, 0x2d, 0xb4, 0x4b, 0x06, 0xf9,
89: 0xf0, 0x0f, 0x42, 0xbd, 0x24, 0xdb, 0x96, 0x69,
90: 0x88, 0x77, 0x3a, 0xc5, 0x5c, 0xa3, 0xee, 0x11,
91: 0x18, 0xe7, 0xaa, 0x55, 0xcc, 0x33, 0x7e, 0x81,
92: 0x80, 0x7f, 0x32, 0xcd, 0x54, 0xab, 0xe6, 0x19,
93: 0x10, 0xef, 0xa2, 0x5d, 0xc4, 0x3b, 0x76, 0x89,
94: 0x68, 0x97, 0xda, 0x25, 0xbc, 0x43, 0x0e, 0xf1,
95: 0xf8, 0x07, 0x4a, 0xb5, 0x2c, 0xd3, 0x9e, 0x61,
96: 0x20, 0xdf, 0x92, 0x6d, 0xf4, 0x0b, 0x46, 0xb9,
97: 0xb0, 0x4f, 0x02, 0xfd, 0x64, 0x9b, 0xd6, 0x29,
98: 0xc8, 0x37, 0x7a, 0x85, 0x1c, 0xe3, 0xae, 0x51,
99: 0x58, 0xa7, 0xea, 0x15, 0x8c, 0x73, 0x3e, 0xc1,
100: 0x40, 0xbf, 0xf2, 0x0d, 0x94, 0x6b, 0x26, 0xd9,
101: 0xd0, 0x2f, 0x62, 0x9d, 0x04, 0xfb, 0xb6, 0x49,
102: 0xa8, 0x57, 0x1a, 0xe5, 0x7c, 0x83, 0xce, 0x31,
103: 0x38, 0xc7, 0x8a, 0x75, 0xec, 0x13, 0x5e, 0xa1,
104: 0xe0, 0x1f, 0x52, 0xad, 0x34, 0xcb, 0x86, 0x79,
105: 0x70, 0x8f, 0xc2, 0x3d, 0xa4, 0x5b, 0x16, 0xe9,
106: 0x08, 0xf7, 0xba, 0x45, 0xdc, 0x23, 0x6e, 0x91,
107: 0x98, 0x67, 0x2a, 0xd5, 0x4c, 0xb3, 0xfe, 0x01
108: };
109:
110: BOOL b8BppHostToScrnCachedWithRop(
111: SURFOBJ *psoTrg,
112: SURFOBJ *psoSrc,
113: CLIPOBJ *pco,
114: XLATEOBJ *pxlo,
115: RECTL *prclTrg,
116: POINTL *pptlSrc,
117: WORD s3Rop);
118:
119: BOOL b1BppHostToScrnCachedWithRop(
120: SURFOBJ *psoTrg,
121: SURFOBJ *psoSrc,
122: CLIPOBJ *pco,
123: XLATEOBJ *pxlo,
124: RECTL *prclTrg,
125: POINTL *pptlSrc,
126: WORD s3Rop);
127:
128: BOOL b8BppHostToScrnWithRop(
129: SURFOBJ *psoTrg,
130: SURFOBJ *psoSrc,
131: CLIPOBJ *pco,
132: XLATEOBJ *pxlo,
133: RECTL *prclTrg,
134: POINTL *pptlSrc,
135: WORD s3Rop);
136:
137: VOID vLowLevel8BppHostToScrnWithRop(
138: PPDEV ppdev,
139: PPOINT pptTrg,
140: PSIZE psizBlt,
141: PWORD pwFirstWord,
142: INT lSrcDelta,
143: XLATEOBJ *pxlo,
144: WORD s3Rop);
145:
146: BOOL b1BppHostToScrnWithRop(
147: SURFOBJ *psoTrg,
148: SURFOBJ *psoSrc,
149: CLIPOBJ *pco,
150: XLATEOBJ *pxlo,
151: RECTL *prclTrg,
152: POINTL *pptlSrc,
153: WORD s3Rop);
154:
155: VOID vLowLevel1BppHostToScrnWithRop(
156: PPDEV ppdev,
157: PPOINT pptTrg,
158: PSIZE psizBlt,
159: INT xSrc,
160: PWORD pwFirstWord,
161: INT lSrcDelta,
162: XLATEOBJ *pxlo,
163: WORD s3Rop);
164:
165: BOOL b4BppHostToScrnWithRop(
166: SURFOBJ *psoTrg,
167: SURFOBJ *psoSrc,
168: CLIPOBJ *pco,
169: XLATEOBJ *pxlo,
170: RECTL *prclTrg,
171: POINTL *pptlSrc,
172: WORD s3Rop);
173:
174:
175: VOID vLowLevel4BppHostToScrnWithRop(
176: PPDEV ppdev,
177: PPOINT pptTrg,
178: PSIZE psizBlt,
179: INT xSrc,
180: PWORD pwFirstWord,
181: INT lSrcDelta,
182: XLATEOBJ *pxlo,
183: WORD s3Rop);
184:
185:
186: WORD wXlateSrcRop3toS3Rop(PPDEV pdev, WORD rop3);
187:
188: ROP4 bXlatePatRop4toS3Rop(
189: PPDEV pdev,
190: ROP4 rop4);
191:
192: BOOL bDownLoadBrushIntoColorCache(
193: PPDEV ppdev,
194: PS3BRUSH ps3Brush,
195: PPOINT ppt);
196:
197: BOOL bDownLoadBrushIntoMonoCache(
198: PPDEV ppdev,
199: PS3BRUSH p3Brush,
200: PXYZPOINT pxyzPt);
201:
202: BOOL bExpandColorBrushIntoHorzCache(
203: PPDEV ppdev,
204: PPOINT ppt);
205:
206: BOOL bExpandMonoBrushIntoHorzCache(
207: PPDEV ppdev,
208: PXYZPOINT pxyzPtl,
209: INT zHorz);
210:
211: BOOL bExpandColorBrushIntoVertCache(
212: PPDEV ppdev,
213: PPOINT ppt);
214:
215: BOOL bExpandMonoBrushIntoVertCache(
216: PPDEV ppdev,
217: PXYZPOINT pxyzPt,
218: INT zVert);
219:
220: BOOL bColorHorzCacheToScreen(
221: PPDEV ppdev,
222: PS3BRUSH ps3Brush,
223: PPOINT pptBrushOrg,
224: PPOINT pptDest,
225: PSIZE psizDest,
226: WORD s3ForeRop,
227: WORD s3BackRop);
228:
229: BOOL bColorExpandHorzCacheToScreen(
230: PPDEV ppdev,
231: PS3BRUSH ps3Brush,
232: INT zHorz,
233: PPOINT pptBrushOrg,
234: PPOINT pptDest,
235: PSIZE psizDest,
236: WORD s3ForeRop,
237: WORD s3BackRop);
238:
239: BOOL bCpyColorHorzCacheToScreen(
240: PPDEV ppdev,
241: PS3BRUSH ps3Brush,
242: PPOINT pptBrushOrg,
243: PPOINT pptDest,
244: PSIZE psizDest);
245:
246: BOOL bCpyColorExpandHorzCacheToScreen(
247: PPDEV ppdev,
248: PS3BRUSH ps3Brush,
249: INT zHorz,
250: PPOINT pptBrushOrg,
251: PPOINT pptDest,
252: PSIZE psizDest);
253:
254: BOOL bColorVertCacheToScreen(
255: PPDEV ppdev,
256: PS3BRUSH ps3Brush,
257: PPOINT pptBrushOrg,
258: PPOINT pptDest,
259: PSIZE psizDest,
260: WORD s3ForeRop,
261: WORD s3BackRop);
262:
263: BOOL bColorExpandVertCacheToScreen(
264: PPDEV ppdev,
265: PS3BRUSH ps3Brush,
266: INT zHorz,
267: PPOINT pptBrushOrg,
268: PPOINT pptDest,
269: PSIZE psizDest,
270: WORD s3ForeRop,
271: WORD s3BackRop);
272:
273:
274: BOOL bPuntBlit(
275: SURFOBJ *psoTrg,
276: SURFOBJ *psoSrc,
277: SURFOBJ *psoMask,
278: CLIPOBJ *pco,
279: XLATEOBJ *pxlo,
280: RECTL *prclTrg,
281: POINTL *pptlSrc,
282: POINTL *pptlMask,
283: BRUSHOBJ *pbo,
284: POINTL *pptlBrush,
285: ROP4 rop4);
286:
287: BOOL bScrnToScrnPuntBlit(
288: SURFOBJ *psoTrg,
289: SURFOBJ *psoSrc,
290: SURFOBJ *psoMask,
291: CLIPOBJ *pco,
292: XLATEOBJ *pxlo,
293: RECTL *prclTrg,
294: POINTL *pptlSrc,
295: POINTL *pptlMask,
296: BRUSHOBJ *pbo,
297: POINTL *pptlBrush,
298: ROP4 rop4);
299:
300:
301: BOOL bSpecialBlits(
302: SURFOBJ *psoTrg,
303: SURFOBJ *psoSrc,
304: SURFOBJ *psoMask,
305: CLIPOBJ *pco,
306: XLATEOBJ *pxlo,
307: RECTL *prclTrg,
308: POINTL *pptlSrc,
309: POINTL *pptlMask,
310: BRUSHOBJ *pbo,
311: POINTL *pptlBrush,
312: ROP4 rop4);
313:
314: BOOL bScrnToScrnWithRop(
315: SURFOBJ *psoTrg,
316: SURFOBJ *psoSrc,
317: CLIPOBJ *pco,
318: RECTL *prclTrg,
319: POINTL *pptlSrc,
320: WORD s3Rop);
321:
322:
323: VOID S3ScrnToScrnBlt(
324: PPDEV ppdev,
325: INT xSrc,
326: INT ySrc,
327: INT xTrg,
328: INT yTrg,
329: INT width,
330: INT height,
331: WORD s3Rop,
332: WORD Cmd);
333:
334: BOOL bPatternSolid(
335: SURFOBJ *psoTrg,
336: SURFOBJ *psoSrc,
337: SURFOBJ *psoMask,
338: CLIPOBJ *pco,
339: XLATEOBJ *pxlo,
340: RECTL *prclTrg,
341: POINTL *pptlSrc,
342: POINTL *pptlMask,
343: BRUSHOBJ *pbo,
344: POINTL *pptlBrush,
345: ROP4 rop4);
346:
347: VOID vS3SolidPattern(
348: PPDEV ppdev,
349: INT left,
350: INT top,
351: INT width,
352: INT height,
353: INT color,
354: WORD s3Mix);
355:
356:
357: BOOL bPatternBrush(
358: SURFOBJ *psoTrg,
359: CLIPOBJ *pco,
360: RECTL *prclTrg,
361: BRUSHOBJ *pbo,
362: POINTL *pptlBrush,
363: ROP4 rop4);
364:
365:
366:
367: /*****************************************************************************
368: * S3 (Banked Frame Buffer) DrvCopyBits
369: *
370: * An I/O through the transfer register take 43 clocks.
371: * A Memory access on the S3 takes 23 clocks, the memory window wins,
372: * so this transfers bits through the memory window for some things.
373: ****************************************************************************/
374: BOOL DrvCopyBits(
375: SURFOBJ *psoDest,
376: SURFOBJ *psoSrc,
377: CLIPOBJ *pco,
378: XLATEOBJ *pxlo,
379: RECTL *prclDest,
380: POINTL *pptlSrc)
381: {
382: #if defined(_X86_) || defined(i386)
383:
384: INT cy;
385: RECTL rclScans;
386: RECTL rclDest, rclTmp;
387: SURFOBJ *pso;
388: PPDEV ppdev;
389: BOOL bRet, bResetBounds;
390:
391: DISPDBG((3,"S3.DLL!DrvCopyBits - Entry\n"));
392:
393: bResetBounds = FALSE;
394:
395: rclDest = *prclDest;
396:
397: cy = prclDest->bottom - prclDest->top;
398:
399: if (psoDest->iType == STYPE_DEVICE)
400: {
401: ppdev = (PPDEV) psoDest->dhsurf;
402:
403: GPWAIT();
404:
405: if (pco == NULL)
406: pco = ppdev->pcoDefault;
407:
408: if (psoSrc->iType == STYPE_DEVICE)
409: {
410: // At this point we know it's a screen to screen copy.
411: // If a color translation needs to be applied then go through ScrnToScrnPuntBlit
412:
413: if ((pxlo == NULL) || (pxlo->flXlate & XO_TRIVIAL))
414: {
415: bScrnToScrnWithRop(psoDest, psoSrc, pco, prclDest, pptlSrc, OVERPAINT);
416: return (TRUE);
417: }
418: else
419: {
420: bRet = bScrnToScrnPuntBlit(psoDest,
421: psoSrc,
422: NULL,
423: pco,
424: pxlo,
425: prclDest,
426: pptlSrc,
427: NULL,
428: NULL,
429: NULL,
430: 0x0000CCCC);
431:
432: return (bRet);
433: }
434: }
435:
436: else if (psoSrc->lDelta < 0)
437: {
438: rclScans.top = prclDest->top;
439: rclScans.bottom = rclScans.top + cy;
440:
441: pso = ppdev->pSurfObj;
442: psoDest = pso;
443: bBankEnumStart(ppdev, &rclScans, pso, pco);
444: }
445:
446: else
447: {
448: switch (psoSrc->iBitmapFormat)
449: {
450: case BMF_DEVICE:
451: case BMF_8BPP:
452: bRet = b8BppHostToScrnCachedWithRop(psoDest, psoSrc,
453: pco, pxlo,
454: prclDest, pptlSrc,
455: OVERPAINT);
456: break;
457:
458: case BMF_1BPP:
459: bRet = b1BppHostToScrnCachedWithRop(psoDest, psoSrc,
460: pco, pxlo,
461: prclDest, pptlSrc,
462: OVERPAINT);
463: break;
464:
465: case BMF_4BPP:
466: bRet = b4BppHostToScrnWithRop(psoDest, psoSrc, pco, pxlo,
467: prclDest, pptlSrc, OVERPAINT);
468: break;
469:
470: case BMF_16BPP:
471: case BMF_24BPP:
472: case BMF_32BPP:
473: case BMF_4RLE:
474: case BMF_8RLE:
475: default:
476: bRet = FALSE;
477: }
478:
479: if (bRet == TRUE)
480: {
481: return (TRUE);
482: }
483:
484: rclScans.top = prclDest->top;
485: rclScans.bottom = rclScans.top + cy;
486:
487: pso = ppdev->pSurfObj;
488: psoDest = pso;
489: bBankEnumStart(ppdev, &rclScans, pso, pco);
490: }
491: }
492: else
493: {
494: rclScans.top = pptlSrc->y;
495: rclScans.bottom = pptlSrc->y + cy;
496:
497: ppdev = (PPDEV) psoSrc->dhsurf;
498:
499: GPWAIT();
500:
501: if (pco == NULL)
502: {
503: pco = ppdev->pcoDefault;
504:
505: // BUGBUG: This mucking around with pcoDefaults's rclBounds is
506: // no longer required by bSrcBankEnumStart:
507:
508: rclTmp = pco->rclBounds;
509: pco->rclBounds = *prclDest;
510: bResetBounds = TRUE;
511: }
512:
513: pso = ppdev->pSurfObj;
514: psoSrc = pso;
515: bSrcBankEnumStart(ppdev, &rclScans, pso, pco, prclDest);
516: }
517:
518: do
519: {
520: bRet = EngCopyBits(psoDest, psoSrc, pco, pxlo, &rclDest, pptlSrc);
521:
522: } while (bRet && (bBankEnum(ppdev, &rclScans, pso, pco)));
523:
524: bBankEnumEnd(ppdev, pso, pco);
525:
526: if (bResetBounds)
527: {
528: ppdev->pcoDefault->rclBounds = rclTmp;
529: }
530:
531: return(bRet);
532:
533: #else
534:
535: // A DrvCopyBits is just a simplified DrvBitBlt:
536:
537: return(DrvBitBlt(psoDest,
538: psoSrc,
539: NULL, // psoMask
540: pco,
541: pxlo,
542: prclDest,
543: pptlSrc,
544: NULL, // pptlMask
545: NULL, // pbo
546: NULL, // pptlBrush
547: 0x0000CCCC)); // mix = SRCCOPY
548:
549: #endif
550: }
551:
552:
553:
554:
555: /*****************************************************************************
556: * S3 DrvBitBlt
557: ****************************************************************************/
558: BOOL DrvBitBlt(
559: SURFOBJ *psoTrg,
560: SURFOBJ *psoSrc,
561: SURFOBJ *psoMask,
562: CLIPOBJ *pco,
563: XLATEOBJ *pxlo,
564: RECTL *prclTrg,
565: POINTL *pptlSrc,
566: POINTL *pptlMask,
567: BRUSHOBJ *pbo,
568: POINTL *pptlBrush,
569: ROP4 rop4)
570:
571: {
572: BOOL b;
573: PPDEV ppdev;
574:
575: DISPDBG((3,"S3.DLL!DrvBitBlt - Entry\n"));
576:
577: // Since we don't support Device-Format Bitmaps, either the source
578: // or the destination (or both) will be the device surface:
579:
580: if (psoTrg->iType == STYPE_DEVICE)
581: ppdev = (PPDEV) psoTrg->dhpdev;
582: else
583: ppdev = (PPDEV) psoSrc->dhpdev;
584:
585: // Protect the driver from a potentially NULL clip object.
586:
587: if (pco == NULL)
588: {
589: pco = ppdev->pcoDefault;
590: }
591:
592: if (bTest == FALSE)
593: {
594: b = bSpecialBlits(psoTrg, psoSrc, psoMask,
595: pco, pxlo,
596: prclTrg, pptlSrc, pptlMask,
597: pbo, pptlBrush,
598: rop4);
599: }
600: else
601: {
602: b = FALSE;
603: }
604:
605: if (b != TRUE)
606: {
607: bPuntBlit(psoTrg,
608: psoSrc,
609: psoMask,
610: pco,
611: pxlo,
612: prclTrg,
613: pptlSrc,
614: pptlMask,
615: pbo,
616: pptlBrush,
617: rop4);
618: }
619:
620: return (TRUE);
621: }
622:
623: /*****************************************************************************
624: * S3 General purpose blit handler. This routine will handle any blit.
625: * Albeit slow, but it will be handled.
626: *
627: * Returns TRUE if the blit was handled.
628: ****************************************************************************/
629: BOOL bPuntBlit(
630: SURFOBJ *psoTrg,
631: SURFOBJ *psoSrc,
632: SURFOBJ *psoMask,
633: CLIPOBJ *pco,
634: XLATEOBJ *pxlo,
635: RECTL *prclTrg,
636: POINTL *pptlSrc,
637: POINTL *pptlMask,
638: BRUSHOBJ *pbo,
639: POINTL *pptlBrush,
640: ROP4 rop4)
641: {
642:
643:
644: #if defined(_X86_) || defined(i386)
645:
646: RECTL rclScans;
647: RECTL rclTrg;
648: PPDEV ppdevTrg, ppdevSrc, ppdevBank;
649: SURFOBJ *psoBank;
650: BOOL bRet;
651: PPDEV ppdev;
652:
653: DISPDBG((2,"S3.DLL!bPuntBlit - Entry\n"));
654:
655: if (psoTrg->iType == STYPE_DEVICE)
656: ppdev = (PPDEV) psoTrg->dhsurf;
657: else
658: ppdev = (PPDEV) psoSrc->dhsurf;
659:
660: // Wait for the S3 coprocessor to finish with the VRAM before we touch it through
661: // the apperature.
662:
663: GPWAIT();
664:
665: rclTrg = *prclTrg;
666:
667: rclScans.top = prclTrg->top;
668: rclScans.bottom = prclTrg->bottom;
669:
670: // Get the correct surface object for the target and the source
671:
672: if ((psoTrg->iType == STYPE_DEVICE) &&
673: ((psoSrc == NULL) || (psoSrc->iType != STYPE_DEVICE)))
674: {
675: ppdevTrg = (PPDEV) psoTrg->dhsurf;
676: psoTrg = ppdevTrg->pSurfObj;
677:
678: bBankEnumStart(ppdevTrg, &rclScans, psoTrg, pco);
679: ppdevBank = ppdevTrg;
680: psoBank = psoTrg;
681:
682: }
683:
684: else if ((psoTrg->iType != STYPE_DEVICE) &&
685: (psoSrc != NULL) && (psoSrc->iType == STYPE_DEVICE))
686: {
687: ppdevSrc = (PPDEV) psoSrc->dhsurf;
688: psoSrc = ppdevSrc->pSurfObj;
689:
690: rclScans.top = pptlSrc->y;
691: rclScans.bottom = pptlSrc->y + (prclTrg->bottom - prclTrg->top);
692:
693: bSrcBankEnumStart(ppdevSrc, &rclScans, psoSrc, pco, prclTrg);
694: ppdevBank = ppdevSrc;
695: psoBank = psoSrc;
696:
697: }
698: else
699: {
700: bRet = bScrnToScrnPuntBlit(psoTrg,
701: psoSrc,
702: psoMask,
703: pco,
704: pxlo,
705: prclTrg,
706: pptlSrc,
707: pptlMask,
708: pbo,
709: pptlBrush,
710: rop4);
711: return (bRet);
712: }
713:
714: do
715: {
716: bRet = EngBitBlt(psoTrg,
717: psoSrc,
718: psoMask,
719: pco,
720: pxlo,
721: &rclTrg,
722: pptlSrc,
723: pptlMask,
724: pbo,
725: pptlBrush,
726: rop4);
727:
728: } while ((bBankEnum(ppdevBank, &rclScans, psoBank, pco)) && bRet);
729:
730: bBankEnumEnd(ppdevBank, psoBank, pco);
731:
732: return bRet;
733:
734: #else
735:
736: BOOL bRet;
737: PPDEV ppdev;
738: RECTL rclSrc;
739:
740: if (psoTrg->iType == STYPE_DEVICE)
741: {
742: ppdev = (PPDEV) psoTrg->dhsurf;
743:
744: if ((psoSrc != NULL) && (psoSrc->iType == STYPE_DEVICE))
745: {
746: // -------------------------------------------------------
747: // Handle screen-to-screen blit:
748:
749: // We have to copy both the source rectangle and the destination
750: // rectangle to the temporary bitmap (the destination rectangle
751: // is needed if there's complex clipping or if there's a ROP that
752: // affects need the destination).
753: //
754: // We simply copy the smallest entire rectangle containing both
755: // the source and the destination rectangles:
756:
757: rclSrc.left = min(pptlSrc->x, prclTrg->left);
758: rclSrc.top = min(pptlSrc->y, prclTrg->top);
759: rclSrc.right = max(pptlSrc->x + prclTrg->right - prclTrg->left,
760: prclTrg->right);
761: rclSrc.bottom = max(pptlSrc->y + prclTrg->bottom - prclTrg->top,
762: prclTrg->bottom);
763:
764: vPuntGetBits(ppdev, psoSrc, &rclSrc);
765:
766: // Now do the copy entirely on the temporary bitmap surface:
767:
768: bRet = EngBitBlt(ppdev->psoTemp,
769: ppdev->psoTemp,
770: psoMask,
771: pco,
772: pxlo,
773: prclTrg,
774: pptlSrc,
775: pptlMask,
776: pbo,
777: pptlBrush,
778: rop4);
779:
780: // Just have to copy the destination back to the surface:
781:
782: if (bRet)
783: {
784: vPuntPutBits(ppdev, psoTrg, prclTrg);
785: }
786: }
787: else
788: {
789: // -------------------------------------------------------
790: // Handle bitmap-to-screen blit:
791:
792: // Make a copy of the destination rectangle in case the ROP
793: // modifies the destination:
794:
795: vPuntGetBits(ppdev, psoTrg, prclTrg);
796:
797: // Do the blit operation on the temporary bitmap:
798:
799: bRet = EngBitBlt(ppdev->psoTemp,
800: psoSrc,
801: psoMask,
802: pco,
803: pxlo,
804: prclTrg,
805: pptlSrc,
806: pptlMask,
807: pbo,
808: pptlBrush,
809: rop4);
810:
811: // Copy everything back to the surface:
812:
813: if (bRet)
814: {
815: vPuntPutBits(ppdev, psoTrg, prclTrg);
816: }
817: }
818: }
819: else
820: {
821: // -------------------------------------------------------
822: // Handle screen-to-bitmap blit:
823:
824: ppdev = (PPDEV) psoSrc->dhsurf;
825:
826: // Copy the source rectangle to the temporary bitmap, then get
827: // GDI to blit to the target surface:
828:
829: rclSrc.left = pptlSrc->x;
830: rclSrc.top = pptlSrc->y;
831: rclSrc.right = pptlSrc->x + (prclTrg->right - prclTrg->left);
832: rclSrc.bottom = pptlSrc->y + (prclTrg->bottom - prclTrg->top);
833:
834: vPuntGetBits(ppdev, psoSrc, &rclSrc);
835:
836: bRet = EngBitBlt(psoTrg,
837: ppdev->psoTemp,
838: psoMask,
839: pco,
840: pxlo,
841: prclTrg,
842: pptlSrc,
843: pptlMask,
844: pbo,
845: pptlBrush,
846: rop4);
847: }
848:
849: vResetS3Clipping(ppdev); // Always reset after using vPunt routines
850:
851: return(bRet);
852:
853: #endif
854: }
855:
856: /******************************************************************************
857: * bScrnToScrnPuntBlit - Screen To Screen Punt Blit
858: *****************************************************************************/
859: BOOL bScrnToScrnPuntBlit(
860: SURFOBJ *psoTrg,
861: SURFOBJ *psoSrc,
862: SURFOBJ *psoMask,
863: CLIPOBJ *pco,
864: XLATEOBJ *pxlo,
865: RECTL *prclTrg,
866: POINTL *pptlSrc,
867: POINTL *pptlMask,
868: BRUSHOBJ *pbo,
869: POINTL *pptlBrush,
870: ROP4 rop4)
871: {
872:
873: SIZEL sizl;
874: HSURF hsurfBm;
875: SURFOBJ *psoTempSrc;
876: WORD cmd;
877: INT i, cxInWords;
878: PBYTE pb;
879: PWORD pw;
880: PPDEV ppdev;
881: RECTL rclScans, rclTrg;
882: BOOL bRet;
883: POINTL ptlTempSrc;
884:
885: DISPDBG((2,"S3.DLL!bScrnToScrnPuntBlit - Entry\n"));
886:
887: // Pickup our pdev and a pointer to the surface object.
888:
889: ppdev = (PPDEV) psoTrg->dhsurf;
890: psoTrg = ppdev->pSurfObj;
891:
892: // Set the default bounding rectangle for the bank manager.
893:
894: rclTrg = *prclTrg;
895:
896: // Create a temporary surface and bitmap.
897:
898: sizl.cx = prclTrg->right - prclTrg->left;
899: sizl.cy = prclTrg->bottom - prclTrg->top;
900:
901: hsurfBm = (HSURF) EngCreateBitmap(sizl,
902: sizl.cx,
903: BMF_8BPP,
904: BMF_TOPDOWN,
905: NULL);
906: if (hsurfBm == NULL)
907: {
908: DISPDBG((0, "S3.DLL!bScrnToScrnPuntBlit - EngCreateBitmap failed\n"));
909: return(FALSE);
910: }
911:
912: // Get a pointer to the surface object.
913:
914: psoTempSrc = EngLockSurface(hsurfBm);
915:
916: // Copy the bits into it.
917:
918: if (!(sizl.cx & 0x01))
919: {
920: cmd = RECTANGLE_FILL | BYTE_SWAP | BUS_SIZE_16 |
921: DRAWING_DIR_TBLRXM | DIR_TYPE_XY | WAIT |
922: DRAW | LAST_PIXEL_ON | READ;
923: }
924: else
925: {
926: cmd = RECTANGLE_FILL | BUS_SIZE_8 |
927: DRAWING_DIR_TBLRXM | DIR_TYPE_XY | WAIT |
928: DRAW | LAST_PIXEL_ON | READ;
929: }
930:
931: FIFOWAIT(FIFO_7_EMPTY);
932:
933: TEST_AND_SET_RD_MASK(0xff);
934: OUTPW (MULTIFUNC_CNTL, (DATA_EXTENSION | ALL_ONES));
935:
936: OUTPW (CUR_X, pptlSrc->x);
937: OUTPW (CUR_Y, pptlSrc->y);
938: OUTPW (RECT_WIDTH, (sizl.cx - 1));
939: OUTPW (MULTIFUNC_CNTL, (RECT_HEIGHT | (sizl.cy - 1)));
940:
941: GPWAIT();
942:
943: OUTPW (CMD, cmd);
944:
945: // Wait for the Data Available.
946:
947: while (!(inpw(GP_STAT) & READ_DATA_AVAILABLE));
948:
949: // Now transfer the data from the screen to the host memory bitmap.
950:
951: if (!(sizl.cx & 0x01))
952: {
953: cxInWords = (sizl.cx + 1) / 2;
954: pw = (PWORD) psoTempSrc->pvScan0;
955: for (i = 0; i < sizl.cy; i++)
956: {
957: vDataPortIn(ppdev, pw, cxInWords);
958: ((PBYTE) pw) += psoTempSrc->lDelta;
959: }
960: }
961: else
962: {
963: pb = psoTempSrc->pvScan0;
964: for (i = 0; i < sizl.cy; i++)
965: {
966: vDataPortInB(ppdev, pb, sizl.cx);
967: pb += psoTempSrc->lDelta;
968: }
969: }
970:
971: // Set the new source position
972:
973: ptlTempSrc.x = 0;
974: ptlTempSrc.y = 0;
975:
976: // Do the banked blit operation.
977:
978: rclScans.top = prclTrg->top;
979: rclScans.bottom = prclTrg->bottom;
980:
981: bBankEnumStart(ppdev, &rclScans, psoTrg, pco);
982:
983: do
984: {
985: bRet = EngBitBlt(psoTrg,
986: psoTempSrc,
987: psoMask,
988: pco,
989: pxlo,
990: &rclTrg,
991: &ptlTempSrc,
992: pptlMask,
993: pbo,
994: pptlBrush,
995: rop4);
996:
997: } while ((bBankEnum(ppdev, &rclScans, psoTrg, pco)) && bRet);
998:
999: bBankEnumEnd(ppdev, psoTrg, pco);
1000:
1001: // free the temp bitmap.
1002:
1003: EngUnlockSurface(psoTempSrc);
1004: EngDeleteSurface(hsurfBm);
1005:
1006: return (bRet);
1007:
1008: }
1009:
1010: /*****************************************************************************
1011: * S3 Special case Blit handler
1012: *
1013: * Returns TRUE if the blit was handled.
1014: ****************************************************************************/
1015: BOOL bSpecialBlits(
1016: SURFOBJ *psoTrg,
1017: SURFOBJ *psoSrc,
1018: SURFOBJ *psoMask,
1019: CLIPOBJ *pco,
1020: XLATEOBJ *pxlo,
1021: RECTL *prclTrg,
1022: POINTL *pptlSrc,
1023: POINTL *pptlMask,
1024: BRUSHOBJ *pbo,
1025: POINTL *pptlBrush,
1026: ROP4 rop4)
1027: {
1028: BOOL bRet;
1029: PPDEV ppdev;
1030: ROP4 s3Rop4;
1031: WORD avecRop, s3Rop;
1032: BRUSHOBJ bo;
1033:
1034: bRet = FALSE;
1035:
1036: if (psoTrg->iType == STYPE_DEVICE)
1037: ppdev = (PPDEV) psoTrg->dhsurf;
1038: else
1039: ppdev = (PPDEV) psoSrc->dhsurf;
1040:
1041: // NOTE: If the ForeRop and BackRop are the same implicitly
1042: // there is no mask.
1043:
1044: // First test for copy opperations.
1045:
1046: if (rop4 == 0x0000CCCC)
1047: {
1048: if ((psoTrg->iType == STYPE_DEVICE) && (psoSrc->iType == STYPE_DEVICE))
1049: {
1050: if ((pxlo == NULL) || (pxlo->flXlate & XO_TRIVIAL))
1051: {
1052: bRet = bScrnToScrnWithRop(psoTrg, psoSrc, pco, prclTrg, pptlSrc, OVERPAINT);
1053: return(bRet);
1054: }
1055: else
1056: {
1057: return (FALSE);
1058: }
1059: }
1060:
1061: }
1062:
1063: // Check for a mask. If there is one, at this time, reject the
1064: // acceleration.
1065:
1066: if (psoMask != NULL)
1067: {
1068: return (FALSE);
1069: }
1070:
1071: // If the background and foreground rops are not the same
1072: // reject the blit.
1073:
1074: if (((rop4 & 0xFF00) >> 8) != (rop4 & 0xff))
1075: {
1076: return (FALSE);
1077: }
1078:
1079: // Pickup the avec for some quick decision later.
1080:
1081: avecRop = gajRop[(rop4 & 0xff)];
1082:
1083: // Check for a DIB. If this is a DIB reject the blit.
1084: // BUGBUG: At some future date (post BETA2) this should be optimized.
1085:
1086: if ((avecRop & AVEC_NEED_SOURCE) && (psoSrc->lDelta < 0))
1087: {
1088: return (FALSE);
1089: }
1090:
1091: // Check for whitness or blackness
1092:
1093: if (((rop4 & 0xff) == 0xff) ||
1094: ((rop4 & 0xff) == 0x00))
1095: {
1096: if ((rop4 & 0xff) == 0xff)
1097: s3Rop4 = LOGICAL_1;
1098: else
1099: s3Rop4 = LOGICAL_0;
1100:
1101: bRet = bPatternSolid(psoTrg, psoSrc, psoMask,
1102: pco, pxlo,
1103: prclTrg, pptlSrc, pptlMask,
1104: pbo, pptlBrush,
1105: s3Rop4);
1106: return (bRet);
1107: }
1108:
1109: // Check for Dest Invert
1110:
1111: if ((rop4 & 0xff) == 0x55)
1112: {
1113: s3Rop4 = SCREEN_XOR_NEW;
1114: bo.iSolidColor = 0xffff;
1115:
1116: bRet = bPatternSolid(psoTrg, psoSrc, psoMask,
1117: pco, pxlo,
1118: prclTrg, pptlSrc, pptlMask,
1119: &bo, pptlBrush,
1120: s3Rop4);
1121: return (bRet);
1122:
1123: }
1124:
1125:
1126: // Check for brushes.
1127:
1128: if ((avecRop & AVEC_NEED_PATTERN) && (!(avecRop & AVEC_NEED_SOURCE)))
1129: {
1130: // Translate the rop from GDI to S3.
1131:
1132: s3Rop4 = bXlatePatRop4toS3Rop(ppdev, rop4);
1133:
1134: // Check for a Solid Brush.
1135:
1136: if (pbo == NULL || pbo->iSolidColor != -1)
1137: {
1138: bRet = bPatternSolid(psoTrg, psoSrc, psoMask,
1139: pco, pxlo,
1140: prclTrg, pptlSrc, pptlMask,
1141: pbo, pptlBrush,
1142: s3Rop4);
1143: }
1144:
1145: // Handle this as a Pattern Brush.
1146:
1147: else
1148: {
1149: bRet = bPatternBrush(psoTrg, pco, prclTrg, pbo, pptlBrush, s3Rop4);
1150: }
1151:
1152: }
1153:
1154: // Check if we may be able to optimize for screen to screen or
1155: // host to screen blits.
1156:
1157: else if ((!(avecRop & AVEC_NEED_PATTERN)) &&
1158: (avecRop & AVEC_NEED_SOURCE))
1159: {
1160: s3Rop = wXlateSrcRop3toS3Rop(ppdev, LOWORD(rop4));
1161: if (s3Rop != 0)
1162: {
1163: if ((psoTrg->iType == STYPE_DEVICE) &&
1164: (psoSrc->iType == STYPE_DEVICE) &&
1165: ((pxlo == NULL) || (pxlo->flXlate & XO_TRIVIAL)))
1166: {
1167: bRet = bScrnToScrnWithRop(psoTrg, psoSrc, pco, prclTrg,
1168: pptlSrc, s3Rop);
1169: }
1170: else if (psoSrc->iType == STYPE_BITMAP)
1171: {
1172: switch (psoSrc->iBitmapFormat)
1173: {
1174: case BMF_DEVICE:
1175: case BMF_8BPP:
1176: bRet = b8BppHostToScrnCachedWithRop(psoTrg,
1177: psoSrc,
1178: pco,
1179: pxlo,
1180: prclTrg,
1181: pptlSrc,
1182: s3Rop);
1183: break;
1184:
1185: case BMF_1BPP:
1186: bRet = b1BppHostToScrnCachedWithRop(psoTrg,
1187: psoSrc,
1188: pco,
1189: pxlo,
1190: prclTrg,
1191: pptlSrc,
1192: s3Rop);
1193: break;
1194:
1195: case BMF_4BPP:
1196: bRet = b4BppHostToScrnWithRop(psoTrg,
1197: psoSrc,
1198: pco,
1199: pxlo,
1200: prclTrg,
1201: pptlSrc,
1202: s3Rop);
1203: break;
1204:
1205: case BMF_16BPP:
1206: case BMF_24BPP:
1207: case BMF_32BPP:
1208: case BMF_4RLE:
1209: case BMF_8RLE:
1210: default:
1211: bRet = FALSE;
1212: break;
1213: }
1214: }
1215: }
1216:
1217: else
1218: {
1219: DISPDBG((0,"S3.DLL!bSpecialBlits - Missed SrcBlt opportunity - rop: 0x%x\n",
1220: rop4));
1221: }
1222: }
1223:
1224: else if ((rop4 & 0xff) == 0xc0) // Merge Copy
1225: {
1226: if ((psoTrg->iType == STYPE_DEVICE) &&
1227: (psoSrc->iType == STYPE_DEVICE) &&
1228: ((pxlo == NULL) || (pxlo->flXlate & XO_TRIVIAL)))
1229:
1230: {
1231: bRet = bScrnToScrnWithRop(psoTrg, psoSrc,
1232: pco, prclTrg, pptlSrc,
1233: OVERPAINT);
1234:
1235: if (bRet)
1236: {
1237: if (pbo == NULL || pbo->iSolidColor != -1)
1238: {
1239: bRet = bPatternSolid(psoTrg, psoSrc, psoMask,
1240: pco, pxlo,
1241: prclTrg, pptlSrc, pptlMask,
1242: pbo, pptlBrush,
1243: SCREEN_AND_NEW);
1244: }
1245: else
1246: {
1247: bRet = bPatternBrush(psoTrg, pco, prclTrg,
1248: pbo, pptlBrush,
1249: (SCREEN_AND_NEW << 8) | SCREEN_AND_NEW);
1250: }
1251: }
1252: }
1253: else if (psoSrc->iType == STYPE_BITMAP)
1254: {
1255: switch (psoSrc->iBitmapFormat)
1256: {
1257: case BMF_DEVICE:
1258: case BMF_8BPP:
1259: bRet = b8BppHostToScrnCachedWithRop(psoTrg,
1260: psoSrc,
1261: pco,
1262: pxlo,
1263: prclTrg,
1264: pptlSrc,
1265: OVERPAINT);
1266: break;
1267:
1268: case BMF_1BPP:
1269: bRet = b1BppHostToScrnCachedWithRop(psoTrg,
1270: psoSrc,
1271: pco,
1272: pxlo,
1273: prclTrg,
1274: pptlSrc,
1275: OVERPAINT);
1276: break;
1277:
1278: case BMF_4BPP:
1279: bRet = b4BppHostToScrnWithRop(psoTrg,
1280: psoSrc,
1281: pco,
1282: pxlo,
1283: prclTrg,
1284: pptlSrc,
1285: OVERPAINT);
1286: break;
1287:
1288: case BMF_16BPP:
1289: case BMF_24BPP:
1290: case BMF_32BPP:
1291: case BMF_4RLE:
1292: case BMF_8RLE:
1293: default:
1294: bRet = FALSE;
1295: break;
1296: }
1297:
1298: if (bRet)
1299: {
1300: if (pbo == NULL || pbo->iSolidColor != -1)
1301: {
1302: bRet = bPatternSolid(psoTrg, psoSrc, psoMask,
1303: pco, pxlo,
1304: prclTrg, pptlSrc, pptlMask,
1305: pbo, pptlBrush,
1306: SCREEN_AND_NEW);
1307: }
1308: else
1309: {
1310: bRet = bPatternBrush(psoTrg, pco, prclTrg,
1311: pbo, pptlBrush,
1312: (SCREEN_AND_NEW << 8) | SCREEN_AND_NEW);
1313: }
1314: }
1315: }
1316: }
1317:
1318:
1319:
1320: return (bRet);
1321: }
1322:
1323:
1324: /*****************************************************************************
1325: * S3 Screen to Screen with a Rop
1326: *
1327: * Returns TRUE if the blit was handled.
1328: ****************************************************************************/
1329: BOOL bScrnToScrnWithRop(
1330: SURFOBJ *psoTrg,
1331: SURFOBJ *psoSrc,
1332: CLIPOBJ *pco,
1333: RECTL *prclTrg,
1334: POINTL *pptlSrc,
1335: WORD s3Rop)
1336: {
1337: INT width, height, xTrg, yTrg, xSrc, ySrc, cx, cy;
1338: WORD cmd, wDirCode;
1339: RECTL rclSrc, rclTrg;
1340: ULONG DirClip;
1341: BOOL bMore, bIntersect, bClipRequired;
1342: UINT i;
1343: ENUMRECTS8 EnumRects8;
1344: PPDEV ppdev;
1345: RECTL rclBounds;
1346: BYTE iDComplexity;
1347:
1348: // Get the pdev.
1349:
1350: ppdev = (PPDEV) psoTrg->dhpdev;
1351:
1352: // There are two completely different code paths.
1353: // for the complex and non-complex clip cases.
1354: // This is because most of the direction and intersection
1355: // calculations need to be done after the clipping.
1356:
1357: if ((iDComplexity = pco->iDComplexity) != DC_COMPLEX)
1358: {
1359: // Make a copy of the target, since we will have to change
1360: // it for clipping.
1361:
1362: rclTrg = *prclTrg;
1363:
1364: if (iDComplexity == DC_RECT)
1365: {
1366: rclBounds = pco->rclBounds;
1367:
1368: // First handle the trivial rejection.
1369:
1370: bClipRequired = bIntersectTest(&rclTrg, &rclBounds);
1371:
1372: // define the clipped target rectangle.
1373:
1374: if (bClipRequired)
1375: {
1376: rclTrg.left = max (rclTrg.left, rclBounds.left);
1377: rclTrg.top = max (rclTrg.top, rclBounds.top);
1378: rclTrg.right = min (rclTrg.right, rclBounds.right);
1379: rclTrg.bottom = min (rclTrg.bottom, rclBounds.bottom);
1380: }
1381: else
1382: {
1383: // The destination rectangle is completely clipped out,
1384: // so just return.
1385:
1386: return (TRUE);
1387: }
1388: }
1389:
1390: // define the cx & cy.
1391:
1392: width = (rclTrg.right - rclTrg.left) - 1;
1393: height = (rclTrg.bottom - rclTrg.top) - 1;
1394:
1395: // calculate the cx & cy shift for the source.
1396:
1397: cx = rclTrg.left - prclTrg->left;
1398: cy = rclTrg.top - prclTrg->top;
1399:
1400: // define the source rectangle.
1401:
1402: rclSrc.left = pptlSrc->x + cx;
1403: rclSrc.top = pptlSrc->y + cy;
1404: rclSrc.right = pptlSrc->x + width + 1;
1405: rclSrc.bottom = pptlSrc->y + height + 1;
1406:
1407: // Determine the direction of the blit.
1408: // First, check for an intersection of the souce and dest rects.
1409:
1410: bIntersect = bIntersectTest(&rclTrg, &rclSrc);
1411:
1412: // Set defaults for the S3 blit direction and the
1413: // initial coordinates
1414:
1415: wDirCode = DRAWING_DIR_TBLRXM;
1416:
1417: xTrg = rclTrg.left;
1418: yTrg = rclTrg.top;
1419: xSrc = rclSrc.left;
1420: ySrc = rclSrc.top;
1421:
1422: // If the source & dest rects intersect adjust the
1423: // blit direction and initial coordinates.
1424:
1425: if (bIntersect)
1426: {
1427: // The horizontal copy direction.
1428:
1429: if (rclTrg.left > rclSrc.left)
1430: {
1431: // R to L
1432:
1433: xTrg = rclTrg.right - 1;
1434: xSrc = rclSrc.left + width;
1435: wDirCode &= ~PLUS_X;
1436: }
1437:
1438: // The vertical copy direction.
1439:
1440: if (rclTrg.top > rclSrc.top)
1441: {
1442: // B to T
1443:
1444: yTrg = rclTrg.bottom - 1;
1445: ySrc = rclSrc.top + height;
1446: wDirCode &= ~PLUS_Y;
1447: }
1448: }
1449:
1450: // Create the S3 Command.
1451:
1452: cmd = BITBLT | DRAW | DIR_TYPE_XY | WRITE;
1453: cmd |= wDirCode;
1454:
1455: // Do the blit.
1456:
1457: S3ScrnToScrnBlt(ppdev, xSrc, ySrc, xTrg, yTrg, width, height, s3Rop, cmd);
1458:
1459: }
1460: else
1461: {
1462: // This a complex clip.
1463:
1464: DirClip = CD_ANY;
1465: wDirCode = DRAWING_DIR_TBLRXM;
1466:
1467: if (prclTrg->left > pptlSrc->x)
1468: wDirCode &= ~PLUS_X;
1469:
1470: if (prclTrg->top > pptlSrc->y)
1471: wDirCode &= ~PLUS_Y;
1472:
1473: switch (wDirCode)
1474: {
1475: case DRAWING_DIR_TBLRXM:
1476: DirClip = CD_RIGHTDOWN;
1477: break;
1478:
1479: case DRAWING_DIR_TBRLXM:
1480: DirClip = CD_LEFTDOWN;
1481: break;
1482:
1483: case DRAWING_DIR_BTLRXM:
1484: DirClip = CD_RIGHTUP;
1485: break;
1486:
1487: case DRAWING_DIR_BTRLXM:
1488: DirClip = CD_LEFTUP;
1489: break;
1490: }
1491:
1492: CLIPOBJ_cEnumStart(pco, FALSE, CT_RECTANGLES, DirClip, 0);
1493:
1494: do
1495: {
1496: bMore = CLIPOBJ_bEnum(pco, sizeof (ENUMRECTS8),
1497: (PULONG) &EnumRects8);
1498:
1499: for (i = 0; i < EnumRects8.c; i++)
1500: {
1501: rclTrg = *prclTrg;
1502: rclBounds = EnumRects8.arcl[i];
1503:
1504: // handle the trivial rejection.
1505:
1506: bClipRequired = bIntersectTest(&rclTrg, &rclBounds);
1507:
1508: // define the clipped target rectangle.
1509:
1510: if (bClipRequired)
1511: {
1512: rclTrg.left = max (rclTrg.left, rclBounds.left);
1513: rclTrg.top = max (rclTrg.top, rclBounds.top);
1514: rclTrg.right = min (rclTrg.right, rclBounds.right);
1515: rclTrg.bottom = min (rclTrg.bottom, rclBounds.bottom);
1516: }
1517: else
1518: {
1519: // The destination rectangle is completely clipped out,
1520: // so use as an early out.
1521:
1522: continue;
1523: }
1524:
1525: // define the cx & cy.
1526:
1527: width = (rclTrg.right - rclTrg.left) - 1;
1528: height = (rclTrg.bottom - rclTrg.top) - 1;
1529:
1530: // calculate the cx & cy shift for the source.
1531:
1532: cx = rclTrg.left - prclTrg->left;
1533: cy = rclTrg.top - prclTrg->top;
1534:
1535: // define the source rectangle.
1536:
1537: rclSrc.left = pptlSrc->x + cx;
1538: rclSrc.top = pptlSrc->y + cy;
1539: rclSrc.right = rclSrc.left + width + 1;
1540: rclSrc.bottom = rclSrc.top + height + 1;
1541:
1542: // Determine the direction of the blit.
1543: // First, check for an intersection of the souce and dest rects.
1544:
1545: bIntersect = bIntersectTest(&rclTrg, &rclSrc);
1546:
1547: // Set defaults for the S3 blit direction and the
1548: // initial coordinates
1549:
1550: wDirCode = DRAWING_DIR_TBLRXM;
1551:
1552: xTrg = rclTrg.left;
1553: yTrg = rclTrg.top;
1554: xSrc = rclSrc.left;
1555: ySrc = rclSrc.top;
1556:
1557: // If the source & dest rects intersect adjust the
1558: // blit direction and initial coordinates.
1559:
1560: if (bIntersect)
1561: {
1562: // The horizontal copy direction.
1563:
1564: if (rclTrg.left > rclSrc.left)
1565: {
1566: // R to L
1567:
1568: xTrg = rclTrg.right - 1;
1569: xSrc = rclSrc.left + width;
1570: wDirCode &= ~PLUS_X;
1571: }
1572:
1573: // The vertical copy direction.
1574:
1575: if (rclTrg.top > rclSrc.top)
1576: {
1577: // B to T
1578:
1579: yTrg = rclTrg.bottom - 1;
1580: ySrc = rclSrc.top + height;
1581: wDirCode &= ~PLUS_Y;
1582: }
1583: }
1584:
1585: // Create the S3 Command.
1586:
1587: cmd = BITBLT | DRAW | DIR_TYPE_XY | WRITE;
1588: cmd |= wDirCode;
1589:
1590: // Do the blit.
1591:
1592: S3ScrnToScrnBlt(ppdev, xSrc, ySrc, xTrg, yTrg, width, height, s3Rop, cmd);
1593:
1594: }
1595:
1596: } while (bMore);
1597: }
1598: return(TRUE);
1599: }
1600:
1601:
1602: /*****************************************************************************
1603: * S3ScrnToScrnBlt
1604: ****************************************************************************/
1605: VOID S3ScrnToScrnBlt(
1606: PPDEV ppdev,
1607: INT xSrc,
1608: INT ySrc,
1609: INT xTrg,
1610: INT yTrg,
1611: INT width,
1612: INT height,
1613: WORD s3Rop,
1614: WORD cmd)
1615: {
1616:
1617: #if DBG
1618:
1619: if (cmd & 0x20)
1620: {
1621: ASSERTS3(((xTrg + width) < (INT) ppdev->cxScreen),
1622: "S3.DLL!S3ScrnToScrnBlt - Blit Operation over right edge (1)\n");
1623: }
1624:
1625: #endif
1626: // This is where the actual S3 registers are set.
1627:
1628: FIFOWAIT(FIFO_2_EMPTY);
1629:
1630: TEST_AND_SET_FRGD_MIX(SRC_DISPLAY_MEMORY | s3Rop);
1631:
1632: OUTPW(MULTIFUNC_CNTL, (DATA_EXTENSION | ALL_ONES));
1633:
1634: FIFOWAIT(FIFO_7_EMPTY);
1635:
1636: OUTPW(RECT_WIDTH, width);
1637: OUTPW(MULTIFUNC_CNTL, (RECT_HEIGHT | height));
1638: OUTPW(CUR_X, xSrc);
1639: OUTPW(CUR_Y, ySrc);
1640: OUTPW(DEST_X, xTrg);
1641: OUTPW(DEST_Y, yTrg);
1642:
1643: OUTPW(CMD, cmd);
1644: }
1645:
1646:
1647: /*****************************************************************************
1648: * S3 Brush Pattern
1649: *
1650: * Returns TRUE if the blit was handled.
1651: ****************************************************************************/
1652: BOOL bPatternBrush(
1653: SURFOBJ *psoTrg,
1654: CLIPOBJ *pco,
1655: RECTL *prclTrg,
1656: BRUSHOBJ *pbo,
1657: POINTL *pptlBrush,
1658: ROP4 s3Rop4) // Note that the least significant byte is
1659: // the S3 foreground ROP, and the next byte
1660: // is the S3 background ROP. So you can't
1661: // just pass in a plain S3 ROP constant!
1662:
1663: {
1664: PPDEV ppdev;
1665: PS3BRUSH ps3Brush;
1666: POINT pt;
1667: XYZPOINT xyzPt;
1668: INT zHorz, zVert, i;
1669: POINT ptDest;
1670: SIZE sizDest;
1671: WORD s3ForeRop, s3BackRop;
1672: BOOL bClipRequired, bMore;
1673: RECTL rclTrg, rclBounds;
1674: BYTE iDComplexity;
1675: ENUMRECTS8 EnumRects8;
1676:
1677: DISPDBG((3, "S3.DLL!bPatternBrush - Entry\n"));
1678:
1679: // Get the pdev.
1680:
1681: ppdev = (PPDEV) psoTrg->dhpdev;
1682:
1683: // Get the pointer to our drivers realization of the brush.
1684:
1685: if (pbo->pvRbrush != NULL)
1686: {
1687: ps3Brush = pbo->pvRbrush;
1688: }
1689: else
1690: {
1691: ps3Brush = BRUSHOBJ_pvGetRbrush(pbo);
1692:
1693: // Fail if we do not handle the brush.
1694:
1695: if (ps3Brush == NULL)
1696: return (FALSE);
1697: }
1698:
1699: s3ForeRop = (WORD) (s3Rop4 & 0xFF);
1700: s3BackRop = (WORD) ((s3Rop4 >> 8) & 0xFF);
1701:
1702: if (ps3Brush->iBitmapFormat == BMF_1BPP)
1703: {
1704: DISPDBG((3, "S3.DLL!bPatternBrush - 1BPP brush\n"));
1705:
1706: // If we have never seen this brush before then allocate a slot
1707: // for it.
1708:
1709: // Keep a count of number of brushes we have seen.
1710: // This will be used to determine if the cache system is adaquate.
1711:
1712: nMonoBrushes++;
1713:
1714: // If we have never seen this brush before or if the cache has
1715: // changed since the last time
1716: // we have seen it then allocate a new cache entry for it.
1717:
1718: if ((ps3Brush->iBrushCacheID == -1) ||
1719: (ps3Brush->iPatternID != ppdev->pulMonoBrushCacheEntries[ps3Brush->iBrushCacheID]))
1720: {
1721: // If we have run out of cache entries invalidate the entire cache.
1722:
1723: if (ppdev->iNextMonoBrushCacheSlot >= ppdev->iMaxCachedMonoBrushes)
1724: {
1725: nMonoBrushCacheInvalidations++;
1726:
1727: memset(ppdev->pulMonoBrushCacheEntries, 0, ppdev->iMaxCachedMonoBrushes * sizeof(ULONG));
1728: ppdev->iNextMonoBrushCacheSlot = 0;
1729: }
1730:
1731: // Get a slot in the cache for this brush.
1732:
1733: i = (ppdev->iNextMonoBrushCacheSlot)++;
1734: ps3Brush->iBrushCacheID = i;
1735:
1736: // Calculate the address of the brush in the cache.
1737:
1738: xyzPt.x = MONO_PATTERN_CACHE_X + ((i >> 3) * 16);
1739: xyzPt.y = MONO_PATTERN_CACHE_Y;
1740: xyzPt.z = ajMonoPatPlanes[i & 0x7];
1741:
1742: // Associate the brush with this cache entry.
1743:
1744: ppdev->pulMonoBrushCacheEntries[i] = ps3Brush->iPatternID;
1745:
1746: // Get an expansion cache slot for this brush.
1747:
1748: i = ppdev->iNextMonoBrushExpansionSlot;
1749: i = ++i % MAX_MONO_BRUSH_EXPANSION_SLOTS;
1750: ppdev->iNextMonoBrushExpansionSlot = i;
1751: ps3Brush->iExpansionCacheID = i;
1752:
1753: // Associate this brush with this expansion cache slot.
1754:
1755: ppdev->aulMonoExpansionCacheTag[i] = ps3Brush->iPatternID;
1756:
1757: // Set the expansion caches planes
1758:
1759: zHorz = zVert = ajMonoPatPlanes[i];
1760:
1761: // Down load the brush to the cache and expand it into
1762: // the horizontal and vertical caches.
1763:
1764: bDownLoadBrushIntoMonoCache(ppdev, ps3Brush, &xyzPt);
1765: bExpandMonoBrushIntoHorzCache(ppdev, &xyzPt, zHorz);
1766: bExpandMonoBrushIntoVertCache(ppdev, &xyzPt, zVert);
1767:
1768: }
1769: else
1770: {
1771: // We got a cache hit, so keep the statistic.
1772:
1773: nMonoBrushCacheHit++;
1774:
1775: // Calculate the address of the brush in the cache.
1776:
1777: i = ps3Brush->iBrushCacheID;
1778: xyzPt.x = MONO_PATTERN_CACHE_X + ((i >> 3) * 16);
1779: xyzPt.y = MONO_PATTERN_CACHE_Y;
1780: xyzPt.z = ajMonoPatPlanes[i & 0x7];
1781:
1782: // Check for an hit in the expansion cache.
1783:
1784: if (ps3Brush->iPatternID == ppdev->aulMonoExpansionCacheTag[(i = ps3Brush->iExpansionCacheID)])
1785: {
1786: zHorz = zVert = ajMonoPatPlanes[i];
1787: nMonoBrushExpansionCacheHit++;
1788: }
1789: else
1790: {
1791: // Get an expansion cache slot for this brush.
1792:
1793: i = ppdev->iNextMonoBrushExpansionSlot;
1794: i = ++i % MAX_MONO_BRUSH_EXPANSION_SLOTS;
1795: ppdev->iNextMonoBrushExpansionSlot = i;
1796: ps3Brush->iExpansionCacheID = i;
1797:
1798: // Associate this brush with this expansion cache slot.
1799:
1800: ppdev->aulMonoExpansionCacheTag[i] = ps3Brush->iPatternID;
1801:
1802: // Set the expansion caches planes
1803:
1804: zHorz = zVert = ajMonoPatPlanes[i];
1805:
1806: bExpandMonoBrushIntoHorzCache(ppdev, &xyzPt, zHorz);
1807: bExpandMonoBrushIntoVertCache(ppdev, &xyzPt, zVert);
1808: }
1809: }
1810: }
1811: else
1812: {
1813: DISPDBG((3, "S3.DLL!bPatternBrush - 8BPP brush\n"));
1814:
1815: // If we have never seen this brush before then allocate a slot
1816: // for it.
1817:
1818: // Keep a count of number of brushes we have seen.
1819: // This will be used to determine if the cache system is adaquate.
1820:
1821: nColorBrushes++;
1822:
1823: // If we have never seen this brush before or if the cache
1824: // has changed since the last time
1825: // we have seen it then allocate a new cache entry for it.
1826:
1827: if ((ps3Brush->iBrushCacheID == -1) ||
1828: (ps3Brush->iPatternID != ppdev->pulColorBrushCacheEntries[ps3Brush->iBrushCacheID]))
1829: {
1830: // If we have run out of cache entries invalidate the entire cache.
1831:
1832: if (ppdev->iNextColorBrushCacheSlot >= ppdev->iMaxCachedColorBrushes)
1833: {
1834: nColorBrushCacheInvalidations++;
1835:
1836: memset(ppdev->pulColorBrushCacheEntries, 0, ppdev->iMaxCachedColorBrushes * sizeof(ULONG));
1837: ppdev->iNextColorBrushCacheSlot = 0;
1838: }
1839:
1840: // Get a slot in the cache for this brush.
1841:
1842: i = (ppdev->iNextColorBrushCacheSlot)++;
1843: ps3Brush->iBrushCacheID = i;
1844:
1845: // Calculate the address of the brush in the cache.
1846:
1847: pt.x = COLOR_PATTERN_CACHE_X + ((i >> 2) * 16);
1848: pt.y = COLOR_PATTERN_CACHE_Y + ((i & 0x3) * 16);
1849:
1850: // Associate the brush with this cache entry.
1851:
1852: ppdev->pulColorBrushCacheEntries[i] = ps3Brush->iPatternID;
1853: ppdev->ulColorExpansionCacheTag = ps3Brush->iPatternID;
1854:
1855: // Down load the brush to the cache and expand it into
1856: // the horizontal and vertical caches.
1857:
1858: bDownLoadBrushIntoColorCache(ppdev, ps3Brush, &pt);
1859: bExpandColorBrushIntoHorzCache(ppdev, &pt);
1860: bExpandColorBrushIntoVertCache(ppdev, &pt);
1861: }
1862: else
1863: {
1864: // We got a cache hit, so keep the statistic.
1865:
1866: nColorBrushCacheHit++;
1867:
1868: // Calculate the address of the brush in the cache.
1869:
1870: i = ps3Brush->iBrushCacheID;
1871: pt.x = COLOR_PATTERN_CACHE_X + ((i >> 2) * 16);
1872: pt.y = COLOR_PATTERN_CACHE_Y + ((i & 0x3) * 16);
1873:
1874: if (ps3Brush->iPatternID == ppdev->ulColorExpansionCacheTag)
1875: {
1876: nColorBrushExpansionCacheHit++;
1877: }
1878: else
1879: {
1880: ppdev->ulColorExpansionCacheTag = ps3Brush->iPatternID;
1881:
1882: bExpandColorBrushIntoHorzCache(ppdev, &pt);
1883: bExpandColorBrushIntoVertCache(ppdev, &pt);
1884: }
1885: }
1886: }
1887:
1888: // Handle the clipping.
1889:
1890: if ((iDComplexity = pco->iDComplexity) != DC_COMPLEX)
1891: {
1892: if (iDComplexity == DC_TRIVIAL)
1893: {
1894: rclTrg = *prclTrg;
1895: }
1896: else
1897: {
1898: rclTrg = *prclTrg;
1899: rclBounds = pco->rclBounds;
1900:
1901: // First handle the trivial rejection.
1902:
1903: bClipRequired = bIntersectTest(&rclTrg, &rclBounds);
1904:
1905: if (bClipRequired)
1906: {
1907: rclTrg.left = max (rclTrg.left, rclBounds.left);
1908: rclTrg.top = max (rclTrg.top, rclBounds.top);
1909: rclTrg.right = min(rclTrg.right, rclBounds.right);
1910: rclTrg.bottom = min(rclTrg.bottom, rclBounds.bottom);
1911: }
1912: else
1913: {
1914: // The brush is completely clipped out.
1915: // so just return sucessfull.
1916:
1917: return (TRUE);
1918: }
1919: }
1920:
1921: ptDest.x = rclTrg.left;
1922: ptDest.y = rclTrg.top;
1923: sizDest.cx = rclTrg.right - rclTrg.left;
1924: sizDest.cy = rclTrg.bottom - rclTrg.top;
1925:
1926: // Color expand the monochrome brush in the Hoizontal Cache to the
1927: // screen.
1928:
1929: if (s3ForeRop == OVERPAINT && s3BackRop == OVERPAINT)
1930: {
1931: if (ps3Brush->iBitmapFormat == BMF_1BPP)
1932: {
1933: bCpyColorExpandHorzCacheToScreen(ppdev, ps3Brush, zHorz,
1934: (PPOINT) pptlBrush,
1935: &ptDest, &sizDest);
1936: }
1937: else
1938: {
1939: // NOTE: The S3-911/924 requries the cx of any "rolling blt"
1940: // to have a cx of >= 64 pels. This is due to how the
1941: // chip's internal FIFO works. This test will catch all
1942: // the souce copy operations that can be accelerated,
1943: // with the rolling blit.
1944:
1945: if ((sizDest.cx >= 64) ||
1946: (sizDest.cx > sizDest.cy))
1947: {
1948: bCpyColorHorzCacheToScreen(ppdev, ps3Brush,
1949: (PPOINT) pptlBrush,
1950: &ptDest, &sizDest);
1951: }
1952: else
1953: {
1954: bColorVertCacheToScreen(ppdev, ps3Brush,
1955: (PPOINT) pptlBrush,
1956: &ptDest, &sizDest,
1957: s3ForeRop, s3BackRop);
1958: }
1959: }
1960: }
1961: else
1962: {
1963: if (sizDest.cy > sizDest.cx)
1964: {
1965: if (ps3Brush->iBitmapFormat == BMF_1BPP)
1966: {
1967: bColorExpandVertCacheToScreen(ppdev, ps3Brush, zVert,
1968: (PPOINT) pptlBrush,
1969: &ptDest, &sizDest,
1970: s3ForeRop, s3BackRop);
1971: }
1972: else
1973: {
1974: bColorVertCacheToScreen(ppdev, ps3Brush,
1975: (PPOINT) pptlBrush,
1976: &ptDest, &sizDest,
1977: s3ForeRop, s3BackRop);
1978: }
1979: }
1980: else
1981: {
1982: if (ps3Brush->iBitmapFormat == BMF_1BPP)
1983: {
1984: bColorExpandHorzCacheToScreen(ppdev, ps3Brush, zHorz,
1985: (PPOINT) pptlBrush,
1986: &ptDest, &sizDest,
1987: s3ForeRop, s3BackRop);
1988: }
1989: else
1990: {
1991: bColorHorzCacheToScreen(ppdev, ps3Brush,
1992: (PPOINT) pptlBrush,
1993: &ptDest, &sizDest,
1994: s3ForeRop, s3BackRop);
1995: }
1996: }
1997: }
1998: }
1999: else
2000: {
2001: CLIPOBJ_cEnumStart(pco, FALSE, CT_RECTANGLES, CD_ANY, 0);
2002:
2003: do
2004: {
2005: bMore = CLIPOBJ_bEnum(pco, sizeof (ENUMRECTS8),
2006: (PULONG) &EnumRects8);
2007:
2008: for (i = 0; i < (INT) EnumRects8.c; i++)
2009: {
2010: rclBounds = EnumRects8.arcl[i];
2011:
2012: if (rclBounds.left < prclTrg->left)
2013: rclBounds.left = prclTrg->left;
2014:
2015: if (rclBounds.right > prclTrg->right)
2016: rclBounds.right = prclTrg->right;
2017:
2018: if (rclBounds.top < prclTrg->top)
2019: rclBounds.top = prclTrg->top;
2020:
2021: if (rclBounds.bottom > prclTrg->bottom)
2022: rclBounds.bottom = prclTrg->bottom;
2023:
2024: // Get the height and width for the blit.
2025:
2026: ptDest.x = rclBounds.left;
2027: ptDest.y = rclBounds.top;
2028: sizDest.cx = rclBounds.right - rclBounds.left;
2029: sizDest.cy = rclBounds.bottom - rclBounds.top;
2030:
2031: // Color expand the monochrome brush in the Hoizontal Cache
2032: // to the screen.
2033:
2034: if (s3ForeRop == OVERPAINT && s3BackRop == OVERPAINT)
2035: {
2036: if (ps3Brush->iBitmapFormat == BMF_1BPP)
2037: {
2038: bCpyColorExpandHorzCacheToScreen(ppdev, ps3Brush, zHorz,
2039: (PPOINT) pptlBrush,
2040: &ptDest, &sizDest);
2041:
2042: }
2043: else
2044: {
2045: if ((sizDest.cx >= 64) ||
2046: (sizDest.cx > sizDest.cy))
2047: {
2048: bCpyColorHorzCacheToScreen(ppdev, ps3Brush,
2049: (PPOINT) pptlBrush,
2050: &ptDest, &sizDest);
2051: }
2052: else
2053: {
2054: bColorVertCacheToScreen(ppdev, ps3Brush,
2055: (PPOINT) pptlBrush,
2056: &ptDest, &sizDest,
2057: s3ForeRop, s3BackRop);
2058: }
2059: }
2060: }
2061: else
2062: {
2063: if (sizDest.cy > sizDest.cx)
2064: {
2065: if (ps3Brush->iBitmapFormat == BMF_1BPP)
2066: {
2067: bColorExpandVertCacheToScreen(ppdev, ps3Brush, zVert,
2068: (PPOINT) pptlBrush,
2069: &ptDest, &sizDest,
2070: s3ForeRop, s3BackRop);
2071: }
2072: else
2073: {
2074: bColorVertCacheToScreen(ppdev, ps3Brush,
2075: (PPOINT) pptlBrush,
2076: &ptDest, &sizDest,
2077: s3ForeRop, s3BackRop);
2078: }
2079: }
2080: else
2081: {
2082: if (ps3Brush->iBitmapFormat == BMF_1BPP)
2083: {
2084: bColorExpandHorzCacheToScreen(ppdev, ps3Brush, zHorz,
2085: (PPOINT) pptlBrush,
2086: &ptDest, &sizDest,
2087: s3ForeRop, s3BackRop);
2088: }
2089: else
2090: {
2091: bColorHorzCacheToScreen(ppdev, ps3Brush,
2092: (PPOINT) pptlBrush,
2093: &ptDest, &sizDest,
2094: s3ForeRop, s3BackRop);
2095: }
2096:
2097: }
2098: }
2099: }
2100: } while (bMore);
2101:
2102: }
2103:
2104: return (TRUE);
2105:
2106: }
2107:
2108: /*****************************************************************************
2109: * wXlateSrcRop3toS3Rop - Translate the Source to Dest Rop 3 to an S3 rop
2110: ****************************************************************************/
2111: WORD wXlateSrcRop3toS3Rop(PPDEV pdev, WORD rop3)
2112: {
2113: WORD s3Rop;
2114:
2115: switch (LOBYTE(rop3))
2116: {
2117: case 0xBB: // DSno
2118: s3Rop = SCREEN_OR_NOT_NEW;
2119: break;
2120:
2121: case 0x33: // Sn
2122: s3Rop = NOT_NEW;
2123: break;
2124:
2125: case 0x44: // SDna
2126: s3Rop = NOT_SCREEN_AND_NEW;
2127: break;
2128:
2129: case 0x66: // DSx
2130: s3Rop = SCREEN_XOR_NEW;
2131: break;
2132:
2133: case 0x77: // DSan
2134: s3Rop = NOT_SCREEN_OR_NOT_NEW;
2135: break;
2136:
2137: case 0x88: // DSa
2138: s3Rop = SCREEN_AND_NEW;
2139: break;
2140:
2141: case 0x99: // DSxn
2142: s3Rop = NOT_SCREEN_XOR_NEW;
2143: break;
2144:
2145: case 0xDD: // SDno
2146: s3Rop = NOT_SCREEN_OR_NEW;
2147: break;
2148:
2149: case 0xCC: // S
2150: s3Rop = OVERPAINT;
2151: break;
2152:
2153: case 0x11: // DSon
2154: s3Rop = NOT_SCREEN_AND_NOT_NEW;
2155: break;
2156:
2157: case 0x22: // DSna
2158: s3Rop = SCREEN_AND_NOT_NEW;
2159: break;
2160:
2161: case 0xEE: // SDo
2162: s3Rop = SCREEN_OR_NEW;
2163: break;
2164:
2165: default:
2166: s3Rop = 0;
2167: break;
2168: }
2169:
2170: return (s3Rop);
2171:
2172: }
2173:
2174:
2175: /*****************************************************************************
2176: * Translate the ROP4 to S3 rops.
2177: ****************************************************************************/
2178:
2179: ROP4 bXlatePatRop4toS3Rop(
2180: PPDEV pdev,
2181: ROP4 rop4)
2182: {
2183: WORD s3Rop;
2184: ROP4 s3Rop4;
2185:
2186: switch (rop4 & 0xff)
2187: {
2188: case 0x00: // 0
2189: s3Rop = LOGICAL_0;
2190: break;
2191:
2192: case 0x05: // ~(P | D)
2193: s3Rop = NOT_SCREEN_AND_NOT_NEW;
2194: break;
2195:
2196: case 0x0A: // ~P & D
2197: s3Rop = SCREEN_AND_NOT_NEW;
2198: break;
2199:
2200: case 0x0F: // ~P
2201: s3Rop = NOT_NEW;
2202: break;
2203:
2204: case 0x50: // P & ~D
2205: s3Rop = NOT_SCREEN_AND_NEW;
2206: break;
2207:
2208: case 0x55: // ~D
2209: s3Rop = NOT_SCREEN;
2210: break;
2211:
2212: case 0x5A: // P ^ D
2213: s3Rop = SCREEN_XOR_NEW;
2214: break;
2215:
2216: case 0x5F: // ~(P & D)
2217: s3Rop = NOT_SCREEN_OR_NOT_NEW;
2218: break;
2219:
2220: case 0xA0: // P & D
2221: s3Rop = SCREEN_AND_NEW;
2222: break;
2223:
2224: case 0xA5: // ~(P ^ D)
2225: s3Rop = NOT_SCREEN_XOR_NEW;
2226: break;
2227:
2228: case 0xAA: // D
2229: s3Rop = LEAVE_ALONE;
2230: break;
2231:
2232: case 0xAF: // ~P | D
2233: s3Rop = SCREEN_OR_NOT_NEW;
2234: break;
2235:
2236: case 0xF0: // P
2237: s3Rop = OVERPAINT;
2238: break;
2239:
2240: case 0xF5: // P | ~D
2241: s3Rop = NOT_SCREEN_OR_NEW;
2242: break;
2243:
2244: case 0xFA: // P | D
2245: s3Rop = SCREEN_OR_NEW;
2246: break;
2247:
2248: case 0xFF: // 1
2249: s3Rop = LOGICAL_1;
2250: break;
2251: }
2252:
2253: s3Rop4 = s3Rop | (s3Rop << 8);
2254:
2255: return(s3Rop4);
2256: }
2257:
2258: /*****************************************************************************
2259: * Download the Color Brush to the Color brush cache in
2260: * graphics memory.
2261: ****************************************************************************/
2262: BOOL bDownLoadBrushIntoColorCache(
2263: PPDEV ppdev,
2264: PS3BRUSH ps3Brush,
2265: PPOINT ppt)
2266: {
2267: WORD Cmd;
2268:
2269: DISPDBG((3, "S3.DLL!bDownLoadBrushIntoColorCache - Entry\n"));
2270:
2271: // Down load the initial pattern image, the upper left 8 X 8 cell.
2272:
2273: Cmd = RECTANGLE_FILL | BUS_SIZE_8 | WAIT |
2274: DRAW | DRAWING_DIR_TBLRXM | DIR_TYPE_XY |
2275: LAST_PIXEL_ON | WRITE;
2276:
2277: // Setup the S3 chip.
2278:
2279: FIFOWAIT(FIFO_6_EMPTY);
2280:
2281: TEST_AND_SET_FRGD_MIX(SRC_CPU_DATA | OVERPAINT);
2282: OUTPW(MULTIFUNC_CNTL, (DATA_EXTENSION | ALL_ONES));
2283:
2284: OUTPW(CUR_X, ppt->x);
2285: OUTPW(CUR_Y, ppt->y);
2286:
2287: OUTPW(RECT_WIDTH, 7);
2288: OUTPW(MULTIFUNC_CNTL, (RECT_HEIGHT | 7));
2289:
2290: GPWAIT();
2291: OUTPW(CMD, Cmd);
2292:
2293: // Now transfer the data from host memory to graphics memory.
2294:
2295: CHECK_DATA_READY;
2296:
2297: vDataPortOutB(ppdev, ps3Brush->ajPattern, 64);
2298:
2299: CHECK_DATA_COMPLETE;
2300:
2301: // Make the pattern double wide. Make copy of the pattern to the right
2302: // of the original pattern.
2303:
2304: Cmd = BITBLT | DRAW | DIR_TYPE_XY | WRITE |
2305: MULTIPLE_PIXELS | DRAWING_DIR_TBLRXM;
2306:
2307: FIFOWAIT(FIFO_8_EMPTY);
2308:
2309: TEST_AND_SET_FRGD_MIX(SRC_DISPLAY_MEMORY | OVERPAINT);
2310:
2311: OUTPW(MULTIFUNC_CNTL, (DATA_EXTENSION | ALL_ONES));
2312:
2313: OUTPW(CUR_X, ppt->x);
2314: OUTPW(CUR_Y, ppt->y);
2315: OUTPW(DEST_X, ppt->x + 8);
2316: OUTPW(DEST_Y, ppt->y);
2317:
2318: OUTPW(CMD, Cmd);
2319:
2320: // Make the pattern double high. Make a copy of the double pattern
2321: // pattern below the original one.
2322:
2323: FIFOWAIT(FIFO_6_EMPTY);
2324:
2325: OUTPW(RECT_WIDTH, 15);
2326:
2327: OUTPW(CUR_X, ppt->x);
2328: OUTPW(CUR_Y, ppt->y);
2329: OUTPW(DEST_X, ppt->x);
2330: OUTPW(DEST_Y, ppt->y + 8);
2331:
2332: OUTPW(CMD, Cmd);
2333:
2334: return(TRUE);
2335: }
2336:
2337:
2338:
2339: /*****************************************************************************
2340: * Download the Monochrome Brush to the Monochrome brush cache in
2341: * graphics memory.
2342: ****************************************************************************/
2343: BOOL bDownLoadBrushIntoMonoCache(
2344: PPDEV ppdev,
2345: PS3BRUSH p3Brush,
2346: PXYZPOINT pxyzPt)
2347: {
2348: WORD Cmd;
2349: INT i;
2350: BYTE ajPattern[8];
2351:
2352: DISPDBG((3, "S3.DLL!bDownLoadBrushIntoMonoCache - Entry\n"));
2353:
2354: // Compress the dword aligned pattern to a byte aligned pattern.
2355:
2356: for (i = 0; i < 8; i++)
2357: {
2358: ajPattern[i] = p3Brush->ajPattern[i * p3Brush->lDeltaPattern];
2359: }
2360:
2361: // Down load the initial pattern image, the upper left 8 X 8 cell.
2362:
2363: Cmd = RECTANGLE_FILL | BUS_SIZE_8 | WAIT |
2364: DRAW | DRAWING_DIR_TBLRXM | DIR_TYPE_XY |
2365: LAST_PIXEL_ON | MULTIPLE_PIXELS | WRITE;
2366:
2367: // Setup the S3 chip.
2368:
2369: FIFOWAIT(FIFO_8_EMPTY);
2370:
2371: TEST_AND_SET_FRGD_MIX(LOGICAL_1);
2372: TEST_AND_SET_BKGD_MIX(LOGICAL_0);
2373:
2374: TEST_AND_SET_WRT_MASK(LOWORD(pxyzPt->z));
2375:
2376: OUTPW(CUR_X, pxyzPt->x);
2377: OUTPW(CUR_Y, pxyzPt->y);
2378:
2379: OUTPW(MULTIFUNC_CNTL, (DATA_EXTENSION | CPU_DATA));
2380: OUTPW(RECT_WIDTH, 7);
2381: OUTPW(MULTIFUNC_CNTL, (RECT_HEIGHT | 7));
2382:
2383: GPWAIT();
2384: OUTPW(CMD, Cmd);
2385:
2386: // Now transfer the data from host memory to graphics memory.
2387:
2388: CHECK_DATA_READY;
2389:
2390: vDataPortOutB(ppdev, ajPattern, 8);
2391:
2392: CHECK_DATA_COMPLETE;
2393:
2394: // Make the pattern double wide. Make copy of the pattern to the right
2395: // of the original pattern.
2396:
2397: Cmd = BITBLT | DRAW | DIR_TYPE_XY | WRITE |
2398: MULTIPLE_PIXELS | DRAWING_DIR_TBLRXM;
2399:
2400: FIFOWAIT(FIFO_8_EMPTY);
2401:
2402: TEST_AND_SET_RD_MASK (LOWORD(pxyzPt->z));
2403: TEST_AND_SET_FRGD_MIX(SRC_DISPLAY_MEMORY | OVERPAINT);
2404:
2405: OUTPW(MULTIFUNC_CNTL, (DATA_EXTENSION | ALL_ONES));
2406:
2407: OUTPW(CUR_X, pxyzPt->x);
2408: OUTPW(CUR_Y, pxyzPt->y);
2409: OUTPW(DEST_X, pxyzPt->x + 8);
2410: OUTPW(DEST_Y, pxyzPt->y);
2411:
2412: OUTPW(CMD, Cmd);
2413:
2414: // Make the pattern double high. Make a copy of the double pattern
2415: // pattern below the original one.
2416:
2417: FIFOWAIT(FIFO_6_EMPTY);
2418:
2419: OUTPW(RECT_WIDTH, 15);
2420:
2421: OUTPW(CUR_X, pxyzPt->x);
2422: OUTPW(CUR_Y, pxyzPt->y);
2423: OUTPW(DEST_X, pxyzPt->x);
2424: OUTPW(DEST_Y, pxyzPt->y + 8);
2425:
2426: OUTPW(CMD, Cmd);
2427:
2428: // Reset the read and write masks.
2429:
2430: FIFOWAIT(FIFO_2_EMPTY);
2431:
2432: TEST_AND_SET_WRT_MASK(0xff);
2433: TEST_AND_SET_RD_MASK(0xff);
2434:
2435: return(TRUE);
2436: }
2437:
2438:
2439: /*****************************************************************************
2440: * Expand the color brush in the vertical dimension.
2441: ****************************************************************************/
2442: BOOL bExpandColorBrushIntoVertCache(
2443: PPDEV ppdev,
2444: PPOINT ppt)
2445: {
2446: WORD Cmd;
2447:
2448: DISPDBG((3, "S3.DLL!bExpandColorBrushIntoVertCache - Entry\n"));
2449:
2450: // Copy the cached double wide, double high pattern to the Horizontal
2451: // expansion cache area.
2452:
2453: Cmd = BITBLT | DRAW | DIR_TYPE_XY | WRITE |
2454: MULTIPLE_PIXELS | DRAWING_DIR_TBLRXM;
2455:
2456: FIFOWAIT(FIFO_1_EMPTY);
2457:
2458: TEST_AND_SET_FRGD_MIX(SRC_DISPLAY_MEMORY | OVERPAINT);
2459:
2460: FIFOWAIT(FIFO_8_EMPTY);
2461:
2462: OUTPW(MULTIFUNC_CNTL, (DATA_EXTENSION | ALL_ONES));
2463: OUTPW(MULTIFUNC_CNTL, (RECT_HEIGHT | 15));
2464: OUTPW(RECT_WIDTH, 15);
2465:
2466: OUTPW(CUR_X, ppt->x);
2467: OUTPW(CUR_Y, ppt->y);
2468: OUTPW(DEST_X, COLOR_VERT_EXPANSION_CACHE_X);
2469: OUTPW(DEST_Y, COLOR_VERT_EXPANSION_CACHE_Y);
2470:
2471: OUTPW(CMD, Cmd);
2472:
2473: // Now the rolling blit to fill all the way.
2474:
2475: FIFOWAIT(FIFO_6_EMPTY);
2476:
2477: OUTPW(MULTIFUNC_CNTL, (RECT_HEIGHT | COLOR_VERT_EXPANSION_CACHE_CY - 17));
2478:
2479: OUTPW(CUR_X, COLOR_VERT_EXPANSION_CACHE_X);
2480: OUTPW(CUR_Y, COLOR_VERT_EXPANSION_CACHE_Y);
2481: OUTPW(DEST_X, COLOR_VERT_EXPANSION_CACHE_X);
2482: OUTPW(DEST_Y, COLOR_VERT_EXPANSION_CACHE_Y + 16);
2483:
2484: OUTPW(CMD, Cmd);
2485:
2486: return(TRUE);
2487:
2488: }
2489:
2490:
2491:
2492: /*****************************************************************************
2493: * Expand the monochrome brush in the vertical dimension.
2494: ****************************************************************************/
2495: BOOL bExpandMonoBrushIntoVertCache(
2496: PPDEV ppdev,
2497: PXYZPOINT pxyzPt,
2498: INT zVert)
2499: {
2500: WORD Cmd;
2501:
2502: DISPDBG((3, "S3.DLL!bExpandMonoBrushIntoVertCache - Entry\n"));
2503:
2504: // Copy the cached double wide, double high pattern to the Horizontal
2505: // expansion cache area.
2506:
2507: Cmd = BITBLT | DRAW | DIR_TYPE_XY | WRITE |
2508: MULTIPLE_PIXELS | DRAWING_DIR_TBLRXM;
2509:
2510: FIFOWAIT(FIFO_7_EMPTY);
2511:
2512: OUTPW(MULTIFUNC_CNTL, (DATA_EXTENSION | DISPLAY_MEMORY));
2513:
2514: TEST_AND_SET_FRGD_MIX(FOREGROUND_COLOR | OVERPAINT);
2515: TEST_AND_SET_FRGD_COLOR(0xff);
2516: TEST_AND_SET_BKGD_MIX(BACKGROUND_COLOR | OVERPAINT);
2517: SET_BKGD_COLOR(0);
2518:
2519: TEST_AND_SET_RD_MASK(LOWORD(pxyzPt->z));
2520: TEST_AND_SET_WRT_MASK(LOWORD(zVert));
2521:
2522: FIFOWAIT(FIFO_7_EMPTY);
2523:
2524: OUTPW(RECT_WIDTH, 15);
2525: OUTPW(MULTIFUNC_CNTL, (RECT_HEIGHT | 15));
2526:
2527: OUTPW(CUR_X, pxyzPt->x);
2528: OUTPW(CUR_Y, pxyzPt->y);
2529: OUTPW(DEST_X, MONO_VERT_EXPANSION_CACHE_X);
2530: OUTPW(DEST_Y, MONO_VERT_EXPANSION_CACHE_Y);
2531:
2532: OUTPW(CMD, Cmd);
2533:
2534: // Now the rolling blit to fill all the way.
2535:
2536: FIFOWAIT(FIFO_7_EMPTY);
2537:
2538: TEST_AND_SET_RD_MASK(zVert);
2539:
2540: OUTPW(MULTIFUNC_CNTL, (RECT_HEIGHT | MONO_VERT_EXPANSION_CACHE_CY - 17));
2541:
2542: OUTPW(CUR_X, MONO_VERT_EXPANSION_CACHE_X);
2543: OUTPW(CUR_Y, MONO_VERT_EXPANSION_CACHE_Y);
2544: OUTPW(DEST_X, MONO_VERT_EXPANSION_CACHE_X);
2545: OUTPW(DEST_Y, MONO_VERT_EXPANSION_CACHE_Y + 16);
2546:
2547: OUTPW(CMD, Cmd);
2548:
2549: // Now reset the read and write plan masks.
2550:
2551: FIFOWAIT(FIFO_2_EMPTY);
2552:
2553: TEST_AND_SET_WRT_MASK(0xff);
2554: TEST_AND_SET_RD_MASK(0xff);
2555:
2556: return(TRUE);
2557:
2558: }
2559:
2560: /*****************************************************************************
2561: * Expand the color brush in the horizontal dimension.
2562: ****************************************************************************/
2563: BOOL bExpandColorBrushIntoHorzCache(
2564: PPDEV ppdev,
2565: PPOINT ppt)
2566: {
2567: WORD Cmd;
2568:
2569: DISPDBG((3, "S3.DLL!bExpandColorBrushIntoHorzCache - Entry\n"));
2570:
2571: // Copy the cached double wide, double high pattern to the Horizontal
2572: // expansion cache area.
2573:
2574: Cmd = BITBLT | DRAW | DIR_TYPE_XY | WRITE |
2575: MULTIPLE_PIXELS | DRAWING_DIR_TBLRXM;
2576:
2577: FIFOWAIT(FIFO_1_EMPTY);
2578:
2579: TEST_AND_SET_FRGD_MIX(SRC_DISPLAY_MEMORY | OVERPAINT);
2580:
2581: FIFOWAIT(FIFO_8_EMPTY);
2582:
2583: OUTPW(MULTIFUNC_CNTL, (DATA_EXTENSION | ALL_ONES));
2584: OUTPW(MULTIFUNC_CNTL, (RECT_HEIGHT | 15));
2585: OUTPW(RECT_WIDTH, 15);
2586:
2587: OUTPW(CUR_X, ppt->x);
2588: OUTPW(CUR_Y, ppt->y);
2589: OUTPW(DEST_X, COLOR_HORZ_EXPANSION_CACHE_X);
2590: OUTPW(DEST_Y, COLOR_HORZ_EXPANSION_CACHE_Y);
2591:
2592: OUTPW(CMD, Cmd);
2593:
2594: // Expand the 16 X 16 double wide, double high.
2595: // First to a 32 X 16
2596:
2597: FIFOWAIT(FIFO_5_EMPTY);
2598:
2599: OUTPW(CUR_X, COLOR_HORZ_EXPANSION_CACHE_X);
2600: OUTPW(CUR_Y, COLOR_HORZ_EXPANSION_CACHE_Y);
2601: OUTPW(DEST_X, COLOR_HORZ_EXPANSION_CACHE_X + 16);
2602: OUTPW(DEST_Y, COLOR_HORZ_EXPANSION_CACHE_Y);
2603:
2604: OUTPW(CMD, Cmd);
2605:
2606: // Now 64 X 16
2607:
2608: FIFOWAIT(FIFO_6_EMPTY);
2609:
2610: OUTPW(RECT_WIDTH, 31);
2611:
2612: OUTPW(CUR_X, COLOR_HORZ_EXPANSION_CACHE_X);
2613: OUTPW(CUR_Y, COLOR_HORZ_EXPANSION_CACHE_Y);
2614: OUTPW(DEST_X, COLOR_HORZ_EXPANSION_CACHE_X + 32);
2615: OUTPW(DEST_Y, COLOR_HORZ_EXPANSION_CACHE_Y);
2616:
2617: OUTPW(CMD, Cmd);
2618:
2619: // Now the rolling blit to fill all the way to 512 pels.
2620:
2621: FIFOWAIT(FIFO_7_EMPTY);
2622:
2623: OUTPW(RECT_WIDTH, COLOR_HORZ_EXPANSION_CACHE_CX - 65);
2624:
2625: OUTPW(CUR_X, COLOR_HORZ_EXPANSION_CACHE_X);
2626: OUTPW(CUR_Y, COLOR_HORZ_EXPANSION_CACHE_Y);
2627: OUTPW(DEST_X, COLOR_HORZ_EXPANSION_CACHE_X + 64);
2628: OUTPW(DEST_Y, COLOR_HORZ_EXPANSION_CACHE_Y);
2629:
2630: OUTPW(CMD, Cmd);
2631:
2632: return(TRUE);
2633: }
2634:
2635:
2636:
2637:
2638: /*****************************************************************************
2639: * Expand the monochrome brush in the horizontal dimension.
2640: ****************************************************************************/
2641: BOOL bExpandMonoBrushIntoHorzCache(
2642: PPDEV ppdev,
2643: PXYZPOINT pxyzPt,
2644: INT zHorz)
2645: {
2646: WORD Cmd;
2647:
2648: DISPDBG((3, "S3.DLL!bExpandMonoBrushIntoHorzCache - Entry\n"));
2649:
2650: // Copy the cached double wide, double high pattern to the Horizontal
2651: // expansion cache area.
2652:
2653: Cmd = BITBLT | DRAW | DIR_TYPE_XY | WRITE |
2654: MULTIPLE_PIXELS | DRAWING_DIR_TBLRXM;
2655:
2656: FIFOWAIT(FIFO_7_EMPTY);
2657:
2658: OUTPW(MULTIFUNC_CNTL, (DATA_EXTENSION | DISPLAY_MEMORY));
2659:
2660: TEST_AND_SET_FRGD_MIX(FOREGROUND_COLOR | OVERPAINT);
2661: TEST_AND_SET_FRGD_COLOR(0xff);
2662: TEST_AND_SET_BKGD_MIX(BACKGROUND_COLOR | OVERPAINT);
2663: SET_BKGD_COLOR(0);
2664:
2665: TEST_AND_SET_RD_MASK(LOWORD(pxyzPt->z));
2666: TEST_AND_SET_WRT_MASK(LOWORD(zHorz));
2667:
2668: FIFOWAIT(FIFO_7_EMPTY);
2669:
2670: OUTPW(RECT_WIDTH, 15);
2671: OUTPW(MULTIFUNC_CNTL, (RECT_HEIGHT | 15));
2672:
2673: OUTPW(CUR_X, pxyzPt->x);
2674: OUTPW(CUR_Y, pxyzPt->y);
2675: OUTPW(DEST_X, MONO_HORZ_EXPANSION_CACHE_X);
2676: OUTPW(DEST_Y, MONO_HORZ_EXPANSION_CACHE_Y);
2677:
2678: OUTPW(CMD, Cmd);
2679:
2680: // Expand the 16 X 16 double wide, double high.
2681: // First to a 32 X 16
2682:
2683: FIFOWAIT(FIFO_7_EMPTY);
2684:
2685: TEST_AND_SET_RD_MASK(LOWORD(zHorz));
2686:
2687: OUTPW(RECT_WIDTH, 15);
2688:
2689: OUTPW(CUR_X, MONO_HORZ_EXPANSION_CACHE_X);
2690: OUTPW(CUR_Y, MONO_HORZ_EXPANSION_CACHE_Y);
2691: OUTPW(DEST_X, MONO_HORZ_EXPANSION_CACHE_X + 16);
2692: OUTPW(DEST_Y, MONO_HORZ_EXPANSION_CACHE_Y);
2693:
2694: OUTPW(CMD, Cmd);
2695:
2696: // Now 64 X 16
2697:
2698: FIFOWAIT(FIFO_6_EMPTY);
2699:
2700: OUTPW(RECT_WIDTH, 31);
2701:
2702: OUTPW(CUR_X, MONO_HORZ_EXPANSION_CACHE_X);
2703: OUTPW(CUR_Y, MONO_HORZ_EXPANSION_CACHE_Y);
2704: OUTPW(DEST_X, MONO_HORZ_EXPANSION_CACHE_X + 32);
2705: OUTPW(DEST_Y, MONO_HORZ_EXPANSION_CACHE_Y);
2706:
2707: OUTPW(CMD, Cmd);
2708:
2709: // Now the rolling blit to fill all the way to 512 pels.
2710:
2711: FIFOWAIT(FIFO_7_EMPTY);
2712:
2713: OUTPW(RECT_WIDTH, MONO_HORZ_EXPANSION_CACHE_CX - 65);
2714:
2715: OUTPW(CUR_X, MONO_HORZ_EXPANSION_CACHE_X);
2716: OUTPW(CUR_Y, MONO_HORZ_EXPANSION_CACHE_Y);
2717: OUTPW(DEST_X, MONO_HORZ_EXPANSION_CACHE_X + 64);
2718: OUTPW(DEST_Y, MONO_HORZ_EXPANSION_CACHE_Y);
2719:
2720: OUTPW(CMD, Cmd);
2721:
2722: // Now reset the read and write plan masks.
2723:
2724: FIFOWAIT(FIFO_2_EMPTY);
2725:
2726: TEST_AND_SET_WRT_MASK(0xff);
2727: TEST_AND_SET_RD_MASK(0xff);
2728:
2729: return(TRUE);
2730: }
2731:
2732:
2733: /*****************************************************************************
2734: * Color brush in the Vertical Cache to the screen.
2735: ****************************************************************************/
2736: BOOL bColorVertCacheToScreen(
2737: PPDEV ppdev,
2738: PS3BRUSH ps3Brush,
2739: PPOINT pptBrushOrg,
2740: PPOINT pptDest,
2741: PSIZE psizDest,
2742: WORD s3ForeRop,
2743: WORD s3BackRop)
2744: {
2745: WORD Cmd;
2746: INT ixBlits, ixLast,
2747: iyFirst, iyBlits, iyLast,
2748: xOffset, yOffset,
2749: i, j;
2750:
2751: DISPDBG((3, "S3.DLL!bColorVertCacheToScreen - Entry\n"));
2752:
2753: // Take into account the pptBrushOrg.
2754:
2755: xOffset = pptDest->x - pptBrushOrg->x;
2756: yOffset = pptDest->y - pptBrushOrg->y;
2757:
2758: if (xOffset < 0)
2759: xOffset = 8 - (-xOffset % 8);
2760: else
2761: xOffset %= 8;
2762:
2763: if (yOffset < 0)
2764: yOffset = 8 - (-yOffset % 8);
2765: else
2766: yOffset %= 8;
2767:
2768: // Color Expand the monochrome vertical cache to the screen.
2769: // This is done in a loop to handle the general case ROPs.
2770:
2771: if (psizDest->cy < 8 - yOffset)
2772: {
2773: iyFirst = psizDest->cy;
2774: iyBlits = 0;
2775: iyLast = 0;
2776:
2777: }
2778: else if (psizDest->cy - yOffset < COLOR_VERT_EXPANSION_CACHE_CY - 8)
2779: {
2780: iyFirst = 8 - yOffset;
2781: iyBlits = 0;
2782: iyLast = psizDest->cy - iyFirst;
2783: }
2784: else
2785: {
2786: iyFirst = 8 - yOffset;
2787: iyBlits = (psizDest->cy - iyFirst) / (COLOR_VERT_EXPANSION_CACHE_CY - 8);
2788: iyLast = (psizDest->cy - iyFirst) % (COLOR_VERT_EXPANSION_CACHE_CY - 8);
2789: }
2790:
2791: ixBlits = psizDest->cx / 8;
2792: ixLast = psizDest->cx % 8;
2793:
2794: Cmd = BITBLT | DRAW | DIR_TYPE_XY | WRITE |
2795: MULTIPLE_PIXELS| DRAWING_DIR_TBLRXM;
2796:
2797: FIFOWAIT(FIFO_4_EMPTY);
2798:
2799: TEST_AND_SET_FRGD_MIX(SRC_DISPLAY_MEMORY | s3ForeRop);
2800: OUTPW(MULTIFUNC_CNTL, (DATA_EXTENSION | ALL_ONES));
2801: OUTPW(MULTIFUNC_CNTL, (RECT_HEIGHT | 7));
2802: OUTPW(RECT_WIDTH, 7);
2803:
2804: for(i = 0; i < ixBlits; i++)
2805: {
2806: ASSERTS3(((pptDest->x + (i * 8) + 7) < (INT) ppdev->cxScreen),
2807: "S3.DLL!bColorVertCacheToScreen - Blit Operation over right edge (1)\n");
2808:
2809: if (iyFirst != 0)
2810: {
2811: FIFOWAIT(FIFO_6_EMPTY);
2812:
2813: OUTPW(MULTIFUNC_CNTL, (RECT_HEIGHT | iyFirst - 1));
2814:
2815: OUTPW(CUR_X, COLOR_VERT_EXPANSION_CACHE_X + xOffset);
2816: OUTPW(CUR_Y, COLOR_VERT_EXPANSION_CACHE_Y + yOffset);
2817: OUTPW(DEST_X, pptDest->x + (i * 8));
2818: OUTPW(DEST_Y, pptDest->y);
2819:
2820: OUTPW(CMD, Cmd);
2821: }
2822:
2823: if (iyBlits != 0)
2824: {
2825: FIFOWAIT(FIFO_1_EMPTY);
2826: OUTPW(MULTIFUNC_CNTL, (RECT_HEIGHT | (COLOR_VERT_EXPANSION_CACHE_CY - 8) - 1));
2827: }
2828:
2829: for (j = 0; j <iyBlits; j++)
2830: {
2831: FIFOWAIT(FIFO_5_EMPTY);
2832:
2833: OUTPW(CUR_X, COLOR_VERT_EXPANSION_CACHE_X + xOffset);
2834: OUTPW(CUR_Y, COLOR_VERT_EXPANSION_CACHE_Y);
2835: OUTPW(DEST_X, pptDest->x + (i * 8));
2836: OUTPW(DEST_Y, pptDest->y + iyFirst +
2837: (j * (COLOR_VERT_EXPANSION_CACHE_CY - 8)));
2838:
2839: OUTPW(CMD, Cmd);
2840: }
2841:
2842: if (iyLast != 0)
2843: {
2844: FIFOWAIT(FIFO_6_EMPTY);
2845:
2846: OUTPW(MULTIFUNC_CNTL, (RECT_HEIGHT | iyLast - 1));
2847:
2848: OUTPW(CUR_X, COLOR_VERT_EXPANSION_CACHE_X + xOffset);
2849: OUTPW(CUR_Y, COLOR_VERT_EXPANSION_CACHE_Y);
2850: OUTPW(DEST_X, pptDest->x + (i * 8));
2851: OUTPW(DEST_Y, pptDest->y + iyFirst +
2852: (iyBlits * (COLOR_VERT_EXPANSION_CACHE_CY - 8)));
2853:
2854: OUTPW(CMD, Cmd);
2855: }
2856: }
2857:
2858: if (ixLast != 0)
2859: {
2860: FIFOWAIT(FIFO_1_EMPTY);
2861: OUTPW(RECT_WIDTH, ixLast - 1);
2862:
2863: ASSERTS3(((pptDest->x + (ixBlits * 8) + (ixLast - 1)) < (INT) ppdev->cxScreen),
2864: "S3.DLL!bColorVertCacheToScreen - Blit Operation over right edge (2)\n");
2865:
2866: if (iyFirst != 0)
2867: {
2868: FIFOWAIT(FIFO_6_EMPTY);
2869:
2870: OUTPW(MULTIFUNC_CNTL, (RECT_HEIGHT | iyFirst - 1));
2871:
2872: OUTPW(CUR_X, COLOR_VERT_EXPANSION_CACHE_X + xOffset);
2873: OUTPW(CUR_Y, COLOR_VERT_EXPANSION_CACHE_Y + yOffset);
2874: OUTPW(DEST_X, pptDest->x + (ixBlits * 8));
2875: OUTPW(DEST_Y, pptDest->y);
2876:
2877: OUTPW(CMD, Cmd);
2878: }
2879:
2880: if (iyBlits != 0)
2881: {
2882: FIFOWAIT(FIFO_1_EMPTY);
2883: OUTPW(MULTIFUNC_CNTL, (RECT_HEIGHT | (COLOR_VERT_EXPANSION_CACHE_CY - 8) - 1));
2884: }
2885:
2886: for (j = 0; j <iyBlits; j++)
2887: {
2888: FIFOWAIT(FIFO_5_EMPTY);
2889:
2890: OUTPW(CUR_X, COLOR_VERT_EXPANSION_CACHE_X + xOffset);
2891: OUTPW(CUR_Y, COLOR_VERT_EXPANSION_CACHE_Y);
2892: OUTPW(DEST_X, pptDest->x + (ixBlits * 8));
2893: OUTPW(DEST_Y, pptDest->y + iyFirst +
2894: (j * (COLOR_VERT_EXPANSION_CACHE_CY - 8)));
2895:
2896: OUTPW(CMD, Cmd);
2897: }
2898:
2899: if (iyLast != 0)
2900: {
2901: FIFOWAIT(FIFO_6_EMPTY);
2902:
2903: OUTPW(MULTIFUNC_CNTL, (RECT_HEIGHT | iyLast - 1));
2904:
2905: OUTPW(CUR_X, COLOR_VERT_EXPANSION_CACHE_X + xOffset);
2906: OUTPW(CUR_Y, COLOR_VERT_EXPANSION_CACHE_Y);
2907: OUTPW(DEST_X, pptDest->x + (ixBlits * 8));
2908: OUTPW(DEST_Y, pptDest->y + iyFirst +
2909: (iyBlits * (COLOR_VERT_EXPANSION_CACHE_CY - 8)));
2910:
2911: OUTPW(CMD, Cmd);
2912: }
2913: }
2914:
2915: return(TRUE);
2916: }
2917:
2918: /*****************************************************************************
2919: * Color expand the monochrome brush in the Vertical Cache to the screen.
2920: ****************************************************************************/
2921: BOOL bColorExpandVertCacheToScreen(
2922: PPDEV ppdev,
2923: PS3BRUSH ps3Brush,
2924: INT zVert,
2925: PPOINT pptBrushOrg,
2926: PPOINT pptDest,
2927: PSIZE psizDest,
2928: WORD s3ForeRop,
2929: WORD s3BackRop)
2930: {
2931: WORD Cmd;
2932: INT ixBlits, ixLast,
2933: iyFirst, iyBlits, iyLast,
2934: xOffset, yOffset,
2935: i, j;
2936:
2937: DISPDBG((3, "S3.DLL!bColorExpandVertCacheToScreen - Entry\n"));
2938:
2939: // Take into account the pptBrushOrg.
2940:
2941: xOffset = pptDest->x - pptBrushOrg->x;
2942: yOffset = pptDest->y - pptBrushOrg->y;
2943:
2944: if (xOffset < 0)
2945: xOffset = 8 - (-xOffset % 8);
2946: else
2947: xOffset %= 8;
2948:
2949: if (yOffset < 0)
2950: yOffset = 8 - (-yOffset % 8);
2951: else
2952: yOffset %= 8;
2953:
2954: // Color Expand the monochrome vertical cache to the screen.
2955: // This is done in a loop to handle the general case ROPs.
2956:
2957: if (psizDest->cy < 8 - yOffset)
2958: {
2959: iyFirst = psizDest->cy;
2960: iyBlits = 0;
2961: iyLast = 0;
2962:
2963: }
2964: else if (psizDest->cy - yOffset < MONO_VERT_EXPANSION_CACHE_CY - 8)
2965: {
2966: iyFirst = 8 - yOffset;
2967: iyBlits = 0;
2968: iyLast = psizDest->cy - iyFirst;
2969: }
2970: else
2971: {
2972: iyFirst = 8 - yOffset;
2973: iyBlits = (psizDest->cy - iyFirst) / (MONO_VERT_EXPANSION_CACHE_CY - 8);
2974: iyLast = (psizDest->cy - iyFirst) % (MONO_VERT_EXPANSION_CACHE_CY - 8);
2975: }
2976:
2977: ixBlits = psizDest->cx / 8;
2978: ixLast = psizDest->cx % 8;
2979:
2980: Cmd = BITBLT | DRAW | DIR_TYPE_XY | WRITE |
2981: MULTIPLE_PIXELS| DRAWING_DIR_TBLRXM;
2982:
2983: FIFOWAIT(FIFO_7_EMPTY);
2984:
2985: TEST_AND_SET_RD_MASK(zVert);
2986:
2987: TEST_AND_SET_FRGD_MIX(FOREGROUND_COLOR | s3ForeRop);
2988: TEST_AND_SET_FRGD_COLOR(LOWORD(ps3Brush->ulForeColor));
2989:
2990: TEST_AND_SET_BKGD_MIX(BACKGROUND_COLOR | s3BackRop);
2991: SET_BKGD_COLOR(LOWORD(ps3Brush->ulBackColor));
2992:
2993: OUTPW(MULTIFUNC_CNTL, (DATA_EXTENSION | DISPLAY_MEMORY));
2994:
2995: OUTPW(RECT_WIDTH, 7);
2996:
2997: for(i = 0; i < ixBlits; i++)
2998: {
2999: ASSERTS3(((pptDest->x + (i * 8) + 7) < (INT) ppdev->cxScreen),
3000: "S3.DLL!bColorExpandVertCacheToScreen - Blit Operation over right edge (1)\n");
3001:
3002: if (iyFirst != 0)
3003: {
3004: FIFOWAIT(FIFO_6_EMPTY);
3005:
3006: OUTPW(MULTIFUNC_CNTL, (RECT_HEIGHT | iyFirst - 1));
3007:
3008: OUTPW(CUR_X, MONO_VERT_EXPANSION_CACHE_X + xOffset);
3009: OUTPW(CUR_Y, MONO_VERT_EXPANSION_CACHE_Y + yOffset);
3010: OUTPW(DEST_X, pptDest->x + (i * 8));
3011: OUTPW(DEST_Y, pptDest->y);
3012:
3013: OUTPW(CMD, Cmd);
3014: }
3015:
3016: if (iyBlits != 0)
3017: {
3018: FIFOWAIT(FIFO_1_EMPTY);
3019: OUTPW(MULTIFUNC_CNTL, (RECT_HEIGHT | (MONO_VERT_EXPANSION_CACHE_CY - 8) - 1));
3020: }
3021:
3022: for (j = 0; j <iyBlits; j++)
3023: {
3024: FIFOWAIT(FIFO_5_EMPTY);
3025:
3026: OUTPW(CUR_X, MONO_VERT_EXPANSION_CACHE_X + xOffset);
3027: OUTPW(CUR_Y, MONO_VERT_EXPANSION_CACHE_Y);
3028: OUTPW(DEST_X, pptDest->x + (i * 8));
3029: OUTPW(DEST_Y, pptDest->y + iyFirst +
3030: (j * (MONO_VERT_EXPANSION_CACHE_CY - 8)));
3031:
3032: OUTPW(CMD, Cmd);
3033: }
3034:
3035: if (iyLast != 0)
3036: {
3037: FIFOWAIT(FIFO_6_EMPTY);
3038:
3039: OUTPW(MULTIFUNC_CNTL, (RECT_HEIGHT | iyLast - 1));
3040:
3041: OUTPW(CUR_X, MONO_VERT_EXPANSION_CACHE_X + xOffset);
3042: OUTPW(CUR_Y, MONO_VERT_EXPANSION_CACHE_Y);
3043: OUTPW(DEST_X, pptDest->x + (i * 8));
3044: OUTPW(DEST_Y, pptDest->y + iyFirst +
3045: (iyBlits * (MONO_VERT_EXPANSION_CACHE_CY - 8)));
3046:
3047: OUTPW(CMD, Cmd);
3048: }
3049: }
3050:
3051: if (ixLast != 0)
3052: {
3053: FIFOWAIT(FIFO_1_EMPTY);
3054: OUTPW(RECT_WIDTH, ixLast - 1);
3055:
3056: ASSERTS3(((pptDest->x + (ixBlits * 8) + (ixLast - 1)) < (INT) ppdev->cxScreen),
3057: "S3.DLL!bColorExpandVertCacheToScreen - Blit Operation over right edge (2)\n");
3058:
3059: if (iyFirst != 0)
3060: {
3061: FIFOWAIT(FIFO_6_EMPTY);
3062:
3063: OUTPW(MULTIFUNC_CNTL, (RECT_HEIGHT | iyFirst - 1));
3064:
3065: OUTPW(CUR_X, MONO_VERT_EXPANSION_CACHE_X + xOffset);
3066: OUTPW(CUR_Y, MONO_VERT_EXPANSION_CACHE_Y + yOffset);
3067: OUTPW(DEST_X, pptDest->x + (ixBlits * 8));
3068: OUTPW(DEST_Y, pptDest->y);
3069:
3070: OUTPW(CMD, Cmd);
3071: }
3072:
3073: if (iyBlits != 0)
3074: {
3075: FIFOWAIT(FIFO_1_EMPTY);
3076: OUTPW(MULTIFUNC_CNTL, (RECT_HEIGHT | (MONO_VERT_EXPANSION_CACHE_CY - 8) - 1));
3077: }
3078:
3079: for (j = 0; j <iyBlits; j++)
3080: {
3081: FIFOWAIT(FIFO_5_EMPTY);
3082:
3083: OUTPW(CUR_X, MONO_VERT_EXPANSION_CACHE_X + xOffset);
3084: OUTPW(CUR_Y, MONO_VERT_EXPANSION_CACHE_Y);
3085: OUTPW(DEST_X, pptDest->x + (ixBlits * 8));
3086: OUTPW(DEST_Y, pptDest->y + iyFirst +
3087: (j * (MONO_VERT_EXPANSION_CACHE_CY - 8)));
3088:
3089: OUTPW(CMD, Cmd);
3090: }
3091:
3092: if (iyLast != 0)
3093: {
3094: FIFOWAIT(FIFO_6_EMPTY);
3095:
3096: OUTPW(MULTIFUNC_CNTL, (RECT_HEIGHT | iyLast - 1));
3097:
3098: OUTPW(CUR_X, MONO_VERT_EXPANSION_CACHE_X + xOffset);
3099: OUTPW(CUR_Y, MONO_VERT_EXPANSION_CACHE_Y);
3100: OUTPW(DEST_X, pptDest->x + (ixBlits * 8));
3101: OUTPW(DEST_Y, pptDest->y + iyFirst +
3102: (iyBlits * (MONO_VERT_EXPANSION_CACHE_CY - 8)));
3103:
3104: OUTPW(CMD, Cmd);
3105: }
3106: }
3107:
3108: // Reset the Read Mask
3109:
3110: FIFOWAIT(FIFO_2_EMPTY);
3111:
3112: TEST_AND_SET_WRT_MASK(0xff);
3113: TEST_AND_SET_RD_MASK(0xff);
3114:
3115: return(TRUE);
3116: }
3117:
3118:
3119: /*****************************************************************************
3120: * Color brush in the Hoizontal Cache to the screen.
3121: ****************************************************************************/
3122: BOOL bColorHorzCacheToScreen(
3123: PPDEV ppdev,
3124: PS3BRUSH ps3Brush,
3125: PPOINT pptBrushOrg,
3126: PPOINT pptDest,
3127: PSIZE psizDest,
3128: WORD s3ForeRop,
3129: WORD s3BackRop)
3130: {
3131: WORD Cmd;
3132: INT xLeft, cxLeft, cxRight, ixBlits, i, j, x, cx,
3133: iyBlits, iyLast,
3134: xOffset, yOffset;
3135:
3136: DISPDBG((3, "S3.DLL!bColorHorzCacheToScreen - Entry\n"));
3137:
3138: // Take into account the pptBrushOrg.
3139:
3140: xOffset = pptDest->x - pptBrushOrg->x;
3141: yOffset = pptDest->y - pptBrushOrg->y;
3142:
3143: if (xOffset < 0)
3144: xOffset = 8 - (-xOffset % 8);
3145: else
3146: xOffset %= 8;
3147:
3148: if (yOffset < 0)
3149: yOffset = 8 - (-yOffset % 8);
3150: else
3151: yOffset %= 8;
3152:
3153: // Color Expand the monochrome horizontal cache to the screen.
3154: // This is done in a loop to handle the general case ROPs.
3155:
3156: xLeft = pptDest->x;
3157: cxLeft = COLOR_HORZ_EXPANSION_CACHE_CX - xOffset;
3158:
3159: if ((cx = psizDest->cx - cxLeft) < 0)
3160: {
3161: cxLeft = psizDest->cx;
3162: ixBlits = 0;
3163: cxRight = 0;
3164: }
3165: else
3166: {
3167: ixBlits = cx / COLOR_HORZ_EXPANSION_CACHE_CX;
3168: cxRight = cx % COLOR_HORZ_EXPANSION_CACHE_CX;
3169: }
3170:
3171: iyBlits = psizDest->cy / 8;
3172: iyLast = psizDest->cy % 8;
3173:
3174: Cmd = BITBLT | DRAW | DIR_TYPE_XY | WRITE |
3175: MULTIPLE_PIXELS| DRAWING_DIR_TBLRXM;
3176:
3177: FIFOWAIT(FIFO_3_EMPTY);
3178:
3179: TEST_AND_SET_FRGD_MIX(SRC_DISPLAY_MEMORY | s3ForeRop);
3180: OUTPW(MULTIFUNC_CNTL, (DATA_EXTENSION | ALL_ONES));
3181: OUTPW(MULTIFUNC_CNTL, (RECT_HEIGHT | 7));
3182:
3183: for (i = 0; i < iyBlits; i++)
3184: {
3185: ASSERTS3(((pptDest->x + (cxLeft - 1)) < (INT) ppdev->cxScreen),
3186: "S3.DLL!bColorHorzCacheToScreen - Blit Operation over right edge (1)\n");
3187:
3188: FIFOWAIT(FIFO_6_EMPTY);
3189:
3190: OUTPW(RECT_WIDTH, cxLeft - 1);
3191:
3192: OUTPW(CUR_X, COLOR_HORZ_EXPANSION_CACHE_X + xOffset);
3193: OUTPW(CUR_Y, COLOR_HORZ_EXPANSION_CACHE_Y + yOffset);
3194: OUTPW(DEST_X, pptDest->x);
3195: OUTPW(DEST_Y, pptDest->y + (i * 8));
3196:
3197: OUTPW(CMD, Cmd);
3198:
3199: // If the the cxDest is wider than the cxHorzCache then fill in the
3200: // right side of the fill area.
3201:
3202: if (cx > 0)
3203: {
3204: FIFOWAIT(FIFO_1_EMPTY);
3205: OUTPW(RECT_WIDTH, COLOR_HORZ_EXPANSION_CACHE_CX - 1);
3206:
3207: for (j = 0; j < ixBlits; j++)
3208: {
3209: x = pptDest->x + cxLeft + (j * COLOR_HORZ_EXPANSION_CACHE_CX);
3210:
3211: ASSERTS3(((x + (COLOR_HORZ_EXPANSION_CACHE_CX - 1)) < (INT) ppdev->cxScreen),
3212: "S3.DLL!bColorHorzCacheToScreen - Blit Operation over right edge (2)\n");
3213:
3214: FIFOWAIT(FIFO_5_EMPTY);
3215:
3216: OUTPW(CUR_X, COLOR_HORZ_EXPANSION_CACHE_X);
3217: OUTPW(CUR_Y, COLOR_HORZ_EXPANSION_CACHE_Y + yOffset);
3218: OUTPW(DEST_X, x);
3219: OUTPW(DEST_Y, pptDest->y + (i * 8));
3220:
3221: OUTPW(CMD, Cmd);
3222: }
3223:
3224: if (cxRight != 0)
3225: {
3226: x = pptDest->x + cxLeft + (ixBlits * COLOR_HORZ_EXPANSION_CACHE_CX);
3227:
3228: ASSERTS3(((x + (cxRight - 1)) < (INT) ppdev->cxScreen),
3229: "S3.DLL!bColorHorzCacheToScreen - Blit Operation over right edge (3)\n");
3230:
3231: FIFOWAIT(FIFO_6_EMPTY);
3232:
3233: OUTPW(RECT_WIDTH, cxRight - 1);
3234:
3235: OUTPW(CUR_X, COLOR_HORZ_EXPANSION_CACHE_X);
3236: OUTPW(CUR_Y, COLOR_HORZ_EXPANSION_CACHE_Y + yOffset);
3237: OUTPW(DEST_X, x);
3238: OUTPW(DEST_Y, pptDest->y + (i * 8));
3239:
3240: OUTPW(CMD, Cmd);
3241: }
3242: }
3243: }
3244:
3245: if (iyLast != 0)
3246: {
3247: ASSERTS3(((pptDest->x + (cxLeft - 1)) < (INT) ppdev->cxScreen),
3248: "S3.DLL!bColorHorzCacheToScreen - Blit Operation over right edge (4)\n");
3249:
3250: FIFOWAIT(FIFO_7_EMPTY);
3251:
3252: OUTPW(RECT_WIDTH, cxLeft - 1);
3253: OUTPW(MULTIFUNC_CNTL, (RECT_HEIGHT | iyLast - 1));
3254:
3255: OUTPW(CUR_X, COLOR_HORZ_EXPANSION_CACHE_X + xOffset);
3256: OUTPW(CUR_Y, COLOR_HORZ_EXPANSION_CACHE_Y + yOffset);
3257: OUTPW(DEST_X, pptDest->x);
3258: OUTPW(DEST_Y, pptDest->y + (iyBlits * 8));
3259:
3260: OUTPW(CMD, Cmd);
3261:
3262: // If the the cxDest is wider than the cxHorzCache then fill in the
3263: // right side of the fill area.
3264:
3265: if (cx > 0)
3266: {
3267: FIFOWAIT(FIFO_1_EMPTY);
3268: OUTPW(RECT_WIDTH, COLOR_HORZ_EXPANSION_CACHE_CX - 1);
3269:
3270: for (j = 0; j < ixBlits; j++)
3271: {
3272: x = pptDest->x + cxLeft + (j * COLOR_HORZ_EXPANSION_CACHE_CX);
3273:
3274: ASSERTS3(((x + (COLOR_HORZ_EXPANSION_CACHE_CX - 1)) < (INT) ppdev->cxScreen),
3275: "S3.DLL!bColorHorzCacheToScreen - Blit Operation over right edge (5)\n");
3276:
3277: FIFOWAIT(FIFO_5_EMPTY);
3278:
3279: OUTPW(CUR_X, COLOR_HORZ_EXPANSION_CACHE_X);
3280: OUTPW(CUR_Y, COLOR_HORZ_EXPANSION_CACHE_Y + yOffset);
3281: OUTPW(DEST_X, x);
3282: OUTPW(DEST_Y, pptDest->y + (iyBlits * 8));
3283:
3284: OUTPW(CMD, Cmd);
3285: }
3286:
3287: if (cxRight != 0)
3288: {
3289: x = pptDest->x + cxLeft + (ixBlits * COLOR_HORZ_EXPANSION_CACHE_CX);
3290:
3291: ASSERTS3(((x + (cxRight - 1)) < (INT) ppdev->cxScreen),
3292: "S3.DLL!bColorHorzCacheToScreen - Blit Operation over right edge (6)\n");
3293:
3294: FIFOWAIT(FIFO_6_EMPTY);
3295:
3296: OUTPW(RECT_WIDTH, cxRight - 1);
3297:
3298: OUTPW(CUR_X, COLOR_HORZ_EXPANSION_CACHE_X);
3299: OUTPW(CUR_Y, COLOR_HORZ_EXPANSION_CACHE_Y + yOffset);
3300: OUTPW(DEST_X, x);
3301: OUTPW(DEST_Y, pptDest->y + (iyBlits * 8));
3302:
3303: OUTPW(CMD, Cmd);
3304: }
3305: }
3306: }
3307:
3308: return(TRUE);
3309: }
3310:
3311: /*****************************************************************************
3312: * Color expand the monochrome brush in the Hoizontal Cache to the screen.
3313: ****************************************************************************/
3314: BOOL bColorExpandHorzCacheToScreen(
3315: PPDEV ppdev,
3316: PS3BRUSH ps3Brush,
3317: INT zHorz,
3318: PPOINT pptBrushOrg,
3319: PPOINT pptDest,
3320: PSIZE psizDest,
3321: WORD s3ForeRop,
3322: WORD s3BackRop)
3323: {
3324: WORD Cmd;
3325: INT xLeft, cxLeft, xMiddle, cxMiddle, xRight, cxRight, i,
3326: iyBlits, iyLast,
3327: xOffset, yOffset;
3328:
3329: DISPDBG((3, "S3.DLL!bColorExpandHorzCacheToScreen - Entry\n"));
3330:
3331: // Take into account the pptBrushOrg.
3332:
3333: xOffset = pptDest->x - pptBrushOrg->x;
3334: yOffset = pptDest->y - pptBrushOrg->y;
3335:
3336: if (xOffset < 0)
3337: xOffset = 8 - (-xOffset % 8);
3338: else
3339: xOffset %= 8;
3340:
3341: if (yOffset < 0)
3342: yOffset = 8 - (-yOffset % 8);
3343: else
3344: yOffset %= 8;
3345:
3346: // Color Expand the monochrome horizontal cache to the screen.
3347: // This is done in a loop to handle the general case ROPs.
3348:
3349: xLeft = pptDest->x;
3350: cxLeft = MONO_HORZ_EXPANSION_CACHE_CX - xOffset;
3351:
3352: if (psizDest->cx < cxLeft)
3353: {
3354: cxLeft = psizDest->cx;
3355: xRight = 0;
3356: cxRight = 0;
3357: }
3358: else
3359: {
3360: xRight = pptDest->x + cxLeft;
3361: cxRight = psizDest->cx - cxLeft;
3362: }
3363:
3364: // This little hack is for 1280 mode.
3365: // Really the correct solution is to use the H/W support.
3366:
3367: if (cxRight > MONO_HORZ_EXPANSION_CACHE_CX)
3368: {
3369: xMiddle = xRight;
3370: xRight += MONO_HORZ_EXPANSION_CACHE_CX;
3371: cxMiddle = MONO_HORZ_EXPANSION_CACHE_CX;
3372: cxRight -= MONO_HORZ_EXPANSION_CACHE_CX;
3373: }
3374: else
3375: {
3376: xMiddle = 0;
3377: cxMiddle = 0;
3378: }
3379:
3380: iyBlits = psizDest->cy / 8;
3381: iyLast = psizDest->cy % 8;
3382:
3383: Cmd = BITBLT | DRAW | DIR_TYPE_XY | WRITE |
3384: MULTIPLE_PIXELS| DRAWING_DIR_TBLRXM;
3385:
3386: FIFOWAIT(FIFO_7_EMPTY);
3387:
3388: TEST_AND_SET_RD_MASK(zHorz);
3389:
3390: TEST_AND_SET_FRGD_MIX(FOREGROUND_COLOR | s3ForeRop);
3391: TEST_AND_SET_FRGD_COLOR(LOWORD(ps3Brush->ulForeColor));
3392:
3393: TEST_AND_SET_BKGD_MIX(BACKGROUND_COLOR | s3BackRop);
3394: SET_BKGD_COLOR(LOWORD(ps3Brush->ulBackColor));
3395:
3396: OUTPW(MULTIFUNC_CNTL, (DATA_EXTENSION | DISPLAY_MEMORY));
3397:
3398: OUTPW(MULTIFUNC_CNTL, (RECT_HEIGHT | 7));
3399:
3400: for (i = 0; i < iyBlits; i++)
3401: {
3402: ASSERTS3(((pptDest->x + (cxLeft - 1)) < (INT) ppdev->cxScreen),
3403: "S3.DLL!bColorExpandHorzCacheToScreen - Blit Operation over right edge (1)\n");
3404:
3405: FIFOWAIT(FIFO_6_EMPTY);
3406:
3407: OUTPW(RECT_WIDTH, cxLeft - 1);
3408:
3409: OUTPW(CUR_X, MONO_HORZ_EXPANSION_CACHE_X + xOffset);
3410: OUTPW(CUR_Y, MONO_HORZ_EXPANSION_CACHE_Y + yOffset);
3411: OUTPW(DEST_X, pptDest->x);
3412: OUTPW(DEST_Y, pptDest->y + (i * 8));
3413:
3414: OUTPW(CMD, Cmd);
3415:
3416: if (cxMiddle != 0)
3417: {
3418: ASSERTS3(((xMiddle + (cxMiddle - 1)) < (INT) ppdev->cxScreen),
3419: "S3.DLL!bColorExpandHorzCacheToScreen - Blit Operation over right edge (2)\n");
3420:
3421: FIFOWAIT(FIFO_6_EMPTY);
3422:
3423: OUTPW(RECT_WIDTH, cxMiddle - 1);
3424:
3425: OUTPW(CUR_X, MONO_HORZ_EXPANSION_CACHE_X);
3426: OUTPW(CUR_Y, MONO_HORZ_EXPANSION_CACHE_Y + yOffset);
3427: OUTPW(DEST_X, xMiddle);
3428: OUTPW(DEST_Y, pptDest->y + (i * 8));
3429:
3430: OUTPW(CMD, Cmd);
3431: }
3432:
3433: // If the the cxDest is wider than the cxHorzCache then fill in the
3434: // right side of the fill area.
3435:
3436: if (cxRight != 0)
3437: {
3438: ASSERTS3(((xRight + (cxRight - 1)) < (INT) ppdev->cxScreen),
3439: "S3.DLL!bColorExpandHorzCacheToScreen - Blit Operation over right edge (3)\n");
3440:
3441: FIFOWAIT(FIFO_6_EMPTY);
3442:
3443: OUTPW(RECT_WIDTH, cxRight - 1);
3444:
3445: OUTPW(CUR_X, MONO_HORZ_EXPANSION_CACHE_X);
3446: OUTPW(CUR_Y, MONO_HORZ_EXPANSION_CACHE_Y + yOffset);
3447: OUTPW(DEST_X, xRight);
3448: OUTPW(DEST_Y, pptDest->y + (i * 8));
3449:
3450: OUTPW(CMD, Cmd);
3451: }
3452: }
3453:
3454: if (iyLast != 0)
3455: {
3456: ASSERTS3(((pptDest->x + (cxLeft - 1)) < (INT) ppdev->cxScreen),
3457: "S3.DLL!bColorExpandHorzCacheToScreen - Blit Operation over right edge (3)\n");
3458:
3459: FIFOWAIT(FIFO_7_EMPTY);
3460:
3461: OUTPW(RECT_WIDTH, cxLeft - 1);
3462: OUTPW(MULTIFUNC_CNTL, (RECT_HEIGHT | iyLast - 1));
3463:
3464: OUTPW(CUR_X, MONO_HORZ_EXPANSION_CACHE_X + xOffset);
3465: OUTPW(CUR_Y, MONO_HORZ_EXPANSION_CACHE_Y + yOffset);
3466: OUTPW(DEST_X, pptDest->x);
3467: OUTPW(DEST_Y, pptDest->y + (iyBlits * 8));
3468:
3469: OUTPW(CMD, Cmd);
3470:
3471: if (cxMiddle != 0)
3472: {
3473: ASSERTS3(((xMiddle + (cxMiddle - 1)) < (INT) ppdev->cxScreen),
3474: "S3.DLL!bColorExpandHorzCacheToScreen - Blit Operation over right edge (4)\n");
3475:
3476: FIFOWAIT(FIFO_6_EMPTY);
3477:
3478: OUTPW(RECT_WIDTH, cxMiddle - 1);
3479:
3480: OUTPW(CUR_X, MONO_HORZ_EXPANSION_CACHE_X);
3481: OUTPW(CUR_Y, MONO_HORZ_EXPANSION_CACHE_Y + yOffset);
3482: OUTPW(DEST_X, xMiddle);
3483: OUTPW(DEST_Y, pptDest->y + (iyBlits * 8));
3484:
3485: OUTPW(CMD, Cmd);
3486: }
3487:
3488: // If the the cxDest is wider than the cxHorzCache then fill in the
3489: // right side of the fill area.
3490:
3491: if (cxRight != 0)
3492: {
3493: ASSERTS3(((xRight + (cxRight - 1)) < (INT) ppdev->cxScreen),
3494: "S3.DLL!bColorExpandHorzCacheToScreen - Blit Operation over right edge (4)\n");
3495:
3496: FIFOWAIT(FIFO_6_EMPTY);
3497:
3498: OUTPW(RECT_WIDTH, cxRight - 1);
3499:
3500: OUTPW(CUR_X, MONO_HORZ_EXPANSION_CACHE_X);
3501: OUTPW(CUR_Y, MONO_HORZ_EXPANSION_CACHE_Y + yOffset);
3502: OUTPW(DEST_X, xRight);
3503: OUTPW(DEST_Y, pptDest->y + (iyBlits * 8));
3504:
3505: OUTPW(CMD, Cmd);
3506: }
3507: }
3508:
3509: // Reset the Read Mask
3510:
3511: FIFOWAIT(FIFO_2_EMPTY);
3512:
3513: TEST_AND_SET_WRT_MASK(0xff);
3514: TEST_AND_SET_RD_MASK(0xff);
3515:
3516: return(TRUE);
3517: }
3518:
3519:
3520: /*****************************************************************************
3521: * Copy Optimized
3522: * Color brush in the Hoizontal Cache to the screen.
3523: ****************************************************************************/
3524: BOOL bCpyColorHorzCacheToScreen(
3525: PPDEV ppdev,
3526: PS3BRUSH ps3Brush,
3527: PPOINT pptBrushOrg,
3528: PPOINT pptDest,
3529: PSIZE psizDest)
3530: {
3531: WORD Cmd;
3532: INT cx, cxLeft, ixBlits, ixLast, i,
3533: cy, x, xOffset, yOffset;
3534:
3535: DISPDBG((3, "S3.DLL!bCpyColorHorzCacheToScreen - Entry\n"));
3536:
3537: // Take into account the pptBrushOrg.
3538:
3539: xOffset = pptDest->x - pptBrushOrg->x;
3540: yOffset = pptDest->y - pptBrushOrg->y;
3541:
3542: if (xOffset < 0)
3543: xOffset = 8 - (-xOffset % 8);
3544: else
3545: xOffset %= 8;
3546:
3547: if (yOffset < 0)
3548: yOffset = 8 - (-yOffset % 8);
3549: else
3550: yOffset %= 8;
3551:
3552: // First Color Expand the monochrome horizontal cache to the screen.
3553:
3554: cxLeft = COLOR_HORZ_EXPANSION_CACHE_CX - xOffset;
3555: if (psizDest->cx < cxLeft)
3556: cxLeft = psizDest->cx;
3557:
3558: cy = 8;
3559: if (psizDest->cy < cy)
3560: cy = psizDest->cy;
3561:
3562: Cmd = BITBLT | DRAW | DIR_TYPE_XY | WRITE |
3563: MULTIPLE_PIXELS| DRAWING_DIR_TBLRXM;
3564:
3565: ASSERTS3(((pptDest->x + (cxLeft - 1)) < (INT) ppdev->cxScreen),
3566: "S3.DLL!bCpyColorHorzCacheToScreen - Blit Operation over right edge (1)\n");
3567:
3568: FIFOWAIT(FIFO_2_EMPTY);
3569:
3570: TEST_AND_SET_FRGD_MIX(SRC_DISPLAY_MEMORY | OVERPAINT);
3571: OUTPW(MULTIFUNC_CNTL, (DATA_EXTENSION | ALL_ONES));
3572:
3573: FIFOWAIT(FIFO_7_EMPTY);
3574:
3575: OUTPW(RECT_WIDTH, cxLeft - 1);
3576: OUTPW(MULTIFUNC_CNTL, (RECT_HEIGHT | (cy - 1)));
3577:
3578: OUTPW(CUR_X, COLOR_HORZ_EXPANSION_CACHE_X + xOffset);
3579: OUTPW(CUR_Y, COLOR_HORZ_EXPANSION_CACHE_Y + yOffset);
3580: OUTPW(DEST_X, pptDest->x);
3581: OUTPW(DEST_Y, pptDest->y);
3582:
3583: OUTPW(CMD, Cmd);
3584:
3585: // If the the cxDest is wider than the cxHorzCache then fill in the
3586: // right side of the fill area.
3587:
3588: if ((cx = psizDest->cx - cxLeft) > 0)
3589: {
3590: ixBlits = cx / COLOR_HORZ_EXPANSION_CACHE_CX;
3591: ixLast = cx % COLOR_HORZ_EXPANSION_CACHE_CX;
3592:
3593: FIFOWAIT(FIFO_1_EMPTY);
3594: OUTPW(RECT_WIDTH, COLOR_HORZ_EXPANSION_CACHE_CX - 1);
3595:
3596: for (i = 0; i < ixBlits; i++)
3597: {
3598: x = pptDest->x + cxLeft + (i * COLOR_HORZ_EXPANSION_CACHE_CX);
3599:
3600: ASSERTS3(((x + (COLOR_HORZ_EXPANSION_CACHE_CX - 1)) < (INT) ppdev->cxScreen),
3601: "S3.DLL!bCpyColorHorzCacheToScreen - Blit Operation over right edge (2)\n");
3602:
3603: FIFOWAIT(FIFO_5_EMPTY);
3604:
3605: OUTPW(CUR_X, COLOR_HORZ_EXPANSION_CACHE_X);
3606: OUTPW(CUR_Y, COLOR_HORZ_EXPANSION_CACHE_Y + yOffset);
3607: OUTPW(DEST_X, x);
3608: OUTPW(DEST_Y, pptDest->y);
3609:
3610: OUTPW(CMD, Cmd);
3611: }
3612:
3613: if (ixLast != 0)
3614: {
3615: x = pptDest->x + cxLeft + (ixBlits * COLOR_HORZ_EXPANSION_CACHE_CX);
3616:
3617: ASSERTS3(((x + (ixLast - 1)) < (INT) ppdev->cxScreen),
3618: "S3.DLL!bCpyColorHorzCacheToScreen - Blit Operation over right edge (3)\n");
3619:
3620: FIFOWAIT(FIFO_6_EMPTY);
3621:
3622: OUTPW(RECT_WIDTH, ixLast - 1);
3623:
3624: OUTPW(CUR_X, COLOR_HORZ_EXPANSION_CACHE_X);
3625: OUTPW(CUR_Y, COLOR_HORZ_EXPANSION_CACHE_Y + yOffset);
3626: OUTPW(DEST_X, x);
3627: OUTPW(DEST_Y, pptDest->y);
3628:
3629: OUTPW(CMD, Cmd);
3630: }
3631: }
3632:
3633: // If the cyDest is taller than 8 pels do a rolling blit to fill in
3634: // the bottom of the fill area.
3635:
3636: if (psizDest->cy > 8)
3637: {
3638: ASSERTS3(((pptDest->x + (psizDest->cx - 1)) < (INT) ppdev->cxScreen),
3639: "S3.DLL!bCpyColorHorzCacheToScreen - Blit Operation over right edge (4)\n");
3640:
3641: FIFOWAIT(FIFO_7_EMPTY);
3642:
3643: OUTPW(RECT_WIDTH, psizDest->cx - 1);
3644: OUTPW(MULTIFUNC_CNTL, (RECT_HEIGHT | psizDest->cy - (cy + 1)));
3645:
3646: OUTPW(CUR_X, pptDest->x);
3647: OUTPW(CUR_Y, pptDest->y);
3648: OUTPW(DEST_X, pptDest->x);
3649: OUTPW(DEST_Y, pptDest->y + 8);
3650:
3651: OUTPW(CMD, Cmd);
3652: }
3653:
3654: return(TRUE);
3655: }
3656:
3657: /*****************************************************************************
3658: * Copy Optimized
3659: * Color expand the monochrome brush in the Hoizontal Cache to the screen.
3660: ****************************************************************************/
3661: BOOL bCpyColorExpandHorzCacheToScreen(
3662: PPDEV ppdev,
3663: PS3BRUSH ps3Brush,
3664: INT zHorz,
3665: PPOINT pptBrushOrg,
3666: PPOINT pptDest,
3667: PSIZE psizDest)
3668: {
3669: WORD Cmd;
3670: INT cx, cxLeft, ixBlits, ixLast, i,
3671: cy, x, xOffset, yOffset;
3672:
3673: DISPDBG((3, "S3.DLL!bCpyColorExpandHorzCacheToScreen - Entry\n"));
3674:
3675: // Take into account the pptBrushOrg.
3676:
3677: xOffset = pptDest->x - pptBrushOrg->x;
3678: yOffset = pptDest->y - pptBrushOrg->y;
3679:
3680: if (xOffset < 0)
3681: xOffset = 8 - (-xOffset % 8);
3682: else
3683: xOffset %= 8;
3684:
3685: if (yOffset < 0)
3686: yOffset = 8 - (-yOffset % 8);
3687: else
3688: yOffset %= 8;
3689:
3690: // First Color Expand the monochrome horizontal cache to the screen.
3691:
3692: cxLeft = MONO_HORZ_EXPANSION_CACHE_CX - xOffset;
3693: if (psizDest->cx < cxLeft)
3694: cxLeft = psizDest->cx;
3695:
3696: cy = 8;
3697: if (psizDest->cy < cy)
3698: cy = psizDest->cy;
3699:
3700: Cmd = BITBLT | DRAW | DIR_TYPE_XY | WRITE |
3701: MULTIPLE_PIXELS| DRAWING_DIR_TBLRXM;
3702:
3703: ASSERTS3(((pptDest->x + (cxLeft - 1)) < (INT) ppdev->cxScreen),
3704: "S3.DLL!bCpyColorExpandHorzCacheToScreen - Blit Operation over right edge (1)\n");
3705:
3706: FIFOWAIT(FIFO_6_EMPTY);
3707:
3708: TEST_AND_SET_RD_MASK(zHorz);
3709:
3710: TEST_AND_SET_FRGD_MIX(FOREGROUND_COLOR | OVERPAINT);
3711: TEST_AND_SET_FRGD_COLOR(LOWORD(ps3Brush->ulForeColor));
3712:
3713: TEST_AND_SET_BKGD_MIX(BACKGROUND_COLOR | OVERPAINT);
3714: SET_BKGD_COLOR(LOWORD(ps3Brush->ulBackColor));
3715:
3716: OUTPW(MULTIFUNC_CNTL, (DATA_EXTENSION | DISPLAY_MEMORY));
3717:
3718: FIFOWAIT(FIFO_7_EMPTY);
3719:
3720: OUTPW(RECT_WIDTH, cxLeft - 1);
3721: OUTPW(MULTIFUNC_CNTL, (RECT_HEIGHT | (cy - 1)));
3722:
3723: OUTPW(CUR_X, MONO_HORZ_EXPANSION_CACHE_X + xOffset);
3724: OUTPW(CUR_Y, MONO_HORZ_EXPANSION_CACHE_Y + yOffset);
3725: OUTPW(DEST_X, pptDest->x);
3726: OUTPW(DEST_Y, pptDest->y);
3727:
3728: OUTPW(CMD, Cmd);
3729:
3730: // If the the cxDest is wider than the cxHorzCache then fill in the
3731: // right side of the fill area.
3732:
3733: if ((cx = psizDest->cx - cxLeft) > 0)
3734: {
3735: ixBlits = cx / MONO_HORZ_EXPANSION_CACHE_CX;
3736: ixLast = cx % MONO_HORZ_EXPANSION_CACHE_CX;
3737:
3738: FIFOWAIT(FIFO_1_EMPTY);
3739: OUTPW(RECT_WIDTH, MONO_HORZ_EXPANSION_CACHE_CX - 1);
3740:
3741: for (i = 0; i < ixBlits; i++)
3742: {
3743: x = pptDest->x + cxLeft + (i * MONO_HORZ_EXPANSION_CACHE_CX);
3744:
3745: ASSERTS3(((x + (COLOR_HORZ_EXPANSION_CACHE_CX - 1)) < (INT) ppdev->cxScreen),
3746: "S3.DLL!bCpyColorExpandHorzCacheToScreen - Blit Operation over right edge (2)\n");
3747:
3748: FIFOWAIT(FIFO_5_EMPTY);
3749:
3750: OUTPW(CUR_X, MONO_HORZ_EXPANSION_CACHE_X);
3751: OUTPW(CUR_Y, MONO_HORZ_EXPANSION_CACHE_Y + yOffset);
3752: OUTPW(DEST_X, x);
3753: OUTPW(DEST_Y, pptDest->y);
3754:
3755: OUTPW(CMD, Cmd);
3756: }
3757:
3758: if (ixLast != 0)
3759: {
3760: x = pptDest->x + cxLeft + (ixBlits * MONO_HORZ_EXPANSION_CACHE_CX);
3761:
3762: ASSERTS3(((x + (ixLast - 1)) < (INT) ppdev->cxScreen),
3763: "S3.DLL!bCpyColorExpandHorzCacheToScreen - Blit Operation over right edge (3)\n");
3764:
3765: FIFOWAIT(FIFO_6_EMPTY);
3766:
3767: OUTPW(RECT_WIDTH, ixLast - 1);
3768:
3769: OUTPW(CUR_X, MONO_HORZ_EXPANSION_CACHE_X);
3770: OUTPW(CUR_Y, MONO_HORZ_EXPANSION_CACHE_Y + yOffset);
3771: OUTPW(DEST_X, x);
3772: OUTPW(DEST_Y, pptDest->y);
3773:
3774: OUTPW(CMD, Cmd);
3775: }
3776: }
3777:
3778: // If the cyDest is taller than 8 pels do a rolling blit to fill in
3779: // the bottom of the fill area.
3780:
3781: if (psizDest->cy > 8)
3782: {
3783: ASSERTS3(((pptDest->x + (psizDest->cx - 1)) < (INT) ppdev->cxScreen),
3784: "S3.DLL!bCpyColorExpandHorzCacheToScreen - Blit Operation over right edge (4)\n");
3785:
3786: FIFOWAIT(FIFO_2_EMPTY);
3787:
3788: TEST_AND_SET_RD_MASK(0xff);
3789: TEST_AND_SET_FRGD_MIX(SRC_DISPLAY_MEMORY | OVERPAINT);
3790:
3791: FIFOWAIT(FIFO_8_EMPTY);
3792:
3793: OUTPW(MULTIFUNC_CNTL, (DATA_EXTENSION | ALL_ONES));
3794:
3795: OUTPW(RECT_WIDTH, psizDest->cx - 1);
3796: OUTPW(MULTIFUNC_CNTL, (RECT_HEIGHT | psizDest->cy - (cy + 1)));
3797:
3798: OUTPW(CUR_X, pptDest->x);
3799: OUTPW(CUR_Y, pptDest->y);
3800: OUTPW(DEST_X, pptDest->x);
3801: OUTPW(DEST_Y, pptDest->y + 8);
3802:
3803: OUTPW(CMD, Cmd);
3804: }
3805:
3806: // Reset the Read Mask
3807:
3808: FIFOWAIT(FIFO_2_EMPTY);
3809:
3810: TEST_AND_SET_WRT_MASK(0xff);
3811: TEST_AND_SET_RD_MASK(0xff);
3812:
3813: return(TRUE);
3814: }
3815:
3816:
3817: /*****************************************************************************
3818: * S3 Solid Pattern
3819: *
3820: * Returns TRUE if the blit was handled.
3821: ****************************************************************************/
3822: BOOL bPatternSolid(
3823: SURFOBJ *psoTrg,
3824: SURFOBJ *psoSrc,
3825: SURFOBJ *psoMask,
3826: CLIPOBJ *pco,
3827: XLATEOBJ *pxlo,
3828: RECTL *prclTrg,
3829: POINTL *pptlSrc,
3830: POINTL *pptlMask,
3831: BRUSHOBJ *pbo,
3832: POINTL *pptlBrush,
3833: ROP4 s3Rop4)
3834: {
3835: INT width,height;
3836: WORD s3Mix;
3837: BOOL bMore;
3838: UINT i;
3839: ENUMRECTS8 EnumRects8;
3840:
3841: LONG rleft; // render coordinates
3842: LONG rtop;
3843: LONG rright;
3844: LONG rbottom;
3845: LONG cleft; // clip coorindates
3846: LONG ctop;
3847: LONG cright;
3848: LONG cbottom;
3849: LONG left;
3850: LONG top;
3851: RECTL rclBounds;
3852: BOOL bClipRequired, bDrawRequired;
3853: PPDEV ppdev;
3854:
3855: DISPDBG((3,"S3.DLL!bPatternSolid - Entry\n"));
3856:
3857: // Get the pdev.
3858:
3859: ppdev = (PPDEV) psoTrg->dhpdev;
3860:
3861: // Just use the for ground mix.
3862:
3863: s3Mix = (WORD) (s3Rop4 & 0xFF);
3864:
3865: // Dereference the target rectangle.
3866:
3867: rleft = prclTrg->left;
3868: rtop = prclTrg->top;
3869: rright = prclTrg->right;
3870: rbottom = prclTrg->bottom;
3871:
3872: // Use software clipping. It's faster than H/W clipping.
3873:
3874: if (pco->iDComplexity != DC_COMPLEX)
3875: {
3876: if (pco->iDComplexity == DC_TRIVIAL)
3877: {
3878: width = (rright - rleft) - 1;
3879: height = (rbottom - rtop) - 1;
3880:
3881: bDrawRequired = TRUE;
3882: }
3883: else
3884: {
3885: bDrawRequired = FALSE;
3886:
3887: rclBounds = pco->rclBounds;
3888:
3889: // First handle the trivial rejection.
3890:
3891: bClipRequired = bIntersectTest(prclTrg, &rclBounds);
3892:
3893: if (bClipRequired)
3894: {
3895: rleft = max (rleft, rclBounds.left);
3896: rtop = max (rtop, rclBounds.top);
3897: width = (min(rright, rclBounds.right) - rleft) - 1;
3898: height = (min(rbottom, rclBounds.bottom) - rtop) - 1;
3899:
3900: bDrawRequired = TRUE;
3901: }
3902: }
3903:
3904: if (bDrawRequired && width >= 0 && height >= 0)
3905: {
3906: vS3SolidPattern(ppdev,
3907: rleft, rtop, width, height,
3908: (pbo != NULL)? pbo->iSolidColor: 0, s3Mix);
3909: }
3910: }
3911: else
3912: {
3913: CLIPOBJ_cEnumStart(pco, FALSE, CT_RECTANGLES, CD_ANY, 0);
3914:
3915: do
3916: {
3917: bMore = CLIPOBJ_bEnum(pco, sizeof (ENUMRECTS8),
3918: (PULONG) &EnumRects8);
3919: for (i = 0; i < EnumRects8.c; i++)
3920: {
3921: // Do a trivial reject on Y.
3922:
3923: if (rtop > (cbottom = EnumRects8.arcl[i].bottom))
3924: continue;
3925: if (rbottom < (ctop = EnumRects8.arcl[i].top))
3926: continue;
3927:
3928: // Do a trivial reject on X.
3929:
3930: if (rleft > (cright = EnumRects8.arcl[i].right))
3931: continue;
3932: if (rright < (cleft = EnumRects8.arcl[i].left))
3933: continue;
3934:
3935: // It's not a trivial reject, so calculate the
3936: // minimal clip area.
3937:
3938: left = max (rleft, cleft);
3939: top = max (rtop, ctop);
3940: width = (min(rright, cright) - left) - 1;
3941: height = (min(rbottom, cbottom) - top) - 1;
3942:
3943: if (width < 0 || height < 0)
3944: continue;
3945:
3946: vS3SolidPattern(ppdev,
3947: left, top,
3948: width, height,
3949: (pbo != NULL)? pbo->iSolidColor: 0, s3Mix);
3950: }
3951: } while (bMore);
3952: }
3953:
3954: return (TRUE);
3955: }
3956:
3957: /*****************************************************************************
3958: * vS3SolidPattern
3959: ****************************************************************************/
3960: VOID vS3SolidPattern(
3961: PPDEV ppdev,
3962: INT left,
3963: INT top,
3964: INT width,
3965: INT height,
3966: INT color,
3967: WORD s3Mix)
3968: {
3969: FIFOWAIT(FIFO_8_EMPTY);
3970:
3971: ASSERTS3 (((left + width) < (INT) ppdev->cxScreen),
3972: "S3.DLL!vS3SolidPattern - (left + width) > (ppdev->cxScreen - 1)\n");
3973:
3974: TEST_AND_SET_FRGD_MIX(FOREGROUND_COLOR | s3Mix);
3975: TEST_AND_SET_FRGD_COLOR(color);
3976:
3977: OUTPW (MULTIFUNC_CNTL, (DATA_EXTENSION | ALL_ONES));
3978:
3979: OUTPW (CUR_X, left);
3980: OUTPW (CUR_Y, top);
3981: OUTPW (RECT_WIDTH, width);
3982: OUTPW (MULTIFUNC_CNTL, (RECT_HEIGHT | height));
3983:
3984: OUTPW (CMD, RECTANGLE_FILL | DRAWING_DIR_TBLRXM |
3985: DRAW | DIR_TYPE_XY |
3986: LAST_PIXEL_ON | MULTIPLE_PIXELS |
3987: WRITE);
3988: }
3989:
3990: /*****************************************************************************
3991: * S3 8bpp Cached Managed Host to Screen Copy
3992: *
3993: * Returns TRUE if the blit was handled.
3994: ****************************************************************************/
3995: BOOL b8BppHostToScrnCachedWithRop(
3996: SURFOBJ *psoTrg,
3997: SURFOBJ *psoSrc,
3998: CLIPOBJ *pco,
3999: XLATEOBJ *pxlo,
4000: RECTL *prclTrg,
4001: POINTL *pptlSrc,
4002: WORD s3Rop)
4003: {
4004: BOOL bRet;
4005: HSURF hsurf;
4006: PPDEV ppdev;
4007: POINTL ptlSrc;
4008: RECTL rclTrg;
4009: SIZEL sizlBitmap;
4010:
4011: PSAVEDSCRNBITSHDR pssbhInPdev;
4012: PSAVEDSCRNBITS pssbNewNode, pssbTemp;
4013:
4014: DISPDBG((3, "S3.DLL!b8BppHostToScrnCachedWithRop - entry\n"));
4015:
4016: n8BppBitmaps++;
4017:
4018: ppdev = (PPDEV) psoTrg->dhpdev;
4019: hsurf = psoSrc->hsurf;
4020:
4021: #if 0
4022: DISPDBG((2, "\thsurf : %x\n", hsurf));
4023: DISPDBG((2, "\tpsoSrc->iUniq : %x\n", psoSrc->iUniq));
4024: DISPDBG((2, "\tpsoSrc->sizlBitmap.cx: %d\n", psoSrc->sizlBitmap.cx));
4025: DISPDBG((2, "\tpsoSrc->sizlBitmap.cy: %d\n", psoSrc->sizlBitmap.cy));
4026: #endif
4027:
4028: #if SRCBM_CACHE
4029:
4030: // Is this bitmap in the cache?
4031:
4032: if ((hsurf == ppdev->hsurfCachedBitmap) &&
4033: (psoSrc->iUniq == ppdev->iUniqCachedBitmap))
4034: {
4035: if ((((pxlo == NULL) ||
4036: (pxlo->flXlate & XO_TRIVIAL)) && (ppdev->iUniqXlate == 1)) ||
4037: (pxlo->iUniq == ppdev->iUniqXlate))
4038: {
4039: // The bitmap is in the cache
4040: // Keep a cache hit count.
4041:
4042: n8BppBmCacheHits++;
4043:
4044: // Blt from the cache.
4045:
4046: ptlSrc.x = pptlSrc->x + OFF_SCREEN_BITMAP_X;
4047: ptlSrc.y = pptlSrc->y + OFF_SCREEN_BITMAP_Y;
4048:
4049: return(bScrnToScrnWithRop(psoTrg, psoTrg, pco, prclTrg,
4050: &ptlSrc, s3Rop));
4051: }
4052: }
4053:
4054: // The bitmap is not in the cache.
4055: // Is it small enough to fit into the cache?
4056:
4057: sizlBitmap = psoSrc->sizlBitmap;
4058:
4059: if ((sizlBitmap.cx <= OFF_SCREEN_BITMAP_CX) &&
4060: (sizlBitmap.cy <= OFF_SCREEN_BITMAP_CY))
4061: {
4062: // It will fit in the cache.
4063: // If the cache is being used for some saved screen bits
4064: // move them to host memory.
4065:
4066: if (ppdev->SavedScreenBitsHeader.iUniq != -1)
4067: {
4068: nSsbMovedToHostFromSrcBmCache++;
4069:
4070: DISPDBG((1, "S3.DLL - Saved Screen Bits Moved to Host Memory from Source Bitmap Cache Manager \n"));
4071:
4072: // Move the actual bits to host memory.
4073:
4074: bRet = bMoveSaveScreenBitsToHost(ppdev, &pssbNewNode);
4075:
4076: if (bRet == FALSE)
4077: return(FALSE);
4078:
4079: // Connect this newNode to the beginning of the list of
4080: // save screen bits nodes.
4081:
4082: pssbhInPdev = &(ppdev->SavedScreenBitsHeader);
4083:
4084: pssbTemp = pssbhInPdev->pssbLink;
4085: pssbhInPdev->pssbLink = pssbNewNode;
4086: pssbNewNode->ssbh.pssbLink = pssbTemp;
4087:
4088: // Invalidate the Save Screen bits in off screen memory
4089:
4090: ppdev->SavedScreenBitsHeader.iUniq = (ULONG) -1;
4091: }
4092:
4093:
4094: // Set the cache tags.
4095:
4096: ppdev->hsurfCachedBitmap = hsurf;
4097: ppdev->iUniqCachedBitmap = psoSrc->iUniq;
4098:
4099: if ((pxlo == NULL) || (pxlo->flXlate & XO_TRIVIAL))
4100: {
4101: ppdev->iUniqXlate = 1;
4102: }
4103: else
4104: {
4105: ppdev->iUniqXlate = pxlo->iUniq;
4106: }
4107:
4108: // Put the entire bitmap into the cache.
4109:
4110: rclTrg.left = OFF_SCREEN_BITMAP_X;
4111: rclTrg.top = OFF_SCREEN_BITMAP_Y;
4112: rclTrg.right = OFF_SCREEN_BITMAP_X + sizlBitmap.cx;
4113: rclTrg.bottom = OFF_SCREEN_BITMAP_Y + sizlBitmap.cy;
4114:
4115: ptlSrc.x = 0;
4116: ptlSrc.y = 0;
4117:
4118: bRet = b8BppHostToScrnWithRop(psoTrg, psoSrc, ppdev->pcoFullRam,
4119: pxlo, &rclTrg, &ptlSrc, OVERPAINT);
4120:
4121: if (bRet == TRUE)
4122: {
4123: // Blt from the cache.
4124:
4125: ptlSrc.x = pptlSrc->x + OFF_SCREEN_BITMAP_X;
4126: ptlSrc.y = pptlSrc->y + OFF_SCREEN_BITMAP_Y;
4127:
4128: bRet = bScrnToScrnWithRop(psoTrg, psoTrg, pco, prclTrg,
4129: &ptlSrc, s3Rop);
4130:
4131: }
4132: }
4133: else
4134: {
4135: // The bitmap was too large to cache.
4136: // So, just blt it directly to the screen.
4137:
4138: bRet = b8BppHostToScrnWithRop(psoTrg, psoSrc, pco, pxlo,
4139: prclTrg, pptlSrc, s3Rop);
4140: }
4141: #else
4142:
4143: bRet = b8BppHostToScrnWithRop(psoTrg, psoSrc, pco, pxlo,
4144: prclTrg, pptlSrc, s3Rop);
4145:
4146: #endif
4147:
4148: return (bRet);
4149: }
4150:
4151: /*****************************************************************************
4152: * S3 8bpp Host to Screen Copy
4153: *
4154: * Returns TRUE if the blit was handled.
4155: ****************************************************************************/
4156: BOOL b8BppHostToScrnWithRop(
4157: SURFOBJ *psoTrg,
4158: SURFOBJ *psoSrc,
4159: CLIPOBJ *pco,
4160: XLATEOBJ *pxlo,
4161: RECTL *prclTrg,
4162: POINTL *pptlSrc,
4163: WORD s3Rop)
4164: {
4165: LONG lSrcDelta;
4166: PWORD pwFirstWord;
4167: BOOL bMore;
4168: PPDEV ppdev;
4169: BYTE iDComplexity;
4170: RECTL rclTrg, rclBounds;
4171: POINT ptSrc;
4172: INT i;
4173: SIZE sizBlt;
4174:
4175: ENUMRECTS8 EnumRects8;
4176:
4177: DISPDBG((3, "S3.DLL!b8BppHostToScrnWithRop - entry\n"));
4178:
4179: ppdev = (PPDEV) psoTrg->dhpdev;
4180:
4181: // Pickup some convienent locals.
4182:
4183: lSrcDelta = psoSrc->lDelta;
4184:
4185: if ((iDComplexity = pco->iDComplexity) != DC_COMPLEX)
4186: {
4187: // Make a copy of the target, since we will have to change
4188: // it for clipping.
4189:
4190: rclTrg = *prclTrg;
4191:
4192: if (iDComplexity == DC_RECT)
4193: {
4194: rclBounds = pco->rclBounds;
4195:
4196: // Handle the trivial rejection and
4197: // define the clipped target rectangle.
4198:
4199: if (bIntersectTest(&rclTrg, &rclBounds))
4200: {
4201: rclTrg.left = max (rclTrg.left, rclBounds.left);
4202: rclTrg.top = max (rclTrg.top, rclBounds.top);
4203: rclTrg.right = min (rclTrg.right, rclBounds.right);
4204: rclTrg.bottom = min (rclTrg.bottom, rclBounds.bottom);
4205: }
4206: else
4207: {
4208: // The destination rectangle is completely clipped out,
4209: // so just return.
4210:
4211: return (TRUE);
4212: }
4213: }
4214:
4215: // define the cx & cy for the blit.
4216:
4217: sizBlt.cx = rclTrg.right - rclTrg.left;
4218: sizBlt.cy = rclTrg.bottom - rclTrg.top;
4219:
4220: // calculate the cx & cy shift (due to clipping) for the source.
4221: // and define the upper left corner of the source.
4222:
4223: ptSrc.x = pptlSrc->x + (rclTrg.left - prclTrg->left);
4224: ptSrc.y = pptlSrc->y + (rclTrg.top - prclTrg->top);
4225:
4226: // Calculate the first word to blit
4227:
4228: pwFirstWord = (PWORD) (((PBYTE) psoSrc->pvScan0)
4229: + (ptSrc.y * lSrcDelta) + ptSrc.x);
4230:
4231: vLowLevel8BppHostToScrnWithRop(ppdev, (PPOINT) &rclTrg, &sizBlt,
4232: pwFirstWord, lSrcDelta, pxlo, s3Rop);
4233:
4234: }
4235: else
4236: {
4237: CLIPOBJ_cEnumStart(pco, FALSE, CT_RECTANGLES, CD_ANY, 0);
4238:
4239: do
4240: {
4241: bMore = CLIPOBJ_bEnum(pco, sizeof (ENUMRECTS8), (PULONG) &EnumRects8);
4242:
4243: for (i = 0; i < (INT) EnumRects8.c; i++)
4244: {
4245: rclTrg = *prclTrg;
4246: rclBounds = EnumRects8.arcl[i];
4247:
4248: // Handle the trivial rejection and
4249: // define the clipped target rectangle.
4250:
4251: if (bIntersectTest(&rclTrg, &rclBounds))
4252: {
4253: rclTrg.left = max (rclTrg.left, rclBounds.left);
4254: rclTrg.top = max (rclTrg.top, rclBounds.top);
4255: rclTrg.right = min (rclTrg.right, rclBounds.right);
4256: rclTrg.bottom = min (rclTrg.bottom, rclBounds.bottom);
4257:
4258: // define the cx & cy for the blit.
4259:
4260: sizBlt.cx = rclTrg.right - rclTrg.left;
4261: sizBlt.cy = rclTrg.bottom - rclTrg.top;
4262:
4263: // calculate the cx & cy shift (due to clipping) for the source.
4264: // and define the upper left corner of the source.
4265:
4266: ptSrc.x = pptlSrc->x + (rclTrg.left - prclTrg->left);
4267: ptSrc.y = pptlSrc->y + (rclTrg.top - prclTrg->top);
4268:
4269: // Calculate the first word to blit
4270:
4271: pwFirstWord = (PWORD) (((PBYTE) psoSrc->pvScan0)
4272: + (ptSrc.y * lSrcDelta) + ptSrc.x);
4273:
4274: vLowLevel8BppHostToScrnWithRop(ppdev,
4275: (PPOINT) &rclTrg,
4276: &sizBlt,
4277: pwFirstWord,
4278: lSrcDelta,
4279: pxlo,
4280: s3Rop);
4281: }
4282: }
4283: } while (bMore);
4284: }
4285:
4286: return (TRUE);
4287: }
4288:
4289:
4290:
4291: /*****************************************************************************
4292: * Low Level 8bpp host to screen copy.
4293: ****************************************************************************/
4294: VOID vLowLevel8BppHostToScrnWithRop(
4295: PPDEV ppdev,
4296: PPOINT pptTrg,
4297: PSIZE psizBlt,
4298: PWORD pwFirstWord,
4299: INT lSrcDelta,
4300: XLATEOBJ *pxlo,
4301: WORD s3Rop)
4302: {
4303: PWORD pw;
4304: INT i, j;
4305: WORD Cmd;
4306: PBYTE pbSrc;
4307: INT nSrc;
4308: PULONG pulXlate;
4309: INT cy, wpl;
4310: BYTE LineBuff[DRIVERS_MAX_CX];
4311:
4312: // Setup the S3 chip.
4313:
4314: cy = psizBlt->cy;
4315:
4316: Cmd = RECTANGLE_FILL | BYTE_SWAP | BUS_SIZE_16 | WAIT |
4317: DRAW | DRAWING_DIR_TBLRXM | DIR_TYPE_XY |
4318: LAST_PIXEL_ON | SINGLE_PIXEL | WRITE;
4319:
4320: FIFOWAIT(FIFO_7_EMPTY);
4321:
4322: TEST_AND_SET_FRGD_MIX(SRC_CPU_DATA | s3Rop);
4323: OUTPW(MULTIFUNC_CNTL, (DATA_EXTENSION | ALL_ONES));
4324:
4325: OUTPW(CUR_X, pptTrg->x);
4326: OUTPW(CUR_Y, pptTrg->y);
4327: OUTPW(RECT_WIDTH, psizBlt->cx - 1);
4328: OUTPW(MULTIFUNC_CNTL, (RECT_HEIGHT | cy - 1));
4329:
4330: GPWAIT();
4331:
4332: OUTPW(CMD, Cmd);
4333:
4334: CHECK_DATA_READY;
4335:
4336: wpl = (psizBlt->cx + 1) >> 1;
4337:
4338: // We may have to do some color translation.
4339:
4340: if ((pxlo == NULL) || (pxlo->flXlate & XO_TRIVIAL))
4341: {
4342: // Now transfer the data.
4343:
4344: // Note: It would nice to do the entire bitmap in one
4345: // fell swoop, but there is no gaurantee source will
4346: // wrap on a bitmap boundary.
4347:
4348: pw = pwFirstWord;
4349: for (i = 0; i < cy; i++)
4350: {
4351: vDataPortOut(ppdev, (PWORD) pw, wpl);
4352: ((PBYTE) pw) += lSrcDelta;
4353: }
4354: }
4355: else
4356: {
4357: if (pxlo->flXlate & XO_TABLE)
4358: {
4359: pulXlate = pxlo->pulXlate;
4360: }
4361: else
4362: {
4363: pulXlate = XLATEOBJ_piVector(pxlo);
4364: }
4365:
4366: pbSrc = (PBYTE) pwFirstWord;
4367: nSrc = wpl * 2;
4368:
4369: for (i = 0; i < cy; i++)
4370: {
4371: for (j = 0; j < nSrc; j++)
4372: {
4373: LineBuff[j] = LOBYTE(pulXlate[pbSrc[j]]);
4374: }
4375:
4376: vDataPortOut(ppdev, (PWORD) LineBuff, wpl);
4377: pbSrc += lSrcDelta;
4378: }
4379: }
4380:
4381: CHECK_DATA_COMPLETE;
4382:
4383: return;
4384:
4385: }
4386:
4387:
4388: /*****************************************************************************
4389: * S3 1bpp Cached Managed Host to Screen With Rop
4390: *
4391: * Returns TRUE if the blit was handled.
4392: ****************************************************************************/
4393: BOOL b1BppHostToScrnCachedWithRop(
4394: SURFOBJ *psoTrg,
4395: SURFOBJ *psoSrc,
4396: CLIPOBJ *pco,
4397: XLATEOBJ *pxlo,
4398: RECTL *prclTrg,
4399: POINTL *pptlSrc,
4400: WORD s3Rop)
4401: {
4402: BOOL bRet;
4403: HSURF hsurf;
4404: PPDEV ppdev;
4405: POINTL ptlSrc;
4406: RECTL rclTrg;
4407: SIZEL sizlBitmap;
4408:
4409: PSAVEDSCRNBITSHDR pssbhInPdev;
4410: PSAVEDSCRNBITS pssbNewNode, pssbTemp;
4411:
4412: DISPDBG((3, "S3.DLL!b1BppHostToScrnCachedWithRop - entry\n"));
4413:
4414: n1BppBitmaps++;
4415:
4416: ppdev = (PPDEV) psoTrg->dhpdev;
4417: hsurf = psoSrc->hsurf;
4418:
4419: #if 1
4420: DISPDBG((2, "\thsurf : %x\n", hsurf));
4421: DISPDBG((2, "\tpsoSrc->iUniq : %x\n", psoSrc->iUniq));
4422: DISPDBG((2, "\tpsoSrc->sizlBitmap.cx: %d\n", psoSrc->sizlBitmap.cx));
4423: DISPDBG((2, "\tpsoSrc->sizlBitmap.cy: %d\n", psoSrc->sizlBitmap.cy));
4424: #endif
4425:
4426: #if SRCBM_CACHE
4427:
4428: // Is this bitmap in the cache?
4429:
4430: if ((hsurf == ppdev->hsurfCachedBitmap) &&
4431: (psoSrc->iUniq == ppdev->iUniqCachedBitmap))
4432: {
4433: if ((((pxlo == NULL) ||
4434: (pxlo->flXlate & XO_TRIVIAL)) && (ppdev->iUniqXlate == 1)) ||
4435: (pxlo->iUniq == ppdev->iUniqXlate))
4436: {
4437: // The bitmap is in the cache
4438: // Keep a cache hit count.
4439:
4440: n1BppBmCacheHits++;
4441:
4442: // Blt from the cache.
4443:
4444: ptlSrc.x = pptlSrc->x + OFF_SCREEN_BITMAP_X;
4445: ptlSrc.y = pptlSrc->y + OFF_SCREEN_BITMAP_Y;
4446:
4447: return(bScrnToScrnWithRop(psoTrg, psoTrg, pco, prclTrg,
4448: &ptlSrc, s3Rop));
4449: }
4450: }
4451:
4452: // The bitmap is not in the cache.
4453: // Is it small enough to fit into the cache?
4454:
4455: sizlBitmap = psoSrc->sizlBitmap;
4456:
4457: if ((sizlBitmap.cx <= OFF_SCREEN_BITMAP_CX) &&
4458: (sizlBitmap.cy <= OFF_SCREEN_BITMAP_CY))
4459: {
4460: // It will fit in the cache.
4461: // If the cache is being used for some saved screen bits
4462: // move them to host memory.
4463:
4464: if (ppdev->SavedScreenBitsHeader.iUniq != -1)
4465: {
4466: nSsbMovedToHostFromSrcBmCache++;
4467:
4468: DISPDBG((1, "S3.DLL - Saved Screen Bits Moved to Host Memory from Source Bitmap Cache Manager \n"));
4469:
4470: // Move the actual bits to host memory.
4471:
4472: bRet = bMoveSaveScreenBitsToHost(ppdev, &pssbNewNode);
4473:
4474: if (bRet == FALSE)
4475: return(FALSE);
4476:
4477: // Connect this newNode to the beginning of the list of
4478: // save screen bits nodes.
4479:
4480: pssbhInPdev = &(ppdev->SavedScreenBitsHeader);
4481:
4482: pssbTemp = pssbhInPdev->pssbLink;
4483: pssbhInPdev->pssbLink = pssbNewNode;
4484: pssbNewNode->ssbh.pssbLink = pssbTemp;
4485:
4486: // Invalidate the Save Screen bits in off screen memory
4487:
4488: ppdev->SavedScreenBitsHeader.iUniq = (ULONG) -1;
4489: }
4490:
4491:
4492: // Set the cache tags.
4493:
4494: ppdev->hsurfCachedBitmap = hsurf;
4495: ppdev->iUniqCachedBitmap = psoSrc->iUniq;
4496:
4497: if ((pxlo == NULL) || (pxlo->flXlate & XO_TRIVIAL))
4498: {
4499: ppdev->iUniqXlate = 1;
4500: }
4501: else
4502: {
4503: ppdev->iUniqXlate = pxlo->iUniq;
4504: }
4505:
4506: // Put the entire bitmap into the cache.
4507:
4508: rclTrg.left = OFF_SCREEN_BITMAP_X;
4509: rclTrg.top = OFF_SCREEN_BITMAP_Y;
4510: rclTrg.right = OFF_SCREEN_BITMAP_X + sizlBitmap.cx;
4511: rclTrg.bottom = OFF_SCREEN_BITMAP_Y + sizlBitmap.cy;
4512:
4513: ptlSrc.x = 0;
4514: ptlSrc.y = 0;
4515:
4516: bRet = b1BppHostToScrnWithRop(psoTrg, psoSrc, ppdev->pcoFullRam,
4517: pxlo, &rclTrg, &ptlSrc, OVERPAINT);
4518:
4519: if (bRet == TRUE)
4520: {
4521: // Blt from the cache.
4522:
4523: ptlSrc.x = pptlSrc->x + OFF_SCREEN_BITMAP_X;
4524: ptlSrc.y = pptlSrc->y + OFF_SCREEN_BITMAP_Y;
4525:
4526: bRet = bScrnToScrnWithRop(psoTrg, psoTrg, pco, prclTrg,
4527: &ptlSrc, s3Rop);
4528:
4529: }
4530: }
4531: else
4532: {
4533: // The bitmap was too large to cache.
4534: // So, just blt it directly to the screen.
4535:
4536: bRet = b1BppHostToScrnWithRop(psoTrg, psoSrc, pco, pxlo,
4537: prclTrg, pptlSrc, s3Rop);
4538: }
4539: #else
4540:
4541: bRet = b1BppHostToScrnWithRop(psoTrg, psoSrc, pco, pxlo,
4542: prclTrg, pptlSrc, s3Rop);
4543:
4544: #endif
4545:
4546: return (bRet);
4547: }
4548:
4549:
4550:
4551:
4552:
4553: /*****************************************************************************
4554: * S3 1bpp Host to Screen With ROP
4555: *
4556: * Returns TRUE if the blit was handled.
4557: ****************************************************************************/
4558: BOOL b1BppHostToScrnWithRop(
4559: SURFOBJ *psoTrg,
4560: SURFOBJ *psoSrc,
4561: CLIPOBJ *pco,
4562: XLATEOBJ *pxlo,
4563: RECTL *prclTrg,
4564: POINTL *pptlSrc,
4565: WORD s3Rop)
4566: {
4567: LONG lSrcDelta;
4568: PWORD pwFirstWord;
4569: BOOL bMore;
4570: PPDEV ppdev;
4571: BYTE iDComplexity;
4572: RECTL rclTrg, rclBounds;
4573: POINT ptSrc;
4574: INT i;
4575: SIZE sizBlt;
4576:
4577: ENUMRECTS8 EnumRects8;
4578:
4579: DISPDBG((3, "S3.DLL!b1BppHostToScrnWithRop - entry\n"));
4580:
4581: ppdev = (PPDEV) psoTrg->dhpdev;
4582:
4583: // Pickup some convienent locals.
4584:
4585: lSrcDelta = psoSrc->lDelta;
4586:
4587: if ((iDComplexity = pco->iDComplexity) != DC_COMPLEX)
4588: {
4589: // Make a copy of the target, since we will have to change
4590: // it for clipping.
4591:
4592: rclTrg = *prclTrg;
4593:
4594: if (iDComplexity == DC_RECT)
4595: {
4596: rclBounds = pco->rclBounds;
4597:
4598: // Handle the trivial rejection and
4599: // define the clipped target rectangle.
4600:
4601: if (bIntersectTest(&rclTrg, &rclBounds))
4602: {
4603: rclTrg.left = max (rclTrg.left, rclBounds.left);
4604: rclTrg.top = max (rclTrg.top, rclBounds.top);
4605: rclTrg.right = min (rclTrg.right, rclBounds.right);
4606: rclTrg.bottom = min (rclTrg.bottom, rclBounds.bottom);
4607: }
4608: else
4609: {
4610: // The destination rectangle is completely clipped out,
4611: // so just return.
4612:
4613: return (TRUE);
4614: }
4615: }
4616:
4617: // define the cx & cy for the blit.
4618:
4619: sizBlt.cx = rclTrg.right - rclTrg.left;
4620: sizBlt.cy = rclTrg.bottom - rclTrg.top;
4621:
4622: // calculate the cx & cy shift (due to clipping) for the source.
4623: // and define the upper left corner of the source.
4624:
4625: ptSrc.x = pptlSrc->x + (rclTrg.left - prclTrg->left);
4626: ptSrc.y = pptlSrc->y + (rclTrg.top - prclTrg->top);
4627:
4628: // Calculate the first word to blit
4629:
4630: pwFirstWord = (PWORD) (((PBYTE) psoSrc->pvScan0)
4631: + (ptSrc.y * lSrcDelta) + (ptSrc.x / 8));
4632:
4633: vSetS3ClipRect(ppdev, &rclTrg);
4634: vLowLevel1BppHostToScrnWithRop(ppdev,
4635: (PPOINT) &rclTrg,
4636: &sizBlt,
4637: ptSrc.x,
4638: pwFirstWord,
4639: lSrcDelta,
4640: pxlo,
4641: s3Rop);
4642:
4643: }
4644: else
4645: {
4646: CLIPOBJ_cEnumStart(pco, FALSE, CT_RECTANGLES, CD_ANY, 0);
4647:
4648: do
4649: {
4650: bMore = CLIPOBJ_bEnum(pco, sizeof (ENUMRECTS8), (PULONG) &EnumRects8);
4651:
4652: for (i = 0; i < (INT) EnumRects8.c; i++)
4653: {
4654: rclTrg = *prclTrg;
4655: rclBounds = EnumRects8.arcl[i];
4656:
4657: // Handle the trivial rejection and
4658: // define the clipped target rectangle.
4659:
4660: if (bIntersectTest(&rclTrg, &rclBounds))
4661: {
4662: rclTrg.left = max (rclTrg.left, rclBounds.left);
4663: rclTrg.top = max (rclTrg.top, rclBounds.top);
4664: rclTrg.right = min (rclTrg.right, rclBounds.right);
4665: rclTrg.bottom = min (rclTrg.bottom, rclBounds.bottom);
4666:
4667: // define the cx & cy for the blit.
4668:
4669: sizBlt.cx = rclTrg.right - rclTrg.left;
4670: sizBlt.cy = rclTrg.bottom - rclTrg.top;
4671:
4672: // calculate the cx & cy shift (due to clipping) for the source.
4673: // and define the upper left corner of the source.
4674:
4675: ptSrc.x = pptlSrc->x + (rclTrg.left - prclTrg->left);
4676: ptSrc.y = pptlSrc->y + (rclTrg.top - prclTrg->top);
4677:
4678: // Calculate the first word to blit
4679:
4680: pwFirstWord = (PWORD) (((PBYTE) psoSrc->pvScan0)
4681: + (ptSrc.y * lSrcDelta) + (ptSrc.x / 8));
4682:
4683: vSetS3ClipRect(ppdev, &rclTrg);
4684: vLowLevel1BppHostToScrnWithRop(ppdev,
4685: (PPOINT) &rclTrg,
4686: &sizBlt,
4687: ptSrc.x,
4688: pwFirstWord,
4689: lSrcDelta,
4690: pxlo,
4691: s3Rop);
4692: }
4693: }
4694: } while (bMore);
4695: }
4696:
4697: vResetS3Clipping(ppdev);
4698:
4699: return (TRUE);
4700: }
4701:
4702:
4703: /*****************************************************************************
4704: * Low Level 1bpp host to screen copy.
4705: *
4706: * Note: This routine should be modified to handle separate foreground
4707: * and background mix modes.
4708: ****************************************************************************/
4709: VOID vLowLevel1BppHostToScrnWithRop(
4710: PPDEV ppdev,
4711: PPOINT pptTrg,
4712: PSIZE psizBlt,
4713: INT xSrc,
4714: PWORD pwFirstWord,
4715: INT lSrcDelta,
4716: XLATEOBJ *pxlo,
4717: WORD s3Rop)
4718: {
4719: PBYTE pb1bpp;
4720: INT i, x, cx, cy, nSrcBytes, xClip;
4721: WORD Cmd;
4722: PULONG pulXlate;
4723:
4724: if (pxlo->flXlate & XO_TABLE)
4725: {
4726: pulXlate = pxlo->pulXlate;
4727: }
4728: else
4729: {
4730: pulXlate = XLATEOBJ_piVector(pxlo);
4731: }
4732:
4733:
4734: x = pptTrg->x;
4735: cx = psizBlt->cx;
4736:
4737: // Take care of the non-byte aligned source case.
4738:
4739: if (xSrc & 0x7)
4740: {
4741: xClip = x;
4742: x -= (xSrc & 0x7);
4743: cx += (xSrc & 0x7);
4744:
4745: FIFOWAIT(FIFO_1_EMPTY);
4746: outpw (MULTIFUNC_CNTL, (CLIP_LEFT | xClip));
4747: }
4748:
4749: Cmd = RECTANGLE_FILL | BUS_SIZE_8 | WAIT |
4750: DRAW | DRAWING_DIR_TBLRXM | DIR_TYPE_XY |
4751: LAST_PIXEL_ON | MULTIPLE_PIXELS | WRITE;
4752:
4753: // Setup the S3 chip.
4754:
4755: cy = psizBlt->cy;
4756:
4757: FIFOWAIT(FIFO_4_EMPTY);
4758:
4759: TEST_AND_SET_FRGD_MIX(FOREGROUND_COLOR | s3Rop);
4760: TEST_AND_SET_FRGD_COLOR(LOWORD(pulXlate[1]));
4761: TEST_AND_SET_BKGD_MIX(BACKGROUND_COLOR | s3Rop);
4762: SET_BKGD_COLOR(LOWORD(pulXlate[0]));
4763:
4764: FIFOWAIT(FIFO_5_EMPTY);
4765:
4766: OUTPW(MULTIFUNC_CNTL, (DATA_EXTENSION | CPU_DATA));
4767:
4768: OUTPW(CUR_X, x);
4769: OUTPW(CUR_Y, pptTrg->y);
4770: OUTPW(RECT_WIDTH, cx - 1);
4771: OUTPW(MULTIFUNC_CNTL, (RECT_HEIGHT | cy - 1));
4772:
4773: GPWAIT();
4774:
4775: OUTPW(CMD, Cmd);
4776:
4777: CHECK_DATA_READY;
4778:
4779: pb1bpp = (PBYTE) pwFirstWord;
4780: nSrcBytes = (cx + 7) / 8;
4781:
4782: for (i = 0; i < cy; i++)
4783: {
4784: vDataPortOutB(ppdev, pb1bpp, nSrcBytes);
4785: pb1bpp += lSrcDelta;
4786: }
4787:
4788: CHECK_DATA_COMPLETE;
4789:
4790: return;
4791:
4792: }
4793:
4794:
4795: /*****************************************************************************
4796: * S3 4bpp Host to Screen Copy
4797: *
4798: * Returns TRUE if the blit was handled.
4799: ****************************************************************************/
4800: BOOL b4BppHostToScrnWithRop(
4801: SURFOBJ *psoTrg,
4802: SURFOBJ *psoSrc,
4803: CLIPOBJ *pco,
4804: XLATEOBJ *pxlo,
4805: RECTL *prclTrg,
4806: POINTL *pptlSrc,
4807: WORD s3Rop)
4808: {
4809: LONG lSrcDelta;
4810: PWORD pwFirstWord;
4811: BOOL bMore;
4812: PPDEV ppdev;
4813: BYTE iDComplexity;
4814: RECTL rclTrg, rclBounds;
4815: POINT ptSrc;
4816: INT i;
4817: SIZE sizBlt;
4818:
4819: ENUMRECTS8 EnumRects8;
4820:
4821: DISPDBG((2, "S3.DLL!b4BppHostToScrnWithRop - entry\n"));
4822:
4823: ppdev = (PPDEV) psoTrg->dhpdev;
4824:
4825: // Pickup some convienent locals.
4826:
4827: lSrcDelta = psoSrc->lDelta;
4828:
4829: if ((iDComplexity = pco->iDComplexity) != DC_COMPLEX)
4830: {
4831: // Make a copy of the target, since we will have to change
4832: // it for clipping.
4833:
4834: rclTrg = *prclTrg;
4835:
4836: if (iDComplexity == DC_RECT)
4837: {
4838: rclBounds = pco->rclBounds;
4839:
4840: // Handle the trivial rejection and
4841: // define the clipped target rectangle.
4842:
4843: if (bIntersectTest(&rclTrg, &rclBounds))
4844: {
4845: rclTrg.left = max (rclTrg.left, rclBounds.left);
4846: rclTrg.top = max (rclTrg.top, rclBounds.top);
4847: rclTrg.right = min (rclTrg.right, rclBounds.right);
4848: rclTrg.bottom = min (rclTrg.bottom, rclBounds.bottom);
4849: }
4850: else
4851: {
4852: // The destination rectangle is completely clipped out,
4853: // so just return.
4854:
4855: return (TRUE);
4856: }
4857: }
4858:
4859: // define the cx & cy for the blit.
4860:
4861: sizBlt.cx = rclTrg.right - rclTrg.left;
4862: sizBlt.cy = rclTrg.bottom - rclTrg.top;
4863:
4864: // calculate the cx & cy shift (due to clipping) for the source.
4865: // and define the upper left corner of the source.
4866:
4867: ptSrc.x = pptlSrc->x + (rclTrg.left - prclTrg->left);
4868: ptSrc.y = pptlSrc->y + (rclTrg.top - prclTrg->top);
4869:
4870: // Calculate the first word to blit
4871:
4872: pwFirstWord = (PWORD) (((PBYTE) psoSrc->pvScan0)
4873: + (ptSrc.y * lSrcDelta) + (ptSrc.x / 2));
4874:
4875: vSetS3ClipRect(ppdev, &rclTrg);
4876: vLowLevel4BppHostToScrnWithRop(ppdev, (PPOINT) &rclTrg, &sizBlt,
4877: ptSrc.x,
4878: pwFirstWord, lSrcDelta, pxlo, s3Rop);
4879:
4880: }
4881: else
4882: {
4883: CLIPOBJ_cEnumStart(pco, FALSE, CT_RECTANGLES, CD_ANY, 0);
4884:
4885: do
4886: {
4887: bMore = CLIPOBJ_bEnum(pco, sizeof (ENUMRECTS8), (PULONG) &EnumRects8);
4888:
4889: for (i = 0; i < (INT) EnumRects8.c; i++)
4890: {
4891: rclTrg = *prclTrg;
4892: rclBounds = EnumRects8.arcl[i];
4893:
4894: // Handle the trivial rejection and
4895: // define the clipped target rectangle.
4896:
4897: if (bIntersectTest(&rclTrg, &rclBounds))
4898: {
4899: rclTrg.left = max (rclTrg.left, rclBounds.left);
4900: rclTrg.top = max (rclTrg.top, rclBounds.top);
4901: rclTrg.right = min (rclTrg.right, rclBounds.right);
4902: rclTrg.bottom = min (rclTrg.bottom, rclBounds.bottom);
4903:
4904: // define the cx & cy for the blit.
4905:
4906: sizBlt.cx = rclTrg.right - rclTrg.left;
4907: sizBlt.cy = rclTrg.bottom - rclTrg.top;
4908:
4909: // calculate the cx & cy shift (due to clipping) for the source.
4910: // and define the upper left corner of the source.
4911:
4912: ptSrc.x = pptlSrc->x + (rclTrg.left - prclTrg->left);
4913: ptSrc.y = pptlSrc->y + (rclTrg.top - prclTrg->top);
4914:
4915: // Calculate the first word to blit
4916:
4917: pwFirstWord = (PWORD) (((PBYTE) psoSrc->pvScan0)
4918: + (ptSrc.y * lSrcDelta) + (ptSrc.x / 2));
4919:
4920: vSetS3ClipRect(ppdev, &rclTrg);
4921: vLowLevel4BppHostToScrnWithRop(ppdev, (PPOINT) &rclTrg, &sizBlt,
4922: ptSrc.x,
4923: pwFirstWord, lSrcDelta, pxlo, s3Rop);
4924: }
4925: }
4926: } while (bMore);
4927: }
4928:
4929: vResetS3Clipping(ppdev);
4930:
4931: return (TRUE);
4932:
4933: }
4934:
4935:
4936:
4937:
4938: /*****************************************************************************
4939: * Low Level 4bpp host to screen copy.
4940: ****************************************************************************/
4941: VOID vLowLevel4BppHostToScrnWithRop(
4942: PPDEV ppdev,
4943: PPOINT pptTrg,
4944: PSIZE psizBlt,
4945: INT xSrc,
4946: PWORD pwFirstWord,
4947: INT lSrcDelta,
4948: XLATEOBJ *pxlo,
4949: WORD s3Rop)
4950: {
4951: PBYTE pb4Bpp;
4952: INT i, j, k, x, cx, cy, nSrcBytes, xClip;
4953: WORD Cmd;
4954: PULONG pulXlate;
4955:
4956: BYTE LineBuff8Bpp[DRIVERS_MAX_CX];
4957:
4958: if (pxlo->flXlate & XO_TABLE)
4959: {
4960: pulXlate = pxlo->pulXlate;
4961: }
4962: else
4963: {
4964: pulXlate = XLATEOBJ_piVector(pxlo);
4965: }
4966:
4967: pb4Bpp = (PBYTE) pwFirstWord;
4968:
4969: x = pptTrg->x;
4970: cx = psizBlt->cx;
4971: cy = psizBlt->cy;
4972:
4973: // Take care of the non-byte aligned source case.
4974:
4975: if (xSrc & 0x1)
4976: {
4977: xClip = x;
4978: x--;
4979: cx++;
4980:
4981: FIFOWAIT(FIFO_1_EMPTY);
4982: outpw (MULTIFUNC_CNTL, (CLIP_LEFT | xClip));
4983: }
4984:
4985: nSrcBytes = (cx + 1) / 2;
4986:
4987: // Setup the S3 chip.
4988:
4989: Cmd = RECTANGLE_FILL | BYTE_SWAP | BUS_SIZE_16 | WAIT |
4990: DRAW | DRAWING_DIR_TBLRXM | DIR_TYPE_XY |
4991: LAST_PIXEL_ON | SINGLE_PIXEL | WRITE;
4992:
4993: FIFOWAIT(FIFO_7_EMPTY);
4994:
4995: TEST_AND_SET_FRGD_MIX(SRC_CPU_DATA | s3Rop);
4996: outpw(MULTIFUNC_CNTL, (DATA_EXTENSION | ALL_ONES));
4997:
4998: outpw(CUR_X, x);
4999: outpw(CUR_Y, pptTrg->y);
5000: outpw(RECT_WIDTH, cx - 1);
5001: outpw(MULTIFUNC_CNTL, (RECT_HEIGHT | cy - 1));
5002:
5003: GPWAIT();
5004:
5005: outpw(CMD, Cmd);
5006:
5007: CHECK_DATA_READY;
5008:
5009: // Now transfer the data.
5010:
5011: for (i = 0; i < cy; i++)
5012: {
5013: for (k = 0, j = 0; j < nSrcBytes; j++)
5014: {
5015: LineBuff8Bpp[k++] = (BYTE) pulXlate[(pb4Bpp[j] & 0xF0) >> 4];
5016: LineBuff8Bpp[k++] = (BYTE) pulXlate[pb4Bpp[j] & 0x0F];
5017: }
5018:
5019: vDataPortOut(ppdev, (PWORD) LineBuff8Bpp, nSrcBytes);
5020: pb4Bpp += lSrcDelta;
5021: }
5022:
5023: CHECK_DATA_COMPLETE;
5024:
5025: return;
5026:
5027: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.