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.

970 lines
36 KiB

  1. /*============================ ==============================================;
  2. *
  3. * Copyright (C) 1998 Microsoft Corporation. All Rights Reserved.
  4. *
  5. * File: pvvid.mcp
  6. * Content: The implementation of the geometry inner loop
  7. *
  8. ***************************************************************************/
  9. #include "pch.cpp"
  10. #pragma hdrstop
  11. #include "light.h"
  12. #include "clipper.h"
  13. #include "pvvid.h"
  14. include(`pvvid.mh') dnl
  15. #ifdef DEBUG_PIPELINE
  16. DWORD g_DebugFlags = 0;
  17. #endif // DEBUG_PIPELINE
  18. //-----------------------------------------------------------------------------
  19. // Input:
  20. // v - input vertex in the model space
  21. // pCoord - vertex, transformed to the camera space
  22. // pWeights- vertex weights
  23. // Output:
  24. // Alpha component of pv->lighting.outSpecular is set
  25. //
  26. void ComputeFog(LPD3DFE_PROCESSVERTICES pv, D3DVECTOR &v, D3DVECTOR* pCoord,
  27. D3DVALUE* pWeights, BYTE* pMatrixIndices)
  28. {
  29. D3DVALUE dist;
  30. // Vertex is already transformed to the camera space
  31. if (pv->dwDeviceFlags & D3DDEV_RANGEBASEDFOG)
  32. dist = SQRTF(pCoord->x*pCoord->x +
  33. pCoord->y*pCoord->y +
  34. pCoord->z*pCoord->z);
  35. else
  36. dist = ABSF(pCoord->z);
  37. ComputeFogFactor(pv, dist, &pv->lighting.outSpecular);
  38. }
  39. //---------------------------------------------------------------------
  40. // Transform 1-dimensional texture
  41. //
  42. void TransformTexture1_1Loop(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m,
  43. DWORD dwCount,
  44. DWORD dwInpStride,
  45. DWORD dwOutStride)
  46. {
  47. for (; dwCount; dwCount--)
  48. {
  49. pOut[0] = pIn[0] * m->_11 + m->_21;
  50. pIn = (D3DVALUE*)((BYTE*)pIn + dwInpStride);
  51. pOut = (D3DVALUE*)((BYTE*)pOut + dwOutStride);
  52. }
  53. }
  54. //---------------------------------------------------------------------
  55. // Transform 1-dimensional texture. Output 2 texture coordinates
  56. //
  57. void TransformTexture1_2Loop(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m,
  58. DWORD dwCount,
  59. DWORD dwInpStride,
  60. DWORD dwOutStride)
  61. {
  62. for (; dwCount; dwCount--)
  63. {
  64. pOut[0] = pIn[0] * m->_11 + m->_21;
  65. pOut[1] = pIn[0] * m->_12 + m->_22;
  66. pIn = (D3DVALUE*)((BYTE*)pIn + dwInpStride);
  67. pOut = (D3DVALUE*)((BYTE*)pOut + dwOutStride);
  68. }
  69. }
  70. //---------------------------------------------------------------------
  71. // Transform 1-dimensional texture. Output 3 texture coordinates
  72. //
  73. void TransformTexture1_3Loop(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m,
  74. DWORD dwCount,
  75. DWORD dwInpStride,
  76. DWORD dwOutStride)
  77. {
  78. for (; dwCount; dwCount--)
  79. {
  80. pOut[0] = pIn[0] * m->_11 + m->_21;
  81. pOut[1] = pIn[0] * m->_12 + m->_22;
  82. pOut[2] = pIn[0] * m->_13 + m->_23;
  83. pIn = (D3DVALUE*)((BYTE*)pIn + dwInpStride);
  84. pOut = (D3DVALUE*)((BYTE*)pOut + dwOutStride);
  85. }
  86. }
  87. //---------------------------------------------------------------------
  88. // Transform 1-dimensional texture. Output 4 texture coordinates
  89. //
  90. void TransformTexture1_4Loop(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m,
  91. DWORD dwCount,
  92. DWORD dwInpStride,
  93. DWORD dwOutStride)
  94. {
  95. for (; dwCount; dwCount--)
  96. {
  97. pOut[0] = pIn[0] * m->_11 + m->_21;
  98. pOut[1] = pIn[0] * m->_12 + m->_22;
  99. pOut[2] = pIn[0] * m->_13 + m->_23;
  100. pOut[3] = pIn[0] * m->_14 + m->_24;
  101. pIn = (D3DVALUE*)((BYTE*)pIn + dwInpStride);
  102. pOut = (D3DVALUE*)((BYTE*)pOut + dwOutStride);
  103. }
  104. }
  105. //---------------------------------------------------------------------
  106. // Transform 2-dimensional texture
  107. //
  108. void TransformTexture2_2Loop(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m,
  109. DWORD dwCount,
  110. DWORD dwInpStride,
  111. DWORD dwOutStride)
  112. {
  113. for (; dwCount; dwCount--)
  114. {
  115. pOut[0] = pIn[0] * m->_11 + pIn[1] * m->_21 + m->_31;
  116. pOut[1] = pIn[0] * m->_12 + pIn[1] * m->_22 + m->_32;
  117. pIn = (D3DVALUE*)((BYTE*)pIn + dwInpStride);
  118. pOut = (D3DVALUE*)((BYTE*)pOut + dwOutStride);
  119. }
  120. }
  121. //---------------------------------------------------------------------
  122. // Transform 2-dimensional texture. Output 1 texture coordinate
  123. //
  124. void TransformTexture2_1Loop(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m,
  125. DWORD dwCount,
  126. DWORD dwInpStride,
  127. DWORD dwOutStride)
  128. {
  129. for (; dwCount; dwCount--)
  130. {
  131. pOut[0] = pIn[0] * m->_11 + pIn[1] * m->_21 + m->_31;
  132. pIn = (D3DVALUE*)((BYTE*)pIn + dwInpStride);
  133. pOut = (D3DVALUE*)((BYTE*)pOut + dwOutStride);
  134. }
  135. }
  136. //---------------------------------------------------------------------
  137. // Transform 2-dimensional texture. Output 3 texture coordinate
  138. //
  139. void TransformTexture2_3Loop(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m,
  140. DWORD dwCount,
  141. DWORD dwInpStride,
  142. DWORD dwOutStride)
  143. {
  144. for (; dwCount; dwCount--)
  145. {
  146. pOut[0] = pIn[0] * m->_11 + pIn[1] * m->_21 + m->_31;
  147. pOut[1] = pIn[0] * m->_12 + pIn[1] * m->_22 + m->_32;
  148. pOut[2] = pIn[0] * m->_13 + pIn[1] * m->_23 + m->_33;
  149. pIn = (D3DVALUE*)((BYTE*)pIn + dwInpStride);
  150. pOut = (D3DVALUE*)((BYTE*)pOut + dwOutStride);
  151. }
  152. }
  153. //---------------------------------------------------------------------
  154. // Transform 2-dimensional texture. Output 4 texture coordinate
  155. //
  156. void TransformTexture2_4Loop(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m,
  157. DWORD dwCount,
  158. DWORD dwInpStride,
  159. DWORD dwOutStride)
  160. {
  161. for (; dwCount; dwCount--)
  162. {
  163. pOut[0] = pIn[0] * m->_11 + pIn[1] * m->_21 + m->_31;
  164. pOut[1] = pIn[0] * m->_12 + pIn[1] * m->_22 + m->_32;
  165. pOut[2] = pIn[0] * m->_13 + pIn[1] * m->_23 + m->_33;
  166. pOut[3] = pIn[0] * m->_14 + pIn[1] * m->_24 + m->_34;
  167. pIn = (D3DVALUE*)((BYTE*)pIn + dwInpStride);
  168. pOut = (D3DVALUE*)((BYTE*)pOut + dwOutStride);
  169. }
  170. }
  171. //---------------------------------------------------------------------
  172. // Transform 3-dimensional texture
  173. //
  174. void TransformTexture3_3Loop(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m,
  175. DWORD dwCount,
  176. DWORD dwInpStride,
  177. DWORD dwOutStride)
  178. {
  179. for (; dwCount; dwCount--)
  180. {
  181. pOut[0] = pIn[0] * m->_11 + pIn[1] * m->_21 + pIn[2] * m->_31 + m->_41;
  182. pOut[1] = pIn[0] * m->_12 + pIn[1] * m->_22 + pIn[2] * m->_32 + m->_42;
  183. pOut[2] = pIn[0] * m->_13 + pIn[1] * m->_23 + pIn[2] * m->_33 + m->_43;
  184. pIn = (D3DVALUE*)((BYTE*)pIn + dwInpStride);
  185. pOut = (D3DVALUE*)((BYTE*)pOut + dwOutStride);
  186. }
  187. }
  188. //---------------------------------------------------------------------
  189. // Transform 3-dimensional texture. Output 1 texture coordinate
  190. //
  191. void TransformTexture3_1Loop(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m,
  192. DWORD dwCount,
  193. DWORD dwInpStride,
  194. DWORD dwOutStride)
  195. {
  196. for (; dwCount; dwCount--)
  197. {
  198. pOut[0] = pIn[0] * m->_11 + pIn[1] * m->_21 + pIn[2] * m->_31 + m->_41;
  199. pIn = (D3DVALUE*)((BYTE*)pIn + dwInpStride);
  200. pOut = (D3DVALUE*)((BYTE*)pOut + dwOutStride);
  201. }
  202. }
  203. //---------------------------------------------------------------------
  204. // Transform 3-dimensional texture. Output 2 texture coordinates
  205. //
  206. void TransformTexture3_2Loop(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m,
  207. DWORD dwCount,
  208. DWORD dwInpStride,
  209. DWORD dwOutStride)
  210. {
  211. for (; dwCount; dwCount--)
  212. {
  213. pOut[0] = pIn[0] * m->_11 + pIn[1] * m->_21 + pIn[2] * m->_31 + m->_41;
  214. pOut[1] = pIn[0] * m->_12 + pIn[1] * m->_22 + pIn[2] * m->_32 + m->_42;
  215. pIn = (D3DVALUE*)((BYTE*)pIn + dwInpStride);
  216. pOut = (D3DVALUE*)((BYTE*)pOut + dwOutStride);
  217. }
  218. }
  219. //---------------------------------------------------------------------
  220. // Transform 3-dimensional texture. Output 4 texture coordinates
  221. //
  222. void TransformTexture3_4Loop(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m,
  223. DWORD dwCount,
  224. DWORD dwInpStride,
  225. DWORD dwOutStride)
  226. {
  227. for (; dwCount; dwCount--)
  228. {
  229. pOut[0] = pIn[0] * m->_11 + pIn[1] * m->_21 + pIn[2] * m->_31 + m->_41;
  230. pOut[1] = pIn[0] * m->_12 + pIn[1] * m->_22 + pIn[2] * m->_32 + m->_42;
  231. pOut[2] = pIn[0] * m->_13 + pIn[1] * m->_23 + pIn[2] * m->_33 + m->_43;
  232. pOut[3] = pIn[0] * m->_14 + pIn[1] * m->_24 + pIn[2] * m->_34 + m->_44;
  233. pIn = (D3DVALUE*)((BYTE*)pIn + dwInpStride);
  234. pOut = (D3DVALUE*)((BYTE*)pOut + dwOutStride);
  235. }
  236. }
  237. //---------------------------------------------------------------------
  238. // Transform 4-dimensional texture
  239. //
  240. void TransformTexture4_4Loop(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m,
  241. DWORD dwCount,
  242. DWORD dwInpStride,
  243. DWORD dwOutStride)
  244. {
  245. for (; dwCount; dwCount--)
  246. {
  247. pOut[0] = pIn[0] * m->_11 + pIn[1] * m->_21 + pIn[2] * m->_31 + pIn[3] * m->_41;
  248. pOut[1] = pIn[0] * m->_12 + pIn[1] * m->_22 + pIn[2] * m->_32 + pIn[3] * m->_42;
  249. pOut[2] = pIn[0] * m->_13 + pIn[1] * m->_23 + pIn[2] * m->_33 + pIn[3] * m->_43;
  250. pOut[3] = pIn[0] * m->_14 + pIn[1] * m->_24 + pIn[2] * m->_34 + pIn[3] * m->_44;
  251. pIn = (D3DVALUE*)((BYTE*)pIn + dwInpStride);
  252. pOut = (D3DVALUE*)((BYTE*)pOut + dwOutStride);
  253. }
  254. }
  255. //---------------------------------------------------------------------
  256. // Transform 4-dimensional texture. Output 1 texture coordinate
  257. //
  258. void TransformTexture4_1Loop(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m,
  259. DWORD dwCount,
  260. DWORD dwInpStride,
  261. DWORD dwOutStride)
  262. {
  263. for (; dwCount; dwCount--)
  264. {
  265. pOut[0] = pIn[0] * m->_11 + pIn[1] * m->_21 + pIn[2] * m->_31 + pIn[3] * m->_41;
  266. pIn = (D3DVALUE*)((BYTE*)pIn + dwInpStride);
  267. pOut = (D3DVALUE*)((BYTE*)pOut + dwOutStride);
  268. }
  269. }
  270. //---------------------------------------------------------------------
  271. // Transform 4-dimensional texture. Output 2 texture coordinates
  272. //
  273. void TransformTexture4_2Loop(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m,
  274. DWORD dwCount,
  275. DWORD dwInpStride,
  276. DWORD dwOutStride)
  277. {
  278. for (; dwCount; dwCount--)
  279. {
  280. pOut[0] = pIn[0] * m->_11 + pIn[1] * m->_21 + pIn[2] * m->_31 + pIn[3] * m->_41;
  281. pOut[1] = pIn[0] * m->_12 + pIn[1] * m->_22 + pIn[2] * m->_32 + pIn[3] * m->_42;
  282. pIn = (D3DVALUE*)((BYTE*)pIn + dwInpStride);
  283. pOut = (D3DVALUE*)((BYTE*)pOut + dwOutStride);
  284. }
  285. }
  286. //---------------------------------------------------------------------
  287. // Transform 4-dimensional texture. Output 3 texture coordinates
  288. //
  289. void TransformTexture4_3Loop(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m,
  290. DWORD dwCount,
  291. DWORD dwInpStride,
  292. DWORD dwOutStride)
  293. {
  294. for (; dwCount; dwCount--)
  295. {
  296. pOut[0] = pIn[0] * m->_11 + pIn[1] * m->_21 + pIn[2] * m->_31 + pIn[3] * m->_41;
  297. pOut[1] = pIn[0] * m->_12 + pIn[1] * m->_22 + pIn[2] * m->_32 + pIn[3] * m->_42;
  298. pOut[2] = pIn[0] * m->_13 + pIn[1] * m->_23 + pIn[2] * m->_33 + pIn[3] * m->_43;
  299. pIn = (D3DVALUE*)((BYTE*)pIn + dwInpStride);
  300. pOut = (D3DVALUE*)((BYTE*)pOut + dwOutStride);
  301. }
  302. }
  303. //---------------------------------------------------------------------
  304. // Transform 1-dimensional texture.
  305. //
  306. void TransformTexture1_1(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m)
  307. {
  308. pOut[0] = pIn[0] * m->_11 + m->_21;
  309. }
  310. //---------------------------------------------------------------------
  311. // Transform 1-dimensional texture. Output 2 texture coordinates
  312. //
  313. void TransformTexture1_2(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m)
  314. {
  315. pOut[0] = pIn[0] * m->_11 + m->_21;
  316. pOut[1] = pIn[0] * m->_12 + m->_22;
  317. }
  318. //---------------------------------------------------------------------
  319. // Transform 1-dimensional texture. Output 3 texture coordinates
  320. //
  321. void TransformTexture1_3(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m)
  322. {
  323. pOut[0] = pIn[0] * m->_11 + m->_21;
  324. pOut[1] = pIn[0] * m->_12 + m->_22;
  325. pOut[2] = pIn[0] * m->_13 + m->_23;
  326. }
  327. //---------------------------------------------------------------------
  328. // Transform 1-dimensional texture. Output 4 texture coordinates
  329. //
  330. void TransformTexture1_4(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m)
  331. {
  332. pOut[0] = pIn[0] * m->_11 + m->_21;
  333. pOut[1] = pIn[0] * m->_12 + m->_22;
  334. pOut[2] = pIn[0] * m->_13 + m->_23;
  335. pOut[3] = pIn[0] * m->_14 + m->_24;
  336. }
  337. //---------------------------------------------------------------------
  338. // Transform 2-dimensional texture
  339. //
  340. void TransformTexture2_2(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m)
  341. {
  342. pOut[0] = pIn[0] * m->_11 + pIn[1] * m->_21 + m->_31;
  343. pOut[1] = pIn[0] * m->_12 + pIn[1] * m->_22 + m->_32;
  344. }
  345. //---------------------------------------------------------------------
  346. // Transform 2-dimensional texture. Output 1 texture coordinate
  347. //
  348. void TransformTexture2_1(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m)
  349. {
  350. pOut[0] = pIn[0] * m->_11 + pIn[1] * m->_21 + m->_31;
  351. }
  352. //---------------------------------------------------------------------
  353. // Transform 2-dimensional texture. Output 3 texture coordinates
  354. //
  355. void TransformTexture2_3(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m)
  356. {
  357. pOut[0] = pIn[0] * m->_11 + pIn[1] * m->_21 + m->_31;
  358. pOut[1] = pIn[0] * m->_12 + pIn[1] * m->_22 + m->_32;
  359. pOut[2] = pIn[0] * m->_13 + pIn[1] * m->_23 + m->_33;
  360. }
  361. //---------------------------------------------------------------------
  362. // Transform 2-dimensional texture. Output 4 texture coordinates
  363. //
  364. void TransformTexture2_4(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m)
  365. {
  366. pOut[0] = pIn[0] * m->_11 + pIn[1] * m->_21 + m->_31;
  367. pOut[1] = pIn[0] * m->_12 + pIn[1] * m->_22 + m->_32;
  368. pOut[2] = pIn[0] * m->_13 + pIn[1] * m->_23 + m->_33;
  369. pOut[3] = pIn[0] * m->_14 + pIn[1] * m->_24 + m->_34;
  370. }
  371. //---------------------------------------------------------------------
  372. // Transform 3-dimensional texture. Output 3 texture coordinates
  373. //
  374. void TransformTexture3_3(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m)
  375. {
  376. pOut[0] = pIn[0] * m->_11 + pIn[1] * m->_21 + pIn[2] * m->_31 + m->_41;
  377. pOut[1] = pIn[0] * m->_12 + pIn[1] * m->_22 + pIn[2] * m->_32 + m->_42;
  378. pOut[2] = pIn[0] * m->_13 + pIn[1] * m->_23 + pIn[2] * m->_33 + m->_43;
  379. }
  380. //---------------------------------------------------------------------
  381. // Transform 3-dimensional texture. Output 1 texture coordinates
  382. //
  383. void TransformTexture3_1(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m)
  384. {
  385. pOut[0] = pIn[0] * m->_11 + pIn[1] * m->_21 + pIn[2] * m->_31 + m->_41;
  386. }
  387. //---------------------------------------------------------------------
  388. // Transform 3-dimensional texture. Output 2 texture coordinates
  389. //
  390. void TransformTexture3_2(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m)
  391. {
  392. pOut[0] = pIn[0] * m->_11 + pIn[1] * m->_21 + pIn[2] * m->_31 + m->_41;
  393. pOut[1] = pIn[0] * m->_12 + pIn[1] * m->_22 + pIn[2] * m->_32 + m->_42;
  394. }
  395. //---------------------------------------------------------------------
  396. // Transform 3-dimensional texture. Output 4 texture coordinates
  397. //
  398. void TransformTexture3_4(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m)
  399. {
  400. pOut[0] = pIn[0] * m->_11 + pIn[1] * m->_21 + pIn[2] * m->_31 + m->_41;
  401. pOut[1] = pIn[0] * m->_12 + pIn[1] * m->_22 + pIn[2] * m->_32 + m->_42;
  402. pOut[2] = pIn[0] * m->_13 + pIn[1] * m->_23 + pIn[2] * m->_33 + m->_43;
  403. pOut[3] = pIn[0] * m->_14 + pIn[1] * m->_24 + pIn[2] * m->_34 + m->_44;
  404. }
  405. //---------------------------------------------------------------------
  406. // Transform 4-dimensional texture. Output 4 texture coordinates
  407. //
  408. void TransformTexture4_4(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m)
  409. {
  410. pOut[0] = pIn[0] * m->_11 + pIn[1] * m->_21 + pIn[2] * m->_31 + pIn[3] * m->_41;
  411. pOut[1] = pIn[0] * m->_12 + pIn[1] * m->_22 + pIn[2] * m->_32 + pIn[3] * m->_42;
  412. pOut[2] = pIn[0] * m->_13 + pIn[1] * m->_23 + pIn[2] * m->_33 + pIn[3] * m->_43;
  413. pOut[3] = pIn[0] * m->_14 + pIn[1] * m->_24 + pIn[2] * m->_34 + pIn[3] * m->_44;
  414. }
  415. //---------------------------------------------------------------------
  416. // Transform 4-dimensional texture. Output 1 texture coordinates
  417. //
  418. void TransformTexture4_1(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m)
  419. {
  420. pOut[0] = pIn[0] * m->_11 + pIn[1] * m->_21 + pIn[2] * m->_31 + pIn[3] * m->_41;
  421. }
  422. //---------------------------------------------------------------------
  423. // Transform 4-dimensional texture. Output 2 texture coordinates
  424. //
  425. void TransformTexture4_2(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m)
  426. {
  427. pOut[0] = pIn[0] * m->_11 + pIn[1] * m->_21 + pIn[2] * m->_31 + pIn[3] * m->_41;
  428. pOut[1] = pIn[0] * m->_12 + pIn[1] * m->_22 + pIn[2] * m->_32 + pIn[3] * m->_42;
  429. }
  430. //---------------------------------------------------------------------
  431. // Transform 4-dimensional texture. Output 3 texture coordinates
  432. //
  433. void TransformTexture4_3(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m)
  434. {
  435. pOut[0] = pIn[0] * m->_11 + pIn[1] * m->_21 + pIn[2] * m->_31 + pIn[3] * m->_41;
  436. pOut[1] = pIn[0] * m->_12 + pIn[1] * m->_22 + pIn[2] * m->_32 + pIn[3] * m->_42;
  437. pOut[2] = pIn[0] * m->_13 + pIn[1] * m->_23 + pIn[2] * m->_33 + pIn[3] * m->_43;
  438. }
  439. //---------------------------------------------------------------------
  440. // Index is:
  441. // bits 0-1 - (number of input texture coordinates - 1)
  442. // bits 2-3 - (number of output texture coordinates - 1)
  443. //
  444. PFN_TEXTURETRANSFORM g_pfnTextureTransform[16] =
  445. {
  446. TransformTexture1_1,
  447. TransformTexture2_1,
  448. TransformTexture3_1,
  449. TransformTexture4_1,
  450. TransformTexture1_2,
  451. TransformTexture2_2,
  452. TransformTexture3_2,
  453. TransformTexture4_2,
  454. TransformTexture1_3,
  455. TransformTexture2_3,
  456. TransformTexture3_3,
  457. TransformTexture4_3,
  458. TransformTexture1_4,
  459. TransformTexture2_4,
  460. TransformTexture3_4,
  461. TransformTexture4_4
  462. };
  463. //---------------------------------------------------------------------
  464. PFN_TEXTURETRANSFORMLOOP g_pfnTextureTransformLoop[16] =
  465. {
  466. TransformTexture1_1Loop,
  467. TransformTexture2_1Loop,
  468. TransformTexture3_1Loop,
  469. TransformTexture4_1Loop,
  470. TransformTexture1_2Loop,
  471. TransformTexture2_2Loop,
  472. TransformTexture3_2Loop,
  473. TransformTexture4_2Loop,
  474. TransformTexture1_3Loop,
  475. TransformTexture2_3Loop,
  476. TransformTexture3_3Loop,
  477. TransformTexture4_3Loop,
  478. TransformTexture1_4Loop,
  479. TransformTexture2_4Loop,
  480. TransformTexture3_4Loop,
  481. TransformTexture4_4Loop
  482. };
  483. //---------------------------------------------------------------------
  484. // This function should be called every time FVF ID is changed
  485. // All pv flags, input and output FVF id should be set before calling the
  486. // function.
  487. static DWORD POSITION_SIZE[16] =
  488. {
  489. 0, 0, 3*4, 0, 4*4, 0, 4*4, 0, 5*4, 0, 6*4, 0, 7*4, 0, 8*4, 0
  490. };
  491. //---------------------------------------------------------------------
  492. void SetupStrides(D3DFE_PROCESSVERTICES* pv, UINT stride)
  493. {
  494. pv->position.dwStride = stride;
  495. pv->weights.dwStride =
  496. pv->normal.dwStride =
  497. pv->diffuse.dwStride =
  498. pv->specular.dwStride =
  499. pv->psize.dwStride =
  500. pv->matrixIndices.dwStride = stride;
  501. pv->textures[0].dwStride = stride;
  502. pv->textures[1].dwStride = stride;
  503. pv->textures[2].dwStride = stride;
  504. pv->textures[3].dwStride = stride;
  505. pv->textures[4].dwStride = stride;
  506. pv->textures[5].dwStride = stride;
  507. pv->textures[6].dwStride = stride;
  508. pv->textures[7].dwStride = stride;
  509. }
  510. //---------------------------------------------------------------------
  511. // This function is called only when the input FVF is changed
  512. //
  513. void UpdateGeometryLoopData(LPD3DFE_PROCESSVERTICES pv)
  514. {
  515. // Compute input offsets
  516. if (!(pv->dwDeviceFlags & D3DDEV_STRIDE))
  517. {
  518. DWORD i = POSITION_SIZE[pv->dwVIDIn & D3DFVF_POSITION_MASK];
  519. pv->normalOffset = i;
  520. if (pv->dwVIDIn & D3DFVF_NORMAL)
  521. i += sizeof(D3DVECTOR);
  522. pv->pointSizeOffset = i;
  523. if (pv->dwVIDIn & D3DFVF_PSIZE)
  524. i += sizeof(D3DVALUE);
  525. pv->diffuseOffset = i;
  526. if (pv->dwVIDIn & D3DFVF_DIFFUSE)
  527. i += sizeof(DWORD);
  528. pv->specularOffset = i;
  529. if (pv->dwVIDIn & D3DFVF_SPECULAR)
  530. i += sizeof(DWORD);
  531. pv->texOffset = i;
  532. }
  533. }
  534. //-----------------------------------------------------------------------------
  535. inline DWORD GetColorComponent(float color)
  536. {
  537. if (FLOAT_LTZ(color))
  538. return 0;
  539. else
  540. if (FLOAT_CMP_PONE(color, >))
  541. return 255;
  542. else
  543. return (DWORD)FTOI(color * 255.0f);
  544. }
  545. //-----------------------------------------------------------------------------
  546. inline DWORD ComputeColor(VVM_WORD* color)
  547. {
  548. DWORD r = GetColorComponent(color->x);
  549. DWORD g = GetColorComponent(color->y);
  550. DWORD b = GetColorComponent(color->z);
  551. DWORD a = GetColorComponent(color->w);
  552. return (a<<24) + (r<<16) + (g<<8) + b;
  553. }
  554. //-----------------------------------------------------------------------------
  555. // Executes vertex shader and computes clip codes.
  556. // Vertices are processed in batches
  557. //
  558. // The following fields from pv are used:
  559. // dwFlags
  560. // dwNumVertices
  561. // all pointer and strides
  562. // dwVIDIn
  563. // dwVIDOut
  564. // lpvOut
  565. // lpClipFlags
  566. // nTexCoord
  567. // Returns:
  568. // returns dwClipIntersection or 0 (if D3DDEV_DONOTCLIP is set)
  569. // Side effects:
  570. // dwClipUnion, dwClipIntersection are set only if D3DDEV_DONOTCLIP is not set
  571. //
  572. #undef DPF_MODNAME
  573. #define DPF_MODNAME "ProcessVerticesVVM"
  574. DWORD D3DFE_PVFUNCSI::ProcessVerticesVVM(LPD3DFE_PROCESSVERTICES pv)
  575. {
  576. D3DFE_CLIPCODE* hout = pv->lpClipFlags;
  577. D3DTLVERTEX* out = (D3DTLVERTEX*)pv->lpvOut;
  578. VVM_REGISTERS* pRegisters = m_VertexVM.GetRegisters();
  579. DWORD dwDeviceFlags = pv->dwDeviceFlags;
  580. DWORD dwClipIntersection = 0;
  581. DWORD dwClipUnion = 0;
  582. DWORD dwOutVerSize = pv->dwOutputSize;
  583. CVShaderCode* shader = m_VertexVM.GetActiveShader();
  584. DWORD dwOutRegs = shader->m_dwOutRegs;
  585. UINT dwNumVertices = pv->dwNumVertices;
  586. // When ProcessVertices is used, output FVF could have a field VVM does not
  587. // modify. In this case we prevent writing to the output field
  588. BOOL bWritePSize = dwOutRegs & CPSGPShader_PSIZE &&
  589. pv->dwVIDOut & D3DFVF_PSIZE;
  590. BOOL bWriteDiffuse = dwOutRegs & CPSGPShader_DIFFUSE &&
  591. pv->dwVIDOut & D3DFVF_DIFFUSE;
  592. BOOL bWriteSpecular = (dwOutRegs & CPSGPShader_SPECULAR ||
  593. (dwOutRegs & CPSGPShader_FOG && !(pv->dwVIDOut & D3DFVF_FOG))) &&
  594. pv->dwVIDOut & D3DFVF_SPECULAR;
  595. BOOL bWriteFog = pv->dwVIDOut & D3DFVF_FOG &&
  596. dwOutRegs & CPSGPShader_FOG;
  597. if (!(dwDeviceFlags & D3DDEV_DONOTCLIP))
  598. dwClipIntersection = ~0;
  599. UINT iVertex = 0; // Vertex index
  600. while (dwNumVertices)
  601. {
  602. UINT count = min(dwNumVertices, VVMVERTEXBATCH);
  603. dwNumVertices -= count;
  604. // Copy vertex elements to the input vertex registers
  605. CVertexDesc* pVD = pv->VertexDesc;
  606. for (DWORD k = pv->dwNumUsedVertexDescs; k; k--)
  607. {
  608. (*(PFN_D3DCOPYELEMENT)pVD->pfnCopy)
  609. ((BYTE*)pVD->pMemory +
  610. iVertex * pVD->dwStride, pVD->dwStride, count,
  611. pRegisters->m_v[pVD->dwRegister]);
  612. pVD++;
  613. }
  614. m_VertexVM.ExecuteShader(pv, count);
  615. // Get the result from the output VVM registers
  616. for (UINT i=0; i < count; i++)
  617. {
  618. float x, y, z, w;
  619. w = pRegisters->m_output[D3DSRO_POSITION][i].w;
  620. z = pRegisters->m_output[D3DSRO_POSITION][i].z;
  621. // Make clipping rules 0 < x < w; 0 < y < w
  622. x = (pRegisters->m_output[D3DSRO_POSITION][i].x + w) * 0.5f;
  623. y = (pRegisters->m_output[D3DSRO_POSITION][i].y + w) * 0.5f;
  624. if (!(dwDeviceFlags & D3DDEV_DONOTCLIP))
  625. {
  626. DWORD clip;
  627. // Compute clip code
  628. d_ComputeClipCode(4)
  629. if (clip == 0)
  630. {
  631. dwClipIntersection = 0;
  632. *hout++ = 0;
  633. w = D3DVAL(1)/w;
  634. }
  635. else
  636. {
  637. if (dwDeviceFlags & D3DDEV_GUARDBAND)
  638. {
  639. // We do guardband check in the projection space, so
  640. // we transform X and Y of the vertex there
  641. d_ComputeClipCodeGB(6)
  642. if ((clip & ~__D3DCS_INGUARDBAND) == 0)
  643. {
  644. // If vertex is inside the guardband we have to compute
  645. // screen coordinates
  646. w = D3DVAL(1)/w;
  647. *hout++ = (D3DFE_CLIPCODE)clip;
  648. dwClipIntersection &= clip;
  649. dwClipUnion |= clip;
  650. goto l_DoScreenCoord;
  651. }
  652. }
  653. dwClipIntersection &= clip;
  654. dwClipUnion |= clip;
  655. *hout++ = (D3DFE_CLIPCODE)clip;
  656. // If vertex is outside the frustum we can not compute screen
  657. // coordinates
  658. out->sx = x;
  659. out->sy = y;
  660. out->sz = z;
  661. out->rhw = w;
  662. goto l_DoLighting;
  663. }
  664. }
  665. else
  666. {
  667. // We have to check this only for DONOTCLIP case, because otherwise
  668. // the vertex with "we = 0" will be clipped and screen coordinates
  669. // will not be computed
  670. // "clip" is not zero, if "w" is zero.
  671. if (!FLOAT_EQZ(w))
  672. w = D3DVAL(1)/w;
  673. else
  674. w = __HUGE_PWR2;
  675. }
  676. l_DoScreenCoord:
  677. d_ComputeScreenCoordinates(3, x, y, z, w, out)
  678. l_DoLighting:
  679. if (bWritePSize)
  680. {
  681. float* p = (float*)((BYTE*)out + pv->pointSizeOffsetOut);
  682. *p = pRegisters->m_output[D3DSRO_POINT_SIZE][i].x;
  683. }
  684. if (bWriteDiffuse)
  685. {
  686. DWORD* p = (DWORD*)((BYTE*)out + pv->diffuseOffsetOut);
  687. *p = ComputeColor(&pRegisters->m_color[0][i]);
  688. }
  689. else
  690. if (!(pv->dwFlags & D3DPV_DONOTCOPYDIFFUSE))
  691. {
  692. *(DWORD*)((BYTE*)out + pv->diffuseOffsetOut) = __DEFAULT_DIFFUSE;
  693. }
  694. if (bWriteSpecular)
  695. {
  696. DWORD color = __DEFAULT_SPECULAR;
  697. DWORD* p = (DWORD*)((BYTE*)out + pv->specularOffsetOut);
  698. if (dwOutRegs & CPSGPShader_SPECULAR)
  699. {
  700. color = ComputeColor(&pRegisters->m_color[1][i]);
  701. }
  702. // We need to clear specular ALPHA, because it should be taken
  703. // from the FOG register even if the shader does not write to it
  704. color &= 0x00FFFFFF;
  705. if (dwOutRegs & CPSGPShader_FOG && !bWriteFog)
  706. {
  707. DWORD a = GetColorComponent(pRegisters->m_output[D3DSRO_FOG][i].x);
  708. ((BYTE*)&color)[3] = (BYTE)a;
  709. }
  710. *p = color;
  711. }
  712. else
  713. if (!(pv->dwFlags & D3DPV_DONOTCOPYSPECULAR))
  714. {
  715. *(DWORD*)((BYTE*)out + pv->specularOffsetOut) = __DEFAULT_SPECULAR;
  716. }
  717. if (bWriteFog)
  718. {
  719. float a = pRegisters->m_output[D3DSRO_FOG][i].x;
  720. if (FLOAT_LTZ(a))
  721. *(float*)((BYTE*)out + pv->fogOffsetOut) = 0.0f;
  722. else
  723. if (FLOAT_CMP_PONE(a, >))
  724. *(float*)((BYTE*)out + pv->fogOffsetOut) = 1.0f;
  725. else
  726. *(float*)((BYTE*)out + pv->fogOffsetOut) = a;
  727. }
  728. D3DVALUE *pOutTexture = (D3DVALUE*)((BYTE*)out + pv->texOffsetOut);
  729. for (DWORD k=0; k < pv->nOutTexCoord; k++)
  730. {
  731. DWORD dwSize = pv->dwTextureCoordSize[k];
  732. memcpy(pOutTexture, &pRegisters->m_texture[k][i], dwSize);
  733. NEXT(pOutTexture, dwSize, D3DVALUE);
  734. }
  735. NEXT(out, dwOutVerSize, D3DTLVERTEX);
  736. }
  737. iVertex += count;
  738. }
  739. pv->dwClipIntersection = dwClipIntersection;
  740. pv->dwClipUnion = dwClipUnion;
  741. return dwClipIntersection;
  742. }
  743. //-----------------------------------------------------------------------------
  744. extern DWORD ProcessVerticesLoop(D3DFE_PROCESSVERTICES *pv);
  745. //-----------------------------------------------------------------------------
  746. DWORD D3DFE_PVFUNCSI::ProcessVertices(LPD3DFE_PROCESSVERTICES pv)
  747. {
  748. CD3DFPstate D3DFPstate; // Sets optimal FPU state for D3D.
  749. if (pv->dwDeviceFlags & D3DDEV_VERTEXSHADERS)
  750. return ProcessVerticesVVM(pv);
  751. else
  752. return ProcessVerticesLoop(pv);
  753. }
  754. //-----------------------------------------------------------------------------
  755. HRESULT D3DFE_PVFUNCSI::ProcessPrimitive(LPD3DFE_PROCESSVERTICES pv)
  756. {
  757. CD3DFPstate D3DFPstate; // Sets optimal FPU state for D3D.
  758. #ifdef DEBUG_PIPELINE
  759. if (!(g_DebugFlags & __DEBUG_ONEPASS))
  760. #endif
  761. if (DoOnePassPrimProcessing(pv))
  762. { // We can do optimized processing of non-indexed primitives that
  763. // require clipping
  764. switch (pv->primType)
  765. {
  766. case D3DPT_TRIANGLELIST : return ProcessTriangleList(pv);
  767. case D3DPT_TRIANGLESTRIP: return ProcessTriangleStrip(pv);
  768. case D3DPT_TRIANGLEFAN : return ProcessTriangleFan(pv);
  769. case D3DPT_LINELIST : return ProcessLineList(pv);
  770. case D3DPT_LINESTRIP : return ProcessLineStrip(pv);
  771. }
  772. }
  773. pv->pGeometryFuncs->ProcessVertices(pv);
  774. if (pv->dwClipIntersection)
  775. {
  776. // all vertices were offscreen
  777. return D3D_OK;
  778. }
  779. return (DoDrawPrimitive(pv));
  780. }
  781. //-----------------------------------------------------------------------------
  782. HRESULT D3DFE_PVFUNCSI::ProcessIndexedPrimitive(LPD3DFE_PROCESSVERTICES pv)
  783. {
  784. pv->pGeometryFuncs->ProcessVertices(pv);
  785. if (pv->dwClipIntersection)
  786. {
  787. // all vertices were offscreen
  788. return D3D_OK;
  789. }
  790. HRESULT hr = DoDrawIndexedPrimitive(pv);
  791. return hr;
  792. }
  793. //-----------------------------------------------------------------------------
  794. D3DFE_PROCESSVERTICES::D3DFE_PROCESSVERTICES()
  795. {
  796. for (DWORD i=0; i < D3DDP_MAXTEXCOORD; i++)
  797. {
  798. // Set texture size array to default for pre-DX7 drivers
  799. this->dwTextureCoordSize[i] = 4*2;
  800. }
  801. for (i = 0; i < VER_IN_BATCH-1; i++)
  802. {
  803. clipVer[i].next = &clipVer[i+1];
  804. }
  805. clipVer[VER_IN_BATCH-1].next = clipVer;
  806. this->dwFlags = 0;
  807. this->dwDeviceFlags = 0;
  808. this->dwFlags2 = 0;
  809. this->dwMaxUserClipPlanes = 0;
  810. this->ClipperState.clipBuf = new BYTE[MAX_CLIP_VERTICES*__MAX_VERTEX_SIZE];
  811. // Set a defaul value for matrix indices in vertices
  812. this->MatrixIndices[0] = 0;
  813. this->MatrixIndices[1] = 1;
  814. this->MatrixIndices[2] = 2;
  815. this->MatrixIndices[3] = 3;
  816. #ifdef DEBUG_PIPELINE
  817. GetD3DRegValue(REG_DWORD, "DebugFlags", &g_DebugFlags, 4);
  818. DWORD dwDisableRendering = 0;
  819. GetD3DRegValue(REG_DWORD, "DisableRendering", &dwDisableRendering, 4);
  820. if (dwDisableRendering)
  821. g_DebugFlags |= __DEBUG_NORENDERING;
  822. #endif
  823. this->pDDI = NULL;
  824. for (i=0; i < __MAXWORLDMATRICES; i++)
  825. {
  826. CTMCount[i] = 0;
  827. WVCount[i] = 0;
  828. WVICount[i] = 0;
  829. }
  830. MatrixStateCount = 1; // To force setting matrices for the first time
  831. }
  832. //-----------------------------------------------------------------------------
  833. D3DFE_PROCESSVERTICES::~D3DFE_PROCESSVERTICES()
  834. {
  835. delete [] this->ClipperState.clipBuf;
  836. }
  837. //---------------------------------------------------------------------
  838. #undef DPF_MODNAME
  839. #define DPF_MODNAME "DoDrawPrimitive"
  840. HRESULT D3DFE_PVFUNCSI::DoDrawPrimitive(LPD3DFE_PROCESSVERTICES pv)
  841. {
  842. HRESULT ret;
  843. if (!CheckIfNeedClipping(pv))
  844. {
  845. try
  846. {
  847. pv->pDDI->DrawPrim(pv);
  848. return S_OK;
  849. }
  850. catch( HRESULT hr )
  851. {
  852. return hr;
  853. }
  854. }
  855. // Preserve primitive type for large begin-end primitives
  856. // Primitive type could be changed by the clipper
  857. D3DPRIMITIVETYPE oldPrimType = pv->primType;
  858. switch (pv->primType)
  859. {
  860. case D3DPT_POINTLIST:
  861. ret = ProcessClippedPoints(pv);
  862. break;
  863. case D3DPT_LINELIST:
  864. ret = ProcessClippedLine(pv);
  865. break;
  866. case D3DPT_LINESTRIP:
  867. ret = ProcessClippedLine(pv);
  868. break;
  869. case D3DPT_TRIANGLELIST:
  870. ret = ProcessClippedTriangleList(pv);
  871. break;
  872. case D3DPT_TRIANGLESTRIP:
  873. ret = ProcessClippedTriangleStrip(pv);
  874. break;
  875. case D3DPT_TRIANGLEFAN:
  876. ret = ProcessClippedTriangleFan(pv);
  877. break;
  878. default:
  879. D3D_ERR( "Unknown primitive type in DrawPrimitive" );
  880. ret = D3DERR_INVALIDCALL;
  881. break;
  882. }
  883. pv->primType = oldPrimType;
  884. return ret;
  885. }
  886. //---------------------------------------------------------------------
  887. #undef DPF_MODNAME
  888. #define DPF_MODNAME "DoDrawIndexedPrimitive"
  889. HRESULT D3DFE_PVFUNCSI::DoDrawIndexedPrimitive(LPD3DFE_PROCESSVERTICES pv)
  890. {
  891. HRESULT ret = S_OK;
  892. if (!CheckIfNeedClipping(pv))
  893. {
  894. try
  895. {
  896. pv->pDDI->DrawIndexPrim(pv);
  897. return S_OK;
  898. }
  899. catch( HRESULT hr )
  900. {
  901. return hr;
  902. }
  903. }
  904. // Preserve primitive type for large begin-end primitives
  905. // Primitive type could be changed by the clipper
  906. D3DPRIMITIVETYPE oldPrimType = pv->primType;
  907. switch (pv->primType)
  908. {
  909. case D3DPT_POINTLIST:
  910. ret = ProcessClippedIndexedPoints(pv);
  911. break;
  912. case D3DPT_LINELIST:
  913. ret = ProcessClippedIndexedLine(pv);
  914. break;
  915. case D3DPT_LINESTRIP:
  916. ret = ProcessClippedIndexedLine(pv);
  917. break;
  918. case D3DPT_TRIANGLELIST:
  919. ret = ProcessClippedIndexedTriangleList(pv);
  920. break;
  921. case D3DPT_TRIANGLEFAN:
  922. ret = ProcessClippedIndexedTriangleFan(pv);
  923. break;
  924. case D3DPT_TRIANGLESTRIP:
  925. ret = ProcessClippedIndexedTriangleStrip(pv);
  926. break;
  927. default:
  928. break;
  929. }
  930. pv->primType = oldPrimType;
  931. return ret;
  932. }