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.

478 lines
15 KiB

  1. /******************************Module*Header*******************************\
  2. * Module Name: mcdutil.h
  3. *
  4. * Include file which indirects all of the hardware-dependent functionality
  5. * in the MCD driver code.
  6. *
  7. * Copyright (c) 1996 Microsoft Corporation
  8. \**************************************************************************/
  9. #ifndef _MCDUTIL_H
  10. #define _MCDUTIL_H
  11. // Function prorotypes:
  12. VOID PickRenderingFuncs(DEVRC *pRc);
  13. #if DBG
  14. UCHAR *MCDDbgAlloc(UINT);
  15. VOID MCDDbgFree(UCHAR *);
  16. #define MCDAlloc MCDDbgAlloc
  17. #define MCDFree MCDDbgFree
  18. VOID MCDrvDebugPrint(char *, ...);
  19. #define MCDBG_PRINT MCDrvDebugPrint
  20. #else
  21. UCHAR *MCDAlloc(UINT);
  22. VOID MCDFree(UCHAR *);
  23. #define MCDBG_PRINT
  24. #endif
  25. #define INTERSECTRECT(RectInter, pRect, Rect)\
  26. {\
  27. RectInter.left = max(pRect->left, Rect.left);\
  28. RectInter.right = min(pRect->right, Rect.right);\
  29. RectInter.top = max(pRect->top, Rect.top);\
  30. RectInter.bottom = min(pRect->bottom, Rect.bottom);\
  31. }
  32. #define MCD_CHECK_RC(pRc)\
  33. if (pRc == NULL) {\
  34. MCDBG_PRINT("NULL device RC");\
  35. return FALSE;\
  36. }
  37. #define MCD_CHECK_DEVWND(pMCDSurface, pDevWnd, resChangedRet)\
  38. {\
  39. if (!pDevWnd) {\
  40. MCDBG_PRINT("MCD_CHECK_DEVWND: NULL DEVWND");\
  41. return FALSE;\
  42. }\
  43. \
  44. if (pDevWnd->dispUnique != GetDisplayUniqueness((PDEV *)pMCDSurface->pso->dhpdev)) {\
  45. MCDBG_PRINT("MCD_CHECK_DEVWND: resolution changed but not updated");\
  46. return resChangedRet;\
  47. }\
  48. }
  49. #define MCD_CHECK_BUFFERS_VALID(pMCDSurface, pRc, resChangedRet)\
  50. {\
  51. DEVWND *pDevWnd = (DEVWND *)pMCDSurface->pWnd->pvUser;\
  52. \
  53. MCD_CHECK_DEVWND(pMCDSurface, pDevWnd, resChangedRet);\
  54. \
  55. if (((pRc)->backBufEnabled) &&\
  56. (!pDevWnd->bValidBackBuffer)) {\
  57. MCDBG_PRINT("HW_CHECK_BUFFERS_VALID: back buffer invalid");\
  58. return FALSE;\
  59. }\
  60. \
  61. if (((pRc)->zBufEnabled) &&\
  62. (!pDevWnd->bValidZBuffer)) {\
  63. MCDBG_PRINT("HW_CHECK_BUFFERS_VALID: z buffer invalid");\
  64. return FALSE;\
  65. }\
  66. \
  67. }
  68. #define MCD_INIT_BUFFER_PARAMS(pMCDSurface, pMCDWnd, pDevWnd, pRc)\
  69. {\
  70. pRc->hwYOrgBias = pMCDWnd->clipBoundsRect.top;\
  71. \
  72. if ((pRc)->MCDState.drawBuffer == GL_FRONT) {\
  73. (pRc)->hwBufferYBias = 0;\
  74. } else if ((pRc)->MCDState.drawBuffer == GL_BACK) {\
  75. if (ppdev->pohBackBuffer == pDevWnd->pohBackBuffer) {\
  76. pRc->hwBufferYBias = pDevWnd->backBufferY;\
  77. } else {\
  78. pRc->hwBufferYBias = pDevWnd->backBufferY - \
  79. pMCDWnd->clipBoundsRect.top;\
  80. }\
  81. }\
  82. }
  83. __inline ULONG HW_GET_VCOUNT(BYTE *pjBase)
  84. {
  85. CP_EIEIO();
  86. return(CP_READ_REGISTER((pjBase) + HST_VCOUNT));
  87. }
  88. __inline void HW_WAIT_DRAWING_DONE(DEVRC *pRc)
  89. {
  90. BYTE *pjBase = pRc->ppdev->pjBase;
  91. ULONG *pScreen;
  92. volatile ULONG read;
  93. while ((GET_FIFO_SPACE(pjBase) < FIFOSIZE) || IS_BUSY(pjBase))
  94. ;
  95. pScreen = (ULONG *)pRc->ppdev->pjScreen;
  96. read = *pScreen;
  97. read |= *(pScreen+32);
  98. }
  99. __inline void HW_INIT_DRAWING_STATE(MCDSURFACE *pMCDSurface, MCDWINDOW *pMCDWnd,
  100. DEVRC *pRc)
  101. {
  102. DEVWND *pDevWnd = (DEVWND *)pMCDWnd->pvUser;
  103. PDEV *ppdev = (PDEV *)pMCDSurface->pso->dhpdev;
  104. BYTE *pjBase = ppdev->pjBase;
  105. ULONG ulAccess;
  106. LONG yOrg;
  107. CHECK_FIFO_SPACE(pjBase, 4);
  108. ulAccess = ppdev->ulAccess;
  109. if (!(pRc->MCDState.enables & MCD_DITHER_ENABLE))
  110. ulAccess |= dither_DISABLE;
  111. pRc->ulAccess = ulAccess;
  112. CP_WRITE(pjBase, DWG_MACCESS, ulAccess);
  113. // Stash the upper-left y away in the context:
  114. pRc->hwYOrgBias = pMCDWnd->clipBoundsRect.top;
  115. // Note: zBufferOffset is maintained in MCDrvTrackWindow
  116. if (pRc->MCDState.drawBuffer == GL_FRONT) {
  117. if (pDevWnd->pohZBuffer) {
  118. LONG zDiff;
  119. if (ppdev->pohZBuffer == pDevWnd->pohZBuffer)
  120. zDiff = pDevWnd->zBufferOffset;
  121. else
  122. zDiff = pDevWnd->zBufferOffset -
  123. (pMCDWnd->clipBoundsRect.top * pDevWnd->zPitch);
  124. if (zDiff < 0)
  125. zDiff = 0x800000 + zDiff;
  126. ASSERTDD((zDiff & 0x1ff) == 0,
  127. "Front and Z buffers are not a multiple of 512 apart.");
  128. CP_WRITE(pjBase, DWG_ZORG, zDiff);
  129. }
  130. pRc->hwBufferYBias = 0;
  131. yOrg = pMCDWnd->clipBoundsRect.top;
  132. } else if (pRc->MCDState.drawBuffer == GL_BACK) {
  133. if (pDevWnd->pohZBuffer) {
  134. LONG zDiff;
  135. zDiff = pDevWnd->zBufferOffset -
  136. (pDevWnd->backBufferY * pDevWnd->zPitch);
  137. ASSERTDD((zDiff & 0x1ff) == 0,
  138. "Back and Z buffers are not a multiple of 512 apart.");
  139. if (zDiff < 0)
  140. zDiff = 0x800000 + zDiff;
  141. CP_WRITE(pjBase, DWG_ZORG, zDiff);
  142. }
  143. if (ppdev->pohBackBuffer == pDevWnd->pohBackBuffer) {
  144. yOrg = pMCDWnd->clipBoundsRect.top + pDevWnd->backBufferY;
  145. pRc->hwBufferYBias = pDevWnd->backBufferY;
  146. } else {
  147. yOrg = pDevWnd->backBufferY;
  148. pRc->hwBufferYBias = pDevWnd->backBufferY -
  149. pMCDWnd->clipBoundsRect.top;
  150. }
  151. }
  152. // We have to adjust the stipple pattern on each batch since the window
  153. // may have moved, and the HW stipple pattern is screen-relative whereas
  154. // OpenGL's is window-relative. We can't do the update in the tracking
  155. // function since we don't have an RC. Note that we only deal with simple
  156. // (101010) checkerboard stipples which are the most common.
  157. if (pRc->hwStipple) {
  158. LONG ofsAdj = (pMCDSurface->pWnd->clientRect.bottom & 0x1) ^
  159. (pMCDSurface->pWnd->clientRect.left & 0x1);
  160. pRc->hwTrapFunc &= ~((ULONG)trans_15);
  161. if (ofsAdj)
  162. pRc->hwTrapFunc |= (pRc->hwStipple ^ (trans_1 | trans_2));
  163. else
  164. pRc->hwTrapFunc |= pRc->hwStipple;
  165. }
  166. CP_WRITE(pjBase, DWG_YDSTORG, (yOrg * ppdev->cxMemory) + ppdev->ulYDstOrg);
  167. CP_WRITE(pjBase, DWG_PLNWT, pRc->hwPlaneMask);
  168. }
  169. __inline void HW_INIT_PRIMITIVE_STATE(MCDSURFACE *pMCDSurface, DEVRC *pRc)
  170. {
  171. PDEV *ppdev = (PDEV *)pMCDSurface->pso->dhpdev;
  172. BYTE *pjBase = ppdev->pjBase;
  173. if (!(pRc->privateEnables & __MCDENABLE_SMOOTH)) {
  174. // We will be using the interpolation mode of the hardware, but we'll
  175. // only be interpolation Z, so set the color deltas to 0.
  176. CHECK_FIFO_SPACE(pjBase, 6);
  177. CP_WRITE(pjBase, DWG_DR6, 0);
  178. CP_WRITE(pjBase, DWG_DR7, 0);
  179. CP_WRITE(pjBase, DWG_DR10, 0);
  180. CP_WRITE(pjBase, DWG_DR11, 0);
  181. CP_WRITE(pjBase, DWG_DR14, 0);
  182. CP_WRITE(pjBase, DWG_DR15, 0);
  183. }
  184. CHECK_FIFO_SPACE(pjBase, FIFOSIZE);
  185. pRc->cFifo = 32;
  186. }
  187. __inline void HW_DEFAULT_STATE(MCDSURFACE *pMCDSurface)
  188. {
  189. PDEV *ppdev = (PDEV *)pMCDSurface->pso->dhpdev;
  190. BYTE *pjBase = ppdev->pjBase;
  191. CHECK_FIFO_SPACE(pjBase, 7);
  192. // restore default clipping, sign register, plane mask, pitch
  193. CP_WRITE(pjBase, DWG_MACCESS, ppdev->ulAccess);
  194. CP_WRITE(pjBase, DWG_SGN, 0);
  195. CP_WRITE(pjBase, DWG_PITCH, ppdev->cxMemory | ylin_LINEARIZE);
  196. CP_WRITE(pjBase, DWG_PLNWT, ppdev->ulPlnWt);
  197. CP_WRITE(pjBase, DWG_YDSTORG, ppdev->ulYDstOrg);
  198. vResetClipping(ppdev);
  199. ppdev->HopeFlags = 0; // brute-force this
  200. }
  201. __inline void HW_GET_PLANE_MASK(DEVRC *pRc)
  202. {
  203. if (pRc->MCDState.colorWritemask[0] &&
  204. pRc->MCDState.colorWritemask[1] &&
  205. pRc->MCDState.colorWritemask[2] &&
  206. pRc->MCDState.colorWritemask[3])
  207. pRc->hwPlaneMask = ~((ULONG)0);
  208. else {
  209. ULONG mask = 0;
  210. if (pRc->MCDState.colorWritemask[0])
  211. mask |= ((1 << pRc->pixelFormat.rBits) - 1) <<
  212. pRc->pixelFormat.rShift;
  213. if (pRc->MCDState.colorWritemask[1])
  214. mask |= ((1 << pRc->pixelFormat.gBits) - 1) <<
  215. pRc->pixelFormat.gShift;
  216. if (pRc->MCDState.colorWritemask[2])
  217. mask |= ((1 << pRc->pixelFormat.bBits) - 1) <<
  218. pRc->pixelFormat.bShift;
  219. switch (pRc->pixelFormat.cColorBits) {
  220. case 8:
  221. pRc->hwPlaneMask = mask | (mask << 8) | (mask << 16) | (mask << 24);
  222. break;
  223. case 15:
  224. case 16:
  225. pRc->hwPlaneMask = mask | (mask << 16);
  226. break;
  227. default:
  228. pRc->hwPlaneMask = mask;
  229. break;
  230. }
  231. }
  232. }
  233. __inline void HW_START_FILL_RECT(MCDSURFACE *pMCDSurface, MCDRC *pMCDRc,
  234. DEVRC *pRc, ULONG buffers)
  235. {
  236. PDEV *ppdev = (PDEV *)pMCDSurface->pso->dhpdev;
  237. BYTE *pjBase = ppdev->pjBase;
  238. DEVWND *pDevWnd = (DEVWND *)pMCDSurface->pWnd->pvUser;
  239. ULONG hwOp;
  240. BOOL bFillC = (buffers & GL_COLOR_BUFFER_BIT) != 0;
  241. BOOL bFillZ = (buffers & GL_DEPTH_BUFFER_BIT) &&
  242. pRc->MCDState.depthWritemask;
  243. RGBACOLOR color;
  244. ULONG zFillValue;
  245. ULONG sumColor;
  246. //MCDBG_PRINT("HW_START_FILL_RECT: bFillC = %d, bFillZ = %d", bFillC, bFillZ);
  247. // This is a little slimy, but we don't know whether or not the plane
  248. // mask has changed since the last drawing batch:
  249. if (pRc->pickNeeded)
  250. HW_GET_PLANE_MASK(pRc);
  251. if (!bFillZ && (pRc->MCDState.colorClearValue.r == (MCDFLOAT)0.0) &&
  252. (pRc->MCDState.colorClearValue.g == (MCDFLOAT)0.0) &&
  253. (pRc->MCDState.colorClearValue.b == (MCDFLOAT)0.0)) {
  254. CHECK_FIFO_SPACE(pjBase, 3);
  255. CP_WRITE(pjBase, DWG_DWGCTL, opcode_TRAP | atype_RPL | bop_SRCCOPY |
  256. zdrwen_NO_DEPTH | blockm_ON | solid_SOLID | arzero_ZERO |
  257. sgnzero_ZERO);
  258. CP_WRITE(pjBase, DWG_FCOL, 0);
  259. CP_WRITE(pjBase, DWG_PLNWT, pRc->hwPlaneMask);
  260. } else {
  261. CHECK_FIFO_SPACE(pjBase, 16);
  262. MCDFIXEDRGB(color, pRc->MCDState.colorClearValue);
  263. // This logic is needed to pass conformance, since dithering
  264. // with pure white will cause problems on the Millenium.
  265. sumColor = (color.r | color.g | color.b) & ~(0x7fff);
  266. if ((sumColor == 0x7f8000) || (sumColor == 0)) {
  267. CP_WRITE(pjBase, DWG_MACCESS, pRc->ulAccess | dither_DISABLE);
  268. }
  269. //MCDBG_PRINT("fixcolor = %x, %x, %x, %x", color.r, color.g, color.b, color.a);
  270. //color.b = 0x3f0000;
  271. //!!MCDBG_PRINT("realcolor = %f, %f, %f, %f", pRc->MCDState.colorClearValue.r,
  272. //!! pRc->MCDState.colorClearValue.g,
  273. //!! pRc->MCDState.colorClearValue.b,
  274. //!! pRc->MCDState.colorClearValue.a);
  275. // NOTE: For Storm, assuming it's fixed so that the z-buffer isn't
  276. // always written, regardless of the 'zdrwen' bit, we will
  277. // have to clear the z-buffer using a 2-d blt (don't forget
  278. // to reset clipping!). But with the Athena, we get this
  279. // functionality by default.
  280. zFillValue = (ULONG)(pRc->MCDState.depthClearValue);
  281. //MCDBG_PRINT("zFillValue = %x", zFillValue);
  282. if (bFillZ) {
  283. //MCDBG_PRINT("Fill Rect with Color+Z");
  284. CP_WRITE(pjBase, DWG_DWGCTL, opcode_TRAP | atype_ZI | bop_SRCCOPY |
  285. solid_SOLID | arzero_ZERO | sgnzero_ZERO);
  286. CP_WRITE(pjBase, DWG_DR0, zFillValue << 15);
  287. } else {
  288. //MCDBG_PRINT("Fill Rect with Color");
  289. CP_WRITE(pjBase, DWG_DWGCTL, opcode_TRAP | atype_I | bop_SRCCOPY |
  290. solid_SOLID | arzero_ZERO | sgnzero_ZERO);
  291. }
  292. // If we're filling the z-buffer only, zero the plane mask:
  293. if (bFillZ && !bFillC)
  294. CP_WRITE(pjBase, DWG_PLNWT, 0);
  295. else
  296. CP_WRITE(pjBase, DWG_PLNWT, pRc->hwPlaneMask);
  297. CP_WRITE(pjBase, DWG_DR4, color.r);
  298. CP_WRITE(pjBase, DWG_DR8, color.g);
  299. CP_WRITE(pjBase, DWG_DR12, color.b);
  300. // Set all deltas to 0
  301. CP_WRITE(pjBase, DWG_DR2, 0);
  302. CP_WRITE(pjBase, DWG_DR3, 0);
  303. CP_WRITE(pjBase, DWG_DR6, 0);
  304. CP_WRITE(pjBase, DWG_DR7, 0);
  305. CP_WRITE(pjBase, DWG_DR10, 0);
  306. CP_WRITE(pjBase, DWG_DR11, 0);
  307. CP_WRITE(pjBase, DWG_DR14, 0);
  308. CP_WRITE(pjBase, DWG_DR15, 0);
  309. }
  310. CHECK_FIFO_SPACE(pjBase, 4);
  311. CP_WRITE(pjBase, DWG_CYTOP,
  312. ((pMCDSurface->pWnd->clipBoundsRect.top + pRc->hwBufferYBias) * ppdev->cxMemory) +
  313. ppdev->ulYDstOrg);
  314. CP_WRITE(pjBase, DWG_CXLEFT, pMCDSurface->pWnd->clipBoundsRect.left);
  315. CP_WRITE(pjBase, DWG_CXRIGHT, pMCDSurface->pWnd->clipBoundsRect.right - 1);
  316. CP_WRITE(pjBase, DWG_CYBOT,
  317. ((pMCDSurface->pWnd->clipBoundsRect.bottom + pRc->hwBufferYBias - 1) * ppdev->cxMemory) +
  318. ppdev->ulYDstOrg);
  319. }
  320. __inline void HW_FILL_RECT(MCDSURFACE *pMCDSurface, DEVRC *pRc, RECTL *pRecl)
  321. {
  322. PDEV *ppdev = (PDEV *)pMCDSurface->pso->dhpdev;
  323. BYTE *pjBase = ppdev->pjBase;
  324. //MCDBG_PRINT("fill rect = %d, %d, %d, %d", pRecl->left,
  325. // pRecl->top,
  326. // pRecl->right,
  327. // pRecl->bottom);
  328. CHECK_FIFO_SPACE(pjBase, 5);
  329. CP_WRITE(pjBase, DWG_YDST, pRecl->top - pRc->hwYOrgBias);
  330. CP_WRITE(pjBase, DWG_YDST, pRecl->top - pRc->hwYOrgBias);
  331. CP_WRITE(pjBase, DWG_FXLEFT, pRecl->left);
  332. CP_WRITE(pjBase, DWG_LEN, pRecl->bottom - pRecl->top);
  333. CP_START(pjBase, DWG_FXRIGHT, pRecl->right);
  334. }
  335. __inline void HW_START_SWAP_BUFFERS(MCDSURFACE *pMCDSurface,
  336. LONG *hwBufferYBias,
  337. ULONG flags)
  338. {
  339. PDEV *ppdev = (PDEV *)pMCDSurface->pso->dhpdev;
  340. BYTE *pjBase = ppdev->pjBase;
  341. DEVWND *pDevWnd = (DEVWND *)(pMCDSurface->pWnd->pvUser);
  342. CHECK_FIFO_SPACE(pjBase, 4);
  343. CP_WRITE(pjBase, DWG_DWGCTL, opcode_BITBLT + atype_RPL + blockm_OFF +
  344. bltmod_BFCOL + pattern_OFF + transc_BG_OPAQUE +
  345. bop_SRCCOPY);
  346. CP_WRITE(pjBase, DWG_SHIFT, 0);
  347. CP_WRITE(pjBase, DWG_SGN, 0);
  348. CP_WRITE(pjBase, DWG_AR5, ppdev->cxMemory);
  349. if (ppdev->pohBackBuffer == pDevWnd->pohBackBuffer) {
  350. *hwBufferYBias = pDevWnd->backBufferY;
  351. } else {
  352. *hwBufferYBias = pDevWnd->backBufferY -
  353. pMCDSurface->pWnd->clipBoundsRect.top;
  354. }
  355. }
  356. void SETUPTRIANGLEDRAWING(MCDSURFACE *pMCDSurface, MCDRC *pMCDRc);
  357. void DrawTriangle(MCDSURFACE *pMCDSurface, MCDRC *pMCDRc,
  358. MCDVERTEX *pMCDVertex);
  359. // External declarations
  360. void FASTCALL __HWDrawTrap(DEVRC *pRc, MCDFLOAT dxLeft, MCDFLOAT dxRight,
  361. LONG y, LONG dy);
  362. VOID FASTCALL __HWSetupDeltas(DEVRC *pRc);
  363. BOOL HWAllocResources(MCDWINDOW *pMCDWnd, SURFOBJ *pso, BOOL zEnabled,
  364. BOOL backBufferEnabled);
  365. VOID HWUpdateBufferPos(MCDWINDOW *pMCDWnd, SURFOBJ *pso, BOOL bForce);
  366. VOID HWFreeResources(MCDWINDOW *pMCDWnd, SURFOBJ *pso);
  367. VOID vMilCopyBlt3D(PDEV* ppdev, POINTL* pptlSrc, RECTL* prclDst);
  368. #endif /* _MCDUTIL_H */