Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

270 lines
9.9 KiB

  1. /******************************Module*Header*******************************\
  2. * Module Name: bltmil24.c
  3. *
  4. * Contains the low-level blt functions for the Millenium at 24bpp.
  5. *
  6. * Hopefully, if you're basing your display driver on this code, to
  7. * support all of DrvBitBlt and DrvCopyBits, you'll only have to implement
  8. * the following routines. You shouldn't have to modify much in
  9. * 'bitblt.c'. I've tried to make these routines as few, modular, simple,
  10. * and efficient as I could, while still accelerating as many calls as
  11. * possible that would be cost-effective in terms of performance wins
  12. * versus size and effort.
  13. *
  14. * Note: In the following, 'relative' coordinates refers to coordinates
  15. * that haven't yet had the offscreen bitmap (DFB) offset applied.
  16. * 'Absolute' coordinates have had the offset applied. For example,
  17. * we may be told to blt to (1, 1) of the bitmap, but the bitmap may
  18. * be sitting in offscreen memory starting at coordinate (0, 768) --
  19. * (1, 1) would be the 'relative' start coordinate, and (1, 769)
  20. * would be the 'absolute' start coordinate'.
  21. *
  22. * Copyright (c) 1992-1996 Microsoft Corporation
  23. * Copyright (c) 1993-1996 Matrox Electronic Systems, Ltd.
  24. \**************************************************************************/
  25. #include "precomp.h"
  26. /******************************Public*Routine******************************\
  27. * VOID vMilPatRealize24bpp
  28. *
  29. * Download the Color Brush to the Color brush cache in the Storm offscreen
  30. * memory. We download a 16x8 brush. We'll use direct frame buffer access.
  31. *
  32. * There are some hardware restrictions concerning the way that a pattern
  33. * must be stored in memory:
  34. * - the first pixel of the pattern must be stored so that the first pixel
  35. * address mod 256 is 0 or 16;
  36. * - each line of 16 pixels is stored continuously, but there must be a
  37. * difference of 32 in the pixel addresses of successive pattern lines.
  38. * This means that we will store patterns in the following way:
  39. *
  40. * +----+---------------+---------------+---------------+---------------+
  41. * | | Pattern 0 | Pattern 1 |
  42. * |Line| | |1 1 1 1 1 1 1 1|1 1 1 1 1 1 1 1|
  43. * | |0 1 2 3 4 5 6 7|8 9 a b c d e f|0 1 2 3 4 5 6 7|8 9 a b c d e f|
  44. * +----+---------------+---------------+---------------+---------------+
  45. * | 0 |* * * * * * * * | o o o o|
  46. * | 1 | * * * * * * * *| o o o o |
  47. * | 2 |* * * * * * * * | o o o o |
  48. * | 3 | * * * * * * * *|o o o o |
  49. * | 4 |* * * * * * * * | o o o o|
  50. * | 5 | * * * * * * * *| o o o o |
  51. * | 6 |* * * * * * * * | o o o o |
  52. * | 7 | * * * * * * * *|o o o o |
  53. * +----+---------------+---------------+---------------+---------------+
  54. *
  55. * where a given pixel address is
  56. * FirstPixelAddress + Line*0x20 + Pattern*0x10 + xPat.
  57. *
  58. \**************************************************************************/
  59. VOID vMilPatRealize24bpp(
  60. PDEV* ppdev,
  61. RBRUSH* prb)
  62. {
  63. BYTE* pjBase;
  64. BRUSHENTRY* pbe;
  65. LONG iBrushCache;
  66. ULONG i;
  67. ULONG j;
  68. ULONG* pulBrush;
  69. ULONG* pulDst;
  70. ULONG lDeltaPat;
  71. pjBase = ppdev->pjBase;
  72. // Allocate a new off-screen cache brush entry for the brush.
  73. iBrushCache = ppdev->iBrushCache;
  74. pbe = &ppdev->pbe[iBrushCache];
  75. iBrushCache++;
  76. if (iBrushCache >= ppdev->cBrushCache)
  77. iBrushCache = 0;
  78. ppdev->iBrushCache = iBrushCache;
  79. // Update our links.
  80. pbe->prbVerify = prb;
  81. prb->apbe[IBOARD(ppdev)] = pbe;
  82. // Point to the pattern bits.
  83. pulBrush = prb->aulPattern;
  84. pulDst = (ULONG*) (pbe->pvScan0);
  85. pulDst = (ULONG*) (ppdev->pjScreen + (pbe->ulLinear * 3));
  86. DISPDBG((1,"pulBrush = %x", pulBrush));
  87. DISPDBG((1,"pulDst = %x", pulDst));
  88. {
  89. ULONG y;
  90. for (y = 0; y < 8; y++)
  91. {
  92. DISPDBG((2, "%02x%02x%02x %02x%02x%02x %02x%02x%02x %02x%02x%02x %02x%02x%02x %02x%02x%02x %02x%02x%02x %02x%02x%02x %02x%02x%02x %02x%02x%02x %02x%02x%02x %02x%02x%02x %02x%02x%02x %02x%02x%02x %02x%02x%02x %02x%02x%02x",
  93. ((BYTE*)pulBrush)[y*48 + 0],
  94. ((BYTE*)pulBrush)[y*48 + 1],
  95. ((BYTE*)pulBrush)[y*48 + 2],
  96. ((BYTE*)pulBrush)[y*48 + 3],
  97. ((BYTE*)pulBrush)[y*48 + 4],
  98. ((BYTE*)pulBrush)[y*48 + 5],
  99. ((BYTE*)pulBrush)[y*48 + 6],
  100. ((BYTE*)pulBrush)[y*48 + 7],
  101. ((BYTE*)pulBrush)[y*48 + 8],
  102. ((BYTE*)pulBrush)[y*48 + 9],
  103. ((BYTE*)pulBrush)[y*48 + 10],
  104. ((BYTE*)pulBrush)[y*48 + 11],
  105. ((BYTE*)pulBrush)[y*48 + 12],
  106. ((BYTE*)pulBrush)[y*48 + 13],
  107. ((BYTE*)pulBrush)[y*48 + 14],
  108. ((BYTE*)pulBrush)[y*48 + 15],
  109. ((BYTE*)pulBrush)[y*48 + 16],
  110. ((BYTE*)pulBrush)[y*48 + 17],
  111. ((BYTE*)pulBrush)[y*48 + 18],
  112. ((BYTE*)pulBrush)[y*48 + 19],
  113. ((BYTE*)pulBrush)[y*48 + 20],
  114. ((BYTE*)pulBrush)[y*48 + 21],
  115. ((BYTE*)pulBrush)[y*48 + 22],
  116. ((BYTE*)pulBrush)[y*48 + 23],
  117. ((BYTE*)pulBrush)[y*48 + 24],
  118. ((BYTE*)pulBrush)[y*48 + 25],
  119. ((BYTE*)pulBrush)[y*48 + 26],
  120. ((BYTE*)pulBrush)[y*48 + 27],
  121. ((BYTE*)pulBrush)[y*48 + 28],
  122. ((BYTE*)pulBrush)[y*48 + 29],
  123. ((BYTE*)pulBrush)[y*48 + 30],
  124. ((BYTE*)pulBrush)[y*48 + 31],
  125. ((BYTE*)pulBrush)[y*48 + 32],
  126. ((BYTE*)pulBrush)[y*48 + 33],
  127. ((BYTE*)pulBrush)[y*48 + 34],
  128. ((BYTE*)pulBrush)[y*48 + 35],
  129. ((BYTE*)pulBrush)[y*48 + 36],
  130. ((BYTE*)pulBrush)[y*48 + 37],
  131. ((BYTE*)pulBrush)[y*48 + 38],
  132. ((BYTE*)pulBrush)[y*48 + 39],
  133. ((BYTE*)pulBrush)[y*48 + 40],
  134. ((BYTE*)pulBrush)[y*48 + 41],
  135. ((BYTE*)pulBrush)[y*48 + 42],
  136. ((BYTE*)pulBrush)[y*48 + 43],
  137. ((BYTE*)pulBrush)[y*48 + 44],
  138. ((BYTE*)pulBrush)[y*48 + 45],
  139. ((BYTE*)pulBrush)[y*48 + 46],
  140. ((BYTE*)pulBrush)[y*48 + 47]
  141. ));
  142. }
  143. }
  144. START_DIRECT_ACCESS_STORM(ppdev, pjBase);
  145. for (i = 8; i != 0 ; i--)
  146. {
  147. for (j = 0; j < 12; j++)
  148. {
  149. pulDst[j] = *pulBrush++;
  150. }
  151. pulDst += (8 * 3); // dwords!
  152. }
  153. END_DIRECT_ACCESS_STORM(ppdev, pjBase);
  154. }
  155. /*****************************************************************************
  156. * VOID vMilFillPat24bpp
  157. *
  158. * 24bpp patterned color fills for Storm.
  159. ****************************************************************************/
  160. VOID vMilFillPat24bpp(
  161. PDEV* ppdev,
  162. LONG c, // Can't be zero
  163. RECTL* prcl, // List of rectangles to be filled, in relative
  164. // coordinates
  165. ULONG rop4, // Rop4
  166. RBRUSH_COLOR rbc, // rbc.prb points to brush realization structure
  167. POINTL* pptlBrush) // Pattern alignment
  168. {
  169. BRUSHENTRY* pbe;
  170. LONG xOffset;
  171. LONG yOffset;
  172. LONG xLeft;
  173. LONG yTop;
  174. LONG xBrush;
  175. LONG yBrush;
  176. LONG lSrcAdd;
  177. ULONG ulLinear;
  178. BYTE* pjBase;
  179. ULONG ulHwMix;
  180. ASSERTDD(!(rbc.prb->fl & RBRUSH_2COLOR), "Can't do 2 colour brushes here");
  181. // We have to ensure that no other brush took our spot in off-screen
  182. // memory, or we might have to realize the brush for the first time.
  183. pbe = rbc.prb->apbe[IBOARD(ppdev)];
  184. if (pbe->prbVerify != rbc.prb)
  185. {
  186. vMilPatRealize24bpp(ppdev, rbc.prb);
  187. pbe = rbc.prb->apbe[IBOARD(ppdev)];
  188. }
  189. pjBase = ppdev->pjBase;
  190. xOffset = ppdev->xOffset;
  191. yOffset = ppdev->yOffset;
  192. lSrcAdd = ppdev->lPatSrcAdd;
  193. CHECK_FIFO_SPACE(pjBase, 6);
  194. CP_WRITE(pjBase, DWG_AR5, 32); // Source (pattern) pitch.
  195. ppdev->HopeFlags = SIGN_CACHE;
  196. if ((rop4 & 0x000000FF) == 0x000000F0)
  197. {
  198. // The rop is PATCOPY.
  199. CP_WRITE(pjBase, DWG_DWGCTL, (opcode_BITBLT + atype_RPL + sgnzero_ZERO +
  200. shftzero_ZERO + bop_SRCCOPY +
  201. bltmod_BFCOL + pattern_ON +
  202. transc_BG_OPAQUE));
  203. }
  204. else
  205. {
  206. ulHwMix = (rop4 & 0x03) + ((rop4 & 0x30) >> 2);
  207. CP_WRITE(pjBase, DWG_DWGCTL, (opcode_BITBLT + atype_RSTR + sgnzero_ZERO +
  208. shftzero_ZERO + bltmod_BFCOL + pattern_ON +
  209. transc_BG_OPAQUE +
  210. (ulHwMix << 16)));
  211. }
  212. // The pattern setup is complete.
  213. while(TRUE)
  214. {
  215. // Take into account the brush origin. The upper left pel of the
  216. // brush should be aligned here in the destination surface.
  217. yTop = prcl->top;
  218. xLeft = prcl->left;
  219. xBrush = (xLeft - pptlBrush->x) & 7;
  220. yBrush = (yTop - pptlBrush->y) & 7;
  221. ulLinear = pbe->ulLinear + (yBrush << 5) + xBrush;
  222. CP_WRITE(pjBase, DWG_AR3, ulLinear);
  223. CP_WRITE(pjBase, DWG_AR0, (ulLinear +7));
  224. CP_WRITE(pjBase, DWG_FXBNDRY,
  225. (((prcl->right + xOffset - 1) << bfxright_SHIFT) |
  226. ((xLeft + xOffset) & bfxleft_MASK)));
  227. // ylength_MASK not is needed since coordinates are within range
  228. CP_START(pjBase, DWG_YDSTLEN,
  229. (((yTop + yOffset ) << yval_SHIFT) |
  230. ((prcl->bottom - yTop))));
  231. if (--c == 0)
  232. return;
  233. CHECK_FIFO_SPACE(pjBase, 4);
  234. prcl++;
  235. }
  236. }