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.

319 lines
10 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. DDASSERT((m_StpCtx.pCtx->pTexture[0]->uFlags & D3DI_SPANTEX_NON_POWER_OF_2) == 0);
  69. if (m_StpCtx.pCtx->cActTex > 1)
  70. {
  71. m_StpCtx.uFlags |= PRIMSF_TEX2_USED;
  72. DDASSERT((m_StpCtx.pCtx->pTexture[1]->uFlags & D3DI_SPANTEX_NON_POWER_OF_2) == 0);
  73. }
  74. }
  75. if ((m_StpCtx.uFlags & PRIMSF_TEX_USED) &&
  76. m_StpCtx.pCtx->pdwRenderState[D3DRENDERSTATE_TEXTUREPERSPECTIVE])
  77. {
  78. m_StpCtx.uFlags |= PRIMSF_PERSP_USED;
  79. }
  80. // Currently only tex1 can be mipmapped.
  81. if (((m_StpCtx.uFlags & PRIMSF_TEX1_USED) &&
  82. (PrimType == D3DPT_TRIANGLELIST ||
  83. PrimType == D3DPT_TRIANGLESTRIP ||
  84. PrimType == D3DPT_TRIANGLEFAN) &&
  85. (m_StpCtx.pCtx->pdwRenderState[D3DRENDERSTATE_FILLMODE]
  86. == D3DFILL_SOLID)) &&
  87. (((m_StpCtx.pCtx->pTexture[0]->cLOD >= 1) &&
  88. (m_StpCtx.pCtx->pTexture[0]->uMipFilter != D3DTFP_NONE)) ||
  89. // need LOD if we need to dynamically switch between different min
  90. // and mag filters
  91. (m_StpCtx.pCtx->pTexture[0]->uMinFilter !=
  92. m_StpCtx.pCtx->pTexture[0]->uMagFilter)))
  93. {
  94. m_StpCtx.uFlags |= PRIMSF_LOD_USED;
  95. }
  96. // select between min and mag filters for TEX2
  97. if (((m_StpCtx.uFlags & PRIMSF_TEX2_USED) &&
  98. (PrimType == D3DPT_TRIANGLELIST ||
  99. PrimType == D3DPT_TRIANGLESTRIP ||
  100. PrimType == D3DPT_TRIANGLEFAN) &&
  101. (m_StpCtx.pCtx->pdwRenderState[D3DRENDERSTATE_FILLMODE]
  102. == D3DFILL_SOLID)) &&
  103. (((m_StpCtx.pCtx->pTexture[1]->cLOD >= 1) &&
  104. (m_StpCtx.pCtx->pTexture[1]->uMipFilter != D3DTFP_NONE)) ||
  105. // need LOD if we need to dynamically switch between different min
  106. // and mag filters
  107. (m_StpCtx.pCtx->pTexture[1]->uMinFilter !=
  108. m_StpCtx.pCtx->pTexture[1]->uMagFilter)))
  109. {
  110. m_StpCtx.uFlags |= PRIMSF_LOD_USED;
  111. }
  112. if (m_StpCtx.pCtx->pdwRenderState[D3DRENDERSTATE_FOGENABLE])
  113. {
  114. // Note, if PWL_FOG is ever brought back to life, enabling
  115. // PRIMSF_GLOBAL_FOG_USED with no Z buffer will not trivially work
  116. // if (m_StpCtx.uFlags & PRIMSF_Z_USED)
  117. {
  118. switch (m_StpCtx.pCtx->pdwRenderState[D3DRENDERSTATE_FOGTABLEMODE])
  119. {
  120. case D3DFOG_EXP:
  121. case D3DFOG_EXP2:
  122. case D3DFOG_LINEAR:
  123. m_StpCtx.uFlags |= PRIMSF_GLOBAL_FOG_USED;
  124. #ifndef PWL_FOG
  125. // The span routines don't support table fog directly.
  126. // Instead table fog is computed per vertex and used to
  127. // set up local fog.
  128. m_StpCtx.uFlags |= PRIMSF_LOCAL_FOG_USED;
  129. #endif
  130. break;
  131. default:
  132. m_StpCtx.uFlags |= PRIMSF_LOCAL_FOG_USED;
  133. break;
  134. }
  135. }
  136. }
  137. PFN_ADDATTRS *ppfnAddAttrsTable;
  138. PFN_ADDSCALEDATTRS *ppfnAddScaledAttrsTable;
  139. PFN_FILLSPANATTRS *ppfnFillSpanAttrsTable;
  140. if (m_StpCtx.pCtx->BeadSet == D3DIBS_RAMP)
  141. {
  142. // Ramp does not support multitexture.
  143. RSASSERT((m_StpCtx.uFlags & PRIMSF_TEX2_USED) == 0);
  144. RSASSERT((PRIMSF_TEX1_USED | PRIMSF_DIDX_USED) == 0x14);
  145. // Derive a function table index from bits 2 and 4 of usage
  146. // information.
  147. // An alternative method would be to use bits 0-4 and have the
  148. // ramp information in the top 16 entries, but splitting the
  149. // ramp and RGB tables is cleaner and decouples the table sizes.
  150. // Decoupling is useful since the ramp possibilities are much
  151. // more limited so its table can be smaller.
  152. m_iAttrFnIdx =
  153. ((m_StpCtx.uFlags & PRIMSF_TEX1_USED) >> 2) |
  154. ((m_StpCtx.uFlags & PRIMSF_DIDX_USED) >> 3);
  155. ppfnAddAttrsTable = g_pfnRampAddFloatAttrsTable;
  156. ppfnAddScaledAttrsTable = g_pfnRampAddScaledFloatAttrsTable;
  157. ppfnFillSpanAttrsTable = g_pfnRampFillSpanFloatAttrsTable;
  158. }
  159. else
  160. {
  161. RSASSERT((PRIMSF_DIFF_USED | PRIMSF_SPEC_USED | PRIMSF_TEX1_USED |
  162. PRIMSF_TEX2_USED) == 0xf);
  163. // Derive a function table index from the lower four bits of
  164. // usage information. The lower bits are deliberately chosen
  165. // to represent the more performance-sensitive cases while
  166. // the upper bits generally represent cases handled by generic
  167. // code.
  168. //
  169. // Even restricted to only four bits the index contains unimportant
  170. // and unreachable cases, such as specular without diffuse or
  171. // tex2 without tex1. Tables indexed must account for this.
  172. m_iAttrFnIdx = m_StpCtx.uFlags & (PRIMSF_DIFF_USED | PRIMSF_SPEC_USED |
  173. PRIMSF_TEX1_USED | PRIMSF_TEX2_USED);
  174. ppfnAddAttrsTable = g_pfnAddFloatAttrsTable;
  175. ppfnAddScaledAttrsTable = g_pfnAddScaledFloatAttrsTable;
  176. ppfnFillSpanAttrsTable = g_pfnFillSpanFloatAttrsTable;
  177. }
  178. //
  179. // These functions only depend on the index and so can be set here.
  180. // Other functions depend on per-triangle information and are set
  181. // later.
  182. //
  183. if ((m_StpCtx.uFlags & PRIMSF_SLOW_USED) != PRIMSF_Z_USED)
  184. {
  185. // If any slow attrs are on or Z is off use the general functions.
  186. m_StpCtx.pfnAddScaledAttrs = AddScaledFloatAttrs_Any_Either;
  187. #ifndef STEP_FIXED
  188. m_StpCtx.pfnAddAttrs = AddFloatAttrs_Any;
  189. m_StpCtx.pfnFillSpanAttrs = FillSpanFloatAttrs_Any_Either;
  190. #endif
  191. }
  192. else
  193. {
  194. m_StpCtx.pfnAddScaledAttrs =
  195. ppfnAddScaledAttrsTable[m_iAttrFnIdx];
  196. #ifndef STEP_FIXED
  197. m_StpCtx.pfnAddAttrs = ppfnAddAttrsTable[m_iAttrFnIdx];
  198. m_StpCtx.pfnFillSpanAttrs = ppfnFillSpanAttrsTable[m_iAttrFnIdx];
  199. #endif
  200. }
  201. // Attribute beads can be set here.
  202. PFN_SETUPTRIATTR *ppfnSlot;
  203. ppfnSlot = &m_StpCtx.pfnTriSetupFirstAttr;
  204. if (m_StpCtx.uFlags & PRIMSF_Z_USED)
  205. {
  206. if (m_StpCtx.pCtx->iZBitCount == 16)
  207. {
  208. *ppfnSlot = TriSetup_Z16;
  209. }
  210. else
  211. {
  212. *ppfnSlot = TriSetup_Z32;
  213. }
  214. ppfnSlot = &m_StpCtx.pfnTriSetupZEnd;
  215. }
  216. if (m_StpCtx.uFlags & PRIMSF_TEX1_USED)
  217. {
  218. if (m_StpCtx.uFlags & PRIMSF_PERSP_USED)
  219. {
  220. *ppfnSlot = TriSetup_Persp_Tex1;
  221. }
  222. else
  223. {
  224. *ppfnSlot = TriSetup_Affine_Tex1;
  225. }
  226. ppfnSlot = &m_StpCtx.pfnTriSetupTex1End;
  227. }
  228. if (m_StpCtx.uFlags & PRIMSF_TEX2_USED)
  229. {
  230. // Code assumes that tex1 is enabled if tex2 is enabled.
  231. RSASSERT(m_StpCtx.uFlags & PRIMSF_TEX1_USED);
  232. if (m_StpCtx.uFlags & PRIMSF_PERSP_USED)
  233. {
  234. *ppfnSlot = TriSetup_Persp_Tex2;
  235. }
  236. else
  237. {
  238. *ppfnSlot = TriSetup_Affine_Tex2;
  239. }
  240. ppfnSlot = &m_StpCtx.pfnTriSetupTex2End;
  241. }
  242. if (m_StpCtx.uFlags & PRIMSF_DIFF_USED)
  243. {
  244. if (m_StpCtx.uFlags & PRIMSF_FLAT_SHADED)
  245. {
  246. *ppfnSlot = TriSetup_DiffFlat;
  247. }
  248. else
  249. {
  250. *ppfnSlot = TriSetup_Diff;
  251. }
  252. ppfnSlot = &m_StpCtx.pfnTriSetupDiffEnd;
  253. }
  254. else if (m_StpCtx.uFlags & PRIMSF_DIDX_USED)
  255. {
  256. if (m_StpCtx.uFlags & PRIMSF_FLAT_SHADED)
  257. {
  258. *ppfnSlot = TriSetup_DIdxFlat;
  259. }
  260. else
  261. {
  262. *ppfnSlot = TriSetup_DIdx;
  263. }
  264. ppfnSlot = &m_StpCtx.pfnTriSetupDiffEnd;
  265. }
  266. if (m_StpCtx.uFlags & PRIMSF_SPEC_USED)
  267. {
  268. if (m_StpCtx.uFlags & PRIMSF_FLAT_SHADED)
  269. {
  270. *ppfnSlot = TriSetup_SpecFlat;
  271. }
  272. else
  273. {
  274. *ppfnSlot = TriSetup_Spec;
  275. }
  276. ppfnSlot = &m_StpCtx.pfnTriSetupSpecEnd;
  277. }
  278. if (m_StpCtx.uFlags & PRIMSF_LOCAL_FOG_USED)
  279. {
  280. *ppfnSlot = TriSetup_Fog;
  281. ppfnSlot = &m_StpCtx.pfnTriSetupFogEnd;
  282. }
  283. *ppfnSlot = TriSetup_End;
  284. // Remember the primitive and vertex type and clear the state change bit.
  285. m_PrimType = PrimType;
  286. m_VertType = VertType;
  287. m_uPpFlags &= ~PPF_STATE_CHANGED;
  288. }