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.

302 lines
9.8 KiB

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