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.

1534 lines
58 KiB

  1. /*==========================================================================;
  2. *
  3. * Copyright (C) 1995-1997 Microsoft Corporation. All Rights Reserved.
  4. *
  5. * File: d3di.hpp
  6. * Content: Direct3D internal include file
  7. *
  8. * $Id:
  9. *
  10. * History:
  11. * Date By Reason
  12. * ==== == ======
  13. * 05/11/95 stevela Initial rev with this header.
  14. *
  15. ***************************************************************************/
  16. #ifndef _D3DI_HPP
  17. #define _D3DI_HPP
  18. #include "ddrawp.h"
  19. #include "d3dp.h"
  20. #include "d3dmem.h"
  21. #if !defined(BUILD_DDDDK)
  22. extern "C" {
  23. #include "ddrawi.h"
  24. };
  25. #include "object.h"
  26. #include "lists.hpp"
  27. #include <d3ditype.h>
  28. #include <d3dutil.h>
  29. #include <d3dfe.hpp>
  30. // Allow vtable hacking
  31. #define VTABLE_HACK
  32. // DEBUG_PIPELINE is defined to check performance and to allow to choose
  33. // diifferent paths in the geometry pipeline
  34. #if DBG
  35. #define DEBUG_PIPELINE
  36. #endif // DBG
  37. #ifndef WIN95
  38. // This is NT only
  39. // Comment this out to disable registry based VidMemVB enables
  40. #define __DISABLE_VIDMEM_VBS__
  41. #endif
  42. //--------------------------------------------------------------------
  43. const DWORD __INIT_VERTEX_NUMBER = 1024;// Initial number of vertices in TL and
  44. // clip flag buffers
  45. const DWORD __MAX_VERTEX_SIZE = 180; // Max size of FVF vertex in bytes
  46. //--------------------------------------------------------------------
  47. /*
  48. * Registry defines
  49. */
  50. #define RESPATH "Software\\Microsoft\\Direct3D\\Drivers"
  51. #define RESPATH_D3D "Software\\Microsoft\\Direct3D"
  52. #define STATS_FONT_FACE "Terminal"
  53. #define STATS_FONT_SIZE 9
  54. #if COLLECTSTATS
  55. DWORD BytesDownloaded(LPDDRAWI_DDRAWSURFACE_LCL lpLcl, LPRECT lpRect);
  56. #endif
  57. extern HINSTANCE hGeometryDLL;
  58. /*
  59. * CPU family and features flags
  60. */
  61. extern DWORD dwCPUFamily, dwCPUFeatures;
  62. extern char szCPUString[];
  63. // MMX available
  64. #define D3DCPU_MMX 0x00000001L
  65. // FCOMI and CMOV are both supported
  66. #define D3DCPU_FCOMICMOV 0x00000002L
  67. // Reads block until satisfied
  68. #define D3DCPU_BLOCKINGREAD 0x00000004L
  69. // Extended 3D support available
  70. #define D3DCPU_X3D 0x00000008L
  71. // Pentium II CPU
  72. #define D3DCPU_PII 0x000000010L
  73. // Streaming SIMD Extensions (aka Katmai) CPU
  74. #define D3DCPU_SSE 0x000000020L
  75. // Intel Willamette CPU
  76. #define D3DCPU_WLMT 0x000000040L
  77. #define DEFAULT_GAMMA DTOVAL(1.4)
  78. /*
  79. INDEX_BATCH_SCALE is the constant which is used by DrawIndexedPrim
  80. to deterimine if the number of primitives being drawn is small
  81. relative to the number of vertices being passed. If it is then
  82. the prims are dereferenced in batches and sent to DrawPrim.
  83. */
  84. #define INDEX_BATCH_SCALE 2
  85. #endif // BUILD_DDDDK
  86. #if !defined(BUILD_DDDDK)
  87. class DIRECT3DDEVICEI;
  88. class CStateSets;
  89. typedef class DIRECT3DI *LPDIRECT3DI;
  90. typedef class DIRECT3DDEVICEI *LPDIRECT3DDEVICEI;
  91. typedef class DIRECT3DLIGHTI *LPDIRECT3DLIGHTI;
  92. typedef class DIRECT3DTEXTUREI *LPDIRECT3DTEXTUREI;
  93. typedef class CDirect3DVertexBuffer *LPDIRECT3DVERTEXBUFFERI;
  94. class CDirect3DUnk : public IUnknown
  95. {
  96. public:
  97. unsigned refCnt; /* Reference count object */
  98. public:
  99. LPDIRECT3DI pD3DI;
  100. public:
  101. // IUnknown Methods
  102. HRESULT D3DAPI QueryInterface(REFIID riid, LPVOID* ppvObj);
  103. ULONG D3DAPI AddRef();
  104. ULONG D3DAPI Release();
  105. };
  106. class DIRECT3DI : public IDirect3D7,
  107. public CD3DAlloc
  108. {
  109. public: //Private Data
  110. /*** Object Relations ***/
  111. /* Devices */
  112. int numDevs;/* Number of devices */
  113. struct _devices { DIRECT3DDEVICEI* Root;} devices;
  114. /* Associated IDirect3DDevices */
  115. /* Vertex Buffers */
  116. int numVBufs; /* Number of vertex buffers */
  117. LIST_ROOT(_vbufs, CDirect3DVertexBuffer) vbufs;
  118. /* Created IDirect3DVertexBuffers */
  119. /* Textures */
  120. LIST_ROOT(_textures, DIRECT3DTEXTUREI) textures;
  121. /*** Object Data ***/
  122. CDirect3DUnk mD3DUnk;
  123. //RLDDIRegistry* lpReg; /* Registry */
  124. struct _D3DBUCKET *lpFreeList; /* Free linked list */
  125. struct _D3DBUCKET *lpBufferList;/* link list of headers of big chunks allocated*/
  126. class TextureCacheManager *lpTextureManager;
  127. /*
  128. * DirectDraw Interface
  129. */
  130. LPDIRECTDRAW lpDD;
  131. LPDIRECTDRAW7 lpDD7; /* needed for CreateSurface to get LPDIRECTDRAWSURFACE7 */
  132. // HACK. D3D needs a DD1 DDRAWI interface because it uses CreateSurface1 internally
  133. // for exebufs, among other things. But the D3DI object cannot keep a reference
  134. // to its parent DD object because it is aggegrated with the DD obj, so that would constitute
  135. // a circular reference that would prevent deletion. So QI for DD1 interface, copy it into D3DI
  136. // and release it, then point lpDD at the copy. (disgusting)
  137. // More disgusting still: These need to be large enough to hold ddrawex interface structs
  138. DDRAWI_DIRECTDRAW_INT DDInt_DD1;
  139. /*
  140. * The special IUnknown interface for the aggregate that does
  141. * not punt to the parent object.
  142. */
  143. LPUNKNOWN lpOwningIUnknown; /* The owning IUnknown */
  144. #if COLLECTSTATS
  145. // For displaying stats
  146. HFONT m_hFont;
  147. // Various counters for stats
  148. DWORD m_setpris, m_setLODs, m_texCreates, m_texDestroys;
  149. #endif
  150. #ifdef __DISABLE_VIDMEM_VBS__
  151. BOOL bDisableVidMemVBs;
  152. #endif //__DISABLE_VIDMEM_VBS__
  153. public: //Private methods
  154. DIRECT3DI(); // Constructor called Direct3DCreate()
  155. ~DIRECT3DI(); // Destructor called by CDirect3DUnk::Release()
  156. HRESULT Initialize(IUnknown* pUnkOuter, LPDDRAWI_DIRECTDRAW_INT pDDrawInt);
  157. HRESULT EnumDevices(LPD3DENUMDEVICESCALLBACK7, LPVOID, DWORD, DWORD);
  158. // Internal CreateVertexBuffer
  159. HRESULT CreateVertexBufferI(LPD3DVERTEXBUFFERDESC, LPDIRECT3DVERTEXBUFFER7*, DWORD);
  160. // Device flushing
  161. HRESULT FlushDevicesExcept(LPDIRECT3DDEVICEI pDev);
  162. public:
  163. // IUnknown Methods
  164. HRESULT D3DAPI QueryInterface(REFIID riid, LPVOID* ppvObj);
  165. ULONG D3DAPI AddRef();
  166. ULONG D3DAPI Release();
  167. HRESULT D3DAPI EnumDevices(LPD3DENUMDEVICESCALLBACK7, LPVOID);
  168. HRESULT D3DAPI CreateDevice(REFCLSID, LPDIRECTDRAWSURFACE7, LPDIRECT3DDEVICE7*);
  169. HRESULT D3DAPI CreateVertexBuffer(LPD3DVERTEXBUFFERDESC, LPDIRECT3DVERTEXBUFFER7*, DWORD);
  170. HRESULT D3DAPI EnumZBufferFormats(REFCLSID, LPD3DENUMPIXELFORMATSCALLBACK, LPVOID);
  171. HRESULT D3DAPI EvictManagedTextures();
  172. #if COLLECTSTATS
  173. // Stats collection funcs
  174. void ResetTexStats();
  175. void GetTexStats(LPD3DDEVINFO_TEXTURING);
  176. void IncNumSetPris()
  177. {
  178. ++m_setpris;
  179. }
  180. void IncNumSetLODs()
  181. {
  182. ++m_setLODs;
  183. }
  184. void IncNumTexCreates()
  185. {
  186. ++m_texCreates;
  187. }
  188. void IncNumTexDestroys()
  189. {
  190. ++m_texDestroys;
  191. }
  192. DWORD GetNumSetPris()
  193. {
  194. return m_setpris;
  195. }
  196. DWORD GetNumSetLODs()
  197. {
  198. return m_setLODs;
  199. }
  200. DWORD GetNumTexCreates()
  201. {
  202. return m_texCreates;
  203. }
  204. DWORD GetNumTexDestroys()
  205. {
  206. return m_texDestroys;
  207. }
  208. DWORD GetNumTexLocks()
  209. {
  210. return ((LPDDRAWI_DIRECTDRAW_INT)lpDD7)->lpLcl->dwNumTexLocks;
  211. }
  212. DWORD GetNumTexGetDCs()
  213. {
  214. return ((LPDDRAWI_DIRECTDRAW_INT)lpDD7)->lpLcl->dwNumTexGetDCs;
  215. }
  216. #endif
  217. };
  218. typedef DIRECT3DI* LPDIRECT3DI;
  219. #include "d3dhal.h"
  220. #include "halprov.h"
  221. //---------------------------------------------------------------------
  222. typedef HRESULT (*PFNDRVSETRENDERTARGET)(LPDIRECTDRAWSURFACE7, LPDIRECTDRAWSURFACE7,
  223. LPDIRECTDRAWPALETTE, LPDIRECT3DDEVICEI);
  224. typedef struct _D3DBUCKET
  225. {
  226. struct _D3DBUCKET *next;
  227. union
  228. {
  229. LPVOID lpD3DDevI;
  230. LPDDRAWI_DDRAWSURFACE_LCL lpLcl;
  231. LPVOID lpBuffer;
  232. LPDIRECT3DTEXTUREI lpD3DTexI;
  233. };
  234. union
  235. {
  236. HRESULT (__cdecl *pfnFlushStates)(LPVOID);
  237. unsigned int ticks;
  238. };
  239. LPDIRECTDRAWSURFACE *lplpDDSZBuffer; //if not NULL, points to lpDDSZBuffer in Direct3DDeviceI
  240. } D3DBUCKET,*LPD3DBUCKET;
  241. typedef struct _D3DI_TEXTUREBLOCK
  242. {
  243. LIST_MEMBER(_D3DI_TEXTUREBLOCK) list;
  244. /* Next block in IDirect3DTexture */
  245. LIST_MEMBER(_D3DI_TEXTUREBLOCK) devList;
  246. /* Next block in IDirect3DDevice */
  247. LPDIRECT3DDEVICEI lpDevI;
  248. /* this texture block refers to either an
  249. * IDirect3DTexture/IDirect3DTexture2, so one of these pointers will
  250. * always be NULL
  251. */
  252. LPDIRECT3DTEXTUREI lpD3DTextureI;
  253. /* pointer to internal struct for IDirect3DTexture/IDirect3DTexture2 */
  254. D3DTEXTUREHANDLE hTex;
  255. /* texture handle */
  256. } D3DI_TEXTUREBLOCK;
  257. typedef struct _D3DI_TEXTUREBLOCK *LPD3DI_TEXTUREBLOCK;
  258. // Function to compute lighting
  259. //
  260. typedef struct _LIGHT_VERTEX_FUNC_TABLE
  261. {
  262. LIGHT_VERTEX_FUNC pfnDirectional;
  263. LIGHT_VERTEX_FUNC pfnPointSpot;
  264. // Used in multi-loop pipeline
  265. PFN_LIGHTLOOP pfnDirectionalFirst;
  266. PFN_LIGHTLOOP pfnDirectionalNext;
  267. PFN_LIGHTLOOP pfnPointSpotFirst;
  268. PFN_LIGHTLOOP pfnPointSpotNext;
  269. } LIGHT_VERTEX_FUNC_TABLE;
  270. //---------------------------------------------------------------------
  271. class DIRECT3DLIGHTI : public CD3DAlloc
  272. {
  273. public:
  274. DIRECT3DLIGHTI() {m_LightI.flags = 0;} // VALID bit is not set
  275. HRESULT SetInternalData();
  276. BOOL Enabled() {return (m_LightI.flags & D3DLIGHTI_ENABLED);}
  277. BOOL Valid() {return (m_LightI.flags & D3DLIGHTI_VALID);}
  278. LIST_MEMBER(DIRECT3DLIGHTI) m_List; // Active light list member
  279. D3DLIGHT7 m_Light;
  280. D3DI_LIGHT m_LightI;
  281. };
  282. //---------------------------------------------------------------------
  283. //
  284. // Bits for D3DFRONTEND flags (dwFEFlags in DIRECT3DDEVICEI)
  285. //
  286. const DWORD D3DFE_WORLDMATRIX_DIRTY = 1 << 0; // World matrix dirty bits
  287. const DWORD D3DFE_WORLDMATRIX1_DIRTY = 1 << 1; // must be sequential !!!
  288. const DWORD D3DFE_WORLDMATRIX2_DIRTY = 1 << 2;
  289. const DWORD D3DFE_WORLDMATRIX3_DIRTY = 1 << 3;
  290. const DWORD D3DFE_TLVERTEX = 1 << 5;
  291. const DWORD D3DFE_REALHAL = 1 << 6;
  292. const DWORD D3DFE_PROJMATRIX_DIRTY = 1 << 8;
  293. const DWORD D3DFE_VIEWMATRIX_DIRTY = 1 << 9;
  294. // Set when we need to check world-view matrix for orthogonality
  295. const DWORD D3DFE_NEEDCHECKWORLDVIEWVMATRIX = 1 << 10;
  296. // Set when some state has been changed and we have to go through the slow path
  297. // Currently the bit is set when one of the following bits is set:
  298. // D3DFE_PROJMATRIX_DIRTY
  299. // D3DFE_VIEWMATRIX_DIRTY
  300. // D3DFE_WORLDMATRIX_DIRTY
  301. // D3DFE_WORLDMATRIX1_DIRTY
  302. // D3DFE_WORLDMATRIX2_DIRTY
  303. // D3DFE_WORLDMATRIX3_DIRTY
  304. // D3DFE_VERTEXBLEND_DIRTY
  305. // D3DFE_LIGHTS_DIRTY
  306. // D3DFE_MATERIAL_DIRTY
  307. // D3DFE_FVF_DIRTY
  308. // D3DFE_CLIPPLANES_DIRTY
  309. const DWORD D3DFE_FRONTEND_DIRTY = 1 << 11;
  310. // We are in recording state set mode
  311. const DWORD D3DFE_RECORDSTATEMODE = 1 << 12;
  312. // We are in execution state set mode
  313. // In this mode the front-and executes recorded states but does not pass
  314. // them to the driver (the states will be passed using a set state handle)
  315. const DWORD D3DFE_EXECUTESTATEMODE = 1 << 13;
  316. const DWORD D3DFE_NEED_TRANSFORM_LIGHTS = 1 << 14;
  317. const DWORD D3DFE_MATERIAL_DIRTY = 1 << 15;
  318. const DWORD D3DFE_CLIPPLANES_DIRTY = 1 << 16;
  319. const DWORD D3DFE_LIGHTS_DIRTY = 1 << 18;
  320. // This bit is set when vertex blending state is dirty
  321. const DWORD D3DFE_VERTEXBLEND_DIRTY = 1 << 19;
  322. // Set if the Current Transformation Matrix has been changed
  323. // Reset when frustum planes in the model space have been computed
  324. const DWORD D3DFE_FRUSTUMPLANES_DIRTY = 1 << 20;
  325. const DWORD D3DFE_WORLDVIEWMATRIX_DIRTY = 1 << 21;
  326. const DWORD D3DFE_FVF_DIRTY = 1 << 22;
  327. // This bit set if UpdateManagedTextures() needs to be called
  328. const DWORD D3DFE_NEED_TEXTURE_UPDATE = 1 << 23;
  329. // This bit set if mapping DX6 texture blend modes to renderstates is desired
  330. const DWORD D3DFE_MAP_TSS_TO_RS = 1 << 24;
  331. const DWORD D3DFE_INVWORLDVIEWMATRIX_DIRTY = 1 << 25;
  332. //
  333. const DWORD D3DFE_LOSTSURFACES = 1 << 27;
  334. // This bit set if texturing is disabled
  335. const DWORD D3DFE_DISABLE_TEXTURES = 1 << 28;
  336. // Clip matrix is used to transform user clipping planes
  337. // to the clipping space
  338. const DWORD D3DFE_CLIPMATRIX_DIRTY = 1 << 29;
  339. // HAL supports Transformation and Lighting
  340. const DWORD D3DFE_TLHAL = 1 << 30;
  341. // HAL supports state sets
  342. const DWORD D3DFE_STATESETS = 1 << 31;
  343. const DWORD D3DFE_TRANSFORM_DIRTY = D3DFE_PROJMATRIX_DIRTY |
  344. D3DFE_VIEWMATRIX_DIRTY |
  345. D3DFE_WORLDMATRIX_DIRTY |
  346. D3DFE_WORLDMATRIX1_DIRTY |
  347. D3DFE_WORLDMATRIX2_DIRTY |
  348. D3DFE_WORLDMATRIX3_DIRTY |
  349. D3DFE_VERTEXBLEND_DIRTY;
  350. const DWORD D3DDEVBOOL_HINTFLAGS_INSCENE = 1 << 0; // Are we in a scene?
  351. const DWORD D3DDEVBOOL_HINTFLAGS_MULTITHREADED = 1 << 1; // multithreaded device
  352. const DWORD D3DDEVBOOL_HINTFLAGS_FPUSETUP = 1 << 3; // Means the FPU is already in preferred state.
  353. //---------------------------------------------------------------------
  354. //
  355. // Bits for dwDebugFlags
  356. //
  357. // Set if DisableFVF key is not 0 in registry and driver supports FVF
  358. const DWORD D3DDEBUG_DISABLEFVF = 1 << 0;
  359. #ifdef WIN95
  360. // Disable Draw Primitive DDI
  361. const DWORD D3DDEBUG_DISABLEDP = 1 << 1;
  362. // Disable Draw Primitive 2 DDI
  363. const DWORD D3DDEBUG_DISABLEDP2 = 1 << 2;
  364. #endif // WIN95
  365. #ifdef WIN95
  366. #define _D3D_FORCEDOUBLE 1
  367. #else //WIN95
  368. #define _D3D_FORCEDOUBLE 0
  369. #endif //WIN95
  370. #if _D3D_FORCEDOUBLE
  371. // Set if ForceDouble key is not 0 in the registry and driver is pre-DX6 REALHAL
  372. const DWORD D3DDEBUG_FORCEDOUBLE= 1 << 2;
  373. #endif //_D3D_FORCEDOUBLE
  374. //---------------------------------------------------------------------
  375. // Bits for transform.dwFlags
  376. //
  377. // Frastum plane equations are valid
  378. const DWORD D3DTRANS_VALIDFRUSTUM = 1 << 2;
  379. //---------------------------------------------------------------------
  380. typedef struct _D3DFE_TRANSFORM
  381. {
  382. D3DMATRIXI proj;
  383. D3DMATRIXI view;
  384. D3DMATRIXI world[4]; // Up to 4 world matrix
  385. D3DMATRIXI mPC; // Mproj * Mclip
  386. D3DMATRIXI mVPC; // Mview * PC
  387. D3DMATRIXI mVPCI; // Inverse Mview * PC, used to transform clipping planes
  388. D3DMATRIXI mCTMI; // Inverse current transformation matrix
  389. D3DVECTORH frustum[6]; // Normalized plane equations for viewing frustum
  390. // in the model space
  391. D3DVECTORH userClipPlane[D3DMAXUSERCLIPPLANES];
  392. DWORD dwMaxUserClipPlanes; // Number provided by the driver
  393. DWORD dwFlags;
  394. } D3DFE_TRANSFORM;
  395. typedef void (*D3DFEDestroyProc)(LPDIRECT3DDEVICEI lpD3DDevI);
  396. extern DWORD dwD3DTriBatchSize, dwTriBatchSize, dwLineBatchSize;
  397. extern DWORD dwHWBufferSize, dwHWMaxTris;
  398. extern DWORD dwHWFewVertices;
  399. typedef enum {
  400. D3DDEVTYPE_OLDHAL = 1,
  401. D3DDEVTYPE_DPHAL,
  402. D3DDEVTYPE_DP2HAL, // DX6 HAL
  403. D3DDEVTYPE_DX7HAL, // DX7 HAL w/out T&L, with state sets
  404. D3DDEVTYPE_DX7TLHAL
  405. } D3DDEVICETYPE;
  406. //---------------------------------------------------------------------
  407. typedef HRESULT (DIRECT3DDEVICEI::*PFN_DRAWPRIM)();
  408. //---------------------------------------------------------------------
  409. // This type is used to define operation for ProcessPrimitive
  410. //
  411. typedef enum
  412. {
  413. __PROCPRIMOP_INDEXEDPRIM, // Process indexed primitive
  414. __PROCPRIMOP_NONINDEXEDPRIM, // Process non-indexed primitive
  415. } __PROCPRIMOP;
  416. //---------------------------------------------------------------------
  417. #ifdef _IA64_ // Removes IA64 compiler alignment warnings
  418. #pragma pack(16)
  419. #endif
  420. #ifdef _AXP64_ // Removes AXP64 compiler alignment warnings
  421. #pragma pack(16)
  422. #endif
  423. // We modify the compiler generated VTable for DIRECT3DDEVICEI object. To make
  424. // life easy, all virtual functions are defined in DIRECT3DDEVICEI. Also since
  425. // DEVICEI has multiple inheritance, there are more than 1 VTable.
  426. // Currently we assume that it only inherits from IDirect3DDevice7 and
  427. // D3DFE_PROCESSVERTICES and, in that order! Thus IDirect3DDevice7 and
  428. // DIRECT3DDEVICEI share the same vtable. This is the VTable we copy and
  429. // modify. The define below is the total entries in this vtable. It is the
  430. // sum of the methods in IDirect3DDevice7 (incl. IUnknown) (49) and all the
  431. // virtual methods in DIRECT3DDEVICEI ()
  432. #define D3D_NUM_API_FUNCTIONS (49)
  433. #define D3D_NUM_VIRTUAL_FUNCTIONS (D3D_NUM_API_FUNCTIONS+38)
  434. // These constants are based on the assumption that rsVec array is an array
  435. // of 32-bit intergers
  436. const D3D_RSVEC_SHIFT = 5; // log2(sizeof(DWORD)*8);
  437. const D3D_RSVEC_MASK = sizeof(DWORD) * 8 - 1;
  438. class DIRECT3DDEVICEI : public IDirect3DDevice7,
  439. public CD3DAlloc,
  440. public D3DFE_PROCESSVERTICES
  441. {
  442. public: // Private Data
  443. ULONGLONG m_qwBatch; // current batch number
  444. DWORD dwHintFlags;
  445. // Pointer to the PV funcs that we need to call
  446. LPD3DFE_PVFUNCS pGeometryFuncs;
  447. // buffer for H vertices
  448. CAlignedBuffer32 HVbuf; // Used for clip flags
  449. // Should be cache line aligned. Now it is not
  450. D3DDEVICETYPE deviceType; // Device Type
  451. /*** Object Relations ***/
  452. LPDIRECT3DI lpDirect3DI; // parent
  453. LIST_MEMBER(DIRECT3DDEVICEI)list; // Next device IDirect3D
  454. /* Textures */
  455. LIST_ROOT(_dmtextures, _D3DI_TEXTUREBLOCK) texBlocks;
  456. /* Ref to created IDirect3DTextures */
  457. /* Viewports */
  458. D3DVIEWPORT7 m_Viewport;
  459. DWORD clrCount; // Number of rects allocated
  460. LPD3DRECT clrRects; // Rects used for clearing
  461. /* Reference count object */
  462. unsigned refCnt;
  463. // for DX3-style devices aggregated onto ddraw, guid should be IID_IDirect3DRGBDevice,
  464. // IID_IDirect3DHALDevice, etc. for DX5 and beyond, guid is IID_IDirect3DDevice,
  465. // IID_IDirect3DDevice2, etc
  466. GUID guid;
  467. LPD3DHAL_CALLBACKS lpD3DHALCallbacks; /* HW specific */
  468. LPD3DHAL_GLOBALDRIVERDATA lpD3DHALGlobalDriverData; /* HW specific */
  469. LPD3DHAL_CALLBACKS2 lpD3DHALCallbacks2; /* HW specific */
  470. LPD3DHAL_CALLBACKS3 lpD3DHALCallbacks3; /* DX6 DDI */
  471. /* DirectDraw objects that we are holding references to */
  472. LPDIRECTDRAW lpDD; // DirectDraw object
  473. LPDDRAWI_DIRECTDRAW_GBL lpDDGbl; //
  474. LPDIRECTDRAWSURFACE lpDDSTarget; // Render target
  475. LPDIRECTDRAWSURFACE lpDDSZBuffer; // Z buffer
  476. LPDIRECTDRAWPALETTE lpDDPalTarget; // Palette for render target (if any)
  477. // these are saved for use by new GetRenderTarget and anything else that requires DDS4 functionality
  478. LPDIRECTDRAWSURFACE7 lpDDSTarget_DDS7;
  479. LPDIRECTDRAWSURFACE7 lpDDSZBuffer_DDS7;
  480. // Front end data
  481. D3DFE_TRANSFORM transform; // Transformation state
  482. int iClipStatus; // Clipping status
  483. DWORD dwhContext; // Driver context
  484. // RenderTarget/ZBuf bit depth info used by Clear to Blt
  485. DWORD red_mask;
  486. DWORD red_scale;
  487. DWORD red_shift;
  488. DWORD green_mask;
  489. DWORD green_scale;
  490. DWORD green_shift;
  491. DWORD blue_mask;
  492. DWORD blue_scale;
  493. DWORD blue_shift;
  494. DWORD alpha_mask;
  495. DWORD alpha_scale;
  496. DWORD alpha_shift;
  497. DWORD zmask_shift,stencilmask_shift;
  498. BOOL bDDSTargetIsPalettized; // true if 4 or 8 bit rendertarget
  499. // Pipeline state info
  500. DWORD dwDebugFlags; // See debug bits above
  501. #ifndef WIN95
  502. DWORD_PTR hSurfaceTarget;
  503. #else
  504. DWORD hSurfaceTarget;
  505. #endif
  506. #ifdef TRACK_HAL_CALLS
  507. DWORD hal_calls;
  508. #endif
  509. //--------------- Lights start -----------------------
  510. DIRECT3DLIGHTI *m_pLights; // Growable light array
  511. DWORD m_dwNumLights; // Size of m_Lights array
  512. LIST_ROOT(_dlights, DIRECT3DLIGHTI) m_ActiveLights;
  513. LIST_ROOT(name10,_SpecularTable) specular_tables;
  514. SpecularTable* specular_table;
  515. LIGHT_VERTEX_FUNC_TABLE *lightVertexFuncTable;
  516. //--------------- Lights end -----------------------
  517. /* Provider backing this driver */
  518. IHalProvider* pHalProv;
  519. HINSTANCE hDllProv;
  520. /* Device description */
  521. D3DDEVICEDESC7 d3dDevDesc;
  522. /*
  523. * Pointer to texture objects for currently installed textures. NULL indicates
  524. * that the texture is either not set (rstate NULL) or that the handle to tex3 pointer
  525. * mapping is not done. This mapping is expensive, so it is deferred until needed.
  526. *
  527. * This is needed for finding the WRAPU,V mode for texture index clipping (since
  528. * the WRAPU,V state is part of the device).
  529. */
  530. LPDIRECT3DTEXTUREI lpD3DMappedTexI[D3DHAL_TSS_MAXSTAGES];
  531. LPD3DI_TEXTUREBLOCK lpD3DMappedBlock[D3DHAL_TSS_MAXSTAGES];
  532. DWORD dwMaxTextureBlendStages; // Max number of blend stages supported by a driver
  533. DWORD m_dwStageDirty;
  534. LPDIRECTDRAWCLIPPER lpClipper;
  535. /*
  536. * DrawPrimitives batching
  537. */
  538. // Buffer to put DrawPrimitives stuff into
  539. // Used for both legacy and DrawPrimitive HALs
  540. WORD *lpwDPBuffer;
  541. WORD *lpwDPBufferAlloced;
  542. #ifndef WIN95
  543. DWORD dwDPBufferSize;
  544. #endif
  545. DWORD dwCurrentBatchVID; // Current FVF type in the batch buffer
  546. LPD3DHAL_D3DEXTENDEDCAPS lpD3DExtendedCaps; /* HW specific */
  547. LPDWORD rstates;
  548. // Runtime copy of texture stage states
  549. DWORD tsstates[D3DHAL_TSS_MAXSTAGES][D3DHAL_TSS_STATESPERSTAGE];
  550. // Object to record state sets
  551. CStateSets * m_pStateSets;
  552. // This is a function provided by sw rasterizers.
  553. // Currently, its only function is to provide an RGB8 clear color.
  554. // It should be non-NULL for anything that supports an 8 bit RGB output
  555. // type.
  556. PFN_RASTSERVICE pfnRastService;
  557. //
  558. // This is function pointer is obtained through the
  559. // HalProvider interface. For real_hals, it is found in all DX7+
  560. // drivers in pDdGbl->lpDDCBtmp->HALDDMiscellaneous2.GetDriverState
  561. // Of the software drivers, only Refrast supports it in its DX7+ mode.
  562. LPDDHAL_GETDRIVERSTATE pfnGetDriverState;
  563. // Max TSS that can be passed to the driver
  564. D3DTEXTURESTAGESTATETYPE m_tssMax;
  565. // Max RS that can be passed to the driver, used for CanHandleRenderState
  566. D3DRENDERSTATETYPE m_rsMax;
  567. // We use 32-bit ints for rsVec. The size if computed using ceil(D3D_MAXRENDERSTATES/32)
  568. DWORD rsVec[(D3D_MAXRENDERSTATES + D3D_RSVEC_MASK) >> D3D_RSVEC_SHIFT];
  569. DWORD rsVecRetired[(D3D_MAXRENDERSTATES + D3D_RSVEC_MASK) >> D3D_RSVEC_SHIFT];
  570. #if COLLECTSTATS
  571. D3DDEVINFO_TEXTURING m_texstats;
  572. #endif
  573. #ifdef VTABLE_HACK
  574. // This points to the original (compiler generated) read-only vtable of DIRECT3DDEVICEI
  575. PVOID* lpVtbl;
  576. // The new vtable which is a read/write copy of the original to allow hacking
  577. PVOID newVtbl[D3D_NUM_VIRTUAL_FUNCTIONS];
  578. #endif // VTABLE_HACK
  579. #ifdef PROFILE4
  580. DWORD m_dwProfStart, m_dwProfStop;
  581. #endif // PROFILE4
  582. #ifdef PROFILE
  583. DWORD m_dwProfStart, m_dwProfStop;
  584. #endif // PROFILE
  585. public: // virtual methods
  586. DIRECT3DDEVICEI();
  587. virtual ~DIRECT3DDEVICEI(); // 0
  588. virtual HRESULT Init(REFCLSID riid, LPDIRECT3DI lpD3DI, LPDIRECTDRAWSURFACE lpDDS,
  589. IUnknown* pUnkOuter, LPUNKNOWN* lplpD3DDevice); // 1
  590. virtual HRESULT FlushStates(bool bWithinPrimitive = false)=0; // 2 // Use to flush current batch to the driver
  591. virtual HRESULT FlushStatesReq(DWORD) { return FlushStates(); }; // 3
  592. virtual HRESULT ProcessPrimitive(__PROCPRIMOP op = __PROCPRIMOP_NONINDEXEDPRIM)=0; // 4
  593. virtual HRESULT CheckSurfaces(); // 5 // Check if the surfaces necessary for rendering are lost
  594. virtual void WriteStateSetToDevice(D3DSTATEBLOCKTYPE) {} // 6
  595. // Function to download viewport info to the driver
  596. virtual void UpdateDrvViewInfo(LPD3DVIEWPORT7 lpVwpData) {}; // 7
  597. virtual void UpdateDrvWInfo() {}; // 8
  598. virtual HRESULT halCreateContext(); // 9
  599. // This function is used when in SetRenderTarget the driver context is
  600. // recreated
  601. virtual HRESULT UpdateDriverStates(); // 10
  602. virtual HRESULT ValidateFVF(DWORD dwFVF); // 11
  603. virtual HRESULT SetupFVFData(DWORD *pdwInpVertexSize); // 12
  604. virtual void LightChanged(DWORD dwLightIndex); // 13
  605. virtual void MaterialChanged(); // 14
  606. virtual void SetTransformI(D3DTRANSFORMSTATETYPE, LPD3DMATRIX); // 15
  607. virtual void SetViewportI(LPD3DVIEWPORT7); // 16
  608. virtual HRESULT D3DAPI SetTextureStageStateFast(DWORD dwStage,
  609. D3DTEXTURESTAGESTATETYPE dwState,
  610. DWORD dwValue); // 17
  611. virtual HRESULT D3DAPI SetRenderStateFast(D3DRENDERSTATETYPE, DWORD); // 18
  612. virtual void LightEnableI(DWORD dwLightIndex, BOOL); // 19
  613. virtual HRESULT UpdateTextures(); // 20
  614. virtual void SetRenderTargetI(LPDIRECTDRAWSURFACE, LPDIRECTDRAWSURFACE); // 21
  615. virtual bool CanDoTexBlt(LPDDRAWI_DDRAWSURFACE_LCL lpDDSSrcSubFace_lcl,
  616. LPDDRAWI_DDRAWSURFACE_LCL lpDDSDstSubFace_lcl); // 22
  617. virtual void ClearI(DWORD dwFlags, DWORD clrCount, D3DCOLOR dwColor, D3DVALUE dvZ, DWORD dwStencil); // 23
  618. #ifdef VTABLE_HACK
  619. virtual HRESULT D3DAPI DrawPrimitiveTL(D3DPRIMITIVETYPE, DWORD, LPVOID, DWORD, DWORD) // 24
  620. { // Dummy function, should never be called
  621. DDASSERT(1);
  622. return DDERR_GENERIC;
  623. };
  624. virtual HRESULT D3DAPI DrawPrimitiveVBTL(D3DPRIMITIVETYPE, LPDIRECT3DVERTEXBUFFER7, DWORD, DWORD, DWORD) // 25
  625. { // Dummy function, should never be called
  626. DDASSERT(1);
  627. return DDERR_GENERIC;
  628. };
  629. virtual HRESULT D3DAPI DrawIndexedPrimitiveTL(D3DPRIMITIVETYPE, DWORD, LPVOID, DWORD, LPWORD, DWORD, DWORD) // 26
  630. { // Dummy function, should never be called
  631. DDASSERT(1);
  632. return DDERR_GENERIC;
  633. };
  634. virtual HRESULT D3DAPI DrawIndexedPrimitiveVBTL(D3DPRIMITIVETYPE, LPDIRECT3DVERTEXBUFFER7, DWORD, DWORD, LPWORD, DWORD, DWORD) // 27
  635. { // Dummy function, should never be called
  636. DDASSERT(1);
  637. return DDERR_GENERIC;
  638. };
  639. virtual HRESULT D3DAPI DrawPrimitiveFE(D3DPRIMITIVETYPE, DWORD, LPVOID, DWORD, DWORD) // 28
  640. { // Dummy function, should never be called
  641. DDASSERT(1);
  642. return DDERR_GENERIC;
  643. };
  644. virtual HRESULT D3DAPI DrawIndexedPrimitiveFE(D3DPRIMITIVETYPE, DWORD, LPVOID, DWORD, LPWORD, DWORD, DWORD) // 29
  645. { // Dummy function, should never be called
  646. DDASSERT(1);
  647. return DDERR_GENERIC;
  648. };
  649. virtual HRESULT D3DAPI DrawPrimitiveVBFE(D3DPRIMITIVETYPE, LPDIRECT3DVERTEXBUFFER7, DWORD, DWORD, DWORD) // 30
  650. { // Dummy function, should never be called
  651. DDASSERT(1);
  652. return DDERR_GENERIC;
  653. };
  654. virtual HRESULT D3DAPI DrawIndexedPrimitiveVBFE(D3DPRIMITIVETYPE, LPDIRECT3DVERTEXBUFFER7, DWORD, DWORD, LPWORD, DWORD, DWORD) // 31
  655. { // Dummy function, should never be called
  656. DDASSERT(1);
  657. return DDERR_GENERIC;
  658. };
  659. #endif
  660. virtual void SetClipPlaneI(DWORD dwPlaneIndex, D3DVALUE* pPlaneEquation); // 32
  661. virtual HRESULT D3DAPI SetTextureInternal(DWORD, LPDIRECTDRAWSURFACE7); // 33
  662. virtual HRESULT D3DAPI ApplyStateBlockInternal(DWORD); // 34
  663. virtual HRESULT SetTSSI(DWORD, D3DTEXTURESTAGESTATETYPE, DWORD) = 0; // 35
  664. virtual HRESULT D3DAPI PreLoadFast(LPDIRECTDRAWSURFACE7); // 36
  665. public: // non virtual methods
  666. BOOL UpdateInternalTextureStageState(DWORD dwStage,
  667. D3DTEXTURESTAGESTATETYPE dwState,
  668. DWORD dwValue);
  669. HRESULT stateInitialize(BOOL bZEnable);
  670. HRESULT checkDeviceSurface(LPDIRECTDRAWSURFACE lpDDS, LPDIRECTDRAWSURFACE lpZbuffer, LPGUID pGuid);
  671. HRESULT HookToD3D(LPDIRECT3DI lpD3DI);
  672. HRESULT UnhookFromD3D();
  673. HRESULT SetupFVFDataCommon(DWORD *pdwInpVertexSize);
  674. void CleanupTextures();
  675. BOOL NeedInternalTSSUpdate(DWORD dwState)
  676. {
  677. return dwState == D3DTSS_TEXCOORDINDEX || dwState >= D3DTSS_TEXTURETRANSFORMFLAGS ||
  678. dwState == D3DTSS_COLOROP;
  679. }
  680. // Always use this function to update "rstates", because we have to
  681. // set some internal flags when "rstats" is changed.
  682. void UpdateInternalState(D3DRENDERSTATETYPE type, DWORD value);
  683. // Checks for 'retired' render state - returns TRUE if not retired
  684. BOOL CheckForRetiredRenderState(D3DRENDERSTATETYPE type)
  685. {
  686. if (!(rsVecRetired[type >> D3D_RSVEC_SHIFT] & (1ul << (type & D3D_RSVEC_MASK))))
  687. {
  688. // not retired
  689. return TRUE;
  690. }
  691. return FALSE;
  692. }
  693. // Checks if we can pass the render state to the driver
  694. BOOL CanHandleRenderState(D3DRENDERSTATETYPE type)
  695. {
  696. if (type >= m_rsMax)
  697. {
  698. // not an error condition because we don't send front-end stuff to
  699. // non-TL Hal devices, for example, but don't send to HAL anyway
  700. return FALSE;
  701. }
  702. return TRUE;
  703. };
  704. // Update internal state
  705. void SetMaterialI(LPD3DMATERIAL7);
  706. void SetLightI(DWORD dwLightIndex, LPD3DLIGHT7);
  707. inline void SetFogFlags(void);
  708. void ForceFVFRecompute(void) { dwVIDIn = 0; dwFEFlags |= D3DFE_FVF_DIRTY | D3DFE_FRONTEND_DIRTY; };
  709. HRESULT CopySurface(LPDIRECTDRAWSURFACE7 lpDDSDst, LPRECT lpDestRect,
  710. LPDIRECTDRAWSURFACE7 lpDDSSrc, LPRECT lpSrcRect,
  711. DWORD dwFlags);
  712. HRESULT GetTextureDDIHandle(LPDIRECT3DTEXTUREI lpTexI,
  713. LPD3DI_TEXTUREBLOCK* lplpBlock);
  714. LPD3DI_TEXTUREBLOCK HookTexture(LPDIRECT3DTEXTUREI lpD3DText);
  715. LPD3DI_TEXTUREBLOCK D3DI_FindTextureBlock(LPDIRECT3DTEXTUREI lpTex);
  716. void BatchTexture(LPDDRAWI_DDRAWSURFACE_LCL lpLcl)
  717. {
  718. if(m_qwBatch > lpLcl->lpSurfMore->qwBatch.QuadPart)
  719. lpLcl->lpSurfMore->qwBatch.QuadPart = m_qwBatch;
  720. }
  721. HRESULT VerifyTextureCaps(LPDIRECT3DTEXTUREI lpTexI);
  722. HRESULT CheckDrawPrimitiveVB(LPDIRECT3DVERTEXBUFFER7 lpVBuf, DWORD dwStartVertex, DWORD dwNumVertices, DWORD dwFlags);
  723. void DisplayStats();
  724. void CheckClipStatus(D3DVALUE * pPositions, DWORD dwStride, DWORD dwNumVertices,
  725. DWORD *pdwClipUnion, DWORD *pdwClipIntersection);
  726. HRESULT VerifyTexture(DWORD dwStage, LPDIRECTDRAWSURFACE7 lpTex);
  727. HRESULT SetRenderStateInternal(D3DRENDERSTATETYPE, DWORD);
  728. BOOL GetInfoInternal(DWORD dwDevInfoID, LPVOID pDevInfoStruct, DWORD dwSize);
  729. #if COLLECTSTATS
  730. void ResetTexStats();
  731. void GetTexStats(LPD3DDEVINFO_TEXTURING);
  732. void IncNumLoads()
  733. {
  734. ++m_texstats.dwNumLoads;
  735. }
  736. void IncNumTexturesSet()
  737. {
  738. ++m_texstats.dwNumSet;
  739. }
  740. void IncNumPreLoads()
  741. {
  742. ++m_texstats.dwNumPreLoads;
  743. }
  744. void IncBytesDownloaded(LPDDRAWI_DDRAWSURFACE_LCL lpLcl, LPRECT lpRect)
  745. {
  746. m_texstats.dwApproxBytesLoaded += BytesDownloaded(lpLcl, lpRect);
  747. }
  748. #endif
  749. #ifdef VTABLE_HACK
  750. void VtblPreLoadFast()
  751. {
  752. // DIRECT3DDEVICEI::PreLoadFast
  753. newVtbl[24] = lpVtbl[D3D_NUM_API_FUNCTIONS+36];
  754. }
  755. void VtblApplyStateBlockRecord()
  756. {
  757. // IDirect3DDevice7::ApplyStateBlock
  758. newVtbl[39] = lpVtbl[39];
  759. }
  760. void VtblApplyStateBlockExecute()
  761. {
  762. // IDirect3DDevice7::ApplyStateBlockInternal
  763. newVtbl[39] = lpVtbl[D3D_NUM_API_FUNCTIONS+34];
  764. }
  765. void VtblSetTextureRecord()
  766. {
  767. // IDirect3DDevice7::SetTexture
  768. newVtbl[35] = lpVtbl[35];
  769. }
  770. void VtblSetTextureExecute()
  771. {
  772. // IDirect3DDevice7::SetTextureInternal
  773. newVtbl[35] = lpVtbl[D3D_NUM_API_FUNCTIONS+33];
  774. }
  775. void VtblSetTextureStageStateRecord()
  776. {
  777. // IDirect3DDevice7::SetTextureStageState
  778. newVtbl[37] = lpVtbl[37];
  779. }
  780. void VtblSetTextureStageStateExecute()
  781. {
  782. // IDirect3DDevice7::SetTextureStageStateI
  783. newVtbl[37] = lpVtbl[D3D_NUM_API_FUNCTIONS+17];
  784. }
  785. void VtblSetRenderStateRecord()
  786. {
  787. // IDirect3DDevice7::SetRenderState
  788. newVtbl[20] = lpVtbl[20];
  789. }
  790. void VtblSetRenderStateExecute()
  791. {
  792. // DIRECT3DDEVICEI::SetRenderStateFast
  793. newVtbl[20] = lpVtbl[D3D_NUM_API_FUNCTIONS+18];
  794. }
  795. void VtblDrawPrimitiveDefault()
  796. {
  797. // IDirect3DDevice7::DrawPrimitive
  798. newVtbl[25] = lpVtbl[25];
  799. }
  800. void VtblDrawPrimitiveTL()
  801. {
  802. // DIRECT3DDEVICEI::DrawPrimitiveTL
  803. newVtbl[25] = lpVtbl[D3D_NUM_API_FUNCTIONS+24];
  804. }
  805. void VtblDrawPrimitiveVBDefault()
  806. {
  807. // IDirect3DDevice7::DrawPrimitiveVB
  808. newVtbl[31] = lpVtbl[31];
  809. }
  810. void VtblDrawPrimitiveVBTL()
  811. {
  812. // DIRECT3DDEVICEI::DrawPrimitiveVBTL
  813. newVtbl[31] = lpVtbl[D3D_NUM_API_FUNCTIONS+25];
  814. }
  815. void VtblDrawIndexedPrimitiveDefault()
  816. {
  817. // IDirect3DDevice7::DrawIndexedPrimitive
  818. newVtbl[26] = lpVtbl[26];
  819. }
  820. void VtblDrawIndexedPrimitiveTL()
  821. {
  822. // DIRECT3DDEVICEI::DrawIndexedPrimitiveTL
  823. newVtbl[26] = lpVtbl[D3D_NUM_API_FUNCTIONS+26];
  824. }
  825. void VtblDrawIndexedPrimitiveVBDefault()
  826. {
  827. // IDirect3DDevice7::DrawIndexedPrimitiveVB
  828. newVtbl[32] = lpVtbl[32];
  829. }
  830. void VtblDrawIndexedPrimitiveVBTL()
  831. {
  832. // DIRECT3DDEVICEI::DrawIndexedPrimitiveVBTL
  833. newVtbl[32] = lpVtbl[D3D_NUM_API_FUNCTIONS+27];
  834. }
  835. void VtblDrawPrimitiveFE()
  836. {
  837. // DIRECT3DDEVICEI::DrawPrimitiveFE
  838. newVtbl[25] = lpVtbl[D3D_NUM_API_FUNCTIONS+28];
  839. }
  840. void VtblDrawIndexedPrimitiveFE()
  841. {
  842. // DIRECT3DDEVICEI::DrawIndexedPrimitiveFE
  843. newVtbl[26] = lpVtbl[D3D_NUM_API_FUNCTIONS+29];
  844. }
  845. void VtblDrawPrimitiveVBFE()
  846. {
  847. // DIRECT3DDEVICEI::DrawPrimitiveFE
  848. newVtbl[31] = lpVtbl[D3D_NUM_API_FUNCTIONS+30];
  849. }
  850. void VtblDrawIndexedPrimitiveVBFE()
  851. {
  852. // DIRECT3DDEVICEI::DrawIndexedPrimitiveFE
  853. newVtbl[32] = lpVtbl[D3D_NUM_API_FUNCTIONS+31];
  854. }
  855. #endif
  856. #if DBG
  857. #define PROF_DRAWPRIMITIVEDEVICE2 0x0003
  858. #define PROF_DRAWINDEXEDPRIMITIVEDEVICE2 0x0004
  859. #define PROF_DRAWPRIMITIVESTRIDED 0x0005
  860. #define PROF_DRAWINDEXEDPRIMITIVESTRIDED 0x0006
  861. #define PROF_DRAWPRIMITIVEDEVICE3 0x0007
  862. #define PROF_DRAWINDEXEDPRIMITIVEDEVICE3 0x0008
  863. #define PROF_DRAWPRIMITIVEVB 0x0009
  864. #define PROF_DRAWINDEXEDPRIMITIVEVB 0x000a
  865. DWORD dwCaller;
  866. DWORD dwPrimitiveType[PROF_DRAWINDEXEDPRIMITIVEVB+1];
  867. DWORD dwVertexType1[PROF_DRAWINDEXEDPRIMITIVEVB+1];
  868. DWORD dwVertexType2[PROF_DRAWINDEXEDPRIMITIVEVB+1];
  869. void Profile(DWORD, D3DPRIMITIVETYPE, DWORD);
  870. #else
  871. #define Profile(a,b,c)
  872. #endif
  873. public:
  874. // IUnknown Methods
  875. HRESULT D3DAPI QueryInterface(REFIID riid, LPVOID* ppvObj);
  876. ULONG D3DAPI AddRef();
  877. ULONG D3DAPI Release();
  878. // IDirect3DDevice7 Methods
  879. HRESULT D3DAPI GetCaps(LPD3DDEVICEDESC7);
  880. HRESULT D3DAPI EnumTextureFormats(LPD3DENUMPIXELFORMATSCALLBACK, LPVOID);
  881. HRESULT D3DAPI BeginScene();
  882. HRESULT D3DAPI EndScene();
  883. HRESULT D3DAPI GetDirect3D(LPDIRECT3D7*);
  884. HRESULT D3DAPI Clear(DWORD, LPD3DRECT, DWORD, D3DCOLOR, D3DVALUE, DWORD);
  885. HRESULT D3DAPI SetRenderTarget(LPDIRECTDRAWSURFACE7, DWORD);
  886. HRESULT D3DAPI GetRenderTarget(LPDIRECTDRAWSURFACE7 *);
  887. HRESULT D3DAPI SetTransform(D3DTRANSFORMSTATETYPE, LPD3DMATRIX);
  888. HRESULT D3DAPI GetTransform(D3DTRANSFORMSTATETYPE, LPD3DMATRIX);
  889. HRESULT D3DAPI MultiplyTransform(D3DTRANSFORMSTATETYPE, LPD3DMATRIX);
  890. HRESULT D3DAPI SetViewport(LPD3DVIEWPORT7);
  891. HRESULT D3DAPI GetViewport(LPD3DVIEWPORT7);
  892. HRESULT D3DAPI SetMaterial(LPD3DMATERIAL7);
  893. HRESULT D3DAPI GetMaterial(LPD3DMATERIAL7);
  894. HRESULT D3DAPI SetLight(DWORD, LPD3DLIGHT7);
  895. HRESULT D3DAPI GetLight(DWORD, LPD3DLIGHT7);
  896. HRESULT D3DAPI GetRenderState(D3DRENDERSTATETYPE, LPDWORD);
  897. HRESULT D3DAPI SetRenderState(D3DRENDERSTATETYPE, DWORD);
  898. HRESULT D3DAPI DrawPrimitive(D3DPRIMITIVETYPE, DWORD, LPVOID, DWORD, DWORD);
  899. HRESULT D3DAPI DrawIndexedPrimitive(D3DPRIMITIVETYPE, DWORD, LPVOID, DWORD, LPWORD, DWORD, DWORD);
  900. HRESULT D3DAPI SetClipStatus(LPD3DCLIPSTATUS);
  901. HRESULT D3DAPI GetClipStatus(LPD3DCLIPSTATUS);
  902. HRESULT D3DAPI DrawPrimitiveStrided(D3DPRIMITIVETYPE, DWORD, LPD3DDRAWPRIMITIVESTRIDEDDATA, DWORD, DWORD);
  903. HRESULT D3DAPI DrawIndexedPrimitiveStrided(D3DPRIMITIVETYPE, DWORD, LPD3DDRAWPRIMITIVESTRIDEDDATA, DWORD, LPWORD, DWORD, DWORD);
  904. HRESULT D3DAPI DrawPrimitiveVB(D3DPRIMITIVETYPE, LPDIRECT3DVERTEXBUFFER7, DWORD, DWORD, DWORD);
  905. HRESULT D3DAPI DrawIndexedPrimitiveVB(D3DPRIMITIVETYPE, LPDIRECT3DVERTEXBUFFER7, DWORD, DWORD, LPWORD, DWORD, DWORD);
  906. HRESULT D3DAPI ComputeSphereVisibility(LPD3DVECTOR, LPD3DVALUE, DWORD, DWORD, LPDWORD);
  907. HRESULT D3DAPI GetTexture(DWORD, LPDIRECTDRAWSURFACE7 *);
  908. HRESULT D3DAPI SetTexture(DWORD, LPDIRECTDRAWSURFACE7);
  909. HRESULT D3DAPI GetTextureStageState(DWORD, D3DTEXTURESTAGESTATETYPE, LPDWORD);
  910. HRESULT D3DAPI DuplicateStateBlock(DWORD InHandle, LPDWORD OutHandle);
  911. HRESULT D3DAPI OverlayStateBlock(DWORD Handle);
  912. HRESULT D3DAPI BeginStateBlock();
  913. HRESULT D3DAPI EndStateBlock(LPDWORD);
  914. HRESULT D3DAPI DeleteStateBlock(DWORD);
  915. HRESULT D3DAPI ApplyStateBlock(DWORD);
  916. HRESULT D3DAPI CaptureStateBlock(DWORD Handle);
  917. HRESULT D3DAPI SetTextureStageState(DWORD dwStage,
  918. D3DTEXTURESTAGESTATETYPE dwState,
  919. DWORD dwValue);
  920. HRESULT D3DAPI ValidateDevice(LPDWORD lpdwNumPasses) = 0;
  921. HRESULT D3DAPI Load(LPDIRECTDRAWSURFACE7 lpDest, LPPOINT lpDestPoint,
  922. LPDIRECTDRAWSURFACE7 lpSrc, LPRECT lpSrcRect,
  923. DWORD dwFlags);
  924. HRESULT D3DAPI LightEnable(DWORD dwLightIndex, BOOL);
  925. HRESULT D3DAPI GetLightEnable(DWORD dwLightIndex, BOOL*);
  926. HRESULT D3DAPI PreLoad(LPDIRECTDRAWSURFACE7 lpTex);
  927. HRESULT D3DAPI GetInfo(DWORD dwDevInfoID, LPVOID pDevInfoStruct, DWORD dwSize);
  928. HRESULT D3DAPI SetClipPlane(DWORD dwPlaneIndex, D3DVALUE* pPlaneEquation);
  929. HRESULT D3DAPI GetClipPlane(DWORD dwPlaneIndex, D3DVALUE* pPlaneEquation);
  930. HRESULT D3DAPI CreateStateBlock(D3DSTATEBLOCKTYPE sbt, LPDWORD pdwHandle);
  931. };
  932. // There is only DP2 HAL on NT
  933. #ifdef WIN95
  934. typedef struct _D3DHAL_DRAWPRIMCOUNTS *LPD3DHAL_DRAWPRIMCOUNTS;
  935. // Legacy HAL batching is done with these structs.
  936. typedef struct _D3DI_HWCOUNTS {
  937. WORD wNumStateChanges; // Number of state changes batched
  938. WORD wNumVertices; // Number of vertices in tri list
  939. WORD wNumTriangles; // Number of triangles in tri list
  940. } D3DI_HWCOUNTS, *LPD3DI_HWCOUNTS;
  941. class CDirect3DDeviceIHW : public DIRECT3DDEVICEI
  942. {
  943. private: // Data
  944. /* Legacy HALs */
  945. // Buffer of counts structures that keep track of the
  946. // number of render states and vertices buffered
  947. LPD3DI_HWCOUNTS lpHWCounts;
  948. // Buffer of triangle structures.
  949. LPD3DTRIANGLE lpHWTris;
  950. // Byte offset into lpHWVertices. This gets incremented
  951. // by 8 when a render state is batched and by 32*dwNumVertices
  952. // when a primitive is batched.
  953. DWORD dwHWOffset;
  954. // Max value of dwHWOffset. Used to decide whether to flush.
  955. DWORD dwHWMaxOffset;
  956. // Index into lpHWTris.
  957. DWORD dwHWTriIndex;
  958. // Number of counts structures used so far. This actually
  959. // gives the number of primitives batched and the index of
  960. // the counts structure to batch render states into.
  961. DWORD dwHWNumCounts;
  962. WORD *wTriIndex;
  963. HRESULT DrawIndexedPrimitiveInBatchesHW(D3DPRIMITIVETYPE PrimitiveType,
  964. D3DVERTEXTYPE VertexType,
  965. LPD3DTLVERTEX lpVertices,
  966. DWORD dwNumPrimitives,
  967. LPWORD lpwIndices);
  968. protected:
  969. CBufferDDS TLVbuf;
  970. public:
  971. CDirect3DDeviceIHW() { deviceType = D3DDEVTYPE_OLDHAL; }
  972. ~CDirect3DDeviceIHW(); // Called by CDirect3DDeviceUnk::Release()
  973. HRESULT SetRenderStateI(D3DRENDERSTATETYPE, DWORD);
  974. HRESULT DrawPrim();
  975. HRESULT DrawIndexPrim();
  976. HRESULT DrawClippedPrim() {return DrawPrim();}
  977. HRESULT FlushStates(bool bWithinPrimitive = false);
  978. HRESULT D3DAPI ValidateDevice(LPDWORD lpdwNumPasses);
  979. HRESULT SetTSSI(DWORD, D3DTEXTURESTAGESTATETYPE, DWORD);
  980. HRESULT MapTSSToRS();
  981. HRESULT Init(REFCLSID riid, LPDIRECT3DI lpD3DI, LPDIRECTDRAWSURFACE lpDDS,
  982. IUnknown* pUnkOuter, LPUNKNOWN* lplpD3DDevice);
  983. HRESULT ProcessPrimitive(__PROCPRIMOP op = __PROCPRIMOP_NONINDEXEDPRIM);
  984. HRESULT MapFVFtoTLVertex(LPVOID lpAddress);
  985. HRESULT MapFVFtoTLVertexIndexed();
  986. };
  987. class CDirect3DDeviceIDP : public CDirect3DDeviceIHW
  988. {
  989. private: // Data
  990. /* data members of DIRECT3DDEVICEI that are specific to DX5 DrawPrimitive HAL drivers
  991. should go here */
  992. /* DrawPrimitive-aware HALs */
  993. // pointer to current prim counts struct
  994. LPD3DHAL_DRAWPRIMCOUNTS lpDPPrimCounts;
  995. // Byte offset into buffer (we are currently
  996. // using the device's wTriIndex)
  997. DWORD dwDPOffset;
  998. // Maximum offset. If dwDPOffset exceeds this, it is
  999. // time to flush.
  1000. DWORD dwDPMaxOffset;
  1001. public:
  1002. CDirect3DDeviceIDP() { deviceType = D3DDEVTYPE_DPHAL; }
  1003. ~CDirect3DDeviceIDP() { CleanupTextures(); }
  1004. HRESULT SetRenderStateI(D3DRENDERSTATETYPE, DWORD);
  1005. HRESULT DrawPrim();
  1006. HRESULT DrawIndexPrim();
  1007. HRESULT DrawClippedPrim() {return DrawPrim();}
  1008. HRESULT FlushStates(bool bWithinPrimitive = false);
  1009. HRESULT Init(REFCLSID riid, LPDIRECT3DI lpD3DI, LPDIRECTDRAWSURFACE lpDDS,
  1010. IUnknown* pUnkOuter, LPUNKNOWN* lplpD3DDevice);
  1011. HRESULT halCreateContext();
  1012. };
  1013. #define IS_DPHAL_DEVICE(lpDevI) ((lpDevI)->deviceType == D3DDEVTYPE_DPHAL)
  1014. #endif // WIN95
  1015. // Flags passed by the runtime to the DDI batching code via PV structure
  1016. // to enable new DDI batching to be done efficiently. These flags are
  1017. // marked as reserved in d3dfe.hpp
  1018. const DWORD D3DPV_WITHINPRIMITIVE = D3DPV_RESERVED1; // This flags that the flush has occured
  1019. // within an primitive. This indicates
  1020. // that we should not flush the vertex buffer
  1021. // If the vertices are in user memory
  1022. const DWORD D3DPV_USERMEMVERTICES = D3DPV_RESERVED3;
  1023. //---------------------------------------------------------------------
  1024. class CDirect3DDeviceIDP2 : public DIRECT3DDEVICEI
  1025. {
  1026. public: // data
  1027. static const DWORD dwD3DDefaultCommandBatchSize;
  1028. // This is the VB interface corresponding to the dp2data.lpDDVertex
  1029. // This is kept so that the VB can be released when done
  1030. // which cannot be done from just the LCL pointer which is lpDDVertex
  1031. CDirect3DVertexBuffer* lpDP2CurrBatchVBI;
  1032. DWORD TLVbuf_size;
  1033. DWORD TLVbuf_base;
  1034. #ifdef VTABLE_HACK
  1035. // Cached dwFlags for fast path
  1036. DWORD dwLastFlags;
  1037. // Last VB used in a call that involved D3D's FE.
  1038. CDirect3DVertexBuffer* lpDP2LastVBI;
  1039. #endif
  1040. DWORD dwDP2CommandBufSize;
  1041. DWORD dwDP2CommandLength;
  1042. // Cache line should start here
  1043. // Pointer to the actual data in CB1
  1044. LPVOID lpvDP2Commands;
  1045. //Pointer to the current position the CB1 buffer
  1046. LPD3DHAL_DP2COMMAND lpDP2CurrCommand;
  1047. // Perf issue: replace the below 3 fields by a 32 bit D3DHAL_DP2COMMAND struct
  1048. WORD wDP2CurrCmdCnt; // Mirror of Count field if the current command
  1049. BYTE bDP2CurrCmdOP; // Mirror of Opcode of the current command
  1050. BYTE bDummy; // Force DWORD alignment of next member
  1051. D3DHAL_DRAWPRIMITIVES2DATA dp2data;
  1052. // The buffer we currently batch into
  1053. LPDIRECTDRAWSURFACE7 lpDDSCB1;
  1054. LPDIRECT3DVERTEXBUFFER7 allocatedBuf;
  1055. LPVOID alignedBuf;
  1056. // Count read/write <-> write-only transistions
  1057. DWORD dwTLVbufChanges;
  1058. // Flags specific to DP2 device
  1059. DWORD dwDP2Flags;
  1060. // If a mode switch occurs just before a TLVbuf_Grow which requires to create a new
  1061. // VB, then the create will fail. This will leave the device in a state where
  1062. // allocatedBuf is NULL. This is bad since many places in the code we derefence this
  1063. // without checking for NULL. To have a contained fix, we create a small dummy system
  1064. // memory VB at device create and if we ever fail the grow due to mode switch, we assign
  1065. // this VB instead to allocated buf and set the TLVbuf_size to 0.
  1066. LPDIRECT3DVERTEXBUFFER7 pNullVB;
  1067. protected: // methods
  1068. inline void ClearBatch(bool);
  1069. HRESULT Init(REFCLSID riid, LPDIRECT3DI lpD3DI, LPDIRECTDRAWSURFACE lpDDS,
  1070. IUnknown* pUnkOuter, LPUNKNOWN* lplpD3DDevice);
  1071. HRESULT GrowCommandBuffer(LPDIRECT3DI lpD3DI, DWORD dwSize);
  1072. #if DBG
  1073. void ValidateVertex(LPDWORD lpdwVertex);
  1074. void ValidateCommand(LPD3DHAL_DP2COMMAND lpCmd);
  1075. #endif
  1076. public:
  1077. CDirect3DDeviceIDP2() { deviceType = D3DDEVTYPE_DP2HAL; }
  1078. ~CDirect3DDeviceIDP2(); // Called by CDirect3DDeviceUnk::Release()
  1079. HRESULT FlushStates(bool bWithinPrimitive = false);
  1080. HRESULT FlushStatesReq(DWORD dwReqSize);
  1081. HRESULT SetRenderStateI(D3DRENDERSTATETYPE, DWORD);
  1082. HRESULT DrawPrim();
  1083. HRESULT DrawIndexPrim();
  1084. HRESULT DrawClippedPrim();
  1085. HRESULT D3DAPI ValidateDevice(LPDWORD lpdwNumPasses);
  1086. HRESULT SetTSSI(DWORD, D3DTEXTURESTAGESTATETYPE, DWORD);
  1087. // Called from DrawPrimitiveVB if a vertex buffer or TL buffer is used for rendering
  1088. HRESULT StartPrimVB(LPDIRECT3DVERTEXBUFFERI vb, DWORD dwStartVertex);
  1089. // Called if user memory buffer is used for rendering
  1090. HRESULT StartPrimUserMem(LPVOID memory);
  1091. // Called if TL buffer of used memory was used for rendering
  1092. HRESULT EndPrim();
  1093. HRESULT CheckSurfaces();
  1094. void UpdateDrvViewInfo(LPD3DVIEWPORT7 lpVwpData);
  1095. void UpdateDrvWInfo();
  1096. // This function is used when in SetRenderTarget the driver context is
  1097. // recreated
  1098. HRESULT UpdateDriverStates();
  1099. HRESULT SetupFVFData(DWORD *pdwInpVertexSize);
  1100. HRESULT ProcessPrimitive(__PROCPRIMOP op = __PROCPRIMOP_NONINDEXEDPRIM);
  1101. // Returns aligned buffer address
  1102. LPVOID TLVbuf_GetAddress()
  1103. {
  1104. return (LPBYTE)alignedBuf + TLVbuf_base;
  1105. }
  1106. // Returns aligned buffer size
  1107. DWORD TLVbuf_GetSize() { return TLVbuf_size - TLVbuf_base; }
  1108. DWORD& TLVbuf_Base() { return TLVbuf_base; }
  1109. // define these later on in this file after CDirect3DVertexBuffer is defined
  1110. inline CDirect3DVertexBuffer* TLVbuf_GetVBI();
  1111. inline LPDIRECTDRAWSURFACE TLVbuf_GetDDS();
  1112. HRESULT TLVbuf_Grow(DWORD dwSize, bool bWriteOnly);
  1113. // Initializes command header in the DP2 command buffer,
  1114. // reserves space for the comamnd data and returns pointer to the command
  1115. // data
  1116. // Throws an HRESULT exception in case of error
  1117. LPVOID GetHalBufferPointer(D3DHAL_DP2OPERATION op, DWORD dwDataSize);
  1118. HRESULT D3DAPI DrawPrimitiveTL(D3DPRIMITIVETYPE, DWORD, LPVOID, DWORD, DWORD);
  1119. HRESULT D3DAPI DrawPrimitiveVBTL(D3DPRIMITIVETYPE, LPDIRECT3DVERTEXBUFFER7, DWORD, DWORD, DWORD);
  1120. HRESULT D3DAPI DrawIndexedPrimitiveTL(D3DPRIMITIVETYPE, DWORD, LPVOID, DWORD, LPWORD, DWORD, DWORD);
  1121. HRESULT D3DAPI DrawIndexedPrimitiveVBTL(D3DPRIMITIVETYPE, LPDIRECT3DVERTEXBUFFER7, DWORD, DWORD, LPWORD, DWORD, DWORD);
  1122. HRESULT D3DAPI DrawPrimitiveFE(D3DPRIMITIVETYPE, DWORD, LPVOID, DWORD, DWORD);
  1123. HRESULT D3DAPI DrawIndexedPrimitiveFE(D3DPRIMITIVETYPE, DWORD, LPVOID, DWORD, LPWORD, DWORD, DWORD);
  1124. HRESULT D3DAPI DrawPrimitiveVBFE(D3DPRIMITIVETYPE, LPDIRECT3DVERTEXBUFFER7, DWORD, DWORD, DWORD);
  1125. HRESULT D3DAPI DrawIndexedPrimitiveVBFE(D3DPRIMITIVETYPE, LPDIRECT3DVERTEXBUFFER7, DWORD, DWORD, LPWORD, DWORD, DWORD);
  1126. };
  1127. // macros to characterize device
  1128. #define IS_DP2HAL_DEVICE(lpDevI) ((lpDevI)->deviceType >= D3DDEVTYPE_DP2HAL)
  1129. #define IS_DX7HAL_DEVICE(lpDevI) ((lpDevI)->deviceType >= D3DDEVTYPE_DX7HAL)
  1130. #define IS_TLHAL_DEVICE(lpDevI) ((lpDevI)->deviceType >= D3DDEVTYPE_DX7TLHAL)
  1131. #define IS_MT_DEVICE(lpDevI) ( (lpDevI)->dwHintFlags & D3DDEVBOOL_HINTFLAGS_MULTITHREADED )
  1132. #define IS_HW_DEVICE(lpDevI) ((lpDevI)->dwFEFlags & D3DFE_REALHAL)
  1133. #define IS_FPU_SETUP(lpDevI) ((lpDevI)->dwHintFlags & D3DDEVBOOL_HINTFLAGS_FPUSETUP )
  1134. /*
  1135. * Internal version of Direct3DTexture object; it has data after the vtable
  1136. */
  1137. class DIRECT3DTEXTUREI : public CD3DAlloc
  1138. {
  1139. public:
  1140. /*** Object Relations ***/
  1141. LIST_ROOT(_blocks, _D3DI_TEXTUREBLOCK) blocks;
  1142. /* Devices we're associated with */
  1143. /* Next member in texture chain */
  1144. LIST_MEMBER(DIRECT3DTEXTUREI) m_List;
  1145. /*** Object Data ***/
  1146. LPDIRECT3DI lpDirect3DI;
  1147. DDRAWI_DDRAWSURFACE_INT DDS1Tex; //we need to keep the legacy
  1148. LPDIRECTDRAWSURFACE7 lpDDS;
  1149. LPDIRECTDRAWSURFACE7 lpDDSSys;
  1150. DDSURFACEDESC2 ddsd;
  1151. DWORD m_dwBytes;
  1152. DWORD m_dwVidBytes;
  1153. DWORD m_dwScene;
  1154. DWORD m_dwPriority;
  1155. DWORD m_dwTicks;
  1156. DWORD m_dwHeapIndex;
  1157. DWORD m_dwLOD;
  1158. D3DTEXTUREHANDLE m_hTex;
  1159. BOOL m_bInUse;
  1160. BOOL bDirty;
  1161. /*
  1162. * The special IUnknown interface for the aggregate that does
  1163. * not punt to the parent object.
  1164. */
  1165. public:
  1166. DIRECT3DTEXTUREI();
  1167. virtual HRESULT Initialize(LPDIRECT3DI lpDirect3DI, LPDIRECTDRAWSURFACE7 pDDS);
  1168. virtual void Destroy();
  1169. ULONGLONG Cost() const
  1170. {
  1171. #ifdef _X86_
  1172. ULONGLONG retval;
  1173. _asm
  1174. {
  1175. mov ebx, this;
  1176. mov edx, [ebx]DIRECT3DTEXTUREI.m_bInUse;
  1177. shl edx, 31;
  1178. mov eax, [ebx]DIRECT3DTEXTUREI.m_dwPriority;
  1179. mov ecx, eax;
  1180. shr eax, 1;
  1181. or edx, eax;
  1182. mov DWORD PTR retval + 4, edx;
  1183. shl ecx, 31;
  1184. mov eax, [ebx]DIRECT3DTEXTUREI.m_dwTicks;
  1185. shr eax, 1;
  1186. or eax, ecx;
  1187. mov DWORD PTR retval, eax;
  1188. }
  1189. return retval;
  1190. #else
  1191. return ((ULONGLONG)m_bInUse << 63) + ((ULONGLONG)m_dwPriority << 31) + ((ULONGLONG)(m_dwTicks >> 1));
  1192. #endif
  1193. }
  1194. bool D3DManaged()
  1195. {
  1196. return this->lpDDSSys != NULL;
  1197. }
  1198. bool InVidmem()
  1199. {
  1200. return m_dwHeapIndex != 0;
  1201. }
  1202. void AddRef()
  1203. {
  1204. LPDDRAWI_DDRAWSURFACE_INT surf_int = (LPDDRAWI_DDRAWSURFACE_INT)(D3DManaged() ? this->lpDDSSys : this->lpDDS);
  1205. ++(surf_int->dwIntRefCnt);
  1206. ++(surf_int->lpLcl->dwLocalRefCnt);
  1207. ++(surf_int->lpLcl->lpGbl->dwRefCnt);
  1208. }
  1209. void Release()
  1210. {
  1211. LPDDRAWI_DDRAWSURFACE_INT surf_int = (LPDDRAWI_DDRAWSURFACE_INT)(D3DManaged() ? this->lpDDSSys : this->lpDDS);
  1212. if(surf_int->dwIntRefCnt > 1) // only do this short way when it's not going away
  1213. {
  1214. --(surf_int->dwIntRefCnt);
  1215. --(surf_int->lpLcl->dwLocalRefCnt);
  1216. --(surf_int->lpLcl->lpGbl->dwRefCnt);
  1217. }
  1218. else
  1219. {
  1220. ((LPDIRECTDRAWSURFACE7)surf_int)->Release();
  1221. }
  1222. }
  1223. virtual HRESULT SetPriority(DWORD dwPriority);
  1224. virtual HRESULT GetPriority(LPDWORD lpdwPriority);
  1225. virtual HRESULT SetLOD(DWORD dwLOD);
  1226. virtual HRESULT GetLOD(LPDWORD lpdwLOD);
  1227. };
  1228. // DIRECT3DTEXTUREM is used when the texture is desired
  1229. // to be driver managed
  1230. class DIRECT3DTEXTUREM : public DIRECT3DTEXTUREI
  1231. {
  1232. public:
  1233. HRESULT SetPriority(DWORD dwPriority);
  1234. HRESULT GetPriority(LPDWORD lpdwPriority);
  1235. HRESULT SetLOD(DWORD dwLOD);
  1236. HRESULT GetLOD(LPDWORD lpdwLOD);
  1237. };
  1238. // DIRECT3DTEXTUREM is used when the texture is desired
  1239. // to be managed by Direct3D
  1240. class DIRECT3DTEXTURED3DM : public DIRECT3DTEXTUREM
  1241. {
  1242. public:
  1243. void Destroy();
  1244. HRESULT Initialize(LPDIRECT3DI lpDirect3DI, LPDIRECTDRAWSURFACE7 pDDS);
  1245. void MarkDirtyPointers();
  1246. HRESULT SetPriority(DWORD dwPriority);
  1247. HRESULT SetLOD(DWORD dwLOD);
  1248. };
  1249. #define D3DVB_NUM_VIRTUAL_FUNCTIONS 10
  1250. // Internal VB create flag:
  1251. #define D3DVBFLAGS_CREATEMULTIBUFFER 0x80000000L
  1252. class CDirect3DVertexBuffer : public IDirect3DVertexBuffer7,
  1253. public CD3DAlloc
  1254. {
  1255. private:
  1256. HRESULT CreateMemoryBuffer(LPDIRECT3DI lpD3DI,
  1257. LPDIRECTDRAWSURFACE7 *lplpSurface7,
  1258. LPDIRECTDRAWSURFACE *lplpS,
  1259. LPVOID *lplpMemory,
  1260. DWORD dwBufferSize);
  1261. #ifdef VTABLE_HACK
  1262. // The new vtable which is a read/write copy of the original to allow hacking
  1263. PVOID newVtbl[D3DVB_NUM_VIRTUAL_FUNCTIONS];
  1264. #endif // VTABLE_HACK
  1265. // Internal data
  1266. DWORD dwPVFlags;
  1267. LPDIRECT3DDEVICEI lpDevIBatched; // Is this VB batched in a device ? If so we need to flush the device
  1268. // on Lock
  1269. DWORD dwLockCnt;
  1270. /* position.lpData = start of vertex buffer data
  1271. * position.dwStride = Number of bytes per vertex
  1272. */
  1273. union {
  1274. D3DDP_PTRSTRIDE position;
  1275. D3DDP_PTRSTRIDE SOA;
  1276. };
  1277. DWORD dwNumVertices;
  1278. DWORD fvf; // Used in Input and Output
  1279. DWORD dwCaps;
  1280. DWORD dwMemType; // DDSCAPS_VIDEOMEMORY, DDSCAPS2_VERTEXBUFFER
  1281. DWORD srcVOP, dstVOP;
  1282. DWORD nTexCoord; // Number of texture coordinates
  1283. DWORD dwTexCoordSize[D3DDP_MAXTEXCOORD];// Size of every texture coordinate set
  1284. DWORD dwTexCoordSizeTotal; // Total size of all texture coordinates
  1285. int refCnt; /* Reference count */
  1286. D3DFE_CLIPCODE* clipCodes;
  1287. LPDIRECTDRAWSURFACE7 lpDDSVB; // DDraw Surface containing the actual VB memory
  1288. LPDIRECTDRAWSURFACE lpDDS1VB; // same dds, legacy interface for legacy hal.
  1289. BOOL bReallyOptimized; // VB could have OPTIMIZED caps set, but be
  1290. // not optimized
  1291. /*** Object Relations */
  1292. LPDIRECT3DI lpDirect3DI; /* Parent */
  1293. LIST_MEMBER(CDirect3DVertexBuffer)list; /* Next vertex buffer in IDirect3D */
  1294. // Friends
  1295. friend void hookVertexBufferToD3D(LPDIRECT3DI, LPDIRECT3DVERTEXBUFFERI);
  1296. friend class DIRECT3DDEVICEI;
  1297. friend class CDirect3DDeviceIDP2;
  1298. #ifdef VTABLE_HACK
  1299. // This points to the original (compiler generated) read-only vtable of DIRECT3DDEVICEI
  1300. PVOID* lpVtbl;
  1301. #endif // VTABLE_HACK
  1302. public:
  1303. CDirect3DVertexBuffer(LPDIRECT3DI);
  1304. ~CDirect3DVertexBuffer();
  1305. HRESULT Init(LPDIRECT3DI, LPD3DVERTEXBUFFERDESC, DWORD);
  1306. LPDIRECTDRAWSURFACE GetDDS() { return lpDDS1VB; }
  1307. HRESULT Restore() { return lpDDSVB->Restore(); }
  1308. void UnlockI();
  1309. void BreakLock();
  1310. #ifndef WIN95
  1311. HRESULT LockWorkAround(CDirect3DDeviceIDP2 *pDev);
  1312. void UnlockWorkAround();
  1313. #endif // WIN95
  1314. // IUnknown Methods
  1315. HRESULT D3DAPI QueryInterface(REFIID riid, LPVOID* ppvObj); // 0
  1316. ULONG D3DAPI AddRef(); // 1
  1317. ULONG D3DAPI Release(); // 2
  1318. // IDirect3DVertexBuffer Methods
  1319. HRESULT D3DAPI Lock(DWORD, LPVOID*, LPDWORD); // 3
  1320. HRESULT D3DAPI Unlock(); // 4
  1321. HRESULT D3DAPI ProcessVertices(DWORD, DWORD, DWORD, LPDIRECT3DVERTEXBUFFER7, DWORD, LPDIRECT3DDEVICE7, DWORD); // 5
  1322. HRESULT D3DAPI GetVertexBufferDesc(LPD3DVERTEXBUFFERDESC); // 6
  1323. HRESULT D3DAPI Optimize(LPDIRECT3DDEVICE7 lpDevI, DWORD dwFlags); // 7
  1324. HRESULT D3DAPI ProcessVerticesStrided(DWORD, DWORD, DWORD, LPD3DDRAWPRIMITIVESTRIDEDDATA, DWORD, LPDIRECT3DDEVICE7, DWORD); // 8
  1325. protected:
  1326. // Internal Lock
  1327. virtual HRESULT D3DAPI LockI(DWORD, LPVOID*, LPDWORD); // 9
  1328. #ifdef VTABLE_HACK
  1329. void VtblLockDefault()
  1330. {
  1331. // 3: IDirect3DVertexBuffer7::Lock
  1332. newVtbl[3] = lpVtbl[3];
  1333. }
  1334. void VtblLockFast()
  1335. {
  1336. // 9: CDirect3DVertexBuffer::LockI
  1337. newVtbl[3] = lpVtbl[9];
  1338. }
  1339. #endif // VTABLE_HACK
  1340. HRESULT ValidateProcessVertices(DWORD vertexOP,
  1341. DWORD dwDstIndex,
  1342. DWORD dwCount,
  1343. LPVOID lpSrc,
  1344. LPDIRECT3DDEVICE7 lpDevice,
  1345. DWORD dwFlags);
  1346. HRESULT DoProcessVertices(LPDIRECT3DVERTEXBUFFERI lpSrcI,
  1347. LPDIRECT3DDEVICEI lpDevI,
  1348. DWORD vertexOP,
  1349. DWORD dwSrcIndex,
  1350. DWORD dwDstIndex,
  1351. DWORD dwFlags);
  1352. };
  1353. // Now that LPDIRECT3DVERTEXBUFFERI is defined...
  1354. inline CDirect3DVertexBuffer* CDirect3DDeviceIDP2::TLVbuf_GetVBI()
  1355. {
  1356. return static_cast<CDirect3DVertexBuffer*>(allocatedBuf);
  1357. }
  1358. inline LPDIRECTDRAWSURFACE CDirect3DDeviceIDP2::TLVbuf_GetDDS()
  1359. {
  1360. return TLVbuf_GetVBI()->GetDDS();
  1361. }
  1362. // The instance of the class providing a guaranteed implementation
  1363. // This is defined / instantiated in pipeln\helxfrm.cpp
  1364. extern D3DFE_PVFUNCS GeometryFuncsGuaranteed;
  1365. extern void
  1366. D3DDeviceDescConvert(LPD3DDEVICEDESC7 lpOut,
  1367. LPD3DDEVICEDESC_V1 lpV1,
  1368. LPD3DHAL_D3DEXTENDEDCAPS lpExt);
  1369. #endif
  1370. // @@END_MSINTERNAL
  1371. #endif /* _D3DI_H */