Source code of Windows XP (NT5)
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.

1116 lines
45 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. // DX8 Copy the whole file to DX8
  11. #ifndef _D3DFE_H
  12. #define _D3DFE_H
  13. #include "d3dtypesp.h"
  14. #include "d3d8p.h"
  15. #include "lists.hpp"
  16. #include "d3ditype.h"
  17. class RTDebugMonitor;
  18. class CD3DDDI;
  19. class ID3DFE_PVFUNCS;
  20. struct CVStream;
  21. const DWORD __MAX_VERTEX_SIZE = 180; // Max size of FVF vertex in bytes
  22. //-----------------------------------------------------------------------------
  23. // "link" member should be the last, because we copy the structure using
  24. // offsetof(D3DMATRIXI, link)
  25. //
  26. #define D3DMATRIXI D3DMATRIX
  27. #define LPD3DMATRIXI LPD3DMATRIX
  28. // Bits for m_dwOutRegs
  29. const DWORD CPSGPShader_SPECULAR = 1 << 0;
  30. const DWORD CPSGPShader_DIFFUSE = 1 << 1;
  31. const DWORD CPSGPShader_POSITION = 1 << 2;
  32. const DWORD CPSGPShader_PSIZE = 1 << 3;
  33. const DWORD CPSGPShader_FOG = 1 << 4;
  34. //-----------------------------------------------------------------------------
  35. // Base class for PSGP vertex shader
  36. // PSGP should derive its internal shader object from the class and return it
  37. // in CreateShader call.
  38. // Desctructor should be implemented.
  39. //
  40. class CPSGPShader
  41. {
  42. public:
  43. virtual ~CPSGPShader() {}
  44. // The following data is initialized by Microsoft after CPSGPShader is
  45. // created
  46. // Defines output registers (except texture) written by the shader
  47. // This member is filled by Microsoft's pipeline. PSGP reads it.
  48. DWORD m_dwOutRegs;
  49. // Output FVF for this shaders
  50. DWORD m_dwOutFVF;
  51. // Diffuse color offset in the output vertex in bytes
  52. DWORD m_dwPointSizeOffset;
  53. // Diffuse color offset in the output vertex in bytes
  54. DWORD m_dwDiffuseOffset;
  55. // Specular color offset in the output vertex in bytes
  56. DWORD m_dwSpecularOffset;
  57. // Fog factor offset in the output vertex in bytes
  58. DWORD m_dwFogOffset;
  59. // Texture offset in the output vertex in bytes
  60. DWORD m_dwTextureOffset;
  61. // Output vertex size in bytes
  62. DWORD m_dwOutVerSize;
  63. // Number of output texture coordinate sets
  64. DWORD m_nOutTexCoord;
  65. // Size of each texture set in bytes
  66. DWORD m_dwOutTexCoordSize[D3DDP_MAXTEXCOORD];
  67. };
  68. //-----------------------------------------------------------------------------
  69. //
  70. // Software pipeline constants
  71. //
  72. //-----------------------------------------------------------------------------
  73. // Default color values that should be used when ther is no lighting and
  74. // color in vertices provided
  75. const DWORD __DEFAULT_DIFFUSE = 0xFFFFFFFF;
  76. const DWORD __DEFAULT_SPECULAR = 0;
  77. const DWORD __MAXUSERCLIPPLANES = 6;
  78. const DWORD __NUMELEMENTS = 17;
  79. const DWORD __NUMSTREAMS = __NUMELEMENTS;
  80. //-----------------------------------------------------------------------------
  81. // The CSetD3DFPstate is used to facilitate the changing of FPU settings.
  82. // In the constructor the optimal FPU state is set. In the destructor the
  83. // old state is restored.
  84. //
  85. class CD3DFPstate
  86. {
  87. public:
  88. CD3DFPstate()
  89. {
  90. #ifdef _X86_
  91. WORD wTemp, wSave;
  92. wSavedFP = FALSE;
  93. // Disable floating point exceptions and go to single mode
  94. __asm fstcw wSave
  95. if (wSave & 0x300 || // Not single mode
  96. 0x3f != (wSave & 0x3f) || // Exceptions enabled
  97. wSave & 0xC00) // Not round to nearest mode
  98. {
  99. __asm {
  100. mov ax, wSave
  101. and ax, not 300h ;; single mode
  102. or ax, 3fh ;; disable all exceptions
  103. and ax, not 0xC00 ;; round to nearest mode
  104. mov wTemp, ax
  105. fldcw wTemp
  106. }
  107. wSavedFP = TRUE;
  108. }
  109. wSaveFP = wSave;
  110. #endif
  111. }
  112. ~CD3DFPstate()
  113. {
  114. #ifdef _X86_
  115. WORD wSave = wSaveFP;
  116. if (wSavedFP)
  117. __asm {
  118. fnclex
  119. fldcw wSave
  120. }
  121. #endif
  122. }
  123. protected:
  124. #ifdef _X86_
  125. WORD wSaveFP;
  126. WORD wSavedFP; // WORD-sized to make the data an even DWORD
  127. #endif
  128. };
  129. #define RESPATH_D3D "Software\\Microsoft\\Direct3D"
  130. // this is not available for alpha or IA64
  131. #ifndef LONG_MAX
  132. #define LONG_MAX 2147483647L /* maximum (signed) long value */
  133. #endif
  134. //-----------------------------------------------------------------------------
  135. // Base definitions
  136. //
  137. // Size of Microsoft's internal clip vertex batch
  138. const DWORD VER_IN_BATCH = 8;
  139. typedef WORD D3DFE_CLIPCODE;
  140. struct BATCHBUFFER;
  141. //-----------------------------------------------------------------------------
  142. struct _D3DFE_LIGHTING;
  143. typedef struct _D3DFE_LIGHTING D3DFE_LIGHTING;
  144. struct _D3DI_LIGHT;
  145. typedef struct _D3DI_LIGHT D3DI_LIGHT;
  146. class D3DFE_PROCESSVERTICES;
  147. typedef class D3DFE_PROCESSVERTICES* LPD3DFE_PROCESSVERTICES;
  148. extern "C"
  149. {
  150. typedef void (*LIGHT_VERTEX_FUNC)(LPD3DFE_PROCESSVERTICES pv,
  151. D3DI_LIGHT *light,
  152. D3DVERTEX *pInpCoord,
  153. D3DVALUE* pWeights,
  154. BYTE* pMatrixIndices,
  155. D3DVECTOR *pInpNormal,
  156. D3DLIGHTINGELEMENT *pEyeSpaceData);
  157. typedef void (*PFN_LIGHTLOOP)(LPD3DFE_PROCESSVERTICES pv,
  158. DWORD dwVerCount,
  159. BATCHBUFFER *pBatchBuffer,
  160. D3DI_LIGHT *light,
  161. D3DVERTEX *in,
  162. D3DVALUE* pWeights,
  163. BYTE* pMatrixIndices,
  164. D3DVECTOR *pNormal,
  165. DWORD *pDiffuse,
  166. DWORD *pSpecular);
  167. }
  168. //-----------------------------------------------------------------------------
  169. // This is per texture stage data
  170. //
  171. typedef struct _D3DFE_TEXTURESTAGE
  172. {
  173. // Original value of the texture stage - input index
  174. DWORD dwInpCoordIndex;
  175. // Texture coord offset in the FVF vertex
  176. DWORD dwInpOffset;
  177. // Input index of the texture set is mapped to this output index
  178. DWORD dwOutCoordIndex;
  179. DWORD dwOrgStage; // Original texture stage
  180. DWORD dwOrgWrapMode; // Original WRAP mode
  181. // NULL if texture transform is disabled for the stage
  182. D3DMATRIXI *pmTextureTransform;
  183. // This is index to a table of functions which perform texture transform.
  184. // Index is computed as follow:
  185. // bits 0-1 - (number of input texture coordinates - 1)
  186. // bits 2-3 - (number of output texture coordinates - 1)
  187. DWORD dwTexTransformFuncIndex;
  188. // Mode of texture generation. This is the same value, passed with
  189. // D3DTSS_TEXCOORDINDEX, but with texture index stripped out.
  190. DWORD dwTexGenMode;
  191. // Set to TRUE, when we need to divide texture coordinates by the last
  192. // element of a texture coordinate set
  193. BOOL bDoTextureProjection;
  194. } D3DFE_TEXTURESTAGE, *LPD3DFE_TEXTURESTAGE;
  195. //-----------------------------------------------------------------------------
  196. typedef struct _RECTV
  197. {
  198. union
  199. {
  200. D3DVALUE x1;
  201. D3DVALUE dvX1;
  202. };
  203. union
  204. {
  205. D3DVALUE y1;
  206. D3DVALUE dvY1;
  207. };
  208. union
  209. {
  210. D3DVALUE x2;
  211. D3DVALUE dvX2;
  212. };
  213. union
  214. {
  215. D3DVALUE y2;
  216. D3DVALUE dvY2;
  217. };
  218. } D3DRECTV, *LPD3DRECTV;
  219. //-----------------------------------------------------------------------------
  220. /*
  221. * Lighting defines
  222. */
  223. typedef struct _SpecularTable
  224. {
  225. LIST_MEMBER(_SpecularTable) list;
  226. float power; /* shininess power */
  227. float table[260]; /* space for overflows */
  228. } SpecularTable;
  229. typedef struct {D3DVALUE r,g,b;} D3DFE_COLOR;
  230. //-----------------------------------------------------------------------------
  231. // Internal version of lightdata and constants for "flags" member of D3DI_LIGHT
  232. //
  233. const DWORD D3DLIGHTI_ATT0_IS_NONZERO = 1 << 0;
  234. const DWORD D3DLIGHTI_ATT1_IS_NONZERO = 1 << 1;
  235. const DWORD D3DLIGHTI_ATT2_IS_NONZERO = 1 << 2;
  236. const DWORD D3DLIGHTI_LINEAR_FALLOFF = 1 << 3;
  237. // Set when light data is changed
  238. const DWORD D3DLIGHTI_DIRTY = 1 << 4;
  239. // This flag depends on D3DRS_SPACULARENABLE and light specular color
  240. const DWORD D3DLIGHTI_COMPUTE_SPECULAR = 1 << 5;
  241. // Set when the light is enabled
  242. const DWORD D3DLIGHTI_ENABLED = 1 << 7;
  243. const DWORD D3DLIGHTI_SPECULAR_IS_ZERO = 1 << 8;
  244. const DWORD D3DLIGHTI_AMBIENT_IS_ZERO = 1 << 9;
  245. // Set when we need to send the light to the driver when switching to the
  246. // hardware vertex processing mode.
  247. const DWORD D3DLIGHTI_UPDATEDDI = 1 << 10;
  248. // Set when we need to send "enable" state of the light to the driver when
  249. // switching to the hardware vertex processing mode
  250. const DWORD D3DLIGHTI_UPDATE_ENABLE_DDI = 1 << 11;
  251. const DWORD D3DLIGHTI_OPTIMIZATIONFLAGS = D3DLIGHTI_SPECULAR_IS_ZERO |
  252. D3DLIGHTI_AMBIENT_IS_ZERO |
  253. D3DLIGHTI_ATT0_IS_NONZERO |
  254. D3DLIGHTI_ATT1_IS_NONZERO |
  255. D3DLIGHTI_ATT2_IS_NONZERO |
  256. D3DLIGHTI_LINEAR_FALLOFF;
  257. //-----------------------------------------------------------------------------
  258. // Members of this structure should be aligned as stated
  259. typedef struct _D3DI_LIGHT
  260. {
  261. // Should be QWORD aligned
  262. D3DVECTOR model_position; // In the camera or model space
  263. D3DLIGHTTYPE type;
  264. // Should be QWORD aligned
  265. D3DVECTOR model_direction;// In the camera or model space
  266. D3DVALUE falloff;
  267. // Should be QWORD aligned
  268. DWORD flags;
  269. // Should be QWORD aligned. R,G,B should be adjacent
  270. D3DFE_COLOR diffuseMat; // Material diffuse times light color
  271. // Should be QWORD aligned. R,G,B should be adjacent
  272. D3DFE_COLOR specularMat; // Material specular times light color
  273. // Should be QWORD aligned. R,G,B should be adjacent
  274. D3DFE_COLOR ambientMat; // Material specular times light color
  275. D3DVALUE inv_theta_minus_phi;
  276. // Should be QWORD aligned
  277. D3DVECTOR halfway; // Used by directional, parallel-point and
  278. // spot lights when camera is in infinity
  279. struct _D3DI_LIGHT *next; // Next in the active light list
  280. // Should be QWORD aligned
  281. D3DFE_COLOR diffuse; // Original color scaled to 0 - 255
  282. D3DFE_COLOR specular; // Original color scaled to 0 - 255
  283. D3DFE_COLOR ambient; // Original color scaled to 0 - 255
  284. LIGHT_VERTEX_FUNC lightVertexFunc; // Function to light a D3DVERTEX
  285. D3DVALUE range_squared;
  286. D3DVALUE attenuation0;
  287. D3DVALUE attenuation1;
  288. D3DVALUE attenuation2;
  289. D3DVALUE cos_theta_by_2;
  290. D3DVALUE cos_phi_by_2;
  291. D3DVECTOR position; // In the world space
  292. D3DVECTOR direction; // In the world space
  293. D3DVALUE range;
  294. // Pointer to a PSGP specific "per light" data
  295. LPVOID pPSGPData;
  296. // Microsoft's pipeline specific data
  297. // Used in multi-loop pipeline for first lights
  298. PFN_LIGHTLOOP pfnLightFirst;
  299. // Used in multi-loop pipeline for not first lights
  300. PFN_LIGHTLOOP pfnLightNext;
  301. } D3DI_LIGHT, *LPD3DI_LIGHT;
  302. //-----------------------------------------------------------------------------
  303. // Bits for lighting flags (dwLightingFlags
  304. //
  305. const DWORD __LIGHT_VERTEXTRANSFORMED = 1; // Vertex is in the camera space
  306. const DWORD __LIGHT_NORMALTRANSFORMED = 2; // Normal is in the camera space
  307. const DWORD __LIGHT_SPECULARCOMPUTED = 4;
  308. const DWORD __LIGHT_DIFFUSECOMPUTED = 8;
  309. //-----------------------------------------------------------------------------
  310. // Members of this structure should be aligned as stated
  311. //
  312. typedef struct _D3DFE_LIGHTING
  313. {
  314. // Temporary data used when computing lighting
  315. // Should be QWORD aligned
  316. D3DFE_COLOR diffuse;
  317. DWORD alpha; // Alpha to use for output vertex color
  318. // (could be overriden by vertex difuse
  319. // color) (0-255) shifted left by 24 bits
  320. // Should be QWORD aligned
  321. D3DFE_COLOR diffuse0; // Ca*Cma + Cme
  322. float *currentSpecTable;
  323. // Should be QWORD aligned
  324. D3DFE_COLOR specular;
  325. DWORD outDiffuse; // Result of lighting
  326. // Should be QWORD aligned
  327. D3DVECTOR model_eye; // camera position in model (camera) space
  328. DWORD vertexAmbient; // Provided with a vertex
  329. // Should be QWORD aligned
  330. D3DFE_COLOR ambientSceneScaled; // Scene ambient color (scaled 0-255)
  331. DWORD vertexDiffuse; // Provided with a vertex
  332. // Should be QWORD aligned
  333. D3DFE_COLOR ambientScene; // Scene ambient color (0.0-1.0)
  334. DWORD outSpecular; // Result of lighting
  335. // Should be QWORD aligned
  336. // Direction to camera in the model space. Used in model space lighting
  337. D3DVECTOR directionToCamera;
  338. DWORD vertexSpecular; // Provided with a vertex
  339. // Should be QWORD aligned
  340. D3DMATERIAL8 material;
  341. DWORD dwLightingFlags;
  342. // Alpha to use for output specular vertex color
  343. // (could be overriden by vertex specular color)
  344. // (0-255) shifted left by 24 bits
  345. DWORD alphaSpecular;
  346. // End of temporary data
  347. D3DI_LIGHT *activeLights;
  348. int fog_mode;
  349. D3DVALUE fog_density;
  350. D3DVALUE fog_start;
  351. D3DVALUE fog_end;
  352. D3DVALUE fog_factor; // 255 / (fog_end - fog_start)
  353. D3DVALUE specThreshold; // If a dot product less than this value,
  354. // specular factor is zero
  355. DWORD ambient_save; // Original unscaled color
  356. int materialAlpha; // Current material diffuse alpha (0-255)
  357. // shifted left by 24 bits
  358. int materialAlphaS; // Current material specular alpha (0-255)
  359. // shifted left by 24 bits
  360. DWORD dwDiffuse0; // Packed diffuse0
  361. DWORD dwAmbientSrcIndex; // 0 - diffuse, 1 - specular
  362. DWORD dwDiffuseSrcIndex; // 0 - diffuse, 1 - specular
  363. DWORD dwSpecularSrcIndex; // 0 - diffuse, 1 - specular
  364. DWORD dwEmissiveSrcIndex; // 0 - diffuse, 1 - specular
  365. } D3DFE_LIGHTING;
  366. //-----------------------------------------------------------------------------
  367. // Some data precomputed for a current viewport
  368. // ATTENTION: If you want to add or re-arrange data, contact IOURIT or ANUJG
  369. //
  370. typedef struct _D3DFE_VIEWPORTCACHE
  371. {
  372. // Coefficients to compute screen coordinates from normalized window
  373. // coordinates
  374. D3DVALUE scaleX; // dvWidth
  375. D3DVALUE scaleY; // -dvHeight
  376. D3DVALUE offsetX; // dvX
  377. D3DVALUE offsetY; // dvY + dvHeight
  378. D3DVALUE scaleZ; // dvMaxZ - dvMinZ
  379. D3DVALUE offsetZ; // dvY + dvHeight
  380. // Min and max window values with gaurd band in pixels
  381. D3DVALUE minXgb;
  382. D3DVALUE minYgb;
  383. D3DVALUE maxXgb;
  384. D3DVALUE maxYgb;
  385. // Min and max values for viewport window in pixels
  386. D3DVALUE minX; // offsetX - scaleX
  387. D3DVALUE minY; // offsetY - scaleY
  388. D3DVALUE maxX; // offsetX + scaleX
  389. D3DVALUE maxY; // offsetY + scaleY
  390. // Coefficients to transform a vertex to perform the guard band clipping
  391. // x*gb11 + w*gb41
  392. // y*gb22 + w*gb42
  393. //
  394. D3DVALUE gb11;
  395. D3DVALUE gb22;
  396. D3DVALUE gb41;
  397. D3DVALUE gb42;
  398. // Coefficients to apply clipping rules for the guard band clipping
  399. // They are used by clipping routins
  400. // w*Kgbx1 < x < w*Kgbx2
  401. // w*Kgby1 < y < w*Kgby2
  402. //
  403. D3DVALUE Kgbx1;
  404. D3DVALUE Kgby1;
  405. D3DVALUE Kgbx2;
  406. D3DVALUE Kgby2;
  407. D3DVALUE dvX; // dwX
  408. D3DVALUE dvY; // dwY
  409. D3DVALUE dvWidth; // dwWidth
  410. D3DVALUE dvHeight; // dwHeight
  411. // Coefficients to compute screen coordinates from normalized window
  412. // coordinates
  413. D3DVALUE scaleXi; // Inverse of scaleX
  414. D3DVALUE scaleYi; // Inverse of scaleY
  415. D3DVALUE scaleZi; // Inverse of scaleZ
  416. // Min and max values for viewport window in pixels (integer version)
  417. int minXi; // offsetX - scaleX
  418. int minYi; // offsetY - scaleY
  419. int maxXi; // offsetX + scaleX
  420. int maxYi; // offsetY + scaleY
  421. } D3DFE_VIEWPORTCACHE;
  422. //-----------------------------------------------------------------------------
  423. // Process vertices interface
  424. //
  425. // Bits for process vertices flags
  426. //
  427. // D3DDEV_STRIDE D3DPV_SOA
  428. // 0 1 position.dwStride = number of vertices in SOA
  429. // 0 0 position.dwStride = contiguous vertex size
  430. // 1 0 vertex is not contiguous, all dwStride fields are used
  431. // 1 1 reserved
  432. // 1 1 reserved
  433. //
  434. // Do position tweening. Guaranties that position2 pointer is not NULL
  435. const DWORD D3DPV_POSITION_TWEENING = 1 << 6;
  436. // Do normal tweening. Guaranties that normal2 pointer is not NULL
  437. const DWORD D3DPV_NORMAL_TWEENING= 1 << 7;
  438. const DWORD D3DPV_FOG = 1 << 8; // Need to apply fog
  439. const DWORD D3DPV_DOCOLORVERTEX = 1 << 9; // Need to apply color vertex
  440. const DWORD D3DPV_LIGHTING = 1 << 10; // Need to apply lighting
  441. const DWORD D3DPV_SOA = 1 << 12; // SOA structure is used
  442. // Need to replace emissive material color
  443. const DWORD D3DPV_COLORVERTEX_E = 1 << 13;
  444. // Need to replace diffuse material color
  445. const DWORD D3DPV_COLORVERTEX_D = 1 << 14;
  446. // Need to replace specular material color
  447. const DWORD D3DPV_COLORVERTEX_S = 1 << 15;
  448. // Need to replace ambient material color
  449. const DWORD D3DPV_COLORVERTEX_A = 1 << 16;
  450. // Set by ProcessVertices call with D3DPV_DONOTCOPYDATA flag set
  451. // Specular color should not be copied to the output vertex
  452. const DWORD D3DPV_DONOTCOPYSPECULAR = 1 << 20;
  453. // Set when one pass clipping and vertex processing is used
  454. const DWORD D3DPV_ONEPASSCLIPPING= 1 << 21;
  455. // This indicates that the primitive is non clipped, but we pretend that it is
  456. // clipped to generate DP2HAL inline primitive. Can only be set by tri fan.
  457. const DWORD D3DPV_NONCLIPPED = 1 << 25;
  458. // Propagated from dwFEFlags
  459. const DWORD D3DPV_FRUSTUMPLANES_DIRTY = 1 << 26;
  460. // Set if the geometry loop is called from VertexBuffer::ProcessVertices.
  461. // Processing is different because the output buffer FVF format is defined by
  462. // user, not by SetupFVFData function.
  463. const DWORD D3DPV_VBCALL = 1 << 27;
  464. // Set by ProcessVertices call with D3DPV_DONOTCOPYDATA flag set
  465. // Texture coordinates should not be copied to the output vertex
  466. const DWORD D3DPV_DONOTCOPYTEXTURE = 1 << 28;
  467. // To mark whether we are doing TLVERTEX clipping or not
  468. const DWORD D3DPV_TLVCLIP = 1 << 29;
  469. // Mictosoft internal !!! Set when only transformation is required
  470. // (no lightng or texture copy)
  471. const DWORD D3DPV_TRANSFORMONLY = 1 << 30;
  472. // Set by ProcessVertices call with D3DPV_DONOTCOPYDATA flag set
  473. // Diffuse color should not be copied to the output vertex
  474. const DWORD D3DPV_DONOTCOPYDIFFUSE = 1 << 31;
  475. // These flags persist from call to call till something causes them to change
  476. const DWORD D3DPV_PERSIST = D3DPV_FOG |
  477. D3DPV_LIGHTING |
  478. D3DPV_DONOTCOPYDIFFUSE |
  479. D3DPV_DONOTCOPYSPECULAR |
  480. D3DPV_DONOTCOPYTEXTURE |
  481. D3DPV_POSITION_TWEENING |
  482. D3DPV_NORMAL_TWEENING |
  483. D3DPV_TRANSFORMONLY ;
  484. // Bits for dwDeviceFlags
  485. //
  486. const DWORD D3DDEV_GUARDBAND = 1 << 1; // Use guard band clipping
  487. const DWORD D3DDEV_RANGEBASEDFOG = 1 << 2; // Set if range based fog is enabled
  488. // This bit is set if fog mode is not FOG_NONE and fog is enabled
  489. const DWORD D3DDEV_FOG = 1 << 3;
  490. // Set when there is no need to compute clip codes, because there are already
  491. // computed
  492. const DWORD D3DDEV_DONOTCOMPUTECLIPCODES = 1 << 4;
  493. // Set when stream source or a shader have been changed
  494. // PSGP should clear the bit
  495. const DWORD D3DDEV_SHADERDIRTY = 1 << 5;
  496. // Copy of D3DFVFCAPS_DONOTSTRIPELEMENTS
  497. const DWORD D3DDEV_DONOTSTRIPELEMENTS = 1 << 6;
  498. // Vertex shaders are used. If this bit is not set, fixed function pipeline is
  499. // used
  500. const DWORD D3DDEV_VERTEXSHADERS = 1 << 7;
  501. // Set, when a vertex buffer, which was a destination for ProcessVerticess,
  502. // is used as a stream source
  503. const DWORD D3DDEV_VBPROCVER = 1 << 8;
  504. // Set when we need to do emulation of point sprites (Microsoft specific)
  505. const D3DDEV_DOPOINTSPRITEEMULATION = 1 << 9;
  506. // These are bits in dwDeviceFlags that could be changed, but not
  507. // necessary per every primitive.
  508. //
  509. // Set when D3DRS_SHADEMODE is D3DSHADE_FLAT
  510. const DWORD D3DDEV_FLATSHADEMODE = 1 << 10;
  511. // Set when D3DRS_SPECULARENABLE is TRUE
  512. const DWORD D3DDEV_SPECULARENABLE = 1 << 11;
  513. // Set when transformed vertices are passed to the front-end
  514. const DWORD D3DDEV_TRANSFORMEDFVF = 1 << 12;
  515. // Set when D3DRS_INDEXEDVERTEXBLENDENABLE is true
  516. const DWORD D3DDEV_INDEXEDVERTEXBLENDENABLE = 1 << 13;
  517. // This flag is for PSGP only. PSGP implementation should clear the flag
  518. const DWORD D3DDEV_FRUSTUMPLANES_DIRTY = 1 << 14;
  519. // This flag is for PSGP only. PSGP implementation should clear the flag
  520. // Need to re-evaluate texture transforms
  521. const DWORD D3DDEV_TEXTRANSFORMDIRTY = 1 << 15;
  522. // The flag is set when the number of output texture coord is greater then the
  523. // number of the input ones. This could happen when the same texture transform
  524. // matrix is used with the same input texture coord set. In this case we save
  525. // texture indices from the texture stages in the textureStages and map all
  526. // indices sequentially.
  527. const DWORD D3DDEV_REMAPTEXTUREINDICES = 1 << 16;
  528. // These two flags are for PSGP only. PSGP implementation should clear the flags
  529. // Transform matrix has been changed
  530. const DWORD D3DDEV_TRANSFORMDIRTY = 1 << 17;
  531. // Lights have been changed
  532. const DWORD D3DDEV_LIGHTSDIRTY = 1 << 18;
  533. // Clipping is disabled
  534. const DWORD D3DDEV_DONOTCLIP = 1 << 19;
  535. // World-view matrix does not have scale, so we can do lighting
  536. // in the model space
  537. const DWORD D3DDEV_MODELSPACELIGHTING = 1 << 23;
  538. // Set if viewer is local (used for lighting)
  539. const DWORD D3DDEV_LOCALVIEWER = 1 << 24;
  540. // Set if we wave to normalize normals after transforming them to the
  541. // camera space
  542. const DWORD D3DDEV_NORMALIZENORMALS = 1 << 25;
  543. // Set if we wave to do texture transform
  544. const DWORD D3DDEV_TEXTURETRANSFORM = 1 << 26;
  545. // Set if the last draw primitive call was strided
  546. const DWORD D3DDEV_STRIDE = 1 << 27;
  547. // Set if D3DRS_COLORVERTEX is TRUE
  548. const DWORD D3DDEV_COLORVERTEX = 1 << 28;
  549. // Set if position in camera space is always needed
  550. const DWORD D3DDEV_POSITIONINCAMERASPACE= 1 << 29;
  551. // Set if normal in camera space is always needed
  552. const DWORD D3DDEV_NORMALINCAMERASPACE = 1 << 30;
  553. // Set if D3DRS_LIGHTING is set
  554. const DWORD D3DDEV_LIGHTING = 1 << 31;
  555. //-----------------------------------------------------------------------------
  556. // Clipper defines
  557. //
  558. // Six standard clipping planes plus six user defined clipping planes.
  559. // See rl\d3d\d3d\d3dtypes.h.
  560. //
  561. #define MAX_CLIPPING_PLANES 12
  562. // Space for vertices generated/copied while clipping one triangle
  563. #define MAX_CLIP_VERTICES (( 2 * MAX_CLIPPING_PLANES ) + 3 )
  564. // 3 verts. -> 1 tri, 4 v -> 2 t, N vertices -> (N - 2) triangles
  565. #define MAX_CLIP_TRIANGLES ( MAX_CLIP_VERTICES - 2 )
  566. const DWORD MAX_FVF_TEXCOORD = 8;
  567. class ClipVertex
  568. {
  569. public:
  570. D3DVALUE hx; // Clipping space coordinates. Must be in this order
  571. D3DVALUE hy;
  572. D3DVALUE hz;
  573. D3DVALUE hw;
  574. int clip;
  575. D3DCOLOR color;
  576. D3DCOLOR specular;
  577. D3DVALUE sx; // Screen space coordinates. Must be in this order
  578. D3DVALUE sy;
  579. D3DVALUE sz;
  580. D3DVALUE rhw;
  581. ClipVertex *next;
  582. D3DVALUE tex[MAX_FVF_TEXCOORD*4];
  583. };
  584. typedef struct _ClipTriangle
  585. {
  586. ClipVertex *v[3];
  587. } ClipTriangle;
  588. typedef struct _D3DI_CLIPSTATE
  589. {
  590. ClipVertex *clip_vbuf1[MAX_CLIP_VERTICES];
  591. ClipVertex *clip_vbuf2[MAX_CLIP_VERTICES];
  592. ClipVertex **current_vbuf; // clip_vbuf1 or clip_vbuf2
  593. ClipVertex clip_vertices[MAX_CLIP_VERTICES];
  594. BYTE *clipBuf; // Used for TL vertices, generated by the clipper
  595. int clip_vertices_used;
  596. DWORD clip_color;
  597. DWORD clip_specular;
  598. } D3DI_CLIPSTATE, *LPD3DI_CLIPSTATE;
  599. // These bit are set when a vertex is clipped by a frustum plane
  600. #define CLIPPED_LEFT (D3DCS_PLANE5 << 1)
  601. #define CLIPPED_RIGHT (D3DCS_PLANE5 << 2)
  602. #define CLIPPED_TOP (D3DCS_PLANE5 << 3)
  603. #define CLIPPED_BOTTOM (D3DCS_PLANE5 << 4)
  604. #define CLIPPED_FRONT (D3DCS_PLANE5 << 5)
  605. #define CLIPPED_BACK (D3DCS_PLANE5 << 6)
  606. #define CLIPPED_ENABLE (D3DCS_PLANE5 << 7) /* wireframe enable flag */
  607. // These bit are set when a vertex is clipped by a user clipping plane
  608. const DWORD CLIPPED_PLANE0 = D3DCS_PLANE5 << 8;
  609. const DWORD CLIPPED_PLANE1 = D3DCS_PLANE5 << 9;
  610. const DWORD CLIPPED_PLANE2 = D3DCS_PLANE5 << 10;
  611. const DWORD CLIPPED_PLANE3 = D3DCS_PLANE5 << 11;
  612. const DWORD CLIPPED_PLANE4 = D3DCS_PLANE5 << 12;
  613. const DWORD CLIPPED_PLANE5 = D3DCS_PLANE5 << 13;
  614. // Guard band clipping bits
  615. //
  616. // A guard bit is set when a point is out of guard band
  617. // Guard bits should be cleared before a call to clip a triangle, because
  618. // they are the same as CLIPPED_... bits
  619. //
  620. // Example of clipping bits setting for X coordinate:
  621. //
  622. // if -w < x < w no clipping bit is set
  623. // if -w*ax1 < x <= -w D3DCS_LEFT bit is set
  624. // if x < -w*ax1 __D3DCLIPGB_LEFT bit is set
  625. //
  626. #define __D3DCLIPGB_LEFT (D3DCS_PLANE5 << 1)
  627. #define __D3DCLIPGB_RIGHT (D3DCS_PLANE5 << 2)
  628. #define __D3DCLIPGB_TOP (D3DCS_PLANE5 << 3)
  629. #define __D3DCLIPGB_BOTTOM (D3DCS_PLANE5 << 4)
  630. #define __D3DCLIPGB_ALL (__D3DCLIPGB_LEFT | __D3DCLIPGB_RIGHT | \
  631. __D3DCLIPGB_TOP | __D3DCLIPGB_BOTTOM)
  632. const DWORD __D3DCS_USERPLANES = D3DCS_PLANE0 | D3DCS_PLANE1 |
  633. D3DCS_PLANE2 | D3DCS_PLANE3 |
  634. D3DCS_PLANE4 | D3DCS_PLANE5;
  635. // If only these bits are set, then this point is inside the guard band
  636. //
  637. #define __D3DCS_INGUARDBAND (D3DCS_LEFT | D3DCS_RIGHT | \
  638. D3DCS_TOP | D3DCS_BOTTOM)
  639. //---------------------------------------------------------------------
  640. // Bits in the dwFlags2
  641. //
  642. // The bit is set when the texture transform is enabled
  643. const DWORD __FLAGS2_TEXTRANSFORM0 = 1 << 0;
  644. const DWORD __FLAGS2_TEXTRANSFORM1 = 1 << 1;
  645. const DWORD __FLAGS2_TEXTRANSFORM2 = 1 << 2;
  646. const DWORD __FLAGS2_TEXTRANSFORM3 = 1 << 3;
  647. const DWORD __FLAGS2_TEXTRANSFORM4 = 1 << 4;
  648. const DWORD __FLAGS2_TEXTRANSFORM5 = 1 << 5;
  649. const DWORD __FLAGS2_TEXTRANSFORM6 = 1 << 6;
  650. const DWORD __FLAGS2_TEXTRANSFORM7 = 1 << 7;
  651. const DWORD __FLAGS2_TEXTRANSFORM = __FLAGS2_TEXTRANSFORM0 |
  652. __FLAGS2_TEXTRANSFORM1 |
  653. __FLAGS2_TEXTRANSFORM2 |
  654. __FLAGS2_TEXTRANSFORM3 |
  655. __FLAGS2_TEXTRANSFORM4 |
  656. __FLAGS2_TEXTRANSFORM5 |
  657. __FLAGS2_TEXTRANSFORM6 |
  658. __FLAGS2_TEXTRANSFORM7;
  659. // The bit is set when texture projection is enabled for the stage and we need
  660. // to do emulation, because device does not support projected textures.
  661. const DWORD __FLAGS2_TEXPROJ0 = 1 << 8;
  662. const DWORD __FLAGS2_TEXPROJ1 = 1 << 9;
  663. const DWORD __FLAGS2_TEXPROJ2 = 1 << 10;
  664. const DWORD __FLAGS2_TEXPROJ3 = 1 << 11;
  665. const DWORD __FLAGS2_TEXPROJ4 = 1 << 12;
  666. const DWORD __FLAGS2_TEXPROJ5 = 1 << 13;
  667. const DWORD __FLAGS2_TEXPROJ6 = 1 << 14;
  668. const DWORD __FLAGS2_TEXPROJ7 = 1 << 15;
  669. const DWORD __FLAGS2_TEXPROJ = __FLAGS2_TEXPROJ0 |
  670. __FLAGS2_TEXPROJ1 |
  671. __FLAGS2_TEXPROJ2 |
  672. __FLAGS2_TEXPROJ3 |
  673. __FLAGS2_TEXPROJ4 |
  674. __FLAGS2_TEXPROJ5 |
  675. __FLAGS2_TEXPROJ6 |
  676. __FLAGS2_TEXPROJ7;
  677. // The bit is set when the texture coordinate set is taken from the vertex data
  678. // (position or normal)
  679. const DWORD __FLAGS2_TEXGEN0 = 1 << 16;
  680. const DWORD __FLAGS2_TEXGEN1 = 1 << 17;
  681. const DWORD __FLAGS2_TEXGEN2 = 1 << 18;
  682. const DWORD __FLAGS2_TEXGEN3 = 1 << 19;
  683. const DWORD __FLAGS2_TEXGEN4 = 1 << 20;
  684. const DWORD __FLAGS2_TEXGEN5 = 1 << 21;
  685. const DWORD __FLAGS2_TEXGEN6 = 1 << 22;
  686. const DWORD __FLAGS2_TEXGEN7 = 1 << 23;
  687. const DWORD __FLAGS2_TEXGEN = __FLAGS2_TEXGEN0 |
  688. __FLAGS2_TEXGEN1 |
  689. __FLAGS2_TEXGEN2 |
  690. __FLAGS2_TEXGEN3 |
  691. __FLAGS2_TEXGEN4 |
  692. __FLAGS2_TEXGEN5 |
  693. __FLAGS2_TEXGEN6 |
  694. __FLAGS2_TEXGEN7;
  695. //---------------------------------------------------------------------
  696. #define __TEXTURETRANSFORMENABLED(pv) (pv->dwFlags2 & __FLAGS2_TEXTRANSFORM)
  697. //---------------------------------------------------------------------
  698. //
  699. // CVElement: Describes a vertex element
  700. // Array of this type is passed to PSGP to create a vertex shader
  701. //
  702. //---------------------------------------------------------------------
  703. class CVElement
  704. {
  705. public:
  706. DWORD m_dwRegister; // Input register index
  707. DWORD m_dwDataType; // Data type and dimension
  708. // -------- Private Microsoft Data ---------
  709. // Pointer to a function to convert input vertex element data type to
  710. // the VVM_WORD
  711. LPVOID m_pfnCopy;
  712. // API stream index
  713. DWORD m_dwStreamIndex;
  714. // Offset in the input stream in bytes
  715. DWORD m_dwOffset;
  716. };
  717. //-----------------------------------------------------------------------------
  718. // Data structure used to initialize vertex pointers
  719. //
  720. struct CVertexDesc
  721. {
  722. // Element memory pointer. Used in vertex loop. Start vertex is used
  723. // to compute it
  724. LPVOID pMemory;
  725. // Element stride in bytes
  726. DWORD dwStride;
  727. //------------ Private Microsoft data -------------
  728. union
  729. {
  730. // Input vertex register index
  731. DWORD dwRegister;
  732. // Used to initilize fixed-function pipeline vertex pointers
  733. D3DDP_PTRSTRIDE *pElement;
  734. };
  735. // Copies vertex element data to an input register
  736. LPVOID pfnCopy;
  737. // Stream memory pointer
  738. CVStream* pStream;
  739. // Offset of the element in the vertex in bytes
  740. DWORD dwVertexOffset;
  741. };
  742. //-----------------------------------------------------------------------------
  743. const DWORD __MAXWORLDMATRICES = 256;
  744. const DWORD __WORLDMATRIXBASE = 256;
  745. //-----------------------------------------------------------------------------
  746. // Visible states, input and output data
  747. //
  748. class D3DFE_PROCESSVERTICES
  749. {
  750. public:
  751. D3DFE_PROCESSVERTICES();
  752. ~D3DFE_PROCESSVERTICES();
  753. // Returns current transformation matrix. Computes it if necessary
  754. inline D3DMATRIXI* GetMatrixCTM(UINT index)
  755. {
  756. D3DMATRIXI* m = &mCTM[index];
  757. if (CTMCount[index] < MatrixStateCount)
  758. {
  759. MatrixProduct(m, &world[index], &mVPC);
  760. CTMCount[index] = MatrixStateCount;
  761. }
  762. return m;
  763. }
  764. // Returns current matrix to transform to the camera space.
  765. // Computes it if necessary
  766. inline D3DMATRIXI* GetMatrixWV(UINT index)
  767. {
  768. D3DMATRIXI* m = &mWV[index];
  769. if (WVCount[index] < MatrixStateCount)
  770. {
  771. MatrixProduct(m, &world[index], &view);
  772. WVCount[index] = MatrixStateCount;
  773. }
  774. return m;
  775. }
  776. // Returns current matrix to transform normals to the camera space.
  777. // This is inverse view-world matrix.
  778. // Computes it if necessary
  779. inline D3DMATRIXI* GetMatrixWVI(UINT index)
  780. {
  781. D3DMATRIXI* m = &mWVI[index];
  782. if (WVICount[index] < MatrixStateCount)
  783. {
  784. D3DMATRIXI* world_view = GetMatrixWV(index);
  785. Inverse4x4((D3DMATRIX*)world_view, (D3DMATRIX*)m);
  786. WVICount[index] = MatrixStateCount;
  787. }
  788. return m;
  789. }
  790. // State
  791. // Should be 16 byte aligned
  792. D3DMATRIXI view; // View matrix (Mview)
  793. D3DMATRIXI mVPC; // Mview * Mprojection * Mclip
  794. D3DMATRIXI mTexture[D3DDP_MAXTEXCOORD]; // Texture transform;
  795. D3DMATRIXI world[__MAXWORLDMATRICES]; // User set world matrices
  796. D3DMATRIXI mCTM[__MAXWORLDMATRICES]; // Matrices used for vertex blending
  797. D3DMATRIXI mWV[__MAXWORLDMATRICES];
  798. D3DMATRIXI mWVI[__MAXWORLDMATRICES];
  799. // Every time we need a matrix (CTM2, WV2, WVI2) we compare its count with
  800. // the MatrixStateCount and if it is less than it we compute the required
  801. // matrix.
  802. ULONGLONG CTMCount[__MAXWORLDMATRICES];
  803. ULONGLONG WVCount[__MAXWORLDMATRICES];
  804. ULONGLONG WVICount[__MAXWORLDMATRICES];
  805. // Every time world, view or projection matrix is changed, the
  806. // MatrixStateCount is incremented.
  807. ULONGLONG MatrixStateCount;
  808. // Current set of matrix indices used for the vertex blending.
  809. // If there are no matrix indices in vertices, it is set to (0,1,2,3)
  810. BYTE MatrixIndices[4];
  811. // Weights in a vertex. There could be up to 3 weights in a vertex. The
  812. // last element is assigned as sum(1.0 - weights(i))
  813. float VertexWeights[4];
  814. // Should be QWORD aligned
  815. D3DFE_LIGHTING lighting; // Lighting state
  816. // Should be QWORD aligned
  817. D3DFE_VIEWPORTCACHE vcache; // Data, computed fromto viewport settings
  818. DWORD dwClipUnion; // OR of all vertex clip flags
  819. DWORD dwClipIntersection; // AND of all vertex clip flags
  820. // Current texture stage vector
  821. LPVOID *pD3DMappedTexI;
  822. D3DI_CLIPSTATE ClipperState; // State for triangle/line clipper
  823. // Cache line should start here
  824. D3DPRIMITIVETYPE primType;
  825. DWORD dwNumVertices; // Number of vertices to process
  826. DWORD dwFlags; // Flags word describing what to do
  827. // Location of the first vertex in the vertex buffer (DP2 DDI)
  828. // ATTENTION May be we can get rid of it?
  829. DWORD dwNumIndices; // 0 for non-indexed primitive
  830. LPWORD lpwIndices;
  831. DWORD dwNumPrimitives;
  832. // Cache line should start here
  833. DWORD dwVIDIn; // Vertex ID of input vertices
  834. DWORD dwDeviceFlags; // Flags that are constant per device
  835. // D3DPV_.. and primitive flags are combined
  836. DWORD dwOutputSize; // Output vertex size
  837. DWORD dwVIDOut; // Vertex ID of output vertices
  838. LPVOID lpvOut; // Output pointer (output always packed)
  839. D3DFE_CLIPCODE* lpClipFlags; // Clip flags to output
  840. DWORD nTexCoord; // Number of the input texture coordinate sets
  841. // Number of the output texture coordinate sets to process.
  842. // WARNING. It could be different from the texture count in dwVIDOut
  843. // (it could be zero for example when dwVIDOut has 1 texture coord set).
  844. // If D3DDEV_REMAPTEXTUREINDICES is set this is equal
  845. // to the number of active texture stages
  846. DWORD nOutTexCoord;
  847. // Total size of all output texture coordinates in bytes
  848. DWORD dwTextureCoordSizeTotal;
  849. union
  850. {
  851. struct
  852. {
  853. // Order of the fields is very important.
  854. // It is the same as the order of input registers in the virtual
  855. // vertex machine
  856. union
  857. {
  858. D3DDP_PTRSTRIDE position; // dwStride should always be set !!!
  859. D3DDP_PTRSTRIDE SOA;
  860. };
  861. D3DDP_PTRSTRIDE weights;
  862. D3DDP_PTRSTRIDE matrixIndices; // Blend matrix indices
  863. union
  864. {
  865. D3DDP_PTRSTRIDE normal;
  866. DWORD dwSOAStartVertex;
  867. };
  868. D3DDP_PTRSTRIDE psize;
  869. D3DDP_PTRSTRIDE diffuse;
  870. D3DDP_PTRSTRIDE specular;
  871. D3DDP_PTRSTRIDE textures[D3DDP_MAXTEXCOORD];
  872. D3DDP_PTRSTRIDE position2;
  873. D3DDP_PTRSTRIDE normal2;
  874. };
  875. D3DDP_PTRSTRIDE elements[__NUMELEMENTS];
  876. };
  877. // Used to offset indices during processing an indexed primitive
  878. DWORD dwIndexOffset;
  879. // Size of output texture coordinate sets in bytes
  880. DWORD dwTextureCoordSize[D3DDP_MAXTEXCOORD];
  881. // Size of input texture coordinate sets in bytes
  882. DWORD dwInpTextureCoordSize[D3DDP_MAXTEXCOORD];
  883. // Output
  884. LPDWORD lpdwRStates; // Current render state vector
  885. D3DFE_TEXTURESTAGE textureStage[D3DDP_MAXTEXCOORD]; // Texture state stages
  886. // Used when we have to re-map texture indices
  887. DWORD dwNumTextureStages;
  888. // This array is used when we do not do re-mapping of texture coordinates
  889. D3DMATRIXI *pmTexture[D3DDP_MAXTEXCOORD];
  890. D3DVECTORH userClipPlane[__MAXUSERCLIPPLANES];
  891. // Low 8 bits are texture transform enable:
  892. // bit 0 corresponds to the texture stage 0
  893. // Bits 8-15 are used to detect if we need to do emulation of texture
  894. // projection for the stage (when no stage re-mapping is needed).
  895. // Bits 16-23 are set if corresponding texture coord set
  896. // is taken from the vertex data (position or normal)
  897. DWORD dwFlags2;
  898. // Blend factor used in vertex tweening
  899. float tweenFactor;
  900. // Number of matrices to apply for vertex blending. Number of weights in a
  901. // vertex is (dwNumVerBlends-1). The last weight is 1-sum(VertexWeight[i]).
  902. DWORD dwNumVerBlends;
  903. // Number of weights in a vertex. It is dwNumVerBlends - 1
  904. DWORD dwNumWeights;
  905. DWORD dwMaxUserClipPlanes;
  906. // Internal data for Microsoft implementation
  907. // Offsets in the input FVF vertex. Recomputed when FVF is changed.
  908. DWORD texOffset;
  909. DWORD normalOffset;
  910. DWORD diffuseOffset;
  911. DWORD specularOffset;
  912. DWORD pointSizeOffset;
  913. // Offsets in the output FVF vertex. Recomputed when FVF is changed.
  914. DWORD texOffsetOut;
  915. DWORD diffuseOffsetOut;
  916. DWORD specularOffsetOut;
  917. DWORD pointSizeOffsetOut;
  918. DWORD fogOffsetOut;
  919. // When and this mask with the clip code we have bits that are outside the
  920. // guard band
  921. DWORD dwClipMaskOffScreen;
  922. // Clip vertices. Used in processing and clipping in the one loop
  923. ClipVertex clipVer[VER_IN_BATCH];
  924. // Index of the first vertex with non-zero clip code
  925. DWORD dwFirstClippedVertex;
  926. DWORD dwMaxTextureIndices; // Max number of texture coord sets
  927. DWORD dwIndexSize; // Index size (2 or 4 bytes)
  928. CD3DDDI* pDDI; // Copy from the device m_pDDI
  929. float PointSizeMax; // Current max point size
  930. ID3DFE_PVFUNCS* pGeometryFuncs; // Copy from the CD3DHal device
  931. //-------------- Vertex Shader data -----------------
  932. // Store information to initialize virtual machine registers
  933. // The elements of this array match the elements of pElements array, passed
  934. // with CreateShader call.
  935. CVertexDesc VertexDesc[__NUMSTREAMS];
  936. // How many VertexDescs are used
  937. // It is equal to the number of vertex elements (dwNumElements), in the
  938. // current active shader. dwNumElements is passed during CreateShader calls
  939. DWORD dwNumUsedVertexDescs;
  940. #if DBG
  941. RTDebugMonitor* pDbgMon; // Copy from the device m_pDbgMon
  942. #endif
  943. };
  944. //-----------------------------------------------------------------------------
  945. // Prototype for the function to be written for a given processor implementation
  946. //
  947. class ID3DFE_PVFUNCS
  948. {
  949. public:
  950. virtual ~ID3DFE_PVFUNCS() {};
  951. virtual DWORD ProcessVertices(LPD3DFE_PROCESSVERTICES)=0;
  952. virtual HRESULT ProcessPrimitive(LPD3DFE_PROCESSVERTICES)=0;
  953. virtual HRESULT ProcessIndexedPrimitive(LPD3DFE_PROCESSVERTICES)=0;
  954. virtual HRESULT OptimizeVertexBuffer
  955. (DWORD dwFVFID, // Vertex type. XYZ position is allowed
  956. DWORD dwNumVertices, // Number of vertices
  957. DWORD dwVertexSize, // Vertex size in bytes
  958. LPVOID lpSrcBuffer, // Source buffer.
  959. LPVOID lpDstBuffer, // Output buffer.
  960. DWORD dwFlags) // Should be zero for now
  961. {return E_NOTIMPL;}
  962. // Returns number of bytes to allocate for an optimized vertex buffer
  963. // This function is called before OptimizeVertexBuffer
  964. virtual DWORD ComputeOptimizedVertexBufferSize
  965. (DWORD dwFVF, // Vertex type
  966. DWORD dwVertexSize, // Vertex size in bytes
  967. DWORD dwNumVertices) // Number of vertices
  968. {return 0;}
  969. // This function could be used if PSGP doesn't want to implement complete
  970. // clipping pipeline
  971. // Parameters:
  972. // pv - state data
  973. // tri - triangle to clip
  974. // clipVertexPointer - pointer to an array of pointers to
  975. // generated vertices
  976. // Returns:
  977. // Number of vertices in clipped triangle
  978. // 0, if the triangle is off screen
  979. virtual int ClipSingleTriangle(D3DFE_PROCESSVERTICES *pv,
  980. ClipTriangle *tri,
  981. ClipVertex ***clipVertexPointer) = 0;
  982. virtual HRESULT ProcessTriangleList(LPD3DFE_PROCESSVERTICES)=0;
  983. virtual HRESULT ProcessTriangleFan(LPD3DFE_PROCESSVERTICES)=0;
  984. virtual HRESULT ProcessTriangleStrip(LPD3DFE_PROCESSVERTICES)=0;
  985. // Create a vertex shader
  986. //
  987. // D3D run-time:
  988. // - parses shader declaration and shader code and does all validation
  989. // - computes output FVF for non-fixed pipeline
  990. // - creates a shader handle
  991. // - calls ID3DFE_PVFUNCS::CreateShader()
  992. // PSGP:
  993. // - compiles shader code using the vertex element descriptions
  994. //
  995. // For fixed function pipeline pdwShaderCode is NULL, dwOutputFVF should be
  996. // ignored (dwVIDOut should be used in Draw calls).
  997. //
  998. virtual HRESULT CreateShader(
  999. // Describes input vertex elements and mapping them to vertex registers
  1000. CVElement* pElements,
  1001. // Number of elements
  1002. DWORD dwNumElements,
  1003. // Binary shader code (NULL for fixed function pipeline)
  1004. DWORD* pdwShaderCode,
  1005. // Describes output vertex format. Ignored by fixed function pipeline
  1006. DWORD dwOutputFVF,
  1007. // PSGP-created shader object. D3D does not have access to it.
  1008. CPSGPShader** ppPSGPShader
  1009. ) = 0;
  1010. virtual HRESULT SetActiveShader(CPSGPShader *pPSGPShader) = 0;
  1011. // Load vertex shader constants
  1012. virtual HRESULT LoadShaderConstants(
  1013. DWORD start, // Constant register address
  1014. DWORD count, // Number of 4-float vectors to load
  1015. LPVOID buffer) = 0; // Memory to load from
  1016. // This function is called when output vertex format is changed, but the
  1017. // active shader remains the same. It is guaranteed that the new FVF is
  1018. // a superset of the FVF, passed to CreateShader. PSGP implementation
  1019. // could re-compute output vertex offsets or it could use updated
  1020. // output offsets and dwOutputSize from PROCESSVERTICES structure.
  1021. virtual HRESULT SetOutputFVF(DWORD dwFVF) = 0;
  1022. virtual HRESULT GetShaderConstants(
  1023. DWORD start, // Constant register address
  1024. DWORD count, // Number of 4-float vectors to load
  1025. LPVOID buffer) = 0;
  1026. };
  1027. typedef ID3DFE_PVFUNCS *LPD3DFE_PVFUNCS;
  1028. //-----------------------------------------------------------------------------
  1029. // GeometrySetup function takes a DWORD describing the dirty bits and the new
  1030. // state vector and passes back the 3 new leaf routines to use.
  1031. //
  1032. typedef HRESULT (D3DAPI *LPD3DFE_CONTEXTCREATE)(
  1033. // dwDeviceFlags are passed
  1034. DWORD dwFlags,
  1035. // A pointer to the Microsoft object is passed to call when there is no
  1036. // PSGP implementation available. PSGP returns its object hear.
  1037. LPD3DFE_PVFUNCS *ppMicrosoftFuncs
  1038. );
  1039. //-----------------------------------------------------------------------------
  1040. // Global pointer to Processor specific PV setup routine
  1041. // This is defined in dlld3d.cpp
  1042. extern LPD3DFE_CONTEXTCREATE pfnFEContextCreate;
  1043. //-----------------------------------------------------------------------------
  1044. // Check if we need to do emulation of texture projection for the stage
  1045. //
  1046. inline BOOL NeedTextureProjection(D3DFE_PROCESSVERTICES* pv, UINT stage)
  1047. {
  1048. return pv->dwFlags2 & (__FLAGS2_TEXPROJ0 << stage);
  1049. }
  1050. #endif // _D3DFE_H