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.

277 lines
7.9 KiB

  1. //----------------------------------------------------------------------------
  2. //
  3. // line.cpp
  4. //
  5. // Line processing.
  6. //
  7. // Copyright (C) Microsoft Corporation, 1997.
  8. //
  9. //----------------------------------------------------------------------------
  10. #include "pch.cpp"
  11. #pragma hdrstop
  12. DBG_DECLARE_FILE();
  13. //----------------------------------------------------------------------------
  14. //
  15. // LinePatternStateMachine
  16. //
  17. // Runs the line pattern state machine and returns TRUE if the pixel is to be
  18. // drawn, false otherwise.
  19. //
  20. //----------------------------------------------------------------------------
  21. static inline BOOL LinePatternStateMachine(WORD wRepeatFactor, WORD wLinePattern, WORD& wRepeati, WORD& wPatterni)
  22. {
  23. if (wRepeatFactor == 0)
  24. {
  25. return TRUE;
  26. }
  27. WORD wBit = (wLinePattern >> wPatterni) & 1;
  28. if (++wRepeati >= wRepeatFactor)
  29. {
  30. wRepeati = 0;
  31. wPatterni = (wPatterni+1) & 0xf;
  32. }
  33. return (BOOL)wBit;
  34. }
  35. #define CLAMP_COLOR(fVal, uVal) \
  36. if (FLOAT_LTZ(fVal)) \
  37. { \
  38. uVal = 0; \
  39. } \
  40. else \
  41. { \
  42. if (uVal > 0xffff) \
  43. { \
  44. uVal = 0xffff; \
  45. } \
  46. } \
  47. #define CLAMP_Z(fVal, uVal) \
  48. if (FLOAT_LTZ(fVal)) \
  49. { \
  50. uVal = 0; \
  51. } \
  52. //----------------------------------------------------------------------------
  53. //
  54. // ClampPixel
  55. //
  56. // Clamp color, specular and z(if any) of a pixel. Right now, it's done for
  57. // first and last pixel of a line only.
  58. //
  59. //----------------------------------------------------------------------------
  60. inline void
  61. ClampPixel(PATTRSET pAttrs, PD3DI_RASTSPAN pSpan)
  62. {
  63. CLAMP_COLOR(pAttrs->fB, pSpan->uB);
  64. CLAMP_COLOR(pAttrs->fG, pSpan->uG);
  65. CLAMP_COLOR(pAttrs->fR, pSpan->uR);
  66. CLAMP_COLOR(pAttrs->fA, pSpan->uA);
  67. CLAMP_COLOR(pAttrs->fBS, pSpan->uBS);
  68. CLAMP_COLOR(pAttrs->fGS, pSpan->uGS);
  69. CLAMP_COLOR(pAttrs->fRS, pSpan->uRS);
  70. CLAMP_Z(pAttrs->fZ, pSpan->uZ);
  71. }
  72. //----------------------------------------------------------------------------
  73. //
  74. // WalkLinePattern
  75. //
  76. // Walks a line and generates the pixels touched according to the pattern.
  77. // If wRepeatFactor >= 1, we are patterning, otherwise, we are not
  78. //
  79. //----------------------------------------------------------------------------
  80. HRESULT
  81. WalkLinePattern(PSETUPCTX pStpCtx, WORD wRepeatFactor, WORD wLinePattern)
  82. {
  83. HRESULT hr;
  84. UINT uSpansAvail;
  85. PD3DI_RASTSPAN pSpan;
  86. WORD wRepeati = 0;
  87. WORD wPatterni = 0;
  88. BOOL bFirst = TRUE;
  89. RSASSERT(pStpCtx->cLinePix > 0);
  90. hr = D3D_OK;
  91. uSpansAvail = 0;
  92. RSASSERT((pStpCtx->uFlags & PRIMSF_LOD_USED) == 0);
  93. #ifdef PWL_FOG
  94. pStpCtx->uPwlFlags = PWL_NO_NEXT_FOG;
  95. #endif
  96. for (;;)
  97. {
  98. if (pStpCtx->iX >= pStpCtx->pCtx->Clip.left &&
  99. pStpCtx->iX < pStpCtx->pCtx->Clip.right &&
  100. pStpCtx->iY >= pStpCtx->pCtx->Clip.top &&
  101. pStpCtx->iY < pStpCtx->pCtx->Clip.bottom)
  102. {
  103. if (LinePatternStateMachine(wRepeatFactor, wLinePattern, wRepeati, wPatterni))
  104. {
  105. if (uSpansAvail == 0)
  106. {
  107. uSpansAvail = pStpCtx->cLinePix;
  108. hr = ALLOC_SPANS(pStpCtx, &uSpansAvail, &pSpan);
  109. if (hr != D3D_OK)
  110. {
  111. // uSpansAvail is set to zero on failure.
  112. goto EH_Exit;
  113. }
  114. }
  115. else
  116. {
  117. pSpan++;
  118. }
  119. uSpansAvail--;
  120. pStpCtx->pPrim->uSpans++;
  121. pSpan->uPix = 1;
  122. pSpan->uX = (UINT16)pStpCtx->iX;
  123. pSpan->uY = (UINT16)pStpCtx->iY;
  124. pStpCtx->pfnFillSpanAttrs(&pStpCtx->Attr, pSpan, pStpCtx, 1);
  125. // Clamp first/last pixel
  126. if (bFirst || pStpCtx->cLinePix == 1)
  127. {
  128. bFirst = FALSE;
  129. ClampPixel(&pStpCtx->Attr, pSpan);
  130. }
  131. }
  132. }
  133. if (--pStpCtx->cLinePix == 0)
  134. {
  135. break;
  136. }
  137. #ifdef VERBOSE_LINES
  138. RSDPF((" %4d,%4d: %10d %11d => ",
  139. pStpCtx->iX, pStpCtx->iY,
  140. pStpCtx->iLineFrac, pStpCtx->iLineFrac + pStpCtx->iDLineFrac));
  141. #endif
  142. pStpCtx->iLineFrac += pStpCtx->iDLineFrac;
  143. if (pStpCtx->iLineFrac < 0)
  144. {
  145. pStpCtx->iLineFrac &= 0x7fffffff;
  146. pStpCtx->iX += pStpCtx->iDXCY;
  147. pStpCtx->iY += pStpCtx->iDYCY;
  148. pStpCtx->DAttrDMajor.ipSurface = pStpCtx->DAttrCY.ipSurface;
  149. pStpCtx->DAttrDMajor.ipZ = pStpCtx->DAttrCY.ipZ;
  150. }
  151. else
  152. {
  153. pStpCtx->iX += pStpCtx->iDXNC;
  154. pStpCtx->iY += pStpCtx->iDYNC;
  155. pStpCtx->DAttrDMajor.ipSurface = pStpCtx->DAttrNC.ipSurface;
  156. pStpCtx->DAttrDMajor.ipZ = pStpCtx->DAttrNC.ipZ;
  157. }
  158. #ifdef VERBOSE_LINES
  159. RSDPFM((DBG_MASK_FORCE | DBG_MASK_NO_PREFIX, "%4d,%4d: %10d\n",
  160. pStpCtx->iX, pStpCtx->iY,
  161. pStpCtx->iLineFrac));
  162. #endif
  163. pStpCtx->pfnAddAttrs(&pStpCtx->Attr, &pStpCtx->DAttrDMajor, pStpCtx);
  164. }
  165. EH_Exit:
  166. if (uSpansAvail > 0)
  167. {
  168. FREE_SPANS(pStpCtx, uSpansAvail);
  169. }
  170. return hr;
  171. }
  172. //----------------------------------------------------------------------------
  173. //
  174. // PrimProcessor::Line
  175. //
  176. // Provides a line for processing.
  177. //
  178. //----------------------------------------------------------------------------
  179. HRESULT
  180. PrimProcessor::Line(LPD3DTLVERTEX pV0,
  181. LPD3DTLVERTEX pV1,
  182. LPD3DTLVERTEX pFlatVtx)
  183. {
  184. HRESULT hr;
  185. hr = D3D_OK;
  186. #if DBG
  187. hr = ValidateVertex(pV0);
  188. if (hr != D3D_OK)
  189. {
  190. return hr;
  191. }
  192. hr = ValidateVertex(pV1);
  193. if (hr != D3D_OK)
  194. {
  195. return hr;
  196. }
  197. #endif
  198. // Clear per-line flags.
  199. m_StpCtx.uFlags &= ~(PRIMF_ALL | LNF_ALL);
  200. RSDPFM((RSM_FLAGS, "m_uPpFlags: 0x%08X, m_StpCtx.uFlags: 0x%08X\n",
  201. m_uPpFlags, m_StpCtx.uFlags));
  202. RSDPFM((RSM_LINES, "Line\n"));
  203. RSDPFM((RSM_LINES, " V0 (%f,%f,%f)\n",
  204. pV0->dvSX, pV0->dvSY, pV0->dvSZ));
  205. RSDPFM((RSM_LINES, " V1 (%f,%f,%f)\n",
  206. pV1->dvSX, pV1->dvSY, pV1->dvSZ));
  207. // Remember flat color controlling vertex for setup.
  208. m_StpCtx.pFlatVtx = pFlatVtx;
  209. if (LineSetup(pV0, pV1))
  210. {
  211. // Compute initial buffer pointers for the scanline.
  212. m_StpCtx.Attr.pSurface = m_StpCtx.pCtx->pSurfaceBits +
  213. m_StpCtx.iX * m_StpCtx.pCtx->iSurfaceStep +
  214. m_StpCtx.iY * m_StpCtx.pCtx->iSurfaceStride;
  215. if (m_StpCtx.uFlags & PRIMSF_Z_USED)
  216. {
  217. m_StpCtx.Attr.pZ = m_StpCtx.pCtx->pZBits +
  218. m_StpCtx.iX * m_StpCtx.pCtx->iZStep +
  219. m_StpCtx.iY * m_StpCtx.pCtx->iZStride;
  220. }
  221. // Line walking only generates single-pixel spans so
  222. // the prim deltas are unused. Therefore, line spans
  223. // are simply added to whatever primitive happens to
  224. // be sitting in the buffer.
  225. hr = AppendPrim();
  226. if (hr != D3D_OK)
  227. {
  228. return hr;
  229. }
  230. union
  231. {
  232. D3DLINEPATTERN LPat;
  233. DWORD dwLPat;
  234. } LinePat;
  235. LinePat.dwLPat = m_StpCtx.pCtx->pdwRenderState[D3DRENDERSTATE_LINEPATTERN];
  236. hr = WalkLinePattern(&m_StpCtx, LinePat.LPat.wRepeatFactor, LinePat.LPat.wLinePattern);
  237. }
  238. return hr;
  239. }