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.

3555 lines
112 KiB

  1. /******************************Module*Header**********************************\
  2. *
  3. * *******************
  4. * * D3D SAMPLE CODE *
  5. * *******************
  6. *
  7. * Module Name: d3dprim.c
  8. *
  9. * Content: D3D primitives rendering
  10. *
  11. * Copyright (c) 1994-1999 3Dlabs Inc. Ltd. All rights reserved.
  12. * Copyright (c) 1995-2003 Microsoft Corporation. All rights reserved.
  13. \*****************************************************************************/
  14. // For the mipmap LOD calculation
  15. #define BIAS_SHIFT 1
  16. #define CULL_HERE 1
  17. #include <limits.h>
  18. #include "glint.h"
  19. #include "dma.h"
  20. #include "tag.h"
  21. //-----------------------------------------------------------------------------
  22. //
  23. // Specialized hardaware rendering functions for the Permedia3,
  24. // for all primitve types
  25. //
  26. //-----------------------------------------------------------------------------
  27. #define GET_FOG(x) ((x) & 0xff000000 )
  28. #define GET_SPEC(x) ((x) & 0x00ffffff )
  29. #define SEND_R3FVFVERTEX_XYZ(Num, Index) \
  30. { \
  31. MEMORY_BARRIER(); \
  32. dmaPtr[0] = GAMBIT_XYZ_VTX | Num; \
  33. MEMORY_BARRIER(); \
  34. dmaPtr[1] = AS_ULONG(pv[Index]->sx); \
  35. MEMORY_BARRIER(); \
  36. dmaPtr[2] = AS_ULONG(pv[Index]->sy); \
  37. MEMORY_BARRIER(); \
  38. dmaPtr[3] = AS_ULONG(pv[Index]->sz); \
  39. dmaPtr += 4; \
  40. CHECK_FIFO(4); \
  41. }
  42. #define SEND_R3FVFVERTEX_XYZ_STQ(Num, Index) \
  43. { \
  44. MEMORY_BARRIER(); \
  45. dmaPtr[0] = GAMBIT_XYZ_STQ_VTX | Num; \
  46. MEMORY_BARRIER(); \
  47. *(float volatile*)&dmaPtr[1] = tc[Index].tu1; \
  48. MEMORY_BARRIER(); \
  49. *(float volatile*)&dmaPtr[2] = tc[Index].tv1; \
  50. MEMORY_BARRIER(); \
  51. dmaPtr[3] = q[Index]; \
  52. MEMORY_BARRIER(); \
  53. dmaPtr[4] = AS_ULONG(pv[Index]->sx); \
  54. MEMORY_BARRIER(); \
  55. dmaPtr[5] = AS_ULONG(pv[Index]->sy); \
  56. MEMORY_BARRIER(); \
  57. dmaPtr[6] = AS_ULONG(pv[Index]->sz); \
  58. dmaPtr += 7; \
  59. CHECK_FIFO(7); \
  60. }
  61. #define SEND_R3FVFVERTEX_XYZ_FOG(Num, Index) \
  62. { \
  63. MEMORY_BARRIER(); \
  64. dmaPtr[0] = GAMBIT_XYZ_VTX | VTX_SPECULAR | Num; \
  65. MEMORY_BARRIER(); \
  66. dmaPtr[1] = AS_ULONG(pv[Index]->sx); \
  67. MEMORY_BARRIER(); \
  68. dmaPtr[2] = AS_ULONG(pv[Index]->sy); \
  69. MEMORY_BARRIER(); \
  70. dmaPtr[3] = AS_ULONG(pv[Index]->sz); \
  71. MEMORY_BARRIER(); \
  72. dmaPtr[4] = GET_FOG( FVFSPEC(pv[Index])->specular ); \
  73. dmaPtr += 5; \
  74. CHECK_FIFO(5); \
  75. }
  76. #define SEND_R3FVFVERTEX_XYZ_STQ_FOG(Num, Index) \
  77. { \
  78. MEMORY_BARRIER(); \
  79. dmaPtr[0] = GAMBIT_XYZ_STQ_VTX | VTX_SPECULAR | Num; \
  80. MEMORY_BARRIER(); \
  81. *(float volatile*)&dmaPtr[1] = tc[Index].tu1; \
  82. MEMORY_BARRIER(); \
  83. *(float volatile*)&dmaPtr[2] = tc[Index].tv1; \
  84. MEMORY_BARRIER(); \
  85. dmaPtr[3] = q[Index]; \
  86. MEMORY_BARRIER(); \
  87. dmaPtr[4] = AS_ULONG(pv[Index]->sx); \
  88. MEMORY_BARRIER(); \
  89. dmaPtr[5] = AS_ULONG(pv[Index]->sy); \
  90. MEMORY_BARRIER(); \
  91. dmaPtr[6] = AS_ULONG(pv[Index]->sz); \
  92. MEMORY_BARRIER(); \
  93. dmaPtr[7] = GET_FOG( FVFSPEC(pv[Index])->specular ); \
  94. dmaPtr += 8; \
  95. CHECK_FIFO(8); \
  96. }
  97. #define SEND_R3FVFVERTEX_XYZ_RGBA(Num, Index) \
  98. { \
  99. MEMORY_BARRIER(); \
  100. dmaPtr[0] = GAMBIT_XYZ_VTX | VTX_COLOR | Num; \
  101. MEMORY_BARRIER(); \
  102. dmaPtr[1] = AS_ULONG(pv[Index]->sx); \
  103. MEMORY_BARRIER(); \
  104. dmaPtr[2] = AS_ULONG(pv[Index]->sy); \
  105. MEMORY_BARRIER(); \
  106. dmaPtr[3] = AS_ULONG(pv[Index]->sz); \
  107. MEMORY_BARRIER(); \
  108. dmaPtr[4] = FVFCOLOR(pv[Index])->color; \
  109. MEMORY_BARRIER(); \
  110. dmaPtr += 5; \
  111. CHECK_FIFO(5); \
  112. }
  113. #define SEND_R3FVFVERTEX_XYZ_RGBA_SFOG(Num, Index) \
  114. { \
  115. MEMORY_BARRIER(); \
  116. dmaPtr[0] = GAMBIT_XYZ_VTX | VTX_COLOR | VTX_SPECULAR | Num; \
  117. MEMORY_BARRIER(); \
  118. dmaPtr[1] = AS_ULONG(pv[Index]->sx); \
  119. MEMORY_BARRIER(); \
  120. dmaPtr[2] = AS_ULONG(pv[Index]->sy); \
  121. MEMORY_BARRIER(); \
  122. dmaPtr[3] = AS_ULONG(pv[Index]->sz); \
  123. MEMORY_BARRIER(); \
  124. dmaPtr[4] = FVFCOLOR(pv[Index])->color; \
  125. MEMORY_BARRIER(); \
  126. dmaPtr[5] = FVFSPEC(pv[Index])->specular; \
  127. dmaPtr += 6; \
  128. CHECK_FIFO(6); \
  129. }
  130. #define SEND_R3FVFVERTEX_XYZ_STQ_RGBA_SFOG(Num, Index) \
  131. { \
  132. MEMORY_BARRIER(); \
  133. dmaPtr[0] = GAMBIT_XYZ_STQ_VTX | VTX_COLOR | VTX_SPECULAR | Num; \
  134. MEMORY_BARRIER(); \
  135. *(float volatile*)&dmaPtr[1] = tc[Index].tu1; \
  136. MEMORY_BARRIER(); \
  137. *(float volatile*)&dmaPtr[2] = tc[Index].tv1; \
  138. MEMORY_BARRIER(); \
  139. dmaPtr[3] = q[Index]; \
  140. MEMORY_BARRIER(); \
  141. dmaPtr[4] = AS_ULONG(pv[Index]->sx); \
  142. MEMORY_BARRIER(); \
  143. dmaPtr[5] = AS_ULONG(pv[Index]->sy); \
  144. MEMORY_BARRIER(); \
  145. dmaPtr[6] = AS_ULONG(pv[Index]->sz); \
  146. MEMORY_BARRIER(); \
  147. dmaPtr[7] = FVFCOLOR(pv[Index])->color; \
  148. MEMORY_BARRIER(); \
  149. dmaPtr[8] = FVFSPEC(pv[Index])->specular; \
  150. dmaPtr += 9; \
  151. CHECK_FIFO(9); \
  152. }
  153. #define SEND_R3FVFVERTEX_XYZ_STQ_RGBA_SFOG_POINT(Num, Index, offset) \
  154. { \
  155. float TempY = Y_ADJUST(pv[Index]->sy); \
  156. if (offset == TRUE) TempY += 1.0f; \
  157. MEMORY_BARRIER(); \
  158. dmaPtr[0] = GAMBIT_XYZ_STQ_VTX | VTX_COLOR | VTX_SPECULAR | Num; \
  159. MEMORY_BARRIER(); \
  160. *(float volatile*)&dmaPtr[1] = tc[Index].tu1; \
  161. MEMORY_BARRIER(); \
  162. *(float volatile*)&dmaPtr[2] = tc[Index].tv1; \
  163. MEMORY_BARRIER(); \
  164. dmaPtr[3] = q[Index]; \
  165. MEMORY_BARRIER(); \
  166. dmaPtr[4] = AS_ULONG(pv[Index]->sx); \
  167. MEMORY_BARRIER(); \
  168. dmaPtr[5] = AS_ULONG(TempY); \
  169. MEMORY_BARRIER(); \
  170. dmaPtr[6] = AS_ULONG(pv[Index]->sz); \
  171. MEMORY_BARRIER(); \
  172. dmaPtr[7] = FVFCOLOR(pv[Index])->color; \
  173. MEMORY_BARRIER(); \
  174. dmaPtr[8] = FVFSPEC(pv[Index])->specular; \
  175. dmaPtr += 9; \
  176. CHECK_FIFO(9); \
  177. }
  178. #define SEND_R3FVFVERTEX_STQ2(Num, Index) \
  179. { \
  180. MEMORY_BARRIER(); \
  181. dmaPtr[0] = GAMBIT_STQ_VTX | Num; \
  182. MEMORY_BARRIER(); \
  183. *(float volatile*)&dmaPtr[1] = tc[Index].tu2; \
  184. MEMORY_BARRIER(); \
  185. *(float volatile*)&dmaPtr[2] = tc[Index].tv2; \
  186. MEMORY_BARRIER(); \
  187. dmaPtr[3] = q[Index]; \
  188. dmaPtr += 4; \
  189. CHECK_FIFO(4); \
  190. }
  191. #if DX8_3DTEXTURES
  192. #define SEND_R3FVFVERTEX_3DTEX(Num, Index) \
  193. { \
  194. MEMORY_BARRIER(); \
  195. dmaPtr[0] = GAMBIT_STQ_VTX | Num; \
  196. MEMORY_BARRIER(); \
  197. *(float volatile*)&dmaPtr[1] = tc[Index].tw1; \
  198. MEMORY_BARRIER(); \
  199. *(float volatile*)&dmaPtr[2] = 0; /* Not used */ \
  200. MEMORY_BARRIER(); \
  201. dmaPtr[3] = q[Index]; \
  202. dmaPtr += 4; \
  203. CHECK_FIFO(4); \
  204. }
  205. #endif // DX8_3DTEXTURES
  206. #if DX8_3DTEXTURES
  207. #define GET_TC_3DTEX( Index ) \
  208. *(DWORD *)&tc[Index].tu1 = *(DWORD *)&FVFTEX(pv[Index], 0)->tu; \
  209. *(DWORD *)&tc[Index].tv1 = *(DWORD *)&FVFTEX(pv[Index], 0)->tv; \
  210. *(DWORD *)&tc[Index].tw1 = *(DWORD *)&FVFTEX(pv[Index], 0)->tw;
  211. #endif // DX8_3DTEXTURES
  212. #define GET_TC( Index ) \
  213. *(DWORD *)&tc[Index].tu1 = *(DWORD *)&FVFTEX(pv[Index], 0)->tu; \
  214. *(DWORD *)&tc[Index].tv1 = *(DWORD *)&FVFTEX(pv[Index], 0)->tv;
  215. #if DX8_3DTEXTURES
  216. #define GET_TC2_3DTEX( Index ) \
  217. *(DWORD *)&tc[Index].tu2 = *(DWORD *)&FVFTEX(pv[Index], 1)->tu; \
  218. *(DWORD *)&tc[Index].tv2 = *(DWORD *)&FVFTEX(pv[Index], 1)->tv; \
  219. *(DWORD *)&tc[Index].tw2 = *(DWORD *)&FVFTEX(pv[Index], 1)->tw;
  220. #endif // DX8_3DTEXTURES
  221. #define GET_TC2( Index ) \
  222. *(DWORD *)&tc[Index].tu2 = *(DWORD *)&FVFTEX(pv[Index], 1)->tu; \
  223. *(DWORD *)&tc[Index].tv2 = *(DWORD *)&FVFTEX(pv[Index], 1)->tv;
  224. #define GET_ONE_TEXCOORD(vtx) \
  225. GET_TC(vtx); \
  226. if( pContext->iTexStage[1] != -1 ) \
  227. { \
  228. GET_TC2(vtx); \
  229. }
  230. #define GET_TEXCOORDS() \
  231. GET_TC(0); GET_TC(1); GET_TC(2); \
  232. if( pContext->iTexStage[1] != -1 ) \
  233. { \
  234. GET_TC2(0); GET_TC2(1); GET_TC2(2); \
  235. }
  236. #if DX8_3DTEXTURES
  237. #define SCALE_BY_Q_3DTEX( Index ) \
  238. tc[Index].tu1 *= *(float *)&q[Index]; \
  239. tc[Index].tv1 *= *(float *)&q[Index]; \
  240. tc[Index].tw1 *= *(float *)&q[Index];
  241. #endif // DX8_3DTEXTURES
  242. #define SCALE_BY_Q( Index ) \
  243. tc[Index].tu1 *= *(float *)&q[Index]; \
  244. tc[Index].tv1 *= *(float *)&q[Index];
  245. #if DX8_3DTEXTURES
  246. #define SCALE_BY_Q2_3DTEX( Index ) \
  247. tc[Index].tu2 *= *(float *)&q[Index]; \
  248. tc[Index].tv2 *= *(float *)&q[Index]; \
  249. tc[Index].tw2 *= *(float *)&q[Index];
  250. #endif // DX8_3DTEXTURES
  251. #define SCALE_BY_Q2( Index ) \
  252. tc[Index].tu2 *= *(float *)&q[Index]; \
  253. tc[Index].tv2 *= *(float *)&q[Index];
  254. #define DRAW_LINE() \
  255. MEMORY_BARRIER(); \
  256. dmaPtr[0] = DrawLine01_Tag; \
  257. MEMORY_BARRIER(); \
  258. dmaPtr[1] = renderCmd; \
  259. dmaPtr += 2; \
  260. CHECK_FIFO(2)
  261. #define DRAW_POINT() \
  262. MEMORY_BARRIER(); \
  263. dmaPtr[0] = DrawPoint_Tag; \
  264. MEMORY_BARRIER(); \
  265. dmaPtr[1] = renderCmd; \
  266. dmaPtr += 2; \
  267. CHECK_FIFO(2)
  268. #define DRAW_LINE_01_OR_10( vtx ) \
  269. MEMORY_BARRIER(); \
  270. dmaPtr[0] = vtx ? DrawLine01_Tag \
  271. : DrawLine10_Tag; \
  272. MEMORY_BARRIER(); \
  273. dmaPtr[1] = renderCmd; \
  274. dmaPtr += 2; \
  275. CHECK_FIFO(2)
  276. #define DRAW_TRIANGLE() \
  277. MEMORY_BARRIER(); \
  278. dmaPtr[0] = DrawTriangle_Tag; \
  279. MEMORY_BARRIER(); \
  280. dmaPtr[1] = renderCmd; \
  281. dmaPtr += 2; \
  282. CHECK_FIFO(2)
  283. //-----------------------------------------------------------------------------
  284. // Easy edge flag renaming
  285. //-----------------------------------------------------------------------------
  286. #define SIDE_0 D3DTRIFLAG_EDGEENABLE1
  287. #define SIDE_1 D3DTRIFLAG_EDGEENABLE2
  288. #define SIDE_2 D3DTRIFLAG_EDGEENABLE3
  289. #define ALL_SIDES ( SIDE_0 | SIDE_1 | SIDE_2 )
  290. //-----------------------------------------------------------------------------
  291. // Cycle vertex indices for triangle strips viz. 0 -> 1, 1 -> 2, 2 -> 0
  292. // See Graphics Gems 3, Pg 69.
  293. //-----------------------------------------------------------------------------
  294. #define INIT_VERTEX_INDICES(pContext, vtx_a, vtx_b) \
  295. vtx_a = 0; \
  296. vtx_b = 0 ^ 1; \
  297. pContext->dwProvokingVertex = 1;
  298. #define CONST_c (0 ^ 1 ^ 2)
  299. #define CYCLE_VERTEX_INDICES(pContext, vtx_a, vtx_b) \
  300. vtx_a ^= vtx_b; \
  301. vtx_b ^= CONST_c; \
  302. pContext->dwProvokingVertex = vtx_b; \
  303. vtx_b ^= vtx_a;
  304. //-----------------------------------------------------------------------------
  305. // Local typedef for temporary texture coordinate storage
  306. //-----------------------------------------------------------------------------
  307. typedef struct
  308. {
  309. float tu1;
  310. float tv1;
  311. #if DX8_3DTEXTURES
  312. float tw1;
  313. #endif // DX8_3DTEXTURES
  314. float tu2;
  315. float tv2;
  316. #if DX8_3DTEXTURES
  317. float tw2;
  318. #endif // DX8_3DTEXTURES
  319. } TEXCOORDS;
  320. //-----------------------------------------------------------------------------
  321. // Macros to access and validate command and vertex buffer data
  322. // These checks need ALWAYS to be made for all builds, free and checked.
  323. //-----------------------------------------------------------------------------
  324. #define LP_FVF_VERTEX(lpBaseAddr, wIndex) \
  325. (LPD3DTLVERTEX)((LPBYTE)(lpBaseAddr) + (wIndex) * pContext->FVFData.dwStride)
  326. #define LP_FVF_NXT_VTX(lpVtx) \
  327. (LPD3DTLVERTEX)((LPBYTE)(lpVtx) + pContext->FVFData.dwStride)
  328. #define CHECK_DATABUF_LIMITS(pbError, dwVBLen, iIndex ) \
  329. { \
  330. if (! (((LONG)(iIndex) >= 0) && \
  331. ((LONG)(iIndex) <(LONG)dwVBLen))) \
  332. { \
  333. DISPDBG((ERRLVL,"D3D: Trying to read past Vertex Buffer limits " \
  334. "%d limit= %d ",(LONG)(iIndex), (LONG)dwVBLen)); \
  335. *pbError = TRUE; \
  336. return; \
  337. } \
  338. }
  339. //-----------------------------------------------------------------------------
  340. // Define values for FVF defaults
  341. //-----------------------------------------------------------------------------
  342. const FVFCOLOR gc_FVFColorDefault = { 0xFFFFFFFF };
  343. const FVFSPECULAR gc_FVFSpecDefault = { 0x00000000 };
  344. const FVFTEXCOORDS gc_FVFTexCoordDefault = { 0.0f,
  345. 0.0f
  346. #if DX8_3DTEXTURES
  347. , 0.0f
  348. #endif
  349. };
  350. //-----------------------------------------------------------------------------
  351. // Macros and functions for texture coord adjustment on wrapping
  352. //-----------------------------------------------------------------------------
  353. #define SHIFT_SET_0 1
  354. #define SHIFT_SET_1 2
  355. #define TEXSHIFT 1
  356. #if TEXSHIFT
  357. #if 0
  358. // 8.0f as a DWORD
  359. #define TEX_SHIFT_LIMIT 0x41000000
  360. #define FP_SIGN_MASK 0x7fffffff
  361. #define TEXTURE_SHIFT( coord ) \
  362. if(( *(DWORD *)&tc[0].##coord & FP_SIGN_MASK ) > TEX_SHIFT_LIMIT ) \
  363. { \
  364. myFtoi( &intVal, tc[0].##coord ); \
  365. \
  366. intVal &= ~1; \
  367. \
  368. tc[0].##coord -= intVal; \
  369. tc[1].##coord -= intVal; \
  370. tc[2].##coord -= intVal; \
  371. \
  372. FLUSH_DUE_TO_WRAP( coord, TRUE ); \
  373. }
  374. #endif
  375. #define TEX_SHIFT_LIMIT 4.0
  376. #define TEXTURE_SHIFT( coord ) \
  377. if((tc[0].##coord > TEX_SHIFT_LIMIT ) || \
  378. (tc[0].##coord < -TEX_SHIFT_LIMIT ) ) \
  379. { \
  380. myFtoi( &intVal, tc[0].##coord ); \
  381. \
  382. intVal &= ~1; \
  383. \
  384. tc[0].##coord -= intVal; \
  385. tc[1].##coord -= intVal; \
  386. tc[2].##coord -= intVal; \
  387. \
  388. FLUSH_DUE_TO_WRAP( coord, TRUE ); \
  389. }
  390. #define WRAP_R3(par, wrapit, vertexSharing) if(wrapit) { \
  391. float elp; \
  392. float erp; \
  393. float emp; \
  394. elp=(float)myFabs(tc[1].##par-tc[0].##par); \
  395. erp=(float)myFabs(tc[2].##par-tc[1].##par); \
  396. emp=(float)myFabs(tc[0].##par-tc[2].##par); \
  397. if( (elp > 0.5f) && (erp > 0.5f) ) \
  398. { \
  399. if (tc[1].##par < tc[2].##par) { tc[1].##par += 1.0f; } \
  400. else { tc[2].##par += 1.0f; tc[0].##par += 1.0f; } \
  401. FLUSH_DUE_TO_WRAP(par,vertexSharing); \
  402. } \
  403. else if( (erp > 0.5f) && (emp > 0.5f) ) \
  404. { \
  405. if (tc[2].##par < tc[0].##par) { tc[2].##par += 1.0f; } \
  406. else { tc[0].##par += 1.0f; tc[1].##par += 1.0f; } \
  407. FLUSH_DUE_TO_WRAP(par,vertexSharing); \
  408. } \
  409. else if( (emp > 0.5f) && (elp > 0.5f) ) \
  410. { \
  411. if(tc[0].##par < tc[1].##par) { tc[0].##par += 1.0f; } \
  412. else { tc[1].##par += 1.0f; tc[2].##par += 1.0f; } \
  413. FLUSH_DUE_TO_WRAP(par,vertexSharing); \
  414. } \
  415. else \
  416. { \
  417. DONT_FLUSH_DUE_TO_WRAP(par,vertexSharing); \
  418. } \
  419. } else { \
  420. DONT_FLUSH_DUE_TO_WRAP(par,vertexSharing); \
  421. }
  422. //-----------------------------------------------------------------------------
  423. //
  424. // __TextureShift
  425. //
  426. //-----------------------------------------------------------------------------
  427. void
  428. __TextureShift(
  429. P3_D3DCONTEXT *pContext,
  430. TEXCOORDS tc[],
  431. DWORD shiftMask )
  432. {
  433. int intVal;
  434. if( shiftMask & SHIFT_SET_0 )
  435. {
  436. if( pContext->TextureStageState[0].m_dwVal[D3DTSS_ADDRESSU] !=
  437. D3DTADDRESS_CLAMP )
  438. {
  439. TEXTURE_SHIFT( tu1 );
  440. }
  441. if( pContext->TextureStageState[0].m_dwVal[D3DTSS_ADDRESSV] !=
  442. D3DTADDRESS_CLAMP )
  443. {
  444. TEXTURE_SHIFT( tv1 );
  445. }
  446. }
  447. if( shiftMask & SHIFT_SET_1 )
  448. {
  449. if( pContext->TextureStageState[1].m_dwVal[D3DTSS_ADDRESSU] !=
  450. D3DTADDRESS_CLAMP )
  451. {
  452. TEXTURE_SHIFT( tu2 );
  453. }
  454. if( pContext->TextureStageState[1].m_dwVal[D3DTSS_ADDRESSV] !=
  455. D3DTADDRESS_CLAMP )
  456. {
  457. TEXTURE_SHIFT( tv2 );
  458. }
  459. }
  460. } // __TextureShift
  461. #endif //TEXSHIFT
  462. //-----------------------------------------------------------------------------
  463. //
  464. // __BackfaceCullNoTexture
  465. //
  466. //-----------------------------------------------------------------------------
  467. int _inline
  468. __BackfaceCullNoTexture(
  469. P3_D3DCONTEXT *pContext,
  470. D3DTLVERTEX *pv[] )
  471. {
  472. DWORD Flags = pContext->Flags;
  473. float PixelArea;
  474. PixelArea = (((pv[0]->sx - pv[2]->sx) * (pv[1]->sy - pv[2]->sy)) -
  475. ((pv[1]->sx - pv[2]->sx) * (pv[0]->sy - pv[2]->sy)));
  476. if (CULLED(pContext,PixelArea))
  477. {
  478. return 1;
  479. }
  480. pContext->R3flushDueToTexCoordAdjust = 0;
  481. return 0;
  482. } // __BackfaceCullNoTexture
  483. //-----------------------------------------------------------------------------
  484. //
  485. // __BackfaceCullSingleTex
  486. //
  487. //-----------------------------------------------------------------------------
  488. int _inline
  489. __BackfaceCullSingleTex(
  490. P3_D3DCONTEXT *pContext,
  491. D3DTLVERTEX *pv[],
  492. TEXCOORDS tc[] )
  493. {
  494. DWORD Flags = pContext->Flags;
  495. float PixelArea;
  496. PixelArea = (((pv[0]->sx - pv[2]->sx) * (pv[1]->sy - pv[2]->sy)) -
  497. ((pv[1]->sx - pv[2]->sx) * (pv[0]->sy - pv[2]->sy)));
  498. if (CULLED(pContext,PixelArea))
  499. {
  500. return 1;
  501. }
  502. pContext->R3flushDueToTexCoordAdjust = 0;
  503. #if TEXSHIFT
  504. __TextureShift( pContext, tc, SHIFT_SET_0 );
  505. #endif
  506. return 0;
  507. } // __BackfaceCullSingleTex
  508. //-----------------------------------------------------------------------------
  509. //
  510. // __BackfaceCullAndMipMap
  511. //
  512. //-----------------------------------------------------------------------------
  513. int _inline
  514. __BackfaceCullAndMipMap(
  515. P3_D3DCONTEXT *pContext,
  516. D3DTLVERTEX *pv[],
  517. TEXCOORDS tc[] )
  518. {
  519. DWORD Flags = pContext->Flags;
  520. float PixelArea;
  521. int iNewMipLevel;
  522. P3_SURF_INTERNAL* pTexture;
  523. P3_THUNKEDDATA* pThisDisplay = pContext->pThisDisplay;
  524. P3_DMA_DEFS();
  525. PixelArea = (((pv[0]->sx - pv[2]->sx) * (pv[1]->sy - pv[2]->sy)) -
  526. ((pv[1]->sx - pv[2]->sx) * (pv[0]->sy - pv[2]->sy)));
  527. if (CULLED(pContext,PixelArea))
  528. {
  529. return 1;
  530. }
  531. // 39 for vertex data, 2 for triangle and 4 for possible LOD change
  532. // for the three vertex case - the one vertex case will check for
  533. // too much but this shouldn't be a problem.
  534. P3_DMA_GET_BUFFER_ENTRIES( 4 );
  535. pContext->R3flushDueToTexCoordAdjust = 0;
  536. if( Flags & SURFACE_TEXTURING )
  537. {
  538. float TextureArea, textureAreaFactor;
  539. int maxLevel;
  540. pTexture = pContext->pCurrentTexture[TEXSTAGE_0];
  541. // Setup LOD of texture # 0 (if necessary)
  542. if( pContext->bTex0Valid &&
  543. ( pContext->TextureStageState[TEXSTAGE_0].m_dwVal[D3DTSS_MIPFILTER] != D3DTFP_NONE )
  544. && pTexture->bMipMap )
  545. {
  546. maxLevel = pTexture->iMipLevels - 1;
  547. textureAreaFactor = pTexture->fArea * pContext->MipMapLODBias[TEXSTAGE_0];
  548. TextureArea = (((tc[0].tu1 - tc[2].tu1) * (tc[1].tv1 - tc[2].tv1)) -
  549. ((tc[1].tu1 - tc[2].tu1) * (tc[0].tv1 - tc[2].tv1))) * textureAreaFactor;
  550. // Ensure that both of these values are positive from now on.
  551. *(signed long *)&PixelArea &= ~(1 << 31);
  552. *(signed long *)&TextureArea &= ~(1 << 31);
  553. FIND_PERMEDIA_MIPLEVEL();
  554. DISPDBG((DBGLVL,"iNewMipLevel = %x",iNewMipLevel));
  555. SEND_P3_DATA( LOD, iNewMipLevel << 8 );
  556. }
  557. pTexture = pContext->pCurrentTexture[TEXSTAGE_1];
  558. // Setup LOD of texture # 1 (if necessary)
  559. if( pContext->bTex1Valid && ( pContext->TextureStageState[TEXSTAGE_1].m_dwVal[D3DTSS_MIPFILTER] != D3DTFP_NONE )
  560. && pTexture->bMipMap )
  561. {
  562. ASSERTDD( pContext->bTex0Valid, "Second texture valid when first isn't" );
  563. maxLevel = pTexture->iMipLevels - 1;
  564. textureAreaFactor = pTexture->fArea * pContext->MipMapLODBias[TEXSTAGE_1];
  565. TextureArea = (((tc[0].tu2 - tc[2].tu2) * (tc[1].tv2 - tc[2].tv2)) -
  566. ((tc[1].tu2 - tc[2].tu2) * (tc[0].tv2 - tc[2].tv2))) * textureAreaFactor;
  567. // Ensure that both of these values are positive from now on.
  568. *(signed long *)&PixelArea &= ~(1 << 31);
  569. *(signed long *)&TextureArea &= ~(1 << 31);
  570. FIND_PERMEDIA_MIPLEVEL();
  571. SEND_P3_DATA( LOD1, iNewMipLevel << 8 );
  572. }
  573. if( pContext->RenderStates[D3DRENDERSTATE_WRAP0] )
  574. {
  575. WRAP_R3( tu1, pContext->RenderStates[D3DRENDERSTATE_WRAP0] & D3DWRAP_U, TRUE );
  576. WRAP_R3( tv1, pContext->RenderStates[D3DRENDERSTATE_WRAP0] & D3DWRAP_V, TRUE );
  577. }
  578. else
  579. {
  580. #if TEXSHIFT
  581. __TextureShift( pContext, tc, SHIFT_SET_0 );
  582. #endif
  583. }
  584. if( pContext->RenderStates[D3DRENDERSTATE_WRAP1] )
  585. {
  586. WRAP_R3( tu2, pContext->RenderStates[D3DRENDERSTATE_WRAP1] & D3DWRAP_U, TRUE );
  587. WRAP_R3( tv2, pContext->RenderStates[D3DRENDERSTATE_WRAP1] & D3DWRAP_V, TRUE );
  588. }
  589. else
  590. {
  591. #if TEXSHIFT
  592. __TextureShift( pContext, tc, SHIFT_SET_1 );
  593. #endif
  594. }
  595. }
  596. P3_DMA_COMMIT_BUFFER();
  597. return 0;
  598. } // __BackfaceCullAndMipMap
  599. //-----------------------------------------------------------------------------
  600. //
  601. // __ProcessTri_1Vtx_NoTexture
  602. //
  603. //-----------------------------------------------------------------------------
  604. int
  605. __ProcessTri_1Vtx_NoTexture(
  606. P3_D3DCONTEXT *pContext,
  607. D3DTLVERTEX *pv[],
  608. int vtx )
  609. {
  610. P3_THUNKEDDATA* pThisDisplay = pContext->pThisDisplay;
  611. DWORD Flags = pContext->Flags;
  612. ULONG renderCmd = pContext->RenderCommand;
  613. P3_DMA_DEFS();
  614. #if CULL_HERE
  615. if( __BackfaceCullNoTexture( pContext, pv ))
  616. return 1;
  617. #endif
  618. P3_DMA_GET_BUFFER_ENTRIES( 9 );
  619. if( pContext->Flags & SURFACE_GOURAUD )
  620. {
  621. // 9 DWORDS.
  622. SEND_R3FVFVERTEX_XYZ_RGBA_SFOG(V0FloatS_Tag + (vtx*16), vtx);
  623. }
  624. else
  625. {
  626. DWORD Col0 = FVFCOLOR(pContext->pProvokingVertex)->color;
  627. if( Flags & SURFACE_SPECULAR )
  628. {
  629. DWORD Spec0 = GET_SPEC( FVFSPEC(pContext->pProvokingVertex)->specular );
  630. CLAMP8888( Col0, Col0, Spec0 );
  631. }
  632. if( Flags & SURFACE_FOGENABLE )
  633. {
  634. // 8 DWORDS.
  635. SEND_R3FVFVERTEX_XYZ_FOG(V0FloatS_Tag + (vtx*16), vtx);
  636. }
  637. else
  638. {
  639. // 7 DWORDS.
  640. SEND_R3FVFVERTEX_XYZ(V0FloatS_Tag + (vtx*16), vtx);
  641. }
  642. // 2 DWORDS.
  643. SEND_P3_DATA(ConstantColor, RGBA_MAKE(RGBA_GETBLUE(Col0),
  644. RGBA_GETGREEN(Col0),
  645. RGBA_GETRED(Col0),
  646. RGBA_GETALPHA(Col0)));
  647. }
  648. RENDER_TRAPEZOID(renderCmd);
  649. DRAW_TRIANGLE();
  650. P3_DMA_COMMIT_BUFFER();
  651. return 0;
  652. } // __ProcessTri_1Vtx_NoTexture
  653. //-----------------------------------------------------------------------------
  654. //
  655. // __ProcessTri_3Vtx_NoTexture
  656. //
  657. //-----------------------------------------------------------------------------
  658. int
  659. __ProcessTri_3Vtx_NoTexture(
  660. P3_D3DCONTEXT *pContext,
  661. D3DTLVERTEX *pv[],
  662. int WireEdgeFlags)
  663. {
  664. P3_THUNKEDDATA* pThisDisplay = pContext->pThisDisplay;
  665. DWORD Flags = pContext->Flags;
  666. ULONG renderCmd = pContext->RenderCommand;
  667. P3_DMA_DEFS();
  668. #if CULL_HERE
  669. if( __BackfaceCullNoTexture( pContext, pv ))
  670. return 1;
  671. #endif
  672. P3_DMA_GET_BUFFER_ENTRIES( 20 );
  673. if( pContext->Flags & SURFACE_GOURAUD )
  674. {
  675. SEND_R3FVFVERTEX_XYZ_RGBA_SFOG(V0FloatS_Tag, 0);
  676. SEND_R3FVFVERTEX_XYZ_RGBA_SFOG(V1FloatS_Tag, 1);
  677. SEND_R3FVFVERTEX_XYZ_RGBA_SFOG(V2FloatS_Tag, 2);
  678. }
  679. else
  680. {
  681. DWORD Col0 = FVFCOLOR(pContext->pProvokingVertex)->color;
  682. if( Flags & SURFACE_SPECULAR )
  683. {
  684. DWORD Spec0 = GET_SPEC( FVFSPEC(pContext->pProvokingVertex)->specular );
  685. CLAMP8888( Col0, Col0, Spec0 );
  686. }
  687. if( Flags & SURFACE_FOGENABLE )
  688. {
  689. SEND_R3FVFVERTEX_XYZ_FOG(V0FloatS_Tag, 0);
  690. SEND_R3FVFVERTEX_XYZ_FOG(V1FloatS_Tag, 1);
  691. SEND_R3FVFVERTEX_XYZ_FOG(V2FloatS_Tag, 2);
  692. }
  693. else
  694. {
  695. SEND_R3FVFVERTEX_XYZ(V0FloatS_Tag, 0);
  696. SEND_R3FVFVERTEX_XYZ(V1FloatS_Tag, 1);
  697. SEND_R3FVFVERTEX_XYZ(V2FloatS_Tag, 2);
  698. }
  699. SEND_P3_DATA(ConstantColor, RGBA_MAKE(RGBA_GETBLUE(Col0),
  700. RGBA_GETGREEN(Col0),
  701. RGBA_GETRED(Col0),
  702. RGBA_GETALPHA(Col0)));
  703. }
  704. RENDER_TRAPEZOID(renderCmd);
  705. DRAW_TRIANGLE();
  706. P3_DMA_COMMIT_BUFFER();
  707. return 0;
  708. } // __ProcessTri_3Vtx_NoTexture
  709. //-----------------------------------------------------------------------------
  710. //
  711. // __ProcessTri_1Vtx_PerspSingleTexGouraud
  712. //
  713. //-----------------------------------------------------------------------------
  714. int
  715. __ProcessTri_1Vtx_PerspSingleTexGouraud(
  716. P3_D3DCONTEXT *pContext,
  717. D3DTLVERTEX *pv[],
  718. int vtx )
  719. {
  720. P3_THUNKEDDATA* pThisDisplay = pContext->pThisDisplay;
  721. TEXCOORDS tc[3];
  722. DWORD q[3];
  723. ULONG renderCmd = pContext->RenderCommand;
  724. #if DX8_3DTEXTURES
  725. P3_SURF_INTERNAL* pTexture = pContext->pCurrentTexture[TEXSTAGE_0];
  726. BOOL b3DTexture = (pTexture ? pTexture->b3DTexture : FALSE);
  727. #endif // DX8_3DTEXTURES
  728. P3_DMA_DEFS();
  729. // We need to refresh all texture coords as they will have been modified
  730. // by the scale by Q and potentially D3D wrapping or TextureShift.
  731. #if DX8_3DTEXTURES
  732. if (b3DTexture)
  733. {
  734. GET_TC_3DTEX(0); GET_TC_3DTEX(1); GET_TC_3DTEX(2);
  735. }
  736. else
  737. {
  738. GET_TC(0); GET_TC(1); GET_TC(2);
  739. }
  740. #else
  741. GET_TC(0); GET_TC(1); GET_TC(2);
  742. #endif // DX8_3DTEXTURES
  743. #if CULL_HERE
  744. if( __BackfaceCullSingleTex( pContext, pv, tc ))
  745. return 1;
  746. #endif
  747. P3_DMA_GET_BUFFER_ENTRIES( 15 );
  748. q[vtx] = *(DWORD *)&(pv[vtx]->rhw);
  749. #if DX8_3DTEXTURES
  750. if (b3DTexture)
  751. {
  752. SCALE_BY_Q_3DTEX( vtx );
  753. }
  754. else
  755. {
  756. SCALE_BY_Q( vtx );
  757. }
  758. #else
  759. SCALE_BY_Q( vtx );
  760. #endif // DX8_3DTEXTURES
  761. #if DX8_3DTEXTURES
  762. if (b3DTexture)
  763. {
  764. SEND_R3FVFVERTEX_3DTEX(V0FloatS1_Tag + (vtx*16), vtx);
  765. }
  766. #endif // DX8_3DTEXTURES
  767. SEND_R3FVFVERTEX_XYZ_STQ_RGBA_SFOG(V0FloatS_Tag + (vtx*16), vtx);
  768. RENDER_TRAPEZOID(renderCmd);
  769. DRAW_TRIANGLE();
  770. P3_DMA_COMMIT_BUFFER();
  771. return pContext->R3flushDueToTexCoordAdjust;
  772. } // __ProcessTri_1Vtx_PerspSingleTexGouraud
  773. //-----------------------------------------------------------------------------
  774. //
  775. // __ProcessTri_3Vtx_PerspSingleTexGouraud
  776. //
  777. //-----------------------------------------------------------------------------
  778. int
  779. __ProcessTri_3Vtx_PerspSingleTexGouraud(
  780. P3_D3DCONTEXT *pContext,
  781. D3DTLVERTEX *pv[],
  782. int WireEdgeFlags )
  783. {
  784. P3_THUNKEDDATA* pThisDisplay = pContext->pThisDisplay;
  785. TEXCOORDS tc[3];
  786. DWORD q[3];
  787. int forcedQ = 0;
  788. ULONG renderCmd = pContext->RenderCommand;
  789. #if DX8_3DTEXTURES
  790. P3_SURF_INTERNAL* pTexture = pContext->pCurrentTexture[TEXSTAGE_0];
  791. BOOL b3DTexture = (pTexture ? pTexture->b3DTexture : FALSE);
  792. #endif // DX8_3DTEXTURES
  793. P3_DMA_DEFS();
  794. #if DX8_3DTEXTURES
  795. if (b3DTexture)
  796. {
  797. GET_TC_3DTEX(0); GET_TC_3DTEX(1); GET_TC_3DTEX(2);
  798. }
  799. else
  800. {
  801. GET_TC(0); GET_TC(1); GET_TC(2);
  802. }
  803. #else
  804. GET_TC(0); GET_TC(1); GET_TC(2);
  805. #endif // DX8_3DTEXTURES
  806. #if CULL_HERE
  807. if( __BackfaceCullSingleTex( pContext, pv, tc ))
  808. return 1;
  809. #endif
  810. P3_DMA_GET_BUFFER_ENTRIES( 26 );
  811. q[0] = *(DWORD *)&(pv[0]->rhw);
  812. q[1] = *(DWORD *)&(pv[1]->rhw);
  813. q[2] = *(DWORD *)&(pv[2]->rhw);
  814. // Check for equal Q's
  815. if((( q[0] ^ q[1] ) | ( q[1] ^ q[2] )) == 0 )
  816. {
  817. // Force to 1.0f
  818. forcedQ = q[0] = q[1] = q[2] = 0x3f800000;
  819. }
  820. else
  821. {
  822. #if DX8_3DTEXTURES
  823. if (b3DTexture)
  824. {
  825. SCALE_BY_Q_3DTEX( 0 );
  826. SCALE_BY_Q_3DTEX( 1 );
  827. SCALE_BY_Q_3DTEX( 2 );
  828. }
  829. else
  830. {
  831. SCALE_BY_Q( 0 );
  832. SCALE_BY_Q( 1 );
  833. SCALE_BY_Q( 2 );
  834. }
  835. #else
  836. SCALE_BY_Q( 0 );
  837. SCALE_BY_Q( 1 );
  838. SCALE_BY_Q( 2 );
  839. #endif // DX8_3DTEXTURES
  840. }
  841. #if DX8_3DTEXTURES
  842. if (b3DTexture)
  843. {
  844. SEND_R3FVFVERTEX_3DTEX(V0FloatS1_Tag, 0);
  845. }
  846. #endif // DX8_3DTEXTURES
  847. SEND_R3FVFVERTEX_XYZ_STQ_RGBA_SFOG(V0FloatS_Tag, 0);
  848. #if DX8_3DTEXTURES
  849. if (b3DTexture)
  850. {
  851. SEND_R3FVFVERTEX_3DTEX(V1FloatS1_Tag, 1);
  852. }
  853. #endif // DX8_3DTEXTURES
  854. SEND_R3FVFVERTEX_XYZ_STQ_RGBA_SFOG(V1FloatS_Tag, 1);
  855. P3_DMA_COMMIT_BUFFER();
  856. P3_DMA_GET_BUFFER_ENTRIES( 15 );
  857. #if DX8_3DTEXTURES
  858. if (b3DTexture)
  859. {
  860. SEND_R3FVFVERTEX_3DTEX(V2FloatS1_Tag, 2);
  861. }
  862. #endif // DX8_3DTEXTURES
  863. SEND_R3FVFVERTEX_XYZ_STQ_RGBA_SFOG(V2FloatS_Tag, 2);
  864. RENDER_TRAPEZOID(renderCmd);
  865. DRAW_TRIANGLE();
  866. P3_DMA_COMMIT_BUFFER();
  867. return ( pContext->R3flushDueToTexCoordAdjust | forcedQ );
  868. } // __ProcessTri_3Vtx_PerspSingleTexGouraud
  869. //-----------------------------------------------------------------------------
  870. //
  871. // __ProcessTri_1Vtx_Generic
  872. //
  873. //-----------------------------------------------------------------------------
  874. int
  875. __ProcessTri_1Vtx_Generic(
  876. P3_D3DCONTEXT *pContext,
  877. D3DTLVERTEX *pv[],
  878. int vtx )
  879. {
  880. P3_THUNKEDDATA* pThisDisplay = pContext->pThisDisplay;
  881. DWORD Flags = pContext->Flags;
  882. TEXCOORDS tc[3];
  883. DWORD q[3];
  884. ULONG renderCmd = pContext->RenderCommand;
  885. P3_DMA_DEFS();
  886. // We need to refresh all texture coords as they will have been modified
  887. // by the scale by Q and potentially D3D wrapping or TextureShift.
  888. GET_TEXCOORDS();
  889. if( __BackfaceCullAndMipMap( pContext, pv, tc ))
  890. return 1;
  891. if( Flags & SURFACE_PERSPCORRECT )
  892. {
  893. q[vtx] = *(DWORD *)&(pv[vtx]->rhw);
  894. SCALE_BY_Q( vtx );
  895. }
  896. // Send vertex data including check for flat shading
  897. P3_DMA_GET_BUFFER_ENTRIES( 16 );
  898. if( pContext->Flags & SURFACE_GOURAUD )
  899. {
  900. // 9 DWORDS.
  901. SEND_R3FVFVERTEX_XYZ_STQ_RGBA_SFOG(V0FloatS_Tag + (vtx*16), vtx);
  902. }
  903. else
  904. {
  905. DWORD Col0 = FVFCOLOR(pContext->pProvokingVertex)->color;
  906. if( Flags & SURFACE_SPECULAR )
  907. {
  908. DWORD Spec0 = GET_SPEC( FVFSPEC(pContext->pProvokingVertex)->specular );
  909. CLAMP8888( Col0, Col0, Spec0 );
  910. }
  911. if( Flags & SURFACE_FOGENABLE )
  912. {
  913. // 8 DWORDS.
  914. SEND_R3FVFVERTEX_XYZ_STQ_FOG(V0FloatS_Tag + (vtx*16), vtx);
  915. }
  916. else
  917. {
  918. // 7 DWORDS.
  919. SEND_R3FVFVERTEX_XYZ_STQ(V0FloatS_Tag + (vtx*16), vtx);
  920. }
  921. // 2 DWORDS.
  922. SEND_P3_DATA(ConstantColor,
  923. RGBA_MAKE(RGBA_GETBLUE(Col0),
  924. RGBA_GETGREEN(Col0),
  925. RGBA_GETRED(Col0),
  926. RGBA_GETALPHA(Col0)));
  927. }
  928. // Send the second set of texture coordinates including scale-by-q
  929. if( pContext->iTexStage[1] != -1
  930. && ( pContext->FVFData.dwTexOffset[0] != pContext->FVFData.dwTexOffset[1]))
  931. {
  932. DISPDBG((DBGLVL,"Sending 2nd texture coordinates"));
  933. if( Flags & SURFACE_PERSPCORRECT )
  934. {
  935. SCALE_BY_Q2( vtx );
  936. }
  937. // 4 DWORDS.
  938. SEND_R3FVFVERTEX_STQ2(V0FloatS1_Tag + (vtx*16), vtx);
  939. }
  940. RENDER_TRAPEZOID(renderCmd);
  941. // 2 DWORDS.
  942. DRAW_TRIANGLE();
  943. P3_DMA_COMMIT_BUFFER();
  944. return pContext->R3flushDueToTexCoordAdjust;
  945. } // __ProcessTri_1Vtx_Generic
  946. //-----------------------------------------------------------------------------
  947. //
  948. // __ProcessTri_3Vtx_Generic
  949. //
  950. //-----------------------------------------------------------------------------
  951. int
  952. __ProcessTri_3Vtx_Generic(
  953. P3_D3DCONTEXT *pContext,
  954. D3DTLVERTEX *pv[],
  955. int WireEdgeFlags )
  956. {
  957. P3_THUNKEDDATA* pThisDisplay = pContext->pThisDisplay;
  958. DWORD Flags = pContext->Flags;
  959. TEXCOORDS tc[3];
  960. DWORD q[3];
  961. int forcedQ = 0;
  962. ULONG renderCmd = pContext->RenderCommand;
  963. P3_DMA_DEFS();
  964. GET_TEXCOORDS();
  965. if( __BackfaceCullAndMipMap( pContext, pv, tc ))
  966. return 1;
  967. if( Flags & SURFACE_PERSPCORRECT )
  968. {
  969. q[0] = *(DWORD *)&(pv[0]->rhw);
  970. q[1] = *(DWORD *)&(pv[1]->rhw);
  971. q[2] = *(DWORD *)&(pv[2]->rhw);
  972. // Check for equal Q's
  973. if((( q[0] ^ q[1] ) | ( q[1] ^ q[2] )) == 0 )
  974. {
  975. // Force to 1.0f
  976. forcedQ = q[0] = q[1] = q[2] = 0x3f800000;
  977. }
  978. else
  979. {
  980. SCALE_BY_Q( 0 );
  981. SCALE_BY_Q( 1 );
  982. SCALE_BY_Q( 2 );
  983. }
  984. }
  985. else
  986. {
  987. q[0] = q[1] = q[2] = 0x3f800000;
  988. }
  989. // Send vertex data including check for flat shading
  990. // Worst case 27 DWORDS
  991. P3_DMA_GET_BUFFER_ENTRIES(29);
  992. if( pContext->Flags & SURFACE_GOURAUD )
  993. {
  994. if( Flags & SURFACE_TEXTURING )
  995. {
  996. // 9 DWORDs each.
  997. SEND_R3FVFVERTEX_XYZ_STQ_RGBA_SFOG(V0FloatS_Tag, 0);
  998. SEND_R3FVFVERTEX_XYZ_STQ_RGBA_SFOG(V1FloatS_Tag, 1);
  999. SEND_R3FVFVERTEX_XYZ_STQ_RGBA_SFOG(V2FloatS_Tag, 2);
  1000. }
  1001. else
  1002. {
  1003. // 6 DWORDs each.
  1004. SEND_R3FVFVERTEX_XYZ_RGBA_SFOG(V0FloatS_Tag, 0);
  1005. SEND_R3FVFVERTEX_XYZ_RGBA_SFOG(V1FloatS_Tag, 1);
  1006. SEND_R3FVFVERTEX_XYZ_RGBA_SFOG(V2FloatS_Tag, 2);
  1007. }
  1008. }
  1009. else
  1010. {
  1011. DWORD Col0 = FVFCOLOR(pContext->pProvokingVertex)->color;
  1012. if( Flags & SURFACE_SPECULAR )
  1013. {
  1014. DWORD Spec0 = GET_SPEC( FVFSPEC(pContext->pProvokingVertex)->specular );
  1015. CLAMP8888( Col0, Col0, Spec0 );
  1016. }
  1017. if( Flags & SURFACE_TEXTURING )
  1018. {
  1019. if( Flags & SURFACE_FOGENABLE )
  1020. {
  1021. // 8 DWORDs each.
  1022. SEND_R3FVFVERTEX_XYZ_STQ_FOG(V0FloatS_Tag, 0);
  1023. SEND_R3FVFVERTEX_XYZ_STQ_FOG(V1FloatS_Tag, 1);
  1024. SEND_R3FVFVERTEX_XYZ_STQ_FOG(V2FloatS_Tag, 2);
  1025. }
  1026. else
  1027. {
  1028. // 7 DWORDs each.
  1029. SEND_R3FVFVERTEX_XYZ_STQ(V0FloatS_Tag, 0);
  1030. SEND_R3FVFVERTEX_XYZ_STQ(V1FloatS_Tag, 1);
  1031. SEND_R3FVFVERTEX_XYZ_STQ(V2FloatS_Tag, 2);
  1032. }
  1033. }
  1034. else
  1035. {
  1036. if( Flags & SURFACE_FOGENABLE )
  1037. {
  1038. // 5 DWORDs each.
  1039. SEND_R3FVFVERTEX_XYZ_FOG(V0FloatS_Tag, 0);
  1040. SEND_R3FVFVERTEX_XYZ_FOG(V1FloatS_Tag, 1);
  1041. SEND_R3FVFVERTEX_XYZ_FOG(V2FloatS_Tag, 2);
  1042. }
  1043. else
  1044. {
  1045. // 4 DWORDs each.
  1046. SEND_R3FVFVERTEX_XYZ(V0FloatS_Tag, 0);
  1047. SEND_R3FVFVERTEX_XYZ(V1FloatS_Tag, 1);
  1048. SEND_R3FVFVERTEX_XYZ(V2FloatS_Tag, 2);
  1049. }
  1050. }
  1051. SEND_P3_DATA(ConstantColor,
  1052. RGBA_MAKE(RGBA_GETBLUE(Col0),
  1053. RGBA_GETGREEN(Col0),
  1054. RGBA_GETRED(Col0),
  1055. RGBA_GETALPHA(Col0)));
  1056. }
  1057. // Send the second set of texture coordinates including scale-by-q
  1058. if( pContext->iTexStage[1] != -1
  1059. && ( pContext->FVFData.dwTexOffset[0] != pContext->FVFData.dwTexOffset[1]))
  1060. {
  1061. DISPDBG((DBGLVL,"Sending 2nd texture coordinates"));
  1062. if( Flags & SURFACE_PERSPCORRECT )
  1063. {
  1064. SCALE_BY_Q2( 0 );
  1065. SCALE_BY_Q2( 1 );
  1066. SCALE_BY_Q2( 2 );
  1067. }
  1068. // 12 DWORDS
  1069. P3_DMA_COMMIT_BUFFER();
  1070. P3_DMA_GET_BUFFER_ENTRIES(14);
  1071. // 4 DWORDs each.
  1072. SEND_R3FVFVERTEX_STQ2(V0FloatS1_Tag, 0);
  1073. SEND_R3FVFVERTEX_STQ2(V1FloatS1_Tag, 1);
  1074. SEND_R3FVFVERTEX_STQ2(V2FloatS1_Tag, 2);
  1075. }
  1076. RENDER_TRAPEZOID(renderCmd);
  1077. DRAW_TRIANGLE();
  1078. P3_DMA_COMMIT_BUFFER();
  1079. return ( pContext->R3flushDueToTexCoordAdjust | forcedQ );
  1080. } // __ProcessTri_3Vtx_Generic
  1081. //-----------------------------------------------------------------------------
  1082. //
  1083. // __ProcessTri_1Vtx_Wire
  1084. //
  1085. //-----------------------------------------------------------------------------
  1086. int
  1087. __ProcessTri_1Vtx_Wire(
  1088. P3_D3DCONTEXT *pContext,
  1089. D3DTLVERTEX *pv[],
  1090. int vtx )
  1091. {
  1092. DISPDBG((WRNLVL,"WE SHOULDN'T DO __ProcessTri_1Vtx_Wire"));
  1093. return 1;
  1094. } // __ProcessTri_1Vtx_Wire
  1095. //-----------------------------------------------------------------------------
  1096. //
  1097. // __ProcessTri_3Vtx_Wire
  1098. //
  1099. //-----------------------------------------------------------------------------
  1100. int
  1101. __ProcessTri_3Vtx_Wire(
  1102. P3_D3DCONTEXT *pContext,
  1103. D3DTLVERTEX *pv[],
  1104. int WireEdgeFlags )
  1105. {
  1106. P3_THUNKEDDATA* pThisDisplay = pContext->pThisDisplay;
  1107. DWORD Flags = pContext->Flags;
  1108. TEXCOORDS tc[3];
  1109. int i;
  1110. DWORD q[3];
  1111. ULONG renderCmd = pContext->RenderCommand;
  1112. const int edges[] = { SIDE_0, SIDE_1, SIDE_2 };
  1113. P3_DMA_DEFS();
  1114. GET_TEXCOORDS();
  1115. if( __BackfaceCullAndMipMap( pContext, pv, tc ))
  1116. return 1;
  1117. RENDER_LINE(renderCmd);
  1118. if( Flags & SURFACE_PERSPCORRECT )
  1119. {
  1120. q[0] = *(DWORD *)&(pv[0]->rhw);
  1121. q[1] = *(DWORD *)&(pv[1]->rhw);
  1122. q[2] = *(DWORD *)&(pv[2]->rhw);
  1123. SCALE_BY_Q( 0 );
  1124. SCALE_BY_Q( 1 );
  1125. SCALE_BY_Q( 2 );
  1126. if(pContext->iTexStage[1] != -1 )
  1127. {
  1128. SCALE_BY_Q2( 0 );
  1129. SCALE_BY_Q2( 1 );
  1130. SCALE_BY_Q2( 2 );
  1131. }
  1132. }
  1133. // Send vertex data including check for flat shading
  1134. for( i = 0; i < 3; i++ )
  1135. {
  1136. int v0, v1;
  1137. v0 = i;
  1138. v1 = i + 1;
  1139. if( v1 == 3 )
  1140. v1 = 0;
  1141. if( WireEdgeFlags & edges[i] )
  1142. {
  1143. P3_DMA_GET_BUFFER_ENTRIES(30);
  1144. if( pContext->Flags & SURFACE_GOURAUD )
  1145. {
  1146. // 9 DWORDs each.
  1147. SEND_R3FVFVERTEX_XYZ_STQ_RGBA_SFOG(V0FloatS_Tag, v0);
  1148. SEND_R3FVFVERTEX_XYZ_STQ_RGBA_SFOG(V1FloatS_Tag, v1);
  1149. }
  1150. else
  1151. {
  1152. DWORD Col0 = FVFCOLOR(pContext->pProvokingVertex)->color;
  1153. if( Flags & SURFACE_SPECULAR )
  1154. {
  1155. DWORD Spec0 = GET_SPEC( FVFSPEC(pContext->pProvokingVertex)->specular );
  1156. CLAMP8888( Col0, Col0, Spec0 );
  1157. }
  1158. if( Flags & SURFACE_FOGENABLE )
  1159. {
  1160. // 6 DWORDs each.
  1161. SEND_R3FVFVERTEX_XYZ_STQ_FOG(V0FloatS_Tag, v0);
  1162. SEND_R3FVFVERTEX_XYZ_STQ_FOG(V1FloatS_Tag, v1);
  1163. }
  1164. else
  1165. {
  1166. // 7 DWORDs each.
  1167. SEND_R3FVFVERTEX_XYZ_STQ(V0FloatS_Tag, v0);
  1168. SEND_R3FVFVERTEX_XYZ_STQ(V1FloatS_Tag, v1);
  1169. }
  1170. SEND_P3_DATA(ConstantColor,
  1171. RGBA_MAKE(RGBA_GETBLUE(Col0),
  1172. RGBA_GETGREEN(Col0),
  1173. RGBA_GETRED(Col0),
  1174. RGBA_GETALPHA(Col0)));
  1175. }
  1176. // Send the second set of texture coordinates
  1177. if( pContext->iTexStage[1] != -1
  1178. && ( pContext->FVFData.dwTexOffset[0] != pContext->FVFData.dwTexOffset[1] ))
  1179. {
  1180. // 4 DWORDs each.
  1181. SEND_R3FVFVERTEX_STQ2(V0FloatS1_Tag, v0);
  1182. SEND_R3FVFVERTEX_STQ2(V1FloatS1_Tag, v1);
  1183. }
  1184. DRAW_LINE();
  1185. P3_DMA_COMMIT_BUFFER();
  1186. }
  1187. }
  1188. return 1;
  1189. } // __ProcessTri_3Vtx_Wire
  1190. //-----------------------------------------------------------------------------
  1191. //
  1192. // __ProcessTri_1Vtx_Point
  1193. //
  1194. //-----------------------------------------------------------------------------
  1195. int
  1196. __ProcessTri_1Vtx_Point(
  1197. P3_D3DCONTEXT *pContext,
  1198. D3DTLVERTEX *pv[],
  1199. int vtx )
  1200. {
  1201. DISPDBG((WRNLVL,"WE SHOULDN'T DO __ProcessTri_1Vtx_Wire"));
  1202. return 1;
  1203. } // __ProcessTri_1Vtx_Point
  1204. //-----------------------------------------------------------------------------
  1205. //
  1206. // __ProcessTri_3Vtx_Point
  1207. //
  1208. //-----------------------------------------------------------------------------
  1209. int
  1210. __ProcessTri_3Vtx_Point(
  1211. P3_D3DCONTEXT *pContext,
  1212. D3DTLVERTEX *pv[],
  1213. int WireEdgeFlags )
  1214. {
  1215. P3_THUNKEDDATA* pThisDisplay = pContext->pThisDisplay;
  1216. DWORD Flags = pContext->Flags;
  1217. TEXCOORDS tc[3];
  1218. int i;
  1219. DWORD q[3];
  1220. ULONG renderCmd = pContext->RenderCommand;
  1221. const int edges[] = { SIDE_0, SIDE_1, SIDE_2 };
  1222. P3_DMA_DEFS();
  1223. GET_TEXCOORDS();
  1224. if( __BackfaceCullAndMipMap( pContext, pv, tc ))
  1225. return 1;
  1226. RENDER_POINT(renderCmd);
  1227. if( Flags & SURFACE_PERSPCORRECT )
  1228. {
  1229. q[0] = *(DWORD *)&(pv[0]->rhw);
  1230. q[1] = *(DWORD *)&(pv[1]->rhw);
  1231. q[2] = *(DWORD *)&(pv[2]->rhw);
  1232. SCALE_BY_Q( 0 );
  1233. SCALE_BY_Q( 1 );
  1234. SCALE_BY_Q( 2 );
  1235. if(pContext->iTexStage[1] != -1)
  1236. {
  1237. SCALE_BY_Q2( 0 );
  1238. SCALE_BY_Q2( 1 );
  1239. SCALE_BY_Q2( 2 );
  1240. }
  1241. }
  1242. // Send vertex data including check for flat shading
  1243. for( i = 0; i < 3; i++ )
  1244. {
  1245. int v0, v1;
  1246. v0 = i;
  1247. v1 = i + 1;
  1248. if( v1 == 3 )
  1249. v1 = 0;
  1250. if( WireEdgeFlags & edges[i] )
  1251. {
  1252. P3_DMA_GET_BUFFER_ENTRIES( 16 );
  1253. if( pContext->Flags & SURFACE_GOURAUD )
  1254. {
  1255. SEND_R3FVFVERTEX_XYZ_STQ_RGBA_SFOG(V0FloatS_Tag, v0);
  1256. }
  1257. else
  1258. {
  1259. DWORD Col0 = FVFCOLOR(pContext->pProvokingVertex)->color;
  1260. if( Flags & SURFACE_SPECULAR )
  1261. {
  1262. DWORD Spec0 = GET_SPEC( FVFSPEC(pContext->pProvokingVertex)->specular );
  1263. CLAMP8888( Col0, Col0, Spec0 );
  1264. }
  1265. if( Flags & SURFACE_FOGENABLE )
  1266. {
  1267. SEND_R3FVFVERTEX_XYZ_STQ_FOG(V0FloatS_Tag, v0);
  1268. }
  1269. else
  1270. {
  1271. SEND_R3FVFVERTEX_XYZ_STQ(V0FloatS_Tag, v0);
  1272. }
  1273. SEND_P3_DATA(ConstantColor,
  1274. RGBA_MAKE(RGBA_GETBLUE(Col0),
  1275. RGBA_GETGREEN(Col0),
  1276. RGBA_GETRED(Col0),
  1277. RGBA_GETALPHA(Col0)));
  1278. }
  1279. // Send the second set of texture coordinates
  1280. if( pContext->iTexStage[1] != -1
  1281. && ( pContext->FVFData.dwTexOffset[0] != pContext->FVFData.dwTexOffset[1]))
  1282. {
  1283. DISPDBG((DBGLVL,"Sending 2nd texture coordinates"));
  1284. SEND_R3FVFVERTEX_STQ2(V0FloatS1_Tag, v0);
  1285. }
  1286. DRAW_POINT();
  1287. P3_DMA_COMMIT_BUFFER();
  1288. }
  1289. }
  1290. return 1;
  1291. } // __ProcessTri_3Vtx_Point
  1292. //-----------------------------------------------------------------------------
  1293. //
  1294. // _D3D_R3_DP2_TriangleList
  1295. //
  1296. // Render D3DDP2OP_TRIANGLELIST triangles
  1297. //
  1298. //-----------------------------------------------------------------------------
  1299. void
  1300. _D3D_R3_DP2_TriangleList(
  1301. P3_D3DCONTEXT *pContext,
  1302. DWORD dwPrimCount,
  1303. LPBYTE lpPrim,
  1304. LPD3DTLVERTEX lpVertices,
  1305. DWORD dwVertexBufferLen,
  1306. BOOL *pbError)
  1307. {
  1308. DWORD dwIndex, i;
  1309. D3DTLVERTEX *pv[3];
  1310. DBG_ENTRY(_D3D_R3_DP2_TriangleList);
  1311. dwIndex = ((D3DHAL_DP2TRIANGLELIST*)lpPrim)->wVStart;
  1312. pv[0] = LP_FVF_VERTEX(lpVertices, dwIndex);
  1313. pv[1] = LP_FVF_NXT_VTX(pv[0]);
  1314. pv[2] = LP_FVF_NXT_VTX(pv[1]);
  1315. // Check first & last vertex
  1316. CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, dwIndex);
  1317. CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, dwIndex + 3*dwPrimCount - 1);
  1318. pContext->dwProvokingVertex = 0;
  1319. for( i = 0; i < dwPrimCount; i++ )
  1320. {
  1321. pContext->pProvokingVertex = pv[pContext->dwProvokingVertex];
  1322. (*pContext->pRendTri_3V)( pContext, pv, ALL_SIDES);
  1323. pv[0] = LP_FVF_NXT_VTX(pv[2]);
  1324. pv[1] = LP_FVF_NXT_VTX(pv[0]);
  1325. pv[2] = LP_FVF_NXT_VTX(pv[1]);
  1326. }
  1327. DBG_EXIT(_D3D_R3_DP2_TriangleList,0);
  1328. } // _D3D_R3_DP2_TriangleList
  1329. //-----------------------------------------------------------------------------
  1330. //
  1331. // _D3D_R3_DP2_TriangleFan
  1332. //
  1333. // Render a D3DDP2OP_TRIANGLEFAN triangle
  1334. //
  1335. //-----------------------------------------------------------------------------
  1336. void
  1337. _D3D_R3_DP2_TriangleFan(
  1338. P3_D3DCONTEXT *pContext,
  1339. DWORD dwPrimCount,
  1340. LPBYTE lpPrim,
  1341. LPD3DTLVERTEX lpVertices,
  1342. DWORD dwVertexBufferLen,
  1343. BOOL *pbError)
  1344. {
  1345. DWORD dwIndex, i;
  1346. D3DTLVERTEX *pv[3];
  1347. int vtx, lastVtx, bCulled;
  1348. SAVE_CULLING_STATE(pContext);
  1349. DBG_ENTRY(_D3D_R3_DP2_TriangleFan);
  1350. lastVtx = vtx = 2;
  1351. dwIndex = ((D3DHAL_DP2TRIANGLEFAN*)lpPrim)->wVStart;
  1352. pv[0] = LP_FVF_VERTEX(lpVertices, dwIndex);
  1353. pv[1] = LP_FVF_NXT_VTX(pv[0]);
  1354. pv[2] = LP_FVF_NXT_VTX(pv[1]);
  1355. // Check first & last vertex
  1356. CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, dwIndex);
  1357. CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, dwIndex + dwPrimCount + 1);
  1358. pContext->dwProvokingVertex = 1;
  1359. pContext->pProvokingVertex = pv[pContext->dwProvokingVertex];
  1360. bCulled = (*pContext->pRendTri_3V)( pContext, pv, ALL_SIDES);
  1361. for( i = 1; i < dwPrimCount; i++ )
  1362. {
  1363. vtx ^= 3; // 2 -> 1, 1 -> 2
  1364. FLIP_CCW_CW_CULLING(pContext);
  1365. pv[vtx] = LP_FVF_NXT_VTX(pv[lastVtx]);
  1366. pContext->dwProvokingVertex = lastVtx;
  1367. pContext->pProvokingVertex = pv[pContext->dwProvokingVertex];
  1368. if( bCulled )
  1369. bCulled = (*pContext->pRendTri_3V)( pContext, pv, ALL_SIDES);
  1370. else
  1371. bCulled = (*pContext->pRendTri_1V)( pContext, pv, vtx );
  1372. lastVtx = vtx;
  1373. }
  1374. RESTORE_CULLING_STATE(pContext);
  1375. DBG_EXIT(_D3D_R3_DP2_TriangleFan,0);
  1376. } // _D3D_R3_DP2_TriangleFan
  1377. //-----------------------------------------------------------------------------
  1378. //
  1379. // _D3D_R3_DP2_TriangleFanImm
  1380. //
  1381. // Render D3DDP2OP_TRIANGLEFAN_IMM triangles
  1382. //
  1383. //-----------------------------------------------------------------------------
  1384. void
  1385. _D3D_R3_DP2_TriangleFanImm(
  1386. P3_D3DCONTEXT *pContext,
  1387. DWORD dwPrimCount,
  1388. LPBYTE lpPrim,
  1389. LPD3DTLVERTEX lpVertices,
  1390. DWORD dwVertexBufferLen,
  1391. BOOL *pbError)
  1392. {
  1393. D3DTLVERTEX *pv[3];
  1394. DWORD i, dwEdgeFlags, eFlags;
  1395. int vtx, lastVtx, bCulled;
  1396. SAVE_CULLING_STATE(pContext);
  1397. DBG_ENTRY(_D3D_R3_DP2_TriangleFanImm);
  1398. lastVtx = vtx = 2;
  1399. // Edge flags are used for wireframe fillmode
  1400. dwEdgeFlags = ((D3DHAL_DP2TRIANGLEFAN_IMM *)lpPrim)->dwEdgeFlags;
  1401. lpPrim += sizeof(D3DHAL_DP2TRIANGLEFAN_IMM);
  1402. // Vertices in an IMM instruction are stored in the
  1403. // command buffer and are DWORD aligned
  1404. lpPrim = (LPBYTE)((ULONG_PTR)( lpPrim + 3 ) & ~3 );
  1405. pv[0] = (LPD3DTLVERTEX)lpPrim;
  1406. pv[1] = LP_FVF_NXT_VTX(pv[0]);
  1407. pv[2] = LP_FVF_NXT_VTX(pv[1]);
  1408. // since data is in the command buffer, we've already verified it as valid
  1409. // Build up edge flags for the next single primitive
  1410. eFlags = ( dwEdgeFlags & 1 ) ? SIDE_0 : 0;
  1411. eFlags |= ( dwEdgeFlags & 2 ) ? SIDE_1 : 0;
  1412. dwEdgeFlags >>= 2;
  1413. pContext->dwProvokingVertex = 1;
  1414. pContext->pProvokingVertex = pv[pContext->dwProvokingVertex];
  1415. bCulled = (*pContext->pRendTri_3V)( pContext, pv, eFlags);
  1416. for( i = 1; i < dwPrimCount; i++ )
  1417. {
  1418. // 2 -> 1, 1 -> 2
  1419. vtx ^= 3;
  1420. FLIP_CCW_CW_CULLING(pContext);
  1421. pv[vtx] = LP_FVF_NXT_VTX(pv[lastVtx]);
  1422. if( i == ( dwPrimCount - 1 ))
  1423. {
  1424. eFlags = ( dwEdgeFlags & 1 ) ? SIDE_1 : 0;
  1425. eFlags |= ( dwEdgeFlags & 2 ) ? SIDE_2 : 0;
  1426. }
  1427. else
  1428. {
  1429. eFlags = ( dwEdgeFlags & 1 ) ? SIDE_1 : 0;
  1430. dwEdgeFlags >>= 1;
  1431. }
  1432. pContext->dwProvokingVertex = lastVtx;
  1433. pContext->pProvokingVertex = pv[pContext->dwProvokingVertex];
  1434. if( bCulled )
  1435. bCulled = (*pContext->pRendTri_3V)( pContext, pv, eFlags);
  1436. else
  1437. bCulled = (*pContext->pRendTri_1V)( pContext, pv, vtx );
  1438. lastVtx = vtx;
  1439. }
  1440. RESTORE_CULLING_STATE(pContext);
  1441. DBG_EXIT(_D3D_R3_DP2_TriangleFanImm,0);
  1442. } // _D3D_R3_DP2_TriangleFanImm
  1443. //-----------------------------------------------------------------------------
  1444. //
  1445. // _D3D_R3_DP2_TriangleStrip
  1446. //
  1447. // Render D3DDP2OP_TRIANGLESTRIP triangles
  1448. //
  1449. //-----------------------------------------------------------------------------
  1450. void
  1451. _D3D_R3_DP2_TriangleStrip(
  1452. P3_D3DCONTEXT *pContext,
  1453. DWORD dwPrimCount,
  1454. LPBYTE lpPrim,
  1455. LPD3DTLVERTEX lpVertices,
  1456. DWORD dwVertexBufferLen,
  1457. BOOL *pbError)
  1458. {
  1459. DWORD dwIndex, i;
  1460. D3DTLVERTEX *pv[3];
  1461. int vtx_a, vtx_b, lastVtx, bCulled;
  1462. SAVE_CULLING_STATE(pContext);
  1463. DBG_ENTRY(_D3D_R3_DP2_TriangleStrip);
  1464. dwIndex = ((D3DHAL_DP2TRIANGLEFAN*)lpPrim)->wVStart;
  1465. pv[0] = LP_FVF_VERTEX(lpVertices, dwIndex);
  1466. pv[1] = LP_FVF_NXT_VTX(pv[0]);
  1467. pv[2] = LP_FVF_NXT_VTX(pv[1]);
  1468. // Check first & last vertex
  1469. CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, dwIndex);
  1470. CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, dwIndex + dwPrimCount + 1);
  1471. pContext->dwProvokingVertex = 0;
  1472. pContext->pProvokingVertex = pv[pContext->dwProvokingVertex];
  1473. bCulled = (*pContext->pRendTri_3V)( pContext, pv, ALL_SIDES);
  1474. lastVtx = 2;
  1475. INIT_VERTEX_INDICES(pContext, vtx_a, vtx_b);
  1476. for( i = 1; i < dwPrimCount; i++ )
  1477. {
  1478. FLIP_CCW_CW_CULLING(pContext);
  1479. pv[vtx_a] = LP_FVF_NXT_VTX(pv[lastVtx]);
  1480. pContext->pProvokingVertex = pv[pContext->dwProvokingVertex];
  1481. if( bCulled )
  1482. bCulled = (*pContext->pRendTri_3V)( pContext, pv,ALL_SIDES);
  1483. else
  1484. bCulled = (*pContext->pRendTri_1V)( pContext, pv, vtx_a );
  1485. lastVtx = vtx_a;
  1486. CYCLE_VERTEX_INDICES(pContext, vtx_a, vtx_b);
  1487. }
  1488. RESTORE_CULLING_STATE(pContext);
  1489. DBG_EXIT(_D3D_R3_DP2_TriangleStrip,0);
  1490. } // _D3D_R3_DP2_TriangleStrip
  1491. //-----------------------------------------------------------------------------
  1492. //
  1493. // _D3D_R3_DP2_IndexedTriangleStrip
  1494. //
  1495. // Render D3DDP2OP_INDEXEDTRIANGLESTRIP triangles
  1496. //
  1497. //-----------------------------------------------------------------------------
  1498. void
  1499. _D3D_R3_DP2_IndexedTriangleStrip(
  1500. P3_D3DCONTEXT *pContext,
  1501. DWORD dwPrimCount,
  1502. LPBYTE lpPrim,
  1503. LPD3DTLVERTEX lpVertices,
  1504. DWORD dwVertexBufferLen,
  1505. BOOL *pbError)
  1506. {
  1507. DWORD dwIndex0, dwIndex1, dwIndex2, i;
  1508. WORD wVStart;
  1509. D3DTLVERTEX *pv[3];
  1510. int vtx_a, vtx_b, bCulled;
  1511. SAVE_CULLING_STATE(pContext);
  1512. DBG_ENTRY(_D3D_R3_DP2_IndexedTriangleStrip);
  1513. wVStart = ((D3DHAL_DP2STARTVERTEX*)lpPrim)->wVStart;
  1514. lpPrim += sizeof(D3DHAL_DP2STARTVERTEX);
  1515. dwIndex0 = ((D3DHAL_DP2INDEXEDTRIANGLEFAN*)lpPrim)->wV[0];
  1516. dwIndex1 = ((D3DHAL_DP2INDEXEDTRIANGLEFAN*)lpPrim)->wV[1];
  1517. dwIndex2 = ((D3DHAL_DP2INDEXEDTRIANGLEFAN*)lpPrim)->wV[2];
  1518. lpVertices = LP_FVF_VERTEX(lpVertices, wVStart);
  1519. pv[0] = LP_FVF_VERTEX(lpVertices, dwIndex0);
  1520. pv[1] = LP_FVF_VERTEX(lpVertices, dwIndex1);
  1521. pv[2] = LP_FVF_VERTEX(lpVertices, dwIndex2);
  1522. CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, dwIndex0);
  1523. CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, dwIndex1);
  1524. CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, dwIndex2);
  1525. pContext->dwProvokingVertex = 0;
  1526. pContext->pProvokingVertex = pv[pContext->dwProvokingVertex];
  1527. bCulled = (*pContext->pRendTri_3V)( pContext, pv, ALL_SIDES);
  1528. lpPrim += sizeof(WORD);
  1529. INIT_VERTEX_INDICES(pContext, vtx_a, vtx_b);
  1530. for( i = 1; i < dwPrimCount; i++ )
  1531. {
  1532. FLIP_CCW_CW_CULLING(pContext);
  1533. dwIndex2 = ((D3DHAL_DP2INDEXEDTRIANGLEFAN*)lpPrim)->wV[2];
  1534. pv[vtx_a] = LP_FVF_VERTEX(lpVertices, dwIndex2);
  1535. CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, dwIndex2);
  1536. pContext->pProvokingVertex = pv[pContext->dwProvokingVertex];
  1537. if( bCulled )
  1538. bCulled = (*pContext->pRendTri_3V)( pContext, pv, ALL_SIDES);
  1539. else
  1540. bCulled = (*pContext->pRendTri_1V)( pContext, pv, vtx_a );
  1541. lpPrim += sizeof(WORD);
  1542. CYCLE_VERTEX_INDICES(pContext, vtx_a, vtx_b);
  1543. }
  1544. RESTORE_CULLING_STATE(pContext);
  1545. DBG_EXIT(_D3D_R3_DP2_IndexedTriangleStrip,0);
  1546. } // _D3D_R3_DP2_IndexedTriangleStrip
  1547. //-----------------------------------------------------------------------------
  1548. //
  1549. // _D3D_R3_DP2_IndexedTriangleFan
  1550. //
  1551. // Render D3DDP2OP_INDEXEDTRIANGLEFAN triangles
  1552. //
  1553. //-----------------------------------------------------------------------------
  1554. void
  1555. _D3D_R3_DP2_IndexedTriangleFan(
  1556. P3_D3DCONTEXT *pContext,
  1557. DWORD dwPrimCount,
  1558. LPBYTE lpPrim,
  1559. LPD3DTLVERTEX lpVertices,
  1560. DWORD dwVertexBufferLen,
  1561. BOOL *pbError)
  1562. {
  1563. DWORD dwIndex0, dwIndex1, dwIndex2, i;
  1564. WORD wVStart;
  1565. D3DTLVERTEX *pv[3];
  1566. int vtx, lastVtx, bCulled;
  1567. SAVE_CULLING_STATE(pContext);
  1568. DBG_ENTRY(_D3D_R3_DP2_IndexedTriangleFan);
  1569. wVStart = ((D3DHAL_DP2STARTVERTEX*)lpPrim)->wVStart;
  1570. lpPrim += sizeof(D3DHAL_DP2STARTVERTEX);
  1571. dwIndex0 = ((D3DHAL_DP2INDEXEDTRIANGLEFAN*)lpPrim)->wV[0];
  1572. dwIndex1 = ((D3DHAL_DP2INDEXEDTRIANGLEFAN*)lpPrim)->wV[1];
  1573. dwIndex2 = ((D3DHAL_DP2INDEXEDTRIANGLEFAN*)lpPrim)->wV[2];
  1574. lastVtx = vtx = 2;
  1575. pv[0] = LP_FVF_VERTEX(lpVertices, wVStart + dwIndex0);
  1576. pv[1] = LP_FVF_VERTEX(lpVertices, wVStart + dwIndex1);
  1577. pv[2] = LP_FVF_VERTEX(lpVertices, wVStart + dwIndex2);
  1578. CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, (DWORD)(wVStart) + dwIndex0);
  1579. CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, (DWORD)(wVStart) + dwIndex1);
  1580. CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, (DWORD)(wVStart) + dwIndex2);
  1581. pContext->dwProvokingVertex = 1;
  1582. pContext->pProvokingVertex = pv[pContext->dwProvokingVertex];
  1583. bCulled = (*pContext->pRendTri_3V)( pContext, pv, ALL_SIDES);
  1584. lpPrim += sizeof(WORD);
  1585. for( i = 1; i < dwPrimCount; i++ )
  1586. {
  1587. // 2 -> 1, 1 -> 2
  1588. vtx ^= 3;
  1589. FLIP_CCW_CW_CULLING(pContext);
  1590. dwIndex2 = ((D3DHAL_DP2INDEXEDTRIANGLEFAN*)lpPrim)->wV[2];
  1591. pv[vtx] = LP_FVF_VERTEX(lpVertices, wVStart + dwIndex2);
  1592. CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, wVStart + dwIndex2);
  1593. pContext->dwProvokingVertex = lastVtx;
  1594. pContext->pProvokingVertex = pv[pContext->dwProvokingVertex];
  1595. if( bCulled )
  1596. bCulled = (*pContext->pRendTri_3V)( pContext, pv, ALL_SIDES);
  1597. else
  1598. bCulled = (*pContext->pRendTri_1V)( pContext, pv, vtx );
  1599. lastVtx = vtx;
  1600. lpPrim += sizeof(WORD);
  1601. }
  1602. RESTORE_CULLING_STATE(pContext);
  1603. DBG_EXIT(_D3D_R3_DP2_IndexedTriangleFan,0);
  1604. } // _D3D_R3_DP2_IndexedTriangleFan
  1605. //-----------------------------------------------------------------------------
  1606. //
  1607. // _D3D_R3_DP2_IndexedTriangleList
  1608. //
  1609. // Render D3DDP2OP_INDEXEDTRIANGLELIST triangles
  1610. //
  1611. //-----------------------------------------------------------------------------
  1612. void
  1613. _D3D_R3_DP2_IndexedTriangleList(
  1614. P3_D3DCONTEXT *pContext,
  1615. DWORD dwPrimCount,
  1616. LPBYTE lpPrim,
  1617. LPD3DTLVERTEX lpVertices,
  1618. DWORD dwVertexBufferLen,
  1619. BOOL *pbError)
  1620. {
  1621. DWORD dwIndex0, dwIndex1, dwIndex2, i, primData;
  1622. WORD wFlags;
  1623. D3DTLVERTEX *pv[3];
  1624. DBG_ENTRY(_D3D_R3_DP2_IndexedTriangleList);
  1625. pContext->dwProvokingVertex = 0;
  1626. for( i = 0; i < dwPrimCount; i++ )
  1627. {
  1628. dwIndex0 = ((D3DHAL_DP2INDEXEDTRIANGLELIST*)lpPrim)->wV1;
  1629. dwIndex1 = ((D3DHAL_DP2INDEXEDTRIANGLELIST*)lpPrim)->wV2;
  1630. dwIndex2 = ((D3DHAL_DP2INDEXEDTRIANGLELIST*)lpPrim)->wV3;
  1631. wFlags = ((D3DHAL_DP2INDEXEDTRIANGLELIST*)lpPrim)->wFlags;
  1632. pv[0] = LP_FVF_VERTEX(lpVertices, dwIndex0);
  1633. pv[1] = LP_FVF_VERTEX(lpVertices, dwIndex1);
  1634. pv[2] = LP_FVF_VERTEX(lpVertices, dwIndex2);
  1635. CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, dwIndex0);
  1636. CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, dwIndex1);
  1637. CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, dwIndex2);
  1638. lpPrim += sizeof(D3DHAL_DP2INDEXEDTRIANGLELIST);
  1639. pContext->pProvokingVertex = pv[pContext->dwProvokingVertex];
  1640. (*pContext->pRendTri_3V)( pContext, pv, wFlags);
  1641. }
  1642. DBG_EXIT(_D3D_R3_DP2_IndexedTriangleList,0);
  1643. } // _D3D_R3_DP2_IndexedTriangleList
  1644. //-----------------------------------------------------------------------------
  1645. //
  1646. // _D3D_R3_DP2_IndexedTriangleList2
  1647. //
  1648. // Render D3DDP2OP_INDEXEDTRIANGLELIST2 triangles
  1649. //
  1650. //-----------------------------------------------------------------------------
  1651. void
  1652. _D3D_R3_DP2_IndexedTriangleList2(
  1653. P3_D3DCONTEXT *pContext,
  1654. DWORD dwPrimCount,
  1655. LPBYTE lpPrim,
  1656. LPD3DTLVERTEX lpVertices,
  1657. DWORD dwVertexBufferLen,
  1658. BOOL *pbError)
  1659. {
  1660. DWORD dwIndex0, dwIndex1, dwIndex2, i;
  1661. WORD wVStart;
  1662. D3DTLVERTEX *pv[3];
  1663. DBG_ENTRY(_D3D_R3_DP2_IndexedTriangleList2);
  1664. wVStart = ((D3DHAL_DP2STARTVERTEX*)lpPrim)->wVStart;
  1665. lpPrim += sizeof(D3DHAL_DP2STARTVERTEX);
  1666. lpVertices = LP_FVF_VERTEX(lpVertices, wVStart);
  1667. pContext->dwProvokingVertex = 0;
  1668. for( i = 0; i < dwPrimCount; i++ )
  1669. {
  1670. dwIndex0 = ((D3DHAL_DP2INDEXEDTRIANGLELIST2*)lpPrim)->wV1;
  1671. dwIndex1 = ((D3DHAL_DP2INDEXEDTRIANGLELIST2*)lpPrim)->wV2;
  1672. dwIndex2 = ((D3DHAL_DP2INDEXEDTRIANGLELIST2*)lpPrim)->wV3;
  1673. pv[0] = LP_FVF_VERTEX(lpVertices, dwIndex0);
  1674. pv[1] = LP_FVF_VERTEX(lpVertices, dwIndex1);
  1675. pv[2] = LP_FVF_VERTEX(lpVertices, dwIndex2);
  1676. CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, (DWORD)wVStart + dwIndex0);
  1677. CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, (DWORD)wVStart + dwIndex1);
  1678. CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, (DWORD)wVStart + dwIndex2);
  1679. lpPrim += sizeof(D3DHAL_DP2INDEXEDTRIANGLELIST2);
  1680. pContext->pProvokingVertex = pv[pContext->dwProvokingVertex];
  1681. (*pContext->pRendTri_3V)( pContext, pv, ALL_SIDES);
  1682. }
  1683. DBG_EXIT(_D3D_R3_DP2_IndexedTriangleList2,0);
  1684. } // _D3D_R3_DP2_IndexedTriangleList2
  1685. //-----------------------------------------------------------------------------
  1686. //
  1687. // __ProcessLine
  1688. //
  1689. // Render a single line
  1690. //
  1691. //-----------------------------------------------------------------------------
  1692. void
  1693. __ProcessLine(
  1694. P3_D3DCONTEXT *pContext,
  1695. D3DTLVERTEX *pv[],
  1696. D3DTLVERTEX *pProvokingVtx)
  1697. {
  1698. P3_THUNKEDDATA* pThisDisplay = pContext->pThisDisplay;
  1699. DWORD Flags = pContext->Flags;
  1700. TEXCOORDS tc[2];
  1701. DWORD q[2];
  1702. ULONG renderCmd = pContext->RenderCommand;
  1703. P3_DMA_DEFS();
  1704. RENDER_LINE(renderCmd);
  1705. GET_TC(0); GET_TC(1);
  1706. P3_DMA_GET_BUFFER_ENTRIES(22);
  1707. if (pContext->RenderStates[D3DRENDERSTATE_LINEPATTERN])
  1708. {
  1709. // if we are line stippling then reset rendering for each line
  1710. SEND_P3_DATA( UpdateLineStippleCounters , 0);
  1711. }
  1712. if( Flags & SURFACE_PERSPCORRECT )
  1713. {
  1714. q[0] = *(DWORD *)&(pv[0]->rhw);
  1715. q[1] = *(DWORD *)&(pv[1]->rhw);
  1716. SCALE_BY_Q( 0 );
  1717. SCALE_BY_Q( 1 );
  1718. }
  1719. else
  1720. {
  1721. q[0] = q[1] = 0;
  1722. }
  1723. if (Flags & SURFACE_GOURAUD)
  1724. {
  1725. SEND_R3FVFVERTEX_XYZ_STQ_RGBA_SFOG(V0FloatS_Tag, 0);
  1726. SEND_R3FVFVERTEX_XYZ_STQ_RGBA_SFOG(V1FloatS_Tag, 1);
  1727. }
  1728. else
  1729. {
  1730. DWORD Col0 = FVFCOLOR(pProvokingVtx)->color;
  1731. SEND_R3FVFVERTEX_XYZ_STQ_FOG(V0FloatS_Tag, 0);
  1732. SEND_R3FVFVERTEX_XYZ_STQ_FOG(V1FloatS_Tag, 1);
  1733. if( pContext->Flags & SURFACE_SPECULAR )
  1734. {
  1735. DWORD Spec0 = GET_SPEC( FVFSPEC(pProvokingVtx)->specular );
  1736. CLAMP8888( Col0, Col0, Spec0 );
  1737. }
  1738. SEND_P3_DATA(ConstantColor, RGBA_MAKE(RGBA_GETBLUE(Col0),
  1739. RGBA_GETGREEN(Col0),
  1740. RGBA_GETRED(Col0),
  1741. RGBA_GETALPHA(Col0)));
  1742. }
  1743. DRAW_LINE();
  1744. P3_DMA_COMMIT_BUFFER();
  1745. } // __ProcessLine
  1746. //-----------------------------------------------------------------------------
  1747. //
  1748. // _D3D_R3_DP2_LineList
  1749. //
  1750. // Render D3DDP2OP_LINELIST lines
  1751. //
  1752. //-----------------------------------------------------------------------------
  1753. void
  1754. _D3D_R3_DP2_LineList(
  1755. P3_D3DCONTEXT *pContext,
  1756. DWORD dwPrimCount,
  1757. LPBYTE lpPrim,
  1758. LPD3DTLVERTEX lpVertices,
  1759. DWORD dwVertexBufferLen,
  1760. BOOL *pbError)
  1761. {
  1762. D3DTLVERTEX *pv[2];
  1763. WORD wVStart;
  1764. DWORD i;
  1765. DBG_ENTRY(_D3D_R3_DP2_LineList);
  1766. wVStart = ((D3DHAL_DP2LINELIST*)lpPrim)->wVStart;
  1767. pv[0] = LP_FVF_VERTEX(lpVertices, wVStart);
  1768. pv[1] = LP_FVF_NXT_VTX(pv[0]);
  1769. // Check first & last vertex
  1770. CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, wVStart);
  1771. CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen,
  1772. (LONG)wVStart + 2*dwPrimCount - 1)
  1773. for( i = 0; i < dwPrimCount; i++ )
  1774. {
  1775. __ProcessLine(pContext, pv, pv[0]);
  1776. pv[0] = LP_FVF_NXT_VTX(pv[1]);
  1777. pv[1] = LP_FVF_NXT_VTX(pv[0]);
  1778. }
  1779. DBG_EXIT(_D3D_R3_DP2_LineList,0);
  1780. } // _D3D_R3_DP2_LineList
  1781. //-----------------------------------------------------------------------------
  1782. //
  1783. // _D3D_R3_DP2_LineListImm
  1784. //
  1785. // Render D3DDP2OP_LINELIST_IMM lines
  1786. //
  1787. //-----------------------------------------------------------------------------
  1788. void
  1789. _D3D_R3_DP2_LineListImm(
  1790. P3_D3DCONTEXT *pContext,
  1791. DWORD dwPrimCount,
  1792. LPBYTE lpPrim,
  1793. LPD3DTLVERTEX lpVertices,
  1794. DWORD dwVertexBufferLen,
  1795. BOOL *pbError)
  1796. {
  1797. D3DTLVERTEX *pv[2];
  1798. DWORD i;
  1799. DBG_ENTRY(_D3D_R3_DP2_LineListImm);
  1800. pv[0] = (LPD3DTLVERTEX)lpPrim;
  1801. pv[1] = LP_FVF_NXT_VTX(pv[0]);
  1802. // since data is in the command buffer, we've already verified it as valid
  1803. for( i = 0; i < dwPrimCount; i++ )
  1804. {
  1805. __ProcessLine(pContext, pv, pv[0]);
  1806. pv[0] = LP_FVF_NXT_VTX(pv[1]);
  1807. pv[1] = LP_FVF_NXT_VTX(pv[0]);
  1808. }
  1809. DBG_EXIT(_D3D_R3_DP2_LineListImm,0);
  1810. } // _D3D_R3_DP2_LineListImm
  1811. //-----------------------------------------------------------------------------
  1812. //
  1813. // _D3D_R3_DP2_LineStrip
  1814. //
  1815. // Render D3DDP2OP_LINESTRIP lines
  1816. //
  1817. //-----------------------------------------------------------------------------
  1818. void
  1819. _D3D_R3_DP2_LineStrip(
  1820. P3_D3DCONTEXT *pContext,
  1821. DWORD dwPrimCount,
  1822. LPBYTE lpPrim,
  1823. LPD3DTLVERTEX lpVertices,
  1824. DWORD dwVertexBufferLen,
  1825. BOOL *pbError)
  1826. {
  1827. D3DTLVERTEX *pv[2];
  1828. WORD wVStart;
  1829. DWORD i;
  1830. DBG_ENTRY(_D3D_R3_DP2_LineStrip);
  1831. wVStart = ((D3DHAL_DP2STARTVERTEX*)lpPrim)->wVStart;
  1832. pv[0] = LP_FVF_VERTEX(lpVertices, wVStart);
  1833. pv[1] = LP_FVF_NXT_VTX(pv[0]);
  1834. // Check first & last vertex
  1835. CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, wVStart);
  1836. CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, wVStart + dwPrimCount);
  1837. for( i = 0; i < dwPrimCount; i++ )
  1838. {
  1839. __ProcessLine(pContext, pv, pv[0]);
  1840. pv[0] = pv[1];
  1841. pv[1] = LP_FVF_NXT_VTX(pv[1]);
  1842. }
  1843. DBG_EXIT(_D3D_R3_DP2_LineStrip,0);
  1844. } // _D3D_R3_DP2_LineStrip
  1845. //-----------------------------------------------------------------------------
  1846. //
  1847. // _D3D_R3_DP2_IndexedLineList
  1848. //
  1849. // Render D3DDP2OP_INDEXEDLINELIST lines
  1850. //
  1851. //-----------------------------------------------------------------------------
  1852. void
  1853. _D3D_R3_DP2_IndexedLineList(
  1854. P3_D3DCONTEXT *pContext,
  1855. DWORD dwPrimCount,
  1856. LPBYTE lpPrim,
  1857. LPD3DTLVERTEX lpVertices,
  1858. DWORD dwVertexBufferLen,
  1859. BOOL *pbError)
  1860. {
  1861. D3DTLVERTEX *pv[2];
  1862. DWORD primData, dwIndex0, dwIndex1, i;
  1863. DBG_ENTRY(_D3D_R3_DP2_IndexedLineList);
  1864. for( i = 0; i < dwPrimCount; i++ )
  1865. {
  1866. primData = *(DWORD *)lpPrim;
  1867. dwIndex0 = ( primData >> 0 ) & 0xffff;
  1868. dwIndex1 = ( primData >> 16 );
  1869. pv[0] = LP_FVF_VERTEX(lpVertices, dwIndex0);
  1870. pv[1] = LP_FVF_VERTEX(lpVertices, dwIndex1);
  1871. CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, dwIndex0);
  1872. CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, dwIndex1);
  1873. lpPrim += sizeof(D3DHAL_DP2INDEXEDLINELIST);
  1874. __ProcessLine(pContext, pv, pv[0]);
  1875. }
  1876. DBG_EXIT(_D3D_R3_DP2_IndexedLineList,0);
  1877. } // _D3D_R3_DP2_IndexedLineList
  1878. //-----------------------------------------------------------------------------
  1879. //
  1880. // _D3D_R3_DP2_IndexedLineList2
  1881. //
  1882. // Render D3DDP2OP_INDEXEDLINELIST2 lines
  1883. //
  1884. //-----------------------------------------------------------------------------
  1885. void
  1886. _D3D_R3_DP2_IndexedLineList2(
  1887. P3_D3DCONTEXT *pContext,
  1888. DWORD dwPrimCount,
  1889. LPBYTE lpPrim,
  1890. LPD3DTLVERTEX lpVertices,
  1891. DWORD dwVertexBufferLen,
  1892. BOOL *pbError)
  1893. {
  1894. D3DTLVERTEX *pv[2];
  1895. DWORD primData, i;
  1896. WORD wVStart, dwIndex0, dwIndex1;
  1897. DBG_ENTRY(_D3D_R3_DP2_IndexedLineList2);
  1898. wVStart = ((D3DHAL_DP2STARTVERTEX*)lpPrim)->wVStart;
  1899. lpVertices = LP_FVF_VERTEX(lpVertices, wVStart);
  1900. lpPrim += sizeof(D3DHAL_DP2STARTVERTEX);
  1901. for( i = 0; i < dwPrimCount; i++ )
  1902. {
  1903. primData = *(DWORD *)lpPrim;
  1904. dwIndex0 = ( (WORD)(primData >> 0) ) & 0xffff;
  1905. dwIndex1 = ( (WORD)(primData >> 16) );
  1906. pv[0] = LP_FVF_VERTEX(lpVertices, dwIndex0);
  1907. pv[1] = LP_FVF_VERTEX(lpVertices, dwIndex1);
  1908. CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, dwIndex0 + wVStart);
  1909. CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, dwIndex1 + wVStart);
  1910. lpPrim += sizeof(D3DHAL_DP2INDEXEDLINELIST);
  1911. __ProcessLine(pContext, pv, pv[0]);
  1912. }
  1913. DBG_EXIT(_D3D_R3_DP2_IndexedLineList2,0);
  1914. } // _D3D_R3_DP2_IndexedLineList2
  1915. //-----------------------------------------------------------------------------
  1916. //
  1917. // _D3D_R3_DP2_IndexedLineStrip
  1918. //
  1919. // Render D3DDP2OP_INDEXEDLINESTRIP lines
  1920. //
  1921. //-----------------------------------------------------------------------------
  1922. void
  1923. _D3D_R3_DP2_IndexedLineStrip(
  1924. P3_D3DCONTEXT *pContext,
  1925. DWORD dwPrimCount,
  1926. LPBYTE lpPrim,
  1927. LPD3DTLVERTEX lpVertices,
  1928. DWORD dwVertexBufferLen,
  1929. BOOL *pbError)
  1930. {
  1931. D3DTLVERTEX *pv[2];
  1932. WORD wVStart, dwIndex, *pwIndx;
  1933. DWORD i;
  1934. DBG_ENTRY(_D3D_R3_DP2_IndexedLineStrip);
  1935. wVStart = ((D3DHAL_DP2STARTVERTEX*)lpPrim)->wVStart;
  1936. lpVertices = LP_FVF_VERTEX(lpVertices, wVStart);
  1937. lpPrim += sizeof(D3DHAL_DP2STARTVERTEX);
  1938. pwIndx = (WORD *)lpPrim;
  1939. dwIndex = *pwIndx++;
  1940. pv[0] = LP_FVF_VERTEX(lpVertices, dwIndex);
  1941. CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, dwIndex);
  1942. for( i = 0; i < dwPrimCount; i++ )
  1943. {
  1944. dwIndex = *pwIndx++;
  1945. pv[1] = LP_FVF_VERTEX(lpVertices, dwIndex);
  1946. CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, dwIndex);
  1947. __ProcessLine(pContext, pv, pv[0]);
  1948. pv[0] = pv[1];
  1949. }
  1950. DBG_EXIT(_D3D_R3_DP2_IndexedLineStrip,0);
  1951. } // _D3D_R3_DP2_IndexedLineStrip
  1952. //-----------------------------------------------------------------------------
  1953. //
  1954. // __ProcessPoints
  1955. //
  1956. // Render a set points specified by adjacent FVF vertices
  1957. //
  1958. //-----------------------------------------------------------------------------
  1959. void
  1960. __ProcessPoints(
  1961. P3_D3DCONTEXT *pContext,
  1962. D3DTLVERTEX *pv[],
  1963. DWORD dwCount)
  1964. {
  1965. P3_THUNKEDDATA* pThisDisplay = pContext->pThisDisplay;
  1966. DWORD Flags = pContext->Flags;
  1967. DWORD q[1];
  1968. TEXCOORDS tc[1];
  1969. ULONG renderCmd = pContext->RenderCommand;
  1970. DWORD j;
  1971. D3DTLVERTEX *ptmpV;
  1972. P3_DMA_DEFS();
  1973. ptmpV = pv[0];
  1974. RENDER_LINE(renderCmd);
  1975. q[0] = 0;
  1976. for( j = 0; j < dwCount; j++ )
  1977. {
  1978. P3_DMA_GET_BUFFER_ENTRIES( 20 );
  1979. GET_TC(0);
  1980. if( Flags & SURFACE_PERSPCORRECT )
  1981. {
  1982. q[0] = *(DWORD *)&(pv[0]->rhw);
  1983. SCALE_BY_Q( 0 );
  1984. }
  1985. SEND_R3FVFVERTEX_XYZ_STQ_RGBA_SFOG_POINT(V0FloatS_Tag, 0, FALSE);
  1986. SEND_R3FVFVERTEX_XYZ_STQ_RGBA_SFOG_POINT(V1FloatS_Tag, 0, TRUE);
  1987. DRAW_LINE();
  1988. P3_DMA_COMMIT_BUFFER();
  1989. pv[0] = LP_FVF_NXT_VTX(pv[0]);
  1990. }
  1991. pv[0] = ptmpV;
  1992. } // __ProcessPoints
  1993. //-----------------------------------------------------------------------------
  1994. //
  1995. // _D3D_R3_DP2_Points
  1996. //
  1997. // Render D3DDP2OP_POINTS points
  1998. //
  1999. //-----------------------------------------------------------------------------
  2000. void
  2001. _D3D_R3_DP2_Points(
  2002. P3_D3DCONTEXT *pContext,
  2003. DWORD dwPrimCount,
  2004. LPBYTE lpPrim,
  2005. LPD3DTLVERTEX lpVertices,
  2006. DWORD dwVertexBufferLen,
  2007. BOOL *pbError)
  2008. {
  2009. D3DTLVERTEX *pv[1];
  2010. WORD wVStart, wCount;
  2011. DWORD i;
  2012. DBG_ENTRY(_D3D_R3_DP2_Points);
  2013. for( i = 0; i < dwPrimCount; i++ )
  2014. {
  2015. wVStart = ((D3DHAL_DP2POINTS*)lpPrim)->wVStart;
  2016. wCount = ((D3DHAL_DP2POINTS*)lpPrim)->wCount;
  2017. lpVertices = LP_FVF_VERTEX(lpVertices, wVStart);
  2018. // Check first & last vertex
  2019. CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, wVStart);
  2020. CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, wVStart + wCount - 1);
  2021. pv[0] = LP_FVF_VERTEX(lpVertices, 0);
  2022. __ProcessPoints(pContext, pv, wCount);
  2023. lpPrim += sizeof(D3DHAL_DP2POINTS);
  2024. }
  2025. DBG_EXIT(_D3D_R3_DP2_Points,0);
  2026. } // _D3D_R3_DP2_Points
  2027. //-----------------------------------------------------------------------------
  2028. //
  2029. // _D3D_R3_DP2_Points_DWCount
  2030. //
  2031. // Render D3DDP2OP_POINTS points for DX8 case
  2032. //
  2033. //-----------------------------------------------------------------------------
  2034. void
  2035. _D3D_R3_DP2_Points_DWCount(
  2036. P3_D3DCONTEXT *pContext,
  2037. DWORD dwPrimCount,
  2038. LPBYTE lpPrim,
  2039. LPD3DTLVERTEX lpVertices,
  2040. DWORD dwVertexBufferLen,
  2041. BOOL *pbError)
  2042. {
  2043. D3DTLVERTEX *pv[1];
  2044. WORD wVStart;
  2045. DWORD i;
  2046. DBG_ENTRY(_D3D_R3_DP2_Points_DWCount);
  2047. wVStart = ((D3DHAL_DP2POINTS*)lpPrim)->wVStart;
  2048. lpVertices = LP_FVF_VERTEX(lpVertices, wVStart);
  2049. // Check first & last vertex
  2050. CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, wVStart);
  2051. CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, wVStart + dwPrimCount - 1);
  2052. pv[0] = LP_FVF_VERTEX(lpVertices, 0);
  2053. __ProcessPoints(pContext, pv, dwPrimCount);
  2054. DBG_EXIT(_D3D_R3_DP2_Points_DWCount,0);
  2055. } // _D3D_R3_DP2_Points_DWCount
  2056. #if DX8_POINTSPRITES
  2057. #define SPRITETEXCOORDMAX 1.0f
  2058. //Size of maximum FVF that we can get. Used for temporary storage
  2059. typedef BYTE P3FVFMAXVERTEX[ 3 * sizeof( D3DVALUE ) + // Position coordinates
  2060. 5 * 4 + // D3DFVF_XYZB5
  2061. sizeof( D3DVALUE ) + // FVF_TRANSFORMED
  2062. 3 * sizeof( D3DVALUE ) + // Normals
  2063. sizeof( DWORD ) + // RESERVED1
  2064. sizeof( DWORD ) + // Diffuse color
  2065. sizeof( D3DCOLOR ) + // Specular color
  2066. sizeof( D3DVALUE ) + // Point sprite size
  2067. 4 * 8 * sizeof( D3DVALUE ) // 8 sets of 4D texture coordinates
  2068. ];
  2069. //-----------------------------------------------------------------------------
  2070. //
  2071. // __Render_One_PointSprite
  2072. //
  2073. // Render a point sprite with FVF vertexes when the point sprite enable is on
  2074. //
  2075. // Note: this is not the most optimized implementation possible for
  2076. // pointprites on this hw. We are merely following the definition.
  2077. // Later implementation will be optimized.
  2078. //-----------------------------------------------------------------------------
  2079. void
  2080. __Render_One_PointSprite(
  2081. P3_D3DCONTEXT *pContext,
  2082. D3DTLVERTEX *lpVertex)
  2083. {
  2084. // notice these are BYTE[], so its not necessary to write &fvfVUL to
  2085. // get the address of fvfVUL (just write fvfVUL)
  2086. P3FVFMAXVERTEX fvfVUL, fvfVUR, fvfVLL, fvfVLR ;
  2087. D3DVALUE fPntSize, fPntSizeHalf, fD2, fD, fScalePntSize, fFac;
  2088. D3DTLVERTEX *pv[3];
  2089. FVFOFFSETS OrigFVF;
  2090. BOOL bTexturingWOTexCoords = FALSE;
  2091. SAVE_CULLING_STATE(pContext);
  2092. DBG_ENTRY(__Render_One_PointSprite);
  2093. // Get point sprite size , if FVF data comes with it, grab it from there
  2094. if (pContext->FVFData.dwPntSizeOffset)
  2095. {
  2096. fPntSize = FVFPSIZE(lpVertex)->psize;
  2097. DISPDBG((DBGLVL,"FVF Data fPntSize = %d",(LONG)(fPntSize*1000.0f) ));
  2098. }
  2099. else
  2100. {
  2101. fPntSize = pContext->PntSprite.fSize;
  2102. DISPDBG((DBGLVL,"RS fPntSize = %d",(LONG)(fPntSize*1000.0f) ));
  2103. }
  2104. // We don't need to compute the point size according to the scale
  2105. // factors and viewport size, etc as we are not a TnL driver.
  2106. // See the spec for deatils
  2107. // Clamp fPntSize to limits defined by the driver caps (dvMaxPointSize)
  2108. // and the D3DRS_POINTSIZE_MIN and D3DRS_POINTSIZE_MAX renderstates
  2109. fPntSize = max(pContext->PntSprite.fSizeMin,
  2110. fPntSize);
  2111. fPntSize = min( min(pContext->PntSprite.fSizeMax,
  2112. P3_MAX_POINTSPRITE_SIZE),
  2113. fPntSize);
  2114. // Divide by 2 to get the amount by which to modify vertex coords
  2115. fPntSizeHalf = fPntSize * 0.5f;
  2116. // Initialize square vertex values
  2117. memcpy( fvfVUL, lpVertex, pContext->FVFData.dwStride);
  2118. memcpy( fvfVUR, lpVertex, pContext->FVFData.dwStride);
  2119. memcpy( fvfVLL, lpVertex, pContext->FVFData.dwStride);
  2120. memcpy( fvfVLR, lpVertex, pContext->FVFData.dwStride);
  2121. // Make this a square of size fPntSize
  2122. ((D3DTLVERTEX *)fvfVUL)->sx -= fPntSizeHalf;
  2123. ((D3DTLVERTEX *)fvfVUL)->sy -= fPntSizeHalf;
  2124. ((D3DTLVERTEX *)fvfVUR)->sx += fPntSizeHalf;
  2125. ((D3DTLVERTEX *)fvfVUR)->sy -= fPntSizeHalf;
  2126. ((D3DTLVERTEX *)fvfVLL)->sx -= fPntSizeHalf;
  2127. ((D3DTLVERTEX *)fvfVLL)->sy += fPntSizeHalf;
  2128. ((D3DTLVERTEX *)fvfVLR)->sx += fPntSizeHalf;
  2129. ((D3DTLVERTEX *)fvfVLR)->sy += fPntSizeHalf;
  2130. // This is for the case in which PntSprite.bEnabled is false
  2131. // and we are texturing even if we have no tex coord data in
  2132. // the pointsprite vertexes
  2133. bTexturingWOTexCoords = (pContext->FVFData.dwNonTexStride ==
  2134. pContext->FVFData.dwStride )
  2135. && (!pContext->bTexDisabled);
  2136. if (pContext->PntSprite.bEnabled || bTexturingWOTexCoords)
  2137. {
  2138. // Remember orig FVF offsets in order to fake our own texcoords
  2139. OrigFVF = pContext->FVFData;
  2140. // We "create" new texturing info in our data in order to
  2141. // process vertexes even without texturing coord info
  2142. // This is OK since we are using P3FVFMAXVERTEX as the type
  2143. // of our temporary data structures for each vertex so we
  2144. // can't overflow.
  2145. // If stage 0 texture is used
  2146. pContext->FVFData.dwTexCount = 1;
  2147. pContext->FVFData.dwTexOffset[0] =
  2148. pContext->FVFData.dwTexCoordOffset[0] =
  2149. pContext->FVFData.dwNonTexStride;
  2150. // If stage 1 texture is used
  2151. // we can use the same tex coord set since they are equal
  2152. pContext->FVFData.dwTexOffset[1] =
  2153. pContext->FVFData.dwTexCoordOffset[0];
  2154. if (pContext->PntSprite.bEnabled)
  2155. {
  2156. // Set up texture coordinates according to spec
  2157. FVFTEX(fvfVUL, 0)->tu = 0.0f;
  2158. FVFTEX(fvfVUL, 0)->tv = 0.0f;
  2159. FVFTEX(fvfVUR, 0)->tu = SPRITETEXCOORDMAX;
  2160. FVFTEX(fvfVUR, 0)->tv = 0.0f;
  2161. FVFTEX(fvfVLL, 0)->tu = 0.0f;
  2162. FVFTEX(fvfVLL, 0)->tv = SPRITETEXCOORDMAX;
  2163. FVFTEX(fvfVLR, 0)->tu = SPRITETEXCOORDMAX;
  2164. FVFTEX(fvfVLR, 0)->tv = SPRITETEXCOORDMAX;
  2165. }
  2166. else
  2167. {
  2168. // if we got here then PntSprite.bEnabled is false
  2169. // so just make the tex coords == (0,0)
  2170. FVFTEX(fvfVUL, 0)->tu = 0.0f;
  2171. FVFTEX(fvfVUL, 0)->tv = 0.0f;
  2172. FVFTEX(fvfVUR, 0)->tu = 0.0f;
  2173. FVFTEX(fvfVUR, 0)->tv = 0.0f;
  2174. FVFTEX(fvfVLL, 0)->tu = 0.0f;
  2175. FVFTEX(fvfVLL, 0)->tv = 0.0f;
  2176. FVFTEX(fvfVLR, 0)->tu = 0.0f;
  2177. FVFTEX(fvfVLR, 0)->tv = 0.0f;
  2178. }
  2179. #if DX8_3DTEXTURES
  2180. // Allow for the case of 3D texturing
  2181. FVFTEX(fvfVUL, 0)->tw = 0.0f;
  2182. FVFTEX(fvfVUR, 0)->tw = 0.0f;
  2183. FVFTEX(fvfVLL, 0)->tw = 0.0f;
  2184. FVFTEX(fvfVLR, 0)->tw = 0.0f;
  2185. #endif
  2186. }
  2187. // Make sure Culling doesn't prevent pointsprites from rendering
  2188. SET_CULLING_TO_NONE(pContext); // culling state was previously saved
  2189. // here we are going to send the required quad
  2190. pv[0] = (D3DTLVERTEX*)fvfVUL;
  2191. pv[1] = (D3DTLVERTEX*)fvfVUR;
  2192. pv[2] = (D3DTLVERTEX*)fvfVLL;
  2193. __ProcessTri_3Vtx_Generic(pContext, pv, ALL_SIDES);
  2194. pv[0] = (D3DTLVERTEX*)fvfVLL;
  2195. pv[1] = (D3DTLVERTEX*)fvfVUR;
  2196. pv[2] = (D3DTLVERTEX*)fvfVLR;
  2197. __ProcessTri_3Vtx_Generic(pContext, pv, ALL_SIDES);
  2198. // Restore original Culling settings
  2199. RESTORE_CULLING_STATE(pContext);
  2200. // Restore original FVF offsets
  2201. if (pContext->PntSprite.bEnabled || bTexturingWOTexCoords)
  2202. {
  2203. pContext->FVFData = OrigFVF;
  2204. }
  2205. DBG_EXIT(__Render_One_PointSprite, 0);
  2206. } // __Render_One_PointSprite
  2207. //-----------------------------------------------------------------------------
  2208. //
  2209. // __ProcessTri_1Vtx_PointSprite
  2210. //
  2211. //-----------------------------------------------------------------------------
  2212. int
  2213. __ProcessTri_1Vtx_PointSprite(
  2214. P3_D3DCONTEXT *pContext,
  2215. D3DTLVERTEX *pv[],
  2216. int vtx )
  2217. {
  2218. DISPDBG((WRNLVL,"WE SHOULDN'T DO __ProcessTri_1Vtx_PointSprite"));
  2219. return 1;
  2220. } // __ProcessTri_1Vtx_PointSprite
  2221. //-----------------------------------------------------------------------------
  2222. //
  2223. // __ProcessTri_3Vtx_PointSprite
  2224. //
  2225. //-----------------------------------------------------------------------------
  2226. int
  2227. __ProcessTri_3Vtx_PointSprite(
  2228. P3_D3DCONTEXT *pContext,
  2229. D3DTLVERTEX *pv[],
  2230. int WireEdgeFlags )
  2231. {
  2232. #if CULL_HERE
  2233. if( __BackfaceCullNoTexture( pContext, pv ))
  2234. return 1;
  2235. #endif
  2236. __Render_One_PointSprite(pContext, pv[0]);
  2237. __Render_One_PointSprite(pContext, pv[1]);
  2238. __Render_One_PointSprite(pContext, pv[2]);
  2239. return 1;
  2240. } // __ProcessTri_3Vtx_PointSprite
  2241. //-----------------------------------------------------------------------------
  2242. //
  2243. // _D3D_R3_DP2_PointsSprite_DWCount
  2244. //
  2245. // Render D3DDP2OP_POINTS points sprites
  2246. //
  2247. //-----------------------------------------------------------------------------
  2248. void
  2249. _D3D_R3_DP2_PointsSprite_DWCount(
  2250. P3_D3DCONTEXT *pContext,
  2251. DWORD dwPrimCount,
  2252. LPBYTE lpPrim,
  2253. LPD3DTLVERTEX lpVertices,
  2254. DWORD dwVertexBufferLen,
  2255. BOOL *pbError)
  2256. {
  2257. D3DTLVERTEX *pv[1];
  2258. WORD wVStart;
  2259. DWORD j;
  2260. DBG_ENTRY(_D3D_R3_DP2_PointsSprite_DWCount);
  2261. wVStart = ((D3DHAL_DP2POINTS*)lpPrim)->wVStart;
  2262. lpVertices = LP_FVF_VERTEX(lpVertices, wVStart);
  2263. // Check first & last vertex
  2264. CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, wVStart);
  2265. CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, wVStart + dwPrimCount - 1);
  2266. pContext->dwProvokingVertex = 0;
  2267. for( j = 0; j < dwPrimCount; j++ )
  2268. {
  2269. pv[0] = LP_FVF_VERTEX(lpVertices, j);
  2270. pContext->pProvokingVertex = pv[pContext->dwProvokingVertex];
  2271. __Render_One_PointSprite(pContext, pv[0]);
  2272. }
  2273. DBG_EXIT(_D3D_R3_DP2_PointsSprite_DWCount,0);
  2274. } // _D3D_R3_DP2_PointsSprite_DWCount
  2275. #endif // DX8_POINTSPRITES
  2276. #if DX8_MULTSTREAMS
  2277. // Macro to render a single triangle depending on the current Fillmode.
  2278. // Notice that for proper line rendering we require one more element in pv (4)
  2279. #define RENDER_ONE_TRIANGLE_CYCLE(pContext, dwFillMode, pv, bVtxInvalid, vtx_a)\
  2280. { \
  2281. if (dwFillMode == D3DFILL_SOLID) \
  2282. { \
  2283. if( bVtxInvalid ) \
  2284. bVtxInvalid = (*pContext->pRendTri_3V)( pContext, pv, ALL_SIDES); \
  2285. else \
  2286. bVtxInvalid = (*pContext->pRendTri_1V)( pContext, pv, vtx_a ); \
  2287. } \
  2288. else if (dwFillMode == D3DFILL_WIREFRAME) \
  2289. { \
  2290. if(!__BackfaceCullNoTexture( pContext, pv )) \
  2291. { \
  2292. pv[3] = pv[0]; \
  2293. __ProcessLine(pContext, &pv[0], pv[pContext->dwProvokingVertex]);\
  2294. __ProcessLine(pContext, &pv[1], pv[pContext->dwProvokingVertex]);\
  2295. __ProcessLine(pContext, &pv[2], pv[pContext->dwProvokingVertex]);\
  2296. } \
  2297. } \
  2298. else \
  2299. /*#if DX8_POINTSPRITES*/ \
  2300. if(IS_POINTSPRITE_ACTIVE(pContext)) \
  2301. { \
  2302. __ProcessTri_3Vtx_PointSprite( pContext, pv, ALL_SIDES ); \
  2303. } \
  2304. else \
  2305. /*#endif*/ \
  2306. { \
  2307. if(!__BackfaceCullNoTexture( pContext, pv )) \
  2308. { \
  2309. __ProcessPoints( pContext, &pv[0], 1); \
  2310. __ProcessPoints( pContext, &pv[1], 1); \
  2311. __ProcessPoints( pContext, &pv[2], 1); \
  2312. } \
  2313. } \
  2314. }
  2315. #define INIT_RENDER_ONE_TRIANGLE(pContext, dwFillMode, pv,VtxInvalid) \
  2316. { \
  2317. int vtx_a_local = 0; \
  2318. VtxInvalid= 1; \
  2319. RENDER_ONE_TRIANGLE_CYCLE(pContext, \
  2320. dwFillMode, \
  2321. pv, \
  2322. VtxInvalid, \
  2323. vtx_a_local); \
  2324. }
  2325. #define RENDER_ONE_TRIANGLE(pContext, dwFillMode, pv) \
  2326. { \
  2327. int vtx_a = 0, VtxInvalid= 1; \
  2328. RENDER_ONE_TRIANGLE_CYCLE(pContext, \
  2329. dwFillMode, \
  2330. pv, \
  2331. VtxInvalid, \
  2332. vtx_a); \
  2333. }
  2334. //-----------------------------------------------------------------------------
  2335. //
  2336. // _D3D_R3_DP2_IndexedLineList_MS_16IND
  2337. //
  2338. // Render D3DDP2OP_INDEXEDLINELIST lines
  2339. // 16 bit index streams are assumed
  2340. //
  2341. //-----------------------------------------------------------------------------
  2342. void
  2343. _D3D_R3_DP2_IndexedLineList_MS_16IND(
  2344. P3_D3DCONTEXT *pContext,
  2345. DWORD dwPrimCount,
  2346. LPBYTE lpPrim,
  2347. LPD3DTLVERTEX lpVertices,
  2348. INT IdxOffset,
  2349. DWORD dwVertexBufferLen,
  2350. BOOL *pbError)
  2351. {
  2352. D3DTLVERTEX *pv[2];
  2353. WORD *pwIndx;
  2354. DWORD dwIndex0, dwIndex1, i;
  2355. DBG_ENTRY(_D3D_R3_DP2_IndexedLineList_MS_16IND);
  2356. pwIndx = (WORD *)lpPrim;
  2357. for( i = 0; i < dwPrimCount; i++ )
  2358. {
  2359. dwIndex0 = *pwIndx++;
  2360. dwIndex1 = *pwIndx++;
  2361. pv[0] = LP_FVF_VERTEX(lpVertices, dwIndex0);
  2362. pv[1] = LP_FVF_VERTEX(lpVertices, dwIndex1);
  2363. CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, IdxOffset + dwIndex0);
  2364. CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, IdxOffset + dwIndex1);
  2365. __ProcessLine( pContext, pv, pv[0]);
  2366. }
  2367. DBG_EXIT(_D3D_R3_DP2_IndexedLineList_MS_16IND,0);
  2368. } // _D3D_R3_DP2_IndexedLineList_MS_16IND
  2369. //-----------------------------------------------------------------------------
  2370. //
  2371. // _D3D_R3_DP2_IndexedLineStrip_MS_16IND
  2372. //
  2373. // Render D3DDP2OP_INDEXEDLINESTRIP lines
  2374. // 16 bit index streams are assumed
  2375. //
  2376. //-----------------------------------------------------------------------------
  2377. void
  2378. _D3D_R3_DP2_IndexedLineStrip_MS_16IND(
  2379. P3_D3DCONTEXT *pContext,
  2380. DWORD dwPrimCount,
  2381. LPBYTE lpPrim,
  2382. LPD3DTLVERTEX lpVertices,
  2383. INT IdxOffset,
  2384. DWORD dwVertexBufferLen,
  2385. BOOL *pbError)
  2386. {
  2387. D3DTLVERTEX *pv[2];
  2388. DWORD dwIndex, i;
  2389. WORD *pwIndx;
  2390. DBG_ENTRY(_D3D_R3_DP2_IndexedLineStrip_MS_32IND);
  2391. pwIndx = (WORD *)lpPrim;
  2392. dwIndex = *pwIndx++;
  2393. pv[0] = LP_FVF_VERTEX(lpVertices, dwIndex);
  2394. CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, IdxOffset + dwIndex);
  2395. for( i = 0; i < dwPrimCount; i++ )
  2396. {
  2397. dwIndex = *pwIndx++;
  2398. pv[1] = LP_FVF_VERTEX(lpVertices, dwIndex);
  2399. CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, IdxOffset + dwIndex);
  2400. __ProcessLine(pContext, pv, pv[0]);
  2401. pv[0] = pv[1];
  2402. }
  2403. DBG_EXIT(_D3D_R3_DP2_IndexedLineStrip_MS_16IND,0);
  2404. } // _D3D_R3_DP2_IndexedLineStrip_MS_16IND
  2405. //-----------------------------------------------------------------------------
  2406. //
  2407. // _D3D_R3_DP2_IndexedTriangleList_MS_16IND
  2408. //
  2409. // Render D3DDP2OP_INDEXEDTRIANGLELIST triangles
  2410. // 16 bit index streams are assumed
  2411. //
  2412. //-----------------------------------------------------------------------------
  2413. void
  2414. _D3D_R3_DP2_IndexedTriangleList_MS_16IND(
  2415. P3_D3DCONTEXT *pContext,
  2416. DWORD dwPrimCount,
  2417. LPBYTE lpPrim,
  2418. LPD3DTLVERTEX lpVertices,
  2419. INT IdxOffset,
  2420. DWORD dwVertexBufferLen,
  2421. BOOL *pbError)
  2422. {
  2423. DWORD dwIndex0, dwIndex1, dwIndex2, i;
  2424. D3DTLVERTEX *pv[4];
  2425. WORD *pwIndexData;
  2426. DWORD dwFillMode = pContext->RenderStates[D3DRS_FILLMODE];
  2427. DBG_ENTRY(_D3D_R3_DP2_IndexedTriangleList_MS_16IND);
  2428. DISPDBG((DBGLVL,"pContext = 0x%x dwPrimCount=%d lpPrim=0x%x lpVertices=0x%x "
  2429. "IdxOffset=%d dwVertexBufferLen=%d ",
  2430. pContext,(DWORD)dwPrimCount,lpPrim,lpVertices,
  2431. IdxOffset, dwVertexBufferLen));
  2432. pwIndexData = (WORD *)lpPrim;
  2433. pContext->dwProvokingVertex = 0;
  2434. for( i = 0; i < dwPrimCount; i++ )
  2435. {
  2436. dwIndex0 = *pwIndexData++;
  2437. dwIndex1 = *pwIndexData++;
  2438. dwIndex2 = *pwIndexData++;
  2439. pv[0] = LP_FVF_VERTEX(lpVertices, dwIndex0);
  2440. pv[1] = LP_FVF_VERTEX(lpVertices, dwIndex1);
  2441. pv[2] = LP_FVF_VERTEX(lpVertices, dwIndex2);
  2442. CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, IdxOffset + dwIndex0);
  2443. CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, IdxOffset + dwIndex1);
  2444. CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, IdxOffset + dwIndex2);
  2445. pContext->pProvokingVertex = pv[pContext->dwProvokingVertex];
  2446. RENDER_ONE_TRIANGLE(pContext,dwFillMode,pv);
  2447. }
  2448. DBG_EXIT(_D3D_R3_DP2_IndexedTriangleList_MS_16IND,0);
  2449. } // _D3D_R3_DP2_IndexedTriangleList_MS_16IND
  2450. //-----------------------------------------------------------------------------
  2451. //
  2452. // _D3D_R3_DP2_IndexedTriangleStrip_MS_16IND
  2453. //
  2454. // Render D3DDP2OP_INDEXEDTRIANGLESTRIP triangles
  2455. // 16 bit index streams are assumed
  2456. //
  2457. //-----------------------------------------------------------------------------
  2458. void
  2459. _D3D_R3_DP2_IndexedTriangleStrip_MS_16IND(
  2460. P3_D3DCONTEXT *pContext,
  2461. DWORD dwPrimCount,
  2462. LPBYTE lpPrim,
  2463. LPD3DTLVERTEX lpVertices,
  2464. INT IdxOffset,
  2465. DWORD dwVertexBufferLen,
  2466. BOOL *pbError)
  2467. {
  2468. DWORD dwIndex0, dwIndex1, dwIndex2, i;
  2469. D3DTLVERTEX *pv[4];
  2470. int vtx_a, vtx_b, bCulled;
  2471. WORD *pwIndexData;
  2472. DWORD dwFillMode = pContext->RenderStates[D3DRS_FILLMODE];
  2473. SAVE_CULLING_STATE(pContext);
  2474. DBG_ENTRY(_D3D_R3_DP2_IndexedTriangleStrip_MS_16IND);
  2475. pwIndexData = (WORD *)lpPrim;
  2476. dwIndex0 = *pwIndexData++;
  2477. dwIndex1 = *pwIndexData++;
  2478. dwIndex2 = *pwIndexData++;
  2479. pv[0] = LP_FVF_VERTEX(lpVertices, dwIndex0);
  2480. pv[1] = LP_FVF_VERTEX(lpVertices, dwIndex1);
  2481. pv[2] = LP_FVF_VERTEX(lpVertices, dwIndex2);
  2482. CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, IdxOffset + dwIndex0);
  2483. CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, IdxOffset + dwIndex1);
  2484. CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, IdxOffset + dwIndex2);
  2485. pContext->dwProvokingVertex = 0;
  2486. pContext->pProvokingVertex = pv[pContext->dwProvokingVertex];
  2487. INIT_RENDER_ONE_TRIANGLE(pContext,dwFillMode,pv,bCulled);
  2488. lpPrim += sizeof(WORD);
  2489. INIT_VERTEX_INDICES(pContext, vtx_a, vtx_b);
  2490. for( i = 1; i < dwPrimCount; i++ )
  2491. {
  2492. FLIP_CCW_CW_CULLING(pContext);
  2493. dwIndex2 = *pwIndexData++;
  2494. pv[vtx_a] = LP_FVF_VERTEX(lpVertices, dwIndex2);
  2495. CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, dwIndex2);
  2496. pContext->pProvokingVertex = pv[pContext->dwProvokingVertex];
  2497. RENDER_ONE_TRIANGLE_CYCLE(pContext,
  2498. dwFillMode,
  2499. pv,
  2500. bCulled,
  2501. vtx_a);
  2502. CYCLE_VERTEX_INDICES(pContext, vtx_a, vtx_b);
  2503. }
  2504. RESTORE_CULLING_STATE(pContext);
  2505. DBG_EXIT(_D3D_R3_DP2_IndexedTriangleStrip_MS_16IND,0);
  2506. } // _D3D_R3_DP2_IndexedTriangleStrip_MS_16IND
  2507. //-----------------------------------------------------------------------------
  2508. //
  2509. // _D3D_R3_DP2_IndexedTriangleFan_MS_16IND
  2510. //
  2511. // Render D3DDP2OP_INDEXEDTRIANGLEFAN triangles in
  2512. // 16 bit index streams are assumed
  2513. //
  2514. //-----------------------------------------------------------------------------
  2515. void
  2516. _D3D_R3_DP2_IndexedTriangleFan_MS_16IND(
  2517. P3_D3DCONTEXT *pContext,
  2518. DWORD dwPrimCount,
  2519. LPBYTE lpPrim,
  2520. LPD3DTLVERTEX lpVertices,
  2521. INT IdxOffset,
  2522. DWORD dwVertexBufferLen,
  2523. BOOL *pbError)
  2524. {
  2525. DWORD dwIndex0, dwIndex1, dwIndex2, i;
  2526. D3DTLVERTEX *pv[4];
  2527. int vtx, lastVtx, bCulled;
  2528. WORD *pwIndexData;
  2529. DWORD dwFillMode = pContext->RenderStates[D3DRS_FILLMODE];
  2530. SAVE_CULLING_STATE(pContext);
  2531. DBG_ENTRY(_D3D_R3_DP2_IndexedTriangleFan_MS_16IND);
  2532. pwIndexData = (WORD *)lpPrim;
  2533. dwIndex0 = *pwIndexData++;
  2534. dwIndex1 = *pwIndexData++;
  2535. dwIndex2 = *pwIndexData++;
  2536. lastVtx = vtx = 2;
  2537. pv[0] = LP_FVF_VERTEX(lpVertices, dwIndex0);
  2538. pv[1] = LP_FVF_VERTEX(lpVertices, dwIndex1);
  2539. pv[2] = LP_FVF_VERTEX(lpVertices, dwIndex2);
  2540. CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, IdxOffset + dwIndex0);
  2541. CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, IdxOffset + dwIndex1);
  2542. CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, IdxOffset + dwIndex2);
  2543. pContext->dwProvokingVertex = 1;
  2544. pContext->pProvokingVertex = pv[pContext->dwProvokingVertex];
  2545. INIT_RENDER_ONE_TRIANGLE(pContext,dwFillMode,pv,bCulled);
  2546. lpPrim += sizeof(WORD);
  2547. for( i = 1; i < dwPrimCount; i++ )
  2548. {
  2549. // 2 -> 1, 1 -> 2
  2550. vtx ^= 3;
  2551. FLIP_CCW_CW_CULLING(pContext);
  2552. dwIndex2 = *pwIndexData++;
  2553. pv[vtx] = LP_FVF_VERTEX(lpVertices, dwIndex2);
  2554. CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, IdxOffset + dwIndex2);
  2555. pContext->dwProvokingVertex = lastVtx;
  2556. pContext->pProvokingVertex = pv[pContext->dwProvokingVertex];
  2557. RENDER_ONE_TRIANGLE_CYCLE(pContext,
  2558. dwFillMode,
  2559. pv,
  2560. bCulled,
  2561. vtx);
  2562. lastVtx = vtx;
  2563. }
  2564. RESTORE_CULLING_STATE(pContext);
  2565. DBG_EXIT(_D3D_R3_DP2_IndexedTriangleFan_MS_16IND,0);
  2566. } // _D3D_R3_DP2_IndexedTriangleFan_MS_16IND
  2567. //-----------------------------------------------------------------------------
  2568. //
  2569. // _D3D_R3_DP2_IndexedLineList_MS_32IND
  2570. //
  2571. // Render D3DDP2OP_INDEXEDLINELIST lines
  2572. // Indices come as 32-bit entities ( DX7 only uses 16-bit indices)
  2573. //
  2574. //-----------------------------------------------------------------------------
  2575. void
  2576. _D3D_R3_DP2_IndexedLineList_MS_32IND(
  2577. P3_D3DCONTEXT *pContext,
  2578. DWORD dwPrimCount,
  2579. LPBYTE lpPrim,
  2580. LPD3DTLVERTEX lpVertices,
  2581. INT IdxOffset,
  2582. DWORD dwVertexBufferLen,
  2583. BOOL *pbError)
  2584. {
  2585. D3DTLVERTEX *pv[2];
  2586. DWORD *pdwIndx, dwIndex0, dwIndex1, i;
  2587. DBG_ENTRY(_D3D_R3_DP2_IndexedLineList_MS_32IND);
  2588. pdwIndx = (DWORD *)lpPrim;
  2589. for( i = 0; i < dwPrimCount; i++ )
  2590. {
  2591. dwIndex0 = *pdwIndx++;
  2592. dwIndex1 = *pdwIndx++;
  2593. pv[0] = LP_FVF_VERTEX(lpVertices, dwIndex0);
  2594. pv[1] = LP_FVF_VERTEX(lpVertices, dwIndex1);
  2595. CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, IdxOffset + dwIndex0);
  2596. CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, IdxOffset + dwIndex1);
  2597. __ProcessLine(pContext, pv, pv[0]);
  2598. }
  2599. DBG_EXIT(_D3D_R3_DP2_IndexedLineList_MS_32IND,0);
  2600. } // _D3D_R3_DP2_IndexedLineList_MS_32IND
  2601. //-----------------------------------------------------------------------------
  2602. //
  2603. // _D3D_R3_DP2_IndexedLineStrip_MS_32IND
  2604. //
  2605. // Render D3DDP2OP_INDEXEDLINESTRIP lines
  2606. // Indices come as 32-bit entities ( DX7 only uses 16-bit indices)
  2607. //
  2608. //-----------------------------------------------------------------------------
  2609. void
  2610. _D3D_R3_DP2_IndexedLineStrip_MS_32IND(
  2611. P3_D3DCONTEXT *pContext,
  2612. DWORD dwPrimCount,
  2613. LPBYTE lpPrim,
  2614. LPD3DTLVERTEX lpVertices,
  2615. INT IdxOffset,
  2616. DWORD dwVertexBufferLen,
  2617. BOOL *pbError)
  2618. {
  2619. D3DTLVERTEX *pv[2];
  2620. DWORD dwIndex, *pdwIndx, i;
  2621. DBG_ENTRY(_D3D_R3_DP2_IndexedLineStrip_MS_32IND);
  2622. pdwIndx = (DWORD *)lpPrim;
  2623. dwIndex = *pdwIndx++;
  2624. pv[0] = LP_FVF_VERTEX(lpVertices, dwIndex);
  2625. CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, IdxOffset + dwIndex);
  2626. for( i = 0; i < dwPrimCount; i++ )
  2627. {
  2628. dwIndex = *pdwIndx++;
  2629. pv[1] = LP_FVF_VERTEX(lpVertices, dwIndex);
  2630. CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, IdxOffset + dwIndex);
  2631. __ProcessLine(pContext, pv, pv[0]);
  2632. pv[0] = pv[1];
  2633. }
  2634. DBG_EXIT(_D3D_R3_DP2_IndexedLineStrip_MS_32IND,0);
  2635. } // _D3D_R3_DP2_IndexedLineStrip_MS_32IND
  2636. //-----------------------------------------------------------------------------
  2637. //
  2638. // _D3D_R3_DP2_IndexedTriangleList_MS_32IND
  2639. //
  2640. // Render D3DDP2OP_INDEXEDTRIANGLELIST triangles
  2641. // Indices come as 32-bit entities ( DX7 only uses 16-bit indices)
  2642. //
  2643. //-----------------------------------------------------------------------------
  2644. void
  2645. _D3D_R3_DP2_IndexedTriangleList_MS_32IND(
  2646. P3_D3DCONTEXT *pContext,
  2647. DWORD dwPrimCount,
  2648. LPBYTE lpPrim,
  2649. LPD3DTLVERTEX lpVertices,
  2650. INT IdxOffset,
  2651. DWORD dwVertexBufferLen,
  2652. BOOL *pbError)
  2653. {
  2654. DWORD dwIndex0, dwIndex1, dwIndex2, *pdwIndexData, i;
  2655. D3DTLVERTEX *pv[4];
  2656. DWORD dwFillMode = pContext->RenderStates[D3DRS_FILLMODE];
  2657. DBG_ENTRY(_D3D_R3_DP2_IndexedTriangleList_MS_32IND);
  2658. DISPDBG((DBGLVL,"pContext = 0x%x dwPrimCount=%d lpPrim=0x%x lpVertices=0x%x "
  2659. "IdxOffset=%d dwVertexBufferLen=%d ",
  2660. pContext,(DWORD)dwPrimCount,lpPrim,lpVertices,IdxOffset,
  2661. dwVertexBufferLen));
  2662. pdwIndexData = (DWORD *)lpPrim;
  2663. pContext->dwProvokingVertex = 0;
  2664. for( i = 0; i < dwPrimCount; i++ )
  2665. {
  2666. dwIndex0 = *pdwIndexData++;
  2667. dwIndex1 = *pdwIndexData++;
  2668. dwIndex2 = *pdwIndexData++;
  2669. pv[0] = LP_FVF_VERTEX(lpVertices, dwIndex0);
  2670. pv[1] = LP_FVF_VERTEX(lpVertices, dwIndex1);
  2671. pv[2] = LP_FVF_VERTEX(lpVertices, dwIndex2);
  2672. CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, IdxOffset + dwIndex0);
  2673. CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, IdxOffset + dwIndex1);
  2674. CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, IdxOffset + dwIndex2);
  2675. pContext->pProvokingVertex = pv[pContext->dwProvokingVertex];
  2676. RENDER_ONE_TRIANGLE(pContext,dwFillMode,pv);
  2677. }
  2678. DBG_EXIT(_D3D_R3_DP2_IndexedTriangleList_MS_32IND,0);
  2679. } // _D3D_R3_DP2_IndexedTriangleList_MS_32IND
  2680. //-----------------------------------------------------------------------------
  2681. //
  2682. // _D3D_R3_DP2_IndexedTriangleStrip_MS_32IND
  2683. //
  2684. // Render D3DDP2OP_INDEXEDTRIANGLESTRIP triangles
  2685. // Indices come as 32-bit entities ( DX7 only uses 16-bit indices)
  2686. //
  2687. //-----------------------------------------------------------------------------
  2688. void
  2689. _D3D_R3_DP2_IndexedTriangleStrip_MS_32IND(
  2690. P3_D3DCONTEXT *pContext,
  2691. DWORD dwPrimCount,
  2692. LPBYTE lpPrim,
  2693. LPD3DTLVERTEX lpVertices,
  2694. INT IdxOffset,
  2695. DWORD dwVertexBufferLen,
  2696. BOOL *pbError)
  2697. {
  2698. DWORD dwIndex0, dwIndex1, dwIndex2, i, *pdwIndexData;
  2699. D3DTLVERTEX *pv[4];
  2700. int vtx_a, vtx_b, bCulled;
  2701. DWORD dwFillMode = pContext->RenderStates[D3DRS_FILLMODE];
  2702. SAVE_CULLING_STATE(pContext);
  2703. DBG_ENTRY(_D3D_R3_DP2_IndexedTriangleStrip_MS_32IND);
  2704. pdwIndexData = (DWORD *)lpPrim;
  2705. dwIndex0 = *pdwIndexData++;
  2706. dwIndex1 = *pdwIndexData++;
  2707. dwIndex2 = *pdwIndexData++;
  2708. pv[0] = LP_FVF_VERTEX(lpVertices, dwIndex0);
  2709. pv[1] = LP_FVF_VERTEX(lpVertices, dwIndex1);
  2710. pv[2] = LP_FVF_VERTEX(lpVertices, dwIndex2);
  2711. CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, IdxOffset + dwIndex0);
  2712. CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, IdxOffset + dwIndex1);
  2713. CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, IdxOffset + dwIndex2);
  2714. pContext->dwProvokingVertex = 0;
  2715. pContext->pProvokingVertex = pv[pContext->dwProvokingVertex];
  2716. INIT_RENDER_ONE_TRIANGLE(pContext,dwFillMode,pv,bCulled);
  2717. lpPrim += sizeof(WORD);
  2718. INIT_VERTEX_INDICES(pContext, vtx_a, vtx_b);
  2719. for( i = 1; i < dwPrimCount; i++ )
  2720. {
  2721. FLIP_CCW_CW_CULLING(pContext);
  2722. dwIndex2 = *pdwIndexData++;
  2723. pv[vtx_a] = LP_FVF_VERTEX(lpVertices, dwIndex2);
  2724. CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, IdxOffset + dwIndex2);
  2725. pContext->pProvokingVertex = pv[pContext->dwProvokingVertex];
  2726. RENDER_ONE_TRIANGLE_CYCLE(pContext,
  2727. dwFillMode,
  2728. pv,
  2729. bCulled,
  2730. vtx_a);
  2731. CYCLE_VERTEX_INDICES(pContext, vtx_a, vtx_b);
  2732. }
  2733. RESTORE_CULLING_STATE(pContext);
  2734. DBG_EXIT(_D3D_R3_DP2_IndexedTriangleStrip_MS_32IND,0);
  2735. } // _D3D_R3_DP2_IndexedTriangleStrip_MS_32IND
  2736. //-----------------------------------------------------------------------------
  2737. //
  2738. // _D3D_R3_DP2_IndexedTriangleFan_MS_32IND
  2739. //
  2740. // Render D3DDP2OP_INDEXEDTRIANGLEFAN triangles
  2741. // Indices come as 32-bit entities ( DX7 only uses 16-bit indices)
  2742. //
  2743. //-----------------------------------------------------------------------------
  2744. void
  2745. _D3D_R3_DP2_IndexedTriangleFan_MS_32IND(
  2746. P3_D3DCONTEXT *pContext,
  2747. DWORD dwPrimCount,
  2748. LPBYTE lpPrim,
  2749. LPD3DTLVERTEX lpVertices,
  2750. INT IdxOffset,
  2751. DWORD dwVertexBufferLen,
  2752. BOOL *pbError)
  2753. {
  2754. DWORD dwIndex0, dwIndex1, dwIndex2, i, *pdwIndexData;
  2755. D3DTLVERTEX *pv[4];
  2756. int vtx, lastVtx, bCulled;
  2757. DWORD dwFillMode = pContext->RenderStates[D3DRS_FILLMODE];
  2758. SAVE_CULLING_STATE(pContext);
  2759. DBG_ENTRY(_D3D_R3_DP2_IndexedTriangleFan_MS_32IND);
  2760. pdwIndexData = (DWORD *)lpPrim;
  2761. dwIndex0 = *pdwIndexData++;
  2762. dwIndex1 = *pdwIndexData++;
  2763. dwIndex2 = *pdwIndexData++;
  2764. lastVtx = vtx = 2;
  2765. pv[0] = LP_FVF_VERTEX(lpVertices, dwIndex0);
  2766. pv[1] = LP_FVF_VERTEX(lpVertices, dwIndex1);
  2767. pv[2] = LP_FVF_VERTEX(lpVertices, dwIndex2);
  2768. CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, IdxOffset + dwIndex0);
  2769. CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, IdxOffset + dwIndex1);
  2770. CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, IdxOffset + dwIndex2);
  2771. pContext->dwProvokingVertex = 1;
  2772. pContext->pProvokingVertex = pv[pContext->dwProvokingVertex];
  2773. INIT_RENDER_ONE_TRIANGLE(pContext,dwFillMode,pv,bCulled);
  2774. lpPrim += sizeof(WORD);
  2775. for( i = 1; i < dwPrimCount; i++ )
  2776. {
  2777. // 2 -> 1, 1 -> 2
  2778. vtx ^= 3;
  2779. FLIP_CCW_CW_CULLING(pContext);
  2780. dwIndex2 = *pdwIndexData++;
  2781. pv[vtx] = LP_FVF_VERTEX(lpVertices, dwIndex2);
  2782. CHECK_DATABUF_LIMITS(pbError, dwVertexBufferLen, dwIndex2);
  2783. pContext->dwProvokingVertex = lastVtx;
  2784. pContext->pProvokingVertex = pv[pContext->dwProvokingVertex];
  2785. RENDER_ONE_TRIANGLE_CYCLE(pContext,
  2786. dwFillMode,
  2787. pv,
  2788. bCulled,
  2789. vtx);
  2790. lastVtx = vtx;
  2791. }
  2792. RESTORE_CULLING_STATE(pContext);
  2793. DBG_EXIT(_D3D_R3_DP2_IndexedTriangleFan_MS_32IND,0);
  2794. } // _D3D_R3_DP2_IndexedTriangleFan_MS_32IND
  2795. #endif // DX8_MULTSTREAMS
  2796. //-----------------------------------------------------------------------------
  2797. //
  2798. // _D3D_R3_PickVertexProcessor
  2799. //
  2800. // Pick appropriate triangle rendering functions based on texturing
  2801. //
  2802. //-----------------------------------------------------------------------------
  2803. void
  2804. _D3D_R3_PickVertexProcessor(
  2805. P3_D3DCONTEXT *pContext )
  2806. {
  2807. DWORD Flags = pContext->Flags;
  2808. DBG_ENTRY(_D3D_R3_PickVertexProcessor);
  2809. if (pContext->RenderStates[D3DRENDERSTATE_FILLMODE] == D3DFILL_WIREFRAME)
  2810. {
  2811. // Wireframe mode renderers
  2812. pContext->pRendTri_1V = __ProcessTri_1Vtx_Wire;
  2813. pContext->pRendTri_3V = __ProcessTri_3Vtx_Wire;
  2814. }
  2815. else if (pContext->RenderStates[D3DRENDERSTATE_FILLMODE] == D3DFILL_POINT)
  2816. {
  2817. #if DX8_DDI
  2818. if(IS_POINTSPRITE_ACTIVE(pContext))
  2819. {
  2820. // Point sprite mode renderers
  2821. pContext->pRendTri_1V = __ProcessTri_1Vtx_PointSprite;
  2822. pContext->pRendTri_3V = __ProcessTri_3Vtx_PointSprite;
  2823. }
  2824. else
  2825. #endif
  2826. {
  2827. // Point mode renderers
  2828. pContext->pRendTri_1V = __ProcessTri_1Vtx_Point;
  2829. pContext->pRendTri_3V = __ProcessTri_3Vtx_Point;
  2830. }
  2831. }
  2832. else
  2833. #if !defined(_WIN64)
  2834. // We avoid this path in IA64 as something is wrongly fed into the chip
  2835. if( ( Flags & SURFACE_PERSPCORRECT ) &&
  2836. ( Flags & SURFACE_GOURAUD ) &&
  2837. (pContext->bTex0Valid) &&
  2838. (!pContext->bTex1Valid) )
  2839. {
  2840. // Solid mode renderes for single textured-gouraud shaded-persp corr
  2841. if(( pContext->RenderStates[D3DRENDERSTATE_WRAP0] )
  2842. || ( pContext->RenderStates[D3DRENDERSTATE_WRAP1] ))
  2843. {
  2844. pContext->pRendTri_1V = __ProcessTri_1Vtx_Generic;
  2845. pContext->pRendTri_3V = __ProcessTri_3Vtx_Generic;
  2846. }
  2847. else
  2848. {
  2849. pContext->pRendTri_1V = __ProcessTri_1Vtx_PerspSingleTexGouraud;
  2850. pContext->pRendTri_3V = __ProcessTri_3Vtx_PerspSingleTexGouraud;
  2851. }
  2852. }
  2853. else
  2854. #endif !defined(_WIN64)
  2855. {
  2856. // Solid mode renderers for textured triangles
  2857. if( pContext->bTex0Valid || pContext->bTex1Valid )
  2858. {
  2859. pContext->pRendTri_1V = __ProcessTri_1Vtx_Generic;
  2860. pContext->pRendTri_3V = __ProcessTri_3Vtx_Generic;
  2861. }
  2862. else
  2863. {
  2864. // Solid mode renderers for non-textured triangles
  2865. pContext->pRendTri_1V = __ProcessTri_1Vtx_NoTexture;
  2866. pContext->pRendTri_3V = __ProcessTri_3Vtx_NoTexture;
  2867. }
  2868. }
  2869. DBG_EXIT(_D3D_R3_PickVertexProcessor,0);
  2870. } // _D3D_R3_PickVertexProcessor