Leaked source code of windows server 2003
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.

356 lines
11 KiB

  1. /******************************Module*Header*******************************\
  2. * Module Name: mcdline.c
  3. *
  4. * Contains all of the line-rendering routines for the Cirrus Logic 546X MCD driver.
  5. *
  6. * (based on mcdline.c from NT4.0 DDK)
  7. *
  8. * Copyright (c) 1996 Microsoft Corporation
  9. * Copyright (c) 1997 Cirrus Logic, Inc.
  10. \**************************************************************************/
  11. #include "precomp.h"
  12. #include "mcdhw.h"
  13. #include "mcdutil.h"
  14. #include "mcdmath.h"
  15. //#undef CHECK_FIFO_FREE
  16. //#define CHECK_FIFO_FREE
  17. #define EXCHANGE(i,j) \
  18. { \
  19. ptemp=i; \
  20. i=j; j=ptemp; \
  21. }
  22. VOID FASTCALL __MCDRenderLine(DEVRC *pRc, MCDVERTEX *a, MCDVERTEX *b, BOOL resetLine)
  23. {
  24. ULONG clipNum;
  25. RECTL *pClip;
  26. LONG lCoord;
  27. PDEV *ppdev = pRc->ppdev;
  28. unsigned int *pdwNext = ppdev->LL_State.pDL->pdwNext;
  29. void *ptemp; // for EXCHANGE and ROTATE_L macros
  30. // output queue stuff...
  31. DWORD *pSrc;
  32. DWORD *pDest = ppdev->LL_State.pRegs + HOST_3D_DATA_PORT;
  33. DWORD *pdwStart = ppdev->LL_State.pDL->pdwStartOutPtr;
  34. DWORD dwFlags=0; // MCD_TEMP - dwflags initialized to 0
  35. DWORD *dwOrig; /* Temp display list pointer */
  36. DWORD dwOpcode; // Built opcode
  37. float frecip_step;
  38. float v1red,v1grn,v1blu;
  39. LONG ax, bx, ay, by;
  40. // FUTURE - do something with resetLine input to line render proc
  41. if ((clipNum = pRc->pEnumClip->c) > 1) {
  42. pClip = &pRc->pEnumClip->arcl[0];
  43. SET_HW_CLIP_REGS(pRc,pdwNext);
  44. pClip++;
  45. }
  46. // window coords are float values, and need to have
  47. // viewportadjust (MCDVIEWPORT) values subtracted to get to real screen space
  48. // color values are 0->1 floats and must be multiplied by scale values (MCDRCINFO)
  49. // to get to nbits range (scale = 0xff for 8 bit, 0x7 for 3 bit, etc.)
  50. // Z values are 0->1 floats and must be multiplied by zscale values (MCDRCINFO)
  51. // Exchange the pointers to vertices if the second point
  52. // of the line is above the first one
  53. //
  54. pRc->pvProvoking = a; // keep track of original first for possible flat shading
  55. if( a->windowCoord.y > b->windowCoord.y )
  56. {
  57. EXCHANGE(a,b);
  58. }
  59. // Store the first address for the opcode
  60. //
  61. dwOrig = pdwNext;
  62. pdwNext += 3;
  63. // Start with a plain line instruction (no modifiers)
  64. // and assume same color. Also add three words for DDA
  65. // line parameters + count (they can not be avoided)
  66. //
  67. dwOpcode = LINE | SAME_COLOR | (2+3);
  68. // Set flags as requested from the dwFlags field of a batch.
  69. // These bits have 1-1 correspondence to their instruction
  70. // counterparts.
  71. //
  72. // Flags : LL_DITHER - Use dither pattern
  73. // LL_PATTERN - Draw pattern
  74. // LL_STIPPLE - Use stipple mask
  75. // LL_LIGHTING - Do lighting
  76. // LL_Z_BUFFER - Use Z buffer
  77. // FETCH_COLOR - Appended for alpha blending
  78. // LL_GOURAUD - Use Gouraud shading
  79. // LL_TEXTURE - Texture mapping
  80. //
  81. /*
  82. dwOpcode |= dwFlags &
  83. ( LL_DITHER | LL_PATTERN | LL_STIPPLE
  84. | LL_LIGHTING | LL_Z_BUFFER | FETCH_COLOR
  85. | LL_GOURAUD | LL_TEXTURE );
  86. */
  87. dwOpcode |= pRc->privateEnables & (__MCDENABLE_SMOOTH|__MCDENABLE_Z);
  88. if (pRc->privateEnables & __MCDENABLE_LINE_STIPPLE)
  89. {
  90. dwOpcode |= LL_STIPPLE;
  91. }
  92. else
  93. {
  94. // can dither only if no stipple
  95. dwOpcode |= (pRc->privateEnables & __MCDENABLE_DITHER) ;
  96. }
  97. if( !(dwFlags & LL_SAME_COLOR) )
  98. {
  99. register DWORD color;
  100. // Clear same_color flag
  101. //
  102. dwOpcode ^= LL_SAME_COLOR;
  103. // If the line is shaded, the starting color that should
  104. // be set is the topmost point (pVert1)
  105. if (pRc->privateEnables & __MCDENABLE_SMOOTH)
  106. {
  107. v1red = a->colors[0].r * pRc->rScale;
  108. *pdwNext = FTOL(v1red);
  109. v1grn = a->colors[0].g * pRc->gScale;
  110. v1blu = a->colors[0].b * pRc->bScale;
  111. *(pdwNext+1) = FTOL(v1grn);
  112. *(pdwNext+2) = FTOL(v1blu);
  113. dwOpcode += 3;
  114. pdwNext += 3;
  115. }
  116. else
  117. {
  118. MCDCOLOR *pColor = &pRc->pvProvoking->colors[0];
  119. *pdwNext = FTOL(pColor->r * pRc->rScale);
  120. *(pdwNext+1) = FTOL(pColor->g * pRc->gScale);
  121. *(pdwNext+2) = FTOL(pColor->b * pRc->bScale);
  122. dwOpcode += 3;
  123. pdwNext += 3;
  124. }
  125. }
  126. // Set the parameters of a line slope and count
  127. // Note: line can only go down, so dy is always positive
  128. //
  129. {
  130. int dx, dy, abs_dx, xdir;
  131. // Well ordered points - set starting point1 coords
  132. // using a pointer to the origin of the instruction
  133. //
  134. ax = FTOL(a->windowCoord.x);
  135. lCoord = ax + pRc->xOffset;
  136. *(dwOrig+1) = (DWORD) (lCoord << 16 );
  137. ay = FTOL(a->windowCoord.y);
  138. lCoord = ay + pRc->yOffset;
  139. *(dwOrig+2) = (DWORD) (lCoord << 16 );
  140. bx = FTOL(b->windowCoord.x);
  141. by = FTOL(b->windowCoord.y);
  142. // dx = x2 - x1,
  143. // dy = y2 - y1 (always positive)
  144. //
  145. dx = bx - ax;
  146. dy = by - ay;
  147. // NOTE that dx and dy are in 32.0 format (LL3D has them in 16.16)
  148. // so math below differs from LL3D
  149. // make sure dx is positive, and setup xdir needed for x major since we're
  150. // already doing the compare here to prevent having to do again for x major case
  151. if (dx < 0)
  152. {
  153. abs_dx = -dx;
  154. xdir = 0xffff0000;
  155. }
  156. else
  157. {
  158. abs_dx = dx;
  159. xdir = 0x00010000;
  160. }
  161. if( abs_dx > dy )
  162. {
  163. // X-major
  164. //
  165. // compute slope with positive dx
  166. frecip_step = ppdev->frecips[abs_dx];
  167. *(pdwNext + 0) = xdir;
  168. *(pdwNext + 1) = abs_dx;
  169. // *(pdwNext + 2) = (double)dy / (double)ABS(dx) * 65536.0;
  170. *(pdwNext + 2) = FTOL(dy * frecip_step * (float)65536.0); // equivalent to above
  171. }
  172. else
  173. {
  174. // Y-major
  175. //
  176. frecip_step = ppdev->frecips[dy];
  177. *(pdwNext + 1) = dy; // Positive count always, by virtue of earlier EXCHANGE
  178. *(pdwNext + 2) = 0x10000; // dy = 1
  179. // *(pdwNext + 0) = (double)dx / (double)dy * 65536.0;
  180. *(pdwNext + 0) = FTOL(dx * frecip_step * (float)65536.0); // equivalent to above
  181. }
  182. pdwNext += 3;
  183. }
  184. if (pRc->privateEnables & __MCDENABLE_SMOOTH)
  185. {
  186. float tmp;
  187. // Calculate and set the color gradients
  188. //
  189. tmp = ((b->colors[0].r * pRc->rScale) - v1red) * frecip_step;
  190. *pdwNext++ = FTOL(tmp);
  191. tmp = ((b->colors[0].g * pRc->gScale) - v1grn) * frecip_step;
  192. *pdwNext++ = FTOL(tmp);
  193. tmp = ((b->colors[0].b * pRc->bScale) - v1blu) * frecip_step;
  194. *pdwNext++ = FTOL(tmp);
  195. // Increase count field by 6 for DR_MAIN_3D, DG_MAIN_3D,
  196. // DB_MAIN_3D and DR_ORTHO_3D, DG_ORTHO_3D, DB_ORTHO_3D
  197. //
  198. dwOpcode += 3;
  199. }
  200. if( pRc->privateEnables & __MCDENABLE_Z)
  201. {
  202. float fdz_main = (b->windowCoord.z - a->windowCoord.z) * pRc->zScale * frecip_step;
  203. *pdwNext++ = FTOL(a->windowCoord.z * pRc->zScale);
  204. *pdwNext++ = FTOL(fdz_main);
  205. // Increase count field by 2 for Z_3D, DZ_MAIN_3D
  206. //
  207. dwOpcode += 2;
  208. }
  209. #if 0
  210. if( dwFlags & LL_TEXTURE )
  211. {
  212. ...
  213. ...
  214. ...
  215. }
  216. #endif
  217. if (pRc->privateEnables & (__MCDENABLE_BLEND|__MCDENABLE_FOG))
  218. {
  219. float v1alp,tmp;
  220. if (pRc->privateEnables & __MCDENABLE_BLEND)
  221. {
  222. // recall that if both blending and fog active, all prims punted back to software
  223. v1alp = a->colors[0].a * pRc->aScale;
  224. *(pdwNext+0) = FTOL(v1alp);
  225. tmp = ((b->colors[0].a * pRc->aScale) - v1alp) * frecip_step;
  226. *(pdwNext+1) = FTOL(tmp);
  227. }
  228. else
  229. {
  230. v1alp = a->fog * (float)16777215.0; // convert from 0->1.0 val to 0->ff.ffff val
  231. *(pdwNext+0) = FTOL(v1alp);
  232. tmp = ((b->fog * (float)16777215.0) - v1alp) * frecip_step;
  233. *(pdwNext+1) = FTOL(tmp);
  234. }
  235. *(pdwNext+0) &= 0x00ffff00;// bits 31->24 and 7->0 reserved
  236. *(pdwNext+1) &= 0xffffff00;// bits 7->0 reserved
  237. dwOpcode += ( FETCH_COLOR | ALPHA + 2 );
  238. pdwNext += 2;
  239. }
  240. // Store the final opcode
  241. //
  242. *dwOrig = dwOpcode;
  243. while (--clipNum) {
  244. int len = (dwOpcode & 0x3F) + 1; // num words for line primitive
  245. SET_HW_CLIP_REGS(pRc,pdwNext)
  246. pClip++;
  247. // dump same line regs again to draw while clipping against occlusion rectangle
  248. pSrc = dwOrig;
  249. while( len-- ) *pdwNext++ = *pSrc++;
  250. }
  251. // output queued data here....
  252. #if 0 // FUTURE - enable queueing algorithm - just outputting everything for now
  253. OUTPUT_COPROCMODE_QUEUE
  254. #else // 0
  255. {
  256. pSrc = pdwStart;
  257. while (pSrc != pdwNext)
  258. {
  259. /* Get the amount of data for this opcode */
  260. int len = (*pSrc & 0x3F) + 1;
  261. USB_TIMEOUT_FIX(ppdev)
  262. while( len-- ) *pDest = *pSrc++;
  263. }
  264. }
  265. #endif // 0
  266. ppdev->LL_State.pDL->pdwNext = ppdev->LL_State.pDL->pdwStartOutPtr = pdwStart;
  267. }
  268. VOID FASTCALL __MCDRenderGenLine(DEVRC *pRc, MCDVERTEX *pv1, MCDVERTEX *pv2, BOOL resetLine)
  269. {
  270. // MGA and S3 MCD's have no code in this proc
  271. MCDBG_PRINT("__MCDRenderGenLine - EMPTY ROUTINE");
  272. }