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.

831 lines
37 KiB

  1. /*==========================================================================;
  2. *
  3. * Copyright (C) 1997 Microsoft Corporation. All Rights Reserved.
  4. *
  5. * File: d3dfe.hpp
  6. * Content: Direct3D internal include file
  7. * for geometry pipeline implementations
  8. *
  9. ***************************************************************************/
  10. #ifndef _D3DFE_H
  11. #include "d3d.h"
  12. #include "lists.hpp"
  13. #include "d3dmem.h"
  14. #include "d3ditype.h"
  15. //---------------------------------------------------------------------
  16. // The CSetD3DFPstate is used to facilitate the changing of FPU settings.
  17. // In the constructor the optimal FPU state is set. In the destructor the
  18. // old state is restored.
  19. //
  20. class CD3DFPstate
  21. {
  22. public:
  23. CD3DFPstate()
  24. {
  25. #ifdef _X86_
  26. WORD wTemp, wSave;
  27. wSavedFP = FALSE;
  28. // Disable floating point exceptions and go to single mode
  29. __asm fstcw wSave
  30. if (wSave & 0x300 || // Not single mode
  31. 0x3f != (wSave & 0x3f) || // Exceptions enabled
  32. wSave & 0xC00) // Not round to nearest mode
  33. {
  34. __asm {
  35. mov ax, wSave
  36. and ax, not 300h ;; single mode
  37. or ax, 3fh ;; disable all exceptions
  38. and ax, not 0xC00 ;; round to nearest mode
  39. mov wTemp, ax
  40. fldcw wTemp
  41. }
  42. wSavedFP = TRUE;
  43. }
  44. wSaveFP = wSave;
  45. #endif
  46. }
  47. ~CD3DFPstate()
  48. {
  49. #ifdef _X86_
  50. WORD wSave = wSaveFP;
  51. if (wSavedFP)
  52. __asm {
  53. fnclex
  54. fldcw wSave
  55. }
  56. #endif
  57. }
  58. protected:
  59. #ifdef _X86_
  60. WORD wSaveFP;
  61. WORD wSavedFP; // WORD-sized to make the data an even DWORD
  62. #endif
  63. };
  64. #define RESPATH_D3D "Software\\Microsoft\\Direct3D"
  65. // this is not available for alpha or IA64
  66. #ifndef LONG_MAX
  67. #define LONG_MAX 2147483647L /* maximum (signed) long value */
  68. #endif
  69. //--------------------------------------------------------------------
  70. // Base definitions
  71. //
  72. // Default color values that should be used when ther is no lighting and
  73. // color in vertices provided
  74. const DWORD __DEFAULT_DIFFUSE = 0xFFFFFFFF;
  75. const DWORD __DEFAULT_SPECULAR = 0;
  76. const DWORD VER_IN_BATCH = 8; // Size of Microsoft's internal clip vertex batch
  77. typedef WORD D3DFE_CLIPCODE;
  78. struct BATCHBUFFER;
  79. //---------------------------------------------------------------------
  80. struct _D3DFE_LIGHTING;
  81. typedef struct _D3DFE_LIGHTING D3DFE_LIGHTING;
  82. struct _D3DI_LIGHT;
  83. typedef struct _D3DI_LIGHT D3DI_LIGHT;
  84. class D3DFE_PROCESSVERTICES;
  85. typedef class D3DFE_PROCESSVERTICES* LPD3DFE_PROCESSVERTICES;
  86. extern "C"
  87. {
  88. typedef void (*LIGHT_VERTEX_FUNC)(LPD3DFE_PROCESSVERTICES pv,
  89. D3DI_LIGHT *light,
  90. D3DVERTEX *pInpCoord,
  91. D3DVECTOR *pInpNormal,
  92. D3DLIGHTINGELEMENT *pEyeSpaceData);
  93. typedef void (*PFN_LIGHTLOOP)(LPD3DFE_PROCESSVERTICES pv,
  94. DWORD dwVerCount,
  95. BATCHBUFFER *pBatchBuffer,
  96. D3DI_LIGHT *light,
  97. D3DVERTEX *in,
  98. D3DVECTOR *pNormal,
  99. DWORD *pDiffuse,
  100. DWORD *pSpecular);
  101. }
  102. //---------------------------------------------------------------------
  103. // "link" member should be the last, because we copy the structure using
  104. // offsetof(D3DMATRIXI, link)
  105. //
  106. typedef struct _D3DMATRIXI
  107. {
  108. D3DVALUE _11, _12, _13, _14;
  109. D3DVALUE _21, _22, _23, _24;
  110. D3DVALUE _31, _32, _33, _34;
  111. D3DVALUE _41, _42, _43, _44;
  112. } D3DMATRIXI, *LPD3DMATRIXI;
  113. //---------------------------------------------------------------------
  114. // This is per texture stage data
  115. //
  116. typedef struct _D3DFE_TEXTURESTAGE
  117. {
  118. DWORD dwInpCoordIndex; // Original value of the texture stage - input index
  119. DWORD dwInpOffset; // Texture coord offset in the FVF vertex
  120. DWORD dwOutCoordIndex; // Input index of the texture set is mapped to this
  121. // output index
  122. DWORD dwOrgStage; // Original texture stage
  123. DWORD dwOrgWrapMode; // Original WRAP mode
  124. D3DMATRIXI *pmTextureTransform; // NULL if texture transform is disabled for the stage
  125. // Bits 0-1 - (number of input texture coordinates - 1)
  126. // Bits 2-3 - (number of output texture coordinates - 1)
  127. DWORD dwTexTransformFuncIndex;
  128. DWORD dwTexGenMode; // Mode of texture generation
  129. } D3DFE_TEXTURESTAGE, *LPD3DFE_TEXTURESTAGE;
  130. //---------------------------------------------------------------------
  131. typedef struct _RECTV
  132. {
  133. union
  134. {
  135. D3DVALUE x1;
  136. D3DVALUE dvX1;
  137. };
  138. union
  139. {
  140. D3DVALUE y1;
  141. D3DVALUE dvY1;
  142. };
  143. union
  144. {
  145. D3DVALUE x2;
  146. D3DVALUE dvX2;
  147. };
  148. union
  149. {
  150. D3DVALUE y2;
  151. D3DVALUE dvY2;
  152. };
  153. } D3DRECTV, *LPD3DRECTV;
  154. //---------------------------------------------------------------------
  155. /*
  156. * Lighting defines
  157. */
  158. typedef struct _SpecularTable
  159. {
  160. LIST_MEMBER(_SpecularTable) list;
  161. float power; /* shininess power */
  162. float table[260]; /* space for overflows */
  163. } SpecularTable;
  164. typedef struct {D3DVALUE r,g,b;} D3DFE_COLOR;
  165. //---------------------------------------------------------------------
  166. // Internal version of lightdata and constants for "flags" member of D3DI_LIGHT
  167. //
  168. const DWORD D3DLIGHTI_ATT0_IS_NONZERO = 1 << 0;
  169. const DWORD D3DLIGHTI_ATT1_IS_NONZERO = 1 << 1;
  170. const DWORD D3DLIGHTI_ATT2_IS_NONZERO = 1 << 2;
  171. const DWORD D3DLIGHTI_LINEAR_FALLOFF = 1 << 3;
  172. // Set when light data is changed
  173. const DWORD D3DLIGHTI_DIRTY = 1 << 4;
  174. // This flag depends on D3DRENDERSTATE_SPACULARENABLE and light specular color
  175. const DWORD D3DLIGHTI_COMPUTE_SPECULAR = 1 << 5;
  176. // Set when light data is set
  177. const DWORD D3DLIGHTI_VALID = 1 << 6;
  178. // Set when the light is enabled
  179. const DWORD D3DLIGHTI_ENABLED = 1 << 7;
  180. const DWORD D3DLIGHTI_SPECULAR_IS_ZERO = 1 << 8;
  181. const DWORD D3DLIGHTI_AMBIENT_IS_ZERO = 1 << 9;
  182. const DWORD D3DLIGHTI_OPTIMIZATIONFLAGS = D3DLIGHTI_SPECULAR_IS_ZERO |
  183. D3DLIGHTI_AMBIENT_IS_ZERO |
  184. D3DLIGHTI_ATT0_IS_NONZERO |
  185. D3DLIGHTI_ATT1_IS_NONZERO |
  186. D3DLIGHTI_ATT2_IS_NONZERO |
  187. D3DLIGHTI_LINEAR_FALLOFF;
  188. //--------------------------------------------------------------------
  189. // Members of this structure should be aligned as stated
  190. typedef struct _D3DI_LIGHT
  191. {
  192. // Should be QWORD aligned
  193. D3DVECTOR model_position; // In the camera or model space
  194. D3DLIGHTTYPE type;
  195. // Should be QWORD aligned
  196. D3DVECTOR model_direction;// In the camera or model space
  197. D3DVALUE falloff;
  198. // Should be QWORD aligned
  199. DWORD flags;
  200. // Should be QWORD aligned. R,G,B should be adjacent
  201. D3DFE_COLOR diffuseMat; // Material diffuse times light color
  202. // Should be QWORD aligned. R,G,B should be adjacent
  203. D3DFE_COLOR specularMat; // Material specular times light color
  204. // Should be QWORD aligned. R,G,B should be adjacent
  205. D3DFE_COLOR ambientMat; // Material specular times light color
  206. D3DVALUE inv_theta_minus_phi;
  207. // Should be QWORD aligned
  208. D3DVECTOR halfway; // Used by directional, parallel-point and
  209. // spot lights when camera is in infinity
  210. struct _D3DI_LIGHT *next; // Next in the active light list
  211. // Should be QWORD aligned
  212. D3DFE_COLOR diffuse; // Original color scaled to 0 - 255
  213. D3DFE_COLOR specular; // Original color scaled to 0 - 255
  214. D3DFE_COLOR ambient; // Original color scaled to 0 - 255
  215. LIGHT_VERTEX_FUNC lightVertexFunc; // Function to light a D3DVERTEX
  216. D3DVALUE range_squared;
  217. D3DVALUE attenuation0;
  218. D3DVALUE attenuation1;
  219. D3DVALUE attenuation2;
  220. D3DVALUE cos_theta_by_2;
  221. D3DVALUE cos_phi_by_2;
  222. D3DVECTOR position; // In the world space
  223. D3DVECTOR direction; // In the world space
  224. D3DVALUE range;
  225. LPVOID pPSGPData; // Pointer to a PSGP specific "per light" data
  226. // Microsoft's pipeline specific data
  227. PFN_LIGHTLOOP pfnLightFirst; // Used in multi-loop pipeline for first lights
  228. PFN_LIGHTLOOP pfnLightNext; // Used in multi-loop pipeline for not first lights
  229. } D3DI_LIGHT, *LPD3DI_LIGHT;
  230. //---------------------------------------------------------------------
  231. // Bits for lighting flags (dwLightingFlags
  232. //
  233. const DWORD __LIGHT_VERTEXTRANSFORMED = 1; // Vertex is in the camera space
  234. const DWORD __LIGHT_NORMALTRANSFORMED = 2; // Normal is in the camera space
  235. const DWORD __LIGHT_SPECULARCOMPUTED = 4;
  236. const DWORD __LIGHT_DIFFUSECOMPUTED = 8;
  237. //---------------------------------------------------------------------
  238. // Members of this structure should be aligned as stated
  239. //
  240. typedef struct _D3DFE_LIGHTING
  241. {
  242. // Temporary data used when computing lighting
  243. // Should be QWORD aligned
  244. D3DFE_COLOR diffuse;
  245. DWORD alpha; // Alpha to use for output vertex color
  246. // (could be overriden by vertex difuse
  247. // color) (0-255) shifted left by 24 bits
  248. // Should be QWORD aligned
  249. D3DFE_COLOR diffuse0; // Ca*Cma + Cme
  250. float *currentSpecTable;
  251. // Should be QWORD aligned
  252. D3DFE_COLOR specular;
  253. DWORD outDiffuse; // Result of lighting
  254. // Should be QWORD aligned
  255. D3DVECTOR model_eye; // camera position in model or camera space
  256. DWORD vertexAmbient; // Provided with a vertex
  257. // Should be QWORD aligned
  258. D3DFE_COLOR ambientSceneScaled; // Scene ambient color (scaled 0.0-255.0)
  259. DWORD vertexDiffuse; // Provided with a vertex
  260. // Should be QWORD aligned
  261. D3DFE_COLOR ambientScene; // Scene ambient color (0.0-1.0)
  262. DWORD outSpecular; // Result of lighting
  263. // Should be QWORD aligned
  264. D3DVECTOR directionToCamera; // Direction to camera in the model space
  265. // Used in model space lighting
  266. DWORD vertexSpecular; // Provided with a vertex
  267. // Should be QWORD aligned
  268. D3DMATERIAL7 material;
  269. DWORD dwLightingFlags;
  270. DWORD alphaSpecular; // Alpha to use for output specular vertex color
  271. // (could be overriden by vertex specular
  272. // color) (0-255) shifted left by 24 bits
  273. // End of temporary data
  274. D3DI_LIGHT *activeLights;
  275. int fog_mode;
  276. D3DVALUE fog_density;
  277. D3DVALUE fog_start;
  278. D3DVALUE fog_end;
  279. D3DVALUE fog_factor; // 255 / (fog_end - fog_start)
  280. D3DVALUE specThreshold; // If a dot product less than this value,
  281. // specular factor is zero
  282. DWORD ambient_save; // Original unscaled color
  283. int materialAlpha; // Current material diffuse alpha (0-255)
  284. // shifted left by 24 bits
  285. int materialAlphaS; // Current material specular alpha (0-255)
  286. // shifted left by 24 bits
  287. DWORD dwDiffuse0; // Packed diffuse0
  288. DWORD dwAmbientSrcIndex; // 0 - diffuse, 1 - specular
  289. DWORD dwDiffuseSrcIndex; // 0 - diffuse, 1 - specular
  290. DWORD dwSpecularSrcIndex; // 0 - diffuse, 1 - specular
  291. DWORD dwEmissiveSrcIndex; // 0 - diffuse, 1 - specular
  292. } D3DFE_LIGHTING;
  293. //---------------------------------------------------------------------
  294. // Some data precomputed for a current viewport
  295. // ATTENTION: If you want to add or re-arrange data, contact IOURIT or ANUJG
  296. //
  297. typedef struct _D3DFE_VIEWPORTCACHE
  298. {
  299. // Coefficients to compute screen coordinates from normalized window
  300. // coordinates
  301. D3DVALUE scaleX; // dvWidth
  302. D3DVALUE scaleY; // -dvHeight
  303. D3DVALUE offsetX; // dvX
  304. D3DVALUE offsetY; // dvY + dvHeight
  305. D3DVALUE scaleZ; // dvMaxZ - dvMinZ
  306. D3DVALUE offsetZ; // dvY + dvHeight
  307. // Min and max window values with gaurd band in pixels
  308. D3DVALUE minXgb;
  309. D3DVALUE minYgb;
  310. D3DVALUE maxXgb;
  311. D3DVALUE maxYgb;
  312. // Min and max values for viewport window in pixels
  313. D3DVALUE minX; // offsetX - scaleX
  314. D3DVALUE minY; // offsetY - scaleY
  315. D3DVALUE maxX; // offsetX + scaleX
  316. D3DVALUE maxY; // offsetY + scaleY
  317. // Coefficients to transform a vertex to perform the guard band clipping
  318. // x*gb11 + w*gb41
  319. // y*gb22 + w*gb42
  320. //
  321. D3DVALUE gb11;
  322. D3DVALUE gb22;
  323. D3DVALUE gb41;
  324. D3DVALUE gb42;
  325. // Coefficients to apply clipping rules for the guard band clipping
  326. // They are used by clipping routins
  327. // w*Kgbx1 < x < w*Kgbx2
  328. // w*Kgby1 < y < w*Kgby2
  329. //
  330. D3DVALUE Kgbx1;
  331. D3DVALUE Kgby1;
  332. D3DVALUE Kgbx2;
  333. D3DVALUE Kgby2;
  334. D3DVALUE dvX; // dwX
  335. D3DVALUE dvY; // dwY
  336. D3DVALUE dvWidth; // dwWidth
  337. D3DVALUE dvHeight; // dwHeight
  338. // Coefficients to compute screen coordinates from normalized window
  339. // coordinates
  340. D3DVALUE scaleXi; // Inverse of scaleX
  341. D3DVALUE scaleYi; // Inverse of scaleY
  342. D3DVALUE scaleZi; // Inverse of scaleZ
  343. // Min and max values for viewport window in pixels (integer version)
  344. int minXi; // offsetX - scaleX
  345. int minYi; // offsetY - scaleY
  346. int maxXi; // offsetX + scaleX
  347. int maxYi; // offsetY + scaleY
  348. } D3DFE_VIEWPORTCACHE;
  349. //---------------------------------------------------------------------
  350. // Process vertices interface
  351. //
  352. // Bits for process vertices flags
  353. // 8 bits are reserved for Draw Primitive flags
  354. //
  355. // D3DDEV_STRIDE D3DPV_SOA
  356. // 0 1 position.dwStride = number of vertices in SOA
  357. // 0 0 position.dwStride = contiguous vertex size
  358. // 1 0 vertex is not contiguous, all dwStride fields are used
  359. // 1 1 reserved
  360. // 1 1 reserved
  361. //
  362. const DWORD D3DPV_FOG = 1 << 8; // Need to apply fog
  363. const DWORD D3DPV_DOCOLORVERTEX = 1 << 9; // Need to apply color vertex
  364. const DWORD D3DPV_LIGHTING = 1 << 10; // Need to apply lighting
  365. const DWORD D3DPV_SOA = 1 << 12; // SOA structure is used
  366. const DWORD D3DPV_COLORVERTEX_E = 1 << 13; // Need to replace emissive material color
  367. const DWORD D3DPV_COLORVERTEX_D = 1 << 14; // Need to replace diffuse material color
  368. const DWORD D3DPV_COLORVERTEX_S = 1 << 15; // Need to replace specular material color
  369. const DWORD D3DPV_COLORVERTEX_A = 1 << 16; // Need to replace ambient material color
  370. // Set by ProcessVertices call with D3DPV_DONOTCOPYDATA flag set
  371. // Specular color should not be copied to the output vertex
  372. const DWORD D3DPV_DONOTCOPYSPECULAR = 1 << 20;
  373. // Set when one pass clipping and vertex processing is used
  374. const DWORD D3DPV_ONEPASSCLIPPING= 1 << 21;
  375. const DWORD D3DPV_RESERVED1 = 1 << 22;
  376. const DWORD D3DPV_RESERVED2 = 1 << 23;
  377. const DWORD D3DPV_RESERVED3 = 1 << 24;
  378. // This indicates that the primitive is non clipped, but we pretend that it is
  379. // clipped to generate DP2HAL inline primitive. Can only be set by tri fan.
  380. const DWORD D3DPV_NONCLIPPED = 1 << 25;
  381. // Propagated from dwFEFlags
  382. const DWORD D3DPV_FRUSTUMPLANES_DIRTY = 1 << 26;
  383. // Set if the geometry loop is called from VertexBuffer::ProcessVertices.
  384. // Processing is different because the output buffer FVF format is defined by
  385. // user, not by SetupFVFData function.
  386. const DWORD D3DPV_VBCALL = 1 << 27;
  387. // Set by ProcessVertices call with D3DPV_DONOTCOPYDATA flag set
  388. // Texture coordinates should not be copied to the output vertex
  389. const DWORD D3DPV_DONOTCOPYTEXTURE = 1 << 28;
  390. // To mark whether we are doing TLVERTEX clipping or not
  391. const DWORD D3DPV_TLVCLIP = 1 << 29;
  392. // Mictosoft internal !!! Set when only transformation is required
  393. // (no lightng or texture copy)
  394. const DWORD D3DPV_TRANSFORMONLY = 1 << 30;
  395. // Set by ProcessVertices call with D3DPV_DONOTCOPYDATA flag set
  396. // Diffuse color should not be copied to the output vertex
  397. const DWORD D3DPV_DONOTCOPYDIFFUSE = 1 << 31;
  398. // These flags persist from call to call till something cuses them to change
  399. const DWORD D3DPV_PERSIST = D3DPV_FOG |
  400. D3DPV_LIGHTING |
  401. D3DPV_DONOTCOPYDIFFUSE |
  402. D3DPV_DONOTCOPYSPECULAR |
  403. D3DPV_DONOTCOPYTEXTURE |
  404. D3DPV_TRANSFORMONLY |
  405. D3DPV_TLVCLIP ;
  406. // Bits for dwDeviceFlags
  407. //
  408. const DWORD D3DDEV_GUARDBAND = 1 << 1; // Use guard band clipping
  409. const DWORD D3DDEV_RANGEBASEDFOG = 1 << 2; // Set if range based fog is enabled
  410. // This bit is set if fog mode is not FOG_NONE and fog is enabled
  411. const DWORD D3DDEV_FOG = 1 << 3;
  412. const DWORD D3DDEV_FVF = 1 << 4; // FVF supported
  413. const DWORD D3DDEV_DONOTSTRIPELEMENTS = 1 << 6; // Copy of D3DFVFCAPS_DONOTSTRIPELEMENTS
  414. // These are bits in dwDeviceFlags that could be changed, but not
  415. // necessary per every primitive.
  416. //
  417. // Set when D3DRENDERSTATE_SPECULARENABLE is TRUE
  418. const DWORD D3DDEV_SPECULARENABLE = 1 << 11;
  419. // Set if diffuse color should be interpolated during clipping
  420. const DWORD D3DDEV_INTERPOLATE_COLOR = 1 << 12;
  421. // Set if specular color should be interpolated during clipping
  422. const DWORD D3DDEV_INTERPOLATE_SPECULAR = 1 << 13;
  423. // This flag is for PSGP only. PSGP implementation should clear the flag
  424. const DWORD D3DDEV_FRUSTUMPLANES_DIRTY = 1 << 14;
  425. // This flag is for PSGP only. PSGP implementation should clear the flag
  426. const DWORD D3DDEV_TEXTRANSFORMDIRTY = 1 << 15; // Need to re-evaluate texture transforms
  427. // The flag is set when the number of output texture coord is greater then the
  428. // number of the input ones. This could happen when the same texture transform
  429. // matrix is used with the same input texture coord set. In this case we save
  430. // texture indices from the texture stages in the textureStages and map all
  431. // indices sequentially.
  432. const DWORD D3DDEV_REMAPTEXTUREINDICES = 1 << 16;
  433. // These two flags are for PSGP only. PSGP implementation should clear the flags
  434. const DWORD D3DDEV_TRANSFORMDIRTY = 1 << 17; // Transform matrix has been changed
  435. const DWORD D3DDEV_LIGHTSDIRTY = 1 << 18; // Lights have been changed
  436. const DWORD D3DDEV_DONOTCLIP = 1 << 19; // Clipping is disabled
  437. const DWORD D3DDEV_DONOTUPDATEEXTENTS = 1 << 20; // Extents computation is disabled
  438. // Set, if driver does not support FVF and there is no texture coordinates in
  439. // the vertex
  440. const DWORD D3DDEV_NOFVFANDNOTEXTURE = 1 << 21;
  441. // This flag is set if the current TLVbuf is write only
  442. const DWORD D3DDEV_TLVBUFWRITEONLY = 1 << 22;
  443. // World-view matrix does not have scale, so we can do lighting
  444. // in the model space
  445. const DWORD D3DDEV_MODELSPACELIGHTING = 1 << 23;
  446. // Set if viewer is local (used for lighting)
  447. const DWORD D3DDEV_LOCALVIEWER = 1 << 24;
  448. // Set if we wave to normalize normals after transforming them to the camera space
  449. const DWORD D3DDEV_NORMALIZENORMALS = 1 << 25;
  450. // Set if we wave to do texture transform
  451. const DWORD D3DDEV_TEXTURETRANSFORM = 1 << 26;
  452. // Set if the last draw primitive call was strided
  453. const DWORD D3DDEV_STRIDE = 1 << 27;
  454. // Set if D3DRENDERSTATE_COLORVERTEX is TRUE
  455. const DWORD D3DDEV_COLORVERTEX = 1 << 28;
  456. // Set if position in camera space is always needed
  457. const DWORD D3DDEV_POSITIONINCAMERASPACE= 1 << 29;
  458. // Set if normal in camera space is always needed
  459. const DWORD D3DDEV_NORMALINCAMERASPACE = 1 << 30;
  460. // Set if D3DRENDERSTATE_LIGHTING is set
  461. const DWORD D3DDEV_LIGHTING = 1 << 31;
  462. //--------------------------------------------------------------------
  463. // Clipper defines
  464. //
  465. // Six standard clipping planes plus six user defined clipping planes.
  466. // See rl\d3d\d3d\d3dtypes.h.
  467. //
  468. #define MAX_CLIPPING_PLANES 12
  469. // Space for vertices generated/copied while clipping one triangle
  470. #define MAX_CLIP_VERTICES (( 2 * MAX_CLIPPING_PLANES ) + 3 )
  471. // 3 verts. -> 1 tri, 4 v -> 2 t, N vertices -> (N - 2) triangles
  472. #define MAX_CLIP_TRIANGLES ( MAX_CLIP_VERTICES - 2 )
  473. const DWORD MAX_FVF_TEXCOORD = 8;
  474. class ClipVertex
  475. {
  476. public:
  477. D3DVALUE hx; // Clipping space coordinates. Must be in this order
  478. D3DVALUE hy;
  479. D3DVALUE hz;
  480. D3DVALUE hw;
  481. int clip;
  482. D3DCOLOR color;
  483. D3DCOLOR specular;
  484. D3DVALUE sx; // Screen space coordinates. Must be in this order
  485. D3DVALUE sy;
  486. D3DVALUE sz;
  487. D3DVALUE rhw;
  488. ClipVertex *next;
  489. D3DVALUE tex[MAX_FVF_TEXCOORD*4];
  490. };
  491. typedef struct _ClipTriangle
  492. {
  493. ClipVertex *v[3];
  494. } ClipTriangle;
  495. typedef struct _D3DI_CLIPSTATE
  496. {
  497. ClipVertex *clip_vbuf1[MAX_CLIP_VERTICES];
  498. ClipVertex *clip_vbuf2[MAX_CLIP_VERTICES];
  499. ClipVertex **current_vbuf; // clip_vbuf1 or clip_vbuf2
  500. ClipVertex clip_vertices[MAX_CLIP_VERTICES];
  501. CBufferDDS clipBuf; // Used for TL vertices, generated by the clipper
  502. CBufferDDS clipBufPrim; // Used for primitives, generated by the clipper
  503. // for execute buffers
  504. int clip_vertices_used;
  505. DWORD clip_color;
  506. DWORD clip_specular;
  507. LPDIRECTDRAWSURFACE lpDDExeBuf; // Current user execute buffer
  508. LPVOID lpvExeBufMem; // Current memory for user execute buffer
  509. } D3DI_CLIPSTATE, *LPD3DI_CLIPSTATE;
  510. // These bit are set when a vertex is clipped by a frustum plane
  511. #define CLIPPED_LEFT (D3DCLIP_GEN5 << 1)
  512. #define CLIPPED_RIGHT (D3DCLIP_GEN5 << 2)
  513. #define CLIPPED_TOP (D3DCLIP_GEN5 << 3)
  514. #define CLIPPED_BOTTOM (D3DCLIP_GEN5 << 4)
  515. #define CLIPPED_FRONT (D3DCLIP_GEN5 << 5)
  516. #define CLIPPED_BACK (D3DCLIP_GEN5 << 6)
  517. #define CLIPPED_ENABLE (D3DCLIP_GEN5 << 7) /* wireframe enable flag */
  518. // These bit are set when a vertex is clipped by a user clipping plane
  519. const DWORD CLIPPED_GEN0 = D3DCLIP_GEN5 << 8;
  520. const DWORD CLIPPED_GEN1 = D3DCLIP_GEN5 << 9;
  521. const DWORD CLIPPED_GEN2 = D3DCLIP_GEN5 << 10;
  522. const DWORD CLIPPED_GEN3 = D3DCLIP_GEN5 << 11;
  523. const DWORD CLIPPED_GEN4 = D3DCLIP_GEN5 << 12;
  524. const DWORD CLIPPED_GEN5 = D3DCLIP_GEN5 << 13;
  525. // Guard band clipping bits
  526. //
  527. // A guard bit is set when a point is out of guard band
  528. // Guard bits should be cleared before a call to clip a triangle, because
  529. // they are the same as CLIPPED_... bits
  530. //
  531. // Example of clipping bits setting for X coordinate:
  532. //
  533. // if -w < x < w no clipping bit is set
  534. // if -w*ax1 < x <= -w D3DCLIP_LEFT bit is set
  535. // if x < -w*ax1 __D3DCLIPGB_LEFT bit is set
  536. //
  537. #define __D3DCLIPGB_LEFT (D3DCLIP_GEN5 << 1)
  538. #define __D3DCLIPGB_RIGHT (D3DCLIP_GEN5 << 2)
  539. #define __D3DCLIPGB_TOP (D3DCLIP_GEN5 << 3)
  540. #define __D3DCLIPGB_BOTTOM (D3DCLIP_GEN5 << 4)
  541. #define __D3DCLIPGB_ALL (__D3DCLIPGB_LEFT | __D3DCLIPGB_RIGHT | \
  542. __D3DCLIPGB_TOP | __D3DCLIPGB_BOTTOM)
  543. const DWORD __D3DCLIP_USERPLANES = D3DCLIP_GEN0 | D3DCLIP_GEN1 | D3DCLIP_GEN2 |
  544. D3DCLIP_GEN3 | D3DCLIP_GEN4 | D3DCLIP_GEN5;
  545. // If only these bits are set, then this point is inside the guard band
  546. //
  547. #define __D3DCLIP_INGUARDBAND (D3DCLIP_LEFT | D3DCLIP_RIGHT | \
  548. D3DCLIP_TOP | D3DCLIP_BOTTOM)
  549. //---------------------------------------------------------------------
  550. // Bits in the dwFlags2
  551. //
  552. // The bit is set when the texture transform is enabled
  553. const DWORD __FLAGS2_TEXTRANSFORM0 = 1 << 0;
  554. const DWORD __FLAGS2_TEXTRANSFORM1 = 1 << 1;
  555. const DWORD __FLAGS2_TEXTRANSFORM2 = 1 << 2;
  556. const DWORD __FLAGS2_TEXTRANSFORM3 = 1 << 3;
  557. const DWORD __FLAGS2_TEXTRANSFORM4 = 1 << 4;
  558. const DWORD __FLAGS2_TEXTRANSFORM5 = 1 << 5;
  559. const DWORD __FLAGS2_TEXTRANSFORM6 = 1 << 6;
  560. const DWORD __FLAGS2_TEXTRANSFORM7 = 1 << 7;
  561. const DWORD __FLAGS2_TEXTRANSFORM = __FLAGS2_TEXTRANSFORM0 |
  562. __FLAGS2_TEXTRANSFORM1 |
  563. __FLAGS2_TEXTRANSFORM2 |
  564. __FLAGS2_TEXTRANSFORM3 |
  565. __FLAGS2_TEXTRANSFORM4 |
  566. __FLAGS2_TEXTRANSFORM5 |
  567. __FLAGS2_TEXTRANSFORM6 |
  568. __FLAGS2_TEXTRANSFORM7;
  569. // The bit is set when the texture coordinate set is taken from the vertex data
  570. // (position or normal)
  571. const DWORD __FLAGS2_TEXGEN0 = 1 << 16;
  572. const DWORD __FLAGS2_TEXGEN1 = 1 << 17;
  573. const DWORD __FLAGS2_TEXGEN2 = 1 << 18;
  574. const DWORD __FLAGS2_TEXGEN3 = 1 << 19;
  575. const DWORD __FLAGS2_TEXGEN4 = 1 << 20;
  576. const DWORD __FLAGS2_TEXGEN5 = 1 << 21;
  577. const DWORD __FLAGS2_TEXGEN6 = 1 << 22;
  578. const DWORD __FLAGS2_TEXGEN7 = 1 << 23;
  579. const DWORD __FLAGS2_TEXGEN = __FLAGS2_TEXGEN0 |
  580. __FLAGS2_TEXGEN1 |
  581. __FLAGS2_TEXGEN2 |
  582. __FLAGS2_TEXGEN3 |
  583. __FLAGS2_TEXGEN4 |
  584. __FLAGS2_TEXGEN5 |
  585. __FLAGS2_TEXGEN6 |
  586. __FLAGS2_TEXGEN7;
  587. //---------------------------------------------------------------------
  588. #define __TEXTURETRANSFORMENABLED(pv) pv->dwFlags2 & __FLAGS2_TEXTRANSFORM
  589. const DWORD __MAXUSERCLIPPLANES = 6;
  590. //---------------------------------------------------------------------
  591. // Visible states, input and output data
  592. //
  593. class D3DFE_PROCESSVERTICES
  594. {
  595. public:
  596. D3DFE_PROCESSVERTICES();
  597. virtual HRESULT SetRenderStateI(D3DRENDERSTATETYPE, DWORD) = 0;
  598. // State
  599. // Should be QWORD aligned
  600. D3DMATRIXI mTexture[D3DDP_MAXTEXCOORD]; // Texture transform;
  601. D3DMATRIXI mCTM2[3];
  602. D3DMATRIXI mWV2[3];
  603. D3DMATRIXI mWVI2[3];
  604. D3DMATRIXI mWV; // Transforms to camera space (Mworld*Mview)
  605. D3DMATRIXI mWVI; // Inverse mWV
  606. D3DMATRIXI mCTM; // Current Transformation Matrix
  607. // supported by driver
  608. // Should be QWORD aligned
  609. D3DFE_LIGHTING lighting; // Lighting state
  610. // Should be QWORD aligned
  611. D3DFE_VIEWPORTCACHE vcache; // Data, computed fromto viewport settings
  612. DWORD dwClipUnion; // OR of all vertex clip flags
  613. DWORD dwClipIntersection; // AND of all vertex clip flags
  614. DWORD dwTextureIndexToCopy; // Used for not FVF devices. Used by PSGP
  615. D3DVALUE dvExtentsAdjust; // Replicated here from device caps
  616. // Current texture stage vector
  617. LPVOID *pD3DMappedTexI;
  618. D3DI_CLIPSTATE ClipperState; // State for triangle/line clipper
  619. union {
  620. D3DDP_PTRSTRIDE normal;
  621. DWORD dwSOAStartVertex;
  622. };
  623. D3DDP_PTRSTRIDE diffuse;
  624. // Cache line should start here
  625. D3DPRIMITIVETYPE primType;
  626. DWORD dwNumVertices; // Number of vertices to process
  627. DWORD dwFlags; // Flags word describing what to do
  628. // Location of the first vertex in the vertex buffer (DP2 DDI)
  629. // ATTENTION May be we can get rid of it?
  630. DWORD dwVertexBase;
  631. DWORD dwNumIndices; // 0 for non-indexed primitive
  632. LPWORD lpwIndices;
  633. DWORD dwNumPrimitives;
  634. DWORD dwDP2VertexCount; // Number of vertices in DP2 vertex buffer
  635. // Internal data for Microsoft implementation
  636. // Cache line should start here
  637. DWORD dwVIDIn; // Vertex ID of input vertices
  638. DWORD dwDeviceFlags; // Flags that are constant per device
  639. // D3DPV_.. and primitive flags are combined
  640. DWORD dwOutputSize; // Output vertex size
  641. DWORD dwFEFlags; // MS internal use Only!!
  642. DWORD dwVIDOut; // Vertex ID of output vertices
  643. LPVOID lpvOut; // Output pointer (output always packed)
  644. DWORD dwVertexPoolSize; // Size of vertices in the un-clipped part of a primitive
  645. // in bytes, put to the DP2 vertex buffer
  646. // Internal data for Microsoft implementation
  647. union {
  648. D3DDP_PTRSTRIDE position; // dwStride should always be set !!!
  649. D3DDP_PTRSTRIDE SOA;
  650. };
  651. D3DFE_CLIPCODE* lpClipFlags; // Clip flags to output
  652. DWORD nTexCoord; // Number of the input texture coordinate sets
  653. DWORD nOutTexCoord; // Number of the output texture coordinate sets to process.
  654. // WARNING. It could be different from the texture count in dwVIDOut
  655. // (it could be zero for example when dwVIDOut has 1 texture coord set).
  656. // If D3DDEV_REMAPTEXTUREINDICES is set this is equal
  657. // to the number of active texture stages
  658. // Total size of all output texture coordinates in bytes
  659. DWORD dwTextureCoordSizeTotal;
  660. D3DDP_PTRSTRIDE specular;
  661. D3DDP_PTRSTRIDE textures[D3DDP_MAXTEXCOORD];
  662. // Size of output texture coordinate sets in bytes
  663. DWORD dwTextureCoordSize[D3DDP_MAXTEXCOORD];
  664. // Size of input texture coordinate sets in bytes
  665. DWORD dwInpTextureCoordSize[D3DDP_MAXTEXCOORD];
  666. // Output
  667. LPDWORD lpdwRStates; // Current render state vector
  668. D3DRECTV rExtents; // Extents rectangle to update, if required
  669. D3DFE_TEXTURESTAGE textureStage[D3DDP_MAXTEXCOORD]; // Texture state stages
  670. DWORD dwNumTextureStages; // Used when we have to re-map texture indices
  671. // This array is used when we do not do re-mapping of texture coordinates
  672. D3DMATRIXI *pmTexture[D3DDP_MAXTEXCOORD];
  673. D3DVECTORH userClipPlane[__MAXUSERCLIPPLANES];
  674. DWORD dwFlags2; // Low 8 bits are texture transform enable:
  675. // bit 0 corresponds to the texture stage 0
  676. // Bits 8-15 are for user clipping plane
  677. // Bits 16-23 are set if corresponding texture coord set
  678. // is taken from the vertex data (position or normal)
  679. DWORD dwNumVerBlends; // Number of weights for vertex blending
  680. DWORD dwMaxUserClipPlanes;
  681. virtual HRESULT DrawPrim()=0; // Use to pass non-indexed primitives to the driver
  682. virtual HRESULT DrawIndexPrim()=0; // Use to pass indexed primitives to driver
  683. virtual HRESULT DrawClippedPrim()=0; // Use to pass clipped non-indexed primitives to driver
  684. // Internal data for Microsoft implementation
  685. DWORD texOffset; // Offsets in the input FVF vertex. Recomputed
  686. DWORD normalOffset; // when FVF is changed.
  687. DWORD diffuseOffset; //
  688. DWORD specularOffset;
  689. DWORD texOffsetOut; // Offsets in the output FVF vertex. Recomputed
  690. DWORD diffuseOffsetOut; // when FVF is changed.
  691. DWORD specularOffsetOut;
  692. DWORD dwClipMaskOffScreen; // When and this mask with the clip code we
  693. // have bits that are outside the guard band
  694. ClipVertex clipVer[VER_IN_BATCH]; // Clip vertices. Used in processing
  695. // and clipping in the one loop
  696. DWORD dwFirstClippedVertex; // Index of the first vertex with non-zero clip code
  697. DWORD dwMaxTextureIndices; // Max number of texture coord sets
  698. };
  699. //---------------------------------------------------------------------
  700. // Prototype for the function to be written for a given processor implementation
  701. //
  702. // Returns clip intersection.
  703. //
  704. class ID3DFE_PVFUNCS
  705. {
  706. public:
  707. virtual ~ID3DFE_PVFUNCS() { };
  708. virtual DWORD ProcessVertices(LPD3DFE_PROCESSVERTICES)=0;
  709. virtual HRESULT ProcessPrimitive(LPD3DFE_PROCESSVERTICES)=0;
  710. virtual HRESULT ProcessIndexedPrimitive(LPD3DFE_PROCESSVERTICES)=0;
  711. virtual HRESULT OptimizeVertexBuffer
  712. (DWORD dwFVFID, // Vertex type. XYZ position is allowed
  713. DWORD dwNumVertices, // Number of vertices
  714. DWORD dwVertexSize, // Vertex size in bytes
  715. LPVOID lpSrcBuffer, // Source buffer.
  716. LPVOID lpDstBuffer, // Output buffer.
  717. DWORD dwFlags) // Should be zero for now
  718. {return E_NOTIMPL;}
  719. // Returns number of bytes to allocate for an optimized vertex buffer
  720. // This function is called before OptimizeVertexBuffer
  721. virtual DWORD ComputeOptimizedVertexBufferSize
  722. (DWORD dwFVF, // Vertex type
  723. DWORD dwVertexSize, // Vertex size in bytes
  724. DWORD dwNumVertices) // Number of vertices
  725. {return 0;}
  726. // This function could be used if PSGP doesn't want to implement complete
  727. // clipping pipeline
  728. // Parameters:
  729. // pv - state data
  730. // tri - triangle to clip
  731. // clipVertexPointer - pointer to an array of pointers to
  732. // generated vertices
  733. // Returns:
  734. // Number of vertices in clipped triangle
  735. // 0, if the triangle is off screen
  736. virtual int ClipSingleTriangle(D3DFE_PROCESSVERTICES *pv,
  737. ClipTriangle *tri,
  738. ClipVertex ***clipVertexPointer) = 0;
  739. virtual HRESULT ComputeSphereVisibility( LPD3DFE_PROCESSVERTICES pPV,
  740. LPD3DVECTOR lpCenters,
  741. LPD3DVALUE lpRadii,
  742. DWORD dwNumSpheres,
  743. DWORD dwFlags,
  744. LPDWORD lpdwReturnValues) = 0;
  745. virtual HRESULT ProcessTriangleList(LPD3DFE_PROCESSVERTICES)=0;
  746. virtual HRESULT ProcessTriangleFan(LPD3DFE_PROCESSVERTICES)=0;
  747. virtual HRESULT ProcessTriangleStrip(LPD3DFE_PROCESSVERTICES)=0;
  748. };
  749. typedef ID3DFE_PVFUNCS *LPD3DFE_PVFUNCS;
  750. //---------------------------------------------------------------------
  751. // Direct3D implementation of PVFUNCS
  752. //
  753. class D3DFE_PVFUNCS : public ID3DFE_PVFUNCS
  754. {
  755. public:
  756. DWORD ProcessVertices(LPD3DFE_PROCESSVERTICES);
  757. HRESULT ProcessPrimitive(LPD3DFE_PROCESSVERTICES);
  758. HRESULT ProcessIndexedPrimitive(LPD3DFE_PROCESSVERTICES);
  759. int ClipSingleTriangle(D3DFE_PROCESSVERTICES *pv,
  760. ClipTriangle *tri,
  761. ClipVertex ***clipVertexPointer);
  762. HRESULT ComputeSphereVisibility( LPD3DFE_PROCESSVERTICES pPV,
  763. LPD3DVECTOR lpCenters,
  764. LPD3DVALUE lpRadii,
  765. DWORD dwNumSpheres,
  766. DWORD dwFlags,
  767. LPDWORD lpdwReturnValues);
  768. HRESULT ProcessTriangleList(LPD3DFE_PROCESSVERTICES);
  769. HRESULT ProcessTriangleFan(LPD3DFE_PROCESSVERTICES);
  770. HRESULT ProcessTriangleStrip(LPD3DFE_PROCESSVERTICES);
  771. private:
  772. HRESULT ProcessLineStrip(D3DFE_PROCESSVERTICES *pv);
  773. HRESULT ProcessLineList(D3DFE_PROCESSVERTICES *pv);
  774. };
  775. // GeometrySetup function takes a DWORD describing the dirty bits and the new state vector
  776. // and passes back the 3 new leaf routines to use.
  777. typedef HRESULT (D3DAPI *LPD3DFE_CONTEXTCREATE)(DWORD dwFlags, LPD3DFE_PVFUNCS *lpLeafFuncs);
  778. // Global pointer to Processor specific PV setup routine
  779. // This is defined in dlld3d.cpp
  780. extern LPD3DFE_CONTEXTCREATE pfnFEContextCreate;
  781. #endif // _D3DFE_H