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.

7427 lines
274 KiB

  1. ////////////////////////////////////////////////////////////////////////////////
  2. //
  3. // DX8SDDIFW
  4. //
  5. // Template library framework for creating a DX8 SDDI pluggable software
  6. // rasterizer.
  7. //
  8. // Two #defines supported:
  9. // DX8SDDIFW_NONAMESPACE: Don't use the DX8SDDIFW namespace. This can cause
  10. // symbols to bloat up if not needed.
  11. // DX8SDDIFW_NOCATCHALL: Don't use catch( ... ) in certain places to create
  12. // a more stable driver. There are catch( ... ) clauses in certain areas
  13. // like DP2 command processing, so that each command succeeds or fails.
  14. // However, this can cause problems debugging, as Access Violations can
  15. // be masked and caught without causing the app to freeze or even see an
  16. // error.
  17. //
  18. ////////////////////////////////////////////////////////////////////////////////
  19. #if _MSC_VER > 1000
  20. #pragma once
  21. #endif // _MSC_VER > 1000
  22. #if !defined( DX8SDDIFW_NONAMESPACE)
  23. namespace DX8SDDIFW
  24. {
  25. #endif // !defined( DX8SDDIFW_NONAMESPACE)
  26. // Since MSVC doesn't have a block type currently, include one. This
  27. // dependency can be removed if a similar type is provided in CRT STL.
  28. #include "block.h"
  29. // Utility functions for clamping a value:
  30. template< class T> inline
  31. void clamp_max( T& Var, const T& ClampMax)
  32. {
  33. if( Var> ClampMax)
  34. Var= ClampMax;
  35. }
  36. template< class T> inline
  37. void clamp_min( T& Var, const T& ClampMin)
  38. {
  39. if( Var< ClampMin)
  40. Var= ClampMin;
  41. }
  42. template< class T> inline
  43. void clamp( T& Var, const T& ClampMin, const T& ClampMax)
  44. {
  45. assert( ClampMax>= ClampMin);
  46. if( Var> ClampMax)
  47. Var= ClampMax;
  48. else if( Var< ClampMin)
  49. Var= ClampMin;
  50. }
  51. ////////////////////////////////////////////////////////////////////////////////
  52. //
  53. // CPushValue
  54. //
  55. // This class creates a safe run-time stack which pushes a value upon
  56. // construction and pops the value upon destruction.
  57. //
  58. ////////////////////////////////////////////////////////////////////////////////
  59. template< class T>
  60. struct CPushValue
  61. {
  62. protected: // Variables
  63. T& m_Val;
  64. T m_OldVal;
  65. public: // Functions
  66. CPushValue( T& Val, const T& NewVal) : m_Val( Val)
  67. {
  68. m_OldVal= Val;
  69. Val= NewVal;
  70. }
  71. ~CPushValue()
  72. {
  73. m_Val= m_OldVal;
  74. }
  75. };
  76. ////////////////////////////////////////////////////////////////////////////////
  77. //
  78. // COSDetector
  79. //
  80. // This class can detect whether the host OS is the Win9X code base or the WinNT
  81. // code base. The difference is important, because driver structures differ
  82. // depending on which OS the rasterizer runs on. We don't want to build 2 lib
  83. // versions, thus requiring the app to link with both.
  84. //
  85. ////////////////////////////////////////////////////////////////////////////////
  86. class COSDetector
  87. {
  88. public: // Types
  89. enum EOS
  90. {
  91. Unknown,
  92. Win9X,
  93. WinNT
  94. };
  95. protected: // Variables
  96. const EOS m_eOS;
  97. protected: // Functions
  98. static EOS DetermineOS()
  99. {
  100. OSVERSIONINFO osvi;
  101. ZeroMemory( &osvi, sizeof( osvi));
  102. osvi.dwOSVersionInfoSize= sizeof( osvi);
  103. if( !GetVersionEx( &osvi))
  104. {
  105. const bool Unsupported_OS_probably_Win31( false);
  106. assert( Unsupported_OS_probably_Win31);
  107. return EOS::Unknown;
  108. }
  109. else if( VER_PLATFORM_WIN32_WINDOWS== osvi.dwPlatformId)
  110. return EOS::Win9X;
  111. else if( VER_PLATFORM_WIN32_NT== osvi.dwPlatformId)
  112. return EOS::WinNT;
  113. else
  114. {
  115. const bool Unsupported_OS( false);
  116. assert( Unsupported_OS);
  117. return EOS::Unknown;
  118. }
  119. }
  120. public: // Functions
  121. COSDetector():
  122. m_eOS( DetermineOS())
  123. { }
  124. ~COSDetector()
  125. { }
  126. EOS GetOS() const
  127. { return m_eOS; }
  128. };
  129. extern COSDetector g_OSDetector;
  130. ////////////////////////////////////////////////////////////////////////////////
  131. //
  132. // DDRAWI_XXX redefinitions
  133. //
  134. // Some DDRAWI_XXX structures differ depending on whether the binary is being
  135. // compiled for Win9X or WinNT. We'll eliminate this difference, but to do so
  136. // both OS structures need to be seperately defined. The structure which causes
  137. // this is DDRAWI_DDRAWSURFACE_MORE. But for safety, more redefinition is done,
  138. // to try to make developers aware of what's going on.
  139. //
  140. ////////////////////////////////////////////////////////////////////////////////
  141. class PORTABLE_DDRAWSURFACE_LCL;
  142. struct PORTABLE_ATTACHLIST
  143. {
  144. DWORD dwFlags;
  145. PORTABLE_ATTACHLIST* lpLink;
  146. PORTABLE_DDRAWSURFACE_LCL* lpAttached; // attached surface local obj
  147. DDRAWI_DDRAWSURFACE_INT* lpIAttached; // attached surface interface
  148. };
  149. class PORTABLE_DDRAWSURFACE_MORE;
  150. class PORTABLE_DDRAWSURFACE_LCL
  151. {
  152. private:
  153. PORTABLE_DDRAWSURFACE_MORE* m_lpSurfMore;
  154. LPDDRAWI_DDRAWSURFACE_GBL m_lpGbl;
  155. ULONG_PTR m_hDDSurface;
  156. PORTABLE_ATTACHLIST* m_lpAttachList;
  157. PORTABLE_ATTACHLIST* m_lpAttachListFrom;
  158. DWORD m_dwLocalRefCnt;
  159. DWORD m_dwProcessId;
  160. DWORD m_dwFlags;
  161. DDSCAPS m_ddsCaps;
  162. union {
  163. LPDDRAWI_DDRAWPALETTE_INT m_lpDDPalette;
  164. LPDDRAWI_DDRAWPALETTE_INT m_lp16DDPalette;
  165. };
  166. union {
  167. LPDDRAWI_DDRAWCLIPPER_LCL m_lpDDClipper;
  168. LPDDRAWI_DDRAWCLIPPER_INT m_lp16DDClipper;
  169. };
  170. DWORD m_dwModeCreatedIn;
  171. DWORD m_dwBackBufferCount;
  172. DDCOLORKEY m_ddckCKDestBlt;
  173. DDCOLORKEY m_ddckCKSrcBlt;
  174. ULONG_PTR m_hDC;
  175. ULONG_PTR m_dwReserved1;
  176. DDCOLORKEY m_ddckCKSrcOverlay;
  177. DDCOLORKEY m_ddckCKDestOverlay;
  178. LPDDRAWI_DDRAWSURFACE_INT m_lpSurfaceOverlaying;
  179. DBLNODE m_dbnOverlayNode;
  180. RECT m_rcOverlaySrc;
  181. RECT m_rcOverlayDest;
  182. DWORD m_dwClrXparent;
  183. DWORD m_dwAlpha;
  184. LONG m_lOverlayX;
  185. LONG m_lOverlayY;
  186. public:
  187. PORTABLE_DDRAWSURFACE_MORE*& lpSurfMore()
  188. { return m_lpSurfMore; }
  189. LPDDRAWI_DDRAWSURFACE_GBL& lpGbl()
  190. { return m_lpGbl; }
  191. ULONG_PTR& hDDSurface()
  192. { return m_hDDSurface; }
  193. PORTABLE_ATTACHLIST*& lpAttachList()
  194. { return m_lpAttachList; }
  195. PORTABLE_ATTACHLIST*& lpAttachListFrom()
  196. { return m_lpAttachListFrom; }
  197. DWORD& dwLocalRefCnt()
  198. { return m_dwLocalRefCnt; }
  199. DWORD& dwProcessId()
  200. { return m_dwProcessId; }
  201. DWORD& dwFlags()
  202. { return m_dwFlags; }
  203. DDSCAPS& ddsCaps()
  204. { return m_ddsCaps; }
  205. LPDDRAWI_DDRAWPALETTE_INT& lpDDPalette()
  206. { return m_lpDDPalette; }
  207. LPDDRAWI_DDRAWPALETTE_INT& lp16DDPalette()
  208. { return m_lp16DDPalette; }
  209. LPDDRAWI_DDRAWCLIPPER_LCL& lpDDClipper()
  210. { return m_lpDDClipper; }
  211. LPDDRAWI_DDRAWCLIPPER_INT& lp16DDClipper()
  212. { return m_lp16DDClipper; }
  213. DWORD& dwModeCreatedIn()
  214. { return m_dwModeCreatedIn; }
  215. DWORD& dwBackBufferCount()
  216. { return m_dwBackBufferCount; }
  217. DDCOLORKEY& ddckCKDestBlt()
  218. { return m_ddckCKDestBlt; }
  219. DDCOLORKEY& ddckCKSrcBlt()
  220. { return m_ddckCKSrcBlt; }
  221. ULONG_PTR& hDC()
  222. { return m_hDC; }
  223. ULONG_PTR& dwReserved1()
  224. { return m_dwReserved1; }
  225. DDCOLORKEY& ddckCKSrcOverlay()
  226. { return m_ddckCKSrcOverlay; }
  227. DDCOLORKEY& ddckCKDestOverlay()
  228. { return m_ddckCKDestOverlay; }
  229. LPDDRAWI_DDRAWSURFACE_INT& lpSurfaceOverlaying()
  230. { return m_lpSurfaceOverlaying; }
  231. DBLNODE& dbnOverlayNode()
  232. { return m_dbnOverlayNode; }
  233. RECT& rcOverlaySrc()
  234. { return m_rcOverlaySrc; }
  235. RECT& rcOverlayDest()
  236. { return m_rcOverlayDest; }
  237. DWORD& dwClrXparent()
  238. { return m_dwClrXparent; }
  239. DWORD& dwAlpha()
  240. { return m_dwAlpha; }
  241. LONG& lOverlayX()
  242. { return m_lOverlayX; }
  243. LONG& lOverlayY()
  244. { return m_lOverlayY; }
  245. };
  246. class PORTABLE_DDRAWSURFACE_MORE
  247. {
  248. public:
  249. struct DDRAWI_DDRAWSURFACE_MORE_WIN9X
  250. {
  251. DWORD dwSize;
  252. IUNKNOWN_LIST FAR * lpIUnknowns;
  253. LPDDRAWI_DIRECTDRAW_LCL lpDD_lcl;
  254. DWORD dwPageLockCount;
  255. DWORD dwBytesAllocated;
  256. LPDDRAWI_DIRECTDRAW_INT lpDD_int;
  257. DWORD dwMipMapCount;
  258. LPDDRAWI_DDRAWCLIPPER_INT lpDDIClipper;
  259. LPHEAPALIASINFO lpHeapAliasInfo;
  260. DWORD dwOverlayFlags;
  261. LPVOID rgjunc;
  262. LPDDRAWI_DDVIDEOPORT_LCL lpVideoPort;
  263. LPDDOVERLAYFX lpddOverlayFX;
  264. DDSCAPSEX ddsCapsEx;
  265. DWORD dwTextureStage;
  266. LPVOID lpDDRAWReserved;
  267. LPVOID lpDDRAWReserved2;
  268. LPVOID lpDDrawReserved3;
  269. DWORD dwDDrawReserved4;
  270. LPVOID lpDDrawReserved5;
  271. LPDWORD lpGammaRamp;
  272. LPDWORD lpOriginalGammaRamp;
  273. LPVOID lpDDrawReserved6;
  274. DWORD dwSurfaceHandle;
  275. DWORD qwDDrawReserved8[2];
  276. LPVOID lpDDrawReserved9;
  277. DWORD cSurfaces;
  278. LPDDSURFACEDESC2 pCreatedDDSurfaceDesc2;
  279. PORTABLE_DDRAWSURFACE_LCL** slist;
  280. DWORD dwFVF;
  281. LPVOID lpVB;
  282. };
  283. struct DDRAWI_DDRAWSURFACE_MORE_WINNT
  284. {
  285. DWORD dwSize;
  286. IUNKNOWN_LIST FAR * lpIUnknowns;
  287. LPDDRAWI_DIRECTDRAW_LCL lpDD_lcl;
  288. DWORD dwPageLockCount;
  289. DWORD dwBytesAllocated;
  290. LPDDRAWI_DIRECTDRAW_INT lpDD_int;
  291. DWORD dwMipMapCount;
  292. LPDDRAWI_DDRAWCLIPPER_INT lpDDIClipper;
  293. LPHEAPALIASINFO lpHeapAliasInfo;
  294. DWORD dwOverlayFlags;
  295. LPVOID rgjunc;
  296. LPDDRAWI_DDVIDEOPORT_LCL lpVideoPort;
  297. LPDDOVERLAYFX lpddOverlayFX;
  298. DDSCAPSEX ddsCapsEx;
  299. DWORD dwTextureStage;
  300. LPVOID lpDDRAWReserved;
  301. LPVOID lpDDRAWReserved2;
  302. LPVOID lpDDrawReserved3;
  303. DWORD dwDDrawReserved4;
  304. LPVOID lpDDrawReserved5;
  305. LPDWORD lpGammaRamp;
  306. LPDWORD lpOriginalGammaRamp;
  307. LPVOID lpDDrawReserved6;
  308. DISPLAYMODEINFO dmiDDrawReserved7;
  309. DWORD dwSurfaceHandle;
  310. DWORD qwDDrawReserved8[2];
  311. LPVOID lpDDrawReserved9;
  312. DWORD cSurfaces;
  313. LPDDSURFACEDESC2 pCreatedDDSurfaceDesc2;
  314. PORTABLE_DDRAWSURFACE_LCL** slist;
  315. DWORD dwFVF;
  316. LPVOID lpVB;
  317. };
  318. private:
  319. union {
  320. DDRAWI_DDRAWSURFACE_MORE_WIN9X m_Win9X;
  321. DDRAWI_DDRAWSURFACE_MORE_WINNT m_WinNT;
  322. };
  323. public:
  324. DWORD& dwSize()
  325. { return m_Win9X.dwSize; }
  326. IUNKNOWN_LIST FAR *& lpIUnknowns()
  327. { return m_Win9X.lpIUnknowns; }
  328. LPDDRAWI_DIRECTDRAW_LCL& lpDD_lcl()
  329. { return m_Win9X.lpDD_lcl; }
  330. DWORD& dwPageLockCount()
  331. { return m_Win9X.dwPageLockCount; }
  332. DWORD& dwBytesAllocated()
  333. { return m_Win9X.dwBytesAllocated; }
  334. LPDDRAWI_DIRECTDRAW_INT& lpDD_int()
  335. { return m_Win9X.lpDD_int; }
  336. DWORD& dwMipMapCount()
  337. { return m_Win9X.dwMipMapCount; }
  338. LPDDRAWI_DDRAWCLIPPER_INT& lpDDIClipper()
  339. { return m_Win9X.lpDDIClipper; }
  340. LPHEAPALIASINFO& lpHeapAliasInfo()
  341. { return m_Win9X.lpHeapAliasInfo; }
  342. DWORD& dwOverlayFlags()
  343. { return m_Win9X.dwOverlayFlags; }
  344. LPVOID& rgjunc()
  345. { return m_Win9X.rgjunc; }
  346. LPDDRAWI_DDVIDEOPORT_LCL& lpVideoPort()
  347. { return m_Win9X.lpVideoPort; }
  348. LPDDOVERLAYFX& lpddOverlayFX()
  349. { return m_Win9X.lpddOverlayFX; }
  350. DDSCAPSEX& ddsCapsEx()
  351. { return m_Win9X.ddsCapsEx; }
  352. DWORD& dwTextureStage()
  353. { return m_Win9X.dwTextureStage; }
  354. LPVOID& lpDDRAWReserved()
  355. { return m_Win9X.lpDDRAWReserved; }
  356. LPVOID& lpDDRAWReserved2()
  357. { return m_Win9X.lpDDRAWReserved2; }
  358. LPVOID& lpDDrawReserved3()
  359. { return m_Win9X.lpDDrawReserved3; }
  360. DWORD& dwDDrawReserved4()
  361. { return m_Win9X.dwDDrawReserved4; }
  362. LPVOID& lpDDrawReserved5()
  363. { return m_Win9X.lpDDrawReserved5; }
  364. LPDWORD& lpGammaRamp()
  365. { return m_Win9X.lpGammaRamp; }
  366. LPDWORD& lpOriginalGammaRamp()
  367. { return m_Win9X.lpOriginalGammaRamp; }
  368. LPVOID& lpDDrawReserved6()
  369. { return m_Win9X.lpDDrawReserved6; }
  370. DWORD& dwSurfaceHandle()
  371. { switch( g_OSDetector.GetOS()) {
  372. case( COSDetector::Win9X): return m_Win9X.dwSurfaceHandle;
  373. case( COSDetector::WinNT): return m_WinNT.dwSurfaceHandle;
  374. default: assert( 2!= 2); return m_WinNT.dwSurfaceHandle;
  375. } }
  376. DWORD& qwDDrawReserved8_0_()
  377. { switch( g_OSDetector.GetOS()) {
  378. case( COSDetector::Win9X): return m_Win9X.qwDDrawReserved8[0];
  379. case( COSDetector::WinNT): return m_WinNT.qwDDrawReserved8[0];
  380. default: assert( 2!= 2); return m_WinNT.qwDDrawReserved8[0];
  381. } }
  382. DWORD& qwDDrawReserved8_1_()
  383. { switch( g_OSDetector.GetOS()) {
  384. case( COSDetector::Win9X): return m_Win9X.qwDDrawReserved8[1];
  385. case( COSDetector::WinNT): return m_WinNT.qwDDrawReserved8[1];
  386. default: assert( 2!= 2); return m_WinNT.qwDDrawReserved8[1];
  387. } }
  388. LPVOID& lpDDrawReserved9()
  389. { switch( g_OSDetector.GetOS()) {
  390. case( COSDetector::Win9X): return m_Win9X.lpDDrawReserved9;
  391. case( COSDetector::WinNT): return m_WinNT.lpDDrawReserved9;
  392. default: assert( 2!= 2); return m_WinNT.lpDDrawReserved9;
  393. } }
  394. DWORD& cSurfaces()
  395. { switch( g_OSDetector.GetOS()) {
  396. case( COSDetector::Win9X): return m_Win9X.cSurfaces;
  397. case( COSDetector::WinNT): return m_WinNT.cSurfaces;
  398. default: assert( 2!= 2); return m_WinNT.cSurfaces;
  399. } }
  400. LPDDSURFACEDESC2& pCreatedDDSurfaceDesc2()
  401. { switch( g_OSDetector.GetOS()) {
  402. case( COSDetector::Win9X): return m_Win9X.pCreatedDDSurfaceDesc2;
  403. case( COSDetector::WinNT): return m_WinNT.pCreatedDDSurfaceDesc2;
  404. default: assert( 2!= 2); return m_WinNT.pCreatedDDSurfaceDesc2;
  405. } }
  406. PORTABLE_DDRAWSURFACE_LCL**& slist()
  407. { switch( g_OSDetector.GetOS()) {
  408. case( COSDetector::Win9X): return m_Win9X.slist;
  409. case( COSDetector::WinNT): return m_WinNT.slist;
  410. default: assert( 2!= 2); return m_WinNT.slist;
  411. } }
  412. DWORD& dwFVF()
  413. { switch( g_OSDetector.GetOS()) {
  414. case( COSDetector::Win9X): return m_Win9X.dwFVF;
  415. case( COSDetector::WinNT): return m_WinNT.dwFVF;
  416. default: assert( 2!= 2); return m_WinNT.dwFVF;
  417. } }
  418. LPVOID& lpVB()
  419. { switch( g_OSDetector.GetOS()) {
  420. case( COSDetector::Win9X): return m_Win9X.lpVB;
  421. case( COSDetector::WinNT): return m_WinNT.lpVB;
  422. default: assert( 2!= 2); return m_WinNT.lpVB;
  423. } }
  424. };
  425. class PORTABLE_CONTEXTCREATEDATA
  426. {
  427. private:
  428. union {
  429. LPDDRAWI_DIRECTDRAW_GBL m_lpDDGbl;
  430. LPDDRAWI_DIRECTDRAW_LCL m_lpDDLcl;
  431. };
  432. union {
  433. LPDIRECTDRAWSURFACE m_lpDDS;
  434. PORTABLE_DDRAWSURFACE_LCL* m_lpDDSLcl;
  435. };
  436. union {
  437. LPDIRECTDRAWSURFACE m_lpDDSZ;
  438. PORTABLE_DDRAWSURFACE_LCL* m_lpDDSZLcl;
  439. };
  440. union {
  441. DWORD m_dwPID;
  442. ULONG_PTR m_dwrstates;
  443. };
  444. ULONG_PTR m_dwhContext;
  445. HRESULT m_ddrval;
  446. public:
  447. LPDDRAWI_DIRECTDRAW_GBL& lpDDGbl()
  448. { return m_lpDDGbl; }
  449. LPDDRAWI_DIRECTDRAW_LCL& lpDDLcl()
  450. { return m_lpDDLcl; }
  451. LPDIRECTDRAWSURFACE& lpDDS()
  452. { return m_lpDDS; }
  453. PORTABLE_DDRAWSURFACE_LCL*& lpDDSLcl()
  454. { return m_lpDDSLcl; }
  455. LPDIRECTDRAWSURFACE& lpDDSZ()
  456. { return m_lpDDSZ; }
  457. PORTABLE_DDRAWSURFACE_LCL*& lpDDSZLcl()
  458. { return m_lpDDSZLcl; }
  459. DWORD& dwPID()
  460. { return m_dwPID; }
  461. ULONG_PTR& dwrstates()
  462. { return m_dwrstates; }
  463. ULONG_PTR& dwhContext()
  464. { return m_dwhContext; }
  465. HRESULT& ddrval()
  466. { return m_ddrval; }
  467. };
  468. class PORTABLE_SETRENDERTARGETDATA
  469. {
  470. private:
  471. ULONG_PTR m_dwhContext;
  472. union {
  473. LPDIRECTDRAWSURFACE m_lpDDS;
  474. PORTABLE_DDRAWSURFACE_LCL* m_lpDDSLcl;
  475. };
  476. union {
  477. LPDIRECTDRAWSURFACE m_lpDDSZ;
  478. PORTABLE_DDRAWSURFACE_LCL* m_lpDDSZLcl;
  479. };
  480. HRESULT m_ddrval;
  481. public:
  482. ULONG_PTR& dwhContext()
  483. { return m_dwhContext; }
  484. LPDIRECTDRAWSURFACE& lpDDS()
  485. { return m_lpDDS; }
  486. PORTABLE_DDRAWSURFACE_LCL*& lpDDSLcl()
  487. { return m_lpDDSLcl; }
  488. LPDIRECTDRAWSURFACE& lpDDSZ()
  489. { return m_lpDDSZ; }
  490. PORTABLE_DDRAWSURFACE_LCL*& lpDDSZLcl()
  491. { return m_lpDDSZLcl; }
  492. HRESULT& ddrval()
  493. { return m_ddrval; }
  494. };
  495. class PORTABLE_DRAWPRIMITIVES2DATA
  496. {
  497. private:
  498. ULONG_PTR m_dwhContext;
  499. DWORD m_dwFlags;
  500. DWORD m_dwVertexType;
  501. PORTABLE_DDRAWSURFACE_LCL* m_lpDDCommands;
  502. DWORD m_dwCommandOffset;
  503. DWORD m_dwCommandLength;
  504. union {
  505. PORTABLE_DDRAWSURFACE_LCL* m_lpDDVertex;
  506. LPVOID m_lpVertices;
  507. };
  508. DWORD m_dwVertexOffset;
  509. DWORD m_dwVertexLength;
  510. DWORD m_dwReqVertexBufSize;
  511. DWORD m_dwReqCommandBufSize;
  512. LPDWORD m_lpdwRStates;
  513. union {
  514. DWORD m_dwVertexSize;
  515. HRESULT m_ddrval;
  516. };
  517. DWORD m_dwErrorOffset;
  518. public:
  519. ULONG_PTR& dwhContext()
  520. { return m_dwhContext; }
  521. DWORD& dwFlags()
  522. { return m_dwFlags; }
  523. DWORD& dwVertexType()
  524. { return m_dwVertexType; }
  525. PORTABLE_DDRAWSURFACE_LCL*& lpDDCommands()
  526. { return m_lpDDCommands; }
  527. DWORD& dwCommandOffset()
  528. { return m_dwCommandOffset; }
  529. DWORD& dwCommandLength()
  530. { return m_dwCommandLength; }
  531. PORTABLE_DDRAWSURFACE_LCL*& lpDDVertex()
  532. { return m_lpDDVertex; }
  533. LPVOID& lpVertices()
  534. { return m_lpVertices; }
  535. DWORD& dwVertexOffset()
  536. { return m_dwVertexOffset; }
  537. DWORD& dwVertexLength()
  538. { return m_dwVertexLength; }
  539. DWORD& dwReqVertexBufSize()
  540. { return m_dwReqVertexBufSize; }
  541. DWORD& dwReqCommandBufSize()
  542. { return m_dwReqCommandBufSize; }
  543. LPDWORD& lpdwRStates()
  544. { return m_lpdwRStates; }
  545. DWORD& dwVertexSize()
  546. { return m_dwVertexSize; }
  547. HRESULT& ddrval()
  548. { return m_ddrval; }
  549. DWORD& dwErrorOffset()
  550. { return m_dwErrorOffset; }
  551. };
  552. class PORTABLE_CREATESURFACEEXDATA
  553. {
  554. private:
  555. DWORD m_dwFlags;
  556. LPDDRAWI_DIRECTDRAW_LCL m_lpDDLcl;
  557. PORTABLE_DDRAWSURFACE_LCL* m_lpDDSLcl;
  558. HRESULT m_ddRVal;
  559. public:
  560. DWORD& dwFlags()
  561. { return m_dwFlags; }
  562. LPDDRAWI_DIRECTDRAW_LCL& lpDDLcl()
  563. { return m_lpDDLcl; }
  564. PORTABLE_DDRAWSURFACE_LCL*& lpDDSLcl()
  565. { return m_lpDDSLcl; }
  566. HRESULT& ddRVal()
  567. { return m_ddRVal; }
  568. };
  569. class PORTABLE_CREATESURFACEDATA
  570. {
  571. private:
  572. LPDDRAWI_DIRECTDRAW_GBL m_lpDD;
  573. LPDDSURFACEDESC m_lpDDSurfaceDesc;
  574. PORTABLE_DDRAWSURFACE_LCL** m_lplpSList;
  575. DWORD m_dwSCnt;
  576. HRESULT m_ddRVal;
  577. LPDDHAL_CREATESURFACE m_CreateSurface;
  578. public:
  579. LPDDRAWI_DIRECTDRAW_GBL& lpDD()
  580. { return m_lpDD; }
  581. LPDDSURFACEDESC& lpDDSurfaceDesc()
  582. { return m_lpDDSurfaceDesc; }
  583. PORTABLE_DDRAWSURFACE_LCL**& lplpSList()
  584. { return m_lplpSList; }
  585. DWORD& dwSCnt()
  586. { return m_dwSCnt; }
  587. HRESULT& ddRVal()
  588. { return m_ddRVal; }
  589. LPDDHAL_CREATESURFACE& CreateSurface()
  590. { return m_CreateSurface; }
  591. };
  592. class PORTABLE_DESTROYSURFACEDATA
  593. {
  594. private:
  595. LPDDRAWI_DIRECTDRAW_GBL m_lpDD;
  596. PORTABLE_DDRAWSURFACE_LCL* m_lpDDSurface;
  597. HRESULT m_ddRVal;
  598. LPDDHALSURFCB_DESTROYSURFACE m_DestroySurface;
  599. public:
  600. LPDDRAWI_DIRECTDRAW_GBL& lpDD()
  601. { return m_lpDD; }
  602. PORTABLE_DDRAWSURFACE_LCL*& lpDDSurface()
  603. { return m_lpDDSurface; }
  604. HRESULT& ddRVal()
  605. { return m_ddRVal; }
  606. LPDDHALSURFCB_DESTROYSURFACE& DestroySurface()
  607. { return m_DestroySurface; }
  608. };
  609. class PORTABLE_LOCKDATA
  610. {
  611. private:
  612. LPDDRAWI_DIRECTDRAW_GBL m_lpDD;
  613. PORTABLE_DDRAWSURFACE_LCL* m_lpDDSurface;
  614. DWORD m_bHasRect;
  615. RECTL m_rArea;
  616. LPVOID m_lpSurfData;
  617. HRESULT m_ddRVal;
  618. LPDDHALSURFCB_LOCK m_Lock;
  619. DWORD m_dwFlags;
  620. public:
  621. LPDDRAWI_DIRECTDRAW_GBL& lpDD()
  622. { return m_lpDD; }
  623. PORTABLE_DDRAWSURFACE_LCL*& lpDDSurface()
  624. { return m_lpDDSurface; }
  625. DWORD& bHasRect()
  626. { return m_bHasRect; }
  627. RECTL& rArea()
  628. { return m_rArea; }
  629. LPVOID& lpSurfData()
  630. { return m_lpSurfData; }
  631. HRESULT& ddRVal()
  632. { return m_ddRVal; }
  633. LPDDHALSURFCB_LOCK& Lock()
  634. { return m_Lock; }
  635. DWORD& dwFlags()
  636. { return m_dwFlags; }
  637. };
  638. class PORTABLE_UNLOCKDATA
  639. {
  640. private:
  641. LPDDRAWI_DIRECTDRAW_GBL m_lpDD;
  642. PORTABLE_DDRAWSURFACE_LCL* m_lpDDSurface;
  643. HRESULT m_ddRVal;
  644. LPDDHALSURFCB_UNLOCK m_Unlock;
  645. public:
  646. LPDDRAWI_DIRECTDRAW_GBL& lpDD()
  647. { return m_lpDD; }
  648. PORTABLE_DDRAWSURFACE_LCL*& lpDDSurface()
  649. { return m_lpDDSurface; }
  650. HRESULT& ddRVal()
  651. { return m_ddRVal; }
  652. LPDDHALSURFCB_UNLOCK& Unlock()
  653. { return m_Unlock; }
  654. };
  655. ////////////////////////////////////////////////////////////////////////////////
  656. //
  657. // CSurfaceLocker
  658. //
  659. // This class safely locks a surface upon construction and unlocks the surface
  660. // upon destruction.
  661. //
  662. ////////////////////////////////////////////////////////////////////////////////
  663. template< class TSurfacePtr>
  664. class CSurfaceLocker
  665. {
  666. protected: // Variables
  667. TSurfacePtr m_pSurface;
  668. void* m_pSData;
  669. public: // Functions
  670. explicit CSurfaceLocker( const TSurfacePtr& S, DWORD dwLockFlags,
  671. const RECTL* pRect) : m_pSurface( S)
  672. { m_pSData= m_pSurface->Lock( dwLockFlags, pRect); }
  673. ~CSurfaceLocker()
  674. { m_pSurface->Unlock(); }
  675. void* const& GetData() const
  676. { return m_pSData; }
  677. };
  678. ////////////////////////////////////////////////////////////////////////////////
  679. //
  680. // CEnsureFPUModeForC
  681. //
  682. // This class converts the FPU mode for x86 chips back into the mode compatable
  683. // for C operations. The mode that D3D sets up for rasterizers is single
  684. // precision, for more speed. But, sometimes, the rasterizer needs to do
  685. // double operations and get double precision accuracy. This class sets up the
  686. // mode for as long as the class is in scope.
  687. //
  688. ////////////////////////////////////////////////////////////////////////////////
  689. class CEnsureFPUModeForC
  690. {
  691. protected: // Variables
  692. WORD m_wSaveFP;
  693. public:
  694. CEnsureFPUModeForC()
  695. {
  696. #if defined(_X86_)
  697. // save floating point mode and set to double precision mode
  698. // which is compatable with C/ C++
  699. WORD wTemp, wSave;
  700. __asm
  701. {
  702. fstcw wSave
  703. mov ax, wSave
  704. or ax, 0200h
  705. mov wTemp, ax
  706. fldcw wTemp
  707. }
  708. m_wSaveFP= wSave;
  709. #endif
  710. }
  711. ~CEnsureFPUModeForC()
  712. {
  713. #if defined(_X86_)
  714. WORD wSave( m_wSaveFP);
  715. __asm fldcw wSave
  716. #endif
  717. }
  718. };
  719. ////////////////////////////////////////////////////////////////////////////////
  720. //
  721. // SDP2NextCmd
  722. //
  723. // A unary_function which can return the pointer to the next
  724. // DrawPrimitive2 command in a contiguous buffer given a pointer to a valid
  725. // DrawPrimitive2 command in the same buffer, as is a common situation for
  726. // processing DrawPrimitive2 commands within the DrawPrimitive2 function call.
  727. // This class is naturally useful for DrawPrimitive2 command iterators.
  728. // It contains all the possible commands that could be encountered for a DX8SDDI
  729. // driver.
  730. //
  731. ////////////////////////////////////////////////////////////////////////////////
  732. struct SDP2NextCmd:
  733. public unary_function< const D3DHAL_DP2COMMAND*, D3DHAL_DP2COMMAND*>
  734. {
  735. // This function allows iteration from one D3DHAL_DP2COMMAND* to the next.
  736. // This operation can be optimized quite a bit if many of the more advanced
  737. // features aren't supported (as tough to process D3DDP2_OPs might not be
  738. // encountered).
  739. D3DHAL_DP2COMMAND* operator()( const D3DHAL_DP2COMMAND* pCur) const
  740. {
  741. const UINT8* pBRet= reinterpret_cast< const UINT8*>(pCur)+
  742. sizeof( D3DHAL_DP2COMMAND);
  743. switch( pCur->bCommand)
  744. {
  745. //case( D3DDP2OP_POINTS): // <DX8
  746. //case( D3DDP2OP_INDEXEDLINELIST): // <DX8
  747. //case( D3DDP2OP_INDEXEDTRIANGLELIST): // <DX8
  748. //case( D3DDP2OP_RESERVED0):
  749. case( D3DDP2OP_RENDERSTATE): // DX8 All
  750. pBRet+= sizeof( D3DHAL_DP2RENDERSTATE)* pCur->wStateCount;
  751. break;
  752. //case( D3DDP2OP_LINELIST): // <DX8
  753. //case( D3DDP2OP_LINESTRIP): // <DX8
  754. //case( D3DDP2OP_INDEXEDLINESTRIP): // <DX8
  755. //case( D3DDP2OP_TRIANGLELIST): // <DX8
  756. //case( D3DDP2OP_TRIANGLESTRIP): // <DX8
  757. //case( D3DDP2OP_INDEXEDTRIANGLESTRIP): // <DX8
  758. //case( D3DDP2OP_TRIANGLEFAN): // <DX8
  759. //case( D3DDP2OP_INDEXEDTRIANGLEFAN): // <DX8
  760. //case( D3DDP2OP_TRIANGLEFAN_IMM): // <DX8
  761. //case( D3DDP2OP_LINELIST_IMM): // <DX8
  762. case( D3DDP2OP_TEXTURESTAGESTATE): // DX8 All
  763. pBRet+= sizeof( D3DHAL_DP2TEXTURESTAGESTATE)* pCur->wStateCount;
  764. break;
  765. //case( D3DDP2OP_INDEXEDTRIANGLELIST2): // <DX8
  766. //case( D3DDP2OP_INDEXEDLINELIST2): // <DX8
  767. case( D3DDP2OP_VIEWPORTINFO): // DX8 All
  768. pBRet+= sizeof( D3DHAL_DP2VIEWPORTINFO)* pCur->wStateCount;
  769. break;
  770. case( D3DDP2OP_WINFO): // DX8 All
  771. pBRet+= sizeof( D3DHAL_DP2WINFO)* pCur->wStateCount;
  772. break;
  773. case( D3DDP2OP_SETPALETTE): // DX8 (if support palettized surf/tex)
  774. pBRet+= sizeof( D3DHAL_DP2SETPALETTE)* pCur->wStateCount;
  775. break;
  776. case( D3DDP2OP_UPDATEPALETTE): // DX8 (if support palettized surf/tex)
  777. assert( pCur->wStateCount== 1);
  778. pBRet= pBRet+ sizeof( D3DHAL_DP2UPDATEPALETTE)+
  779. reinterpret_cast< const D3DHAL_DP2UPDATEPALETTE*>(
  780. pBRet)->wNumEntries* sizeof( DWORD);
  781. break;
  782. case( D3DDP2OP_ZRANGE): // DX8 (if support TnL)
  783. pBRet+= sizeof( D3DHAL_DP2ZRANGE)* pCur->wStateCount;
  784. break;
  785. case( D3DDP2OP_SETMATERIAL): // DX8 (if support TnL)
  786. pBRet+= sizeof( D3DHAL_DP2SETMATERIAL)* pCur->wStateCount;
  787. break;
  788. case( D3DDP2OP_SETLIGHT): // DX8 (if support TnL)
  789. { WORD wStateCount( pCur->wStateCount);
  790. if( wStateCount!= 0) do
  791. {
  792. const D3DHAL_DP2SETLIGHT* pSL=
  793. reinterpret_cast< const D3DHAL_DP2SETLIGHT*>( pBRet);
  794. if( D3DHAL_SETLIGHT_DATA== pSL->dwDataType)
  795. pBRet+= sizeof( D3DLIGHT8);
  796. pBRet+= sizeof( D3DHAL_DP2SETLIGHT);
  797. } while( --wStateCount); }
  798. break;
  799. case( D3DDP2OP_CREATELIGHT): // DX8 (if support TnL)
  800. pBRet+= sizeof( D3DHAL_DP2CREATELIGHT)* pCur->wStateCount;
  801. break;
  802. case( D3DDP2OP_SETTRANSFORM): // DX8 (if support TnL)
  803. pBRet+= sizeof( D3DHAL_DP2SETTRANSFORM)* pCur->wStateCount;
  804. break;
  805. case( D3DDP2OP_EXT): // DX8 (if work seemlessly with TnL extensions)
  806. { WORD wStateCount( pCur->wStateCount);
  807. if( wStateCount!= 0) do
  808. {
  809. pBRet+= reinterpret_cast< const D3DHAL_DP2EXT*>(pBRet)->dwSize;
  810. } while( --wStateCount); }
  811. break;
  812. case( D3DDP2OP_TEXBLT): // DX8 (if support vidmem texture)
  813. pBRet+= sizeof( D3DHAL_DP2TEXBLT)* pCur->wStateCount;
  814. break;
  815. case( D3DDP2OP_STATESET): // DX8 All
  816. pBRet+= sizeof( D3DHAL_DP2STATESET)* pCur->wStateCount;
  817. break;
  818. case( D3DDP2OP_SETPRIORITY): // DX8 (if manage textures)
  819. pBRet+= sizeof( D3DHAL_DP2SETPRIORITY)* pCur->wStateCount;
  820. break;
  821. case( D3DDP2OP_SETRENDERTARGET): // DX8 All
  822. pBRet+= sizeof( D3DHAL_DP2SETRENDERTARGET)* pCur->wStateCount;
  823. break;
  824. case( D3DDP2OP_CLEAR): // DX8 All
  825. pBRet+= sizeof( D3DHAL_DP2CLEAR)- sizeof( RECT)+ sizeof( RECT)*
  826. pCur->wStateCount;
  827. break;
  828. case( D3DDP2OP_SETTEXLOD): // DX8 (if manage textures)
  829. pBRet+= sizeof( D3DHAL_DP2SETTEXLOD)* pCur->wStateCount;
  830. break;
  831. case( D3DDP2OP_SETCLIPPLANE): // DX8 (if support user clip planes)
  832. pBRet+= sizeof( D3DHAL_DP2SETCLIPPLANE)* pCur->wStateCount;
  833. break;
  834. case( D3DDP2OP_CREATEVERTEXSHADER): // DX8 (if support vshaders)
  835. { WORD wStateCount( pCur->wStateCount);
  836. if( wStateCount!= 0) do
  837. {
  838. const D3DHAL_DP2CREATEVERTEXSHADER* pCVS=
  839. reinterpret_cast< const D3DHAL_DP2CREATEVERTEXSHADER*>(
  840. pBRet);
  841. pBRet+= sizeof( D3DHAL_DP2CREATEVERTEXSHADER)+
  842. pCVS->dwDeclSize+ pCVS->dwCodeSize;
  843. } while( --wStateCount); }
  844. break;
  845. case( D3DDP2OP_DELETEVERTEXSHADER): // DX8 (if support vshaders)
  846. pBRet+= sizeof( D3DHAL_DP2VERTEXSHADER)* pCur->wStateCount;
  847. break;
  848. case( D3DDP2OP_SETVERTEXSHADER): // DX8 All
  849. pBRet+= sizeof( D3DHAL_DP2VERTEXSHADER)* pCur->wStateCount;
  850. break;
  851. case( D3DDP2OP_SETVERTEXSHADERCONST): // DX8 (if support vshaders)
  852. { WORD wStateCount( pCur->wStateCount);
  853. if( wStateCount!= 0) do
  854. {
  855. const D3DHAL_DP2SETVERTEXSHADERCONST* pSVSC=
  856. reinterpret_cast< const D3DHAL_DP2SETVERTEXSHADERCONST*>(
  857. pBRet);
  858. pBRet+= sizeof( D3DHAL_DP2SETVERTEXSHADERCONST)+
  859. 4* sizeof( D3DVALUE)* pSVSC->dwCount;
  860. } while( --wStateCount); }
  861. break;
  862. case( D3DDP2OP_SETSTREAMSOURCE): // DX8 All
  863. pBRet+= sizeof( D3DHAL_DP2SETSTREAMSOURCE)* pCur->wStateCount;
  864. break;
  865. case( D3DDP2OP_SETSTREAMSOURCEUM): // DX8 All (unless no DrawPrimUP calls)
  866. pBRet+= sizeof( D3DHAL_DP2SETSTREAMSOURCEUM)* pCur->wStateCount;
  867. break;
  868. case( D3DDP2OP_SETINDICES): // DX8 All
  869. pBRet+= sizeof( D3DHAL_DP2SETINDICES)* pCur->wStateCount;
  870. break;
  871. case( D3DDP2OP_DRAWPRIMITIVE): // DX8 All
  872. pBRet+= sizeof( D3DHAL_DP2DRAWPRIMITIVE)* pCur->wPrimitiveCount;
  873. break;
  874. case( D3DDP2OP_DRAWINDEXEDPRIMITIVE): // DX8 All
  875. pBRet+= sizeof( D3DHAL_DP2DRAWINDEXEDPRIMITIVE)*
  876. pCur->wPrimitiveCount;
  877. break;
  878. case( D3DDP2OP_CREATEPIXELSHADER): // DX8 (if support pshaders)
  879. { WORD wStateCount( pCur->wStateCount);
  880. if( wStateCount!= 0) do
  881. {
  882. const D3DHAL_DP2CREATEPIXELSHADER* pCPS=
  883. reinterpret_cast< const D3DHAL_DP2CREATEPIXELSHADER*>(
  884. pBRet);
  885. pBRet+= sizeof( D3DHAL_DP2CREATEPIXELSHADER)+
  886. pCPS->dwCodeSize;
  887. } while( --wStateCount); }
  888. break;
  889. case( D3DDP2OP_DELETEPIXELSHADER): // DX8 (if support pshaders)
  890. pBRet+= sizeof( D3DHAL_DP2PIXELSHADER)* pCur->wStateCount;
  891. break;
  892. case( D3DDP2OP_SETPIXELSHADER): // DX8 (if support pshaders)
  893. pBRet+= sizeof( D3DHAL_DP2PIXELSHADER)* pCur->wStateCount;
  894. break;
  895. case( D3DDP2OP_SETPIXELSHADERCONST): // DX8 (if support pshaders)
  896. { WORD wStateCount( pCur->wStateCount);
  897. if( wStateCount!= 0) do
  898. {
  899. const D3DHAL_DP2SETPIXELSHADERCONST* pSPSC=
  900. reinterpret_cast< const D3DHAL_DP2SETPIXELSHADERCONST*>(
  901. pBRet);
  902. pBRet+= sizeof( D3DHAL_DP2SETPIXELSHADERCONST)+
  903. 4* sizeof( D3DVALUE)* pSPSC->dwCount;
  904. } while( --wStateCount); }
  905. break;
  906. case( D3DDP2OP_CLIPPEDTRIANGLEFAN): // DX8 All
  907. pBRet+= sizeof( D3DHAL_CLIPPEDTRIANGLEFAN)* pCur->wPrimitiveCount;
  908. break;
  909. case( D3DDP2OP_DRAWPRIMITIVE2): // DX8 All
  910. pBRet+= sizeof( D3DHAL_DP2DRAWPRIMITIVE2)* pCur->wPrimitiveCount;
  911. break;
  912. case( D3DDP2OP_DRAWINDEXEDPRIMITIVE2): // DX8 All
  913. pBRet+= sizeof( D3DHAL_DP2DRAWINDEXEDPRIMITIVE2)*
  914. pCur->wPrimitiveCount;
  915. break;
  916. case( D3DDP2OP_DRAWRECTPATCH): // DX8 (if support higher order prims)
  917. { WORD wPrimitiveCount( pCur->wPrimitiveCount);
  918. if( wPrimitiveCount!= 0) do
  919. {
  920. const D3DHAL_DP2DRAWRECTPATCH* pDRP=
  921. reinterpret_cast< const D3DHAL_DP2DRAWRECTPATCH*>(pBRet);
  922. pBRet+= sizeof( D3DHAL_DP2DRAWRECTPATCH);
  923. if((pDRP->Flags& RTPATCHFLAG_HASSEGS)!= 0)
  924. pBRet+= 4* sizeof( D3DVALUE);
  925. if((pDRP->Flags& RTPATCHFLAG_HASINFO)!= 0)
  926. pBRet+= sizeof( D3DRECTPATCH_INFO);
  927. } while( --wPrimitiveCount); }
  928. break;
  929. case( D3DDP2OP_DRAWTRIPATCH): // DX8 (if support higher order prims)
  930. { WORD wPrimitiveCount( pCur->wPrimitiveCount);
  931. if( wPrimitiveCount!= 0) do
  932. {
  933. const D3DHAL_DP2DRAWTRIPATCH* pDTP=
  934. reinterpret_cast< const D3DHAL_DP2DRAWTRIPATCH*>(pBRet);
  935. pBRet+= sizeof( D3DHAL_DP2DRAWTRIPATCH);
  936. if((pDTP->Flags& RTPATCHFLAG_HASSEGS)!= 0)
  937. pBRet+= 3* sizeof( D3DVALUE);
  938. if((pDTP->Flags& RTPATCHFLAG_HASINFO)!= 0)
  939. pBRet+= sizeof( D3DTRIPATCH_INFO);
  940. } while( --wPrimitiveCount); }
  941. break;
  942. case( D3DDP2OP_VOLUMEBLT): // DX8 (if support vidmem volume texture)
  943. pBRet+= sizeof( D3DHAL_DP2VOLUMEBLT)* pCur->wStateCount;
  944. break;
  945. case( D3DDP2OP_BUFFERBLT): // DX8 (if support vidmem vrtx/indx buffer)
  946. pBRet+= sizeof( D3DHAL_DP2BUFFERBLT)* pCur->wStateCount;
  947. break;
  948. case( D3DDP2OP_MULTIPLYTRANSFORM): // DX8 (if support TnL)
  949. pBRet+= sizeof( D3DHAL_DP2MULTIPLYTRANSFORM)* pCur->wStateCount;
  950. break;
  951. default: {
  952. const bool Unable_To_Parse_Unrecognized_D3DDP2OP( false);
  953. assert( Unable_To_Parse_Unrecognized_D3DDP2OP);
  954. } break;
  955. }
  956. return const_cast<D3DHAL_DP2COMMAND*>
  957. (reinterpret_cast<const D3DHAL_DP2COMMAND*>(pBRet));
  958. }
  959. };
  960. ////////////////////////////////////////////////////////////////////////////////
  961. //
  962. // CDP2CmdIterator & CDP2ConstCmdIterator
  963. //
  964. // These iterators are provided as a convenience to iterate DrawPrimitive2
  965. // commands which are packed in a contiguous chunk of memory, as is typical
  966. // of execute/ command buffers which need to be processed within the
  967. // DrawPrimitive2 function call. The actual iteration logic is encapsulated in
  968. // the template parameter, so that it can be easily extended, if certain
  969. // commands aren't exepected and a better iteration scheme could be used.
  970. //
  971. // Be careful, these iterators are only useful for iterating. They do not
  972. // directly know the size of the data they point to. For completeness, which
  973. // would allow seperate storage of commands, another class would need to be
  974. // created and assigned as the value_type. Dereferencing the iterator only
  975. // returns a D3DHAL_DP2COMMAND without any extra data. Something like:
  976. //
  977. // CDP2Cmd DP2Cmd= *itDP2Cmd;
  978. //
  979. // is possible; but requires more work and definition of CDP2Cmd.
  980. //
  981. ////////////////////////////////////////////////////////////////////////////////
  982. template< class TNextCmd= SDP2NextCmd>
  983. class CDP2CmdIterator
  984. {
  985. public: // Types
  986. typedef forward_iterator_tag iterator_category;
  987. typedef D3DHAL_DP2COMMAND value_type;
  988. typedef ptrdiff_t difference_type;
  989. typedef D3DHAL_DP2COMMAND* pointer;
  990. typedef D3DHAL_DP2COMMAND& reference;
  991. protected: // Variables
  992. pointer m_pRawCmd;
  993. TNextCmd m_NextCmd;
  994. public: // Functions
  995. CDP2CmdIterator( pointer pRaw= NULL)
  996. :m_pRawCmd( pRaw) { }
  997. CDP2CmdIterator( pointer pRaw, const TNextCmd& NextCmd)
  998. :m_NextCmd( NextCmd), m_pRawCmd( pRaw) { }
  999. CDP2CmdIterator( const CDP2CmdIterator< TNextCmd>& Other)
  1000. :m_NextCmd( Other.m_NextCmd), m_pRawCmd( Other.m_pRawCmd) { }
  1001. reference operator*() const
  1002. { return *m_pRawCmd; }
  1003. pointer operator->() const
  1004. { return m_pRawCmd; }
  1005. operator pointer() const
  1006. { return m_pRawCmd; }
  1007. CDP2CmdIterator< TNextCmd>& operator++()
  1008. { m_pRawCmd= m_NextCmd( m_pRawCmd); return *this; }
  1009. CDP2CmdIterator< TNextCmd> operator++(int)
  1010. {
  1011. CDP2CmdIterator< TNextCmd> tmp= *this;
  1012. m_pRawCmd= m_NextCmd( m_pRawCmd);
  1013. return tmp;
  1014. }
  1015. bool operator==( CDP2CmdIterator< TNextCmd>& x) const
  1016. { return m_pRawCmd== x.m_pRawCmd; }
  1017. bool operator!=( CDP2CmdIterator< TNextCmd>& x) const
  1018. { return m_pRawCmd!= x.m_pRawCmd; }
  1019. };
  1020. template< class TNextCmd= SDP2NextCmd>
  1021. class CConstDP2CmdIterator
  1022. {
  1023. public: // Types
  1024. typedef forward_iterator_tag iterator_category;
  1025. typedef const D3DHAL_DP2COMMAND value_type;
  1026. typedef ptrdiff_t difference_type;
  1027. typedef const D3DHAL_DP2COMMAND* pointer;
  1028. typedef const D3DHAL_DP2COMMAND& reference;
  1029. protected: // Variables
  1030. pointer m_pRawCmd;
  1031. TNextCmd m_NextCmd;
  1032. public: // Functions
  1033. CConstDP2CmdIterator( pointer pRaw= NULL)
  1034. :m_pRawCmd( pRaw) { }
  1035. CConstDP2CmdIterator( pointer pRaw, const TNextCmd& NextCmd)
  1036. :m_NextCmd( NextCmd), m_pRawCmd( pRaw) { }
  1037. CConstDP2CmdIterator( const CDP2CmdIterator< TNextCmd>& Other)
  1038. :m_NextCmd( Other.m_NextCmd), m_pRawCmd( Other.m_pRawCmd) { }
  1039. CConstDP2CmdIterator( const CConstDP2CmdIterator< TNextCmd>& Other)
  1040. :m_NextCmd( Other.m_NextCmd), m_pRawCmd( Other.m_pRawCmd) { }
  1041. reference operator*() const
  1042. { return *m_pRawCmd; }
  1043. pointer operator->() const
  1044. { return m_pRawCmd; }
  1045. operator pointer() const
  1046. { return m_pRawCmd; }
  1047. CConstDP2CmdIterator< TNextCmd>& operator++()
  1048. { m_pRawCmd= m_NextCmd( m_pRawCmd); return *this; }
  1049. CConstDP2CmdIterator< TNextCmd> operator++(int)
  1050. {
  1051. CConstDP2CmdIterator< TNextCmd> tmp= *this;
  1052. m_pRawCmd= m_NextCmd( m_pRawCmd);
  1053. return tmp;
  1054. }
  1055. bool operator==( CConstDP2CmdIterator< TNextCmd>& x) const
  1056. { return m_pRawCmd== x.m_pRawCmd; }
  1057. bool operator!=( CConstDP2CmdIterator< TNextCmd>& x) const
  1058. { return m_pRawCmd!= x.m_pRawCmd; }
  1059. };
  1060. ////////////////////////////////////////////////////////////////////////////////
  1061. //
  1062. // CDP2DataWrap
  1063. //
  1064. // This class is provided as a convenience to expose the
  1065. // PORTABLE_DRAWPRIMITIVES2DATA as a more friendly class. Mostly, it wraps the
  1066. // execute/ command buffer with an STL Sequence Container, so that the commands
  1067. // can be iterated over without copying and pre-parsing the command data.
  1068. //
  1069. // <Template Parameters>
  1070. // TNextCmd: a unary_function which takes a const D3DHAL_DP2COMMAND* in and
  1071. // returns a D3DHAL_DP2COMMAND* which points to the next command. In
  1072. // essence, a unary_function which enables a forward iterator on a
  1073. // contiguous command buffer.
  1074. //
  1075. // <Exposed Types>
  1076. // TCmds: The Sequence Container type which exposed the commands.
  1077. //
  1078. // <Exposed Functions>
  1079. // CDP2DataWrap( PORTABLE_DRAWPRIMITIVES2DATA& DP2Data): Constructor to wrap the
  1080. // PORTABLE_DRAWPRIMITIVES2DATA.
  1081. // const TCmds& GetCommands() const: Accessor function to get at the Sequence
  1082. // Container.
  1083. //
  1084. ////////////////////////////////////////////////////////////////////////////////
  1085. template< class TNextCmd= SDP2NextCmd>
  1086. class CDP2DataWrap:
  1087. public PORTABLE_DRAWPRIMITIVES2DATA
  1088. {
  1089. public: // Types
  1090. class CDP2Cmds
  1091. {
  1092. public: // Types
  1093. typedef CConstDP2CmdIterator< TNextCmd> const_iterator;
  1094. typedef typename const_iterator::value_type value_type;
  1095. typedef typename const_iterator::reference const_reference;
  1096. typedef typename const_iterator::pointer const_pointer;
  1097. typedef typename const_iterator::difference_type difference_type;
  1098. typedef size_t size_type;
  1099. protected: // Variables
  1100. CDP2DataWrap< TNextCmd>* m_pDP2Data;
  1101. protected: // Functions
  1102. // Allow to call constructor and set member variable.
  1103. friend class CDP2DataWrap< TNextCmd>;
  1104. CDP2Cmds( )
  1105. :m_pDP2Data( NULL) { }
  1106. public: // Functions
  1107. const_iterator begin( void) const
  1108. {
  1109. return const_iterator( reinterpret_cast<D3DHAL_DP2COMMAND*>(
  1110. reinterpret_cast<UINT8*>(m_pDP2Data->lpDDCommands()->lpGbl()->fpVidMem)
  1111. + m_pDP2Data->dwCommandOffset()));
  1112. }
  1113. const_iterator end( void) const
  1114. {
  1115. return const_iterator( reinterpret_cast<D3DHAL_DP2COMMAND*>(
  1116. reinterpret_cast<UINT8*>(m_pDP2Data->lpDDCommands()->lpGbl()->fpVidMem)
  1117. + m_pDP2Data->dwCommandOffset()+ m_pDP2Data->dwCommandLength()));
  1118. }
  1119. size_type size( void) const
  1120. {
  1121. size_type N( 0);
  1122. const_iterator itS( begin());
  1123. const_iterator itE( end());
  1124. while( itS!= itE)
  1125. { ++itS; ++N; }
  1126. return N;
  1127. }
  1128. size_type max_size( void) const
  1129. { return size(); }
  1130. bool empty( void) const
  1131. { return begin()== end(); }
  1132. };
  1133. typedef CDP2Cmds TCmds;
  1134. protected: // Variables
  1135. TCmds m_Cmds;
  1136. public: // Functions
  1137. explicit CDP2DataWrap( PORTABLE_DRAWPRIMITIVES2DATA& DP2Data)
  1138. : PORTABLE_DRAWPRIMITIVES2DATA( DP2Data)
  1139. { m_Cmds.m_pDP2Data= this; }
  1140. const TCmds& GetCommands( void) const
  1141. { return m_Cmds; }
  1142. };
  1143. ////////////////////////////////////////////////////////////////////////////////
  1144. //
  1145. // SDP2MFnParser
  1146. //
  1147. // This class is a functional class, with many too many paramters to squeeze
  1148. // into the standard functional classes. It automates the parsing, member fn
  1149. // lookup, and dispatching for DrawPrimitive2 commands. This parser uses the
  1150. // command number to lookup a member function from a container to call.
  1151. //
  1152. ////////////////////////////////////////////////////////////////////////////////
  1153. struct SDP2MFnParser
  1154. {
  1155. // <Parameters>
  1156. // MFnCaller: A binary_function type with TDP2CmdFnCtr::value_type,
  1157. // typically a member function pointer, as the first argument;
  1158. // TIter, typically a smart DP2 command iterator, as the second
  1159. // argument; and returns an HRESULT. This function type should call
  1160. // the member function to process the DP2 command, with the iterator
  1161. // used to determine the DP2 Cmd data.
  1162. // DP2CmdFnCtr: This can be any Unique, Pair Associative Container,
  1163. // typically a map, which associates a D3DHAL_DP2OPERATION with a
  1164. // member function.
  1165. // [itStart, itEnd): These iterators define a standard range of
  1166. // D3DHAL_DP2COMMAND. The iterators need only be forward iterators,
  1167. // and be convertable to raw D3DHAL_DP2COMMAND*. Note: itStart is
  1168. // a reference, so that the caller can determine the current iterator
  1169. // position upon return of function (when HRESULT!= DD_OK).
  1170. template< class TMFnCaller, class TDP2CmdFnCtr, class TIter>
  1171. HRESULT ParseDP2( TMFnCaller& MFnCaller, TDP2CmdFnCtr& DP2CmdFnCtr,
  1172. TIter& itStart, TIter itEnd) const
  1173. {
  1174. HRESULT hr( DD_OK);
  1175. while( itStart!= itEnd)
  1176. {
  1177. try
  1178. {
  1179. hr= MFnCaller( DP2CmdFnCtr[ itStart->bCommand], itStart);
  1180. } catch( HRESULT hrEx) {
  1181. hr= hrEx;
  1182. #if !defined( DX8SDDIFW_NOCATCHALL)
  1183. } catch ( ... ) {
  1184. const bool Unrecognized_Exception_In_A_DP2_Op_Function( false);
  1185. assert( Unrecognized_Exception_In_A_DP2_Op_Function);
  1186. hr= E_UNEXPECTED;
  1187. #endif // !defined( DX8SDDIFW_NOCATCHALL)
  1188. }
  1189. // Only move on to next command if DD_OK. Otherwise return out
  1190. // to caller. They can always call us back if caller determines
  1191. // error code is a SUCCESS.
  1192. if( DD_OK== hr)
  1193. ++itStart;
  1194. else
  1195. break;
  1196. }
  1197. return hr;
  1198. }
  1199. };
  1200. ////////////////////////////////////////////////////////////////////////////////
  1201. //
  1202. // CSubStateSet & CMinimalStateSet
  1203. //
  1204. // This class contains a default implementation of a stateset. It copies/ packs
  1205. // a contiguous DP2 command buffer into a memory buffer. To capture, it asks
  1206. // the context to record the command buffer with the Context's current state.
  1207. // To execute, it fixes up a Fake DrawPrimitives2 point parameter
  1208. // and calls the context's DrawPrimitives2 entry point. The context
  1209. // needs to be able to handle recursive DrawPrimitives2 calls in order to use
  1210. // this default stateset. CStdDrawPrimitives2's DrawPrimitives2 handler
  1211. // does this by storing whether it is executing a stateset.
  1212. //
  1213. // <Template Parameters>
  1214. // TSuper: Standard parent type which is inheriting from this child class.
  1215. // In this case, it should typically be the CMyStateSet type.
  1216. // TC: The Context type, typically, CMyContext.
  1217. //
  1218. // <Exposed Types>
  1219. // TContext: The Context type passed in as a template parameter.
  1220. //
  1221. // <Exposed Functions>
  1222. // CSubStateSet( TContext&, const D3DHAL_DP2COMMAND*, const D3DHAL_DP2COMMAND*):
  1223. // The constructor which builds a stateset for a Context, from a range of
  1224. // a command buffer. The default implementation will just copy this range.
  1225. // CSubStateSet( const CSubStateSet& Other): Standard copy constructor.
  1226. // void Capture( TContext&): The state set is instructed to capture the
  1227. // necessary data from the Context, in order to perform an Execute later,
  1228. // which will restore the data fields or state that the state set was
  1229. // constructed with.
  1230. // void Execute( TContext&): Restore or rebuild the Context with the data/
  1231. // state that was saved during the Capture operation.
  1232. //
  1233. ////////////////////////////////////////////////////////////////////////////////
  1234. template< class TSuper, class TC>
  1235. class CSubStateSet
  1236. {
  1237. public: // Types
  1238. typedef TC TContext;
  1239. protected: // Variables
  1240. TContext& m_Context;
  1241. D3DHAL_DP2COMMAND* m_pBeginSS;
  1242. size_t m_uiSSBufferSize;
  1243. protected: // Functions
  1244. CSubStateSet( const CSubStateSet< TSuper, TC>& Other)
  1245. :m_Context( Other.m_Context), m_pBeginSS( NULL),
  1246. m_uiSSBufferSize( Other.m_uiSSBufferSize)
  1247. {
  1248. try {
  1249. m_pBeginSS= reinterpret_cast< D3DHAL_DP2COMMAND*>(
  1250. operator new( m_uiSSBufferSize));
  1251. } catch( ... ) {
  1252. }
  1253. if( NULL== m_pBeginSS)
  1254. throw bad_alloc( "Not enough room to copy state set command "
  1255. "buffer.");
  1256. memcpy( m_pBeginSS, Other.m_pBeginSS, m_uiSSBufferSize);
  1257. }
  1258. CSubStateSet( TContext& C, const D3DHAL_DP2COMMAND* pBeginSS, const
  1259. D3DHAL_DP2COMMAND* pEndSS) : m_Context( C), m_pBeginSS( NULL),
  1260. m_uiSSBufferSize( 0)
  1261. {
  1262. // Convert the contiguous command pointers to byte pointers, to
  1263. // calculate the size of buffer needed to copy the data.
  1264. const UINT8* pSBytePtr= reinterpret_cast< const UINT8*>( pBeginSS);
  1265. const UINT8* pEBytePtr= reinterpret_cast< const UINT8*>( pEndSS);
  1266. m_uiSSBufferSize= static_cast< size_t>( pEBytePtr- pSBytePtr);
  1267. try {
  1268. m_pBeginSS= reinterpret_cast< D3DHAL_DP2COMMAND*>(
  1269. operator new( m_uiSSBufferSize));
  1270. } catch( ... ) {
  1271. }
  1272. if( NULL== m_pBeginSS)
  1273. throw bad_alloc( "Not enough room to allocate state set command "
  1274. "buffer.");
  1275. memcpy( m_pBeginSS, pBeginSS, m_uiSSBufferSize);
  1276. }
  1277. ~CSubStateSet()
  1278. {
  1279. operator delete( static_cast< void*>( m_pBeginSS));
  1280. }
  1281. public: // Functions
  1282. CSubStateSet< TSuper, TC>& operator=( const CSubStateSet< TSuper, TC>& Oth)
  1283. {
  1284. assert( &m_Context== &Oth.m_Context);
  1285. if( m_uiSSBufferSize<= Oth.m_uiSSBufferSize)
  1286. {
  1287. m_uiSSBufferSize= Oth.m_uiSSBufferSize;
  1288. memcpy( m_pBeginSS, Oth.m_pBeginSS, m_uiSSBufferSize);
  1289. }
  1290. else
  1291. {
  1292. void* pNewBuffer= NULL;
  1293. try {
  1294. pNewBuffer= operator new( Oth.m_uiSSBufferSize);
  1295. } catch( ... ) {
  1296. }
  1297. if( NULL== pNewBuffer)
  1298. throw bad_alloc( "Not enough room to copy state set command "
  1299. "buffer.");
  1300. operator delete( static_cast< void*>( m_pBeginSS));
  1301. m_pBeginSS= reinterpret_cast< D3DHAL_DP2COMMAND*>( pNewBuffer);
  1302. m_uiSSBufferSize= Oth.m_uiSSBufferSize;
  1303. memcpy( m_pBeginSS, Other.m_pBeginSS, m_uiSSBufferSize);
  1304. }
  1305. return *this;
  1306. }
  1307. void Capture( TContext& Ctx)
  1308. {
  1309. assert( &m_Context== &Ctx);
  1310. UINT8* pBytePtr= reinterpret_cast< UINT8*>( m_pBeginSS);
  1311. D3DHAL_DP2COMMAND* pEndSS= reinterpret_cast< D3DHAL_DP2COMMAND*>(
  1312. pBytePtr+ m_uiSSBufferSize);
  1313. // Ask Context to record it's current state into the stored command
  1314. // buffer. CStdDrawPrimitives2 can provide an implementation of
  1315. // RecordCommandBuffer for the Context.
  1316. Ctx.RecordCommandBuffer( m_pBeginSS, pEndSS);
  1317. }
  1318. void Execute( TContext& Ctx)
  1319. {
  1320. assert( &m_Context== &Ctx);
  1321. // Build up a fake PORTABLE_DRAWPRIMITIVES2DATA environment.
  1322. PORTABLE_DDRAWSURFACE_LCL DDSLcl;
  1323. PORTABLE_DDRAWSURFACE_MORE DDSMore;
  1324. DDRAWI_DDRAWSURFACE_GBL DDSGbl;
  1325. memset( &DDSLcl, 0, sizeof( DDSLcl));
  1326. memset( &DDSMore, 0, sizeof( DDSMore));
  1327. memset( &DDSGbl, 0, sizeof( DDSGbl));
  1328. PORTABLE_DRAWPRIMITIVES2DATA FakeDPD;
  1329. FakeDPD.dwhContext()= reinterpret_cast< ULONG_PTR>( &Ctx);
  1330. FakeDPD.dwFlags()= D3DHALDP2_USERMEMVERTICES;
  1331. FakeDPD.dwVertexType()= 0;
  1332. FakeDPD.lpDDCommands()= &DDSLcl;
  1333. FakeDPD.dwCommandOffset()= 0;
  1334. FakeDPD.dwCommandLength()= m_uiSSBufferSize;
  1335. FakeDPD.lpVertices()= NULL;
  1336. FakeDPD.dwVertexOffset()= 0;
  1337. FakeDPD.dwVertexLength()= 0;
  1338. FakeDPD.dwReqVertexBufSize()= 0;
  1339. FakeDPD.dwReqCommandBufSize()= 0;
  1340. FakeDPD.lpdwRStates()= NULL;
  1341. FakeDPD.dwVertexSize()= 0;
  1342. // If the data is not 0, then a union can't be used, as we're
  1343. // writing over valid data.
  1344. DDSLcl.lpGbl()= &DDSGbl;
  1345. DDSLcl.ddsCaps().dwCaps= DDSCAPS2_COMMANDBUFFER| DDSCAPS_SYSTEMMEMORY;
  1346. DDSLcl.lpSurfMore()= &DDSMore;
  1347. DDSGbl.fpVidMem= reinterpret_cast<FLATPTR>( m_pBeginSS);
  1348. // Now call Context's DrawPrimitives2 entry point. CStdDrawPrimitives2
  1349. // can provide an implementation of DrawPrimitives2 for the Context.
  1350. HRESULT hr( Ctx.DrawPrimitives2( FakeDPD));
  1351. assert( SUCCEEDED( hr));
  1352. }
  1353. };
  1354. //
  1355. // <Template Parameters>
  1356. // TC: The Context type, typically, CMyContext.
  1357. //
  1358. template< class TC>
  1359. class CMinimalStateSet: public CSubStateSet< CMinimalStateSet, TC>
  1360. {
  1361. public: // Types
  1362. typedef TC TContext;
  1363. public: // Functions
  1364. CMinimalStateSet( const CMinimalStateSet< TC>& Other)
  1365. :CSubStateSet< CMinimalStateSet, TC>( Other)
  1366. { }
  1367. CMinimalStateSet( TContext& C, const D3DHAL_DP2COMMAND* pBeginSS, const
  1368. D3DHAL_DP2COMMAND* pEndSS) :
  1369. CSubStateSet< CMinimalStateSet, TC>( C, pBeginSS, pEndSS) { }
  1370. ~CMinimalStateSet() { }
  1371. };
  1372. ////////////////////////////////////////////////////////////////////////////////
  1373. //
  1374. // CStdDrawPrimitives2
  1375. //
  1376. // This class contains a default implementation of responding to the
  1377. // DrawPrimitives2 function call, as well as a function to record state back
  1378. // into a command buffer. Upon constuction, it will use the provided ranges
  1379. // to bind DP2 operations to both processing and recording member functions.
  1380. // In order to process the DrawPrimitives2 function call, it must wrap the
  1381. // PORTABLE_DRAWPRIMITIVES2DATA with a convience type which allows commands to
  1382. // be walked through with iterators. It will then use the DP2MFnParser to
  1383. // parse the DP2 commands and call the member functions.
  1384. //
  1385. // This class also provides a member function for processing the DP2 StateSet
  1386. // operation, and uses it to build up, manage, and execute state sets. In
  1387. // order to handle pure device state sets, it creates the appropriate command
  1388. // buffer for the Device (based off of caps), constructs a new state set
  1389. // on this command buffer, and asks the state set to Capture the current state.
  1390. //
  1391. // <Template Parameters>
  1392. // TSuper: Standard parent type which is inheriting from this child class.
  1393. // In this case, it should typically be the CMyContext type.
  1394. // TSS: The StateSet type, typically, CMyStateSet or CMinimalStateSet. The
  1395. // StateSet class should be able to be constructed from a command buffer,
  1396. // and then be able to Capture and Execute.
  1397. // TSSDB: This can be any Unique, Pair Associative Container, typically a map,
  1398. // which associates a DWORD state set handle to a StateSet type.
  1399. // TDP2D: This is some kind of wrapper class for PORTABLE_DRAWPRIMITIVES2DATA.
  1400. // The type is expected to inherit or emulate PORTABLE_DRAWPRIMITIVES2DATA's
  1401. // fields/ member variables, along with exposing an STL conforming
  1402. // container which provides iterators which ease iterating over the command
  1403. // buffer. This is typically CDP2DataWrap<>.
  1404. // TDP2MFC: A map container, which associates a D3DHAL_DP2OPERATION with a
  1405. // member function. A standard array is acceptable, as the number of
  1406. // entries is not variable at runtime. The member function is used to
  1407. // process the command.
  1408. // TDP2RMFC: A map container, which associates a D3DHAL_DP2OPERATION with a
  1409. // member function. A standard array is acceptable, as the number of
  1410. // entries is not variable at runtime. The member function is used to
  1411. // record or fill in the command with the current state.
  1412. //
  1413. // <Exposed Types>
  1414. // TDP2Data: The wrapper class type for PORTABLE_DRAWPRIMITIVES2DATA, which is
  1415. // the passed in TDP2D template parameter.
  1416. // TDP2DataCmds: The Sequence Container of DP2 commands provided by the
  1417. // TDP2Data wrapper class, which is relied upon to provide iteration over
  1418. // the command buffer. (TDP2Data::TCmds)
  1419. // TStateSet: The StateSet type, which was passed in as the TSS template
  1420. // parameter.
  1421. // TMFn: The member function type, which all DP2 command processing member
  1422. // functions should conform to. This is mostly exposed as a convience to
  1423. // Context implementors.
  1424. // TMFnCaller: An Adaptable Binary Function class which is used to call
  1425. // a TMFn, only being passed the TMFn and DP2 command pointer.
  1426. // TDP2CmdBind: A simple type, exposed as a convience to Context implementors,
  1427. // to provide a type that can be passed into the constructor, associating
  1428. // D3DHAL_DP2OPERATIONs with member functions/ TMFn.
  1429. // TRMFn: The member function type, which all DP2 command recording member
  1430. // functions should conform to. This is mostly exposed as a convience to
  1431. // Context implementors.
  1432. // TRMFnCaller: An Adaptable Binary Function class which is used to call
  1433. // a TRMFn, only being passed the TRMFn and DP2 command pointer.
  1434. // TRecDP2CmdBind: A simple type, exposed as a convience to Context implementors,
  1435. // to provide a type that can be passed into the constructor, associating
  1436. // D3DHAL_DP2OPERATIONs with member functions/ TRMFn.
  1437. //
  1438. // <Exposed Functions>
  1439. // CStdDrawPrimitives2(): Default constructor.
  1440. // template< class TIter1, class TIter2>
  1441. // CStdDrawPrimitives2( TIter1, const TIter1, TIter2, const TIter2): Standard
  1442. // constructor which receives two ranges of D3DHAL_DP2OPERATION bindings.
  1443. // The first range is a range of DP2 command processing bindings. The
  1444. // second range is a range of DP2 command recording bindings.
  1445. // void OnBeginDrawPrimitives2( TDP2Data&): A notification function called
  1446. // at the beginning of processing a DrawPrimitives2 entry point.
  1447. // void OnEndDrawPrimitives2( TDP2Data&): A notification function called at
  1448. // the end of processing a DrawPrimitives2 entry point.
  1449. // void CreateAndCaptureAllState( DWORD): The request to capture all state,
  1450. // which should only be received by pure devices.
  1451. // void CreateAndCapturePixelState( DWORD): The request to capture pixel state,
  1452. // which should only be received by pure devices.
  1453. // void CreateAndCaptureVertexState( DWORD): The request to capture vertex
  1454. // state, which should only be received by pure devices.
  1455. // HRESULT DP2StateSet( TDP2Data&, const D3DHAL_DP2COMMAND*, const void*): The
  1456. // default DP2 command processing member function for D3DDP2OP_STATESET.
  1457. // void RecordCommandBuffer( D3DHAL_DP2COMMAND*, D3DHAL_DP2COMMAND*): The
  1458. // request to save or fill in the blanks of the passed in range of command
  1459. // buffer, by using the DP2 command recording functions.
  1460. // HRESULT DrawPrimitives2( PORTABLE_DRAWPRIMITIVES2DATA&): The function,
  1461. // typically called by the Driver class to process the DrawPrimitives2
  1462. // entry point.
  1463. //
  1464. ////////////////////////////////////////////////////////////////////////////////
  1465. template< class TSuper,
  1466. class TSS= CMinimalStateSet< TSuper>, class TSSDB= map< DWORD, TSS>,
  1467. class TDP2D= CDP2DataWrap<>,
  1468. class TDP2MFC= block<
  1469. HRESULT(TSuper::*)( TDP2D&, const D3DHAL_DP2COMMAND*, const void*), 66>,
  1470. class TDP2RMFC= block<
  1471. HRESULT(TSuper::*)( const D3DHAL_DP2COMMAND*, void*), 66> >
  1472. class CStdDrawPrimitives2
  1473. {
  1474. public: // Types
  1475. typedef TDP2D TDP2Data;
  1476. typedef typename TDP2Data::TCmds TDP2DataCmds;
  1477. typedef TSS TStateSet;
  1478. typedef HRESULT (TSuper::* TMFn)(TDP2Data&,const D3DHAL_DP2COMMAND*,
  1479. const void*);
  1480. struct TMFnCaller: // Used in conjunction
  1481. public binary_function< TMFn, const D3DHAL_DP2COMMAND*, HRESULT>
  1482. {
  1483. TSuper& m_Context;
  1484. TDP2Data& m_DP2Data;
  1485. TMFnCaller( TSuper& Context, TDP2Data& DP2Data)
  1486. : m_Context( Context), m_DP2Data( DP2Data)
  1487. { }
  1488. result_type operator()( first_argument_type MFn,
  1489. second_argument_type pDP2Cmd) const
  1490. {
  1491. #if defined(DBG) || defined(_DEBUG)
  1492. const D3DHAL_DP2OPERATION Op(
  1493. static_cast< D3DHAL_DP2OPERATION>( pDP2Cmd->bCommand));
  1494. #endif
  1495. return (m_Context.*MFn)( m_DP2Data, pDP2Cmd, pDP2Cmd+ 1);
  1496. }
  1497. };
  1498. struct TDP2CmdBind
  1499. {
  1500. D3DHAL_DP2OPERATION m_DP2Op;
  1501. TMFn m_MFn;
  1502. operator D3DHAL_DP2OPERATION() const
  1503. { return m_DP2Op; }
  1504. operator TMFn() const
  1505. { return m_MFn; }
  1506. };
  1507. typedef HRESULT (TSuper::* TRMFn)( const D3DHAL_DP2COMMAND*, void*);
  1508. struct TRMFnCaller:
  1509. public binary_function< TRMFn, D3DHAL_DP2COMMAND*, HRESULT>
  1510. {
  1511. TSuper& m_Context;
  1512. TRMFnCaller( TSuper& Context)
  1513. : m_Context( Context)
  1514. { }
  1515. result_type operator()( first_argument_type RMFn,
  1516. second_argument_type pDP2Cmd) const
  1517. {
  1518. #if defined(DBG) || defined(_DEBUG)
  1519. const D3DHAL_DP2OPERATION Op(
  1520. static_cast< D3DHAL_DP2OPERATION>( pDP2Cmd->bCommand));
  1521. #endif
  1522. return (m_Context.*RMFn)( pDP2Cmd, pDP2Cmd+ 1);
  1523. }
  1524. };
  1525. struct TRecDP2CmdBind
  1526. {
  1527. D3DHAL_DP2OPERATION m_DP2Op;
  1528. TRMFn m_RMFn;
  1529. operator D3DHAL_DP2OPERATION() const
  1530. { return m_DP2Op; }
  1531. operator TRMFn() const
  1532. { return m_RMFn; }
  1533. };
  1534. protected: // Types
  1535. typedef TSSDB TSSDB;
  1536. typedef TDP2MFC TDP2MFnCtr;
  1537. typedef TDP2RMFC TDP2RecMFnCtr;
  1538. protected: // Variables
  1539. static const HRESULT c_hrStateSetBegin;
  1540. static const HRESULT c_hrStateSetEnd;
  1541. TSSDB m_StateSetDB;
  1542. TDP2MFnCtr m_DefFnCtr;
  1543. TDP2RecMFnCtr m_RecFnCtr;
  1544. const D3DHAL_DP2COMMAND* m_pEndStateSet;
  1545. DWORD m_dwStateSetId;
  1546. bool m_bRecordingStateSet;
  1547. bool m_bExecutingStateSet;
  1548. protected: // Functions
  1549. // This function is used as a filler. If the assert is hit, step one
  1550. // level up/down in the call stack and check which DP2 Operation has
  1551. // no support, but the app indirectly needs it.
  1552. HRESULT DP2Empty( TDP2Data&, const D3DHAL_DP2COMMAND*, const void*)
  1553. {
  1554. const bool A_DP2_Op_Requires_A_Supporting_Function( false);
  1555. assert( A_DP2_Op_Requires_A_Supporting_Function);
  1556. return D3DERR_COMMAND_UNPARSED;
  1557. }
  1558. // This function is used as a fake, to prevent actual processing of
  1559. // DP2 Operations while recording a StateSet.
  1560. HRESULT DP2Fake( TDP2Data&, const D3DHAL_DP2COMMAND*, const void*)
  1561. { return DD_OK; }
  1562. // Notification functions. Overriding is optional.
  1563. void OnBeginDrawPrimitives2( TDP2Data& DP2Data) const
  1564. { }
  1565. void OnEndDrawPrimitives2( TDP2Data& DP2Data) const
  1566. { }
  1567. CStdDrawPrimitives2()
  1568. :m_bRecordingStateSet( false), m_bExecutingStateSet( false),
  1569. m_pEndStateSet( NULL)
  1570. {
  1571. typename TDP2MFnCtr::iterator itCur( m_DefFnCtr.begin());
  1572. while( itCur!= m_DefFnCtr.end())
  1573. {
  1574. *itCur= DP2Empty;
  1575. ++itCur;
  1576. }
  1577. itCur= m_RecFnCtr.begin();
  1578. while( itCur!= m_RecFnCtr.end())
  1579. {
  1580. *itCur= NULL;
  1581. ++itCur;
  1582. }
  1583. m_DefFnCtr[ D3DDP2OP_STATESET]= DP2StateSet;
  1584. }
  1585. // [itSetStart, itSetEnd): A valid range of bindings, which associate
  1586. // a D3DHAL_DP2OPERATION with a processing member function.
  1587. // [itRecStart, itRecEnd): A valid range of bindings, which associate
  1588. // a D3DHAL_DP2OPERATION with a recording member function.
  1589. template< class TIter1, class TIter2> // TDP2CmdBind*, TRecDP2CmdBind*
  1590. CStdDrawPrimitives2( TIter1 itSetStart, const TIter1 itSetEnd,
  1591. TIter2 itRecStart, const TIter2 itRecEnd)
  1592. :m_bRecordingStateSet( false), m_bExecutingStateSet( false),
  1593. m_pEndStateSet( NULL)
  1594. {
  1595. typename TDP2MFnCtr::iterator itCur( m_DefFnCtr.begin());
  1596. while( itCur!= m_DefFnCtr.end())
  1597. {
  1598. *itCur= DP2Empty;
  1599. ++itCur;
  1600. }
  1601. typename TDP2RecMFnCtr::iterator itRCur= m_RecFnCtr.begin();
  1602. while( itRCur!= m_RecFnCtr.end())
  1603. {
  1604. *itRCur= NULL;
  1605. ++itRCur;
  1606. }
  1607. while( itSetStart!= itSetEnd)
  1608. {
  1609. const D3DHAL_DP2OPERATION DP2Op(
  1610. static_cast<D3DHAL_DP2OPERATION>(*itSetStart));
  1611. // This assert will fire if there are duplicate entries for the
  1612. // same DP2OPERATION.
  1613. assert( DP2Empty== m_DefFnCtr[ DP2Op]);
  1614. m_DefFnCtr[ DP2Op]= static_cast<TMFn>(*itSetStart);
  1615. ++itSetStart;
  1616. }
  1617. while( itRecStart!= itRecEnd)
  1618. {
  1619. const D3DHAL_DP2OPERATION DP2Op(
  1620. static_cast<D3DHAL_DP2OPERATION>(*itRecStart));
  1621. // This assert will fire if there are duplicate entries for the
  1622. // same DP2OPERATION.
  1623. assert( NULL== m_RecFnCtr[ DP2Op]);
  1624. m_RecFnCtr[ DP2Op]= static_cast<TRMFn>(*itRecStart);
  1625. ++itRecStart;
  1626. }
  1627. if( DP2Empty== m_DefFnCtr[ D3DDP2OP_STATESET])
  1628. m_DefFnCtr[ D3DDP2OP_STATESET]= DP2StateSet;
  1629. // Supporting these operations is considered the "safe minimal"
  1630. // support necessary to function. It is strongly recommended that
  1631. // these functions are supported, unless you know you can live without.
  1632. assert( m_DefFnCtr[ D3DDP2OP_VIEWPORTINFO]!= DP2Empty);
  1633. assert( m_DefFnCtr[ D3DDP2OP_WINFO]!= DP2Empty);
  1634. assert( m_DefFnCtr[ D3DDP2OP_RENDERSTATE]!= DP2Empty);
  1635. assert( m_DefFnCtr[ D3DDP2OP_TEXTURESTAGESTATE]!= DP2Empty);
  1636. assert( m_DefFnCtr[ D3DDP2OP_CLEAR]!= DP2Empty);
  1637. assert( m_DefFnCtr[ D3DDP2OP_SETRENDERTARGET]!= DP2Empty);
  1638. assert( m_DefFnCtr[ D3DDP2OP_SETVERTEXSHADER]!= DP2Empty);
  1639. assert( m_DefFnCtr[ D3DDP2OP_SETSTREAMSOURCE]!= DP2Empty);
  1640. assert( m_DefFnCtr[ D3DDP2OP_SETSTREAMSOURCEUM]!= DP2Empty);
  1641. assert( m_DefFnCtr[ D3DDP2OP_SETINDICES]!= DP2Empty);
  1642. assert( m_DefFnCtr[ D3DDP2OP_DRAWPRIMITIVE]!= DP2Empty);
  1643. assert( m_DefFnCtr[ D3DDP2OP_DRAWPRIMITIVE2]!= DP2Empty);
  1644. assert( m_DefFnCtr[ D3DDP2OP_DRAWINDEXEDPRIMITIVE]!= DP2Empty);
  1645. assert( m_DefFnCtr[ D3DDP2OP_DRAWINDEXEDPRIMITIVE2]!= DP2Empty);
  1646. assert( m_DefFnCtr[ D3DDP2OP_CLIPPEDTRIANGLEFAN]!= DP2Empty);
  1647. assert( m_RecFnCtr[ D3DDP2OP_VIEWPORTINFO]!= NULL);
  1648. assert( m_RecFnCtr[ D3DDP2OP_WINFO]!= NULL);
  1649. assert( m_RecFnCtr[ D3DDP2OP_RENDERSTATE]!= NULL);
  1650. assert( m_RecFnCtr[ D3DDP2OP_TEXTURESTAGESTATE]!= NULL);
  1651. assert( m_RecFnCtr[ D3DDP2OP_SETVERTEXSHADER]!= NULL);
  1652. assert( m_RecFnCtr[ D3DDP2OP_SETSTREAMSOURCE]!= NULL);
  1653. assert( m_RecFnCtr[ D3DDP2OP_SETINDICES]!= NULL);
  1654. // To remove this asserting, bind these functions to a different stub,
  1655. // most likely a member function of TSuper, which does nothing; so that
  1656. // they will not be equal to DP2Empty. Or use the default constructor.
  1657. }
  1658. ~CStdDrawPrimitives2()
  1659. { }
  1660. // To determine number of const registers available to pixel shader.
  1661. static DWORD GetNumPixelShaderConstReg( const DWORD dwPixelShaderVer)
  1662. {
  1663. switch(dwPixelShaderVer)
  1664. {
  1665. case( 0): return 0;
  1666. case( D3DPS_VERSION(1,0)): return 8;
  1667. case( D3DPS_VERSION(1,1)): return 8;
  1668. case( D3DPS_VERSION(254,254)): return 2;
  1669. case( D3DPS_VERSION(255,255)): return 16;
  1670. default: {
  1671. const bool Unrecognizable_Pixel_Shader_Version( false);
  1672. assert( Unrecognizable_Pixel_Shader_Version);
  1673. } break;
  1674. }
  1675. return 0;
  1676. }
  1677. public: // Functions
  1678. // Default implementataions for Capturing amounts of state, DX8
  1679. // pure device style.
  1680. void CreateAndCaptureAllState( DWORD dwStateSetId)
  1681. {
  1682. #if defined( D3D_ENABLE_SHADOW_BUFFER)
  1683. #if defined( D3D_ENABLE_SHADOW_JITTER)
  1684. typedef block< D3DRENDERSTATETYPE, 78> TAllRSToCapture;
  1685. #else // !defined( D3D_ENABLE_SHADOW_JITTER)
  1686. typedef block< D3DRENDERSTATETYPE, 75> TAllRSToCapture;
  1687. #endif // !defined( D3D_ENABLE_SHADOW_JITTER)
  1688. #else // !defined( D3D_ENABLE_SHADOW_BUFFER)
  1689. typedef block< D3DRENDERSTATETYPE, 73> TAllRSToCapture;
  1690. #endif// !defined( D3D_ENABLE_SHADOW_BUFFER)
  1691. const TAllRSToCapture AllRSToCapture=
  1692. {
  1693. D3DRENDERSTATE_SPECULARENABLE,
  1694. D3DRENDERSTATE_ZENABLE,
  1695. D3DRENDERSTATE_FILLMODE,
  1696. D3DRENDERSTATE_SHADEMODE,
  1697. D3DRENDERSTATE_LINEPATTERN,
  1698. D3DRENDERSTATE_ZWRITEENABLE,
  1699. D3DRENDERSTATE_ALPHATESTENABLE,
  1700. D3DRENDERSTATE_LASTPIXEL,
  1701. D3DRENDERSTATE_SRCBLEND,
  1702. D3DRENDERSTATE_DESTBLEND,
  1703. D3DRENDERSTATE_CULLMODE,
  1704. D3DRENDERSTATE_ZFUNC,
  1705. D3DRENDERSTATE_ALPHAREF,
  1706. D3DRENDERSTATE_ALPHAFUNC,
  1707. D3DRENDERSTATE_DITHERENABLE,
  1708. D3DRENDERSTATE_FOGENABLE,
  1709. D3DRENDERSTATE_STIPPLEDALPHA,
  1710. D3DRENDERSTATE_FOGCOLOR,
  1711. D3DRENDERSTATE_FOGTABLEMODE,
  1712. D3DRENDERSTATE_FOGSTART,
  1713. D3DRENDERSTATE_FOGEND,
  1714. D3DRENDERSTATE_FOGDENSITY,
  1715. D3DRENDERSTATE_EDGEANTIALIAS,
  1716. D3DRENDERSTATE_ALPHABLENDENABLE,
  1717. D3DRENDERSTATE_ZBIAS,
  1718. D3DRENDERSTATE_RANGEFOGENABLE,
  1719. D3DRENDERSTATE_STENCILENABLE,
  1720. D3DRENDERSTATE_STENCILFAIL,
  1721. D3DRENDERSTATE_STENCILZFAIL,
  1722. D3DRENDERSTATE_STENCILPASS,
  1723. D3DRENDERSTATE_STENCILFUNC,
  1724. D3DRENDERSTATE_STENCILREF,
  1725. D3DRENDERSTATE_STENCILMASK,
  1726. D3DRENDERSTATE_STENCILWRITEMASK,
  1727. D3DRENDERSTATE_TEXTUREFACTOR,
  1728. D3DRENDERSTATE_WRAP0,
  1729. D3DRENDERSTATE_WRAP1,
  1730. D3DRENDERSTATE_WRAP2,
  1731. D3DRENDERSTATE_WRAP3,
  1732. D3DRENDERSTATE_WRAP4,
  1733. D3DRENDERSTATE_WRAP5,
  1734. D3DRENDERSTATE_WRAP6,
  1735. D3DRENDERSTATE_WRAP7,
  1736. D3DRENDERSTATE_AMBIENT,
  1737. D3DRENDERSTATE_COLORVERTEX,
  1738. D3DRENDERSTATE_FOGVERTEXMODE,
  1739. D3DRENDERSTATE_CLIPPING,
  1740. D3DRENDERSTATE_LIGHTING,
  1741. D3DRENDERSTATE_NORMALIZENORMALS,
  1742. D3DRENDERSTATE_LOCALVIEWER,
  1743. D3DRENDERSTATE_EMISSIVEMATERIALSOURCE,
  1744. D3DRENDERSTATE_AMBIENTMATERIALSOURCE,
  1745. D3DRENDERSTATE_DIFFUSEMATERIALSOURCE,
  1746. D3DRENDERSTATE_SPECULARMATERIALSOURCE,
  1747. D3DRENDERSTATE_VERTEXBLEND,
  1748. D3DRENDERSTATE_CLIPPLANEENABLE,
  1749. D3DRS_SOFTWAREVERTEXPROCESSING,
  1750. D3DRS_POINTSIZE,
  1751. D3DRS_POINTSIZE_MIN,
  1752. D3DRS_POINTSPRITEENABLE,
  1753. D3DRS_POINTSCALEENABLE,
  1754. D3DRS_POINTSCALE_A,
  1755. D3DRS_POINTSCALE_B,
  1756. D3DRS_POINTSCALE_C,
  1757. D3DRS_MULTISAMPLEANTIALIAS,
  1758. D3DRS_MULTISAMPLEMASK,
  1759. D3DRS_PATCHEDGESTYLE,
  1760. D3DRS_PATCHSEGMENTS,
  1761. D3DRS_POINTSIZE_MAX,
  1762. D3DRS_INDEXEDVERTEXBLENDENABLE,
  1763. D3DRS_COLORWRITEENABLE,
  1764. D3DRS_TWEENFACTOR,
  1765. D3DRS_BLENDOP,
  1766. #if defined( D3D_ENABLE_SHADOW_BUFFER)
  1767. D3DRS_ZSLOPESCALE,
  1768. D3DRS_ZCLAMP,
  1769. #if defined( D3D_ENABLE_SHADOW_JITTER)
  1770. D3DRS_JITZBIASMIN,
  1771. D3DRS_JITZBIASMAX,
  1772. D3DRS_JITSHADOWSIZE,
  1773. #endif // defined( D3D_ENABLE_SHADOW_JITTER)
  1774. #endif // defined( D3D_ENABLE_SHADOW_BUFFER)
  1775. };
  1776. #if defined( D3D_ENABLE_SHADOW_BUFFER)
  1777. #if defined( D3D_ENABLE_SHADOW_JITTER)
  1778. assert( D3DRS_JITSHADOWSIZE== *AllRSToCapture.rbegin());
  1779. #else // !defined( D3D_ENABLE_SHADOW_JITTER)
  1780. assert( D3DRS_ZCLAMP== *AllRSToCapture.rbegin());
  1781. #endif // !defined( D3D_ENABLE_SHADOW_JITTER)
  1782. #else // !defined( D3D_ENABLE_SHADOW_BUFFER)
  1783. assert( D3DRS_BLENDOP== *AllRSToCapture.rbegin());
  1784. #endif // !defined( D3D_ENABLE_SHADOW_BUFFER)
  1785. #if defined( D3D_ENABLE_SHADOW_BUFFER)
  1786. typedef block< D3DTEXTURESTAGESTATETYPE, 30> TAllTSSToCapture;
  1787. #else // !defined( D3D_ENABLE_SHADOW_BUFFER)
  1788. typedef block< D3DTEXTURESTAGESTATETYPE, 27> TAllTSSToCapture;
  1789. #endif // !defined( D3D_ENABLE_SHADOW_BUFFER)
  1790. const TAllTSSToCapture AllTSSToCapture=
  1791. {
  1792. D3DTSS_COLOROP,
  1793. D3DTSS_COLORARG1,
  1794. D3DTSS_COLORARG2,
  1795. D3DTSS_ALPHAOP,
  1796. D3DTSS_ALPHAARG1,
  1797. D3DTSS_ALPHAARG2,
  1798. D3DTSS_BUMPENVMAT00,
  1799. D3DTSS_BUMPENVMAT01,
  1800. D3DTSS_BUMPENVMAT10,
  1801. D3DTSS_BUMPENVMAT11,
  1802. D3DTSS_TEXCOORDINDEX,
  1803. D3DTSS_ADDRESSU,
  1804. D3DTSS_ADDRESSV,
  1805. D3DTSS_BORDERCOLOR,
  1806. D3DTSS_MAGFILTER,
  1807. D3DTSS_MINFILTER,
  1808. D3DTSS_MIPFILTER,
  1809. D3DTSS_MIPMAPLODBIAS,
  1810. D3DTSS_MAXMIPLEVEL,
  1811. D3DTSS_MAXANISOTROPY,
  1812. D3DTSS_BUMPENVLSCALE,
  1813. D3DTSS_BUMPENVLOFFSET,
  1814. D3DTSS_TEXTURETRANSFORMFLAGS,
  1815. D3DTSS_ADDRESSW,
  1816. D3DTSS_COLORARG0,
  1817. D3DTSS_ALPHAARG0,
  1818. D3DTSS_RESULTARG,
  1819. #if defined( D3D_ENABLE_SHADOW_BUFFER)
  1820. D3DTSS_SHADOWNEARW,
  1821. D3DTSS_SHADOWFARW,
  1822. D3DTSS_SHADOWBUFFERENABLE,
  1823. #endif // defined( D3D_ENABLE_SHADOW_BUFFER)
  1824. };
  1825. #if defined( D3D_ENABLE_SHADOW_BUFFER)
  1826. assert( D3DTSS_SHADOWBUFFERENABLE== *AllTSSToCapture.rbegin());
  1827. #else // !defined( D3D_ENABLE_SHADOW_BUFFER)
  1828. assert( D3DTSS_RESULTARG== *AllTSSToCapture.rbegin());
  1829. #endif // !defined( D3D_ENABLE_SHADOW_BUFFER)
  1830. TSuper* pSThis= static_cast< TSuper*>( this);
  1831. typedef TSuper::TPerDDrawData TPerDDrawData;
  1832. typedef TPerDDrawData::TDriver TDriver;
  1833. const DWORD dwTextureStages( D3DHAL_TSS_MAXSTAGES);
  1834. const DWORD dwTextureMatrices( D3DHAL_TSS_MAXSTAGES);
  1835. const DWORD dwClipPlanes( TDriver::GetCaps().MaxUserClipPlanes);
  1836. const DWORD dwVertexShaderConsts( TDriver::GetCaps().MaxVertexShaderConst);
  1837. const DWORD dwPixelShaderConsts( GetNumPixelShaderConstReg(
  1838. TDriver::GetCaps().PixelShaderVersion));
  1839. // Algorithm to determine maximum SetTransform Index to support.
  1840. DWORD dwWorldMatrices( TDriver::GetCaps().MaxVertexBlendMatrixIndex+ 1);
  1841. if( TDriver::GetCaps().MaxVertexBlendMatrices> dwWorldMatrices)
  1842. dwWorldMatrices= TDriver::GetCaps().MaxVertexBlendMatrices;
  1843. DWORD dwActiveLights( 0);
  1844. size_t uiRecDP2BufferSize( 0);
  1845. // Pass 1: Calculate size of DP2 buffer required.
  1846. // Render States
  1847. if( m_RecFnCtr[ D3DDP2OP_RENDERSTATE]!= NULL)
  1848. { assert( m_DefFnCtr[ D3DDP2OP_RENDERSTATE]!= DP2Empty);
  1849. uiRecDP2BufferSize+= sizeof( D3DHAL_DP2COMMAND)+
  1850. AllRSToCapture.size()* sizeof( D3DHAL_DP2RENDERSTATE);
  1851. }
  1852. else { assert( m_DefFnCtr[ D3DDP2OP_RENDERSTATE]== DP2Empty); }
  1853. // Texture States
  1854. if( m_RecFnCtr[ D3DDP2OP_TEXTURESTAGESTATE]!= NULL&&
  1855. dwTextureStages!= 0)
  1856. { assert( m_DefFnCtr[ D3DDP2OP_TEXTURESTAGESTATE]!= DP2Empty);
  1857. uiRecDP2BufferSize+= sizeof( D3DHAL_DP2COMMAND)+ dwTextureStages*
  1858. AllTSSToCapture.size()* sizeof( D3DHAL_DP2TEXTURESTAGESTATE);
  1859. }
  1860. else { assert( m_DefFnCtr[ D3DDP2OP_TEXTURESTAGESTATE]== DP2Empty); }
  1861. // Viewport
  1862. if( m_RecFnCtr[ D3DDP2OP_VIEWPORTINFO]!= NULL)
  1863. { assert( m_DefFnCtr[ D3DDP2OP_VIEWPORTINFO]!= DP2Empty);
  1864. uiRecDP2BufferSize+= sizeof( D3DHAL_DP2COMMAND)+
  1865. sizeof( D3DHAL_DP2VIEWPORTINFO);
  1866. }
  1867. else { assert( m_DefFnCtr[ D3DDP2OP_VIEWPORTINFO]== DP2Empty); }
  1868. // Transforms
  1869. if( m_RecFnCtr[ D3DDP2OP_SETTRANSFORM]!= NULL)
  1870. { assert( m_DefFnCtr[ D3DDP2OP_SETTRANSFORM]!= DP2Empty);
  1871. // World, Texture, View, & Projection
  1872. uiRecDP2BufferSize+= sizeof( D3DHAL_DP2COMMAND)+
  1873. sizeof( D3DHAL_DP2SETTRANSFORM)* (dwWorldMatrices+
  1874. dwTextureMatrices+ 2);
  1875. }
  1876. else { assert( m_DefFnCtr[ D3DDP2OP_SETTRANSFORM]== DP2Empty); }
  1877. // Clipplanes
  1878. if( m_RecFnCtr[ D3DDP2OP_SETCLIPPLANE]!= NULL&& dwClipPlanes!= 0)
  1879. { assert( m_DefFnCtr[ D3DDP2OP_SETCLIPPLANE]!= DP2Empty);
  1880. uiRecDP2BufferSize+= sizeof( D3DHAL_DP2COMMAND)+
  1881. sizeof( D3DHAL_DP2SETCLIPPLANE)* dwClipPlanes;
  1882. }
  1883. else { assert( m_DefFnCtr[ D3DDP2OP_SETCLIPPLANE]== DP2Empty); }
  1884. // Material
  1885. if( m_RecFnCtr[ D3DDP2OP_SETMATERIAL]!= NULL)
  1886. { assert( m_DefFnCtr[ D3DDP2OP_SETMATERIAL]!= DP2Empty);
  1887. uiRecDP2BufferSize+= sizeof( D3DHAL_DP2COMMAND)+
  1888. sizeof( D3DHAL_DP2SETMATERIAL);
  1889. }
  1890. else { assert( m_DefFnCtr[ D3DDP2OP_SETMATERIAL]== DP2Empty); }
  1891. // Lights
  1892. if( m_RecFnCtr[ D3DDP2OP_CREATELIGHT]!= NULL)
  1893. { assert( m_DefFnCtr[ D3DDP2OP_SETLIGHT]!= DP2Empty);
  1894. assert( m_DefFnCtr[ D3DDP2OP_CREATELIGHT]!= DP2Empty);
  1895. // Special exception here. First, ask how many active lights there
  1896. // are. We'll then prepare a buffer that the RecFnCtr function
  1897. // will have to know what to do with (as this is the only case
  1898. // that is not obvious how to handle). RecFnCtr will key off
  1899. // bCommand== 0.
  1900. const D3DHAL_DP2COMMAND DP2Cmd= {
  1901. static_cast< D3DHAL_DP2OPERATION>( 0), 0 };
  1902. // Ask for how many active lights in DP2ActiveLights.dwIndex;
  1903. D3DHAL_DP2CREATELIGHT DP2ActiveLights= { 0 };
  1904. (pSThis->*m_RecFnCtr[ D3DDP2OP_CREATELIGHT])(
  1905. &DP2Cmd, &DP2ActiveLights);
  1906. dwActiveLights= DP2ActiveLights.dwIndex;
  1907. if( dwActiveLights!= 0)
  1908. {
  1909. // Create structures.
  1910. uiRecDP2BufferSize+= sizeof( D3DHAL_DP2COMMAND)+ dwActiveLights*
  1911. sizeof( D3DHAL_DP2CREATELIGHT);
  1912. // Set structures.
  1913. uiRecDP2BufferSize+= sizeof( D3DHAL_DP2COMMAND)+ dwActiveLights*
  1914. (2* sizeof( D3DHAL_DP2SETLIGHT)+ sizeof( D3DLIGHT8));
  1915. }
  1916. }
  1917. else {
  1918. assert( m_DefFnCtr[ D3DDP2OP_SETLIGHT]== DP2Empty);
  1919. assert( m_DefFnCtr[ D3DDP2OP_CREATELIGHT]== DP2Empty);
  1920. }
  1921. // Vertex Shader
  1922. if( m_RecFnCtr[ D3DDP2OP_SETVERTEXSHADER]!= NULL)
  1923. { assert( m_DefFnCtr[ D3DDP2OP_SETVERTEXSHADER]!= DP2Empty);
  1924. uiRecDP2BufferSize+= sizeof( D3DHAL_DP2COMMAND)+
  1925. sizeof( D3DHAL_DP2VERTEXSHADER);
  1926. }
  1927. else { assert( m_DefFnCtr[ D3DDP2OP_SETVERTEXSHADER]== DP2Empty); }
  1928. // Pixel Shader
  1929. if( m_RecFnCtr[ D3DDP2OP_SETPIXELSHADER]!= NULL)
  1930. { assert( m_DefFnCtr[ D3DDP2OP_SETPIXELSHADER]!= DP2Empty);
  1931. uiRecDP2BufferSize+= sizeof( D3DHAL_DP2COMMAND)+
  1932. sizeof( D3DHAL_DP2PIXELSHADER);
  1933. }
  1934. else { assert( m_DefFnCtr[ D3DDP2OP_SETPIXELSHADER]== DP2Empty); }
  1935. // Vertex Shader Constants
  1936. if( m_RecFnCtr[ D3DDP2OP_SETVERTEXSHADERCONST]!= NULL&&
  1937. dwVertexShaderConsts!= 0)
  1938. { assert( m_DefFnCtr[ D3DDP2OP_SETVERTEXSHADERCONST]!= DP2Empty);
  1939. uiRecDP2BufferSize+= sizeof( D3DHAL_DP2COMMAND)+
  1940. sizeof( D3DHAL_DP2SETVERTEXSHADERCONST)+
  1941. dwVertexShaderConsts* 4* sizeof(D3DVALUE);
  1942. }
  1943. else { assert( m_DefFnCtr[ D3DDP2OP_SETVERTEXSHADERCONST]== DP2Empty); }
  1944. // Pixel Shader Constants
  1945. if( m_RecFnCtr[ D3DDP2OP_SETPIXELSHADERCONST]!= NULL&&
  1946. dwPixelShaderConsts!= 0)
  1947. { assert( m_DefFnCtr[ D3DDP2OP_SETPIXELSHADERCONST]!= DP2Empty);
  1948. uiRecDP2BufferSize+= sizeof( D3DHAL_DP2COMMAND)+
  1949. sizeof( D3DHAL_DP2SETPIXELSHADERCONST)+
  1950. dwPixelShaderConsts* 4* sizeof(D3DVALUE);
  1951. }
  1952. else { assert( m_DefFnCtr[ D3DDP2OP_SETPIXELSHADERCONST]== DP2Empty); }
  1953. // Pass 2: Build command buffer for states.
  1954. UINT8* pTempBuffer= NULL;
  1955. try {
  1956. pTempBuffer= reinterpret_cast< UINT8*>(
  1957. operator new ( uiRecDP2BufferSize));
  1958. } catch ( ... ) {
  1959. }
  1960. if( NULL== pTempBuffer)
  1961. throw bad_alloc( "Not enough room for StateSet");
  1962. D3DHAL_DP2COMMAND* pStartSSet= reinterpret_cast< D3DHAL_DP2COMMAND*>(
  1963. pTempBuffer);
  1964. D3DHAL_DP2COMMAND* pCur= pStartSSet;
  1965. D3DHAL_DP2COMMAND* pEndSSet= reinterpret_cast< D3DHAL_DP2COMMAND*>(
  1966. pTempBuffer+ uiRecDP2BufferSize);
  1967. // Render States
  1968. if( m_RecFnCtr[ D3DDP2OP_RENDERSTATE]!= NULL)
  1969. {
  1970. pCur->bCommand= D3DDP2OP_RENDERSTATE;
  1971. pCur->wStateCount= static_cast< WORD>( AllRSToCapture.size());
  1972. D3DHAL_DP2RENDERSTATE* pParam=
  1973. reinterpret_cast< D3DHAL_DP2RENDERSTATE*>( pCur+ 1);
  1974. TAllRSToCapture::const_iterator itRS( AllRSToCapture.begin());
  1975. while( itRS!= AllRSToCapture.end())
  1976. {
  1977. pParam->RenderState= *itRS;
  1978. ++itRS;
  1979. ++pParam;
  1980. }
  1981. pCur= reinterpret_cast< D3DHAL_DP2COMMAND*>( pParam);
  1982. }
  1983. // Texture States
  1984. if( m_RecFnCtr[ D3DDP2OP_TEXTURESTAGESTATE]!= NULL&&
  1985. dwTextureStages!= 0)
  1986. {
  1987. pCur->bCommand= D3DDP2OP_TEXTURESTAGESTATE;
  1988. pCur->wStateCount= static_cast< WORD>( dwTextureStages*
  1989. AllTSSToCapture.size());
  1990. D3DHAL_DP2TEXTURESTAGESTATE* pParam=
  1991. reinterpret_cast< D3DHAL_DP2TEXTURESTAGESTATE*>( pCur+ 1);
  1992. for( WORD wStage( 0); wStage< dwTextureStages; ++wStage)
  1993. {
  1994. TAllTSSToCapture::const_iterator itTSS( AllTSSToCapture.begin());
  1995. while( itTSS!= AllTSSToCapture.end())
  1996. {
  1997. pParam->wStage= wStage;
  1998. pParam->TSState= *itTSS;
  1999. ++itTSS;
  2000. ++pParam;
  2001. }
  2002. }
  2003. pCur= reinterpret_cast< D3DHAL_DP2COMMAND*>( pParam);
  2004. }
  2005. // Viewport
  2006. if( m_RecFnCtr[ D3DDP2OP_VIEWPORTINFO]!= NULL)
  2007. {
  2008. pCur->bCommand= D3DDP2OP_VIEWPORTINFO;
  2009. pCur->wStateCount= 1;
  2010. D3DHAL_DP2VIEWPORTINFO* pParam=
  2011. reinterpret_cast< D3DHAL_DP2VIEWPORTINFO*>( pCur+ 1);
  2012. pCur= reinterpret_cast< D3DHAL_DP2COMMAND*>( pParam+ 1);
  2013. }
  2014. // Transforms
  2015. if( m_RecFnCtr[ D3DDP2OP_SETTRANSFORM]!= NULL)
  2016. {
  2017. pCur->bCommand= D3DDP2OP_SETTRANSFORM;
  2018. pCur->wStateCount= static_cast< WORD>( dwWorldMatrices+
  2019. dwTextureMatrices+ 2);
  2020. D3DHAL_DP2SETTRANSFORM* pParam=
  2021. reinterpret_cast< D3DHAL_DP2SETTRANSFORM*>( pCur+ 1);
  2022. pParam->xfrmType= D3DTRANSFORMSTATE_PROJECTION;
  2023. ++pParam;
  2024. pParam->xfrmType= D3DTRANSFORMSTATE_VIEW;
  2025. ++pParam;
  2026. for( DWORD dwTM( 0); dwTM< dwTextureMatrices; ++dwTM)
  2027. {
  2028. pParam->xfrmType= static_cast< D3DTRANSFORMSTATETYPE>(
  2029. D3DTRANSFORMSTATE_TEXTURE0+ dwTM);
  2030. ++pParam;
  2031. }
  2032. for( DWORD dwWM( 0); dwWM< dwWorldMatrices; ++dwWM)
  2033. {
  2034. pParam->xfrmType= D3DTS_WORLDMATRIX( dwWM);
  2035. ++pParam;
  2036. }
  2037. pCur= reinterpret_cast< D3DHAL_DP2COMMAND*>( pParam);
  2038. }
  2039. // Clipplanes
  2040. if( m_RecFnCtr[ D3DDP2OP_SETCLIPPLANE]!= NULL&& dwClipPlanes!= 0)
  2041. {
  2042. pCur->bCommand= D3DDP2OP_SETCLIPPLANE;
  2043. pCur->wStateCount= static_cast< WORD>( dwClipPlanes);
  2044. D3DHAL_DP2SETCLIPPLANE* pParam=
  2045. reinterpret_cast< D3DHAL_DP2SETCLIPPLANE*>( pCur+ 1);
  2046. for( DWORD dwCP( 0); dwCP< dwClipPlanes; ++dwCP)
  2047. {
  2048. pParam->dwIndex= dwCP;
  2049. ++pParam;
  2050. }
  2051. pCur= reinterpret_cast< D3DHAL_DP2COMMAND*>( pParam);
  2052. }
  2053. // Material
  2054. if( m_RecFnCtr[ D3DDP2OP_SETMATERIAL]!= NULL)
  2055. {
  2056. pCur->bCommand= D3DDP2OP_SETMATERIAL;
  2057. pCur->wStateCount= 1;
  2058. D3DHAL_DP2SETMATERIAL* pParam=
  2059. reinterpret_cast< D3DHAL_DP2SETMATERIAL*>( pCur+ 1);
  2060. pCur= reinterpret_cast< D3DHAL_DP2COMMAND*>( pParam+ 1);
  2061. }
  2062. // Lights
  2063. if( m_RecFnCtr[ D3DDP2OP_CREATELIGHT]!= NULL&& dwActiveLights!= 0)
  2064. {
  2065. // Special exception here. First, we asked how many active lights
  2066. // there were. The RecFnCtr function will have to know what to do
  2067. // with this buffer. We now give it a chance to fill in the
  2068. // light ids. RecFnCtr will key off bCommand== 0.
  2069. pCur->bCommand= static_cast< D3DHAL_DP2OPERATION>( 0);
  2070. pCur->wStateCount= static_cast< WORD>( dwActiveLights);
  2071. D3DHAL_DP2CREATELIGHT* pParam=
  2072. reinterpret_cast< D3DHAL_DP2CREATELIGHT*>( pCur+ 1);
  2073. (pSThis->*m_RecFnCtr[ D3DDP2OP_CREATELIGHT])(
  2074. pCur, pParam);
  2075. // Change back the bCommand for proper usage later.
  2076. pCur->bCommand= D3DDP2OP_CREATELIGHT;
  2077. pCur= reinterpret_cast< D3DHAL_DP2COMMAND*>( pParam+ dwActiveLights);
  2078. // Now, with the light ids in the CREATELIGHT structures, we can
  2079. // fill out SETLIGHT structures with ids correctly.
  2080. pCur->bCommand= D3DDP2OP_SETLIGHT;
  2081. pCur->wStateCount= static_cast< WORD>( 2* dwActiveLights);
  2082. D3DHAL_DP2SETLIGHT* pSParam=
  2083. reinterpret_cast< D3DHAL_DP2SETLIGHT*>( pCur+ 1);
  2084. for( DWORD dwL( 0); dwL< dwActiveLights; ++dwL)
  2085. {
  2086. pSParam->dwIndex= pParam->dwIndex;
  2087. pSParam->dwDataType= D3DHAL_SETLIGHT_DATA;
  2088. D3DLIGHT8* pLight= reinterpret_cast< D3DLIGHT8*>( pSParam+ 1);
  2089. pSParam= reinterpret_cast< D3DHAL_DP2SETLIGHT*>( pLight+ 1);
  2090. pSParam->dwIndex= pParam->dwIndex;
  2091. pSParam->dwDataType= D3DHAL_SETLIGHT_DISABLE;
  2092. ++pParam;
  2093. ++pSParam;
  2094. }
  2095. pCur= reinterpret_cast< D3DHAL_DP2COMMAND*>( pSParam);
  2096. }
  2097. // Vertex Shader
  2098. if( m_RecFnCtr[ D3DDP2OP_SETVERTEXSHADER]!= NULL)
  2099. {
  2100. pCur->bCommand= D3DDP2OP_SETVERTEXSHADER;
  2101. pCur->wStateCount= 1;
  2102. D3DHAL_DP2VERTEXSHADER* pParam=
  2103. reinterpret_cast< D3DHAL_DP2VERTEXSHADER*>( pCur+ 1);
  2104. pCur= reinterpret_cast< D3DHAL_DP2COMMAND*>( pParam+ 1);
  2105. }
  2106. // Pixel Shader
  2107. if( m_RecFnCtr[ D3DDP2OP_SETPIXELSHADER]!= NULL)
  2108. {
  2109. pCur->bCommand= D3DDP2OP_SETPIXELSHADER;
  2110. pCur->wStateCount= 1;
  2111. D3DHAL_DP2PIXELSHADER* pParam=
  2112. reinterpret_cast< D3DHAL_DP2PIXELSHADER*>( pCur+ 1);
  2113. pCur= reinterpret_cast< D3DHAL_DP2COMMAND*>( pParam+ 1);
  2114. }
  2115. // Vertex Shader Constants
  2116. if( m_RecFnCtr[ D3DDP2OP_SETVERTEXSHADERCONST]!= NULL&&
  2117. dwVertexShaderConsts!= 0)
  2118. {
  2119. pCur->bCommand= D3DDP2OP_SETVERTEXSHADERCONST;
  2120. pCur->wStateCount= 1;
  2121. D3DHAL_DP2SETVERTEXSHADERCONST* pParam=
  2122. reinterpret_cast< D3DHAL_DP2SETVERTEXSHADERCONST*>( pCur+ 1);
  2123. pParam->dwRegister= 0;
  2124. pParam->dwCount= dwVertexShaderConsts;
  2125. D3DVALUE* pFloat= reinterpret_cast< D3DVALUE*>( pParam+ 1);
  2126. pCur= reinterpret_cast< D3DHAL_DP2COMMAND*>(
  2127. pFloat+ 4* dwVertexShaderConsts);
  2128. }
  2129. // Pixel Shader Constants
  2130. if( m_RecFnCtr[ D3DDP2OP_SETPIXELSHADERCONST]!= NULL&&
  2131. dwPixelShaderConsts!= 0)
  2132. {
  2133. pCur->bCommand= D3DDP2OP_SETPIXELSHADERCONST;
  2134. pCur->wStateCount= 1;
  2135. D3DHAL_DP2SETPIXELSHADERCONST* pParam=
  2136. reinterpret_cast< D3DHAL_DP2SETPIXELSHADERCONST*>( pCur+ 1);
  2137. pParam->dwRegister= 0;
  2138. pParam->dwCount= dwPixelShaderConsts;
  2139. D3DVALUE* pFloat= reinterpret_cast< D3DVALUE*>( pParam+ 1);
  2140. pCur= reinterpret_cast< D3DHAL_DP2COMMAND*>(
  2141. pFloat+ 4* dwPixelShaderConsts);
  2142. }
  2143. assert( reinterpret_cast< D3DHAL_DP2COMMAND*>( pCur)== pEndSSet);
  2144. // Finally, build stateset.
  2145. pair< TSSDB::iterator, bool> Ret;
  2146. try {
  2147. Ret= m_StateSetDB.insert( TSSDB::value_type(
  2148. dwStateSetId, TStateSet( *pSThis, pStartSSet, pEndSSet)));
  2149. assert( Ret.second);
  2150. } catch ( ... ) {
  2151. operator delete ( static_cast< void*>( pTempBuffer));
  2152. throw;
  2153. }
  2154. // Now, capture it.
  2155. Ret.first->second.Capture( *pSThis);
  2156. }
  2157. void CreateAndCapturePixelState( DWORD dwStateSetId)
  2158. {
  2159. #if defined( D3D_ENABLE_SHADOW_BUFFER)
  2160. #if defined( D3D_ENABLE_SHADOW_JITTER)
  2161. typedef block< D3DRENDERSTATETYPE, 44> TPixRSToCapture;
  2162. #else // !defined( D3D_ENABLE_SHADOW_JITTER)
  2163. typedef block< D3DRENDERSTATETYPE, 41> TPixRSToCapture;
  2164. #endif // !defined( D3D_ENABLE_SHADOW_JITTER)
  2165. #else // !defined( D3D_ENABLE_SHADOW_BUFFER)
  2166. typedef block< D3DRENDERSTATETYPE, 39> TPixRSToCapture;
  2167. #endif // !defined( D3D_ENABLE_SHADOW_BUFFER)
  2168. const TPixRSToCapture PixRSToCapture=
  2169. {
  2170. D3DRENDERSTATE_ZENABLE,
  2171. D3DRENDERSTATE_FILLMODE,
  2172. D3DRENDERSTATE_SHADEMODE,
  2173. D3DRENDERSTATE_LINEPATTERN,
  2174. D3DRENDERSTATE_ZWRITEENABLE,
  2175. D3DRENDERSTATE_ALPHATESTENABLE,
  2176. D3DRENDERSTATE_LASTPIXEL,
  2177. D3DRENDERSTATE_SRCBLEND,
  2178. D3DRENDERSTATE_DESTBLEND,
  2179. D3DRENDERSTATE_ZFUNC,
  2180. D3DRENDERSTATE_ALPHAREF,
  2181. D3DRENDERSTATE_ALPHAFUNC,
  2182. D3DRENDERSTATE_DITHERENABLE,
  2183. D3DRENDERSTATE_STIPPLEDALPHA,
  2184. D3DRENDERSTATE_FOGSTART,
  2185. D3DRENDERSTATE_FOGEND,
  2186. D3DRENDERSTATE_FOGDENSITY,
  2187. D3DRENDERSTATE_EDGEANTIALIAS,
  2188. D3DRENDERSTATE_ALPHABLENDENABLE,
  2189. D3DRENDERSTATE_ZBIAS,
  2190. D3DRENDERSTATE_STENCILENABLE,
  2191. D3DRENDERSTATE_STENCILFAIL,
  2192. D3DRENDERSTATE_STENCILZFAIL,
  2193. D3DRENDERSTATE_STENCILPASS,
  2194. D3DRENDERSTATE_STENCILFUNC,
  2195. D3DRENDERSTATE_STENCILREF,
  2196. D3DRENDERSTATE_STENCILMASK,
  2197. D3DRENDERSTATE_STENCILWRITEMASK,
  2198. D3DRENDERSTATE_TEXTUREFACTOR,
  2199. D3DRENDERSTATE_WRAP0,
  2200. D3DRENDERSTATE_WRAP1,
  2201. D3DRENDERSTATE_WRAP2,
  2202. D3DRENDERSTATE_WRAP3,
  2203. D3DRENDERSTATE_WRAP4,
  2204. D3DRENDERSTATE_WRAP5,
  2205. D3DRENDERSTATE_WRAP6,
  2206. D3DRENDERSTATE_WRAP7,
  2207. D3DRS_COLORWRITEENABLE,
  2208. D3DRS_BLENDOP,
  2209. #if defined( D3D_ENABLE_SHADOW_BUFFER)
  2210. D3DRS_ZSLOPESCALE,
  2211. D3DRS_ZCLAMP,
  2212. #if defined( D3D_ENABLE_SHADOW_JITTER)
  2213. D3DRS_JITZBIASMIN,
  2214. D3DRS_JITZBIASMAX,
  2215. D3DRS_JITSHADOWSIZE,
  2216. #endif // defined( D3D_ENABLE_SHADOW_JITTER)
  2217. #endif // defined( D3D_ENABLE_SHADOW_BUFFER)
  2218. };
  2219. #if defined( D3D_ENABLE_SHADOW_BUFFER)
  2220. #if defined( D3D_ENABLE_SHADOW_JITTER)
  2221. assert( D3DRS_JITSHADOWSIZE== *PixRSToCapture.rbegin());
  2222. #else // !defined( D3D_ENABLE_SHADOW_JITTER)
  2223. assert( D3DRS_ZCLAMP== *PixRSToCapture.rbegin());
  2224. #endif // !defined( D3D_ENABLE_SHADOW_JITTER)
  2225. #else // !defined( D3D_ENABLE_SHADOW_BUFFER)
  2226. assert( D3DRS_BLENDOP== *PixRSToCapture.rbegin());
  2227. #endif // !defined( D3D_ENABLE_SHADOW_BUFFER)
  2228. #if defined( D3D_ENABLE_SHADOW_BUFFER)
  2229. typedef block< D3DTEXTURESTAGESTATETYPE, 30> TPixTSSToCapture;
  2230. #else // !defined( D3D_ENABLE_SHADOW_BUFFER)
  2231. typedef block< D3DTEXTURESTAGESTATETYPE, 27> TPixTSSToCapture;
  2232. #endif // !defined( D3D_ENABLE_SHADOW_BUFFER)
  2233. const TPixTSSToCapture PixTSSToCapture=
  2234. {
  2235. D3DTSS_COLOROP,
  2236. D3DTSS_COLORARG1,
  2237. D3DTSS_COLORARG2,
  2238. D3DTSS_ALPHAOP,
  2239. D3DTSS_ALPHAARG1,
  2240. D3DTSS_ALPHAARG2,
  2241. D3DTSS_BUMPENVMAT00,
  2242. D3DTSS_BUMPENVMAT01,
  2243. D3DTSS_BUMPENVMAT10,
  2244. D3DTSS_BUMPENVMAT11,
  2245. D3DTSS_TEXCOORDINDEX,
  2246. D3DTSS_ADDRESSU,
  2247. D3DTSS_ADDRESSV,
  2248. D3DTSS_BORDERCOLOR,
  2249. D3DTSS_MAGFILTER,
  2250. D3DTSS_MINFILTER,
  2251. D3DTSS_MIPFILTER,
  2252. D3DTSS_MIPMAPLODBIAS,
  2253. D3DTSS_MAXMIPLEVEL,
  2254. D3DTSS_MAXANISOTROPY,
  2255. D3DTSS_BUMPENVLSCALE,
  2256. D3DTSS_BUMPENVLOFFSET,
  2257. D3DTSS_TEXTURETRANSFORMFLAGS,
  2258. D3DTSS_ADDRESSW,
  2259. D3DTSS_COLORARG0,
  2260. D3DTSS_ALPHAARG0,
  2261. D3DTSS_RESULTARG,
  2262. #if defined( D3D_ENABLE_SHADOW_BUFFER)
  2263. D3DTSS_SHADOWNEARW,
  2264. D3DTSS_SHADOWFARW,
  2265. D3DTSS_SHADOWBUFFERENABLE,
  2266. #endif // defined( D3D_ENABLE_SHADOW_BUFFER)
  2267. };
  2268. #if defined( D3D_ENABLE_SHADOW_BUFFER)
  2269. assert( D3DTSS_SHADOWBUFFERENABLE== *PixTSSToCapture.rbegin());
  2270. #else // !defined( D3D_ENABLE_SHADOW_BUFFER)
  2271. assert( D3DTSS_RESULTARG== *PixTSSToCapture.rbegin());
  2272. #endif // !defined( D3D_ENABLE_SHADOW_BUFFER)
  2273. TSuper* pSThis= static_cast< TSuper*>( this);
  2274. typedef TSuper::TPerDDrawData TPerDDrawData;
  2275. typedef TPerDDrawData::TDriver TDriver;
  2276. const DWORD dwTextureStages( D3DHAL_TSS_MAXSTAGES);
  2277. const DWORD dwPixelShaderConsts( GetNumPixelShaderConstReg(
  2278. TDriver::GetCaps().PixelShaderVersion));
  2279. size_t uiRecDP2BufferSize( 0);
  2280. // Pass 1: Calculate size of DP2 buffer required.
  2281. // Render States
  2282. if( m_RecFnCtr[ D3DDP2OP_RENDERSTATE]!= NULL)
  2283. { assert( m_DefFnCtr[ D3DDP2OP_RENDERSTATE]!= DP2Empty);
  2284. uiRecDP2BufferSize+= sizeof( D3DHAL_DP2COMMAND)+
  2285. PixRSToCapture.size()* sizeof( D3DHAL_DP2RENDERSTATE);
  2286. }
  2287. else { assert( m_DefFnCtr[ D3DDP2OP_RENDERSTATE]== DP2Empty); }
  2288. // Texture States
  2289. if( m_RecFnCtr[ D3DDP2OP_TEXTURESTAGESTATE]!= NULL&&
  2290. dwTextureStages!= 0)
  2291. { assert( m_DefFnCtr[ D3DDP2OP_TEXTURESTAGESTATE]!= DP2Empty);
  2292. uiRecDP2BufferSize+= sizeof( D3DHAL_DP2COMMAND)+ dwTextureStages*
  2293. PixTSSToCapture.size()* sizeof( D3DHAL_DP2TEXTURESTAGESTATE);
  2294. }
  2295. else { assert( m_DefFnCtr[ D3DDP2OP_TEXTURESTAGESTATE]== DP2Empty); }
  2296. // Pixel Shader
  2297. if( m_RecFnCtr[ D3DDP2OP_SETPIXELSHADER]!= NULL)
  2298. { assert( m_DefFnCtr[ D3DDP2OP_SETPIXELSHADER]!= DP2Empty);
  2299. uiRecDP2BufferSize+= sizeof( D3DHAL_DP2COMMAND)+
  2300. sizeof( D3DHAL_DP2PIXELSHADER);
  2301. }
  2302. else { assert( m_DefFnCtr[ D3DDP2OP_SETPIXELSHADER]== DP2Empty); }
  2303. // Pixel Shader Constants
  2304. if( m_RecFnCtr[ D3DDP2OP_SETPIXELSHADERCONST]!= NULL&&
  2305. dwPixelShaderConsts!= 0)
  2306. { assert( m_DefFnCtr[ D3DDP2OP_SETPIXELSHADERCONST]!= DP2Empty);
  2307. uiRecDP2BufferSize+= sizeof( D3DHAL_DP2COMMAND)+
  2308. sizeof( D3DHAL_DP2SETPIXELSHADERCONST)+
  2309. dwPixelShaderConsts* 4* sizeof(D3DVALUE);
  2310. }
  2311. else { assert( m_DefFnCtr[ D3DDP2OP_SETPIXELSHADERCONST]== DP2Empty); }
  2312. // Pass 2: Build command buffer for states.
  2313. UINT8* pTempBuffer= NULL;
  2314. try {
  2315. pTempBuffer= reinterpret_cast< UINT8*>(
  2316. operator new ( uiRecDP2BufferSize));
  2317. } catch ( ... ) {
  2318. }
  2319. if( NULL== pTempBuffer)
  2320. throw bad_alloc( "Not enough room for StateSet");
  2321. D3DHAL_DP2COMMAND* pStartSSet= reinterpret_cast< D3DHAL_DP2COMMAND*>(
  2322. pTempBuffer);
  2323. D3DHAL_DP2COMMAND* pCur= pStartSSet;
  2324. D3DHAL_DP2COMMAND* pEndSSet= reinterpret_cast< D3DHAL_DP2COMMAND*>(
  2325. pTempBuffer+ uiRecDP2BufferSize);
  2326. // Render States
  2327. if( m_RecFnCtr[ D3DDP2OP_RENDERSTATE]!= NULL)
  2328. {
  2329. pCur->bCommand= D3DDP2OP_RENDERSTATE;
  2330. pCur->wStateCount= static_cast< WORD>( PixRSToCapture.size());
  2331. D3DHAL_DP2RENDERSTATE* pParam=
  2332. reinterpret_cast< D3DHAL_DP2RENDERSTATE*>( pCur+ 1);
  2333. TPixRSToCapture::const_iterator itRS( PixRSToCapture.begin());
  2334. while( itRS!= PixRSToCapture.end())
  2335. {
  2336. pParam->RenderState= *itRS;
  2337. ++itRS;
  2338. ++pParam;
  2339. }
  2340. pCur= reinterpret_cast< D3DHAL_DP2COMMAND*>( pParam);
  2341. }
  2342. // Texture States
  2343. if( m_RecFnCtr[ D3DDP2OP_TEXTURESTAGESTATE]!= NULL&&
  2344. dwTextureStages!= 0)
  2345. {
  2346. pCur->bCommand= D3DDP2OP_TEXTURESTAGESTATE;
  2347. pCur->wStateCount= static_cast< WORD>( dwTextureStages*
  2348. PixTSSToCapture.size());
  2349. D3DHAL_DP2TEXTURESTAGESTATE* pParam=
  2350. reinterpret_cast< D3DHAL_DP2TEXTURESTAGESTATE*>( pCur+ 1);
  2351. for( WORD wStage( 0); wStage< dwTextureStages; ++wStage)
  2352. {
  2353. TPixTSSToCapture::const_iterator itTSS( PixTSSToCapture.begin());
  2354. while( itTSS!= PixTSSToCapture.end())
  2355. {
  2356. pParam->wStage= wStage;
  2357. pParam->TSState= *itTSS;
  2358. ++itTSS;
  2359. ++pParam;
  2360. }
  2361. }
  2362. pCur= reinterpret_cast< D3DHAL_DP2COMMAND*>( pParam);
  2363. }
  2364. // Pixel Shader
  2365. if( m_RecFnCtr[ D3DDP2OP_SETPIXELSHADER]!= NULL)
  2366. {
  2367. pCur->bCommand= D3DDP2OP_SETPIXELSHADER;
  2368. pCur->wStateCount= 1;
  2369. D3DHAL_DP2PIXELSHADER* pParam=
  2370. reinterpret_cast< D3DHAL_DP2PIXELSHADER*>( pCur+ 1);
  2371. pCur= reinterpret_cast< D3DHAL_DP2COMMAND*>( pParam+ 1);
  2372. }
  2373. // Pixel Shader Constants
  2374. if( m_RecFnCtr[ D3DDP2OP_SETPIXELSHADERCONST]!= NULL&&
  2375. dwPixelShaderConsts!= 0)
  2376. {
  2377. pCur->bCommand= D3DDP2OP_SETPIXELSHADERCONST;
  2378. pCur->wStateCount= 1;
  2379. D3DHAL_DP2SETPIXELSHADERCONST* pParam=
  2380. reinterpret_cast< D3DHAL_DP2SETPIXELSHADERCONST*>( pCur+ 1);
  2381. pParam->dwRegister= 0;
  2382. pParam->dwCount= dwPixelShaderConsts;
  2383. D3DVALUE* pFloat= reinterpret_cast< D3DVALUE*>( pParam+ 1);
  2384. pCur= reinterpret_cast< D3DHAL_DP2COMMAND*>(
  2385. pFloat+ 4* dwPixelShaderConsts);
  2386. }
  2387. assert( reinterpret_cast< D3DHAL_DP2COMMAND*>( pCur)== pEndSSet);
  2388. // Finally, build stateset.
  2389. pair< TSSDB::iterator, bool> Ret;
  2390. try {
  2391. Ret= m_StateSetDB.insert( TSSDB::value_type(
  2392. dwStateSetId, TStateSet( *pSThis, pStartSSet, pEndSSet)));
  2393. assert( Ret.second);
  2394. } catch ( ... ) {
  2395. operator delete ( static_cast< void*>( pTempBuffer));
  2396. throw;
  2397. }
  2398. // Now, capture it.
  2399. Ret.first->second.Capture( *pSThis);
  2400. }
  2401. void CreateAndCaptureVertexState( DWORD dwStateSetId)
  2402. {
  2403. typedef block< D3DRENDERSTATETYPE, 38> TVtxRSToCapture;
  2404. const TVtxRSToCapture VtxRSToCapture=
  2405. {
  2406. D3DRENDERSTATE_SPECULARENABLE,
  2407. D3DRENDERSTATE_SHADEMODE,
  2408. D3DRENDERSTATE_CULLMODE,
  2409. D3DRENDERSTATE_FOGENABLE,
  2410. D3DRENDERSTATE_FOGCOLOR,
  2411. D3DRENDERSTATE_FOGTABLEMODE,
  2412. D3DRENDERSTATE_FOGSTART,
  2413. D3DRENDERSTATE_FOGEND,
  2414. D3DRENDERSTATE_FOGDENSITY,
  2415. D3DRENDERSTATE_RANGEFOGENABLE,
  2416. D3DRENDERSTATE_AMBIENT,
  2417. D3DRENDERSTATE_COLORVERTEX,
  2418. D3DRENDERSTATE_FOGVERTEXMODE,
  2419. D3DRENDERSTATE_CLIPPING,
  2420. D3DRENDERSTATE_LIGHTING,
  2421. D3DRENDERSTATE_NORMALIZENORMALS,
  2422. D3DRENDERSTATE_LOCALVIEWER,
  2423. D3DRENDERSTATE_EMISSIVEMATERIALSOURCE,
  2424. D3DRENDERSTATE_AMBIENTMATERIALSOURCE,
  2425. D3DRENDERSTATE_DIFFUSEMATERIALSOURCE,
  2426. D3DRENDERSTATE_SPECULARMATERIALSOURCE,
  2427. D3DRENDERSTATE_VERTEXBLEND,
  2428. D3DRENDERSTATE_CLIPPLANEENABLE,
  2429. D3DRS_SOFTWAREVERTEXPROCESSING,
  2430. D3DRS_POINTSIZE,
  2431. D3DRS_POINTSIZE_MIN,
  2432. D3DRS_POINTSPRITEENABLE,
  2433. D3DRS_POINTSCALEENABLE,
  2434. D3DRS_POINTSCALE_A,
  2435. D3DRS_POINTSCALE_B,
  2436. D3DRS_POINTSCALE_C,
  2437. D3DRS_MULTISAMPLEANTIALIAS,
  2438. D3DRS_MULTISAMPLEMASK,
  2439. D3DRS_PATCHEDGESTYLE,
  2440. D3DRS_PATCHSEGMENTS,
  2441. D3DRS_POINTSIZE_MAX,
  2442. D3DRS_INDEXEDVERTEXBLENDENABLE,
  2443. D3DRS_TWEENFACTOR
  2444. };
  2445. assert( D3DRS_TWEENFACTOR== *VtxRSToCapture.rbegin());
  2446. typedef block< D3DTEXTURESTAGESTATETYPE, 2> TVtxTSSToCapture;
  2447. const TVtxTSSToCapture VtxTSSToCapture=
  2448. {
  2449. D3DTSS_TEXCOORDINDEX,
  2450. D3DTSS_TEXTURETRANSFORMFLAGS
  2451. };
  2452. assert( D3DTSS_TEXTURETRANSFORMFLAGS== *VtxTSSToCapture.rbegin());
  2453. TSuper* pSThis= static_cast< TSuper*>( this);
  2454. typedef TSuper::TPerDDrawData TPerDDrawData;
  2455. typedef TPerDDrawData::TDriver TDriver;
  2456. const DWORD dwTextureStages( D3DHAL_TSS_MAXSTAGES);
  2457. const DWORD dwVertexShaderConsts( TDriver::GetCaps().MaxVertexShaderConst);
  2458. DWORD dwActiveLights( 0);
  2459. size_t uiRecDP2BufferSize( 0);
  2460. // Pass 1: Calculate size of DP2 buffer required.
  2461. // Render States
  2462. if( m_RecFnCtr[ D3DDP2OP_RENDERSTATE]!= NULL)
  2463. { assert( m_DefFnCtr[ D3DDP2OP_RENDERSTATE]!= DP2Empty);
  2464. uiRecDP2BufferSize+= sizeof( D3DHAL_DP2COMMAND)+
  2465. VtxRSToCapture.size()* sizeof( D3DHAL_DP2RENDERSTATE);
  2466. }
  2467. else { assert( m_DefFnCtr[ D3DDP2OP_RENDERSTATE]== DP2Empty); }
  2468. // Texture States
  2469. if( m_RecFnCtr[ D3DDP2OP_TEXTURESTAGESTATE]!= NULL&&
  2470. dwTextureStages!= 0)
  2471. { assert( m_DefFnCtr[ D3DDP2OP_TEXTURESTAGESTATE]!= DP2Empty);
  2472. uiRecDP2BufferSize+= sizeof( D3DHAL_DP2COMMAND)+ dwTextureStages*
  2473. VtxTSSToCapture.size()* sizeof( D3DHAL_DP2TEXTURESTAGESTATE);
  2474. }
  2475. else { assert( m_DefFnCtr[ D3DDP2OP_TEXTURESTAGESTATE]== DP2Empty); }
  2476. // Lights
  2477. if( m_RecFnCtr[ D3DDP2OP_CREATELIGHT]!= NULL)
  2478. { assert( m_DefFnCtr[ D3DDP2OP_SETLIGHT]!= DP2Empty);
  2479. assert( m_DefFnCtr[ D3DDP2OP_CREATELIGHT]!= DP2Empty);
  2480. // Special exception here. First, ask how many active lights there
  2481. // are. We'll then prepare a buffer that the RecFnCtr function
  2482. // will have to know what to do with (as this is the only case
  2483. // that is not obvious how to handle). RecFnCtr will key off
  2484. // bCommand== 0.
  2485. const D3DHAL_DP2COMMAND DP2Cmd= {
  2486. static_cast< D3DHAL_DP2OPERATION>( 0), 0 };
  2487. // Ask for how many active lights in DP2ActiveLights.dwIndex;
  2488. D3DHAL_DP2CREATELIGHT DP2ActiveLights= { 0 };
  2489. (pSThis->*m_RecFnCtr[ D3DDP2OP_CREATELIGHT])(
  2490. &DP2Cmd, &DP2ActiveLights);
  2491. dwActiveLights= DP2ActiveLights.dwIndex;
  2492. if( dwActiveLights!= 0)
  2493. {
  2494. // Create structures.
  2495. uiRecDP2BufferSize+= sizeof( D3DHAL_DP2COMMAND)+ dwActiveLights*
  2496. sizeof( D3DHAL_DP2CREATELIGHT);
  2497. // Set structures.
  2498. uiRecDP2BufferSize+= sizeof( D3DHAL_DP2COMMAND)+ dwActiveLights*
  2499. (2* sizeof( D3DHAL_DP2SETLIGHT)+ sizeof( D3DLIGHT8));
  2500. }
  2501. }
  2502. else {
  2503. assert( m_DefFnCtr[ D3DDP2OP_SETLIGHT]== DP2Empty);
  2504. assert( m_DefFnCtr[ D3DDP2OP_CREATELIGHT]== DP2Empty);
  2505. }
  2506. // Vertex Shader
  2507. if( m_RecFnCtr[ D3DDP2OP_SETVERTEXSHADER]!= NULL)
  2508. { assert( m_DefFnCtr[ D3DDP2OP_SETVERTEXSHADER]!= DP2Empty);
  2509. uiRecDP2BufferSize+= sizeof( D3DHAL_DP2COMMAND)+
  2510. sizeof( D3DHAL_DP2VERTEXSHADER);
  2511. }
  2512. else { assert( m_DefFnCtr[ D3DDP2OP_SETVERTEXSHADER]== DP2Empty); }
  2513. // Vertex Shader Constants
  2514. if( m_RecFnCtr[ D3DDP2OP_SETVERTEXSHADERCONST]!= NULL&&
  2515. dwVertexShaderConsts!= 0)
  2516. { assert( m_DefFnCtr[ D3DDP2OP_SETVERTEXSHADERCONST]!= DP2Empty);
  2517. uiRecDP2BufferSize+= sizeof( D3DHAL_DP2COMMAND)+
  2518. sizeof( D3DHAL_DP2SETVERTEXSHADERCONST)+
  2519. dwVertexShaderConsts* 4* sizeof(D3DVALUE);
  2520. }
  2521. else { assert( m_DefFnCtr[ D3DDP2OP_SETVERTEXSHADERCONST]== DP2Empty); }
  2522. // Pass 2: Build command buffer for states.
  2523. UINT8* pTempBuffer= NULL;
  2524. try {
  2525. pTempBuffer= reinterpret_cast< UINT8*>(
  2526. operator new ( uiRecDP2BufferSize));
  2527. } catch ( ... ) {
  2528. }
  2529. if( NULL== pTempBuffer)
  2530. throw bad_alloc( "Not enough room for StateSet");
  2531. D3DHAL_DP2COMMAND* pStartSSet= reinterpret_cast< D3DHAL_DP2COMMAND*>(
  2532. pTempBuffer);
  2533. D3DHAL_DP2COMMAND* pCur= pStartSSet;
  2534. D3DHAL_DP2COMMAND* pEndSSet= reinterpret_cast< D3DHAL_DP2COMMAND*>(
  2535. pTempBuffer+ uiRecDP2BufferSize);
  2536. // Render States
  2537. if( m_RecFnCtr[ D3DDP2OP_RENDERSTATE]!= NULL)
  2538. {
  2539. pCur->bCommand= D3DDP2OP_RENDERSTATE;
  2540. pCur->wStateCount= static_cast< WORD>( VtxRSToCapture.size());
  2541. D3DHAL_DP2RENDERSTATE* pParam=
  2542. reinterpret_cast< D3DHAL_DP2RENDERSTATE*>( pCur+ 1);
  2543. TVtxRSToCapture::const_iterator itRS( VtxRSToCapture.begin());
  2544. while( itRS!= VtxRSToCapture.end())
  2545. {
  2546. pParam->RenderState= *itRS;
  2547. ++itRS;
  2548. ++pParam;
  2549. }
  2550. pCur= reinterpret_cast< D3DHAL_DP2COMMAND*>( pParam);
  2551. }
  2552. // Texture States
  2553. if( m_RecFnCtr[ D3DDP2OP_TEXTURESTAGESTATE]!= NULL&&
  2554. dwTextureStages!= 0)
  2555. {
  2556. pCur->bCommand= D3DDP2OP_TEXTURESTAGESTATE;
  2557. pCur->wStateCount= static_cast< WORD>( dwTextureStages*
  2558. VtxTSSToCapture.size());
  2559. D3DHAL_DP2TEXTURESTAGESTATE* pParam=
  2560. reinterpret_cast< D3DHAL_DP2TEXTURESTAGESTATE*>( pCur+ 1);
  2561. for( WORD wStage( 0); wStage< dwTextureStages; ++wStage)
  2562. {
  2563. TVtxTSSToCapture::const_iterator itTSS( VtxTSSToCapture.begin());
  2564. while( itTSS!= VtxTSSToCapture.end())
  2565. {
  2566. pParam->wStage= wStage;
  2567. pParam->TSState= *itTSS;
  2568. ++itTSS;
  2569. ++pParam;
  2570. }
  2571. }
  2572. pCur= reinterpret_cast< D3DHAL_DP2COMMAND*>( pParam);
  2573. }
  2574. // Lights
  2575. if( m_RecFnCtr[ D3DDP2OP_CREATELIGHT]!= NULL&& dwActiveLights!= 0)
  2576. {
  2577. // Special exception here. First, we asked how many active lights
  2578. // there were. The RecFnCtr function will have to know what to do
  2579. // with this buffer. We now give it a chance to fill in the
  2580. // light ids. RecFnCtr will key off bCommand== 0.
  2581. pCur->bCommand= static_cast< D3DHAL_DP2OPERATION>( 0);
  2582. pCur->wStateCount= static_cast< WORD>( dwActiveLights);
  2583. D3DHAL_DP2CREATELIGHT* pParam=
  2584. reinterpret_cast< D3DHAL_DP2CREATELIGHT*>( pCur+ 1);
  2585. (pSThis->*m_RecFnCtr[ D3DDP2OP_CREATELIGHT])(
  2586. pCur, pParam);
  2587. // Change back the bCommand for proper usage later.
  2588. pCur->bCommand= D3DDP2OP_CREATELIGHT;
  2589. pCur= reinterpret_cast< D3DHAL_DP2COMMAND*>( pParam+ dwActiveLights);
  2590. // Now, with the light ids in the CREATELIGHT structures, we can
  2591. // fill out SETLIGHT structures with ids correctly.
  2592. pCur->bCommand= D3DDP2OP_SETLIGHT;
  2593. pCur->wStateCount= static_cast< WORD>( 2* dwActiveLights);
  2594. D3DHAL_DP2SETLIGHT* pSParam=
  2595. reinterpret_cast< D3DHAL_DP2SETLIGHT*>( pCur+ 1);
  2596. for( DWORD dwL( 0); dwL< dwActiveLights; ++dwL)
  2597. {
  2598. pSParam->dwIndex= pParam->dwIndex;
  2599. pSParam->dwDataType= D3DHAL_SETLIGHT_DATA;
  2600. D3DLIGHT8* pLight= reinterpret_cast< D3DLIGHT8*>( pSParam+ 1);
  2601. pSParam= reinterpret_cast< D3DHAL_DP2SETLIGHT*>( pLight+ 1);
  2602. pSParam->dwIndex= pParam->dwIndex;
  2603. pSParam->dwDataType= D3DHAL_SETLIGHT_DISABLE;
  2604. ++pParam;
  2605. ++pSParam;
  2606. }
  2607. pCur= reinterpret_cast< D3DHAL_DP2COMMAND*>( pSParam);
  2608. }
  2609. // Vertex Shader
  2610. if( m_RecFnCtr[ D3DDP2OP_SETVERTEXSHADER]!= NULL)
  2611. {
  2612. pCur->bCommand= D3DDP2OP_SETVERTEXSHADER;
  2613. pCur->wStateCount= 1;
  2614. D3DHAL_DP2VERTEXSHADER* pParam=
  2615. reinterpret_cast< D3DHAL_DP2VERTEXSHADER*>( pCur+ 1);
  2616. pCur= reinterpret_cast< D3DHAL_DP2COMMAND*>( pParam+ 1);
  2617. }
  2618. // Vertex Shader Constants
  2619. if( m_RecFnCtr[ D3DDP2OP_SETVERTEXSHADERCONST]!= NULL&&
  2620. dwVertexShaderConsts!= 0)
  2621. {
  2622. pCur->bCommand= D3DDP2OP_SETVERTEXSHADERCONST;
  2623. pCur->wStateCount= 1;
  2624. D3DHAL_DP2SETVERTEXSHADERCONST* pParam=
  2625. reinterpret_cast< D3DHAL_DP2SETVERTEXSHADERCONST*>( pCur+ 1);
  2626. pParam->dwRegister= 0;
  2627. pParam->dwCount= dwVertexShaderConsts;
  2628. D3DVALUE* pFloat= reinterpret_cast< D3DVALUE*>( pParam+ 1);
  2629. pCur= reinterpret_cast< D3DHAL_DP2COMMAND*>(
  2630. pFloat+ 4* dwVertexShaderConsts);
  2631. }
  2632. assert( reinterpret_cast< D3DHAL_DP2COMMAND*>( pCur)== pEndSSet);
  2633. // Finally, build stateset.
  2634. pair< TSSDB::iterator, bool> Ret;
  2635. try {
  2636. Ret= m_StateSetDB.insert( TSSDB::value_type(
  2637. dwStateSetId, TStateSet( *pSThis, pStartSSet, pEndSSet)));
  2638. assert( Ret.second);
  2639. } catch ( ... ) {
  2640. operator delete ( static_cast< void*>( pTempBuffer));
  2641. throw;
  2642. }
  2643. // Now, capture it.
  2644. Ret.first->second.Capture( *pSThis);
  2645. }
  2646. // This member function handles the DP2OP_STATESET, which communicates back
  2647. // to the DrawPrimitives2 entry point handler to implement state sets.
  2648. HRESULT DP2StateSet( TDP2Data& DP2Data,
  2649. const D3DHAL_DP2COMMAND* pCmd, const void* pP)
  2650. {
  2651. const D3DHAL_DP2STATESET* pParam=
  2652. reinterpret_cast<const D3DHAL_DP2STATESET*>(pP);
  2653. HRESULT hr( DD_OK);
  2654. WORD wStateCount( pCmd->wStateCount);
  2655. TSuper* pSThis= static_cast<TSuper*>(this);
  2656. if( wStateCount!= 0) do
  2657. {
  2658. switch( pParam->dwOperation)
  2659. {
  2660. case( D3DHAL_STATESETCREATE):
  2661. assert( !m_bRecordingStateSet);
  2662. typedef TSuper::TPerDDrawData TPerDDrawData;
  2663. typedef TPerDDrawData::TDriver TDriver;
  2664. assert((TDriver::GetCaps().DevCaps& D3DDEVCAPS_PUREDEVICE)!= 0);
  2665. try {
  2666. switch( pParam->sbType)
  2667. {
  2668. case( D3DSBT_ALL):
  2669. pSThis->CreateAndCaptureAllState( pParam->dwParam);
  2670. break;
  2671. case( D3DSBT_PIXELSTATE):
  2672. pSThis->CreateAndCapturePixelState( pParam->dwParam);
  2673. break;
  2674. case( D3DSBT_VERTEXSTATE):
  2675. pSThis->CreateAndCaptureVertexState( pParam->dwParam);
  2676. break;
  2677. default: {
  2678. const bool Unrecognized_StateSetCreate_Operation( false);
  2679. assert( Unrecognized_StateSetCreate_Operation);
  2680. } break;
  2681. }
  2682. } catch( bad_alloc ba) {
  2683. return DDERR_OUTOFMEMORY;
  2684. }
  2685. break;
  2686. case( D3DHAL_STATESETBEGIN):
  2687. assert( 1== wStateCount);
  2688. assert( !m_bRecordingStateSet);
  2689. m_bRecordingStateSet= true;
  2690. hr= c_hrStateSetBegin;
  2691. // Returning this constant will break out of the parsing and
  2692. // notify DrawPrimitive2 entry point handler to create a state
  2693. // set.
  2694. break;
  2695. case( D3DHAL_STATESETCAPTURE):
  2696. if( !m_bRecordingStateSet)
  2697. {
  2698. // First, find the StateSet to capture.
  2699. typename TSSDB::iterator itSS(
  2700. m_StateSetDB.find( pParam->dwParam));
  2701. assert( itSS!= m_StateSetDB.end());
  2702. // Capture it.
  2703. itSS->second.Capture( *pSThis);
  2704. }
  2705. break;
  2706. case( D3DHAL_STATESETDELETE):
  2707. if( !m_bRecordingStateSet)
  2708. {
  2709. m_StateSetDB.erase( pParam->dwParam);
  2710. }
  2711. break;
  2712. case( D3DHAL_STATESETEND):
  2713. assert( 1== wStateCount);
  2714. assert( m_bRecordingStateSet);
  2715. m_bRecordingStateSet= false;
  2716. m_dwStateSetId= pParam->dwParam;
  2717. m_pEndStateSet= pCmd;
  2718. hr= c_hrStateSetEnd;
  2719. break;
  2720. case( D3DHAL_STATESETEXECUTE):
  2721. if( !m_bRecordingStateSet)
  2722. {
  2723. // First, find the StateSet to execute.
  2724. typename TSSDB::iterator itSS(
  2725. m_StateSetDB.find( pParam->dwParam));
  2726. assert( itSS!= m_StateSetDB.end());
  2727. // "Push" value of m_bExecutingStateSet, then set to true.
  2728. // "Pop" will occur at destruction.
  2729. CPushValue< bool> m_PushExecutingBit(
  2730. m_bExecutingStateSet, true);
  2731. // Execute it.
  2732. itSS->second.Execute( *pSThis);
  2733. }
  2734. break;
  2735. default: {
  2736. const bool Unrecognized_StateSet_Operation( false);
  2737. assert( Unrecognized_StateSet_Operation);
  2738. } break;
  2739. }
  2740. ++pParam;
  2741. } while( SUCCEEDED( hr) && --wStateCount);
  2742. return hr;
  2743. }
  2744. // This function is used to record the current state of the context/ device
  2745. // into the command buffer.
  2746. void RecordCommandBuffer( D3DHAL_DP2COMMAND* pBeginSS,
  2747. D3DHAL_DP2COMMAND* pEndSS)
  2748. {
  2749. TSuper* pSThis= static_cast<TSuper*>(this);
  2750. CDP2CmdIterator<> itCur( pBeginSS);
  2751. const CDP2CmdIterator<> itEnd( pEndSS);
  2752. SDP2MFnParser DP2Parser;
  2753. TRMFnCaller RMFnCaller( *pSThis);
  2754. HRESULT hr( DD_OK);
  2755. while( itCur!= itEnd)
  2756. {
  2757. hr= DP2Parser.ParseDP2( RMFnCaller, m_RecFnCtr, itCur, itEnd);
  2758. assert( SUCCEEDED( hr));
  2759. // Ignore recording errors, except for debugging. Hopefully
  2760. // the processing of this DP2 command (when appling the state set)
  2761. // won't fault later.
  2762. if( FAILED( hr))
  2763. ++itCur;
  2764. }
  2765. }
  2766. // Primary reason for class, handling of this function for the context.
  2767. HRESULT DrawPrimitives2( PORTABLE_DRAWPRIMITIVES2DATA& dpd)
  2768. {
  2769. TSuper* pSThis= static_cast<TSuper*>(this);
  2770. TDP2Data DP2Data( dpd);
  2771. // If not currently executing a stateset (which might recursively call
  2772. // this function) notify start of DP2 entry point.
  2773. if( !m_bExecutingStateSet)
  2774. pSThis->OnBeginDrawPrimitives2( DP2Data);
  2775. typename TDP2DataCmds::const_iterator itCur(
  2776. DP2Data.GetCommands().begin() );
  2777. const typename TDP2DataCmds::const_iterator itEnd(
  2778. DP2Data.GetCommands().end() );
  2779. SDP2MFnParser DP2Parser;
  2780. TMFnCaller MFnCaller( *pSThis, DP2Data);
  2781. HRESULT hr( DD_OK);
  2782. do
  2783. {
  2784. hr= DP2Parser.ParseDP2( MFnCaller, m_DefFnCtr,
  2785. itCur, itEnd);
  2786. if( c_hrStateSetBegin== hr)
  2787. {
  2788. typename TDP2DataCmds::const_iterator itStartSSet( ++itCur);
  2789. {
  2790. TDP2MFnCtr FakeFnCtr;
  2791. typename TDP2MFnCtr::iterator itCurFake( FakeFnCtr.begin());
  2792. while( itCurFake!= FakeFnCtr.end())
  2793. *itCurFake++ = DP2Fake;
  2794. FakeFnCtr[ D3DDP2OP_STATESET]= DP2StateSet;
  2795. hr= DP2Parser.ParseDP2( MFnCaller, FakeFnCtr,
  2796. itCur, itEnd);
  2797. assert( c_hrStateSetEnd== hr);
  2798. itCur++;
  2799. }
  2800. try
  2801. {
  2802. pair< TSSDB::iterator, bool> Ret;
  2803. Ret= m_StateSetDB.insert( TSSDB::value_type( m_dwStateSetId,
  2804. TStateSet( *pSThis, itStartSSet, m_pEndStateSet)));
  2805. // There shouldn't be two statesets with the same Id.
  2806. assert( Ret.second);
  2807. hr= S_OK;
  2808. } catch( bad_alloc e) {
  2809. hr= DDERR_OUTOFMEMORY;
  2810. }
  2811. }
  2812. assert( c_hrStateSetEnd!= hr);
  2813. } while( SUCCEEDED(hr)&& itCur!= itEnd);
  2814. if( FAILED( hr))
  2815. {
  2816. const D3DHAL_DP2COMMAND* pS= itCur;
  2817. const D3DHAL_DP2COMMAND* pE= itEnd;
  2818. dpd.dwErrorOffset()= reinterpret_cast<const UINT8*>(pE)-
  2819. reinterpret_cast<const UINT8*>(pS);
  2820. }
  2821. // If not currently executing a stateset (which might recursively call
  2822. // this function) notify end of DP2 entry point.
  2823. if( !m_bExecutingStateSet)
  2824. pSThis->OnEndDrawPrimitives2( DP2Data);
  2825. return hr;
  2826. }
  2827. };
  2828. template< class TSuper, class TSS, class TSSDB, class TDP2D, class TDP2MFC,
  2829. class TDP2RMFC>
  2830. const HRESULT CStdDrawPrimitives2< TSuper, TSS, TSSDB, TDP2D, TDP2MFC,
  2831. TDP2RMFC>::c_hrStateSetBegin= S_FALSE+ 556;
  2832. template< class TSuper, class TSS, class TSSDB, class TDP2D, class TDP2MFC,
  2833. class TDP2RMFC>
  2834. const HRESULT CStdDrawPrimitives2< TSuper, TSS, TSSDB, TDP2D, TDP2MFC,
  2835. TDP2RMFC>::c_hrStateSetEnd= S_FALSE+ 557;
  2836. ////////////////////////////////////////////////////////////////////////////////
  2837. //
  2838. // CStdDP2ViewportInfoStore,
  2839. // CStdDP2WInfoStore,
  2840. // CStdDP2SetTransformStore,
  2841. // etc: CStdDP2xxxxxStore...
  2842. //
  2843. // These classes provide default DP2 operation support, typically just storing
  2844. // state. They have support for a notification mechanism, which delegates to
  2845. // the parent Context.
  2846. //
  2847. ////////////////////////////////////////////////////////////////////////////////
  2848. // MSVC doesn't support partial specialization or we could've had something
  2849. // elegant like:
  2850. //
  2851. // template< class TSuper, class TParam>
  2852. // class CStdDP2ParamStore {};
  2853. //
  2854. // for typical support like:
  2855. // CStdDP2ParamStore< ..., D3DHAL_DP2VIEWPORTINFO>
  2856. // CStdDP2ParamStore< ..., D3DHAL_DP2WINFO>
  2857. //
  2858. // with partial specializations for exceptions like:
  2859. //
  2860. // template< class TSuper>
  2861. // class CStdDP2ParamStore< TSuper, D3DHAL_DP2RENDERSTATE> {};
  2862. // template< class TSuper>
  2863. // class CStdDP2ParamStore< TSuper, D3DHAL_DP2TEXTURESTAGESTATE> {};
  2864. //
  2865. // So, without this support, it'll be easier for each class to have a unique
  2866. // name; as MSVC is currently buggy about inheriting from the same named class
  2867. // multiple times, even WITH a different template parameter.
  2868. //
  2869. // <Template Parameters>
  2870. // TSuper: Standard parent type which is inheriting from this child class.
  2871. // In this case, it should typically be the CMyContext type.
  2872. // TDP2Data: This is some kind of wrapper class for PORTABLE_DRAWPRIMITIVES2DATA
  2873. // The type is expected to inherit or emulate PORTABLE_DRAWPRIMITIVES2DATA's
  2874. // fields/ member variables, and should typically be consistent with
  2875. // CStdDrawPrimitives2< xxx >::TDP2Data.
  2876. //
  2877. template< class TSuper, class TDP2Data= CDP2DataWrap<> >
  2878. class CStdDP2ViewportInfoStore
  2879. {
  2880. protected: // Variables
  2881. D3DHAL_DP2VIEWPORTINFO m_Param;
  2882. protected: // Functions
  2883. CStdDP2ViewportInfoStore()
  2884. { }
  2885. explicit CStdDP2ViewportInfoStore( const D3DHAL_DP2VIEWPORTINFO& P)
  2886. :m_Param( P)
  2887. { }
  2888. ~CStdDP2ViewportInfoStore()
  2889. { }
  2890. D3DHAL_DP2VIEWPORTINFO NewDP2ViewportInfo( const D3DHAL_DP2VIEWPORTINFO&
  2891. CurParam, const D3DHAL_DP2VIEWPORTINFO& NewParam) const
  2892. { // Tell notifier to store the new param.
  2893. return NewParam;
  2894. }
  2895. public: // Fuctions
  2896. void GetDP2ViewportInfo( D3DHAL_DP2VIEWPORTINFO& GetParam) const
  2897. { GetParam= m_Param; }
  2898. operator D3DHAL_DP2VIEWPORTINFO() const
  2899. { return m_Param; }
  2900. HRESULT DP2ViewportInfo( TDP2Data&, const D3DHAL_DP2COMMAND* pCmd,
  2901. const void* pP)
  2902. {
  2903. TSuper* pSThis= static_cast<TSuper*>(this);
  2904. const D3DHAL_DP2VIEWPORTINFO* pParam=
  2905. reinterpret_cast< const D3DHAL_DP2VIEWPORTINFO*>( pP);
  2906. WORD wStateCount( pCmd->wStateCount);
  2907. if( wStateCount!= 0) do
  2908. {
  2909. m_Param= pSThis->NewDP2ViewportInfo( m_Param, *pParam);
  2910. ++pParam;
  2911. } while( --wStateCount!= 0);
  2912. return DD_OK;
  2913. }
  2914. HRESULT RecDP2ViewportInfo( const D3DHAL_DP2COMMAND* pCmd, void* pP)
  2915. {
  2916. D3DHAL_DP2VIEWPORTINFO* pParam=
  2917. reinterpret_cast< D3DHAL_DP2VIEWPORTINFO*>( pP);
  2918. WORD wStateCount( pCmd->wStateCount);
  2919. if( wStateCount!= 0) do
  2920. {
  2921. GetDP2ViewportInfo( *pParam);
  2922. ++pParam;
  2923. } while( --wStateCount!= 0);
  2924. return DD_OK;
  2925. }
  2926. };
  2927. //
  2928. // <Template Parameters>
  2929. // TSuper: Standard parent type which is inheriting from this child class.
  2930. // In this case, it should typically be the CMyContext type.
  2931. // TDP2Data: This is some kind of wrapper class for PORTABLE_DRAWPRIMITIVES2DATA
  2932. // The type is expected to inherit or emulate PORTABLE_DRAWPRIMITIVES2DATA's
  2933. // fields/ member variables, and should typically be consistent with
  2934. // CStdDrawPrimitives2< xxx >::TDP2Data.
  2935. //
  2936. template< class TSuper, class TDP2Data= CDP2DataWrap<> >
  2937. class CStdDP2WInfoStore
  2938. {
  2939. protected: // Variables
  2940. D3DHAL_DP2WINFO m_Param;
  2941. protected: // Functions
  2942. CStdDP2WInfoStore()
  2943. { }
  2944. explicit CStdDP2WInfoStore( const D3DHAL_DP2WINFO& P)
  2945. :m_Param( P)
  2946. { }
  2947. ~CStdDP2WInfoStore()
  2948. { }
  2949. D3DHAL_DP2WINFO NewDP2WInfo( const D3DHAL_DP2WINFO& CurParam,
  2950. const D3DHAL_DP2WINFO& NewParam) const
  2951. { // Tell notifier to store the new param.
  2952. return NewParam;
  2953. }
  2954. public: // Fuctions
  2955. void GetDP2WInfo( D3DHAL_DP2WINFO& GetParam) const
  2956. { GetParam= m_Param; }
  2957. operator D3DHAL_DP2WINFO() const
  2958. { return m_Param; }
  2959. HRESULT DP2WInfo( TDP2Data&, const D3DHAL_DP2COMMAND* pCmd,
  2960. const void* pP)
  2961. {
  2962. TSuper* pSThis= static_cast<TSuper*>(this);
  2963. const D3DHAL_DP2WINFO* pParam=
  2964. reinterpret_cast< const D3DHAL_DP2WINFO*>( pP);
  2965. WORD wStateCount( pCmd->wStateCount);
  2966. if( wStateCount!= 0) do
  2967. {
  2968. m_Param= pSThis->NewDP2WInfo( m_Param, *pParam);
  2969. ++pParam;
  2970. } while( --wStateCount!= 0);
  2971. return DD_OK;
  2972. }
  2973. HRESULT RecDP2WInfo( const D3DHAL_DP2COMMAND* pCmd, void* pP)
  2974. {
  2975. D3DHAL_DP2WINFO* pParam=
  2976. reinterpret_cast< D3DHAL_DP2WINFO*>( pP);
  2977. WORD wStateCount( pCmd->wStateCount);
  2978. if( wStateCount!= 0) do
  2979. {
  2980. GetDP2WInfo( *pParam);
  2981. ++pParam;
  2982. } while( --wStateCount!= 0);
  2983. return DD_OK;
  2984. }
  2985. };
  2986. //
  2987. // <Template Parameters>
  2988. // TSuper: Standard parent type which is inheriting from this child class.
  2989. // In this case, it should typically be the CMyContext type.
  2990. // TDP2Data: This is some kind of wrapper class for PORTABLE_DRAWPRIMITIVES2DATA
  2991. // The type is expected to inherit or emulate PORTABLE_DRAWPRIMITIVES2DATA's
  2992. // fields/ member variables, and should typically be consistent with
  2993. // CStdDrawPrimitives2< xxx >::TDP2Data.
  2994. //
  2995. template< class TSuper, class TDP2Data= CDP2DataWrap<> >
  2996. class CStdDP2ZRangeStore
  2997. {
  2998. protected: // Variables
  2999. D3DHAL_DP2ZRANGE m_Param;
  3000. protected: // Functions
  3001. CStdDP2ZRangeStore()
  3002. { }
  3003. explicit CStdDP2ZRangeStore( const D3DHAL_DP2ZRANGE& P)
  3004. :m_Param( P)
  3005. { }
  3006. ~CStdDP2ZRangeStore()
  3007. { }
  3008. D3DHAL_DP2ZRANGE NewDP2ZRange( const D3DHAL_DP2ZRANGE& CurParam,
  3009. const D3DHAL_DP2ZRANGE& NewParam) const
  3010. { // Tell notifier to store the new param.
  3011. return NewParam;
  3012. }
  3013. public: // Fuctions
  3014. void GetDP2ZRange( D3DHAL_DP2ZRANGE& GetParam) const
  3015. { GetParam= m_Param; }
  3016. operator D3DHAL_DP2ZRANGE() const
  3017. { return m_Param; }
  3018. HRESULT DP2ZRange( TDP2Data&, const D3DHAL_DP2COMMAND* pCmd,
  3019. const void* pP)
  3020. {
  3021. TSuper* pSThis= static_cast<TSuper*>(this);
  3022. const D3DHAL_DP2ZRANGE* pParam=
  3023. reinterpret_cast< const D3DHAL_DP2ZRANGE*>( pP);
  3024. WORD wStateCount( pCmd->wStateCount);
  3025. if( wStateCount!= 0) do
  3026. {
  3027. m_Param= pSThis->NewDP2ZRange( m_Param, *pParam);
  3028. ++pParam;
  3029. } while( --wStateCount!= 0);
  3030. return DD_OK;
  3031. }
  3032. HRESULT RecDP2ZRange( const D3DHAL_DP2COMMAND* pCmd, void* pP)
  3033. {
  3034. D3DHAL_DP2ZRANGE* pParam=
  3035. reinterpret_cast< D3DHAL_DP2ZRANGE*>( pP);
  3036. WORD wStateCount( pCmd->wStateCount);
  3037. if( wStateCount!= 0) do
  3038. {
  3039. GetDP2ZRange( *pParam);
  3040. ++pParam;
  3041. } while( --wStateCount!= 0);
  3042. return DD_OK;
  3043. }
  3044. };
  3045. //
  3046. // <Template Parameters>
  3047. // TSuper: Standard parent type which is inheriting from this child class.
  3048. // In this case, it should typically be the CMyContext type.
  3049. // TDP2Data: This is some kind of wrapper class for PORTABLE_DRAWPRIMITIVES2DATA
  3050. // The type is expected to inherit or emulate PORTABLE_DRAWPRIMITIVES2DATA's
  3051. // fields/ member variables, and should typically be consistent with
  3052. // CStdDrawPrimitives2< xxx >::TDP2Data.
  3053. //
  3054. template< class TSuper, class TDP2Data= CDP2DataWrap<> >
  3055. class CStdDP2SetMaterialStore
  3056. {
  3057. protected: // Variables
  3058. D3DHAL_DP2SETMATERIAL m_Param;
  3059. protected: // Functions
  3060. CStdDP2SetMaterialStore()
  3061. { }
  3062. explicit CStdDP2SetMaterialStore( const D3DHAL_DP2SETMATERIAL& P)
  3063. :m_Param( P)
  3064. { }
  3065. ~CStdDP2SetMaterialStore()
  3066. { }
  3067. D3DHAL_DP2SETMATERIAL NewDP2SetMaterial( const D3DHAL_DP2SETMATERIAL& CurParam,
  3068. const D3DHAL_DP2SETMATERIAL& NewParam) const
  3069. { // Tell notifier to store the new param.
  3070. return NewParam;
  3071. }
  3072. public: // Fuctions
  3073. void GetDP2SetMaterial( D3DHAL_DP2SETMATERIAL& GetParam) const
  3074. { GetParam= m_Param; }
  3075. operator D3DHAL_DP2SETMATERIAL() const
  3076. { return m_Param; }
  3077. HRESULT DP2SetMaterial( TDP2Data&, const D3DHAL_DP2COMMAND* pCmd,
  3078. const void* pP)
  3079. {
  3080. TSuper* pSThis= static_cast<TSuper*>(this);
  3081. const D3DHAL_DP2SETMATERIAL* pParam=
  3082. reinterpret_cast< const D3DHAL_DP2SETMATERIAL*>( pP);
  3083. WORD wStateCount( pCmd->wStateCount);
  3084. if( wStateCount!= 0) do
  3085. {
  3086. m_Param= pSThis->NewDP2SetMaterial( m_Param, *pParam);
  3087. ++pParam;
  3088. } while( --wStateCount!= 0);
  3089. return DD_OK;
  3090. }
  3091. HRESULT RecDP2SetMaterial( const D3DHAL_DP2COMMAND* pCmd, void* pP)
  3092. {
  3093. D3DHAL_DP2SETMATERIAL* pParam=
  3094. reinterpret_cast< D3DHAL_DP2SETMATERIAL*>( pP);
  3095. WORD wStateCount( pCmd->wStateCount);
  3096. if( wStateCount!= 0) do
  3097. {
  3098. GetDP2SetMaterial( *pParam);
  3099. ++pParam;
  3100. } while( --wStateCount);
  3101. return DD_OK;
  3102. }
  3103. };
  3104. //
  3105. // <Template Parameters>
  3106. // TSuper: Standard parent type which is inheriting from this child class.
  3107. // In this case, it should typically be the CMyContext type.
  3108. // TDP2Data: This is some kind of wrapper class for PORTABLE_DRAWPRIMITIVES2DATA
  3109. // The type is expected to inherit or emulate PORTABLE_DRAWPRIMITIVES2DATA's
  3110. // fields/ member variables, and should typically be consistent with
  3111. // CStdDrawPrimitives2< xxx >::TDP2Data.
  3112. //
  3113. template< class TSuper, class TDP2Data= CDP2DataWrap<> >
  3114. class CStdDP2SetVertexShaderStore
  3115. {
  3116. protected: // Variables
  3117. D3DHAL_DP2VERTEXSHADER m_Param;
  3118. protected: // Functions
  3119. CStdDP2SetVertexShaderStore()
  3120. { }
  3121. explicit CStdDP2SetVertexShaderStore( const D3DHAL_DP2VERTEXSHADER& P)
  3122. : m_Param( P)
  3123. { }
  3124. ~CStdDP2SetVertexShaderStore()
  3125. { }
  3126. D3DHAL_DP2VERTEXSHADER NewDP2SetVertexShader( const D3DHAL_DP2VERTEXSHADER&
  3127. CurParam, const D3DHAL_DP2VERTEXSHADER& NewParam) const
  3128. { // Tell notifier to store the new param.
  3129. return NewParam;
  3130. }
  3131. public: // Fuctions
  3132. void GetDP2SetVertexShader( D3DHAL_DP2VERTEXSHADER& GetParam) const
  3133. { GetParam= m_Param; }
  3134. operator D3DHAL_DP2VERTEXSHADER() const
  3135. { return m_Param; }
  3136. HRESULT DP2SetVertexShader( TDP2Data&, const D3DHAL_DP2COMMAND* pCmd,
  3137. const void* pP)
  3138. {
  3139. TSuper* pSThis= static_cast<TSuper*>(this);
  3140. const D3DHAL_DP2VERTEXSHADER* pParam=
  3141. reinterpret_cast< const D3DHAL_DP2VERTEXSHADER*>( pP);
  3142. WORD wStateCount( pCmd->wStateCount);
  3143. if( wStateCount!= 0) do
  3144. {
  3145. m_Param= pSThis->NewDP2SetVertexShader( m_Param, *pParam);
  3146. // If the handle is 0, the Device/ Context needs to invalidate all
  3147. // streams.
  3148. if( 0== m_Param.dwHandle)
  3149. {
  3150. // The CStdDP2VStreamManager provides a default implementation
  3151. // for InvalidateAllVStreams()
  3152. pSThis->InvalidateAllVStreams();
  3153. // The CStdDP2IStreamManager provides a default implementation
  3154. // for InvalidateAllIStreams()
  3155. pSThis->InvalidateAllIStreams();
  3156. }
  3157. ++pParam;
  3158. } while( --wStateCount!= 0);
  3159. return DD_OK;
  3160. }
  3161. HRESULT RecDP2SetVertexShader( const D3DHAL_DP2COMMAND* pCmd, void* pP)
  3162. {
  3163. D3DHAL_DP2VERTEXSHADER* pParam=
  3164. reinterpret_cast< D3DHAL_DP2VERTEXSHADER*>( pP);
  3165. WORD wStateCount( pCmd->wStateCount);
  3166. if( wStateCount!= 0) do
  3167. {
  3168. GetDP2SetVertexShader( *pParam);
  3169. ++pParam;
  3170. } while( wStateCount!= 0);
  3171. return DD_OK;
  3172. }
  3173. };
  3174. //
  3175. // <Template Parameters>
  3176. // TSuper: Standard parent type which is inheriting from this child class.
  3177. // In this case, it should typically be the CMyContext type.
  3178. // TDP2Data: This is some kind of wrapper class for PORTABLE_DRAWPRIMITIVES2DATA
  3179. // The type is expected to inherit or emulate PORTABLE_DRAWPRIMITIVES2DATA's
  3180. // fields/ member variables, and should typically be consistent with
  3181. // CStdDrawPrimitives2< xxx >::TDP2Data.
  3182. //
  3183. template< class TSuper, class TDP2Data= CDP2DataWrap<> >
  3184. class CStdDP2SetPixelShaderStore
  3185. {
  3186. protected: // Variables
  3187. D3DHAL_DP2PIXELSHADER m_Param;
  3188. protected: // Functions
  3189. CStdDP2SetPixelShaderStore()
  3190. { }
  3191. explicit CStdDP2SetPixelShaderStore( const D3DHAL_DP2PIXELSHADER& P)
  3192. : m_Param( P)
  3193. { }
  3194. ~CStdDP2SetPixelShaderStore()
  3195. { }
  3196. D3DHAL_DP2PIXELSHADER NewDP2SetPixelShader( const D3DHAL_DP2PIXELSHADER&
  3197. CurParam, const D3DHAL_DP2PIXELSHADER& NewParam) const
  3198. { // Tell notifier to store the new param.
  3199. return NewParam;
  3200. }
  3201. public: // Fuctions
  3202. void GetDP2SetPixelShader( D3DHAL_DP2PIXELSHADER& GetParam) const
  3203. { GetParam= m_Param; }
  3204. operator D3DHAL_DP2PIXELSHADER() const
  3205. { return m_Param; }
  3206. HRESULT DP2SetPixelShader( TDP2Data&, const D3DHAL_DP2COMMAND* pCmd,
  3207. const void* pP)
  3208. {
  3209. TSuper* pSThis= static_cast<TSuper*>(this);
  3210. const D3DHAL_DP2PIXELSHADER* pParam=
  3211. reinterpret_cast< const D3DHAL_DP2PIXELSHADER*>( pP);
  3212. WORD wStateCount( pCmd->wStateCount);
  3213. if( wStateCount!= 0) do
  3214. {
  3215. m_Param= pSThis->NewDP2SetPixelShader( m_Param, *pParam);
  3216. ++pParam;
  3217. } while( --wStateCount!= 0);
  3218. return DD_OK;
  3219. }
  3220. HRESULT RecDP2SetPixelShader( const D3DHAL_DP2COMMAND* pCmd, void* pP)
  3221. {
  3222. D3DHAL_DP2PIXELSHADER* pParam=
  3223. reinterpret_cast< D3DHAL_DP2PIXELSHADER*>( pP);
  3224. WORD wStateCount( pCmd->wStateCount);
  3225. if( wStateCount!= 0) do
  3226. {
  3227. GetDP2SetPixelShader( *pParam);
  3228. ++pParam;
  3229. } while( --wStateCount!= 0);
  3230. return DD_OK;
  3231. }
  3232. };
  3233. //
  3234. // <Template Parameters>
  3235. // TSuper: Standard parent type which is inheriting from this child class.
  3236. // In this case, it should typically be the CMyContext type.
  3237. // c_uiWorldMatrices: The number of world transform matrices that should be
  3238. // stored.
  3239. // c_uiTextureMatrices: The number of texture transform matrices that should
  3240. // be stored.
  3241. // TDP2Data: This is some kind of wrapper class for PORTABLE_DRAWPRIMITIVES2DATA
  3242. // The type is expected to inherit or emulate PORTABLE_DRAWPRIMITIVES2DATA's
  3243. // fields/ member variables, and should typically be consistent with
  3244. // CStdDrawPrimitives2< xxx >::TDP2Data.
  3245. //
  3246. template< class TSuper, const size_t c_uiWorldMatrices= 256,
  3247. const size_t c_uiTextureMatrices= D3DHAL_TSS_MAXSTAGES,
  3248. class TDP2Data= CDP2DataWrap<> >
  3249. class CStdDP2SetTransformStore
  3250. {
  3251. protected: // Types
  3252. typedef block< D3DMATRIX, 2+ c_uiTextureMatrices+ c_uiWorldMatrices>
  3253. TMatrices;
  3254. protected: // Variables
  3255. TMatrices m_Matrices;
  3256. private: // Functions
  3257. static bool IsValidTransformType( D3DTRANSFORMSTATETYPE Type)
  3258. {
  3259. // We might not be storing this transform matrix, so we shouldn't
  3260. // record it in a state set and ignore any SET requests.
  3261. if( (Type>= D3DTS_VIEW&& Type<= D3DTS_PROJECTION)||
  3262. (Type>= D3DTS_TEXTURE0&& Type< static_cast< D3DTRANSFORMSTATETYPE>(
  3263. D3DTS_TEXTURE0+ c_uiTextureMatrices))||
  3264. (Type>= D3DTS_WORLD&& Type< static_cast< D3DTRANSFORMSTATETYPE>(
  3265. D3DTS_WORLDMATRIX( c_uiWorldMatrices))))
  3266. return true;
  3267. return false;
  3268. }
  3269. static size_t TransformTypeToIndex( D3DTRANSFORMSTATETYPE Type)
  3270. {
  3271. assert( Type>= D3DTS_VIEW);
  3272. if( Type< D3DTS_TEXTURE0)
  3273. {
  3274. assert( Type<= D3DTS_PROJECTION);
  3275. return static_cast< size_t>( Type- D3DTS_VIEW);
  3276. }
  3277. else if( Type< D3DTS_WORLD)
  3278. {
  3279. assert( Type< static_cast< D3DTRANSFORMSTATETYPE>( \
  3280. D3DTS_TEXTURE0+ c_uiTextureMatrices));
  3281. return static_cast< size_t>( Type- D3DTS_TEXTURE0+ 2);
  3282. }
  3283. else
  3284. {
  3285. assert( Type< static_cast< D3DTRANSFORMSTATETYPE>( \
  3286. D3DTS_WORLDMATRIX( c_uiWorldMatrices)));
  3287. return static_cast< size_t>( Type- D3DTS_WORLD+
  3288. c_uiTextureMatrices+ 2);
  3289. }
  3290. }
  3291. protected: // Functions
  3292. CStdDP2SetTransformStore()
  3293. { }
  3294. template< class TIter> // D3DHAL_DP2SETTRANSFORM*
  3295. CStdDP2SetTransformStore( TIter itStart, const TIter itEnd)
  3296. {
  3297. while( itStart!= itEnd)
  3298. {
  3299. m_Matrices[ TransformTypeToIndex( itStart->xfrmType)]=
  3300. itStart->matrix;
  3301. ++itStart;
  3302. }
  3303. }
  3304. ~CStdDP2SetTransformStore()
  3305. { }
  3306. D3DHAL_DP2SETTRANSFORM NewDP2SetTransform( const D3DHAL_DP2SETTRANSFORM&
  3307. CurParam, const D3DHAL_DP2SETTRANSFORM& NewParam) const
  3308. { // Tell notifier to store the new param.
  3309. return NewParam;
  3310. }
  3311. public: // Fuctions
  3312. D3DMATRIX GetTransform( D3DTRANSFORMSTATETYPE Type) const
  3313. { return m_Matrices[ TransformTypeToIndex( Type)]; }
  3314. void GetDP2SetTransform( D3DHAL_DP2SETTRANSFORM& GetParam) const
  3315. { GetParam.matrix= GetTransform( GetParam.xfrmType); }
  3316. HRESULT DP2SetTransform( TDP2Data&, const D3DHAL_DP2COMMAND* pCmd,
  3317. const void* pP)
  3318. {
  3319. TSuper* pSThis= static_cast<TSuper*>(this);
  3320. const D3DHAL_DP2SETTRANSFORM* pParam=
  3321. reinterpret_cast<const D3DHAL_DP2SETTRANSFORM*>( pP);
  3322. WORD wStateCount( pCmd->wStateCount);
  3323. if( wStateCount!= 0) do
  3324. {
  3325. if( IsValidTransformType( pParam->xfrmType))
  3326. {
  3327. D3DHAL_DP2SETTRANSFORM CurWrap;
  3328. CurWrap.xfrmType= pParam->xfrmType;
  3329. GetDP2SetTransform( CurWrap);
  3330. D3DHAL_DP2SETTRANSFORM NewState(
  3331. pSThis->NewDP2SetTransform( CurWrap, *pParam));
  3332. m_Matrices[ TransformTypeToIndex( NewState.xfrmType)]=
  3333. NewState.matrix;
  3334. }
  3335. ++pParam;
  3336. } while( --wStateCount!= 0);
  3337. return DD_OK;
  3338. }
  3339. HRESULT RecDP2SetTransform( const D3DHAL_DP2COMMAND* pCmd, void* pP)
  3340. {
  3341. D3DHAL_DP2SETTRANSFORM* pParam=
  3342. reinterpret_cast< D3DHAL_DP2SETTRANSFORM*>( pP);
  3343. WORD wStateCount( pCmd->wStateCount);
  3344. if( wStateCount!= 0) do
  3345. {
  3346. if( IsValidTransformType( pParam->xfrmType))
  3347. GetDP2SetTransform( *pParam);
  3348. ++pParam;
  3349. } while( --wStateCount!= 0);
  3350. return DD_OK;
  3351. }
  3352. };
  3353. //
  3354. // <Template Parameters>
  3355. // TSuper: Standard parent type which is inheriting from this child class.
  3356. // In this case, it should typically be the CMyContext type.
  3357. // c_uiClipPlanes: The number of user clip planes that should be stored. This
  3358. // should be consistent with the driver cap.
  3359. // TDP2Data: This is some kind of wrapper class for PORTABLE_DRAWPRIMITIVES2DATA
  3360. // The type is expected to inherit or emulate PORTABLE_DRAWPRIMITIVES2DATA's
  3361. // fields/ member variables, and should typically be consistent with
  3362. // CStdDrawPrimitives2< xxx >::TDP2Data.
  3363. //
  3364. template< class TSuper, const size_t c_uiClipPlanes,
  3365. class TDP2Data= CDP2DataWrap<> >
  3366. class CStdDP2SetClipPlaneStore
  3367. {
  3368. protected: // Types
  3369. typedef block< block< D3DVALUE, 4>, c_uiClipPlanes> TClipPlanes;
  3370. protected: // Variables
  3371. TClipPlanes m_ClipPlanes;
  3372. protected: // Functions
  3373. CStdDP2SetClipPlaneStore()
  3374. { }
  3375. template< class TIter> // D3DHAL_DP2SETCLIPPLANE*
  3376. CStdDP2SetClipPlaneStore( TIter itStart, const TIter itEnd)
  3377. {
  3378. while( itStart!= itEnd)
  3379. {
  3380. m_ClipPlanes[ itStart->dwIndex]= itStart->plane;
  3381. ++itStart;
  3382. }
  3383. }
  3384. ~CStdDP2SetClipPlaneStore()
  3385. { }
  3386. D3DHAL_DP2SETCLIPPLANE NewDP2SetClipPlane( const D3DHAL_DP2SETCLIPPLANE&
  3387. CurParam, const D3DHAL_DP2SETCLIPPLANE& NewParam) const
  3388. { // Tell notifier to store the new param.
  3389. return NewParam;
  3390. }
  3391. public: // Functions
  3392. block< D3DVALUE, 4> GetClipPlane( DWORD dwIndex) const
  3393. { return m_ClipPlanes[ dwIndex]; }
  3394. void GetDP2SetClipPlane( D3DHAL_DP2SETCLIPPLANE& GetParam) const
  3395. {
  3396. block< D3DVALUE, 4> CP( GetClipPlane( GetParam.dwIndex));
  3397. copy( CP.begin(), CP.end(), &GetParam.plane[ 0]);
  3398. }
  3399. HRESULT DP2SetClipPlane( TDP2Data& DP2Data,
  3400. const D3DHAL_DP2COMMAND* pCmd, const void* pP)
  3401. {
  3402. TSuper* pSThis= static_cast<TSuper*>(this);
  3403. const D3DHAL_DP2SETCLIPPLANE* pParam=
  3404. reinterpret_cast<const D3DHAL_DP2SETCLIPPLANE*>(pP);
  3405. WORD wStateCount( pCmd->wStateCount);
  3406. if( wStateCount!= 0) do
  3407. {
  3408. if( pParam->dwIndex< m_ClipPlanes.size())
  3409. {
  3410. D3DHAL_DP2SETCLIPPLANE CurWrap;
  3411. CurWrap.dwIndex= pParam->dwIndex;
  3412. GetDP2SetClipPlane( CurWrap);
  3413. D3DHAL_DP2SETCLIPPLANE NewState(
  3414. pSThis->NewDP2SetClipPlane( CurWrap, *pParam));
  3415. copy( &NewState.plane[ 0], &NewState.plane[ 4],
  3416. m_ClipPlanes[ NewState.dwIndex].begin());
  3417. }
  3418. ++pParam;
  3419. } while( --wStateCount);
  3420. return DD_OK;
  3421. }
  3422. HRESULT RecDP2SetClipPlane( const D3DHAL_DP2COMMAND* pCmd, void* pP)
  3423. {
  3424. D3DHAL_DP2SETCLIPPLANE* pParam=
  3425. reinterpret_cast< D3DHAL_DP2SETCLIPPLANE*>(pP);
  3426. WORD wStateCount( pCmd->wStateCount);
  3427. if( wStateCount!= 0) do
  3428. {
  3429. if( pParam->dwIndex< m_ClipPlanes.size())
  3430. GetDP2SetClipPlane( *pParam);
  3431. ++pParam;
  3432. } while( --wStateCount!= 0);
  3433. return DD_OK;
  3434. }
  3435. };
  3436. //
  3437. // <Template Parameters>
  3438. // TSuper: Standard parent type which is inheriting from this child class.
  3439. // In this case, it should typically be the CMyContext type.
  3440. // TDP2Data: This is some kind of wrapper class for PORTABLE_DRAWPRIMITIVES2DATA
  3441. // The type is expected to inherit or emulate PORTABLE_DRAWPRIMITIVES2DATA's
  3442. // fields/ member variables, and should typically be consistent with
  3443. // CStdDrawPrimitives2< xxx >::TDP2Data.
  3444. //
  3445. template< class TSuper, class TDP2Data= CDP2DataWrap<> >
  3446. class CStdDP2RenderStateStore
  3447. {
  3448. protected: // Variables
  3449. block< DWORD, D3DHAL_MAX_RSTATES> m_Param;
  3450. protected: // Functions
  3451. CStdDP2RenderStateStore()
  3452. { m_Param[ D3DRENDERSTATE_SCENECAPTURE]= FALSE; }
  3453. template< class TIter> // D3DHAL_DP2RENDERSTATE*
  3454. CStdDP2RenderStateStore( TIter itStart, const TIter itEnd)
  3455. {
  3456. m_Param[ D3DRENDERSTATE_SCENECAPTURE]= FALSE;
  3457. while( itStart!= itEnd)
  3458. {
  3459. m_Param[ itStart->RenderState]= itStart->dwState;
  3460. itStart++;
  3461. }
  3462. }
  3463. ~CStdDP2RenderStateStore()
  3464. { }
  3465. D3DHAL_DP2RENDERSTATE NewDP2RenderState( const D3DHAL_DP2RENDERSTATE&
  3466. CurParam, const D3DHAL_DP2RENDERSTATE& NewParam) const
  3467. { // Tell notifier to store the new param.
  3468. return NewParam;
  3469. }
  3470. void OnSceneCaptureStart( void)
  3471. { }
  3472. void OnSceneCaptureEnd( void)
  3473. { }
  3474. public: // Functions
  3475. DWORD GetRenderStateDW( D3DRENDERSTATETYPE RS) const
  3476. { return m_Param[ RS]; }
  3477. D3DVALUE GetRenderStateDV( D3DRENDERSTATETYPE RS) const
  3478. { return *(reinterpret_cast< const D3DVALUE*>( &m_Param[ RS])); }
  3479. void GetDP2RenderState( D3DHAL_DP2RENDERSTATE& GetParam) const
  3480. { GetParam.dwState= GetRenderStateDW( GetParam.RenderState); }
  3481. HRESULT DP2RenderState( TDP2Data& DP2Data, const D3DHAL_DP2COMMAND* pCmd,
  3482. const void* pP)
  3483. {
  3484. TSuper* pSThis= static_cast<TSuper*>(this);
  3485. const D3DHAL_DP2RENDERSTATE* pParam=
  3486. reinterpret_cast<const D3DHAL_DP2RENDERSTATE*>(pP);
  3487. WORD wStateCount( pCmd->wStateCount);
  3488. D3DHAL_DP2RENDERSTATE SCap;
  3489. SCap.RenderState= static_cast< D3DRENDERSTATETYPE>(
  3490. D3DRENDERSTATE_SCENECAPTURE);
  3491. GetDP2RenderState( SCap);
  3492. const DWORD dwOldSC( SCap.dwState);
  3493. if((DP2Data.dwFlags()& D3DHALDP2_EXECUTEBUFFER)!= 0)
  3494. {
  3495. // DP2Data.lpdwRStates should be valid.
  3496. if( wStateCount!= 0) do
  3497. {
  3498. if( pParam->RenderState< D3DHAL_MAX_RSTATES)
  3499. {
  3500. D3DHAL_DP2RENDERSTATE CurWrap;
  3501. CurWrap.RenderState= pParam->RenderState;
  3502. GetDP2RenderState( CurWrap);
  3503. D3DHAL_DP2RENDERSTATE NewState(
  3504. pSThis->NewDP2RenderState( CurWrap, *pParam));
  3505. m_Param[ NewState.RenderState]= NewState.dwState;
  3506. DP2Data.lpdwRStates()[ NewState.RenderState]= NewState.dwState;
  3507. }
  3508. ++pParam;
  3509. } while( --wStateCount!= 0);
  3510. }
  3511. else
  3512. {
  3513. if( wStateCount!= 0) do
  3514. {
  3515. if( pParam->RenderState< D3DHAL_MAX_RSTATES)
  3516. {
  3517. D3DHAL_DP2RENDERSTATE CurWrap;
  3518. CurWrap.RenderState= pParam->RenderState;
  3519. GetDP2RenderState( CurWrap);
  3520. D3DHAL_DP2RENDERSTATE NewState(
  3521. pSThis->NewDP2RenderState( CurWrap, *pParam));
  3522. m_Param[ NewState.RenderState]= NewState.dwState;
  3523. }
  3524. ++pParam;
  3525. } while( --wStateCount!= 0);
  3526. }
  3527. GetDP2RenderState( SCap);
  3528. if( FALSE== dwOldSC && TRUE== SCap.dwState)
  3529. OnSceneCaptureStart();
  3530. else if( TRUE== dwOldSC && FALSE== SCap.dwState)
  3531. OnSceneCaptureEnd();
  3532. return DD_OK;
  3533. }
  3534. HRESULT RecDP2RenderState( const D3DHAL_DP2COMMAND* pCmd, void* pP)
  3535. {
  3536. D3DHAL_DP2RENDERSTATE* pParam=
  3537. reinterpret_cast< D3DHAL_DP2RENDERSTATE*>(pP);
  3538. WORD wStateCount( pCmd->wStateCount);
  3539. if( wStateCount) do
  3540. {
  3541. if( pParam->RenderState< D3DHAL_MAX_RSTATES)
  3542. GetDP2RenderState( *pParam);
  3543. ++pParam;
  3544. } while( --wStateCount!= 0);
  3545. return DD_OK;
  3546. }
  3547. };
  3548. //
  3549. // <Template Parameters>
  3550. // TSuper: Standard parent type which is inheriting from this child class.
  3551. // In this case, it should typically be the CMyContext type.
  3552. // TDP2Data: This is some kind of wrapper class for PORTABLE_DRAWPRIMITIVES2DATA
  3553. // The type is expected to inherit or emulate PORTABLE_DRAWPRIMITIVES2DATA's
  3554. // fields/ member variables, and should typically be consistent with
  3555. // CStdDrawPrimitives2< xxx >::TDP2Data.
  3556. //
  3557. template< class TSuper, class TDP2Data= CDP2DataWrap<> >
  3558. class CStdDP2TextureStageStateStore
  3559. {
  3560. protected: // Variables
  3561. block< block< DWORD, D3DTSS_MAX>, D3DHAL_TSS_MAXSTAGES> m_Param;
  3562. protected: // Functions
  3563. CStdDP2TextureStageStateStore()
  3564. { }
  3565. template< class TIter> // D3DHAL_DP2TEXTURESTAGESTATE*
  3566. CStdDP2TextureStageStateStore( TIter itStart, const TIter itEnd)
  3567. {
  3568. while( itStart!= itEnd)
  3569. {
  3570. m_Param[ itStart->wStage][ itStart->TSState]= itStart->dwValue();
  3571. ++itStart;
  3572. }
  3573. }
  3574. ~CStdDP2TextureStageStateStore()
  3575. { }
  3576. D3DHAL_DP2TEXTURESTAGESTATE NewDP2TextureStageState( const
  3577. D3DHAL_DP2TEXTURESTAGESTATE& CurParam, const
  3578. D3DHAL_DP2TEXTURESTAGESTATE& NewParam) const
  3579. { // Tell notifier to store the new param.
  3580. return NewParam;
  3581. }
  3582. public: // Functions
  3583. DWORD GetTextureStageStateDW( WORD wStage, WORD wTSState) const
  3584. { return m_Param[ wStage][ wTSState]; }
  3585. D3DVALUE GetTextureStageStateDV( WORD wStage, WORD wTSState) const
  3586. { return *(reinterpret_cast< const D3DVALUE*>( &m_Param[ wStage][ wTSState])); }
  3587. void GetDP2TextureStageState( D3DHAL_DP2TEXTURESTAGESTATE& GetParam) const
  3588. { GetParam.dwValue= GetTextureStageStateDW( GetParam.wStage, GetParam.TSState); }
  3589. HRESULT DP2TextureStageState( TDP2Data& DP2Data,
  3590. const D3DHAL_DP2COMMAND* pCmd, const void* pP)
  3591. {
  3592. TSuper* pSThis= static_cast<TSuper*>(this);
  3593. const D3DHAL_DP2TEXTURESTAGESTATE* pParam=
  3594. reinterpret_cast<const D3DHAL_DP2TEXTURESTAGESTATE*>(pP);
  3595. WORD wStateCount( pCmd->wStateCount);
  3596. if( wStateCount!= 0) do
  3597. {
  3598. if( pParam->wStage< D3DHAL_TSS_MAXSTAGES&& pParam->TSState< D3DTSS_MAX)
  3599. {
  3600. D3DHAL_DP2TEXTURESTAGESTATE CurWrap;
  3601. CurWrap.wStage= pParam->wStage;
  3602. CurWrap.TSState= pParam->TSState;
  3603. GetDP2TextureStageState( CurWrap);
  3604. D3DHAL_DP2TEXTURESTAGESTATE NewState(
  3605. pSThis->NewDP2TextureStageState( CurWrap, *pParam));
  3606. m_Param[ NewState.wStage][ NewState.TSState]= NewState.dwValue;
  3607. }
  3608. ++pParam;
  3609. } while( --wStateCount);
  3610. return DD_OK;
  3611. }
  3612. HRESULT RecDP2TextureStageState( const D3DHAL_DP2COMMAND* pCmd, void* pP)
  3613. {
  3614. D3DHAL_DP2TEXTURESTAGESTATE* pParam=
  3615. reinterpret_cast< D3DHAL_DP2TEXTURESTAGESTATE*>(pP);
  3616. WORD wStateCount( pCmd->wStateCount);
  3617. if( wStateCount!= 0) do
  3618. {
  3619. if( pParam->wStage< D3DHAL_TSS_MAXSTAGES&& pParam->TSState< D3DTSS_MAX)
  3620. GetDP2TextureStageState( *pParam);
  3621. ++pParam;
  3622. } while( --wStateCount!= 0);
  3623. return DD_OK;
  3624. }
  3625. };
  3626. //
  3627. // The more complex manager classes:
  3628. //
  3629. ////////////////////////////////////////////////////////////////////////////////
  3630. //
  3631. // CVStream
  3632. //
  3633. // This class stores everything associated with a vertex stream. This
  3634. // implementation allows 4 representations (video, system, user, and none).
  3635. // This class is used by a VStream manager class.
  3636. //
  3637. // <Template Parameters>
  3638. // TS: Video memory surface object, typically either CMySurface or
  3639. // IVidMemSurface, etc. A valid pointer to this object is stored, when the
  3640. // stream source is from a video memory surface.
  3641. // TSDBE: The SurfDBEntry type, typically, CMySurfDBEntry or CSurfDBEntry. A
  3642. // valid pointer to this object is stored, when the stream source is from
  3643. // a video memory or system memory surface.
  3644. //
  3645. ////////////////////////////////////////////////////////////////////////////////
  3646. template< class TS, class TSDBE>
  3647. class CVStream
  3648. {
  3649. public: // Types
  3650. typedef TS TSurface;
  3651. typedef TSDBE TSurfDBEntry;
  3652. enum EMemLocation
  3653. {
  3654. None,
  3655. User,
  3656. System,
  3657. Video
  3658. };
  3659. protected: // Variables
  3660. DWORD m_dwHandle;
  3661. TSurface m_Surface;
  3662. TSurfDBEntry m_SurfDBEntry;
  3663. void* m_pUserMemData;
  3664. DWORD m_dwStride;
  3665. DWORD m_dwFVF;
  3666. EMemLocation m_eMemLocation;
  3667. public: // Functions
  3668. CVStream()
  3669. : m_dwHandle( 0), m_pUserMemData( NULL), m_dwStride( 0), m_dwFVF( 0),
  3670. m_eMemLocation( None)
  3671. { }
  3672. // Video Memory representation constructor.
  3673. CVStream( DWORD dwHandle, const TSurface& Surface,
  3674. const TSurfDBEntry& SurfDBEntry, DWORD dwStride): m_dwHandle( dwHandle),
  3675. m_Surface( Surface), m_SurfDBEntry( SurfDBEntry), m_pUserMemData( NULL),
  3676. m_dwStride( dwStride), m_dwFVF( 0), m_eMemLocation( Video)
  3677. { }
  3678. // System Memory representation constructor.
  3679. CVStream( DWORD dwHandle, const TSurfDBEntry& SurfDBEntry, DWORD dwStride):
  3680. m_dwHandle( dwHandle), m_SurfDBEntry( SurfDBEntry),
  3681. m_pUserMemData( NULL), m_dwStride( dwStride), m_dwFVF( 0),
  3682. m_eMemLocation( System)
  3683. { }
  3684. // User Memory representation constructor.
  3685. CVStream( void* pUserMem, DWORD dwStride):
  3686. m_dwHandle( 0), m_pUserMemData( pUserMem), m_dwStride( dwStride),
  3687. m_dwFVF( 0), m_eMemLocation( User)
  3688. { }
  3689. EMemLocation GetMemLocation() const
  3690. { return m_eMemLocation; }
  3691. void SetFVF( DWORD dwFVF)
  3692. { m_dwFVF= dwFVF; }
  3693. DWORD GetFVF() const
  3694. { return m_dwFVF; }
  3695. DWORD GetHandle() const
  3696. {
  3697. assert( GetMemLocation()== System|| GetMemLocation()== Video);
  3698. return m_dwHandle;
  3699. }
  3700. DWORD GetStride() const
  3701. {
  3702. assert( GetMemLocation()!= None);
  3703. return m_dwStride;
  3704. }
  3705. TSurface& GetVidMemRepresentation()
  3706. {
  3707. assert( GetMemLocation()== Video);
  3708. return m_Surface;
  3709. }
  3710. const TSurface& GetVidMemRepresentation() const
  3711. {
  3712. assert( GetMemLocation()== Video);
  3713. return m_Surface;
  3714. }
  3715. TSurfDBEntry& GetSurfDBRepresentation()
  3716. {
  3717. assert( GetMemLocation()== Video|| GetMemLocation()== System);
  3718. return m_SurfDBEntry;
  3719. }
  3720. const TSurfDBEntry& GetSurfDBRepresentation() const
  3721. {
  3722. assert( GetMemLocation()== Video|| GetMemLocation()== System);
  3723. return m_SurfDBEntry;
  3724. }
  3725. void* GetUserMemPtr() const
  3726. {
  3727. assert( GetMemLocation()== User);
  3728. return m_pUserMemData;
  3729. }
  3730. };
  3731. ////////////////////////////////////////////////////////////////////////////////
  3732. //
  3733. // CStdDP2VStreamManager
  3734. //
  3735. // This class contains DP2 member functions to correctly process
  3736. // D3DDP2OP_SETSTREAMSOURCE & D3DDP2OP_SETSTREAMSOURCEUM. It can also correctly
  3737. // record a command buffer operation for D3DDP2OP_SETSTREAMSOURCE. To do this,
  3738. // however, it must maintain information for vertex stream, or "manage"
  3739. // VStream objects.
  3740. //
  3741. // This class also contains a function, InvalidateAllStreams, which is needed
  3742. // to be called when a D3DDP2OP_SETVERTEXSHADER operation is processed with a
  3743. // zero value VERTEXSHADER.
  3744. //
  3745. // <Template Parameters>
  3746. // TSuper: Standard parent type which is inheriting from this child class.
  3747. // In this case, it should typically be the CMyContext type.
  3748. // TVS: The vertex stream type which represents data associated with a vertex
  3749. // stream. This is typically, CVStream<> or something derived from it.
  3750. // c_uiStreams: The number of vertex streams to support. Typically, non-TnL
  3751. // drivers only support 1. This should be consistent with the cap in the
  3752. // driver.
  3753. // TDP2Data: This is some kind of wrapper class for PORTABLE_DRAWPRIMITIVES2DATA
  3754. // The type is expected to inherit or emulate PORTABLE_DRAWPRIMITIVES2DATA's
  3755. // fields/ member variables, and should typically be consistent with
  3756. // CStdDrawPrimitives2< xxx >::TDP2Data.
  3757. //
  3758. ////////////////////////////////////////////////////////////////////////////////
  3759. template< class TSuper,
  3760. class TVS= CVStream< TSuper::TPerDDrawData::TDriver::TSurface*, TSuper::TPerDDrawData::TSurfDBEntry*>,
  3761. const size_t c_uiStreams= 1, class TDP2Data= CDP2DataWrap<> >
  3762. class CStdDP2VStreamManager
  3763. {
  3764. public: // Types
  3765. typedef TVS TVStream;
  3766. typedef block< TVStream, c_uiStreams> TVStreamDB;
  3767. protected: // Variables
  3768. TVStreamDB m_VStreamDB;
  3769. protected: // Functions
  3770. CStdDP2VStreamManager()
  3771. { }
  3772. ~CStdDP2VStreamManager()
  3773. { }
  3774. public: // Fuctions
  3775. TVStream& GetVStream( TVStreamDB::size_type uiStream)
  3776. { return m_VStreamDB[ uiStream]; }
  3777. const TVStream& GetVStream( TVStreamDB::size_type uiStream) const
  3778. { return m_VStreamDB[ uiStream]; }
  3779. HRESULT DP2SetStreamSource( TDP2Data&, const D3DHAL_DP2COMMAND* pCmd,
  3780. const void* pP)
  3781. {
  3782. const D3DHAL_DP2SETSTREAMSOURCE* pParam=
  3783. reinterpret_cast< const D3DHAL_DP2SETSTREAMSOURCE*>( pP);
  3784. TSuper* pSThis= static_cast<TSuper*>(this);
  3785. WORD wStateCount( pCmd->wStateCount);
  3786. if( wStateCount!= 0) do
  3787. {
  3788. if( pParam->dwStream< m_VStreamDB.size())
  3789. {
  3790. if( 0== pParam->dwVBHandle)
  3791. m_VStreamDB[ pParam->dwStream]= TVStream();
  3792. else
  3793. {
  3794. typename TSuper::TPerDDrawData::TSurfDBEntry* pDBEntry=
  3795. pSThis->GetPerDDrawData().GetSurfDBEntry(
  3796. pParam->dwVBHandle);
  3797. if( pDBEntry!= NULL)
  3798. {
  3799. if((pDBEntry->GetLCLddsCaps().dwCaps&
  3800. DDSCAPS_VIDEOMEMORY)!= 0)
  3801. {
  3802. // Assign in a video memory representation.
  3803. m_VStreamDB[ pParam->dwStream]=
  3804. TVStream( pParam->dwVBHandle, pSThis->
  3805. GetPerDDrawData().GetDriver().GetSurface(
  3806. *pDBEntry), pDBEntry, pParam->dwStride);
  3807. }
  3808. else
  3809. {
  3810. // Assign in a system memory representation.
  3811. m_VStreamDB[ pParam->dwStream]=
  3812. TVStream( pParam->dwVBHandle,
  3813. pDBEntry, pParam->dwStride);
  3814. }
  3815. }
  3816. else
  3817. {
  3818. // Handle invalid, reset stream.
  3819. m_VStreamDB[ pParam->dwStream]= TVStream();
  3820. }
  3821. }
  3822. }
  3823. ++pParam;
  3824. } while( --wStateCount!= 0);
  3825. return DD_OK;
  3826. }
  3827. HRESULT DP2SetStreamSourceUM( TDP2Data& DP2Data, const D3DHAL_DP2COMMAND* pCmd,
  3828. const void* pP)
  3829. {
  3830. const D3DHAL_DP2SETSTREAMSOURCEUM* pParam=
  3831. reinterpret_cast< const D3DHAL_DP2SETSTREAMSOURCEUM*>( pP);
  3832. TSuper* pSThis= static_cast<TSuper*>(this);
  3833. WORD wStateCount( pCmd->wStateCount);
  3834. if( wStateCount!= 0) do
  3835. {
  3836. if( pParam->dwStream< m_VStreamDB.size())
  3837. {
  3838. if( DP2Data.lpVertices()!= NULL)
  3839. {
  3840. // Assign in a user memory representation.
  3841. m_VStreamDB[ pParam->dwStream]=
  3842. TVStream( DP2Data.lpVertices(), pParam->dwStride);
  3843. }
  3844. else
  3845. {
  3846. // Reset stream.
  3847. m_VStreamDB[ pParam->dwStream]= TVStream();
  3848. }
  3849. }
  3850. ++pParam;
  3851. } while( --wStateCount!= 0);
  3852. return DD_OK;
  3853. }
  3854. HRESULT RecDP2SetStreamSource( const D3DHAL_DP2COMMAND* pCmd, void* pP)
  3855. {
  3856. D3DHAL_DP2SETSTREAMSOURCE* pParam=
  3857. reinterpret_cast< D3DHAL_DP2SETSTREAMSOURCE*>( pP);
  3858. WORD wStateCount( pCmd->wStateCount);
  3859. if( wStateCount!= 0) do
  3860. {
  3861. const DWORD dwStream( pParam->dwStream);
  3862. if( dwStream< m_VStreamDB.size())
  3863. {
  3864. const TVStream& VStream( m_VStreamDB[ dwStream]);
  3865. switch( VStream.GetMemLocation())
  3866. {
  3867. case( TVStream::EMemLocation::None): ;
  3868. case( TVStream::EMemLocation::User): ;
  3869. pParam->dwVBHandle= 0;
  3870. pParam->dwStride= 0;
  3871. break;
  3872. case( TVStream::EMemLocation::System): ;
  3873. case( TVStream::EMemLocation::Video): ;
  3874. pParam->dwVBHandle= VStream.GetHandle();
  3875. pParam->dwStride= VStream.GetStride();
  3876. break;
  3877. default: {
  3878. const bool Unrecognized_VStream_enum( false);
  3879. assert( Unrecognized_VStream_enum);
  3880. }
  3881. }
  3882. }
  3883. ++pParam;
  3884. } while( --wStateCount!= 0);
  3885. return DD_OK;
  3886. }
  3887. void InvalidateAllVStreams()
  3888. {
  3889. fill( m_VStreamDB.begin(), m_VStreamDB.end(), TVStream());
  3890. }
  3891. };
  3892. ////////////////////////////////////////////////////////////////////////////////
  3893. //
  3894. // CIStream
  3895. //
  3896. // This class stores everything associated with a index stream. This
  3897. // implementation allows 3 representations (video, system, and none).
  3898. // This class is used by a IStream manager class.
  3899. //
  3900. // <Template Parameters>
  3901. // TS: Video memory surface object, typically either CMySurface or
  3902. // IVidMemSurface, etc. A valid pointer to this object is stored, when the
  3903. // stream source is from a video memory surface.
  3904. // TSDBE: The SurfDBEntry type, typically, CMySurfDBEntry or CSurfDBEntry. A
  3905. // valid pointer to this object is stored, when the stream source is from
  3906. // a video memory or system memory surface.
  3907. //
  3908. ////////////////////////////////////////////////////////////////////////////////
  3909. template< class TS, class TSDBE>
  3910. class CIStream
  3911. {
  3912. public: // Types
  3913. typedef TS TSurface;
  3914. typedef TSDBE TSurfDBEntry;
  3915. enum EMemLocation
  3916. {
  3917. None,
  3918. System,
  3919. Video
  3920. };
  3921. protected: // Variables
  3922. DWORD m_dwHandle;
  3923. TSurface m_Surface;
  3924. TSurfDBEntry m_SurfDBEntry;
  3925. DWORD m_dwStride;
  3926. EMemLocation m_eMemLocation;
  3927. public: // Functions
  3928. CIStream():
  3929. m_dwHandle( 0), m_dwStride( 0), m_eMemLocation( None)
  3930. { }
  3931. // Video Memory representation constructor.
  3932. CIStream( DWORD dwHandle, const TSurface& Surface,
  3933. const TSurfDBEntry& SurfDBEntry, DWORD dwStride): m_dwHandle( dwHandle),
  3934. m_Surface( Surface), m_SurfDBEntry( SurfDBEntry), m_dwStride( dwStride),
  3935. m_eMemLocation( Video)
  3936. { }
  3937. // System Memory representation constructor.
  3938. CIStream( DWORD dwHandle, const TSurfDBEntry& SurfDBEntry, DWORD dwStride):
  3939. m_dwHandle( dwHandle), m_SurfDBEntry( SurfDBEntry),
  3940. m_dwStride( dwStride), m_eMemLocation( System)
  3941. { }
  3942. EMemLocation GetMemLocation() const
  3943. { return m_eMemLocation; }
  3944. DWORD GetHandle() const
  3945. {
  3946. assert( GetMemLocation()== System|| GetMemLocation()== Video);
  3947. return m_dwHandle;
  3948. }
  3949. DWORD GetStride() const
  3950. {
  3951. assert( GetMemLocation()!= None);
  3952. return m_dwStride;
  3953. }
  3954. const TSurface& GetVidMemRepresentation() const
  3955. {
  3956. assert( GetMemLocation()== Video);
  3957. return m_Surface;
  3958. }
  3959. TSurface& GetVidMemRepresentation()
  3960. {
  3961. assert( GetMemLocation()== Video);
  3962. return m_Surface;
  3963. }
  3964. const TSurfDBEntry& GetSurfDBRepresentation() const
  3965. {
  3966. assert( GetMemLocation()== Video|| GetMemLocation()== System);
  3967. return m_SurfDBEntry;
  3968. }
  3969. TSurfDBEntry& GetSurfDBRepresentation()
  3970. {
  3971. assert( GetMemLocation()== Video|| GetMemLocation()== System);
  3972. return m_SurfDBEntry;
  3973. }
  3974. };
  3975. ////////////////////////////////////////////////////////////////////////////////
  3976. //
  3977. // CStdDP2IStreamManager
  3978. //
  3979. // This class contains DP2 member functions to correctly process
  3980. // D3DDP2OP_SETINDICES. It can also correctly record a command buffer operation
  3981. // for D3DDP2OP_SETINDICES. To do this, however, it must maintain information
  3982. // for index streams, or "manage" IStream objects.
  3983. //
  3984. // <Template Parameters>
  3985. // TSuper: Standard parent type which is inheriting from this child class.
  3986. // In this case, it should typically be the CMyContext type.
  3987. // TIS: The index stream type which represents data associated with a index
  3988. // stream. This is typically, CIStream<> or something derived from it.
  3989. // TDP2Data: This is some kind of wrapper class for PORTABLE_DRAWPRIMITIVES2DATA
  3990. // The type is expected to inherit or emulate PORTABLE_DRAWPRIMITIVES2DATA's
  3991. // fields/ member variables, and should typically be consistent with
  3992. // CStdDrawPrimitives2< xxx >::TDP2Data.
  3993. //
  3994. ////////////////////////////////////////////////////////////////////////////////
  3995. template< class TSuper,
  3996. class TIS= CIStream< TSuper::TPerDDrawData::TDriver::TSurface*, TSuper::TPerDDrawData::TSurfDBEntry*>,
  3997. class TDP2Data= CDP2DataWrap<> >
  3998. class CStdDP2IStreamManager
  3999. {
  4000. public: // Types
  4001. typedef TIS TIStream;
  4002. typedef block< TIStream, 1> TIStreamDB;
  4003. protected: // Variables
  4004. TIStreamDB m_IStreamDB;
  4005. protected: // Functions
  4006. CStdDP2IStreamManager()
  4007. { }
  4008. ~CStdDP2IStreamManager()
  4009. { }
  4010. public: // Fuctions
  4011. TIStream& GetIStream( TIStreamDB::size_type uiStream)
  4012. { return m_IStreamDB[ uiStream]; }
  4013. const TIStream& GetIStream( TIStreamDB::size_type uiStream) const
  4014. { return m_IStreamDB[ uiStream]; }
  4015. HRESULT DP2SetIndices( TDP2Data&, const D3DHAL_DP2COMMAND* pCmd,
  4016. const void* pP)
  4017. {
  4018. const D3DHAL_DP2SETINDICES* pParam=
  4019. reinterpret_cast< const D3DHAL_DP2SETINDICES*>( pP);
  4020. TSuper* pSThis= static_cast<TSuper*>(this);
  4021. WORD wStateCount( pCmd->wStateCount);
  4022. if( wStateCount!= 0) do
  4023. {
  4024. // For ease of extension in case multiple IStreams are supported
  4025. // later.
  4026. const DWORD dwStream( 0);
  4027. if( dwStream< m_IStreamDB.size())
  4028. {
  4029. if( 0== pParam->dwVBHandle)
  4030. m_IStreamDB[ dwStream]= TIStream();
  4031. else
  4032. {
  4033. typename TSuper::TPerDDrawData::TSurfDBEntry* pDBEntry=
  4034. pSThis->GetPerDDrawData().GetSurfDBEntry(
  4035. pParam->dwVBHandle);
  4036. if( pDBEntry!= NULL)
  4037. {
  4038. if((pDBEntry->GetLCLddsCaps().dwCaps&
  4039. DDSCAPS_VIDEOMEMORY)!= 0)
  4040. {
  4041. // Assign in a video memory representation.
  4042. m_IStreamDB[ dwStream]=
  4043. TIStream( pParam->dwVBHandle, pSThis->
  4044. GetPerDDrawData().GetDriver().GetSurface(
  4045. *pDBEntry), pDBEntry, pParam->dwStride);
  4046. }
  4047. else
  4048. {
  4049. // Assign in a system memory representation.
  4050. m_IStreamDB[ dwStream]=
  4051. TIStream( pParam->dwVBHandle,
  4052. pDBEntry, pParam->dwStride);
  4053. }
  4054. }
  4055. else
  4056. {
  4057. // Handle invalid, reset stream.
  4058. m_IStreamDB[ dwStream]= TIStream();
  4059. }
  4060. }
  4061. }
  4062. ++pParam;
  4063. } while( --wStateCount!= 0);
  4064. return DD_OK;
  4065. }
  4066. HRESULT RecDP2SetIndices( const D3DHAL_DP2COMMAND* pCmd, void* pP)
  4067. {
  4068. D3DHAL_DP2SETINDICES* pParam=
  4069. reinterpret_cast< D3DHAL_DP2SETINDICES*>( pP);
  4070. WORD wStateCount( pCmd->wStateCount);
  4071. if( wStateCount!= 0) do
  4072. {
  4073. const DWORD dwStream( 0);
  4074. if( dwStream< m_IStreamDB.size())
  4075. {
  4076. const TIStream& IStream( m_IStreamDB[ dwStream]);
  4077. switch( IStream.GetMemLocation())
  4078. {
  4079. case( TIStream::EMemLocation::None): ;
  4080. pParam->dwVBHandle= 0;
  4081. pParam->dwStride= 0;
  4082. break;
  4083. case( TIStream::EMemLocation::System): ;
  4084. case( TIStream::EMemLocation::Video): ;
  4085. pParam->dwVBHandle= IStream.GetHandle();
  4086. pParam->dwStride= IStream.GetStride();
  4087. break;
  4088. default: {
  4089. const bool Unrecognized_IStream_enum( false);
  4090. assert( Unrecognized_IStream_enum);
  4091. }
  4092. }
  4093. }
  4094. ++pParam;
  4095. } while( --wStateCount!= 0);
  4096. return DD_OK;
  4097. }
  4098. void InvalidateAllIStreams()
  4099. {
  4100. fill( m_IStreamDB.begin(), m_IStreamDB.end(), TIStream());
  4101. }
  4102. };
  4103. class CPalDBEntry
  4104. {
  4105. protected: // Types
  4106. typedef block< DWORD, 256> TPalEntries;
  4107. protected: // Variables
  4108. DWORD m_dwFlags;
  4109. TPalEntries m_PalEntries;
  4110. public: // Functions
  4111. CPalDBEntry() : m_dwFlags( 0)
  4112. { fill( m_PalEntries.begin(), m_PalEntries.end(), 0); }
  4113. ~CPalDBEntry()
  4114. { }
  4115. void SetFlags( DWORD dwFlags)
  4116. { m_dwFlags= dwFlags; }
  4117. DWORD GetFlags()
  4118. { return m_dwFlags; }
  4119. DWORD* GetEntries()
  4120. { return m_PalEntries.begin(); }
  4121. template< class ForwardIterator>
  4122. void Update( TPalEntries::size_type uiStart, ForwardIterator f,
  4123. ForwardIterator l)
  4124. { copy( f, l, m_PalEntries.begin()+ uiStart); }
  4125. };
  4126. //
  4127. // <Template Parameters>
  4128. // TSuper: Standard parent type which is inheriting from this child class.
  4129. // In this case, it should typically be the CMyContext type.
  4130. // TPDBE: This is the palette database entry type, or whatever is associated
  4131. // with a palette. This type is typically, CPalDBEntry or something
  4132. // derived from it.
  4133. // TPDB: This can be any Unique, Pair Associative Container, typically a map,
  4134. // which associates a DWORD palette handle to a palette type.
  4135. // TSPDB: This can be any Unique, Pair Associative Container, typically a map,
  4136. // which associates a DWORD surface handle to a DWORD palette handle.
  4137. // TDP2Data: This is some kind of wrapper class for PORTABLE_DRAWPRIMITIVES2DATA
  4138. // The type is expected to inherit or emulate PORTABLE_DRAWPRIMITIVES2DATA's
  4139. // fields/ member variables, and should typically be consistent with
  4140. // CStdDrawPrimitives2< xxx >::TDP2Data.
  4141. //
  4142. template< class TSuper, class TPDBE= CPalDBEntry, class TPDB= map< DWORD, TPDBE>,
  4143. class TDP2Data= CDP2DataWrap<> >
  4144. class CStdDP2PaletteManager
  4145. {
  4146. public: // Types
  4147. typedef TPDBE TPalDBEntry;
  4148. typedef TPDB TPalDB;
  4149. protected: // Variables
  4150. TPalDB m_PalDB;
  4151. protected: // Functions
  4152. CStdDP2PaletteManager()
  4153. { }
  4154. ~CStdDP2PaletteManager()
  4155. { }
  4156. public: // Functions
  4157. void UpdatePalette( const D3DHAL_DP2UPDATEPALETTE* pParam)
  4158. {
  4159. typename TPalDB::iterator itPal(
  4160. m_PalDB.find( pParam->dwPaletteHandle));
  4161. if( m_PalDB.end()== itPal)
  4162. itPal= m_PalDB.insert( TPalDB::value_type( pParam->dwPaletteHandle,
  4163. TPalDBEntry())).first;
  4164. const DWORD* pEStart= reinterpret_cast< const DWORD*>( pParam+ 1);
  4165. itPal->second.Update( pParam->wStartIndex, pEStart,
  4166. pEStart+ pParam->wNumEntries);
  4167. }
  4168. void SetPalette( const D3DHAL_DP2SETPALETTE* pParam)
  4169. {
  4170. TSuper* pSThis= static_cast< TSuper*>( this);
  4171. typedef typename TSuper::TPerDDrawData TPerDDrawData;
  4172. typename TPerDDrawData::TSurfDBEntry* pSurfDBEntry=
  4173. pSThis->GetPerDDrawData().GetSurfDBEntry( pParam->dwSurfaceHandle);
  4174. assert( NULL!= pSurfDBEntry);
  4175. if( 0== pParam->dwPaletteHandle)
  4176. {
  4177. // Disassociate the surface with any palette.
  4178. pSurfDBEntry->SetPalette( NULL);
  4179. }
  4180. else
  4181. {
  4182. typename TPalDB::iterator itPal(
  4183. m_PalDB.find( pParam->dwPaletteHandle));
  4184. if( m_PalDB.end()== itPal)
  4185. itPal= m_PalDB.insert( TPalDB::value_type( pParam->dwPaletteHandle,
  4186. TPalDBEntry())).first;
  4187. itPal->second.SetFlags( pParam->dwPaletteFlags);
  4188. pSurfDBEntry->SetPalette( &itPal->second);
  4189. }
  4190. }
  4191. HRESULT DP2SetPalette( TDP2Data& DP2Data,
  4192. const D3DHAL_DP2COMMAND* pCmd, const void* pP)
  4193. {
  4194. TSuper* pSThis= static_cast<TSuper*>(this);
  4195. const D3DHAL_DP2SETPALETTE* pParam=
  4196. reinterpret_cast<const D3DHAL_DP2SETPALETTE*>(pP);
  4197. WORD wStateCount( pCmd->wStateCount);
  4198. try
  4199. {
  4200. if( wStateCount!= 0) do
  4201. {
  4202. pSThis->SetPalette( pParam);
  4203. ++pParam;
  4204. } while( --wStateCount);
  4205. } catch ( bad_alloc ba)
  4206. { return E_OUTOFMEMORY; }
  4207. return DD_OK;
  4208. }
  4209. HRESULT DP2UpdatePalette( TDP2Data& DP2Data,
  4210. const D3DHAL_DP2COMMAND* pCmd, const void* pP)
  4211. {
  4212. TSuper* pSThis= static_cast<TSuper*>(this);
  4213. const D3DHAL_DP2UPDATEPALETTE* pParam=
  4214. reinterpret_cast<const D3DHAL_DP2UPDATEPALETTE*>(pP);
  4215. WORD wStateCount( pCmd->wStateCount);
  4216. try
  4217. {
  4218. if( wStateCount!= 0)
  4219. pSThis->UpdatePalette( pParam);
  4220. } catch ( bad_alloc ba)
  4221. { return E_OUTOFMEMORY; }
  4222. return DD_OK;
  4223. }
  4224. };
  4225. class CLightDBEntry:
  4226. public D3DLIGHT8
  4227. {
  4228. protected: // Variables
  4229. bool m_bEnabled;
  4230. public: // Functions
  4231. CLightDBEntry()
  4232. : m_bEnabled( false)
  4233. {
  4234. // Default light settings:
  4235. Type= D3DLIGHT_DIRECTIONAL;
  4236. Diffuse.r= 1.0f; Diffuse.g= 1.0f; Diffuse.b= 1.0f; Diffuse.a= 0.0f;
  4237. Specular.r= 0.0f; Specular.g= 0.0f; Specular.b= 0.0f; Specular.a= 0.0f;
  4238. Ambient.r= 0.0f; Ambient.g= 0.0f; Ambient.b= 0.0f; Ambient.a= 0.0f;
  4239. Position.x= 0.0f; Position.y= 0.0f; Position.z= 0.0f;
  4240. Direction.x= 0.0f; Direction.y= 0.0f; Direction.z= 1.0f;
  4241. Range= 0.0f;
  4242. Falloff= 0.0f;
  4243. Attenuation0= 0.0f;
  4244. Attenuation1= 0.0f;
  4245. Attenuation2= 0.0f;
  4246. Theta= 0.0f;
  4247. Phi= 0.0f;
  4248. }
  4249. operator const D3DLIGHT8&() const
  4250. { return *static_cast< const D3DLIGHT8*>( this); }
  4251. CLightDBEntry& operator=( const D3DLIGHT8& Other)
  4252. {
  4253. *static_cast< D3DLIGHT8*>( this)= Other;
  4254. return *this;
  4255. }
  4256. void SetEnabled( bool bEn)
  4257. { m_bEnabled= bEn; }
  4258. bool GetEnabled() const
  4259. { return m_bEnabled; }
  4260. };
  4261. //
  4262. // <Template Parameters>
  4263. // TSuper: Standard parent type which is inheriting from this child class.
  4264. // In this case, it should typically be the CMyContext type.
  4265. // TLDBE: This is the light database entry type, or whatever is associated
  4266. // with a light. This type is typically, CLightDBEntry or something
  4267. // derived from it or convertable to D3DLIGHT8, at least.
  4268. // TLDB: This can be any Unique, Pair Associative Container, typically a map,
  4269. // which associates a DWORD light id to a light type.
  4270. // TDP2Data: This is some kind of wrapper class for PORTABLE_DRAWPRIMITIVES2DATA
  4271. // The type is expected to inherit or emulate PORTABLE_DRAWPRIMITIVES2DATA's
  4272. // fields/ member variables, and should typically be consistent with
  4273. // CStdDrawPrimitives2< xxx >::TDP2Data.
  4274. //
  4275. template< class TSuper, class TLDBE= CLightDBEntry,
  4276. class TLDB= map< DWORD, TLDBE>, class TDP2Data= CDP2DataWrap<> >
  4277. class CStdDP2LightManager
  4278. {
  4279. public: // Types
  4280. typedef TLDBE TLightDBEntry;
  4281. typedef TLDB TLightDB;
  4282. protected: // Variables
  4283. TLightDB m_LightDB;
  4284. protected: // Functions
  4285. CStdDP2LightManager()
  4286. { }
  4287. ~CStdDP2LightManager()
  4288. { }
  4289. public: // Functions
  4290. void CreateLight( DWORD dwId)
  4291. {
  4292. pair< typename TLightDB::iterator, bool> Ret= m_LightDB.insert(
  4293. typename TLightDB::value_type( dwId, TLightDBEntry()));
  4294. }
  4295. void EnableLight( DWORD dwId, bool bEnable)
  4296. {
  4297. typename TLightDB::iterator itLight( m_LightDB.find( dwId));
  4298. assert( itLight!= m_LightDB.end());
  4299. itLight->second.SetEnabled( bEnable);
  4300. }
  4301. void UpdateLight( DWORD dwId, const D3DLIGHT8& LightValue)
  4302. {
  4303. typename TLightDB::iterator itLight( m_LightDB.find( dwId));
  4304. assert( itLight!= m_LightDB.end());
  4305. itLight->second= LightValue;
  4306. }
  4307. HRESULT DP2CreateLight( TDP2Data& DP2Data,
  4308. const D3DHAL_DP2COMMAND* pCmd, const void* pP)
  4309. {
  4310. TSuper* pSThis= static_cast< TSuper*>( this);
  4311. const D3DHAL_DP2CREATELIGHT* pParam=
  4312. reinterpret_cast< const D3DHAL_DP2CREATELIGHT*>( pP);
  4313. WORD wStateCount( pCmd->wStateCount);
  4314. try
  4315. {
  4316. if( wStateCount!= 0) do
  4317. {
  4318. pSThis->CreateLight( pParam->dwIndex);
  4319. ++pParam;
  4320. } while( --wStateCount);
  4321. } catch ( bad_alloc ba)
  4322. { return E_OUTOFMEMORY; }
  4323. return D3D_OK;
  4324. }
  4325. HRESULT DP2SetLight( TDP2Data& DP2Data,
  4326. const D3DHAL_DP2COMMAND* pCmd, const void* pP)
  4327. {
  4328. TSuper* pSThis= static_cast< TSuper*>( this);
  4329. const D3DHAL_DP2SETLIGHT* pParam=
  4330. reinterpret_cast< const D3DHAL_DP2SETLIGHT*>( pP);
  4331. WORD wStateCount( pCmd->wStateCount);
  4332. try
  4333. {
  4334. if( wStateCount!= 0) do
  4335. {
  4336. if( m_LightDB.end()== m_LightDB.find( pParam->dwIndex))
  4337. {
  4338. const bool SetLight_without_succeeded_CreateLight( false);
  4339. assert( SetLight_without_succeeded_CreateLight);
  4340. return DDERR_INVALIDPARAMS;
  4341. }
  4342. bool bEnable( false);
  4343. switch( pParam->dwDataType)
  4344. {
  4345. case( D3DHAL_SETLIGHT_DATA):
  4346. const D3DLIGHT8* pL= reinterpret_cast< const D3DLIGHT8*>(
  4347. pParam+ 1);
  4348. pSThis->UpdateLight( pParam->dwIndex, *pL);
  4349. pParam= reinterpret_cast< const D3DHAL_DP2SETLIGHT*>(
  4350. pL+ 1);
  4351. break;
  4352. case( D3DHAL_SETLIGHT_ENABLE):
  4353. bEnable= true; // Fall-through.
  4354. case( D3DHAL_SETLIGHT_DISABLE):
  4355. pSThis->EnableLight( pParam->dwIndex, bEnable);
  4356. ++pParam;
  4357. break;
  4358. default: {
  4359. const bool Unrecognized_D3DHAL_SETLIGHT_data_type( false);
  4360. assert( Unrecognized_D3DHAL_SETLIGHT_data_type);
  4361. return DDERR_INVALIDPARAMS;
  4362. }
  4363. }
  4364. } while( --wStateCount);
  4365. } catch ( bad_alloc ba)
  4366. { return E_OUTOFMEMORY; }
  4367. return D3D_OK;
  4368. }
  4369. HRESULT RecDP2CreateLight( const D3DHAL_DP2COMMAND* pCmd, void* pP)
  4370. {
  4371. D3DHAL_DP2CREATELIGHT* pParam=
  4372. reinterpret_cast< D3DHAL_DP2CREATELIGHT*>( pP);
  4373. WORD wStateCount( pCmd->wStateCount);
  4374. // Special case here, the default state set capturing, will ask how
  4375. // many active lights are needed to be recorded, and their id's. In
  4376. // order to support the default state set, we must process this
  4377. // specially.
  4378. if( 0== pCmd->bCommand)
  4379. {
  4380. // Now, we're either being asked how many lights or what their
  4381. // id's are.
  4382. if( 0== wStateCount)
  4383. pParam->dwIndex= m_LightDB.size();
  4384. else
  4385. {
  4386. assert( m_LightDB.size()== wStateCount);
  4387. typename TLightDB::const_iterator itCur( m_LightDB.begin());
  4388. do
  4389. {
  4390. pParam->dwIndex= itCur.first;
  4391. ++pParam;
  4392. ++itCur;
  4393. } while( --wStateCount!= 0);
  4394. }
  4395. return D3D_OK;
  4396. }
  4397. // Otherwise, recording creation is easy,
  4398. // leave the command buffer as is.
  4399. return D3D_OK;
  4400. }
  4401. HRESULT RecDP2SetLight( const D3DHAL_DP2COMMAND* pCmd, void* pP)
  4402. {
  4403. D3DHAL_DP2SETLIGHT* pParam=
  4404. reinterpret_cast< D3DHAL_DP2SETLIGHT*>( pP);
  4405. WORD wStateCount( pCmd->wStateCount);
  4406. const typename TLightDB::const_iterator itEnd( m_LightDB.end());
  4407. typename TLightDB::const_iterator itLight( itEnd);
  4408. if( wStateCount!= 0) do
  4409. {
  4410. if( itLight!= itEnd&& itLight->first!= pParam->dwIndex)
  4411. itLight= m_LightDB.find( pParam->dwIndex);
  4412. assert( itLight!= itEnd);
  4413. switch( pParam->dwDataType)
  4414. {
  4415. case( D3DHAL_SETLIGHT_DATA):
  4416. D3DLIGHT8* pL= reinterpret_cast< D3DLIGHT8*>( pParam+ 1);
  4417. *pL= itLight->second;
  4418. pParam= reinterpret_cast< D3DHAL_DP2SETLIGHT*>( pL+ 1);
  4419. break;
  4420. case( D3DHAL_SETLIGHT_ENABLE):
  4421. case( D3DHAL_SETLIGHT_DISABLE):
  4422. pParam->dwDataType= ( itLight->second.GetEnabled()?
  4423. D3DHAL_SETLIGHT_ENABLE: D3DHAL_SETLIGHT_DISABLE);
  4424. ++pParam;
  4425. break;
  4426. default: {
  4427. const bool Unrecognized_D3DHAL_SETLIGHT_data_type( false);
  4428. assert( Unrecognized_D3DHAL_SETLIGHT_data_type);
  4429. return DDERR_INVALIDPARAMS;
  4430. }
  4431. }
  4432. } while( --wStateCount!= 0);
  4433. return D3D_OK;
  4434. }
  4435. };
  4436. template< class TS, class TSDBE>
  4437. class CRTarget
  4438. {
  4439. public: // Types
  4440. typedef TS TSurface;
  4441. typedef TSDBE TSurfDBEntry;
  4442. enum EMemLocation
  4443. {
  4444. None,
  4445. Video
  4446. };
  4447. protected: // Variables
  4448. DWORD m_dwHandle;
  4449. TSurface m_Surface;
  4450. TSurfDBEntry m_SurfDBEntry;
  4451. EMemLocation m_eMemLocation;
  4452. public: // Functions
  4453. CRTarget(): m_eMemLocation( None)
  4454. { }
  4455. // Video Memory representation constructor.
  4456. CRTarget( DWORD dwHandle, const TSurface& Surface,
  4457. const TSurfDBEntry& SurfDBEntry): m_dwHandle( dwHandle),
  4458. m_Surface( Surface), m_SurfDBEntry( SurfDBEntry), m_eMemLocation( Video)
  4459. { }
  4460. ~CRTarget()
  4461. { }
  4462. bool operator==( const CRTarget& Other) const
  4463. {
  4464. const EMemLocation MemLocation( GetMemLocation());
  4465. return MemLocation== Other.GetMemLocation()&&
  4466. (None== MemLocation|| GetHandle()== Other.GetHandle());
  4467. }
  4468. bool operator!=( const CRTarget& Other) const
  4469. { return !(*this== Other); }
  4470. DWORD GetHandle() const
  4471. {
  4472. assert( GetMemLocation()!= None);
  4473. return m_dwHandle;
  4474. }
  4475. TSurface& GetVidMemRepresentation()
  4476. {
  4477. assert( GetMemLocation()== Video);
  4478. return m_Surface;
  4479. }
  4480. const TSurface& GetVidMemRepresentation() const
  4481. {
  4482. assert( GetMemLocation()== Video);
  4483. return m_Surface;
  4484. }
  4485. TSurfDBEntry& GetSurfDBRepresentation()
  4486. {
  4487. assert( GetMemLocation()== Video);
  4488. return m_SurfDBEntry;
  4489. }
  4490. const TSurfDBEntry& GetSurfDBRepresentation() const
  4491. {
  4492. assert( GetMemLocation()== Video);
  4493. return m_SurfDBEntry;
  4494. }
  4495. EMemLocation GetMemLocation() const
  4496. { return m_eMemLocation; }
  4497. void Clear( const D3DHAL_DP2CLEAR& DP2Clear, const RECT& Rect)
  4498. {
  4499. if( GetMemLocation()!= None)
  4500. GetVidMemRepresentation()->Clear( DP2Clear, Rect);
  4501. }
  4502. };
  4503. ////////////////////////////////////////////////////////////////////////////////
  4504. //
  4505. // CSubContext
  4506. //
  4507. // This provides a base implementation for a context. It provides
  4508. // implementations for dealing with the SetRenderTarget and Clear
  4509. // DrawPrimitive2 commands; and also a minimal implementation for
  4510. // GetDriverState.
  4511. //
  4512. // <Template Parameters>
  4513. // TSuper: Standard parent type which is inheriting from this child class.
  4514. // In this case, it should typically be the CMyContext type.
  4515. // TPDDD: The PerDDrawData type, typically CMyPerDDrawData or
  4516. // CMinimalPerDDrawData<>.
  4517. // TDP2Data: This is some kind of wrapper class for PORTABLE_DRAWPRIMITIVES2DATA
  4518. // The type is expected to inherit or emulate PORTABLE_DRAWPRIMITIVES2DATA's
  4519. // fields/ member variables, and should typically be consistent with
  4520. // CStdDrawPrimitives2< xxx >::TDP2Data.
  4521. //
  4522. // <Exposed Types>
  4523. // TPerDDrawData: The PerDDrawData type, passed in as the template parameter,
  4524. // TPDDD.
  4525. // TDriver: This is equal to TPerDDrawData::TDriver. This type is exposed
  4526. // only as a convience to the implementation to get at TDriver::TSurface.
  4527. // TSurface: This is equal to TDriver::TSurface. This type is exposed only
  4528. // as a convience to the implementation.
  4529. //
  4530. // <Exposed Functions>
  4531. // CSubContext( TPerDDrawData&, TSurface*, TSurface*, DWORD): Constructor,
  4532. // a typical SDDI Context isnt' expected to be created without this data.
  4533. // ~CSubContext(): Standard destructor.
  4534. // TPerDDrawData& GetPerDDrawData() const: Trivial accessor function to get at
  4535. // the PerDDrawData.
  4536. // TSurface* GetRTarget() const: Trivial accessor function to get at the
  4537. // current render target.
  4538. // TSurface* GetZBuffer() const: Trivial accessor function to get at the
  4539. // current z/ stencil buffer.
  4540. // HRESULT DP2SetRenderTarget( TDP2Data&, const D3DHAL_DP2COMMAND*, const void*):
  4541. // The default DP2 command processing member function for
  4542. // D3DDP2OP_SETRENDERTARGET.
  4543. // void NewRenderTarget( TSurface*, TSurface*) const: Notification mechanism
  4544. // called just before new render targets are saved into the member
  4545. // variables. This notification mechanism is called by DP2SetRenderTarget.
  4546. // HRESULT DP2Clear( TDP2Data&, const D3DHAL_DP2COMMAND*, const void*):
  4547. // The default DP2 command processing member function for D3DDP2OP_CLEAR.
  4548. // This function relies on TSurface having a member function Clear.
  4549. // HRESULT GetDriverState( DDHAL_GETDRIVERSTATEDATA&): A minimal implementation
  4550. // of GetDriverState, which should return S_FALSE if the id isn't
  4551. // understood. This function should be overriden to add understanding for
  4552. // custom ids.
  4553. //
  4554. ////////////////////////////////////////////////////////////////////////////////
  4555. template< class TSuper, class TPDDD,
  4556. class TRT= CRTarget< TPDDD::TDriver::TSurface*, TPDDD::TSurfDBEntry*>,
  4557. class TDP2Data= CDP2DataWrap<> >
  4558. class CSubContext
  4559. {
  4560. public: // Types
  4561. typedef TPDDD TPerDDrawData;
  4562. typedef TRT TRTarget;
  4563. protected: // Variables
  4564. TPerDDrawData& m_PerDDrawData;
  4565. TRTarget m_ColorBuffer;
  4566. TRTarget m_DepthBuffer;
  4567. protected: // Functions
  4568. void NewColorBuffer() const
  4569. {
  4570. // Override this notification mechanism to provide color buffer
  4571. // state managing.
  4572. }
  4573. void NewDepthBuffer() const
  4574. {
  4575. // Override this notification mechanism to provide depth buffer
  4576. // state managing.
  4577. }
  4578. CSubContext( TPerDDrawData& PerDDrawData, PORTABLE_CONTEXTCREATEDATA& ccd):
  4579. m_PerDDrawData( PerDDrawData)
  4580. {
  4581. // To set the render targets, we must convert the structures to our
  4582. // SurfDBEntry representation.
  4583. typename TPerDDrawData::TDriver& Driver= PerDDrawData.GetDriver();
  4584. if( ccd.lpDDSLcl()!= NULL)
  4585. {
  4586. typename TPerDDrawData::TDriver::TSurface* pSurface=
  4587. Driver.GetSurface( *ccd.lpDDSLcl());
  4588. if( pSurface!= NULL)
  4589. {
  4590. const DWORD dwHandle(
  4591. ccd.lpDDSLcl()->lpSurfMore()->dwSurfaceHandle());
  4592. m_ColorBuffer= TRTarget( dwHandle, pSurface,
  4593. PerDDrawData.GetSurfDBEntry( dwHandle));
  4594. }
  4595. }
  4596. if( ccd.lpDDSZLcl()!= NULL)
  4597. {
  4598. typename TPerDDrawData::TDriver::TSurface* pSurface=
  4599. Driver.GetSurface( *ccd.lpDDSZLcl());
  4600. if( pSurface!= NULL)
  4601. {
  4602. const DWORD dwHandle(
  4603. ccd.lpDDSZLcl()->lpSurfMore()->dwSurfaceHandle());
  4604. m_DepthBuffer= TRTarget( dwHandle, pSurface,
  4605. PerDDrawData.GetSurfDBEntry( dwHandle));
  4606. }
  4607. }
  4608. }
  4609. ~CSubContext()
  4610. { }
  4611. public: // Functions
  4612. TPerDDrawData& GetPerDDrawData() const { return m_PerDDrawData; }
  4613. const TRTarget& GetColorBuffer() const { return m_ColorBuffer; }
  4614. TRTarget& GetColorBuffer() { return m_ColorBuffer; }
  4615. const TRTarget& GetDepthBuffer() const { return m_DepthBuffer; }
  4616. TRTarget& GetDepthBuffer() { return m_DepthBuffer; }
  4617. HRESULT DP2SetRenderTarget( TDP2Data& DP2Data, const D3DHAL_DP2COMMAND*
  4618. pCmd, const void* pP)
  4619. {
  4620. const D3DHAL_DP2SETRENDERTARGET* pParam=
  4621. reinterpret_cast< const D3DHAL_DP2SETRENDERTARGET*>( pP);
  4622. TSuper* pSThis= static_cast< TSuper*>( this);
  4623. WORD wStateCount( pCmd->wStateCount);
  4624. if( wStateCount!= 0)
  4625. {
  4626. TPerDDrawData& PerDDrawData= GetPerDDrawData();
  4627. typename TPerDDrawData::TDriver& Driver= PerDDrawData.GetDriver();
  4628. do
  4629. {
  4630. // To set the render targets, we must convert the handles to our
  4631. // SurfDBEntry representation.
  4632. typename TPerDDrawData::TSurfDBEntry* pSurfDBEntry=
  4633. PerDDrawData.GetSurfDBEntry( pParam->hRenderTarget);
  4634. if( pSurfDBEntry!= NULL)
  4635. {
  4636. // We can immediately convert the SurfDBEntry representation to our
  4637. // Video Memory object, because Render Targets MUST be VM.
  4638. typename TPerDDrawData::TDriver::TSurface* pSurface=
  4639. Driver.GetSurface( *pSurfDBEntry);
  4640. if( pSurface!= NULL)
  4641. {
  4642. m_ColorBuffer= TRTarget( pParam->hRenderTarget,
  4643. pSurface, pSurfDBEntry);
  4644. pSThis->NewColorBuffer();
  4645. }
  4646. }
  4647. pSurfDBEntry= PerDDrawData.GetSurfDBEntry( pParam->hZBuffer);
  4648. if( pSurfDBEntry!= NULL)
  4649. {
  4650. // We can immediately convert the SurfDBEntry representation to our
  4651. // Video Memory object, because Render Targets MUST be VM.
  4652. typename TPerDDrawData::TDriver::TSurface* pSurface=
  4653. Driver.GetSurface( *pSurfDBEntry);
  4654. if( pSurface!= NULL)
  4655. {
  4656. m_DepthBuffer= TRTarget( pParam->hZBuffer,
  4657. pSurface, pSurfDBEntry);
  4658. pSThis->NewDepthBuffer();
  4659. }
  4660. }
  4661. } while( --wStateCount!= 0);
  4662. }
  4663. return DD_OK;
  4664. }
  4665. HRESULT DP2Clear( TDP2Data& DP2Data, const D3DHAL_DP2COMMAND* pCmd,
  4666. const void* pP)
  4667. {
  4668. const D3DHAL_DP2CLEAR* pParam= reinterpret_cast< const D3DHAL_DP2CLEAR*>
  4669. ( pP);
  4670. TSuper* pSThis= static_cast< TSuper*>( this);
  4671. const D3DHAL_DP2VIEWPORTINFO CurViewport( *pSThis);
  4672. RECT ViewportRect;
  4673. ViewportRect.left= CurViewport.dwX;
  4674. ViewportRect.top= CurViewport.dwY;
  4675. ViewportRect.right= CurViewport.dwX+ CurViewport.dwWidth;
  4676. ViewportRect.bottom= CurViewport.dwY+ CurViewport.dwHeight;
  4677. TRTarget& ColorBuffer= GetColorBuffer();
  4678. TRTarget& DepthBuffer= GetDepthBuffer();
  4679. const bool bClearBoth(!(ColorBuffer== DepthBuffer));
  4680. if( 0== pCmd->wStateCount)
  4681. {
  4682. if( TRTarget::EMemLocation::None!= ColorBuffer.GetMemLocation())
  4683. ColorBuffer.Clear( *pParam, ViewportRect);
  4684. if( TRTarget::EMemLocation::None!= DepthBuffer.GetMemLocation()&&
  4685. bClearBoth)
  4686. DepthBuffer.Clear( *pParam, ViewportRect);
  4687. }
  4688. else
  4689. {
  4690. WORD wStateCount( pCmd->wStateCount);
  4691. const RECT* pRect= pParam->Rects;
  4692. if((pParam->dwFlags& D3DCLEAR_COMPUTERECTS)!= 0)
  4693. {
  4694. // Clip rect to viewport.
  4695. RECT rcClipped( *pRect);
  4696. do
  4697. {
  4698. clamp_min( rcClipped.left, ViewportRect.left);
  4699. clamp_min( rcClipped.top, ViewportRect.top);
  4700. clamp( rcClipped.right, rcClipped.left, ViewportRect.right);
  4701. clamp( rcClipped.bottom, rcClipped.top, ViewportRect.bottom);
  4702. if( TRTarget::EMemLocation::None!=
  4703. ColorBuffer.GetMemLocation())
  4704. ColorBuffer.Clear( *pParam, rcClipped);
  4705. if( TRTarget::EMemLocation::None!=
  4706. DepthBuffer.GetMemLocation()&& bClearBoth)
  4707. DepthBuffer.Clear( *pParam, rcClipped);
  4708. pRect++;
  4709. } while( --wStateCount);
  4710. }
  4711. else
  4712. {
  4713. do
  4714. {
  4715. if( TRTarget::EMemLocation::None!=
  4716. ColorBuffer.GetMemLocation())
  4717. ColorBuffer.Clear( *pParam, *pRect);
  4718. if( TRTarget::EMemLocation::None!=
  4719. DepthBuffer.GetMemLocation()&& bClearBoth)
  4720. DepthBuffer.Clear( *pParam, *pRect);
  4721. pRect++;
  4722. } while( --wStateCount);
  4723. }
  4724. }
  4725. return DD_OK;
  4726. }
  4727. // A minimal implementation of GetDriverState, which should return S_FALSE
  4728. // if the id isn't understood. Override this function to add understanding.
  4729. HRESULT GetDriverState( DDHAL_GETDRIVERSTATEDATA& gdsd)
  4730. { return S_FALSE; }
  4731. };
  4732. ////////////////////////////////////////////////////////////////////////////////
  4733. //
  4734. // CMinimalContext
  4735. //
  4736. // This class contains a minimal implementation of a Context for a driver,
  4737. // which supports only one stream, no TnL, and legacy pixel shading. This
  4738. // Context still needs an implementation of the primitive drawing functions,
  4739. // which it uses a Rasterizer class for. CMinimalContext takes care of most
  4740. // of the responsibilities of a SDDI driver, except rasterization.
  4741. //
  4742. // <Template Parameters>
  4743. // TPDDD: The PerDDrawData type, typically CMyPerDDrawData or
  4744. // CMinimalPerDDrawData<>.
  4745. // TR: The Rasterizer type, typically CMyRasterizer.
  4746. //
  4747. ////////////////////////////////////////////////////////////////////////////////
  4748. template< class TPDDD, class TR>
  4749. class CMinimalContext:
  4750. public CSubContext< CMinimalContext< TPDDD, TR>, TPDDD>,
  4751. public CStdDrawPrimitives2< CMinimalContext< TPDDD, TR> >,
  4752. public CStdDP2ViewportInfoStore< CMinimalContext< TPDDD, TR> >,
  4753. public CStdDP2WInfoStore< CMinimalContext< TPDDD, TR> >,
  4754. public CStdDP2RenderStateStore< CMinimalContext< TPDDD, TR> >,
  4755. public CStdDP2TextureStageStateStore< CMinimalContext< TPDDD, TR> >,
  4756. public CStdDP2SetVertexShaderStore< CMinimalContext< TPDDD, TR> >,
  4757. public CStdDP2VStreamManager< CMinimalContext< TPDDD, TR> >,
  4758. public CStdDP2IStreamManager< CMinimalContext< TPDDD, TR> >
  4759. {
  4760. public: // Types
  4761. typedef TPDDD TPerDDrawData;
  4762. typedef TR TRasterizer;
  4763. typedef block< TDP2CmdBind, 15> TDP2Bindings;
  4764. typedef block< TRecDP2CmdBind, 7> TRecDP2Bindings;
  4765. protected: // Variables
  4766. TRasterizer m_Rasterizer;
  4767. static const TDP2Bindings c_DP2Bindings;
  4768. static const TRecDP2Bindings c_RecDP2Bindings;
  4769. public: // Functions
  4770. CMinimalContext( TPerDDrawData& PDDD, PORTABLE_CONTEXTCREATEDATA& ccd)
  4771. : CSubContext< CMinimalContext< TPDDD, TR>, TPDDD>( PDDD, ccd),
  4772. CStdDrawPrimitives2< CMinimalContext< TPDDD, TR>>(
  4773. c_DP2Bindings.begin(), c_DP2Bindings.end(),
  4774. c_RecDP2Bindings.begin(), c_RecDP2Bindings.end())
  4775. {
  4776. // These keep the arrays in sync with their typedef.
  4777. assert( D3DDP2OP_CLIPPEDTRIANGLEFAN== *c_DP2Bindings.rbegin());
  4778. assert( D3DDP2OP_SETINDICES== *c_RecDP2Bindings.rbegin());
  4779. }
  4780. ~CMinimalContext() { }
  4781. // Provide this function to ease minimal implementations.
  4782. HRESULT ValidateTextureStageState( const D3DHAL_VALIDATETEXTURESTAGESTATEDATA&
  4783. vsssd) const
  4784. { return DD_OK; }
  4785. HRESULT DP2DrawPrimitive( TDP2Data& DP2Data,
  4786. const D3DHAL_DP2COMMAND* pCmd, const void* pP)
  4787. {
  4788. const D3DHAL_DP2DRAWPRIMITIVE* pParam= reinterpret_cast<
  4789. const D3DHAL_DP2DRAWPRIMITIVE*>(pP);
  4790. return m_Rasterizer.DrawPrimitive( *this, *pCmd, pParam);
  4791. }
  4792. HRESULT DP2DrawPrimitive2( TDP2Data& DP2Data,
  4793. const D3DHAL_DP2COMMAND* pCmd, const void* pP)
  4794. {
  4795. const D3DHAL_DP2DRAWPRIMITIVE2* pParam= reinterpret_cast<
  4796. const D3DHAL_DP2DRAWPRIMITIVE2*>(pP);
  4797. return m_Rasterizer.DrawPrimitive2( *this, *pCmd, pParam);
  4798. }
  4799. HRESULT DP2DrawIndexedPrimitive( TDP2Data& DP2Data,
  4800. const D3DHAL_DP2COMMAND* pCmd, const void* pP)
  4801. {
  4802. const D3DHAL_DP2DRAWINDEXEDPRIMITIVE* pParam= reinterpret_cast<
  4803. const D3DHAL_DP2DRAWINDEXEDPRIMITIVE*>(pP);
  4804. return m_Rasterizer.DrawIndexedPrimitive( *this, *pCmd, pParam);
  4805. }
  4806. HRESULT DP2DrawIndexedPrimitive2( TDP2Data& DP2Data,
  4807. const D3DHAL_DP2COMMAND* pCmd, const void* pP)
  4808. {
  4809. const D3DHAL_DP2DRAWINDEXEDPRIMITIVE2* pParam= reinterpret_cast<
  4810. const D3DHAL_DP2DRAWINDEXEDPRIMITIVE2*>(pP);
  4811. return m_Rasterizer.DrawIndexedPrimitive2( *this, *pCmd, pParam);
  4812. }
  4813. HRESULT DP2ClippedTriangleFan( TDP2Data& DP2Data,
  4814. const D3DHAL_DP2COMMAND* pCmd, const void* pP)
  4815. {
  4816. const D3DHAL_CLIPPEDTRIANGLEFAN* pParam= reinterpret_cast<
  4817. const D3DHAL_CLIPPEDTRIANGLEFAN*>(pP);
  4818. return m_Rasterizer.ClippedTriangleFan( *this, *pCmd, pParam);
  4819. }
  4820. };
  4821. // These tables require TConstDP2Bindings to be changed also, with the number
  4822. // of bindings.
  4823. template< class TPDDD, class TR>
  4824. const CMinimalContext< TPDDD, TR>::TDP2Bindings
  4825. CMinimalContext< TPDDD, TR>::c_DP2Bindings=
  4826. {
  4827. D3DDP2OP_VIEWPORTINFO, DP2ViewportInfo,
  4828. D3DDP2OP_WINFO, DP2WInfo,
  4829. D3DDP2OP_RENDERSTATE, DP2RenderState,
  4830. D3DDP2OP_TEXTURESTAGESTATE, DP2TextureStageState,
  4831. D3DDP2OP_CLEAR, DP2Clear,
  4832. D3DDP2OP_SETRENDERTARGET, DP2SetRenderTarget,
  4833. D3DDP2OP_SETVERTEXSHADER, DP2SetVertexShader,
  4834. D3DDP2OP_SETSTREAMSOURCE, DP2SetStreamSource,
  4835. D3DDP2OP_SETSTREAMSOURCEUM, DP2SetStreamSourceUM,
  4836. D3DDP2OP_SETINDICES, DP2SetIndices,
  4837. D3DDP2OP_DRAWPRIMITIVE, DP2DrawPrimitive,
  4838. D3DDP2OP_DRAWPRIMITIVE2, DP2DrawPrimitive2,
  4839. D3DDP2OP_DRAWINDEXEDPRIMITIVE, DP2DrawIndexedPrimitive,
  4840. D3DDP2OP_DRAWINDEXEDPRIMITIVE2, DP2DrawIndexedPrimitive2,
  4841. D3DDP2OP_CLIPPEDTRIANGLEFAN, DP2ClippedTriangleFan
  4842. };
  4843. // These tables require TConstRecDP2Bindings to be changed also, with the number
  4844. // of bindings.
  4845. template< class TPDDD, class TR>
  4846. const CMinimalContext< TPDDD, TR>::TRecDP2Bindings
  4847. CMinimalContext< TPDDD, TR>::c_RecDP2Bindings=
  4848. {
  4849. D3DDP2OP_VIEWPORTINFO, RecDP2ViewportInfo,
  4850. D3DDP2OP_WINFO, RecDP2WInfo,
  4851. D3DDP2OP_RENDERSTATE, RecDP2RenderState,
  4852. D3DDP2OP_TEXTURESTAGESTATE, RecDP2TextureStageState,
  4853. D3DDP2OP_SETVERTEXSHADER, RecDP2SetVertexShader,
  4854. D3DDP2OP_SETSTREAMSOURCE, RecDP2SetStreamSource,
  4855. D3DDP2OP_SETINDICES, RecDP2SetIndices
  4856. };
  4857. class IVidMemSurface
  4858. {
  4859. protected: // Variables
  4860. DWORD m_dwHandle;
  4861. protected: // Functions
  4862. IVidMemSurface( DWORD dwHandle) : m_dwHandle( dwHandle) { }
  4863. public: // Functions
  4864. DWORD GetHandle() const
  4865. { return m_dwHandle; }
  4866. virtual ~IVidMemSurface()
  4867. { }
  4868. virtual void* Lock( DWORD dwFlags, const RECTL* pRect)= 0;
  4869. virtual void Unlock( void)= 0;
  4870. virtual void Clear( const D3DHAL_DP2CLEAR& DP2Clear, const RECT& RC)= 0;
  4871. };
  4872. struct SD3DDataConv
  4873. {
  4874. // A( 0), R( 1), G( 2), B( 3), Z( 4), S( 5)
  4875. typedef block< DWORD, 6> TMasks;
  4876. // A( 0), R( 1), G( 2), B( 3), Z( 4), ZBits( 5), S( 6), SBits( 7)
  4877. typedef block< signed char, 8> TD3DBitShftRgt;
  4878. TMasks m_ToSurfMasks;
  4879. TD3DBitShftRgt m_D3DBitShftRgt;
  4880. SD3DDataConv()
  4881. {
  4882. fill( m_ToSurfMasks.begin(), m_ToSurfMasks.end(),
  4883. static_cast< TMasks::value_type>( 0));
  4884. fill( m_D3DBitShftRgt.begin(), m_D3DBitShftRgt.end(),
  4885. static_cast< TD3DBitShftRgt::value_type>( 0));
  4886. }
  4887. SD3DDataConv( const DDPIXELFORMAT& PF)
  4888. { (*this)= PF; }
  4889. SD3DDataConv& operator=( const DDPIXELFORMAT& PF)
  4890. {
  4891. const block< signed char, 4> D3DHighBitPos= {31,23,15,7};
  4892. fill( m_ToSurfMasks.begin(), m_ToSurfMasks.end(),
  4893. static_cast< TMasks::value_type>( 0));
  4894. fill( m_D3DBitShftRgt.begin(), m_D3DBitShftRgt.end(),
  4895. static_cast< TD3DBitShftRgt::value_type>( 0));
  4896. // Alpha
  4897. if((PF.dwFlags& DDPF_ALPHA)!= 0)
  4898. {
  4899. assert( PF.dwAlphaBitDepth< 32);
  4900. m_ToSurfMasks[ 0]= (0x1<< PF.dwAlphaBitDepth)- 1;
  4901. }
  4902. else if((PF.dwFlags& DDPF_ALPHAPIXELS)!= 0)
  4903. m_ToSurfMasks[ 0]= PF.dwRGBAlphaBitMask;
  4904. // RGB Color
  4905. if((PF.dwFlags& DDPF_RGB)!= 0)
  4906. {
  4907. m_ToSurfMasks[ 1]= PF.dwRBitMask;
  4908. m_ToSurfMasks[ 2]= PF.dwGBitMask;
  4909. m_ToSurfMasks[ 3]= PF.dwBBitMask;
  4910. }
  4911. // Z
  4912. if((PF.dwFlags& DDPF_ZBUFFER)!= 0)
  4913. {
  4914. m_D3DBitShftRgt[ 5]= PF.dwZBufferBitDepth;
  4915. if( 32== PF.dwZBufferBitDepth)
  4916. m_ToSurfMasks[ 4]= 0xFFFFFFFF;
  4917. else
  4918. m_ToSurfMasks[ 4]= (0x1<< PF.dwZBufferBitDepth)- 1;
  4919. }
  4920. else if((PF.dwFlags& DDPF_ZPIXELS)!= 0)
  4921. {
  4922. DWORD dwZBitMask( PF.dwRGBZBitMask);
  4923. m_ToSurfMasks[ 5]= PF.dwRGBZBitMask;
  4924. while((dwZBitMask& 1)== 0)
  4925. {
  4926. m_D3DBitShftRgt[ 4]--;
  4927. dwZBitMask>>= 1;
  4928. }
  4929. while((dwZBitMask& 1)!= 0)
  4930. {
  4931. dwZBitMask>>= 1;
  4932. m_D3DBitShftRgt[ 5]++;
  4933. }
  4934. }
  4935. // Stensil
  4936. if((PF.dwFlags& DDPF_STENCILBUFFER)!= 0)
  4937. {
  4938. DWORD dwSBitMask( PF.dwStencilBitMask);
  4939. m_ToSurfMasks[ 6]= PF.dwStencilBitMask;
  4940. while((dwSBitMask& 1)== 0)
  4941. {
  4942. m_D3DBitShftRgt[ 6]--;
  4943. dwSBitMask>>= 1;
  4944. }
  4945. while((dwSBitMask& 1)!= 0)
  4946. {
  4947. dwSBitMask>>= 1;
  4948. m_D3DBitShftRgt[ 7]++;
  4949. }
  4950. }
  4951. block< signed char, 4>::const_iterator itD3DBitPos( D3DHighBitPos.begin());
  4952. TD3DBitShftRgt::iterator itBitShftRgt( m_D3DBitShftRgt.begin());
  4953. TMasks::const_iterator itToSurfMask( m_ToSurfMasks.begin());
  4954. while( itD3DBitPos!= D3DHighBitPos.end())
  4955. {
  4956. signed char iBitPos( 31);
  4957. TMasks::value_type dwMask( 0x80000000);
  4958. while((dwMask& *itToSurfMask)== 0 && iBitPos>= 0)
  4959. {
  4960. dwMask>>= 1;
  4961. iBitPos--;
  4962. }
  4963. *itBitShftRgt= ( iBitPos>= 0? *itD3DBitPos- iBitPos: 0);
  4964. ++itD3DBitPos;
  4965. ++itToSurfMask;
  4966. ++itBitShftRgt;
  4967. }
  4968. return *this;
  4969. }
  4970. // SurfData, ValidMask
  4971. pair< UINT32, UINT32> ConvColor( D3DCOLOR D3DColor) const
  4972. {
  4973. pair< UINT32, UINT32> RetVal( 0, 0);
  4974. const block< DWORD, 4> FromD3DMasks= {0xFF000000,0xFF0000,0xFF00,0xFF};
  4975. TD3DBitShftRgt::const_iterator itBitShftRgt( m_D3DBitShftRgt.begin());
  4976. block< DWORD, 4>::const_iterator itFromMask( FromD3DMasks.begin());
  4977. TMasks::const_iterator itToMask( m_ToSurfMasks.begin());
  4978. while( itFromMask!= FromD3DMasks.end())
  4979. {
  4980. const UINT32 uiTmp( D3DColor& *itFromMask);
  4981. RetVal.first|= *itToMask& (*itBitShftRgt>= 0?
  4982. uiTmp>> *itBitShftRgt: uiTmp<< *itBitShftRgt);
  4983. RetVal.second|= *itToMask;
  4984. ++itBitShftRgt;
  4985. ++itToMask;
  4986. ++itFromMask;
  4987. }
  4988. return RetVal;
  4989. }
  4990. // SurfData, ValidMask
  4991. pair< UINT32, UINT32> ConvZ( D3DVALUE D3DZ) const
  4992. {
  4993. CEnsureFPUModeForC FPUMode;
  4994. if( D3DZ> 1.0f)
  4995. D3DZ= 1.0f;
  4996. else if( D3DZ< 0.0f)
  4997. D3DZ= 0.0f;
  4998. pair< UINT32, UINT32> RetVal( 0, 0);
  4999. const UINT32 uiMaxZ( m_D3DBitShftRgt[ 5]== 32? 0xFFFFFFFF:
  5000. (0x1<< m_D3DBitShftRgt[ 5])- 1);
  5001. const UINT32 uiZVal( static_cast<UINT32>(
  5002. static_cast< DOUBLE>(D3DZ)* static_cast< DOUBLE>(uiMaxZ)+ 0.5));
  5003. RetVal.first|= m_ToSurfMasks[ 4]& (m_D3DBitShftRgt[ 4]>= 0?
  5004. uiZVal>> m_D3DBitShftRgt[ 4]: uiZVal<< m_D3DBitShftRgt[ 4]);
  5005. RetVal.second|= m_ToSurfMasks[ 4];
  5006. return RetVal;
  5007. }
  5008. // SurfData, ValidMask
  5009. pair< UINT32, UINT32> ConvS( DWORD D3DStensil) const
  5010. {
  5011. pair< UINT32, UINT32> RetVal( 0, 0);
  5012. RetVal.first|= m_ToSurfMasks[ 5]& (m_D3DBitShftRgt[ 6]>= 0?
  5013. D3DStensil>> m_D3DBitShftRgt[ 6]: D3DStensil<< m_D3DBitShftRgt[ 6]);
  5014. RetVal.second|= m_ToSurfMasks[ 5];
  5015. return RetVal;
  5016. }
  5017. };
  5018. class CGenSurface:
  5019. public IVidMemSurface
  5020. {
  5021. public: // Types
  5022. typedef unsigned int TLocks;
  5023. protected: // Variables
  5024. SD3DDataConv m_D3DDataConv;
  5025. DWORD m_dwCaps;
  5026. TLocks m_uiLocks;
  5027. // Regular data
  5028. void* m_pData;
  5029. LONG m_lPitch;
  5030. size_t m_uiBytes;
  5031. WORD m_wWidth;
  5032. WORD m_wHeight;
  5033. unsigned char m_ucBPP;
  5034. public: // Functions
  5035. CGenSurface( const DDSURFACEDESC& SDesc, PORTABLE_DDRAWSURFACE_LCL& DDSurf)
  5036. :IVidMemSurface( DDSurf.lpSurfMore()->dwSurfaceHandle()),
  5037. m_dwCaps( SDesc.ddsCaps.dwCaps), m_uiLocks( 0), m_pData( NULL),
  5038. m_lPitch( 0), m_uiBytes( 0), m_wWidth( DDSurf.lpGbl()->wWidth),
  5039. m_wHeight( DDSurf.lpGbl()->wHeight), m_ucBPP( 0)
  5040. {
  5041. size_t uiBytesPerPixel( 0);
  5042. // Certain data needs to be written into the DDSurf description,
  5043. // so that the DXG runtime and the app will know characteristics
  5044. // about the surface. (fpVidMem, lPitch, etc.)
  5045. // DO NOT STORE &DDSurf! This is considered illegal. The typical
  5046. // implementation contains a surfaceDB which contains copies of the
  5047. // DDRAWI_ structures.
  5048. if((SDesc.dwFlags& DDSD_PIXELFORMAT)!= 0)
  5049. {
  5050. // CGenSurface can only be used for byte-aligned pixels.
  5051. assert( 8== SDesc.ddpfPixelFormat.dwRGBBitCount ||
  5052. 16== SDesc.ddpfPixelFormat.dwRGBBitCount ||
  5053. 24== SDesc.ddpfPixelFormat.dwRGBBitCount ||
  5054. 32== SDesc.ddpfPixelFormat.dwRGBBitCount);
  5055. m_D3DDataConv= SDesc.ddpfPixelFormat;
  5056. m_ucBPP= static_cast<unsigned char>(
  5057. SDesc.ddpfPixelFormat.dwRGBBitCount>> 3);
  5058. // Align the Pitch/ Width.
  5059. DDSurf.lpGbl()->lPitch= m_lPitch= ((m_ucBPP* m_wWidth+ 7)& ~7);
  5060. m_uiBytes= m_lPitch* m_wHeight;
  5061. }
  5062. else if((m_dwCaps& DDSCAPS_EXECUTEBUFFER)!= 0)
  5063. {
  5064. // Execute buffers are considered linear and byte-sized.
  5065. m_lPitch= DDSurf.lpGbl()->lPitch;
  5066. m_uiBytes= m_lPitch* m_wHeight;
  5067. }
  5068. else
  5069. {
  5070. const bool Unsupported_Surface_In_Allocation_Routine2( false);
  5071. assert( Unsupported_Surface_In_Allocation_Routine2);
  5072. }
  5073. // It would've been nice to have the initial proctection NOACCESS, but
  5074. // it seems the HAL needs to read to the region, initially.
  5075. m_pData= VirtualAlloc( NULL, m_uiBytes, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
  5076. if( m_pData== NULL)
  5077. throw bad_alloc( "Not enough memory to allocate Surface data");
  5078. DDSurf.lpGbl()->fpVidMem= reinterpret_cast<FLATPTR>(m_pData);
  5079. }
  5080. virtual ~CGenSurface()
  5081. {
  5082. // Warning: m_uiLocks doesn't have to be 0. The run-time will destroy
  5083. // a surface without un-locking it.
  5084. assert( m_pData!= NULL);
  5085. VirtualFree( m_pData, 0, MEM_DECOMMIT| MEM_RELEASE);
  5086. }
  5087. virtual void* Lock( DWORD dwFlags, const RECTL* pRect)
  5088. {
  5089. // Typically, m_uiLocks!= 0 equals bad design or bug. But, it is valid.
  5090. // Second Dummy removes vc6 unrefd variable warning.
  5091. numeric_limits< TLocks> Dummy; Dummy;
  5092. assert( Dummy.max()!= m_uiLocks);
  5093. ++m_uiLocks;
  5094. if( pRect!= NULL)
  5095. {
  5096. // If it is either a 1) VB, 2) IB or 3) CB then the rect has a
  5097. // special meaning. rect.top - rect.bottom gives the range of
  5098. // memory desired, because of being linear.
  5099. if((m_dwCaps& DDSCAPS_EXECUTEBUFFER)!= 0)
  5100. {
  5101. return static_cast<void*>( reinterpret_cast<UINT8*>(
  5102. m_pData)+ pRect->top);
  5103. }
  5104. else
  5105. {
  5106. return static_cast<void*>( reinterpret_cast<UINT8*>(
  5107. m_pData)+ pRect->top* m_lPitch+ pRect->left* m_ucBPP);
  5108. }
  5109. }
  5110. else
  5111. return m_pData;
  5112. }
  5113. virtual void Unlock( void)
  5114. {
  5115. assert( 0!= m_uiLocks);
  5116. --m_uiLocks;
  5117. }
  5118. virtual void Clear( const D3DHAL_DP2CLEAR& DP2Clear, const RECT& RC)
  5119. {
  5120. // A VB, IB, or CB should never be asked to 'Clear'. Only
  5121. // RenderTargets and ZBuffers, etc.
  5122. assert((m_dwCaps& DDSCAPS_EXECUTEBUFFER)== 0);
  5123. // Check for empty RECT.
  5124. if((RC.left>= RC.right) || (RC.top>= RC.bottom))
  5125. return;
  5126. assert( 1<= m_ucBPP && 4>= m_ucBPP);
  5127. UINT32 ui32BitFill( 0), ui32BitValidMask( 0);
  5128. UINT32 ui32BitSMask( 4== m_ucBPP? 0xFFFFFFFF: (1<< (m_ucBPP* 8))- 1);
  5129. pair< UINT32, UINT32> RetVal;
  5130. if((DP2Clear.dwFlags& D3DCLEAR_TARGET)!= 0)
  5131. {
  5132. RetVal= m_D3DDataConv.ConvColor( DP2Clear.dwFillColor);
  5133. ui32BitFill|= RetVal.first;
  5134. ui32BitValidMask|= RetVal.second;
  5135. }
  5136. if((DP2Clear.dwFlags& D3DCLEAR_ZBUFFER)!= 0)
  5137. {
  5138. RetVal= m_D3DDataConv.ConvZ( DP2Clear.dvFillDepth);
  5139. ui32BitFill|= RetVal.first;
  5140. ui32BitValidMask|= RetVal.second;
  5141. }
  5142. if((DP2Clear.dwFlags& D3DCLEAR_STENCIL)!= 0)
  5143. {
  5144. RetVal= m_D3DDataConv.ConvS( DP2Clear.dwFillStencil);
  5145. ui32BitFill|= RetVal.first;
  5146. ui32BitValidMask|= RetVal.second;
  5147. }
  5148. RECTL RectL;
  5149. RectL.top= RC.top;
  5150. RectL.left= RC.left;
  5151. RectL.bottom= RC.bottom;
  5152. RectL.right= RC.right;
  5153. unsigned int iRow( RC.bottom- RC.top);
  5154. const unsigned int iCols( RC.right- RC.left);
  5155. // New scope for SurfaceLocker.
  5156. {
  5157. CSurfaceLocker< CGenSurface*> MySLocker( this, 0, &RectL);
  5158. UINT8* pSData= reinterpret_cast<UINT8*>( MySLocker.GetData());
  5159. if( 3== m_ucBPP)
  5160. {
  5161. UINT32 ui32FillData[3];
  5162. ui32FillData[0]= ((ui32BitFill& 0xFFFFFF)<< 8)|
  5163. ((ui32BitFill& 0xFF0000)>> 16);
  5164. ui32FillData[1]= ((ui32BitFill& 0x00FFFF)<< 16)|
  5165. ((ui32BitFill& 0xFFFF00)>> 8);
  5166. ui32FillData[2]= ((ui32BitFill& 0x0000FF)<< 24)|
  5167. ((ui32BitFill& 0xFFFFFF)>> 0);
  5168. // Little-endian implementation.
  5169. UINT8 ui8FillData[3];
  5170. ui8FillData[0]= (0xFF& ui32BitFill);
  5171. ui8FillData[1]= (0xFF00& ui32BitFill)>> 8;
  5172. ui8FillData[2]= (0xFF0000& ui32BitFill)>> 16;
  5173. if( ui32BitSMask== ui32BitValidMask)
  5174. {
  5175. // Only fill, no need to read, modify, write.
  5176. do
  5177. {
  5178. UINT32* p32Data= reinterpret_cast<UINT32*>(pSData);
  5179. // We've packed 4 pixels of data in 3 UINT32.
  5180. unsigned int iCol( iCols>> 2); // (>> 2) == (/ 4)
  5181. // Unroll.
  5182. if( iCol!= 0) do
  5183. {
  5184. p32Data[ 0]= ui32FillData[0];
  5185. p32Data[ 1]= ui32FillData[1];
  5186. p32Data[ 2]= ui32FillData[2];
  5187. p32Data[ 3]= ui32FillData[0];
  5188. p32Data[ 4]= ui32FillData[1];
  5189. p32Data[ 5]= ui32FillData[2];
  5190. p32Data[ 6]= ui32FillData[0];
  5191. p32Data[ 7]= ui32FillData[1];
  5192. p32Data[ 8]= ui32FillData[2];
  5193. p32Data[ 9]= ui32FillData[0];
  5194. p32Data[10]= ui32FillData[1];
  5195. p32Data[11]= ui32FillData[2];
  5196. p32Data+= 12;
  5197. } while( --iCol);
  5198. iCol= iCols& 0x3; // (% 4) == (& 0x3)
  5199. if( iCol!= 0) {
  5200. UINT8* p8Data= reinterpret_cast<UINT8*>(p32Data);
  5201. do
  5202. {
  5203. p8Data[0]= ui8FillData[0];
  5204. p8Data[1]= ui8FillData[1];
  5205. p8Data[2]= ui8FillData[2];
  5206. p8Data+= 3;
  5207. } while( --iCol);
  5208. }
  5209. pSData+= m_lPitch;
  5210. } while( --iRow);
  5211. }
  5212. else
  5213. {
  5214. const UINT32 ui32BitMask= ~ui32BitValidMask;
  5215. UINT32 ui32MaskData[3];
  5216. ui32MaskData[0]= ((ui32BitMask& 0xFFFFFF)<< 8)|
  5217. ((ui32BitMask& 0xFF0000)>> 16);
  5218. ui32MaskData[1]= ((ui32BitMask& 0x00FFFF)<< 16)|
  5219. ((ui32BitMask& 0xFFFF00)>> 8);
  5220. ui32MaskData[2]= ((ui32BitMask& 0x0000FF)<< 24)|
  5221. ((ui32BitMask& 0xFFFFFF)>> 0);
  5222. UINT8 ui8MaskData[3];
  5223. ui8MaskData[0]= (0xFF& ui32BitMask);
  5224. ui8MaskData[1]= (0xFF00& ui32BitMask)>> 8;
  5225. ui8MaskData[2]= (0xFF0000& ui32BitMask)>> 16;
  5226. // Need to mask in the data.
  5227. do
  5228. {
  5229. UINT32* p32Data= reinterpret_cast<UINT32*>(pSData);
  5230. // We've packed 4 pixels of data in 3 UINT32.
  5231. int iCol( iCols>> 2); // (>> 2) == (/ 4)
  5232. // Unroll.
  5233. if( iCol!= 0) do
  5234. {
  5235. p32Data[ 0]= (p32Data[ 0]& ui32MaskData[0])| ui32FillData[0];
  5236. p32Data[ 1]= (p32Data[ 1]& ui32MaskData[1])| ui32FillData[1];
  5237. p32Data[ 2]= (p32Data[ 2]& ui32MaskData[2])| ui32FillData[2];
  5238. p32Data[ 3]= (p32Data[ 3]& ui32MaskData[0])| ui32FillData[0];
  5239. p32Data[ 4]= (p32Data[ 4]& ui32MaskData[1])| ui32FillData[1];
  5240. p32Data[ 5]= (p32Data[ 5]& ui32MaskData[2])| ui32FillData[2];
  5241. p32Data[ 6]= (p32Data[ 6]& ui32MaskData[0])| ui32FillData[0];
  5242. p32Data[ 7]= (p32Data[ 7]& ui32MaskData[1])| ui32FillData[1];
  5243. p32Data[ 8]= (p32Data[ 8]& ui32MaskData[2])| ui32FillData[2];
  5244. p32Data[ 9]= (p32Data[ 9]& ui32MaskData[0])| ui32FillData[0];
  5245. p32Data[10]= (p32Data[10]& ui32MaskData[1])| ui32FillData[1];
  5246. p32Data[11]= (p32Data[11]& ui32MaskData[2])| ui32FillData[2];
  5247. p32Data+= 12;
  5248. } while( --iCol);
  5249. iCol= iCols& 0x3; // (% 4) == (& 0x3)
  5250. if( iCol!= 0) {
  5251. UINT8* p8Data= reinterpret_cast<UINT8*>(p32Data);
  5252. do
  5253. {
  5254. p8Data[0]= (p8Data[0]& ui8MaskData[0])| ui8FillData[0];
  5255. p8Data[1]= (p8Data[1]& ui8MaskData[1])| ui8FillData[1];
  5256. p8Data[2]= (p8Data[2]& ui8MaskData[2])| ui8FillData[2];
  5257. p8Data+= 3;
  5258. } while( --iCol);
  5259. }
  5260. pSData+= m_lPitch;
  5261. } while( --iRow);
  5262. }
  5263. }
  5264. else
  5265. {
  5266. unsigned int uiPakedPixels;
  5267. unsigned int uiPixelsLeft;
  5268. UINT32 ui32FillData;
  5269. UINT32 ui32MaskData;
  5270. if( 1== m_ucBPP)
  5271. {
  5272. uiPakedPixels= iCols>> 6;
  5273. uiPixelsLeft= iCols& 0x3F;
  5274. ui32FillData= (ui32BitFill& 0xFF)|
  5275. ((ui32BitFill& 0xFF)<< 8)|
  5276. ((ui32BitFill& 0xFF)<< 16)|
  5277. ((ui32BitFill& 0xFF)<< 24);
  5278. ui32MaskData= (~ui32BitValidMask& 0xFF)|
  5279. ((~ui32BitValidMask& 0xFF)<< 8)|
  5280. ((~ui32BitValidMask& 0xFF)<< 16)|
  5281. ((~ui32BitValidMask& 0xFF)<< 24);
  5282. }
  5283. else if( 2== m_ucBPP)
  5284. {
  5285. uiPakedPixels= iCols>> 5;
  5286. uiPixelsLeft= iCols& 0x1F;
  5287. ui32FillData= (ui32BitFill& 0xFFFF)|
  5288. ((ui32BitFill& 0xFFFF)<< 16);
  5289. ui32MaskData= (~ui32BitValidMask& 0xFFFF)|
  5290. ((~ui32BitValidMask& 0xFFFF)<< 16);
  5291. }
  5292. else if( 4== m_ucBPP)
  5293. {
  5294. uiPakedPixels= iCols>> 4;
  5295. uiPixelsLeft= iCols& 0xF;
  5296. ui32FillData= ui32BitFill;
  5297. ui32MaskData= ~ui32BitValidMask;
  5298. }
  5299. if( ui32BitSMask== ui32BitValidMask)
  5300. {
  5301. // Only fill, no need to read, modify, write.
  5302. do
  5303. {
  5304. UINT32* p32Data= reinterpret_cast<UINT32*>(pSData);
  5305. // We've packed pixels of data in a UINT32.
  5306. unsigned int iCol( uiPakedPixels);
  5307. // Unroll.
  5308. if( iCol!= 0) do
  5309. {
  5310. p32Data[ 0]= ui32FillData;
  5311. p32Data[ 1]= ui32FillData;
  5312. p32Data[ 2]= ui32FillData;
  5313. p32Data[ 3]= ui32FillData;
  5314. p32Data[ 4]= ui32FillData;
  5315. p32Data[ 5]= ui32FillData;
  5316. p32Data[ 6]= ui32FillData;
  5317. p32Data[ 7]= ui32FillData;
  5318. p32Data[ 8]= ui32FillData;
  5319. p32Data[ 9]= ui32FillData;
  5320. p32Data[10]= ui32FillData;
  5321. p32Data[11]= ui32FillData;
  5322. p32Data[12]= ui32FillData;
  5323. p32Data[13]= ui32FillData;
  5324. p32Data[14]= ui32FillData;
  5325. p32Data[15]= ui32FillData;
  5326. p32Data+= 16;
  5327. } while( --iCol);
  5328. iCol= uiPixelsLeft;
  5329. if( iCol!= 0) {
  5330. if( 1== m_ucBPP)
  5331. {
  5332. UINT8 ui8FillData= ui32FillData& 0xFF;
  5333. UINT8* p8Data= reinterpret_cast<UINT8*>(p32Data);
  5334. do
  5335. {
  5336. p8Data[0]= ui8FillData;
  5337. p8Data++;
  5338. } while( --iCol);
  5339. }
  5340. else if( 2== m_ucBPP)
  5341. {
  5342. UINT16 ui16FillData= ui32FillData& 0xFFFF;
  5343. UINT16* p16Data= reinterpret_cast<UINT16*>(p32Data);
  5344. do
  5345. {
  5346. p16Data[0]= ui16FillData;
  5347. p16Data++;
  5348. } while( --iCol);
  5349. }
  5350. else if( 4== m_ucBPP)
  5351. {
  5352. do
  5353. {
  5354. p32Data[0]= ui32FillData;
  5355. p32Data++;
  5356. } while( --iCol);
  5357. }
  5358. }
  5359. pSData+= m_lPitch;
  5360. } while( --iRow);
  5361. }
  5362. else
  5363. {
  5364. // Need to mask in the data.
  5365. do
  5366. {
  5367. UINT32* p32Data= reinterpret_cast<UINT32*>(pSData);
  5368. // We've packed pixels of data in a UINT32.
  5369. unsigned int iCol( uiPakedPixels);
  5370. // Unroll.
  5371. if( iCol!= 0) do
  5372. {
  5373. p32Data[ 0]= (p32Data[ 0]& ui32MaskData)| ui32FillData;
  5374. p32Data[ 1]= (p32Data[ 1]& ui32MaskData)| ui32FillData;
  5375. p32Data[ 2]= (p32Data[ 2]& ui32MaskData)| ui32FillData;
  5376. p32Data[ 3]= (p32Data[ 3]& ui32MaskData)| ui32FillData;
  5377. p32Data[ 4]= (p32Data[ 4]& ui32MaskData)| ui32FillData;
  5378. p32Data[ 5]= (p32Data[ 5]& ui32MaskData)| ui32FillData;
  5379. p32Data[ 6]= (p32Data[ 6]& ui32MaskData)| ui32FillData;
  5380. p32Data[ 7]= (p32Data[ 7]& ui32MaskData)| ui32FillData;
  5381. p32Data[ 8]= (p32Data[ 8]& ui32MaskData)| ui32FillData;
  5382. p32Data[ 9]= (p32Data[ 9]& ui32MaskData)| ui32FillData;
  5383. p32Data[10]= (p32Data[10]& ui32MaskData)| ui32FillData;
  5384. p32Data[11]= (p32Data[11]& ui32MaskData)| ui32FillData;
  5385. p32Data[12]= (p32Data[12]& ui32MaskData)| ui32FillData;
  5386. p32Data[13]= (p32Data[13]& ui32MaskData)| ui32FillData;
  5387. p32Data[14]= (p32Data[14]& ui32MaskData)| ui32FillData;
  5388. p32Data[15]= (p32Data[15]& ui32MaskData)| ui32FillData;
  5389. p32Data+= 16;
  5390. } while( --iCol);
  5391. iCol= uiPixelsLeft;
  5392. if( iCol!= 0) {
  5393. if( 1== m_ucBPP)
  5394. {
  5395. UINT8 ui8FillData= ui32FillData& 0xFF;
  5396. UINT8 ui8MaskData= ui32MaskData& 0xFF;
  5397. UINT8* p8Data= reinterpret_cast<UINT8*>(p32Data);
  5398. do
  5399. {
  5400. p8Data[0]= (p8Data[0]& ui8MaskData)| ui8FillData;
  5401. p8Data++;
  5402. } while( --iCol);
  5403. }
  5404. else if( 2== m_ucBPP)
  5405. {
  5406. UINT16 ui16FillData= ui32FillData& 0xFFFF;
  5407. UINT16 ui16MaskData= ui32MaskData& 0xFFFF;
  5408. UINT16* p16Data= reinterpret_cast<UINT16*>(p32Data);
  5409. do
  5410. {
  5411. p16Data[0]= (p16Data[0]& ui16MaskData)| ui16FillData;
  5412. p16Data++;
  5413. } while( --iCol);
  5414. }
  5415. else if( 4== m_ucBPP)
  5416. {
  5417. do
  5418. {
  5419. p32Data[0]= (p32Data[0]& ui32MaskData)| ui32FillData;
  5420. p32Data++;
  5421. } while( --iCol);
  5422. }
  5423. }
  5424. pSData+= m_lPitch;
  5425. } while( --iRow);
  5426. }
  5427. }
  5428. }
  5429. }
  5430. static IVidMemSurface* CreateSurf( const DDSURFACEDESC& SDesc,
  5431. PORTABLE_DDRAWSURFACE_LCL& DDSurf)
  5432. {
  5433. return new CGenSurface( SDesc, DDSurf);
  5434. }
  5435. };
  5436. struct SPixelFormat: public DDPIXELFORMAT
  5437. {
  5438. SPixelFormat( D3DFORMAT D3DFmt)
  5439. {
  5440. ZeroMemory( static_cast< DDPIXELFORMAT*>(this),
  5441. sizeof(DDPIXELFORMAT));
  5442. dwSize= sizeof(DDPIXELFORMAT);
  5443. // Convert away
  5444. if( HIWORD( static_cast< DWORD>(D3DFmt))!= 0)
  5445. {
  5446. dwFlags= DDPF_FOURCC;
  5447. dwFourCC= static_cast< DWORD>(D3DFmt);
  5448. }
  5449. else switch( D3DFmt)
  5450. {
  5451. case( D3DFMT_R8G8B8):
  5452. dwFlags = DDPF_RGB;
  5453. dwRBitMask = 0x00ff0000;
  5454. dwGBitMask = 0x0000ff00;
  5455. dwBBitMask = 0x000000ff;
  5456. dwRGBBitCount = 24;
  5457. break;
  5458. case( D3DFMT_A8R8G8B8):
  5459. dwFlags = DDPF_RGB| DDPF_ALPHAPIXELS;
  5460. dwRGBAlphaBitMask = 0xFF000000;
  5461. dwRBitMask = 0x00ff0000;
  5462. dwGBitMask = 0x0000ff00;
  5463. dwBBitMask = 0x000000ff;
  5464. dwRGBBitCount = 32;
  5465. break;
  5466. case( D3DFMT_X8R8G8B8):
  5467. dwFlags = DDPF_RGB;
  5468. dwRBitMask = 0x00ff0000;
  5469. dwGBitMask = 0x0000ff00;
  5470. dwBBitMask = 0x000000ff;
  5471. dwRGBBitCount = 32;
  5472. break;
  5473. case( D3DFMT_R5G6B5):
  5474. dwFlags = DDPF_RGB;
  5475. dwRBitMask = 0x0000f800;
  5476. dwGBitMask = 0x000007e0;
  5477. dwBBitMask = 0x0000001f;
  5478. dwRGBBitCount = 16;
  5479. break;
  5480. case( D3DFMT_X1R5G5B5):
  5481. dwFlags = DDPF_RGB;
  5482. dwRBitMask = 0x00007c00;
  5483. dwGBitMask = 0x000003e0;
  5484. dwBBitMask = 0x0000001f;
  5485. dwRGBBitCount = 16;
  5486. break;
  5487. case( D3DFMT_A1R5G5B5):
  5488. dwFlags = DDPF_RGB| DDPF_ALPHAPIXELS;
  5489. dwRGBAlphaBitMask = 0x00008000;
  5490. dwRBitMask = 0x00007c00;
  5491. dwGBitMask = 0x000003e0;
  5492. dwBBitMask = 0x0000001f;
  5493. dwRGBBitCount = 16;
  5494. break;
  5495. case( D3DFMT_A4R4G4B4):
  5496. dwFlags = DDPF_RGB| DDPF_ALPHAPIXELS;
  5497. dwRGBAlphaBitMask = 0x0000f000;
  5498. dwRBitMask = 0x00000f00;
  5499. dwGBitMask = 0x000000f0;
  5500. dwBBitMask = 0x0000000f;
  5501. dwRGBBitCount = 16;
  5502. break;
  5503. case( D3DFMT_X4R4G4B4):
  5504. dwFlags = DDPF_RGB;
  5505. dwRBitMask = 0x00000f00;
  5506. dwGBitMask = 0x000000f0;
  5507. dwBBitMask = 0x0000000f;
  5508. dwRGBBitCount = 16;
  5509. break;
  5510. case( D3DFMT_R3G3B2):
  5511. dwFlags = DDPF_RGB;
  5512. dwRBitMask = 0x000000e0;
  5513. dwGBitMask = 0x0000001c;
  5514. dwBBitMask = 0x00000003;
  5515. dwRGBBitCount = 8;
  5516. break;
  5517. case( D3DFMT_A8R3G3B2):
  5518. dwFlags = DDPF_RGB| DDPF_ALPHAPIXELS;
  5519. dwRGBAlphaBitMask = 0x0000FF00;
  5520. dwRBitMask = 0x000000e0;
  5521. dwGBitMask = 0x0000001c;
  5522. dwBBitMask = 0x00000003;
  5523. dwRGBBitCount = 16;
  5524. break;
  5525. case( D3DFMT_A8P8):
  5526. dwFlags = DDPF_RGB| DDPF_ALPHAPIXELS| DDPF_PALETTEINDEXED8;
  5527. dwRGBAlphaBitMask = 0x0000FF00;
  5528. dwRGBBitCount = 16;
  5529. break;
  5530. case( D3DFMT_P8):
  5531. dwFlags = DDPF_RGB| DDPF_PALETTEINDEXED8;
  5532. dwRGBBitCount = 8;
  5533. break;
  5534. case( D3DFMT_L8):
  5535. dwFlags = DDPF_LUMINANCE;
  5536. dwLuminanceBitMask = 0x000000FF;
  5537. dwLuminanceBitCount = 8;
  5538. break;
  5539. case( D3DFMT_A8L8):
  5540. dwFlags = DDPF_LUMINANCE| DDPF_ALPHAPIXELS;
  5541. dwLuminanceAlphaBitMask = 0x0000FF00;
  5542. dwLuminanceBitMask = 0x000000FF;
  5543. dwLuminanceBitCount = 16;
  5544. break;
  5545. case( D3DFMT_A4L4):
  5546. dwFlags = DDPF_LUMINANCE| DDPF_ALPHAPIXELS;
  5547. dwLuminanceAlphaBitMask = 0x000000F0;
  5548. dwLuminanceBitMask = 0x0000000F;
  5549. dwLuminanceBitCount = 8;
  5550. break;
  5551. case( D3DFMT_V8U8):
  5552. dwFlags = DDPF_BUMPDUDV;
  5553. dwBumpDvBitMask = 0x0000FF00;
  5554. dwBumpDuBitMask = 0x000000FF;
  5555. dwBumpBitCount = 16;
  5556. break;
  5557. case( D3DFMT_L6V5U5):
  5558. dwFlags = DDPF_BUMPDUDV| DDPF_BUMPLUMINANCE;
  5559. dwBumpLuminanceBitMask = 0x0000FC00;
  5560. dwBumpDvBitMask = 0x000003E0;
  5561. dwBumpDuBitMask = 0x0000001F;
  5562. dwBumpBitCount = 16;
  5563. break;
  5564. case( D3DFMT_X8L8V8U8):
  5565. dwFlags = DDPF_BUMPDUDV| DDPF_BUMPLUMINANCE;
  5566. dwBumpLuminanceBitMask = 0x00FF0000;
  5567. dwBumpDvBitMask = 0x0000FF00;
  5568. dwBumpDuBitMask = 0x000000FF;
  5569. dwBumpBitCount = 32;
  5570. break;
  5571. case( D3DFMT_A8):
  5572. dwFlags = DDPF_ALPHA;
  5573. dwAlphaBitDepth = 8;
  5574. break;
  5575. case( D3DFMT_D16):
  5576. case( D3DFMT_D16_LOCKABLE):
  5577. dwFlags = DDPF_ZBUFFER;
  5578. dwZBufferBitDepth = 16;
  5579. dwZBitMask = 0xFFFF;
  5580. break;
  5581. case( D3DFMT_D32):
  5582. dwFlags = DDPF_ZBUFFER;
  5583. dwZBufferBitDepth = 32;
  5584. dwZBitMask = 0xFFFFFFFF;
  5585. break;
  5586. case( D3DFMT_D15S1):
  5587. dwFlags = DDPF_ZBUFFER| DDPF_STENCILBUFFER;
  5588. dwZBufferBitDepth = 16;
  5589. dwZBitMask = 0xFFFE;
  5590. dwStencilBitDepth = 1;
  5591. dwStencilBitMask = 0x0001;
  5592. break;
  5593. case( D3DFMT_D24S8):
  5594. dwFlags = DDPF_ZBUFFER| DDPF_STENCILBUFFER;
  5595. dwZBufferBitDepth = 32;
  5596. dwZBitMask = 0xFFFFFF00;
  5597. dwStencilBitDepth = 8;
  5598. dwStencilBitMask = 0xFF;
  5599. break;
  5600. case( D3DFMT_S1D15):
  5601. dwFlags = DDPF_ZBUFFER| DDPF_STENCILBUFFER;
  5602. dwZBufferBitDepth = 16;
  5603. dwZBitMask = 0x7FFF;
  5604. dwStencilBitDepth = 1;
  5605. dwStencilBitMask = 0x8000;
  5606. break;
  5607. case( D3DFMT_S8D24):
  5608. dwFlags = DDPF_ZBUFFER| DDPF_STENCILBUFFER;
  5609. dwZBufferBitDepth = 32;
  5610. dwZBitMask = 0x00FFFFFF;
  5611. dwStencilBitDepth = 8;
  5612. dwStencilBitMask = 0xFF000000;
  5613. break;
  5614. case( D3DFMT_X8D24):
  5615. dwFlags = DDPF_ZBUFFER;
  5616. dwZBufferBitDepth = 32;
  5617. dwZBitMask = 0x00FFFFFF;
  5618. break;
  5619. case( D3DFMT_D24X8):
  5620. dwFlags = DDPF_ZBUFFER;
  5621. dwZBufferBitDepth = 32;
  5622. dwZBitMask = 0xFFFFFF00;
  5623. break;
  5624. case( D3DFMT_D24X4S4):
  5625. dwFlags = DDPF_ZBUFFER| DDPF_STENCILBUFFER;
  5626. dwZBufferBitDepth = 32;
  5627. dwZBitMask = 0xFFFFFF00;
  5628. dwStencilBitDepth = 4;
  5629. dwStencilBitMask = 0x0000000F;
  5630. break;
  5631. case( D3DFMT_X4S4D24):
  5632. dwFlags = DDPF_ZBUFFER| DDPF_STENCILBUFFER;
  5633. dwZBufferBitDepth = 32;
  5634. dwZBitMask = 0x00FFFFFF;
  5635. dwStencilBitDepth = 4;
  5636. dwStencilBitMask = 0x0F000000;
  5637. break;
  5638. default:
  5639. const bool Unrecognized_D3DFmt( false);
  5640. assert( Unrecognized_D3DFmt);
  5641. dwFlags= DDPF_FOURCC;
  5642. dwFourCC= static_cast< DWORD>(D3DFmt);
  5643. break;
  5644. }
  5645. }
  5646. };
  5647. struct SMatchSDesc:
  5648. public unary_function< const DDSURFACEDESC&, bool>
  5649. {
  5650. const DDSURFACEDESC& m_SDesc;
  5651. SMatchSDesc( const DDSURFACEDESC& SDesc) : m_SDesc( SDesc) { }
  5652. result_type operator()( argument_type Arg) const
  5653. {
  5654. if((Arg.dwFlags& DDSD_CAPS)!= 0&& ((m_SDesc.dwFlags& DDSD_CAPS)== 0 ||
  5655. (m_SDesc.ddsCaps.dwCaps& Arg.ddsCaps.dwCaps)!= Arg.ddsCaps.dwCaps))
  5656. return false;
  5657. if((Arg.dwFlags& DDSD_PIXELFORMAT)!= 0&&
  5658. ((m_SDesc.dwFlags& DDSD_PIXELFORMAT)== 0 ||
  5659. m_SDesc.ddpfPixelFormat.dwFlags!= Arg.ddpfPixelFormat.dwFlags ||
  5660. m_SDesc.ddpfPixelFormat.dwFourCC!= Arg.ddpfPixelFormat.dwFourCC ||
  5661. m_SDesc.ddpfPixelFormat.dwRGBBitCount!= Arg.ddpfPixelFormat.dwRGBBitCount ||
  5662. m_SDesc.ddpfPixelFormat.dwRBitMask!= Arg.ddpfPixelFormat.dwRBitMask ||
  5663. m_SDesc.ddpfPixelFormat.dwGBitMask!= Arg.ddpfPixelFormat.dwGBitMask ||
  5664. m_SDesc.ddpfPixelFormat.dwBBitMask!= Arg.ddpfPixelFormat.dwBBitMask ||
  5665. m_SDesc.ddpfPixelFormat.dwRGBZBitMask!= Arg.ddpfPixelFormat.dwRGBZBitMask))
  5666. return false;
  5667. return true;
  5668. }
  5669. };
  5670. ////////////////////////////////////////////////////////////////////////////////
  5671. //
  5672. // CSurfaceAllocator
  5673. //
  5674. ////////////////////////////////////////////////////////////////////////////////
  5675. template< class TMatchFn= SMatchSDesc>
  5676. class CIVidMemAllocator
  5677. {
  5678. public: // Types
  5679. typedef IVidMemSurface TSurface;
  5680. typedef TSurface* (*TCreateSurfFn)( const DDSURFACEDESC&,
  5681. PORTABLE_DDRAWSURFACE_LCL&);
  5682. typedef vector< pair< DDSURFACEDESC, TCreateSurfFn> > TCreateSurfFns;
  5683. protected: // Types
  5684. TCreateSurfFns m_CreateSurfFns;
  5685. struct SAdaptedMatchFn: public TMatchFn
  5686. {
  5687. typedef typename TCreateSurfFns::value_type argument_type;
  5688. using typename TMatchFn::result_type;
  5689. SAdaptedMatchFn( const DDSURFACEDESC& SDesc) : TMatchFn( SDesc) {}
  5690. result_type operator()( argument_type Arg) const
  5691. { return (*static_cast< const TMatchFn*>(this))( Arg.first); }
  5692. };
  5693. public: // Functions
  5694. CIVidMemAllocator() { }
  5695. template< class TIter>
  5696. CIVidMemAllocator( TIter itStart, const TIter itEnd)
  5697. {
  5698. while( itStart!= itEnd)
  5699. {
  5700. m_CreateSurfFns.push_back(
  5701. typename TCreateSurfFns::value_type( *itStart, *itStart));
  5702. itStart++;
  5703. }
  5704. }
  5705. ~CIVidMemAllocator() { }
  5706. TSurface* CreateSurf( const DDSURFACEDESC& SDesc,
  5707. PORTABLE_DDRAWSURFACE_LCL& Surf) const
  5708. {
  5709. if( m_CreateSurfFns.empty())
  5710. return new CGenSurface( SDesc, Surf);
  5711. typename TCreateSurfFns::const_iterator itFound(
  5712. find_if( m_CreateSurfFns.begin(), m_CreateSurfFns.end(),
  5713. SAdaptedMatchFn( SDesc) ) );
  5714. if( itFound!= m_CreateSurfFns.end())
  5715. return (itFound->second)( SDesc, Surf);
  5716. // Warning, no specifications matched. If creation functions were
  5717. // provided, there should also be a "default" specification or
  5718. // DDSURFACEDESC with empty flags?, in order to "match rest".
  5719. const bool No_Default_CreateSurface_Function_Found( false);
  5720. assert( No_Default_CreateSurface_Function_Found);
  5721. return new CGenSurface( SDesc, Surf);
  5722. }
  5723. };
  5724. ////////////////////////////////////////////////////////////////////////////////
  5725. //
  5726. // CPerDDrawData
  5727. //
  5728. ////////////////////////////////////////////////////////////////////////////////
  5729. template< class THV= vector< DWORD> >
  5730. class CSurfDBEntry
  5731. {
  5732. public: // Types
  5733. typedef THV THandleVector;
  5734. protected: // Variables
  5735. DWORD m_LCLdwFlags;
  5736. DDSCAPS m_LCLddsCaps;
  5737. DWORD m_LCLdwBackBufferCount;
  5738. DWORD m_MOREdwMipMapCount;
  5739. DDSCAPSEX m_MOREddsCapsEx;
  5740. DWORD m_MOREdwSurfaceHandle;
  5741. DWORD m_MOREdwFVF;
  5742. DWORD m_GBLdwGlobalFlags;
  5743. ULONG_PTR m_GBLfpVidMem;
  5744. LONG m_GBLlPitch;
  5745. WORD m_GBLwHeight;
  5746. WORD m_GBLwWidth;
  5747. ULONG_PTR m_GBLdwReserved1;
  5748. DDPIXELFORMAT m_GBLddpfSurface;
  5749. THandleVector m_AttachedTo;
  5750. THandleVector m_AttachedFrom;
  5751. public: // Functions
  5752. CSurfDBEntry() { }
  5753. explicit CSurfDBEntry( PORTABLE_DDRAWSURFACE_LCL& DDSurf)
  5754. {
  5755. try{
  5756. (*this)= DDSurf;
  5757. } catch( ... ) {
  5758. m_AttachedTo.clear();
  5759. m_AttachedFrom.clear();
  5760. throw;
  5761. }
  5762. }
  5763. ~CSurfDBEntry() { }
  5764. CSurfDBEntry< THV>& operator=( PORTABLE_DDRAWSURFACE_LCL& DDSurf)
  5765. {
  5766. // DO NOT STORE &DDSurf. This is considered illegal.
  5767. m_LCLdwFlags= DDSurf.dwFlags();
  5768. m_LCLddsCaps= DDSurf.ddsCaps();
  5769. m_LCLdwBackBufferCount= DDSurf.dwBackBufferCount();
  5770. m_MOREdwMipMapCount= DDSurf.lpSurfMore()->dwMipMapCount();
  5771. m_MOREddsCapsEx= DDSurf.lpSurfMore()->ddsCapsEx();
  5772. m_MOREdwSurfaceHandle= DDSurf.lpSurfMore()->dwSurfaceHandle();
  5773. m_MOREdwFVF= DDSurf.lpSurfMore()->dwFVF();
  5774. m_GBLdwGlobalFlags= DDSurf.lpGbl()->dwGlobalFlags;
  5775. m_GBLfpVidMem= DDSurf.lpGbl()->fpVidMem;
  5776. m_GBLlPitch= DDSurf.lpGbl()->lPitch;
  5777. m_GBLwHeight= DDSurf.lpGbl()->wHeight;
  5778. m_GBLwWidth= DDSurf.lpGbl()->wWidth;
  5779. m_GBLdwReserved1= DDSurf.lpGbl()->dwReserved1;
  5780. m_GBLddpfSurface= DDSurf.lpGbl()->ddpfSurface;
  5781. const DWORD dwMyHandle( DDSurf.lpSurfMore()->dwSurfaceHandle());
  5782. m_AttachedTo.clear();
  5783. m_AttachedFrom.clear();
  5784. PORTABLE_ATTACHLIST* pAl, *pNextAl;
  5785. if((pAl= DDSurf.lpAttachList())!= NULL)
  5786. {
  5787. pNextAl= pAl;
  5788. do
  5789. {
  5790. if( pNextAl->lpAttached!= NULL&& dwMyHandle!=
  5791. pNextAl->lpAttached->lpSurfMore()->dwSurfaceHandle())
  5792. {
  5793. m_AttachedTo.push_back(
  5794. pNextAl->lpAttached->lpSurfMore()->dwSurfaceHandle());
  5795. }
  5796. pNextAl= pNextAl->lpLink;
  5797. } while( pNextAl!= pAl && pNextAl!= NULL);
  5798. }
  5799. if((pAl= DDSurf.lpAttachListFrom())!= NULL)
  5800. {
  5801. pNextAl= pAl;
  5802. do
  5803. {
  5804. if( pNextAl->lpAttached!= NULL&& dwMyHandle!=
  5805. pNextAl->lpAttached->lpSurfMore()->dwSurfaceHandle())
  5806. {
  5807. m_AttachedFrom.push_back(
  5808. pNextAl->lpAttached->lpSurfMore()->dwSurfaceHandle());
  5809. }
  5810. pNextAl= pNextAl->lpLink;
  5811. } while( pNextAl!= pAl && pNextAl!= NULL);
  5812. }
  5813. return *this;
  5814. }
  5815. DWORD GetLCLdwFlags( void) const
  5816. { return m_LCLdwFlags; }
  5817. const DDSCAPS& GetLCLddsCaps( void) const
  5818. { return m_LCLddsCaps; }
  5819. DWORD GetLCLdwBackBufferCount( void) const
  5820. { return m_LCLdwBackBufferCount; }
  5821. DWORD GetMOREdwMipMapCount( void) const
  5822. { return m_MOREdwMipMapCount; }
  5823. const DDSCAPSEX& GetMOREddsCapsEx( void) const
  5824. { return m_MOREddsCapsEx; }
  5825. DWORD GetMOREdwSurfaceHandle( void) const
  5826. { return m_MOREdwSurfaceHandle; }
  5827. DWORD GetMOREdwFVF( void) const
  5828. { return m_MOREdwFVF; }
  5829. DWORD GetGBLdwGlobalFlags( void) const
  5830. { return m_GBLdwGlobalFlags; }
  5831. ULONG_PTR GetGBLfpVidMem( void) const
  5832. { return m_GBLfpVidMem; }
  5833. LONG GetGBLlPitch( void) const
  5834. { return m_GBLlPitch; }
  5835. WORD GetGBLwHeight( void) const
  5836. { return m_GBLwHeight; }
  5837. WORD GetGBLwWidth( void) const
  5838. { return m_GBLwWidth; }
  5839. ULONG_PTR GetGBLdwReserved1( void) const
  5840. { return m_GBLdwReserved1; }
  5841. const DDPIXELFORMAT& GetGBLddpfSurface( void) const
  5842. { return m_GBLddpfSurface; }
  5843. const THandleVector& GetAttachedTo( void) const
  5844. { return m_AttachedTo; }
  5845. const THandleVector& GetAttachedFrom( void) const
  5846. { return m_AttachedFrom; }
  5847. };
  5848. template< class TPDBE= CPalDBEntry, class THV= vector< DWORD> >
  5849. class CSurfDBEntryWPal:
  5850. public CSurfDBEntry< THV>
  5851. {
  5852. public: // Types
  5853. typedef TPDBE TPalDBEntry;
  5854. protected: // Variables
  5855. TPalDBEntry* m_pPalDBEntry;
  5856. public: // Functions
  5857. CSurfDBEntryWPal():
  5858. m_pPalDBEntry( NULL)
  5859. { }
  5860. explicit CSurfDBEntryWPal( PORTABLE_DDRAWSURFACE_LCL& DDSurf):
  5861. CSurfDBEntry< THV>( DDSurf), m_pPalDBEntry( NULL)
  5862. { }
  5863. ~CSurfDBEntryWPal()
  5864. { }
  5865. CSurfDBEntryWPal< TPDBE, THV>& operator=( PORTABLE_DDRAWSURFACE_LCL& DDSurf)
  5866. {
  5867. CSurfDBEntry< THV>* pSub= static_cast< CSurfDBEntry< THV>*>( this);
  5868. // DO NOT STORE &DDSurf. This is considered illegal.
  5869. *pSub= DDSurf;
  5870. return *this;
  5871. }
  5872. void SetPalette( TPalDBEntry* pPalDBEntry)
  5873. { m_pPalDBEntry= pPalDBEntry; }
  5874. TPalDBEntry* GetPalette() const
  5875. { return m_pPalDBEntry; }
  5876. };
  5877. template< class TSuper, class TD, class TSDBE= CSurfDBEntry<>,
  5878. class TSDB= map< DWORD, TSDBE>,
  5879. class TFS= set< PORTABLE_DDRAWSURFACE_LCL*> >
  5880. class CSubPerDDrawData
  5881. {
  5882. public: // Types
  5883. typedef TD TDriver;
  5884. typedef TSDBE TSurfDBEntry;
  5885. typedef TSDB TSurfDB;
  5886. protected: // Variables
  5887. TDriver& m_Driver;
  5888. TSurfDB m_SurfDB;
  5889. protected: // Functions
  5890. CSubPerDDrawData( TDriver& Driver, const DDRAWI_DIRECTDRAW_LCL& DDLcl)
  5891. :m_Driver( Driver)
  5892. { }
  5893. ~CSubPerDDrawData() { }
  5894. public: // Functions
  5895. TDriver& GetDriver( void) const { return m_Driver; }
  5896. TSurfDBEntry* GetSurfDBEntry( DWORD dwH)
  5897. {
  5898. typename TSurfDB::iterator itSurf( m_SurfDB.find( dwH));
  5899. if( itSurf!= m_SurfDB.end())
  5900. return &itSurf->second;
  5901. else
  5902. return NULL;
  5903. }
  5904. const TSurfDBEntry* GetSurfDBEntry( DWORD dwH) const
  5905. {
  5906. typename TSurfDB::const_iterator itSurf( m_SurfDB.find( dwH));
  5907. if( itSurf!= m_SurfDB.end())
  5908. return &itSurf->second;
  5909. else
  5910. return NULL;
  5911. }
  5912. bool PreProcessFullSurface( PORTABLE_DDRAWSURFACE_LCL& DDSLcl) const
  5913. {
  5914. // DO NOT STORE &DDSLcl. This is considered illegal.
  5915. // It is only valid for the duration of the call.
  5916. return false;
  5917. }
  5918. bool PreProcessIndividualSurface( PORTABLE_DDRAWSURFACE_LCL& DDSLcl) const
  5919. {
  5920. // DO NOT STORE &DDSLcl. This is considered illegal.
  5921. // It is only valid for the duration of the call.
  5922. return false;
  5923. }
  5924. void ProcessIndividualSurface( PORTABLE_DDRAWSURFACE_LCL& DDSLcl)
  5925. {
  5926. // DO NOT STORE &DDSLcl. This is considered illegal.
  5927. // It is only valid for the duration of the call.
  5928. pair< TSurfDB::iterator, bool> Ret= m_SurfDB.insert(
  5929. TSurfDB::value_type( DDSLcl.lpSurfMore()->dwSurfaceHandle(),
  5930. TSurfDBEntry( DDSLcl)));
  5931. // If not added, update data.
  5932. if( !Ret.second) Ret.first->second= DDSLcl;
  5933. }
  5934. void ProcessFullSurface( PORTABLE_DDRAWSURFACE_LCL& DDSLcl)
  5935. {
  5936. // DO NOT STORE &DDSLcl. This is considered illegal.
  5937. // It is only valid for the duration of the call.
  5938. TSuper* pSThis= static_cast<TSuper*>(this);
  5939. typedef TFS TFoundSet;
  5940. TFoundSet FoundSet;
  5941. typename TFoundSet::size_type OldSetSize( FoundSet.size());
  5942. // First traverse all over the attach lists looking for new surfaces.
  5943. PORTABLE_ATTACHLIST* pAl, *pNextAl;
  5944. FoundSet.insert( &DDSLcl);
  5945. typename TFoundSet::size_type NewSetSize( FoundSet.size());
  5946. while( OldSetSize!= NewSetSize)
  5947. {
  5948. OldSetSize= NewSetSize;
  5949. typename TFoundSet::iterator itSurf( FoundSet.begin());
  5950. while( itSurf!= FoundSet.end())
  5951. {
  5952. if((pAl= (*itSurf)->lpAttachList())!= NULL)
  5953. {
  5954. pNextAl= pAl;
  5955. do
  5956. {
  5957. if( pNextAl->lpAttached!= NULL)
  5958. FoundSet.insert( pNextAl->lpAttached);
  5959. pNextAl= pNextAl->lpLink;
  5960. } while( pNextAl!= pAl && pNextAl!= NULL);
  5961. }
  5962. if((pAl= (*itSurf)->lpAttachListFrom())!= NULL)
  5963. {
  5964. pNextAl= pAl;
  5965. do
  5966. {
  5967. if( pNextAl->lpAttached!= NULL)
  5968. FoundSet.insert( pNextAl->lpAttached);
  5969. pNextAl= pNextAl->lpLink;
  5970. } while( pNextAl!= pAl && pNextAl!= NULL);
  5971. }
  5972. itSurf++;
  5973. }
  5974. NewSetSize= FoundSet.size();
  5975. }
  5976. // After all surfaces have been found, add them to the DB.
  5977. typename TFoundSet::iterator itSurf( FoundSet.begin());
  5978. while( itSurf!= FoundSet.end())
  5979. {
  5980. if( !pSThis->PreProcessIndividualSurface( *(*itSurf)))
  5981. ProcessIndividualSurface( *(*itSurf));
  5982. itSurf++;
  5983. }
  5984. }
  5985. // Notification that a system or video memory surface was created. At the
  5986. // least, we have to keep track of the surface handles.
  5987. void SurfaceCreated( PORTABLE_DDRAWSURFACE_LCL& DDSLcl)
  5988. {
  5989. // DO NOT STORE &DDSLcl. This is considered illegal.
  5990. // It is only valid for the duration of the call.
  5991. TSuper* pSThis= static_cast<TSuper*>(this);
  5992. // If true is returned, then a super structure was recognized and
  5993. // processed. Otherwise, false indicates no recognition, and all
  5994. // surfaces will be scoured.
  5995. if( !pSThis->PreProcessFullSurface( DDSLcl))
  5996. pSThis->ProcessFullSurface( DDSLcl);
  5997. }
  5998. bool SurfaceDestroyed( PORTABLE_DDRAWSURFACE_LCL& DDSLcl)
  5999. {
  6000. // DO NOT STORE &DDSLcl. This is considered illegal.
  6001. // It is only valid for the duration of the call.
  6002. // No need to assert removal, as we might not be tracking this type
  6003. // of surface. Someone could override and filter out surfaces.
  6004. m_SurfDB.erase( DDSLcl.lpSurfMore()->dwSurfaceHandle());
  6005. // Return true to tell driver to delete this object. So,
  6006. // if DB is empty, odds are good to delete this.
  6007. return m_SurfDB.empty();
  6008. }
  6009. };
  6010. template< class TD>
  6011. class CMinimalPerDDrawData:
  6012. public CSubPerDDrawData< CMinimalPerDDrawData< TD>, TD>
  6013. {
  6014. public:
  6015. CMinimalPerDDrawData( TDriver& Driver, DDRAWI_DIRECTDRAW_LCL& DDLcl)
  6016. :CSubPerDDrawData< CMinimalPerDDrawData< TD>, TD>( Driver, DDLcl)
  6017. { }
  6018. ~CMinimalPerDDrawData() { }
  6019. };
  6020. ////////////////////////////////////////////////////////////////////////////////
  6021. //
  6022. // CSubDriver
  6023. //
  6024. ////////////////////////////////////////////////////////////////////////////////
  6025. template< class T>
  6026. struct SFakeEntryPointHook
  6027. {
  6028. SFakeEntryPointHook( T& t, const char* szEntryPoint) { }
  6029. ~SFakeEntryPointHook() { }
  6030. };
  6031. template< class TD, class TC, class TSA= CIVidMemAllocator<>,
  6032. class TPDDD= CMinimalPerDDrawData< TD>,
  6033. class TCs= set< TC*>,
  6034. class TPDDDs= map< LPDDRAWI_DIRECTDRAW_LCL, TPDDD>,
  6035. class TSs= set< TSA::TSurface*>,
  6036. class TEntryPointHook= SFakeEntryPointHook< TD> >
  6037. class CSubDriver
  6038. {
  6039. public: // Types
  6040. typedef TD TDriver;
  6041. typedef TC TContext;
  6042. typedef TCs TContexts;
  6043. typedef TPDDD TPerDDrawData;
  6044. typedef TPDDDs TPerDDrawDatas;
  6045. typedef TSA TSurfAlloc;
  6046. typedef typename TSurfAlloc::TSurface TSurface;
  6047. typedef TSs TSurfaces;
  6048. class CSurfaceCapWrap
  6049. {
  6050. protected:
  6051. DDSURFACEDESC m_SDesc;
  6052. public:
  6053. CSurfaceCapWrap() { }
  6054. CSurfaceCapWrap( const D3DFORMAT D3DFmt, const DWORD dwSupportedOps,
  6055. const DWORD dwPrivateFmtBitCount= 0,
  6056. const WORD wFlipMSTypes= 0, const WORD wBltMSTypes= 0)
  6057. {
  6058. ZeroMemory( &m_SDesc, sizeof( m_SDesc));
  6059. m_SDesc.dwSize= sizeof( m_SDesc);
  6060. m_SDesc.ddpfPixelFormat.dwFlags= DDPF_D3DFORMAT;
  6061. m_SDesc.ddpfPixelFormat.dwFourCC= static_cast<DWORD>(D3DFmt);
  6062. m_SDesc.ddpfPixelFormat.dwOperations= dwSupportedOps;
  6063. m_SDesc.ddpfPixelFormat.dwPrivateFormatBitCount= dwPrivateFmtBitCount;
  6064. m_SDesc.ddpfPixelFormat.MultiSampleCaps.wFlipMSTypes= wFlipMSTypes;
  6065. m_SDesc.ddpfPixelFormat.MultiSampleCaps.wBltMSTypes= wBltMSTypes;
  6066. }
  6067. CSurfaceCapWrap( const D3DFORMAT D3DFmt, const bool bTexture,
  6068. const bool bVolTexture, const bool bCubeTexture,
  6069. const bool bOffScreenTarget, const bool bSameFmtTarget,
  6070. const bool bZStencil, const bool bZStencilWithColor,
  6071. const bool bSameFmtUpToAlpha, const bool b3DAccel,
  6072. const DWORD dwPrivateFmtBitCount= 0,
  6073. const WORD wFlipMSTypes= 0, const WORD wBltMSTypes= 0)
  6074. {
  6075. ZeroMemory( &m_SDesc, sizeof( m_SDesc));
  6076. m_SDesc.dwSize= sizeof( m_SDesc);
  6077. DWORD dwOps( 0);
  6078. if( bTexture) dwOps|= D3DFORMAT_OP_TEXTURE;
  6079. if( bVolTexture) dwOps|= D3DFORMAT_OP_VOLUMETEXTURE;
  6080. if( bCubeTexture) dwOps|= D3DFORMAT_OP_CUBETEXTURE;
  6081. if( bOffScreenTarget) dwOps|= D3DFORMAT_OP_OFFSCREEN_RENDERTARGET;
  6082. if( bSameFmtTarget) dwOps|= D3DFORMAT_OP_SAME_FORMAT_RENDERTARGET;
  6083. if( bZStencil) dwOps|= D3DFORMAT_OP_ZSTENCIL;
  6084. if( bZStencilWithColor) dwOps|= D3DFORMAT_OP_ZSTENCIL_WITH_ARBITRARY_COLOR_DEPTH;
  6085. if( bSameFmtUpToAlpha) dwOps|= D3DFORMAT_OP_SAME_FORMAT_UP_TO_ALPHA_RENDERTARGET;
  6086. if( b3DAccel) dwOps|= D3DFORMAT_OP_3DACCELERATION;
  6087. m_SDesc.ddpfPixelFormat.dwFlags= DDPF_D3DFORMAT;
  6088. m_SDesc.ddpfPixelFormat.dwFourCC= static_cast<DWORD>(D3DFmt);
  6089. m_SDesc.ddpfPixelFormat.dwOperations= dwOps;
  6090. m_SDesc.ddpfPixelFormat.dwPrivateFormatBitCount= dwPrivateFmtBitCount;
  6091. m_SDesc.ddpfPixelFormat.MultiSampleCaps.wFlipMSTypes= wFlipMSTypes;
  6092. m_SDesc.ddpfPixelFormat.MultiSampleCaps.wBltMSTypes= wBltMSTypes;
  6093. }
  6094. ~CSurfaceCapWrap() { }
  6095. operator DDSURFACEDESC() const
  6096. { return m_SDesc; }
  6097. };
  6098. private:
  6099. // Stubs for secondary entry points.
  6100. DWORD static APIENTRY ContextCreateStub( LPD3DHAL_CONTEXTCREATEDATA pccd)
  6101. {
  6102. return sm_pGlobalDriver->ContextCreate(
  6103. *reinterpret_cast< PORTABLE_CONTEXTCREATEDATA*>( pccd));
  6104. }
  6105. DWORD static APIENTRY ContextDestroyStub( LPD3DHAL_CONTEXTDESTROYDATA pcdd)
  6106. { return sm_pGlobalDriver->ContextDestroy( *pcdd); }
  6107. DWORD static APIENTRY ContextDestroyAllStub( LPD3DHAL_CONTEXTDESTROYALLDATA pcdad)
  6108. { return sm_pGlobalDriver->ContextDestroyAll( *pcdad); }
  6109. DWORD static APIENTRY SceneCaptureStub( LPD3DHAL_SCENECAPTUREDATA pscd)
  6110. { return sm_pGlobalDriver->SceneCapture( *pscd); }
  6111. DWORD static APIENTRY RenderStateStub( LPD3DHAL_RENDERSTATEDATA prsd)
  6112. { return sm_pGlobalDriver->RenderState( *prsd); }
  6113. DWORD static APIENTRY RenderPrimitiveStub( LPD3DHAL_RENDERPRIMITIVEDATA prpd)
  6114. { return sm_pGlobalDriver->RenderPrimitive( *prpd); }
  6115. DWORD static APIENTRY TextureCreateStub( LPD3DHAL_TEXTURECREATEDATA ptcd)
  6116. { return sm_pGlobalDriver->TextureCreate( *ptcd); }
  6117. DWORD static APIENTRY TextureDestroyStub( LPD3DHAL_TEXTUREDESTROYDATA ptdd)
  6118. { return sm_pGlobalDriver->TextureDestroy( *ptdd); }
  6119. DWORD static APIENTRY TextureSwapStub( LPD3DHAL_TEXTURESWAPDATA ptsd)
  6120. { return sm_pGlobalDriver->TextureSwap( *ptsd); }
  6121. DWORD static APIENTRY TextureGetSurfStub( LPD3DHAL_TEXTUREGETSURFDATA ptgsd)
  6122. { return sm_pGlobalDriver->TextureGetSurf( *ptgsd); }
  6123. DWORD static APIENTRY GetStateStub( LPD3DHAL_GETSTATEDATA pgsd)
  6124. { return sm_pGlobalDriver->GetState( *pgsd); }
  6125. DWORD static APIENTRY SetRenderTargetStub( LPD3DHAL_SETRENDERTARGETDATA psrtd)
  6126. {
  6127. return sm_pGlobalDriver->SetRenderTarget(
  6128. *reinterpret_cast< PORTABLE_SETRENDERTARGETDATA*>( psrtd));
  6129. }
  6130. DWORD static APIENTRY ClearStub( LPD3DHAL_CLEARDATA pcd)
  6131. { return sm_pGlobalDriver->Clear( *pcd); }
  6132. DWORD static APIENTRY DrawOnePrimitiveStub( LPD3DHAL_DRAWONEPRIMITIVEDATA pdopd)
  6133. { return sm_pGlobalDriver->DrawOnePrimitive( *pdopd); }
  6134. DWORD static APIENTRY DrawOneIndexedPrimitiveStub( LPD3DHAL_DRAWONEINDEXEDPRIMITIVEDATA pdoipd)
  6135. { return sm_pGlobalDriver->DrawOneIndexedPrimitive( *pdoipd); }
  6136. DWORD static APIENTRY DrawPrimitivesStub( LPD3DHAL_DRAWPRIMITIVESDATA pdpd)
  6137. { return sm_pGlobalDriver->DrawPrimitives( *pdpd); }
  6138. DWORD static APIENTRY Clear2Stub( LPD3DHAL_CLEAR2DATA pc2d)
  6139. { return sm_pGlobalDriver->Clear2( *pc2d); }
  6140. DWORD static APIENTRY ValidateTextureStageStateStub( LPD3DHAL_VALIDATETEXTURESTAGESTATEDATA pvtssd)
  6141. { return sm_pGlobalDriver->ValidateTextureStageState( *pvtssd); }
  6142. DWORD static APIENTRY DrawPrimitives2Stub( LPD3DHAL_DRAWPRIMITIVES2DATA pdpd)
  6143. {
  6144. return sm_pGlobalDriver->DrawPrimitives2(
  6145. *reinterpret_cast< PORTABLE_DRAWPRIMITIVES2DATA*>( pdpd));
  6146. }
  6147. DWORD static APIENTRY GetDriverStateStub( LPDDHAL_GETDRIVERSTATEDATA pgdsd)
  6148. { return sm_pGlobalDriver->GetDriverState( *pgdsd); }
  6149. DWORD static APIENTRY CreateSurfaceExStub( LPDDHAL_CREATESURFACEEXDATA pcsxd)
  6150. {
  6151. return sm_pGlobalDriver->CreateSurfaceEx(
  6152. *reinterpret_cast< PORTABLE_CREATESURFACEEXDATA*>( pcsxd));
  6153. }
  6154. DWORD static APIENTRY CreateSurfaceStub( LPDDHAL_CREATESURFACEDATA pcsd)
  6155. {
  6156. return sm_pGlobalDriver->CreateSurface(
  6157. *reinterpret_cast< PORTABLE_CREATESURFACEDATA*>( pcsd));
  6158. }
  6159. DWORD static APIENTRY DestroySurfaceStub( LPDDHAL_DESTROYSURFACEDATA pdsd)
  6160. {
  6161. return sm_pGlobalDriver->DestroySurface(
  6162. *reinterpret_cast< PORTABLE_DESTROYSURFACEDATA*>( pdsd));
  6163. }
  6164. DWORD static APIENTRY LockStub( LPDDHAL_LOCKDATA pld)
  6165. {
  6166. return sm_pGlobalDriver->Lock(
  6167. *reinterpret_cast< PORTABLE_LOCKDATA*>( pld));
  6168. }
  6169. DWORD static APIENTRY UnlockStub( LPDDHAL_UNLOCKDATA pud)
  6170. {
  6171. return sm_pGlobalDriver->Unlock(
  6172. *reinterpret_cast< PORTABLE_UNLOCKDATA*>( pud));
  6173. }
  6174. protected:
  6175. TSurfAlloc m_SurfAlloc;
  6176. TContexts m_Contexts;
  6177. TPerDDrawDatas m_PerDDrawDatas;
  6178. TSurfaces m_Surfaces;
  6179. typedef vector< DDSURFACEDESC> TSupportedSurfaces;
  6180. TSupportedSurfaces m_SupportedSurfaces;
  6181. template< class TIter> // DDSURFACEDESC*
  6182. CSubDriver( TIter itStart, const TIter itEnd, TSurfAlloc SA= TSurfAlloc()):
  6183. m_SurfAlloc( SA)
  6184. {
  6185. // Copy supported surfaces formats into a guarenteed contiguous storage
  6186. // for passing to D3D.
  6187. while( itStart!= itEnd)
  6188. m_SupportedSurfaces.push_back( *itStart++);
  6189. }
  6190. ~CSubDriver() { }
  6191. // Binds a VidMem DDRAWI object together with an internal driver surface object.
  6192. void static AssociateSurface( PORTABLE_DDRAWSURFACE_LCL& DDSurf,
  6193. TSurface* pSurf)
  6194. {
  6195. assert((DDSurf.ddsCaps().dwCaps& DDSCAPS_VIDEOMEMORY)!= 0);
  6196. DDSurf.lpGbl()->dwReserved1= reinterpret_cast< ULONG_PTR>(pSurf);
  6197. }
  6198. public:
  6199. // The global driver static member pointer. Only one Driver object, and
  6200. // this points to it.
  6201. static TDriver* sm_pGlobalDriver;
  6202. TSurface* GetSurface( PORTABLE_DDRAWSURFACE_LCL& DDSurf,
  6203. bool bCheck= true) const
  6204. {
  6205. TSurface* pSurface= reinterpret_cast< TSurface*>(
  6206. DDSurf.lpGbl()->dwReserved1);
  6207. assert( bCheck&& m_Surfaces.find( pSurface)!= m_Surfaces.end());
  6208. return pSurface;
  6209. }
  6210. TSurface* GetSurface( const typename TPerDDrawData::TSurfDBEntry& DBEntry,
  6211. bool bCheck= true) const
  6212. {
  6213. TSurface* pSurface= reinterpret_cast< TSurface*>(
  6214. DBEntry.GetGBLdwReserved1());
  6215. assert( bCheck&& m_Surfaces.find( pSurface)!= m_Surfaces.end());
  6216. return pSurface;
  6217. }
  6218. // Secondary entry points with C++ friendly parameters.
  6219. DWORD ContextCreate( PORTABLE_CONTEXTCREATEDATA& ccd) throw()
  6220. {
  6221. try
  6222. {
  6223. TEntryPointHook EntryPointHook( *sm_pGlobalDriver, "ContextCreate");
  6224. ccd.ddrval()= DD_OK;
  6225. TDriver* pSThis= static_cast<TDriver*>(this);
  6226. // We should already have a PerDDrawData at this point, as the
  6227. // surfaces to initialize the context had to be created already,
  6228. // and the PerDDrawData should've been created there.
  6229. typename TPerDDrawDatas::iterator itPerDDrawData(
  6230. m_PerDDrawDatas.find( ccd.lpDDLcl()));
  6231. assert( itPerDDrawData!= m_PerDDrawDatas.end());
  6232. // Create the new context, passing in a ref to the PerDDrawData object.
  6233. auto_ptr< TContext> pNewContext( new TContext(
  6234. itPerDDrawData->second, ccd));
  6235. // Keep track of our new context.
  6236. pair< TContexts::iterator, bool> RetVal( m_Contexts.insert(
  6237. pNewContext.get()));
  6238. assert( RetVal.second); // Assure that there wasn't a duplicate.
  6239. // Ownership now has been transfered to m_Contexts & D3D.
  6240. ccd.dwhContext()= reinterpret_cast<ULONG_PTR>( pNewContext.release());
  6241. } catch( bad_alloc e) {
  6242. ccd.ddrval()= D3DHAL_OUTOFCONTEXTS;
  6243. } catch( HRESULT hr) {
  6244. ccd.ddrval()= hr;
  6245. #if !defined( DX8SDDIFW_NOCATCHALL)
  6246. } catch( ... ) {
  6247. const bool ContextCreate_Unrecognized_Exception( false);
  6248. assert( ContextCreate_Unrecognized_Exception);
  6249. ccd.ddrval()= E_UNEXPECTED;
  6250. #endif // !defined( DX8SDDIFW_NOCATCHALL)
  6251. }
  6252. return DDHAL_DRIVER_HANDLED;
  6253. }
  6254. DWORD ContextDestroy( D3DHAL_CONTEXTDESTROYDATA& cdd) throw()
  6255. {
  6256. try
  6257. {
  6258. TEntryPointHook EntryPointHook( *sm_pGlobalDriver, "ContextDestroy");
  6259. cdd.ddrval= DD_OK;
  6260. // Ownership now has been transfered to local auto_ptr.
  6261. auto_ptr< TContext> pContext(
  6262. reinterpret_cast<TContext*>(cdd.dwhContext));
  6263. // Remove tracking of this context.
  6264. typename TContexts::size_type Ret( m_Contexts.erase( pContext.get()));
  6265. assert( Ret!= 0);
  6266. } catch( HRESULT hr) {
  6267. cdd.ddrval= hr;
  6268. #if !defined( DX8SDDIFW_NOCATCHALL)
  6269. } catch( ... ) {
  6270. const bool ContextDestroy_Unrecognized_Exception( false);
  6271. assert( ContextDestroy_Unrecognized_Exception);
  6272. cdd.ddrval= E_UNEXPECTED;
  6273. #endif // !defined( DX8SDDIFW_NOCATCHALL)
  6274. }
  6275. return DDHAL_DRIVER_HANDLED;
  6276. }
  6277. DWORD ContextDestroyAll( D3DHAL_CONTEXTDESTROYALLDATA& cdad) const throw()
  6278. {
  6279. TEntryPointHook EntryPointHook( *sm_pGlobalDriver, "ContextDestroyAll");
  6280. const bool ContextDestroyAll_thought_to_be_depreciated_entry_point( false);
  6281. assert( ContextDestroyAll_thought_to_be_depreciated_entry_point);
  6282. return DDHAL_DRIVER_NOTHANDLED;
  6283. }
  6284. DWORD SceneCapture( D3DHAL_SCENECAPTUREDATA& scd) const throw()
  6285. {
  6286. TEntryPointHook EntryPointHook( *sm_pGlobalDriver, "SceneCapture");
  6287. const bool SceneCapture_thought_to_be_depreciated_entry_point( false);
  6288. assert( SceneCapture_thought_to_be_depreciated_entry_point);
  6289. return DDHAL_DRIVER_NOTHANDLED;
  6290. }
  6291. DWORD RenderState( D3DHAL_RENDERSTATEDATA& rsd) const throw()
  6292. {
  6293. TEntryPointHook EntryPointHook( *sm_pGlobalDriver, "RenderState");
  6294. const bool RenderState_thought_to_be_depreciated_entry_point( false);
  6295. assert( RenderState_thought_to_be_depreciated_entry_point);
  6296. return DDHAL_DRIVER_NOTHANDLED;
  6297. }
  6298. DWORD RenderPrimitive( D3DHAL_RENDERPRIMITIVEDATA& rpd) const throw()
  6299. {
  6300. TEntryPointHook EntryPointHook( *sm_pGlobalDriver, "RenderPrimitive");
  6301. const bool RenderPrimitive_thought_to_be_depreciated_entry_point( false);
  6302. assert( RenderPrimitive_thought_to_be_depreciated_entry_point);
  6303. return DDHAL_DRIVER_NOTHANDLED;
  6304. }
  6305. DWORD TextureCreate( D3DHAL_TEXTURECREATEDATA& tcd) const throw()
  6306. {
  6307. TEntryPointHook EntryPointHook( *sm_pGlobalDriver, "TextureCreate");
  6308. const bool TextureCreate_thought_to_be_depreciated_entry_point( false);
  6309. assert( TextureCreate_thought_to_be_depreciated_entry_point);
  6310. return DDHAL_DRIVER_NOTHANDLED;
  6311. }
  6312. DWORD TextureDestroy( D3DHAL_TEXTUREDESTROYDATA& tdd) const throw()
  6313. {
  6314. TEntryPointHook EntryPointHook( *sm_pGlobalDriver, "TextureDestroy");
  6315. const bool TextureDestroy_thought_to_be_depreciated_entry_point( false);
  6316. assert( TextureDestroy_thought_to_be_depreciated_entry_point);
  6317. return DDHAL_DRIVER_NOTHANDLED;
  6318. }
  6319. DWORD TextureSwap( D3DHAL_TEXTURESWAPDATA& tsd) const throw()
  6320. {
  6321. TEntryPointHook EntryPointHook( *sm_pGlobalDriver, "TextureSwap");
  6322. const bool TextureSwap_thought_to_be_depreciated_entry_point( false);
  6323. assert( TextureSwap_thought_to_be_depreciated_entry_point);
  6324. return DDHAL_DRIVER_NOTHANDLED;
  6325. }
  6326. DWORD TextureGetSurf( D3DHAL_TEXTUREGETSURFDATA& tgsd) const throw()
  6327. {
  6328. TEntryPointHook EntryPointHook( *sm_pGlobalDriver, "TextureGetSurf");
  6329. const bool TextureGetSurf_thought_to_be_depreciated_entry_point( false);
  6330. assert( TextureGetSurf_thought_to_be_depreciated_entry_point);
  6331. return DDHAL_DRIVER_NOTHANDLED;
  6332. }
  6333. DWORD GetState( D3DHAL_GETSTATEDATA& gsd) const throw()
  6334. {
  6335. TEntryPointHook EntryPointHook( *sm_pGlobalDriver, "GetState");
  6336. const bool GetState_thought_to_be_depreciated_entry_point( false);
  6337. assert( GetState_thought_to_be_depreciated_entry_point);
  6338. return DDHAL_DRIVER_NOTHANDLED;
  6339. }
  6340. DWORD SetRenderTarget( PORTABLE_SETRENDERTARGETDATA& srtd) const throw()
  6341. {
  6342. TEntryPointHook EntryPointHook( *sm_pGlobalDriver, "SetRenderTarget");
  6343. const bool SetRenderTarget_thought_to_be_depreciated_entry_point( false);
  6344. assert( SetRenderTarget_thought_to_be_depreciated_entry_point);
  6345. return DDHAL_DRIVER_NOTHANDLED;
  6346. }
  6347. DWORD Clear( D3DHAL_CLEARDATA& cd) const throw()
  6348. {
  6349. TEntryPointHook EntryPointHook( *sm_pGlobalDriver, "Clear");
  6350. const bool Clear_thought_to_be_depreciated_entry_point( false);
  6351. assert( Clear_thought_to_be_depreciated_entry_point);
  6352. return DDHAL_DRIVER_NOTHANDLED;
  6353. }
  6354. DWORD DrawOnePrimitive( D3DHAL_DRAWONEPRIMITIVEDATA& dopd) const throw()
  6355. {
  6356. TEntryPointHook EntryPointHook( *sm_pGlobalDriver, "DrawOnePrimitive");
  6357. const bool DrawOnePrimitive_thought_to_be_depreciated_entry_point( false);
  6358. assert( DrawOnePrimitive_thought_to_be_depreciated_entry_point);
  6359. return DDHAL_DRIVER_NOTHANDLED;
  6360. }
  6361. DWORD DrawOneIndexedPrimitive( D3DHAL_DRAWONEINDEXEDPRIMITIVEDATA& doipd) const throw()
  6362. {
  6363. TEntryPointHook EntryPointHook( *sm_pGlobalDriver, "DrawOneIndexedPrimitive");
  6364. const bool DrawOneIndexedPrimitive_thought_to_be_depreciated_entry_point( false);
  6365. assert( DrawOneIndexedPrimitive_thought_to_be_depreciated_entry_point);
  6366. return DDHAL_DRIVER_NOTHANDLED;
  6367. }
  6368. DWORD DrawPrimitives( D3DHAL_DRAWPRIMITIVESDATA& dpd) const throw()
  6369. {
  6370. TEntryPointHook EntryPointHook( *sm_pGlobalDriver, "DrawPrimitives");
  6371. const bool DrawPrimitives_thought_to_be_depreciated_entry_point( false);
  6372. assert( DrawPrimitives_thought_to_be_depreciated_entry_point);
  6373. return DDHAL_DRIVER_NOTHANDLED;
  6374. }
  6375. DWORD Clear2( D3DHAL_CLEAR2DATA& c2d) const throw()
  6376. {
  6377. TEntryPointHook EntryPointHook( *sm_pGlobalDriver, "Clear2");
  6378. const bool Clear2_thought_to_be_depreciated_entry_point( false);
  6379. assert( Clear2_thought_to_be_depreciated_entry_point);
  6380. return DDHAL_DRIVER_NOTHANDLED;
  6381. }
  6382. DWORD ValidateTextureStageState( D3DHAL_VALIDATETEXTURESTAGESTATEDATA& vtssd) const throw()
  6383. {
  6384. try
  6385. {
  6386. TEntryPointHook EntryPointHook( *sm_pGlobalDriver, "ValidateTextureStageState");
  6387. vtssd.ddrval= DD_OK;
  6388. TContext* pContext= reinterpret_cast<TContext*>(vtssd.dwhContext);
  6389. // Make sure we've created this context.
  6390. assert( m_Contexts.find( pContext)!= m_Contexts.end());
  6391. // Pass entry point to context.
  6392. vtssd.ddrval= pContext->ValidateTextureStageState( vtssd);
  6393. } catch( HRESULT hr) {
  6394. vtssd.ddrval= hr;
  6395. #if !defined( DX8SDDIFW_NOCATCHALL)
  6396. } catch( ... ) {
  6397. const bool ValidateTextureStageState_Unrecognized_Exception( false);
  6398. assert( ValidateTextureStageState_Unrecognized_Exception);
  6399. vtssd.ddrval= E_UNEXPECTED;
  6400. #endif // !defined( DX8SDDIFW_NOCATCHALL)
  6401. }
  6402. return DDHAL_DRIVER_HANDLED;
  6403. }
  6404. DWORD DrawPrimitives2( PORTABLE_DRAWPRIMITIVES2DATA& dpd) const throw()
  6405. {
  6406. try
  6407. {
  6408. TEntryPointHook EntryPointHook( *sm_pGlobalDriver, "DrawPrimitives2");
  6409. dpd.ddrval()= DD_OK;
  6410. TContext* pContext= reinterpret_cast<TContext*>(dpd.dwhContext());
  6411. // Make sure we've created this context.
  6412. assert( m_Contexts.find( pContext)!= m_Contexts.end());
  6413. // Pass entry point to context.
  6414. dpd.ddrval()= pContext->DrawPrimitives2( dpd);
  6415. } catch( HRESULT hr) {
  6416. dpd.ddrval()= hr;
  6417. #if !defined( DX8SDDIFW_NOCATCHALL)
  6418. } catch( ... ) {
  6419. const bool DrawPrimitives2_Unrecognized_Exception( false);
  6420. assert( DrawPrimitives2_Unrecognized_Exception);
  6421. dpd.ddrval()= E_UNEXPECTED;
  6422. #endif // !defined( DX8SDDIFW_NOCATCHALL)
  6423. }
  6424. return DDHAL_DRIVER_HANDLED;
  6425. }
  6426. DWORD GetDriverState( DDHAL_GETDRIVERSTATEDATA& gdsd) const throw()
  6427. {
  6428. // This entry point is hooked up to IDirect3DDevice8::GetInfo(
  6429. // DWORD DevInfoId, VOID* pDevInfoStruct, DWORD DevInfoStructSize).
  6430. // gdsd.dwFlags= DevInfoId
  6431. // gdsd.lpdwStates= pDevInfoStruct
  6432. // gdsd.dwLength= DevInfoStructSize
  6433. //
  6434. // This entry point can be used for driver defined/ extended state
  6435. // passing. Currently no DevInfoIds are pre-defined. S_FALSE should
  6436. // be returned if nothing is done or the Id is not understood.
  6437. try
  6438. {
  6439. TEntryPointHook EntryPointHook( *sm_pGlobalDriver, "GetDriverState");
  6440. gdsd.ddRVal= DD_OK;
  6441. TContext* pContext= reinterpret_cast< TContext*>( gdsd.dwhContext);
  6442. // Make sure we've created this context.
  6443. assert( m_Contexts.find( pContext)!= m_Contexts.end());
  6444. // Pass entry point to context.
  6445. gdsd.ddRVal= pContext->GetDriverState( gdsd);
  6446. } catch( HRESULT hr) {
  6447. gdsd.ddRVal= hr;
  6448. #if !defined( DX8SDDIFW_NOCATCHALL)
  6449. } catch( ... ) {
  6450. const bool GetDriverState_Unrecognized_Exception( false);
  6451. assert( GetDriverState_Unrecognized_Exception);
  6452. gdsd.ddRVal= E_UNEXPECTED;
  6453. #endif // !defined( DX8SDDIFW_NOCATCHALL)
  6454. }
  6455. return DDHAL_DRIVER_HANDLED;
  6456. }
  6457. DWORD CreateSurfaceEx( PORTABLE_CREATESURFACEEXDATA& csxd) throw()
  6458. {
  6459. try
  6460. {
  6461. TEntryPointHook EntryPointHook( *sm_pGlobalDriver, "CreateSurfaceEx");
  6462. TDriver* pSThis= static_cast<TDriver*>(this);
  6463. csxd.ddRVal()= DD_OK;
  6464. // Upon CreateSurfaceEx, we must detect whether this is a creation
  6465. // or destruction notification and pass it to the associated
  6466. // PerDDrawData.
  6467. // Get PerDDrawData for this DDraw object.
  6468. typename TPerDDrawDatas::iterator itPerDDrawData( m_PerDDrawDatas.find(
  6469. csxd.lpDDLcl()));
  6470. if( 0== csxd.lpDDSLcl()->lpGbl()->fpVidMem)
  6471. { // System Memory Surface Destruction,
  6472. // Pass notification to PerDDrawData, if exists. PerDDraw data
  6473. // will return bool indicating whether to delete it or not.
  6474. if( itPerDDrawData!= m_PerDDrawDatas.end() &&
  6475. itPerDDrawData->second.SurfaceDestroyed( *csxd.lpDDSLcl()))
  6476. m_PerDDrawDatas.erase( itPerDDrawData);
  6477. }
  6478. else
  6479. { // Video or System Memory Surface Creation
  6480. // If we don't have PerDDrawData for this DDraw object yet,
  6481. // we must create it.
  6482. if( itPerDDrawData== m_PerDDrawDatas.end())
  6483. {
  6484. // Typically, storing pointers to DDRAWI objects is illegal,
  6485. // but this case has been deemed okay. Otherwise, we
  6486. // couldn't have the concept of "per DDraw" data, as
  6487. // "per DDraw" would be hard to figure out; as nothing
  6488. // guarentees uniqueness between the DDRAWI objects, besides
  6489. // the pointers.
  6490. itPerDDrawData= m_PerDDrawDatas.insert(
  6491. TPerDDrawDatas::value_type( csxd.lpDDLcl(),
  6492. TPerDDrawData( *pSThis, *csxd.lpDDLcl())) ).first;
  6493. }
  6494. // Now pass notification to PerDDrawData.
  6495. // DO NOT STORE csxd.lpDDSLcl. This is considered illegal.
  6496. // It is only valid for the duration of the call.
  6497. itPerDDrawData->second.SurfaceCreated( *csxd.lpDDSLcl());
  6498. }
  6499. } catch( bad_alloc e) {
  6500. csxd.ddRVal()= DDERR_OUTOFMEMORY;
  6501. } catch( HRESULT hr) {
  6502. csxd.ddRVal()= hr;
  6503. #if !defined( DX8SDDIFW_NOCATCHALL)
  6504. } catch( ... ) {
  6505. const bool CreateSurfaceEx_Unrecognized_Exception( false);
  6506. assert( CreateSurfaceEx_Unrecognized_Exception);
  6507. csxd.ddRVal()= E_UNEXPECTED;
  6508. #endif // !defined( DX8SDDIFW_NOCATCHALL)
  6509. }
  6510. return DDHAL_DRIVER_HANDLED;
  6511. }
  6512. DWORD CreateSurface( PORTABLE_CREATESURFACEDATA& csd) throw()
  6513. {
  6514. try
  6515. {
  6516. TEntryPointHook EntryPointHook( *sm_pGlobalDriver, "CreateSurface");
  6517. TDriver* pSThis= static_cast<TDriver*>(this);
  6518. csd.ddRVal()= DD_OK;
  6519. // Upon CreateSurface, we must allocate memory for the "video"
  6520. // memory surface and also associate our internal representation
  6521. // with the surface.
  6522. DWORD dwS( 0);
  6523. try
  6524. {
  6525. // For each surface we're asked to create...
  6526. while( dwS< csd.dwSCnt())
  6527. {
  6528. // Get PerDDrawData for this DDraw object.
  6529. const LPDDRAWI_DIRECTDRAW_LCL pDDLcl(
  6530. csd.lplpSList()[ dwS]->lpSurfMore()->lpDD_lcl());
  6531. typename TPerDDrawDatas::iterator itPerDDrawData(
  6532. m_PerDDrawDatas.find( pDDLcl));
  6533. // If we don't have PerDDrawData for this DDraw object yet,
  6534. // we must create it.
  6535. if( itPerDDrawData== m_PerDDrawDatas.end())
  6536. {
  6537. // Typically, storing pointers to DDRAWI objects is
  6538. // illegal, but this case has been deemed okay.
  6539. // Otherwise, we couldn't have the concept of
  6540. // "per DDraw" data, as "per DDraw" would be hard to
  6541. // figure out; as nothing guarentees uniqueness
  6542. // between the DDRAWI objects, besides the pointers.
  6543. itPerDDrawData= m_PerDDrawDatas.insert(
  6544. TPerDDrawDatas::value_type( pDDLcl,
  6545. TPerDDrawData( *pSThis, *pDDLcl)) ).first;
  6546. }
  6547. // Create the new surface, by using the surface allocator.
  6548. // DO NOT STORE csd.lplpSList[ dwS]. This is considered
  6549. // illegal. It is only valid for the duration of the call.
  6550. auto_ptr< TSurface> pNewSurf(
  6551. m_SurfAlloc.CreateSurf( *csd.lpDDSurfaceDesc(),
  6552. *csd.lplpSList()[ dwS]));
  6553. // Add the pointer to our set of VM surfaces for tracking.
  6554. m_Surfaces.insert( pNewSurf.get());
  6555. // Bind the internal representation to the DDRAWI object.
  6556. AssociateSurface( *csd.lplpSList()[ dwS], pNewSurf.get());
  6557. pNewSurf.release();
  6558. dwS++;
  6559. }
  6560. } catch( ... ) {
  6561. // dwS will point to failed alloc, then deallocate the
  6562. // succeeded allocations.
  6563. // Bind NULL to the DDRAWI object and blank out fpVidMem, just
  6564. // in case.
  6565. AssociateSurface( *csd.lplpSList()[ dwS], NULL);
  6566. csd.lplpSList()[ dwS]->lpGbl()->fpVidMem= NULL;
  6567. if( dwS!= 0) do
  6568. {
  6569. --dwS;
  6570. TSurface* pSurface= GetSurface( *csd.lplpSList()[ dwS]);
  6571. m_Surfaces.erase( pSurface);
  6572. delete pSurface;
  6573. // Bind NULL to the DDRAWI object and blank out fpVidMem,
  6574. // to avoid DDraw in thinking the surface was allocated.
  6575. AssociateSurface( *csd.lplpSList()[ dwS], NULL);
  6576. csd.lplpSList()[ dwS]->lpGbl()->fpVidMem= NULL;
  6577. } while( dwS!= 0);
  6578. throw; // Re-throw the exception.
  6579. }
  6580. // We wait till CreateSurfaceEx to make the handle association.
  6581. } catch( bad_alloc e) {
  6582. csd.ddRVal()= DDERR_OUTOFMEMORY;
  6583. } catch( HRESULT hr) {
  6584. csd.ddRVal()= hr;
  6585. #if !defined( DX8SDDIFW_NOCATCHALL)
  6586. } catch( ... ) {
  6587. const bool CreateSurface_Unrecognized_Exception( false);
  6588. assert( CreateSurface_Unrecognized_Exception);
  6589. csd.ddRVal()= E_UNEXPECTED;
  6590. #endif // !defined( DX8SDDIFW_NOCATCHALL)
  6591. }
  6592. return DDHAL_DRIVER_HANDLED;
  6593. }
  6594. DWORD DestroySurface( PORTABLE_DESTROYSURFACEDATA& dsd) throw()
  6595. {
  6596. try
  6597. {
  6598. TEntryPointHook EntryPointHook( *sm_pGlobalDriver, "DestroySurface");
  6599. dsd.ddRVal()= DD_OK;
  6600. // Retrieve
  6601. TSurface* pSurface= GetSurface( *dsd.lpDDSurface());
  6602. // Surface object must be destroyed before the DB entry. This is
  6603. // a requirement so that a link (pointer) can safely be
  6604. // established between the DB entry and the object.
  6605. m_Surfaces.erase( pSurface);
  6606. delete pSurface;
  6607. // Pass destruction notice to PerDDrawData. If it returns true,
  6608. // then PerDDrawData indicates that it should be destroyed.
  6609. typename TPerDDrawDatas::iterator itPerDDrawData( m_PerDDrawDatas.find(
  6610. dsd.lpDDSurface()->lpSurfMore()->lpDD_lcl()));
  6611. if( itPerDDrawData!= m_PerDDrawDatas.end() &&
  6612. itPerDDrawData->second.SurfaceDestroyed( *dsd.lpDDSurface()))
  6613. m_PerDDrawDatas.erase( itPerDDrawData);
  6614. } catch( HRESULT hr) {
  6615. dsd.ddRVal()= hr;
  6616. #if !defined( DX8SDDIFW_NOCATCHALL)
  6617. } catch( ... ) {
  6618. const bool DestroySurface_Unrecognized_Exception( false);
  6619. assert( DestroySurface_Unrecognized_Exception);
  6620. dsd.ddRVal()= E_UNEXPECTED;
  6621. #endif // !defined( DX8SDDIFW_NOCATCHALL)
  6622. }
  6623. return DDHAL_DRIVER_HANDLED;
  6624. }
  6625. DWORD Lock( PORTABLE_LOCKDATA& ld) const throw()
  6626. {
  6627. // Typically, an application requesting a "Lock" of a multisampled
  6628. // surface is not allowed. It would require a MSLock or a new version
  6629. // of Lock to get access to the multisampled bits. However, these
  6630. // surfaces still need to be able to "Present" the bits or "Blt" the
  6631. // bits to the Primary, typically. This requires a workaround:
  6632. // The runtime WILL lock the surface (not for the app), expecting the
  6633. // rasterizer to subsample the multisampled bits into an equivalent
  6634. // non-multisampled area and return this smaller area out of Lock,
  6635. // so that the runtime can "Present" the bits, or whatever.
  6636. try
  6637. {
  6638. TEntryPointHook EntryPointHook( *sm_pGlobalDriver, "Lock");
  6639. ld.ddRVal()= DD_OK;
  6640. // First, retrieve surface object bound to this structure.
  6641. TSurface* pSurface= GetSurface( *ld.lpDDSurface());
  6642. // Pass control to object's Lock function.
  6643. ld.lpSurfData()= pSurface->Lock( ld.dwFlags(), (ld.bHasRect()?
  6644. &ld.rArea(): NULL));
  6645. } catch( HRESULT hr) {
  6646. ld.ddRVal()= hr;
  6647. #if !defined( DX8SDDIFW_NOCATCHALL)
  6648. } catch( ... ) {
  6649. const bool Lock_Unrecognized_Exception( false);
  6650. assert( Lock_Unrecognized_Exception);
  6651. ld.ddRVal()= E_UNEXPECTED;
  6652. #endif // !defined( DX8SDDIFW_NOCATCHALL)
  6653. }
  6654. return DDHAL_DRIVER_HANDLED;
  6655. }
  6656. DWORD Unlock( PORTABLE_UNLOCKDATA& ud) const throw()
  6657. {
  6658. try
  6659. {
  6660. TEntryPointHook EntryPointHook( *sm_pGlobalDriver, "Unlock");
  6661. ud.ddRVal()= DD_OK;
  6662. // First, retrieve surface object bound to this structure.
  6663. TSurface* pSurface= GetSurface( *ud.lpDDSurface());
  6664. // Pass control to object's Unlock function.
  6665. pSurface->Unlock();
  6666. } catch( HRESULT hr) {
  6667. ud.ddRVal()= hr;
  6668. #if !defined( DX8SDDIFW_NOCATCHALL)
  6669. } catch( ... ) {
  6670. const bool Unlock_Unrecognized_Exception( false);
  6671. assert( Unlock_Unrecognized_Exception);
  6672. ud.ddRVal()= E_UNEXPECTED;
  6673. #endif // !defined( DX8SDDIFW_NOCATCHALL)
  6674. }
  6675. return DDHAL_DRIVER_HANDLED;
  6676. }
  6677. // Main entry point of driver.
  6678. // Should be called by a bridge function, only.
  6679. HRESULT GetSWInfo( D3DCAPS8& Caps8, D3D8_SWCALLBACKS& Callbacks,
  6680. DWORD& dwNumTextures, DDSURFACEDESC*& pTexList) throw()
  6681. {
  6682. // This static member variable should be initialized to be NULL or
  6683. // point it to the global class.
  6684. assert( NULL== sm_pGlobalDriver|| \
  6685. static_cast< TDriver*>( this)== sm_pGlobalDriver);
  6686. sm_pGlobalDriver= static_cast< TDriver*>( this);
  6687. Callbacks.CreateContext = ContextCreateStub; // Needed.
  6688. Callbacks.ContextDestroy = ContextDestroyStub; // Needed.
  6689. Callbacks.ContextDestroyAll = ContextDestroyAllStub; // Unused in DX8DDI?
  6690. Callbacks.SceneCapture = SceneCaptureStub; // Unused in DX8DDI, now a render state.
  6691. Callbacks.RenderState = RenderStateStub; // Unused in DX8DDI?
  6692. Callbacks.RenderPrimitive = RenderPrimitiveStub; // Unused in DX8DDI?
  6693. Callbacks.TextureCreate = TextureCreateStub; // Unused in DX8DDI?
  6694. Callbacks.TextureDestroy = TextureDestroyStub; // Unused in DX8DDI?
  6695. Callbacks.TextureSwap = TextureSwapStub; // Unused in DX8DDI?
  6696. Callbacks.TextureGetSurf = TextureGetSurfStub; // Unused in DX8DDI?
  6697. Callbacks.GetState = GetStateStub; // Unused in DX8DDI?
  6698. Callbacks.SetRenderTarget = SetRenderTargetStub; // Unused in DX8DDI?
  6699. Callbacks.Clear = ClearStub; // Unused in DX8DDI?
  6700. Callbacks.DrawOnePrimitive = DrawOnePrimitiveStub; // Unused in DX8DDI?
  6701. Callbacks.DrawOneIndexedPrimitive = DrawOneIndexedPrimitiveStub; // Unused in DX8DDI?
  6702. Callbacks.DrawPrimitives = DrawPrimitivesStub; // Unused in DX8DDI?
  6703. Callbacks.Clear2 = Clear2Stub; // Unused in DX8DDI?
  6704. Callbacks.ValidateTextureStageState= ValidateTextureStageStateStub; // Optional?
  6705. Callbacks.DrawPrimitives2 = DrawPrimitives2Stub; // Needed.
  6706. Callbacks.GetDriverState = GetDriverStateStub; // Optional?
  6707. Callbacks.CreateSurfaceEx = CreateSurfaceExStub; // Needed.
  6708. Callbacks.CreateSurface = CreateSurfaceStub; // Needed.
  6709. Callbacks.DestroySurface = DestroySurfaceStub; // Needed.
  6710. Callbacks.Lock = LockStub; // Needed.
  6711. Callbacks.Unlock = UnlockStub; // Needed.
  6712. try {
  6713. Caps8= sm_pGlobalDriver->GetCaps();
  6714. // There needs to be support for some surfaces, at least.
  6715. assert( !m_SupportedSurfaces.empty());
  6716. dwNumTextures= m_SupportedSurfaces.size();
  6717. pTexList= &(*m_SupportedSurfaces.begin());
  6718. } catch( bad_alloc ba) {
  6719. return E_OUTOFMEMORY;
  6720. } catch( HRESULT hr) {
  6721. return hr;
  6722. #if !defined( DX8SDDIFW_NOCATCHALL)
  6723. } catch( ... ) {
  6724. return E_UNEXPECTED;
  6725. #endif // !defined( DX8SDDIFW_NOCATCHALL)
  6726. }
  6727. return S_OK;
  6728. }
  6729. };
  6730. template< class TD, class TR>
  6731. class CMinimalDriver:
  6732. public CSubDriver< TD, CMinimalContext< CMinimalPerDDrawData< TD>, TR> >
  6733. {
  6734. public: // Types
  6735. typedef TR TRasterizer;
  6736. protected:
  6737. template< class TIter> // DDSURFACEDESC*
  6738. CMinimalDriver( TIter itStart, const TIter itEnd) :
  6739. CSubDriver< TD, TContext>( itStart, itEnd)
  6740. { /* TODO: Check caps? */ }
  6741. ~CMinimalDriver()
  6742. { }
  6743. };
  6744. #if !defined( DX8SDDIFW_NONAMESPACE)
  6745. }
  6746. #endif // !defined( DX8SDDIFW_NONAMESPACE)