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.

314 lines
8.3 KiB

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