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.

309 lines
9.9 KiB

  1. //----------------------------------------------------------------------------
  2. //
  3. // primproc.cpp
  4. //
  5. // Miscellaneous PrimProcessor methods.
  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. //----------------------------------------------------------------------------
  20. //
  21. // PrimProcessor::BeginPrimSet
  22. //
  23. // Marks the start of a set of primitives that have the same vertex type.
  24. // Computes attributes used from the current state and the vertex type.
  25. //
  26. //----------------------------------------------------------------------------
  27. void
  28. PrimProcessor::BeginPrimSet(D3DPRIMITIVETYPE PrimType,
  29. RAST_VERTEX_TYPE VertType)
  30. {
  31. // If state hasn't changed and the primitive and vertex types match the
  32. // ones we're already set up for there's no work to do.
  33. if ((m_uPpFlags & PPF_STATE_CHANGED) == 0 &&
  34. VertType == m_VertType &&
  35. PrimType == m_PrimType)
  36. {
  37. return;
  38. }
  39. m_StpCtx.uFlags &= ~PRIMSF_ALL;
  40. if (m_StpCtx.pCtx->pdwRenderState[D3DRS_ZENABLE] ||
  41. m_StpCtx.pCtx->pdwRenderState[D3DRS_ZWRITEENABLE] ||
  42. m_StpCtx.pCtx->pdwRenderState[D3DRS_STENCILENABLE])
  43. {
  44. m_StpCtx.uFlags |= PRIMSF_Z_USED;
  45. }
  46. /*if (m_StpCtx.pCtx->BeadSet == D3DIBS_RAMP)
  47. {
  48. // Index is unused during copy mode texturing.
  49. if (m_StpCtx.pCtx->pdwRenderState
  50. [D3DRENDERSTATE_TEXTUREMAPBLEND] != D3DTBLEND_COPY ||
  51. m_StpCtx.pCtx->cActTex == 0)
  52. {
  53. m_StpCtx.uFlags |= PRIMSF_DIDX_USED;
  54. }
  55. }
  56. else */
  57. {
  58. // ATTENTION - Don't set these for copy mode texture? Is
  59. // copy mode texture meaningful in RGB?
  60. m_StpCtx.uFlags |= PRIMSF_DIFF_USED;
  61. if (m_StpCtx.pCtx->pdwRenderState[D3DRS_SPECULARENABLE])
  62. {
  63. m_StpCtx.uFlags |= PRIMSF_SPEC_USED;
  64. }
  65. }
  66. if (m_StpCtx.pCtx->pdwRenderState[D3DRS_SHADEMODE] ==
  67. D3DSHADE_FLAT)
  68. {
  69. m_StpCtx.uFlags |= PRIMSF_FLAT_SHADED;
  70. }
  71. if (m_StpCtx.pCtx->cActTex > 0)
  72. {
  73. m_StpCtx.uFlags |= PRIMSF_TEX1_USED;
  74. if (m_StpCtx.pCtx->cActTex > 1)
  75. {
  76. m_StpCtx.uFlags |= PRIMSF_TEX2_USED;
  77. }
  78. }
  79. if ((m_StpCtx.uFlags & PRIMSF_TEX_USED) &&
  80. (true || m_StpCtx.pCtx->pdwRenderState[D3DRENDERSTATE_TEXTUREPERSPECTIVE]))
  81. {
  82. m_StpCtx.uFlags |= PRIMSF_PERSP_USED;
  83. }
  84. // Currently only tex1 can be mipmapped.
  85. if (((m_StpCtx.uFlags & PRIMSF_TEX1_USED) &&
  86. (PrimType == D3DPT_TRIANGLELIST ||
  87. PrimType == D3DPT_TRIANGLESTRIP ||
  88. PrimType == D3DPT_TRIANGLEFAN) &&
  89. (m_StpCtx.pCtx->pdwRenderState[D3DRS_FILLMODE]
  90. == D3DFILL_SOLID)) &&
  91. (((m_StpCtx.pCtx->pTexture[0]->cLOD >= 1) &&
  92. (m_StpCtx.pCtx->pTexture[0]->uMipFilter != D3DTFP_NONE)) ||
  93. // need LOD if we need to dynamically switch between different min
  94. // and mag filters
  95. (m_StpCtx.pCtx->pTexture[0]->uMinFilter !=
  96. m_StpCtx.pCtx->pTexture[0]->uMagFilter)))
  97. {
  98. m_StpCtx.uFlags |= PRIMSF_LOD_USED;
  99. }
  100. // select between min and mag filters for TEX2
  101. if (((m_StpCtx.uFlags & PRIMSF_TEX2_USED) &&
  102. (PrimType == D3DPT_TRIANGLELIST ||
  103. PrimType == D3DPT_TRIANGLESTRIP ||
  104. PrimType == D3DPT_TRIANGLEFAN) &&
  105. (m_StpCtx.pCtx->pdwRenderState[D3DRS_FILLMODE]
  106. == D3DFILL_SOLID)) &&
  107. (((m_StpCtx.pCtx->pTexture[1]->cLOD >= 1) &&
  108. (m_StpCtx.pCtx->pTexture[1]->uMipFilter != D3DTFP_NONE)) ||
  109. // need LOD if we need to dynamically switch between different min
  110. // and mag filters
  111. (m_StpCtx.pCtx->pTexture[1]->uMinFilter !=
  112. m_StpCtx.pCtx->pTexture[1]->uMagFilter)))
  113. {
  114. m_StpCtx.uFlags |= PRIMSF_LOD_USED;
  115. }
  116. if (m_StpCtx.pCtx->pdwRenderState[D3DRS_FOGENABLE])
  117. {
  118. // Note, if PWL_FOG is ever brought back to life, enabling
  119. // PRIMSF_GLOBAL_FOG_USED with no Z buffer will not trivially work
  120. // if (m_StpCtx.uFlags & PRIMSF_Z_USED)
  121. {
  122. switch (m_StpCtx.pCtx->pdwRenderState[D3DRS_FOGTABLEMODE])
  123. {
  124. case D3DFOG_EXP:
  125. case D3DFOG_EXP2:
  126. case D3DFOG_LINEAR:
  127. m_StpCtx.uFlags |= PRIMSF_GLOBAL_FOG_USED;
  128. #ifndef PWL_FOG
  129. // The span routines don't support table fog directly.
  130. // Instead table fog is computed per vertex and used to
  131. // set up local fog.
  132. m_StpCtx.uFlags |= PRIMSF_LOCAL_FOG_USED;
  133. #endif
  134. break;
  135. default:
  136. m_StpCtx.uFlags |= PRIMSF_LOCAL_FOG_USED;
  137. break;
  138. }
  139. }
  140. }
  141. PFN_ADDATTRS *ppfnAddAttrsTable;
  142. PFN_ADDSCALEDATTRS *ppfnAddScaledAttrsTable;
  143. PFN_FILLSPANATTRS *ppfnFillSpanAttrsTable;
  144. if (m_StpCtx.pCtx->BeadSet == D3DIBS_RAMP)
  145. {
  146. // Ramp does not support multitexture.
  147. RSASSERT((m_StpCtx.uFlags & PRIMSF_TEX2_USED) == 0);
  148. RSASSERT((PRIMSF_TEX1_USED | PRIMSF_DIDX_USED) == 0x14);
  149. // Derive a function table index from bits 2 and 4 of usage
  150. // information.
  151. // An alternative method would be to use bits 0-4 and have the
  152. // ramp information in the top 16 entries, but splitting the
  153. // ramp and RGB tables is cleaner and decouples the table sizes.
  154. // Decoupling is useful since the ramp possibilities are much
  155. // more limited so its table can be smaller.
  156. m_iAttrFnIdx =
  157. ((m_StpCtx.uFlags & PRIMSF_TEX1_USED) >> 2) |
  158. ((m_StpCtx.uFlags & PRIMSF_DIDX_USED) >> 3);
  159. ppfnAddAttrsTable = g_pfnRampAddFloatAttrsTable;
  160. ppfnAddScaledAttrsTable = g_pfnRampAddScaledFloatAttrsTable;
  161. ppfnFillSpanAttrsTable = g_pfnRampFillSpanFloatAttrsTable;
  162. }
  163. else
  164. {
  165. RSASSERT((PRIMSF_DIFF_USED | PRIMSF_SPEC_USED | PRIMSF_TEX1_USED |
  166. PRIMSF_TEX2_USED) == 0xf);
  167. // Derive a function table index from the lower four bits of
  168. // usage information. The lower bits are deliberately chosen
  169. // to represent the more performance-sensitive cases while
  170. // the upper bits generally represent cases handled by generic
  171. // code.
  172. //
  173. // Even restricted to only four bits the index contains unimportant
  174. // and unreachable cases, such as specular without diffuse or
  175. // tex2 without tex1. Tables indexed must account for this.
  176. m_iAttrFnIdx = m_StpCtx.uFlags & (PRIMSF_DIFF_USED | PRIMSF_SPEC_USED |
  177. PRIMSF_TEX1_USED | PRIMSF_TEX2_USED);
  178. ppfnAddAttrsTable = g_pfnAddFloatAttrsTable;
  179. ppfnAddScaledAttrsTable = g_pfnAddScaledFloatAttrsTable;
  180. ppfnFillSpanAttrsTable = g_pfnFillSpanFloatAttrsTable;
  181. }
  182. //
  183. // These functions only depend on the index and so can be set here.
  184. // Other functions depend on per-triangle information and are set
  185. // later.
  186. //
  187. if ((m_StpCtx.uFlags & PRIMSF_SLOW_USED) != PRIMSF_Z_USED)
  188. {
  189. // If any slow attrs are on or Z is off use the general functions.
  190. m_StpCtx.pfnAddScaledAttrs = AddScaledFloatAttrs_Any_Either;
  191. #ifndef STEP_FIXED
  192. m_StpCtx.pfnAddAttrs = AddFloatAttrs_Any;
  193. m_StpCtx.pfnFillSpanAttrs = FillSpanFloatAttrs_Any_Either;
  194. #endif
  195. }
  196. else
  197. {
  198. m_StpCtx.pfnAddScaledAttrs =
  199. ppfnAddScaledAttrsTable[m_iAttrFnIdx];
  200. #ifndef STEP_FIXED
  201. m_StpCtx.pfnAddAttrs = ppfnAddAttrsTable[m_iAttrFnIdx];
  202. m_StpCtx.pfnFillSpanAttrs = ppfnFillSpanAttrsTable[m_iAttrFnIdx];
  203. #endif
  204. }
  205. // Attribute beads can be set here.
  206. PFN_SETUPTRIATTR *ppfnSlot;
  207. ppfnSlot = &m_StpCtx.pfnTriSetupFirstAttr;
  208. if (m_StpCtx.uFlags & PRIMSF_Z_USED)
  209. {
  210. if (m_StpCtx.pCtx->iZBitCount == 16)
  211. {
  212. *ppfnSlot = TriSetup_Z16;
  213. }
  214. else
  215. {
  216. *ppfnSlot = TriSetup_Z32;
  217. }
  218. ppfnSlot = &m_StpCtx.pfnTriSetupZEnd;
  219. }
  220. if (m_StpCtx.uFlags & PRIMSF_TEX1_USED)
  221. {
  222. if (m_StpCtx.uFlags & PRIMSF_PERSP_USED)
  223. {
  224. *ppfnSlot = TriSetup_Persp_Tex;
  225. }
  226. else
  227. {
  228. *ppfnSlot = TriSetup_Affine_Tex;
  229. }
  230. ppfnSlot = &m_StpCtx.pfnTriSetupTexEnd;
  231. }
  232. if (m_StpCtx.uFlags & PRIMSF_DIFF_USED)
  233. {
  234. if (m_StpCtx.uFlags & PRIMSF_FLAT_SHADED)
  235. {
  236. *ppfnSlot = TriSetup_DiffFlat;
  237. }
  238. else
  239. {
  240. *ppfnSlot = TriSetup_Diff;
  241. }
  242. ppfnSlot = &m_StpCtx.pfnTriSetupDiffEnd;
  243. }
  244. else if (m_StpCtx.uFlags & PRIMSF_DIDX_USED)
  245. {
  246. if (m_StpCtx.uFlags & PRIMSF_FLAT_SHADED)
  247. {
  248. *ppfnSlot = TriSetup_DIdxFlat;
  249. }
  250. else
  251. {
  252. *ppfnSlot = TriSetup_DIdx;
  253. }
  254. ppfnSlot = &m_StpCtx.pfnTriSetupDiffEnd;
  255. }
  256. if (m_StpCtx.uFlags & PRIMSF_SPEC_USED)
  257. {
  258. if (m_StpCtx.uFlags & PRIMSF_FLAT_SHADED)
  259. {
  260. *ppfnSlot = TriSetup_SpecFlat;
  261. }
  262. else
  263. {
  264. *ppfnSlot = TriSetup_Spec;
  265. }
  266. ppfnSlot = &m_StpCtx.pfnTriSetupSpecEnd;
  267. }
  268. if (m_StpCtx.uFlags & PRIMSF_LOCAL_FOG_USED)
  269. {
  270. *ppfnSlot = TriSetup_Fog;
  271. ppfnSlot = &m_StpCtx.pfnTriSetupFogEnd;
  272. }
  273. *ppfnSlot = TriSetup_End;
  274. // Remember the primitive and vertex type and clear the state change bit.
  275. m_PrimType = PrimType;
  276. m_VertType = VertType;
  277. m_uPpFlags &= ~PPF_STATE_CHANGED;
  278. }