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.

307 lines
8.1 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->UVoW[0].iUoW = FTOI(fUoW * TEX_SCALE);
  70. pSpan->UVoW[0].iVoW = FTOI(fVoW * TEX_SCALE);
  71. }
  72. if (m_StpCtx.uFlags & PRIMSF_TEX2_USED)
  73. {
  74. for (INT32 i = 1; i < (INT32)m_StpCtx.pCtx->cActTex; i++)
  75. {
  76. if (m_StpCtx.uFlags & PRIMSF_PERSP_USED)
  77. {
  78. pSpan->UVoW[i].iUoW =
  79. FTOI(((PRAST_GENERIC_VERTEX)pV0)->texCoord[i].dvTU *
  80. pV0->dvRHW * TEX_SCALE);
  81. pSpan->UVoW[i].iVoW =
  82. FTOI(((PRAST_GENERIC_VERTEX)pV0)->texCoord[i].dvTV *
  83. pV0->dvRHW * TEX_SCALE);
  84. }
  85. else
  86. {
  87. pSpan->UVoW[i].iUoW =
  88. FTOI(((PRAST_GENERIC_VERTEX)pV0)->texCoord[i].dvTU * TEX_SCALE);
  89. pSpan->UVoW[i].iVoW =
  90. FTOI(((PRAST_GENERIC_VERTEX)pV0)->texCoord[i].dvTV * TEX_SCALE);
  91. }
  92. }
  93. }
  94. if (m_StpCtx.uFlags & PRIMSF_DIFF_USED)
  95. {
  96. pSpan->uB = (UINT)RGBA_GETBLUE(m_StpCtx.pFlatVtx->dcColor) <<
  97. COLOR_SHIFT;
  98. pSpan->uG = (UINT)RGBA_GETGREEN(m_StpCtx.pFlatVtx->dcColor) <<
  99. COLOR_SHIFT;
  100. pSpan->uR = (UINT)RGBA_GETRED(m_StpCtx.pFlatVtx->dcColor) <<
  101. COLOR_SHIFT;
  102. pSpan->uA = (UINT)RGBA_GETALPHA(m_StpCtx.pFlatVtx->dcColor) <<
  103. COLOR_SHIFT;
  104. }
  105. else if (m_StpCtx.uFlags & PRIMSF_DIDX_USED)
  106. {
  107. pSpan->iIdx = (INT32)CI_MASKALPHA(m_StpCtx.pFlatVtx->dcColor) <<
  108. INDEX_COLOR_FIXED_SHIFT;
  109. pSpan->iIdxA = (INT32)CI_GETALPHA(m_StpCtx.pFlatVtx->dcColor) <<
  110. INDEX_COLOR_SHIFT;
  111. }
  112. if (m_StpCtx.uFlags & PRIMSF_SPEC_USED)
  113. {
  114. pSpan->uBS = (UINT)RGBA_GETBLUE(m_StpCtx.pFlatVtx->dcSpecular) <<
  115. COLOR_SHIFT;
  116. pSpan->uGS = (UINT)RGBA_GETGREEN(m_StpCtx.pFlatVtx->dcSpecular) <<
  117. COLOR_SHIFT;
  118. pSpan->uRS = (UINT)RGBA_GETRED(m_StpCtx.pFlatVtx->dcSpecular) <<
  119. COLOR_SHIFT;
  120. }
  121. if (m_StpCtx.uFlags & PRIMSF_LOCAL_FOG_USED)
  122. {
  123. if (m_StpCtx.uFlags & PRIMSF_GLOBAL_FOG_USED)
  124. {
  125. // Make sure that fZ has been set.
  126. RSASSERT(m_StpCtx.uFlags & PRIMSF_Z_USED);
  127. pSpan->uFog = (UINT16)ComputeTableFog(m_StpCtx.pCtx->pdwRenderState, fZ);
  128. }
  129. else
  130. {
  131. pSpan->uFog = (UINT16)(
  132. FTOI((FLOAT)RGBA_GETALPHA(pV0->dcSpecular) *
  133. FOG_255_SCALE));
  134. }
  135. }
  136. }
  137. // Determine whether any of the given values are less than zero or greater
  138. // than one. Negative zero counts as less than zero so this check will
  139. // produce some false positives but that's OK.
  140. #define NEEDS_NORMALIZE1(fV0) \
  141. (ASUINT32(fV0) > INT32_FLOAT_ONE)
  142. //----------------------------------------------------------------------------
  143. //
  144. // PrimProcessor::NormalizePointRHW
  145. //
  146. // D3DTLVERTEX.dvRHW can be anything, but our internal structures only
  147. // allow for it being in the range [0, 1]. This function clamps
  148. // the RHW to the proper range.
  149. //
  150. //----------------------------------------------------------------------------
  151. void
  152. PrimProcessor::NormalizePointRHW(LPD3DTLVERTEX pV0)
  153. {
  154. // Save original value.
  155. m_dvV0RHW = pV0->dvRHW;
  156. // Produce a warning when a value is out of the desired range.
  157. #if DBG
  158. if (FLOAT_LTZ(pV0->dvRHW))
  159. {
  160. RSDPF(("Point RHW out of range %f,%f",
  161. pV0->dvRHW));
  162. }
  163. #endif
  164. if (pV0->dvRHW < NORMALIZED_RHW_MIN)
  165. {
  166. pV0->dvRHW = NORMALIZED_RHW_MIN;
  167. }
  168. else if (pV0->dvRHW > NORMALIZED_RHW_MAX)
  169. {
  170. pV0->dvRHW = NORMALIZED_RHW_MAX;
  171. }
  172. }
  173. //----------------------------------------------------------------------------
  174. //
  175. // PrimProcessor::Point
  176. //
  177. // Provides a point for processing.
  178. //
  179. //----------------------------------------------------------------------------
  180. HRESULT
  181. PrimProcessor::Point(LPD3DTLVERTEX pV0,
  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. #endif
  193. // Clear per-point flags.
  194. m_StpCtx.uFlags &= ~(PRIMF_ALL | PTF_ALL);
  195. RSDPFM((RSM_FLAGS, "m_uPpFlags: 0x%08X, m_StpCtx.uFlags: 0x%08X",
  196. m_uPpFlags, m_StpCtx.uFlags));
  197. // Round coordinates to integer.
  198. m_StpCtx.iX = IFLOORF(pV0->dvSX + g_fHalf);
  199. m_StpCtx.iY = IFLOORF(pV0->dvSY + g_fHalf);
  200. RSDPFM((RSM_POINTS, "Point\n"));
  201. RSDPFM((RSM_POINTS, " V0 (%f,%f,%f) (%d,%d)\n",
  202. pV0->dvSX, pV0->dvSY, pV0->dvSZ,
  203. m_StpCtx.iX, m_StpCtx.iY));
  204. // Clip test.
  205. if (m_StpCtx.iX < m_StpCtx.pCtx->Clip.left ||
  206. m_StpCtx.iX >= m_StpCtx.pCtx->Clip.right ||
  207. m_StpCtx.iY < m_StpCtx.pCtx->Clip.top ||
  208. m_StpCtx.iY >= m_StpCtx.pCtx->Clip.bottom)
  209. {
  210. return D3D_OK;
  211. }
  212. //
  213. // Fill out a one-pixel span for the point.
  214. // Since the prim deltas are irrelevant for the span,
  215. // the span is appended to whatever primitive happens
  216. // to be available in the buffer.
  217. //
  218. PD3DI_RASTSPAN pSpan;
  219. UINT cSpans = 1;
  220. hr = AppendPrim();
  221. if (hr != D3D_OK)
  222. {
  223. return hr;
  224. }
  225. hr = AllocSpans(&cSpans, &pSpan);
  226. if (hr != D3D_OK)
  227. {
  228. return hr;
  229. }
  230. m_StpCtx.pPrim->uSpans++;
  231. BOOL bNorm;
  232. // USED checks cannot be combined since TEX_USED is a multibit check.
  233. if ((m_StpCtx.uFlags & PRIMSF_TEX_USED) &&
  234. (m_StpCtx.uFlags & PRIMSF_PERSP_USED) &&
  235. (m_uPpFlags & PPF_NORMALIZE_RHW) &&
  236. NEEDS_NORMALIZE1(pV0->dvRHW))
  237. {
  238. NormalizePointRHW(pV0);
  239. bNorm = TRUE;
  240. }
  241. else
  242. {
  243. bNorm = FALSE;
  244. }
  245. // Remember flat color controlling vertex for setup, if flat shaded.
  246. if (m_StpCtx.uFlags & PRIMSF_FLAT_SHADED)
  247. {
  248. m_StpCtx.pFlatVtx = pFlatVtx;
  249. }
  250. else
  251. {
  252. m_StpCtx.pFlatVtx = pV0;
  253. }
  254. FillPointSpan(pV0, pSpan);
  255. if (bNorm)
  256. {
  257. pV0->dvRHW = m_dvV0RHW;
  258. }
  259. return D3D_OK;
  260. }