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.

296 lines
7.8 KiB

  1. //----------------------------------------------------------------------------
  2. //
  3. // point.cpp
  4. //
  5. // Point processing.
  6. //
  7. // Copyright (C) Microsoft Corporation, 1997.
  8. //
  9. //----------------------------------------------------------------------------
  10. #include "pch.cpp"
  11. #pragma hdrstop
  12. DBG_DECLARE_FILE();
  13. void
  14. PrimProcessor::FillPointSpan(LPD3DTLVERTEX pV0, PD3DI_RASTSPAN pSpan)
  15. {
  16. FLOAT fZ;
  17. FLOAT fZScale;
  18. pSpan->uPix = 1;
  19. pSpan->uX = (UINT16)m_StpCtx.iX;
  20. pSpan->uY = (UINT16)m_StpCtx.iY;
  21. pSpan->pSurface = m_StpCtx.pCtx->pSurfaceBits +
  22. m_StpCtx.iX * m_StpCtx.pCtx->iSurfaceStep +
  23. m_StpCtx.iY * m_StpCtx.pCtx->iSurfaceStride;
  24. if (m_StpCtx.uFlags & PRIMSF_Z_USED)
  25. {
  26. pSpan->pZ = m_StpCtx.pCtx->pZBits +
  27. m_StpCtx.iX * m_StpCtx.pCtx->iZStep +
  28. m_StpCtx.iY * m_StpCtx.pCtx->iZStride;
  29. if (m_StpCtx.pCtx->iZBitCount == 16)
  30. {
  31. fZScale = Z16_SCALE;
  32. }
  33. else
  34. {
  35. fZScale = Z32_SCALE;
  36. }
  37. // fZ may be used later so set if from the vertex Z.
  38. fZ = pV0->dvSZ;
  39. pSpan->uZ = FTOI(fZ * fZScale);
  40. }
  41. if (m_StpCtx.uFlags & PRIMSF_TEX_USED)
  42. {
  43. FLOAT fW;
  44. FLOAT fUoW, fVoW;
  45. // Mipmapping doesn't have any meaning.
  46. RSASSERT((m_StpCtx.uFlags & PRIMSF_LOD_USED) == 0);
  47. if (m_StpCtx.uFlags & PRIMSF_PERSP_USED)
  48. {
  49. if (FLOAT_EQZ(pV0->dvRHW))
  50. {
  51. fW = g_fZero;
  52. }
  53. else
  54. {
  55. fW = g_fOne / pV0->dvRHW;
  56. }
  57. pSpan->iW = FTOI(fW * W_SCALE);
  58. fUoW = pV0->dvTU * pV0->dvRHW;
  59. fVoW = pV0->dvTV * pV0->dvRHW;
  60. pSpan->iOoW = FTOI(pV0->dvRHW * OOW_SCALE);
  61. }
  62. else
  63. {
  64. fUoW = pV0->dvTU;
  65. fVoW = pV0->dvTV;
  66. }
  67. pSpan->iLOD = 0;
  68. pSpan->iDLOD = 0;
  69. pSpan->iUoW1 = FTOI(fUoW * TEX_SCALE);
  70. pSpan->iVoW1 = FTOI(fVoW * TEX_SCALE);
  71. }
  72. if (m_StpCtx.uFlags & PRIMSF_TEX2_USED)
  73. {
  74. if (m_StpCtx.uFlags & PRIMSF_PERSP_USED)
  75. {
  76. pSpan->iUoW2 =
  77. FTOI(((PRAST_GENERIC_VERTEX)pV0)->dvTU2 *
  78. pV0->dvRHW * TEX_SCALE);
  79. pSpan->iVoW2 =
  80. FTOI(((PRAST_GENERIC_VERTEX)pV0)->dvTV2 *
  81. pV0->dvRHW * TEX_SCALE);
  82. }
  83. else
  84. {
  85. pSpan->iUoW2 =
  86. FTOI(((PRAST_GENERIC_VERTEX)pV0)->dvTU2 * TEX_SCALE);
  87. pSpan->iVoW2 =
  88. FTOI(((PRAST_GENERIC_VERTEX)pV0)->dvTV2 * TEX_SCALE);
  89. }
  90. }
  91. if (m_StpCtx.uFlags & PRIMSF_DIFF_USED)
  92. {
  93. pSpan->uB = (UINT)RGBA_GETBLUE(m_StpCtx.pFlatVtx->dcColor) <<
  94. COLOR_SHIFT;
  95. pSpan->uG = (UINT)RGBA_GETGREEN(m_StpCtx.pFlatVtx->dcColor) <<
  96. COLOR_SHIFT;
  97. pSpan->uR = (UINT)RGBA_GETRED(m_StpCtx.pFlatVtx->dcColor) <<
  98. COLOR_SHIFT;
  99. pSpan->uA = (UINT)RGBA_GETALPHA(m_StpCtx.pFlatVtx->dcColor) <<
  100. COLOR_SHIFT;
  101. }
  102. else if (m_StpCtx.uFlags & PRIMSF_DIDX_USED)
  103. {
  104. pSpan->iIdx = (INT32)CI_MASKALPHA(m_StpCtx.pFlatVtx->dcColor) <<
  105. INDEX_COLOR_FIXED_SHIFT;
  106. pSpan->iIdxA = (INT32)CI_GETALPHA(m_StpCtx.pFlatVtx->dcColor) <<
  107. INDEX_COLOR_SHIFT;
  108. }
  109. if (m_StpCtx.uFlags & PRIMSF_SPEC_USED)
  110. {
  111. pSpan->uBS = (UINT)RGBA_GETBLUE(m_StpCtx.pFlatVtx->dcSpecular) <<
  112. COLOR_SHIFT;
  113. pSpan->uGS = (UINT)RGBA_GETGREEN(m_StpCtx.pFlatVtx->dcSpecular) <<
  114. COLOR_SHIFT;
  115. pSpan->uRS = (UINT)RGBA_GETRED(m_StpCtx.pFlatVtx->dcSpecular) <<
  116. COLOR_SHIFT;
  117. }
  118. if (m_StpCtx.uFlags & PRIMSF_LOCAL_FOG_USED)
  119. {
  120. if (m_StpCtx.uFlags & PRIMSF_GLOBAL_FOG_USED)
  121. {
  122. // Make sure that fZ has been set.
  123. RSASSERT(m_StpCtx.uFlags & PRIMSF_Z_USED);
  124. pSpan->uFog = (UINT16)ComputeTableFog(m_StpCtx.pCtx->pdwRenderState, fZ);
  125. }
  126. else
  127. {
  128. pSpan->uFog = (INT16)
  129. FTOI((FLOAT)RGBA_GETALPHA(pV0->dcSpecular) *
  130. FOG_255_SCALE);
  131. }
  132. }
  133. }
  134. // Determine whether any of the given values are less than zero or greater
  135. // than one. Negative zero counts as less than zero so this check will
  136. // produce some false positives but that's OK.
  137. #define NEEDS_NORMALIZE1(fV0) \
  138. (ASUINT32(fV0) > INT32_FLOAT_ONE)
  139. //----------------------------------------------------------------------------
  140. //
  141. // PrimProcessor::NormalizePointRHW
  142. //
  143. // D3DTLVERTEX.dvRHW can be anything, but our internal structures only
  144. // allow for it being in the range [0, 1]. This function clamps
  145. // the RHW to the proper range.
  146. //
  147. //----------------------------------------------------------------------------
  148. void
  149. PrimProcessor::NormalizePointRHW(LPD3DTLVERTEX pV0)
  150. {
  151. // Save original value.
  152. m_dvV0RHW = pV0->dvRHW;
  153. // Produce a warning when a value is out of the desired range.
  154. #if DBG
  155. if (FLOAT_LTZ(pV0->dvRHW))
  156. {
  157. RSDPF(("Point RHW out of range %f,%f",
  158. pV0->dvRHW));
  159. }
  160. #endif
  161. if (pV0->dvRHW < NORMALIZED_RHW_MIN)
  162. {
  163. pV0->dvRHW = NORMALIZED_RHW_MIN;
  164. }
  165. else if (pV0->dvRHW > NORMALIZED_RHW_MAX)
  166. {
  167. pV0->dvRHW = NORMALIZED_RHW_MAX;
  168. }
  169. }
  170. //----------------------------------------------------------------------------
  171. //
  172. // PrimProcessor::Point
  173. //
  174. // Provides a point for processing.
  175. //
  176. //----------------------------------------------------------------------------
  177. HRESULT
  178. PrimProcessor::Point(LPD3DTLVERTEX pV0,
  179. LPD3DTLVERTEX pFlatVtx)
  180. {
  181. HRESULT hr;
  182. hr = D3D_OK;
  183. #if DBG
  184. hr = ValidateVertex(pV0);
  185. if (hr != D3D_OK)
  186. {
  187. return hr;
  188. }
  189. #endif
  190. // Clear per-point flags.
  191. m_StpCtx.uFlags &= ~(PRIMF_ALL | PTF_ALL);
  192. RSDPFM((RSM_FLAGS, "m_uPpFlags: 0x%08X, m_StpCtx.uFlags: 0x%08X",
  193. m_uPpFlags, m_StpCtx.uFlags));
  194. // Round coordinates to integer.
  195. m_StpCtx.iX = IFLOORF(pV0->dvSX + g_fHalf);
  196. m_StpCtx.iY = IFLOORF(pV0->dvSY + g_fHalf);
  197. RSDPFM((RSM_POINTS, "Point\n"));
  198. RSDPFM((RSM_POINTS, " V0 (%f,%f,%f) (%d,%d)\n",
  199. pV0->dvSX, pV0->dvSY, pV0->dvSZ,
  200. m_StpCtx.iX, m_StpCtx.iY));
  201. // Clip test.
  202. if (m_StpCtx.iX < m_StpCtx.pCtx->Clip.left ||
  203. m_StpCtx.iX >= m_StpCtx.pCtx->Clip.right ||
  204. m_StpCtx.iY < m_StpCtx.pCtx->Clip.top ||
  205. m_StpCtx.iY >= m_StpCtx.pCtx->Clip.bottom)
  206. {
  207. return D3D_OK;
  208. }
  209. //
  210. // Fill out a one-pixel span for the point.
  211. // Since the prim deltas are irrelevant for the span,
  212. // the span is appended to whatever primitive happens
  213. // to be available in the buffer.
  214. //
  215. PD3DI_RASTSPAN pSpan;
  216. UINT cSpans = 1;
  217. hr = AppendPrim();
  218. if (hr != D3D_OK)
  219. {
  220. return hr;
  221. }
  222. hr = AllocSpans(&cSpans, &pSpan);
  223. if (hr != D3D_OK)
  224. {
  225. return hr;
  226. }
  227. m_StpCtx.pPrim->uSpans++;
  228. BOOL bNorm;
  229. // USED checks cannot be combined since TEX_USED is a multibit check.
  230. if ((m_StpCtx.uFlags & PRIMSF_TEX_USED) &&
  231. (m_StpCtx.uFlags & PRIMSF_PERSP_USED) &&
  232. (m_uPpFlags & PPF_NORMALIZE_RHW) &&
  233. NEEDS_NORMALIZE1(pV0->dvRHW))
  234. {
  235. NormalizePointRHW(pV0);
  236. bNorm = TRUE;
  237. }
  238. else
  239. {
  240. bNorm = FALSE;
  241. }
  242. // Remember flat color controlling vertex for setup.
  243. m_StpCtx.pFlatVtx = pFlatVtx;
  244. FillPointSpan(pV0, pSpan);
  245. if (bNorm)
  246. {
  247. pV0->dvRHW = m_dvV0RHW;
  248. }
  249. return D3D_OK;
  250. }