Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1195 lines
47 KiB

  1. /*==========================================================================;
  2. *
  3. * Copyright (C) 1998 Microsoft Corporation. All Rights Reserved.
  4. *
  5. * File: stateset.cpp
  6. * Content: State sets handling
  7. *
  8. ***************************************************************************/
  9. #include "pch.cpp"
  10. #pragma hdrstop
  11. //=====================================================================
  12. // CStateSets interface
  13. //
  14. //---------------------------------------------------------------------
  15. #undef DPF_MODNAME
  16. #define DPF_MODNAME "CStateSets::CStateSets"
  17. CStateSets::CStateSets(): m_GrowSize(10)
  18. {
  19. m_dwMaxSets = 0;
  20. m_dwCurrentHandle = __INVALIDHANDLE;
  21. m_pStateSets = NULL;
  22. // Init handle factory
  23. m_SetHandles.Init(m_GrowSize, m_GrowSize);
  24. m_SetHandles.CreateNewHandle(); // Reserve handle 0
  25. m_DeviceHandles.Init(m_GrowSize, m_GrowSize);
  26. m_DeviceHandles.CreateNewHandle(); // Reserve handle 0
  27. }
  28. //---------------------------------------------------------------------
  29. #undef DPF_MODNAME
  30. #define DPF_MODNAME "CStateSets::~CStateSets"
  31. CStateSets::~CStateSets()
  32. {
  33. delete [] m_pStateSets;
  34. m_SetHandles.ReleaseHandle(0);
  35. m_DeviceHandles.ReleaseHandle(0);
  36. }
  37. //---------------------------------------------------------------------
  38. #undef DPF_MODNAME
  39. #define DPF_MODNAME "CStateSets::Init"
  40. HRESULT CStateSets::Init(DWORD dwFlags)
  41. {
  42. m_dwFlags = dwFlags;
  43. return D3D_OK;
  44. }
  45. //---------------------------------------------------------------------
  46. #undef DPF_MODNAME
  47. #define DPF_MODNAME "CStateSets::StartNewSet"
  48. HRESULT CStateSets::StartNewSet()
  49. {
  50. m_dwCurrentHandle = m_SetHandles.CreateNewHandle();
  51. if (m_dwCurrentHandle == __INVALIDHANDLE)
  52. return DDERR_OUTOFMEMORY;
  53. if (m_dwCurrentHandle >= m_dwMaxSets)
  54. {
  55. // Time to grow the array
  56. CStateSet *pNew = new CStateSet[m_dwMaxSets + m_GrowSize];
  57. if (pNew == NULL)
  58. {
  59. m_SetHandles.ReleaseHandle(m_dwCurrentHandle);
  60. return DDERR_OUTOFMEMORY;
  61. }
  62. for (DWORD i=0; i < m_dwMaxSets; i++)
  63. pNew[i] = m_pStateSets[i];
  64. delete [] m_pStateSets;
  65. m_pStateSets = pNew;
  66. m_dwMaxSets += m_GrowSize;
  67. }
  68. m_BufferSet.m_FEOnlyBuffer.Reset();
  69. m_BufferSet.m_DriverBuffer.Reset();
  70. m_pCurrentStateSet = &m_BufferSet;
  71. return D3D_OK;
  72. }
  73. //---------------------------------------------------------------------
  74. #undef DPF_MODNAME
  75. #define DPF_MODNAME "CStateSets::EndSet"
  76. void CStateSets::EndSet()
  77. {
  78. m_pStateSets[m_dwCurrentHandle] = *m_pCurrentStateSet;
  79. m_pCurrentStateSet = &m_pStateSets[m_dwCurrentHandle];
  80. m_pCurrentStateSet->m_dwStateSetFlags |= __STATESET_INITIALIZED;
  81. }
  82. //---------------------------------------------------------------------
  83. #undef DPF_MODNAME
  84. #define DPF_MODNAME "CStateSets::DeleteStateSet"
  85. void CStateSets::DeleteStateSet(LPDIRECT3DDEVICEI pDevI, DWORD dwHandle)
  86. {
  87. if (dwHandle >= m_dwMaxSets)
  88. {
  89. D3D_ERR("State block handle is greater than available number of blocks");
  90. throw D3DERR_INVALIDSTATEBLOCK;
  91. }
  92. CStateSet *pStateSet = &m_pStateSets[dwHandle];
  93. if (!(pStateSet->m_dwStateSetFlags & __STATESET_INITIALIZED))
  94. {
  95. D3D_ERR("State block is not initialized");
  96. throw D3DERR_INVALIDSTATEBLOCK;
  97. }
  98. // Pass delete instruction to the driver only if there was some data recorded
  99. if (pStateSet->m_DriverBuffer.m_dwCurrentSize > 0)
  100. InsertStateSetOp(pDevI, D3DHAL_STATESETDELETE, pStateSet->m_dwDeviceHandle, (D3DSTATEBLOCKTYPE)0);
  101. Cleanup(dwHandle);
  102. }
  103. //---------------------------------------------------------------------
  104. #undef DPF_MODNAME
  105. #define DPF_MODNAME "CStateSets::Cleanup"
  106. void CStateSets::Cleanup(DWORD dwHandle)
  107. {
  108. CStateSet &pStateSet = m_pStateSets[dwHandle];
  109. m_SetHandles.ReleaseHandle(dwHandle);
  110. if (pStateSet.m_dwDeviceHandle != __INVALIDHANDLE)
  111. m_DeviceHandles.ReleaseHandle(pStateSet.m_dwDeviceHandle);
  112. pStateSet.Release();
  113. }
  114. //---------------------------------------------------------------------
  115. #undef DPF_MODNAME
  116. #define DPF_MODNAME "CStateSets::Capture"
  117. void CStateSets::Capture(LPDIRECT3DDEVICEI pDevI, DWORD dwHandle)
  118. {
  119. if (dwHandle >= m_dwMaxSets)
  120. {
  121. D3D_ERR("Invalid state block handle");
  122. throw D3DERR_INVALIDSTATEBLOCK;
  123. }
  124. CStateSet *pStateSet = &m_pStateSets[dwHandle];
  125. if (!(pStateSet->m_dwStateSetFlags & __STATESET_INITIALIZED))
  126. {
  127. D3D_ERR("State block not initialized");
  128. throw D3DERR_INVALIDSTATEBLOCK;
  129. }
  130. pStateSet->Capture(pDevI, TRUE);
  131. if (pStateSet->m_DriverBuffer.m_dwCurrentSize > 0)
  132. {
  133. pStateSet->Capture(pDevI, FALSE);
  134. InsertStateSetOp(pDevI, D3DHAL_STATESETCAPTURE, pStateSet->m_dwDeviceHandle, (D3DSTATEBLOCKTYPE)0);
  135. }
  136. }
  137. //---------------------------------------------------------------------
  138. #undef DPF_MODNAME
  139. #define DPF_MODNAME "CStateSets::CreatePredefined"
  140. void CStateSets::CreatePredefined(LPDIRECT3DDEVICEI pDevI, D3DSTATEBLOCKTYPE sbt)
  141. {
  142. static D3DRENDERSTATETYPE ALLrstates[] =
  143. {
  144. D3DRENDERSTATE_TEXTUREPERSPECTIVE,
  145. D3DRENDERSTATE_ANTIALIAS,
  146. D3DRENDERSTATE_SPECULARENABLE,
  147. D3DRENDERSTATE_ZENABLE,
  148. D3DRENDERSTATE_FILLMODE,
  149. D3DRENDERSTATE_SHADEMODE,
  150. D3DRENDERSTATE_LINEPATTERN,
  151. D3DRENDERSTATE_ZWRITEENABLE,
  152. D3DRENDERSTATE_ALPHATESTENABLE,
  153. D3DRENDERSTATE_LASTPIXEL,
  154. D3DRENDERSTATE_SRCBLEND,
  155. D3DRENDERSTATE_DESTBLEND,
  156. D3DRENDERSTATE_CULLMODE,
  157. D3DRENDERSTATE_ZFUNC,
  158. D3DRENDERSTATE_ALPHAREF,
  159. D3DRENDERSTATE_ALPHAFUNC,
  160. D3DRENDERSTATE_DITHERENABLE,
  161. D3DRENDERSTATE_FOGENABLE,
  162. D3DRENDERSTATE_STIPPLEDALPHA,
  163. D3DRENDERSTATE_FOGCOLOR,
  164. D3DRENDERSTATE_FOGTABLEMODE,
  165. D3DRENDERSTATE_FOGSTART,
  166. D3DRENDERSTATE_FOGEND,
  167. D3DRENDERSTATE_FOGDENSITY,
  168. D3DRENDERSTATE_EDGEANTIALIAS,
  169. D3DRENDERSTATE_COLORKEYENABLE,
  170. D3DRENDERSTATE_ALPHABLENDENABLE,
  171. D3DRENDERSTATE_ZBIAS,
  172. D3DRENDERSTATE_RANGEFOGENABLE,
  173. D3DRENDERSTATE_STENCILENABLE,
  174. D3DRENDERSTATE_STENCILFAIL,
  175. D3DRENDERSTATE_STENCILZFAIL,
  176. D3DRENDERSTATE_STENCILPASS,
  177. D3DRENDERSTATE_STENCILFUNC,
  178. D3DRENDERSTATE_STENCILREF,
  179. D3DRENDERSTATE_STENCILMASK,
  180. D3DRENDERSTATE_STENCILWRITEMASK,
  181. D3DRENDERSTATE_TEXTUREFACTOR,
  182. D3DRENDERSTATE_WRAP0,
  183. D3DRENDERSTATE_WRAP1,
  184. D3DRENDERSTATE_WRAP2,
  185. D3DRENDERSTATE_WRAP3,
  186. D3DRENDERSTATE_WRAP4,
  187. D3DRENDERSTATE_WRAP5,
  188. D3DRENDERSTATE_WRAP6,
  189. D3DRENDERSTATE_WRAP7,
  190. D3DRENDERSTATE_AMBIENT,
  191. D3DRENDERSTATE_COLORVERTEX,
  192. D3DRENDERSTATE_FOGVERTEXMODE,
  193. D3DRENDERSTATE_CLIPPING,
  194. D3DRENDERSTATE_LIGHTING,
  195. D3DRENDERSTATE_EXTENTS,
  196. D3DRENDERSTATE_NORMALIZENORMALS,
  197. D3DRENDERSTATE_LOCALVIEWER,
  198. D3DRENDERSTATE_EMISSIVEMATERIALSOURCE,
  199. D3DRENDERSTATE_AMBIENTMATERIALSOURCE,
  200. D3DRENDERSTATE_DIFFUSEMATERIALSOURCE,
  201. D3DRENDERSTATE_SPECULARMATERIALSOURCE,
  202. D3DRENDERSTATE_VERTEXBLEND,
  203. D3DRENDERSTATE_CLIPPLANEENABLE,
  204. D3DRENDERSTATE_COLORKEYBLENDENABLE
  205. };
  206. static D3DTEXTURESTAGESTATETYPE ALLtsstates[] =
  207. {
  208. D3DTSS_COLOROP,
  209. D3DTSS_COLORARG1,
  210. D3DTSS_COLORARG2,
  211. D3DTSS_ALPHAOP,
  212. D3DTSS_ALPHAARG1,
  213. D3DTSS_ALPHAARG2,
  214. D3DTSS_BUMPENVMAT00,
  215. D3DTSS_BUMPENVMAT01,
  216. D3DTSS_BUMPENVMAT10,
  217. D3DTSS_BUMPENVMAT11,
  218. D3DTSS_TEXCOORDINDEX,
  219. D3DTSS_ADDRESS,
  220. D3DTSS_ADDRESSU,
  221. D3DTSS_ADDRESSV,
  222. D3DTSS_BORDERCOLOR,
  223. D3DTSS_MAGFILTER,
  224. D3DTSS_MINFILTER,
  225. D3DTSS_MIPFILTER,
  226. D3DTSS_MIPMAPLODBIAS,
  227. D3DTSS_MAXMIPLEVEL,
  228. D3DTSS_MAXANISOTROPY,
  229. D3DTSS_BUMPENVLSCALE,
  230. D3DTSS_BUMPENVLOFFSET,
  231. D3DTSS_TEXTURETRANSFORMFLAGS
  232. };
  233. static D3DRENDERSTATETYPE PIXELrstates[] =
  234. {
  235. D3DRENDERSTATE_TEXTUREPERSPECTIVE,
  236. D3DRENDERSTATE_ANTIALIAS,
  237. D3DRENDERSTATE_ZENABLE,
  238. D3DRENDERSTATE_FILLMODE,
  239. D3DRENDERSTATE_SHADEMODE,
  240. D3DRENDERSTATE_LINEPATTERN,
  241. D3DRENDERSTATE_ZWRITEENABLE,
  242. D3DRENDERSTATE_ALPHATESTENABLE,
  243. D3DRENDERSTATE_LASTPIXEL,
  244. D3DRENDERSTATE_SRCBLEND,
  245. D3DRENDERSTATE_DESTBLEND,
  246. D3DRENDERSTATE_ZFUNC,
  247. D3DRENDERSTATE_ALPHAREF,
  248. D3DRENDERSTATE_ALPHAFUNC,
  249. D3DRENDERSTATE_DITHERENABLE,
  250. D3DRENDERSTATE_STIPPLEDALPHA,
  251. D3DRENDERSTATE_FOGSTART,
  252. D3DRENDERSTATE_FOGEND,
  253. D3DRENDERSTATE_FOGDENSITY,
  254. D3DRENDERSTATE_EDGEANTIALIAS,
  255. D3DRENDERSTATE_COLORKEYENABLE,
  256. D3DRENDERSTATE_ALPHABLENDENABLE,
  257. D3DRENDERSTATE_ZBIAS,
  258. D3DRENDERSTATE_STENCILENABLE,
  259. D3DRENDERSTATE_STENCILFAIL,
  260. D3DRENDERSTATE_STENCILZFAIL,
  261. D3DRENDERSTATE_STENCILPASS,
  262. D3DRENDERSTATE_STENCILFUNC,
  263. D3DRENDERSTATE_STENCILREF,
  264. D3DRENDERSTATE_STENCILMASK,
  265. D3DRENDERSTATE_STENCILWRITEMASK,
  266. D3DRENDERSTATE_TEXTUREFACTOR,
  267. D3DRENDERSTATE_WRAP0,
  268. D3DRENDERSTATE_WRAP1,
  269. D3DRENDERSTATE_WRAP2,
  270. D3DRENDERSTATE_WRAP3,
  271. D3DRENDERSTATE_WRAP4,
  272. D3DRENDERSTATE_WRAP5,
  273. D3DRENDERSTATE_WRAP6,
  274. D3DRENDERSTATE_WRAP7,
  275. D3DRENDERSTATE_COLORKEYBLENDENABLE
  276. };
  277. static D3DTEXTURESTAGESTATETYPE PIXELtsstates[] =
  278. {
  279. D3DTSS_COLOROP,
  280. D3DTSS_COLORARG1,
  281. D3DTSS_COLORARG2,
  282. D3DTSS_ALPHAOP,
  283. D3DTSS_ALPHAARG1,
  284. D3DTSS_ALPHAARG2,
  285. D3DTSS_BUMPENVMAT00,
  286. D3DTSS_BUMPENVMAT01,
  287. D3DTSS_BUMPENVMAT10,
  288. D3DTSS_BUMPENVMAT11,
  289. D3DTSS_TEXCOORDINDEX,
  290. D3DTSS_ADDRESS,
  291. D3DTSS_ADDRESSU,
  292. D3DTSS_ADDRESSV,
  293. D3DTSS_BORDERCOLOR,
  294. D3DTSS_MAGFILTER,
  295. D3DTSS_MINFILTER,
  296. D3DTSS_MIPFILTER,
  297. D3DTSS_MIPMAPLODBIAS,
  298. D3DTSS_MAXMIPLEVEL,
  299. D3DTSS_MAXANISOTROPY,
  300. D3DTSS_BUMPENVLSCALE,
  301. D3DTSS_BUMPENVLOFFSET,
  302. D3DTSS_TEXTURETRANSFORMFLAGS
  303. };
  304. static D3DRENDERSTATETYPE VERTEXrstates[] =
  305. {
  306. D3DRENDERSTATE_SHADEMODE,
  307. D3DRENDERSTATE_SPECULARENABLE,
  308. D3DRENDERSTATE_CULLMODE,
  309. D3DRENDERSTATE_FOGENABLE,
  310. D3DRENDERSTATE_FOGCOLOR,
  311. D3DRENDERSTATE_FOGTABLEMODE,
  312. D3DRENDERSTATE_FOGSTART,
  313. D3DRENDERSTATE_FOGEND,
  314. D3DRENDERSTATE_FOGDENSITY,
  315. D3DRENDERSTATE_RANGEFOGENABLE,
  316. D3DRENDERSTATE_AMBIENT,
  317. D3DRENDERSTATE_COLORVERTEX,
  318. D3DRENDERSTATE_FOGVERTEXMODE,
  319. D3DRENDERSTATE_CLIPPING,
  320. D3DRENDERSTATE_LIGHTING,
  321. D3DRENDERSTATE_EXTENTS,
  322. D3DRENDERSTATE_NORMALIZENORMALS,
  323. D3DRENDERSTATE_LOCALVIEWER,
  324. D3DRENDERSTATE_EMISSIVEMATERIALSOURCE,
  325. D3DRENDERSTATE_AMBIENTMATERIALSOURCE,
  326. D3DRENDERSTATE_DIFFUSEMATERIALSOURCE,
  327. D3DRENDERSTATE_SPECULARMATERIALSOURCE,
  328. D3DRENDERSTATE_VERTEXBLEND,
  329. D3DRENDERSTATE_CLIPPLANEENABLE
  330. };
  331. static D3DTEXTURESTAGESTATETYPE VERTEXtsstates[] =
  332. {
  333. D3DTSS_TEXCOORDINDEX,
  334. D3DTSS_TEXTURETRANSFORMFLAGS
  335. };
  336. DWORD i;
  337. switch(sbt)
  338. {
  339. case (D3DSTATEBLOCKTYPE)0:
  340. break;
  341. case D3DSBT_ALL:
  342. for(i = 0; i < sizeof(ALLrstates) / sizeof(D3DRENDERSTATETYPE); ++i)
  343. InsertRenderState(ALLrstates[i], pDevI->rstates[ALLrstates[i]], pDevI->CanHandleRenderState(ALLrstates[i]));
  344. for (i = 0; i < pDevI->dwMaxTextureBlendStages; i++)
  345. for(DWORD j = 0; j < sizeof(ALLtsstates) / sizeof(D3DTEXTURESTAGESTATETYPE); ++j)
  346. InsertTextureStageState(i, ALLtsstates[j], pDevI->tsstates[i][ALLtsstates[j]]);
  347. // Capture textures
  348. for (i = 0; i < pDevI->dwMaxTextureBlendStages; i++)
  349. {
  350. LPDIRECTDRAWSURFACE7 pTexture;
  351. if (pDevI->lpD3DMappedTexI[i])
  352. {
  353. if(pDevI->lpD3DMappedTexI[i]->D3DManaged())
  354. pTexture = pDevI->lpD3DMappedTexI[i]->lpDDSSys;
  355. else
  356. pTexture = pDevI->lpD3DMappedTexI[i]->lpDDS;
  357. }
  358. else
  359. {
  360. pTexture = NULL;
  361. }
  362. InsertTexture(i, pTexture);
  363. }
  364. // Capture current viewport
  365. InsertViewport(&pDevI->m_Viewport);
  366. // Capture current transforms
  367. InsertTransform(D3DTRANSFORMSTATE_WORLD, (LPD3DMATRIX)&pDevI->transform.world[0]);
  368. InsertTransform(D3DTRANSFORMSTATE_VIEW, (LPD3DMATRIX)&pDevI->transform.view);
  369. InsertTransform(D3DTRANSFORMSTATE_PROJECTION, (LPD3DMATRIX)&pDevI->transform.proj);
  370. InsertTransform(D3DTRANSFORMSTATE_WORLD1, (LPD3DMATRIX)&pDevI->transform.world[1]);
  371. InsertTransform(D3DTRANSFORMSTATE_WORLD2, (LPD3DMATRIX)&pDevI->transform.world[2]);
  372. InsertTransform(D3DTRANSFORMSTATE_WORLD3, (LPD3DMATRIX)&pDevI->transform.world[3]);
  373. for (i = 0; i < pDevI->dwMaxTextureBlendStages; i++)
  374. {
  375. InsertTransform((D3DTRANSFORMSTATETYPE)(D3DTRANSFORMSTATE_TEXTURE0 + i), (LPD3DMATRIX)&pDevI->mTexture[i]);
  376. }
  377. // Capture current clip-planes
  378. for (i = 0; i < pDevI->transform.dwMaxUserClipPlanes; i++)
  379. {
  380. InsertClipPlane(i, (LPD3DVALUE)&pDevI->transform.userClipPlane[i]);
  381. }
  382. // Capture current material
  383. InsertMaterial(&pDevI->lighting.material);
  384. // Capture current lights
  385. for (i = 0; i < pDevI->m_dwNumLights; i++)
  386. {
  387. if(pDevI->m_pLights[i].Valid())
  388. {
  389. InsertLight(i, &pDevI->m_pLights[i].m_Light);
  390. if(pDevI->m_pLights[i].Enabled())
  391. {
  392. InsertLightEnable(i, TRUE);
  393. }
  394. else
  395. {
  396. InsertLightEnable(i, FALSE);
  397. }
  398. }
  399. }
  400. break;
  401. case D3DSBT_PIXELSTATE:
  402. for(i = 0; i < sizeof(PIXELrstates) / sizeof(D3DRENDERSTATETYPE); ++i)
  403. InsertRenderState(PIXELrstates[i], pDevI->rstates[PIXELrstates[i]], pDevI->CanHandleRenderState(PIXELrstates[i]));
  404. for (i = 0; i < pDevI->dwMaxTextureBlendStages; i++)
  405. for(DWORD j = 0; j < sizeof(PIXELtsstates) / sizeof(D3DTEXTURESTAGESTATETYPE); ++j)
  406. InsertTextureStageState(i, PIXELtsstates[j], pDevI->tsstates[i][PIXELtsstates[j]]);
  407. break;
  408. case D3DSBT_VERTEXSTATE:
  409. for(i = 0; i < sizeof(VERTEXrstates) / sizeof(D3DRENDERSTATETYPE); ++i)
  410. InsertRenderState(VERTEXrstates[i], pDevI->rstates[VERTEXrstates[i]], pDevI->CanHandleRenderState(VERTEXrstates[i]));
  411. for (i = 0; i < pDevI->dwMaxTextureBlendStages; i++)
  412. for(DWORD j = 0; j < sizeof(VERTEXtsstates) / sizeof(D3DTEXTURESTAGESTATETYPE); ++j)
  413. InsertTextureStageState(i, VERTEXtsstates[j], pDevI->tsstates[i][VERTEXtsstates[j]]);
  414. // Capture current light enables
  415. for (i = 0; i < pDevI->m_dwNumLights; i++)
  416. {
  417. if(pDevI->m_pLights[i].Valid())
  418. {
  419. if(pDevI->m_pLights[i].Enabled())
  420. {
  421. InsertLightEnable(i, TRUE);
  422. }
  423. else
  424. {
  425. InsertLightEnable(i, FALSE);
  426. }
  427. }
  428. }
  429. break;
  430. default:
  431. throw DDERR_INVALIDPARAMS;
  432. }
  433. }
  434. //---------------------------------------------------------------------
  435. // Allocates device handle if necessary
  436. // And returns information of the device buffer
  437. //
  438. #undef DPF_MODNAME
  439. #define DPF_MODNAME "CStateSets::GetDeviceBufferInfo"
  440. void CStateSets::GetDeviceBufferInfo(DWORD* dwStateSetHandle,
  441. LPVOID *pBuffer,
  442. DWORD* dwBufferSize)
  443. {
  444. if (m_pCurrentStateSet->m_DriverBuffer.m_dwCurrentSize != 0)
  445. {
  446. // Allocate a handle for the device
  447. m_pCurrentStateSet->m_dwDeviceHandle = m_DeviceHandles.CreateNewHandle();
  448. if (m_pCurrentStateSet->m_dwDeviceHandle == __INVALIDHANDLE)
  449. {
  450. D3D_ERR("Cannot allocate device handle for a state block");
  451. throw DDERR_OUTOFMEMORY;
  452. }
  453. }
  454. *dwStateSetHandle = m_pCurrentStateSet->m_dwDeviceHandle;
  455. *pBuffer = (LPVOID)m_pCurrentStateSet->m_DriverBuffer.m_pBuffer;
  456. *dwBufferSize = m_pCurrentStateSet->m_DriverBuffer.m_dwCurrentSize;
  457. }
  458. //---------------------------------------------------------------------
  459. #undef DPF_MODNAME
  460. #define DPF_MODNAME "CStateSets::InsertRenderState"
  461. void CStateSets::InsertRenderState(D3DRENDERSTATETYPE state, DWORD dwValue,
  462. BOOL bDriverCanHandle)
  463. {
  464. struct
  465. {
  466. D3DRENDERSTATETYPE state;
  467. DWORD dwValue;
  468. } data = {state, dwValue};
  469. m_pCurrentStateSet->InsertCommand(D3DDP2OP_RENDERSTATE,
  470. &data, sizeof(data),
  471. m_dwFlags & D3DFE_STATESETS && bDriverCanHandle);
  472. }
  473. //---------------------------------------------------------------------
  474. #undef DPF_MODNAME
  475. #define DPF_MODNAME "CStateSets::InsertLight"
  476. void CStateSets::InsertLight(DWORD dwLightIndex, LPD3DLIGHT7 pData)
  477. {
  478. struct
  479. {
  480. D3DHAL_DP2SETLIGHT header;
  481. D3DLIGHT7 light;
  482. } data;
  483. data.header.dwIndex = dwLightIndex;
  484. data.header.dwDataType = D3DHAL_SETLIGHT_DATA;
  485. data.light= *pData;
  486. m_pCurrentStateSet->InsertCommand(D3DDP2OP_SETLIGHT, &data, sizeof(data),
  487. m_dwFlags & D3DFE_STATESETS && m_dwFlags & D3DFE_TLHAL);
  488. }
  489. //---------------------------------------------------------------------
  490. #undef DPF_MODNAME
  491. #define DPF_MODNAME "CStateSets::InsertLightEnable"
  492. void CStateSets::InsertLightEnable(DWORD dwLightIndex, BOOL bEnable)
  493. {
  494. D3DHAL_DP2SETLIGHT data;
  495. data.dwIndex = dwLightIndex;
  496. if (bEnable)
  497. data.dwDataType = D3DHAL_SETLIGHT_ENABLE;
  498. else
  499. data.dwDataType = D3DHAL_SETLIGHT_DISABLE;
  500. m_pCurrentStateSet->InsertCommand(D3DDP2OP_SETLIGHT, &data, sizeof(data),
  501. m_dwFlags & D3DFE_STATESETS && m_dwFlags & D3DFE_TLHAL);
  502. }
  503. //---------------------------------------------------------------------
  504. #undef DPF_MODNAME
  505. #define DPF_MODNAME "CStateSets::InsertViewport"
  506. void CStateSets::InsertViewport(LPD3DVIEWPORT7 lpVwpData)
  507. {
  508. D3DHAL_DP2VIEWPORTINFO data2;
  509. data2.dwX = lpVwpData->dwX;
  510. data2.dwY = lpVwpData->dwY;
  511. data2.dwWidth = lpVwpData->dwWidth;
  512. data2.dwHeight = lpVwpData->dwHeight;
  513. m_pCurrentStateSet->InsertCommand(D3DDP2OP_VIEWPORTINFO, &data2, sizeof(data2),
  514. m_dwFlags & D3DFE_STATESETS && m_dwFlags & D3DFE_TLHAL);
  515. D3DHAL_DP2ZRANGE data1;
  516. data1.dvMinZ = lpVwpData->dvMinZ;
  517. data1.dvMaxZ = lpVwpData->dvMaxZ;
  518. m_pCurrentStateSet->InsertCommand(D3DDP2OP_ZRANGE, &data1, sizeof(data1),
  519. m_dwFlags & D3DFE_STATESETS && m_dwFlags & D3DFE_TLHAL);
  520. m_pCurrentStateSet->ResetCurrentCommand();
  521. }
  522. //---------------------------------------------------------------------
  523. #undef DPF_MODNAME
  524. #define DPF_MODNAME "CStateSets::InsertMaterial"
  525. void CStateSets::InsertMaterial(LPD3DMATERIAL7 pData)
  526. {
  527. m_pCurrentStateSet->InsertCommand(D3DDP2OP_SETMATERIAL,
  528. pData, sizeof(D3DMATERIAL7),
  529. m_dwFlags & D3DFE_STATESETS && m_dwFlags & D3DFE_TLHAL);
  530. m_pCurrentStateSet->ResetCurrentCommand();
  531. }
  532. //---------------------------------------------------------------------
  533. #undef DPF_MODNAME
  534. #define DPF_MODNAME "CStateSets::InsertClipPlane"
  535. void CStateSets::InsertClipPlane(DWORD dwPlaneIndex, D3DVALUE* pPlaneEquation)
  536. {
  537. D3DHAL_DP2SETCLIPPLANE data;
  538. data.dwIndex = dwPlaneIndex;
  539. data.plane[0] = pPlaneEquation[0];
  540. data.plane[1] = pPlaneEquation[1];
  541. data.plane[2] = pPlaneEquation[2];
  542. data.plane[3] = pPlaneEquation[3];
  543. m_pCurrentStateSet->InsertCommand(D3DDP2OP_SETCLIPPLANE,
  544. &data, sizeof(data),
  545. m_dwFlags & D3DFE_STATESETS && m_dwFlags & D3DFE_TLHAL);
  546. }
  547. //---------------------------------------------------------------------
  548. #undef DPF_MODNAME
  549. #define DPF_MODNAME "CStateSets::InsertTransform"
  550. void CStateSets::InsertTransform(D3DTRANSFORMSTATETYPE state, LPD3DMATRIX lpMat)
  551. {
  552. D3DHAL_DP2SETTRANSFORM data;
  553. data.xfrmType = state;
  554. data.matrix = *lpMat;
  555. m_pCurrentStateSet->InsertCommand(D3DDP2OP_SETTRANSFORM,
  556. &data, sizeof(data),
  557. m_dwFlags & D3DFE_STATESETS && m_dwFlags & D3DFE_TLHAL);
  558. }
  559. //---------------------------------------------------------------------
  560. #undef DPF_MODNAME
  561. #define DPF_MODNAME "CStateSets::InsertTextureStageState"
  562. void CStateSets::InsertTextureStageState(DWORD dwStage,
  563. D3DTEXTURESTAGESTATETYPE type,
  564. DWORD dwValue)
  565. {
  566. D3DHAL_DP2TEXTURESTAGESTATE data = {(WORD)dwStage, type, dwValue};
  567. m_pCurrentStateSet->InsertCommand(D3DDP2OP_TEXTURESTAGESTATE,
  568. &data, sizeof(data),
  569. m_dwFlags & D3DFE_STATESETS);
  570. }
  571. //---------------------------------------------------------------------
  572. #undef DPF_MODNAME
  573. #define DPF_MODNAME "CStateSets::InsertTexture"
  574. void CStateSets::InsertTexture(DWORD dwStage, LPDIRECTDRAWSURFACE7 pTex)
  575. {
  576. D3DHAL_DP2FRONTENDDATA data = {(WORD)dwStage, (LPVOID)pTex};
  577. // Only the front-end will parse this instruction
  578. m_pCurrentStateSet->InsertCommand((D3DHAL_DP2OPERATION)D3DDP2OP_FRONTENDDATA, &data, sizeof(data), FALSE);
  579. }
  580. //---------------------------------------------------------------------
  581. #undef DPF_MODNAME
  582. #define DPF_MODNAME "CStateSets::Execute"
  583. void CStateSets::Execute(LPDIRECT3DDEVICEI pDevI, DWORD dwHandle)
  584. {
  585. #if DBG
  586. if (dwHandle >= m_dwMaxSets)
  587. {
  588. D3D_ERR("Invalid state block handle");
  589. throw D3DERR_INVALIDSTATEBLOCK;
  590. }
  591. #endif
  592. CStateSet *pStateSet = &m_pStateSets[dwHandle];
  593. #if DBG
  594. if (!(pStateSet->m_dwStateSetFlags & __STATESET_INITIALIZED))
  595. {
  596. D3D_ERR("State block not initialized");
  597. throw D3DERR_INVALIDSTATEBLOCK;
  598. }
  599. #endif
  600. // Parse recorded data first
  601. pStateSet->Execute(pDevI, TRUE);
  602. // If the hardware buffer is not empty, we pass recorded data to it
  603. if (pStateSet->m_DriverBuffer.m_dwCurrentSize > 0)
  604. {
  605. pStateSet->Execute(pDevI, FALSE);
  606. InsertStateSetOp(pDevI, D3DHAL_STATESETEXECUTE, pStateSet->m_dwDeviceHandle, (D3DSTATEBLOCKTYPE)0);
  607. }
  608. }
  609. //=====================================================================
  610. // CStateSet interface
  611. //
  612. #undef DPF_MODNAME
  613. #define DPF_MODNAME "CStateSet::Release"
  614. HRESULT CStateSet::Release()
  615. {
  616. if (!(m_dwStateSetFlags & __STATESET_INITIALIZED))
  617. return D3DERR_INVALIDSTATEBLOCK;
  618. m_dwStateSetFlags &= ~__STATESET_INITIALIZED;
  619. m_FEOnlyBuffer.Reset();
  620. m_DriverBuffer.Reset();
  621. return D3D_OK;
  622. }
  623. //---------------------------------------------------------------------
  624. #undef DPF_MODNAME
  625. #define DPF_MODNAME "CStateSet::InsertCommand"
  626. void CStateSet::InsertCommand(D3DHAL_DP2OPERATION op, LPVOID pData,
  627. DWORD dwDataSize,
  628. BOOL bDriverCanHandle)
  629. {
  630. if (op == D3DDP2OP_TEXTURESTAGESTATE ||
  631. (op == D3DDP2OP_RENDERSTATE &&
  632. ((LPD3DHAL_DP2RENDERSTATE)pData)->RenderState >= D3DRENDERSTATE_WRAP0 &&
  633. ((LPD3DHAL_DP2RENDERSTATE)pData)->RenderState <= D3DRENDERSTATE_WRAP7))
  634. {
  635. m_dwStateSetFlags |= __STATESET_NEEDCHECKREMAPPING;
  636. }
  637. if (bDriverCanHandle)
  638. m_DriverBuffer.InsertCommand(op, pData, dwDataSize);
  639. else
  640. m_FEOnlyBuffer.InsertCommand(op, pData, dwDataSize);
  641. }
  642. //---------------------------------------------------------------------
  643. #undef DPF_MODNAME
  644. #define DPF_MODNAME "CStateSet::Execute"
  645. void CStateSet::Execute(LPDIRECT3DDEVICEI pDevI, BOOL bFrontEndBuffer)
  646. {
  647. DWORD *p;
  648. DWORD dwSize;
  649. DWORD *pEnd;
  650. try
  651. {
  652. // Texture stages could be re-mapped during texture transform processing.
  653. // Before we set new values we have to restore original ones
  654. if (pDevI->dwDeviceFlags & D3DDEV_REMAPTEXTUREINDICES &&
  655. m_dwStateSetFlags & __STATESET_NEEDCHECKREMAPPING)
  656. {
  657. RestoreTextureStages(pDevI);
  658. pDevI->ForceFVFRecompute();
  659. }
  660. if (bFrontEndBuffer)
  661. {
  662. p = (DWORD*)m_FEOnlyBuffer.m_pBuffer;
  663. dwSize = m_FEOnlyBuffer.m_dwCurrentSize;
  664. }
  665. else
  666. {
  667. p = (DWORD*)m_DriverBuffer.m_pBuffer;
  668. dwSize = m_DriverBuffer.m_dwCurrentSize;
  669. pDevI->dwFEFlags |= D3DFE_EXECUTESTATEMODE;
  670. }
  671. pEnd = (DWORD*)((BYTE*)p + dwSize);
  672. while (p < pEnd)
  673. {
  674. LPD3DHAL_DP2COMMAND pCommand = (LPD3DHAL_DP2COMMAND)p;
  675. p = (DWORD*)((BYTE*)p + sizeof(D3DHAL_DP2COMMAND));
  676. switch ((D3DHAL_DP2OPERATION)pCommand->bCommand)
  677. {
  678. case D3DDP2OP_RENDERSTATE:
  679. {
  680. if(pDevI->dwFEFlags & D3DFE_EXECUTESTATEMODE)
  681. {
  682. for(DWORD i = 0; i < (DWORD)pCommand->wStateCount; ++i)
  683. {
  684. D3DRENDERSTATETYPE dwState = (D3DRENDERSTATETYPE)*p++;
  685. DWORD dwValue = *p++;
  686. if (pDevI->rstates[dwState] != dwValue)
  687. {
  688. if (!(pDevI->rsVec[dwState >> D3D_RSVEC_SHIFT] & (1ul << (dwState & D3D_RSVEC_MASK))))
  689. { // Fast path. We do not need any processing done in UpdateInternalState other than updating rstates array
  690. pDevI->rstates[dwState] = dwValue;
  691. }
  692. else
  693. {
  694. pDevI->UpdateInternalState(dwState, dwValue);
  695. }
  696. }
  697. else
  698. {
  699. D3D_WARN(4,"Ignoring redundant SetRenderState");
  700. }
  701. }
  702. }
  703. else
  704. {
  705. for(DWORD i = 0; i < (DWORD)pCommand->wStateCount; ++i)
  706. {
  707. D3DRENDERSTATETYPE dwState = (D3DRENDERSTATETYPE)*p++;
  708. DWORD dwValue = *p++;
  709. if (pDevI->rstates[dwState] != dwValue)
  710. {
  711. if (!(pDevI->rsVec[dwState >> D3D_RSVEC_SHIFT] & (1ul << (dwState & D3D_RSVEC_MASK))))
  712. { // Fast path. We do not need any processing done in UpdateInternalState other than updating rstates array
  713. pDevI->rstates[dwState] = dwValue;
  714. HRESULT ret = pDevI->SetRenderStateI(dwState, dwValue);
  715. if(ret != D3D_OK)
  716. throw ret;
  717. }
  718. else
  719. {
  720. pDevI->UpdateInternalState(dwState, dwValue);
  721. if (pDevI->CanHandleRenderState(dwState))
  722. {
  723. HRESULT ret = pDevI->SetRenderStateI(dwState, dwValue);
  724. if(ret != D3D_OK)
  725. throw ret;
  726. }
  727. }
  728. }
  729. else
  730. {
  731. D3D_WARN(4,"Ignoring redundant SetRenderState");
  732. }
  733. }
  734. }
  735. break;
  736. }
  737. case D3DDP2OP_SETLIGHT:
  738. {
  739. for(DWORD i = 0; i < (DWORD)pCommand->wStateCount; ++i)
  740. {
  741. LPD3DHAL_DP2SETLIGHT pData = (LPD3DHAL_DP2SETLIGHT)p;
  742. p = (DWORD*)((BYTE*)p + sizeof(D3DHAL_DP2SETLIGHT));
  743. switch (pData->dwDataType)
  744. {
  745. case D3DHAL_SETLIGHT_ENABLE:
  746. pDevI->LightEnableI( pData->dwIndex, TRUE );
  747. break;
  748. case D3DHAL_SETLIGHT_DISABLE:
  749. pDevI->LightEnableI( pData->dwIndex, FALSE );
  750. break;
  751. case D3DHAL_SETLIGHT_DATA:
  752. pDevI->SetLightI(pData->dwIndex, (D3DLIGHT7 *)p);
  753. p = (LPDWORD)((LPBYTE)p + sizeof(D3DLIGHT7));
  754. break;
  755. }
  756. }
  757. break;
  758. }
  759. case D3DDP2OP_SETMATERIAL:
  760. {
  761. for(DWORD i = 0; i < (DWORD)pCommand->wStateCount; ++i)
  762. {
  763. LPD3DHAL_DP2SETMATERIAL pData = (LPD3DHAL_DP2SETMATERIAL)p;
  764. p = (DWORD*)((BYTE*)p + sizeof(D3DHAL_DP2SETMATERIAL));
  765. pDevI->SetMaterialI(pData);
  766. }
  767. break;
  768. }
  769. case D3DDP2OP_SETTRANSFORM:
  770. {
  771. for(DWORD i = 0; i < (DWORD)pCommand->wStateCount; ++i)
  772. {
  773. D3DHAL_DP2SETTRANSFORM *pData = (D3DHAL_DP2SETTRANSFORM*)p;
  774. p = (DWORD*)((BYTE*)p + sizeof(D3DHAL_DP2SETTRANSFORM));
  775. pDevI->SetTransformI(pData->xfrmType, &pData->matrix);
  776. }
  777. break;
  778. }
  779. case D3DDP2OP_TEXTURESTAGESTATE:
  780. {
  781. if (pDevI->dwFEFlags & D3DFE_EXECUTESTATEMODE)
  782. {
  783. for(DWORD i = 0; i < (DWORD)pCommand->wStateCount; ++i)
  784. {
  785. LPD3DHAL_DP2TEXTURESTAGESTATE pData = (LPD3DHAL_DP2TEXTURESTAGESTATE)p;
  786. p = (DWORD*)((BYTE*)p + sizeof(D3DHAL_DP2TEXTURESTAGESTATE));
  787. DWORD dwStage = pData->wStage;
  788. DWORD dwState = pData->TSState;
  789. DWORD dwValue = pData->dwValue;
  790. if (pDevI->tsstates[dwStage][dwState] != dwValue)
  791. {
  792. // Fast path. We do not need any processing done in UpdateInternalTSS other than updating tsstates array
  793. if (pDevI->NeedInternalTSSUpdate(dwState))
  794. pDevI->UpdateInternalTextureStageState(dwStage, (D3DTEXTURESTAGESTATETYPE)dwState, dwValue);
  795. else
  796. pDevI->tsstates[dwStage][dwState] = dwValue;
  797. }
  798. else
  799. {
  800. D3D_WARN(4,"Ignoring redundant SetTextureStageState");
  801. }
  802. }
  803. }
  804. else
  805. {
  806. for(DWORD i = 0; i < (DWORD)pCommand->wStateCount; ++i)
  807. {
  808. LPD3DHAL_DP2TEXTURESTAGESTATE pData = (LPD3DHAL_DP2TEXTURESTAGESTATE)p;
  809. p = (DWORD*)((BYTE*)p + sizeof(D3DHAL_DP2TEXTURESTAGESTATE));
  810. DWORD dwStage = pData->wStage;
  811. DWORD dwState = pData->TSState;
  812. DWORD dwValue = pData->dwValue;
  813. if (pDevI->tsstates[dwStage][dwState] != dwValue)
  814. {
  815. // Fast path. We do not need any processing done in UpdateInternalTSS other than updating tsstates array
  816. if (pDevI->NeedInternalTSSUpdate(dwState))
  817. {
  818. if(pDevI->UpdateInternalTextureStageState(dwStage, (D3DTEXTURESTAGESTATETYPE)dwState, dwValue))
  819. continue;
  820. }
  821. else
  822. {
  823. pDevI->tsstates[dwStage][dwState] = dwValue;
  824. }
  825. if (dwStage >= pDevI->dwMaxTextureBlendStages)
  826. continue;
  827. HRESULT ret = pDevI->SetTSSI(dwStage, (D3DTEXTURESTAGESTATETYPE)dwState, dwValue);
  828. if(ret != D3D_OK)
  829. throw ret;
  830. }
  831. else
  832. {
  833. D3D_WARN(4,"Ignoring redundant SetTextureStageState");
  834. }
  835. }
  836. }
  837. break;
  838. }
  839. case D3DDP2OP_FRONTENDDATA:
  840. {
  841. for(DWORD i = 0; i < (DWORD)pCommand->wStateCount; ++i)
  842. {
  843. LPD3DHAL_DP2FRONTENDDATA pData = (LPD3DHAL_DP2FRONTENDDATA)p;
  844. p = (DWORD*)((BYTE*)p + sizeof(D3DHAL_DP2FRONTENDDATA));
  845. HRESULT ret = pDevI->SetTexture(pData->wStage, (LPDIRECTDRAWSURFACE7)pData->pTexture);
  846. if (ret != D3D_OK)
  847. throw ret;
  848. }
  849. break;
  850. }
  851. case D3DDP2OP_VIEWPORTINFO:
  852. {
  853. for(DWORD i = 0; i < (DWORD)pCommand->wStateCount; ++i)
  854. {
  855. D3DVIEWPORT7 viewport;
  856. LPD3DHAL_DP2VIEWPORTINFO lpVwpData = (LPD3DHAL_DP2VIEWPORTINFO)p;
  857. p = (DWORD*)((BYTE*)p + sizeof(D3DHAL_DP2VIEWPORTINFO));
  858. viewport.dwX = lpVwpData->dwX;
  859. viewport.dwY = lpVwpData->dwY;
  860. viewport.dwWidth = lpVwpData->dwWidth;
  861. viewport.dwHeight = lpVwpData->dwHeight;
  862. // The next command has to be D3DDP2OP_ZRANGE
  863. p = (DWORD*)((BYTE*)p + sizeof(D3DHAL_DP2COMMAND));
  864. LPD3DHAL_DP2ZRANGE pData = (LPD3DHAL_DP2ZRANGE)p;
  865. p = (DWORD*)((BYTE*)p + sizeof(D3DHAL_DP2ZRANGE));
  866. viewport.dvMinZ = pData->dvMinZ;
  867. viewport.dvMaxZ = pData->dvMaxZ;
  868. pDevI->SetViewportI(&viewport);
  869. }
  870. break;
  871. }
  872. case D3DDP2OP_SETCLIPPLANE:
  873. {
  874. for(DWORD i = 0; i < (DWORD)pCommand->wStateCount; ++i)
  875. {
  876. D3DHAL_DP2SETCLIPPLANE *pData = (D3DHAL_DP2SETCLIPPLANE*)p;
  877. p = (DWORD*)((BYTE*)p + sizeof(D3DHAL_DP2SETCLIPPLANE));
  878. pDevI->SetClipPlaneI(pData->dwIndex, pData->plane);
  879. }
  880. break;
  881. }
  882. #ifdef DBG
  883. default:
  884. DDASSERT(FALSE);
  885. #endif
  886. }
  887. }
  888. pDevI->dwFEFlags &= ~D3DFE_EXECUTESTATEMODE;
  889. }
  890. catch(HRESULT ret)
  891. {
  892. pDevI->dwFEFlags &= ~D3DFE_EXECUTESTATEMODE;
  893. throw ret;
  894. }
  895. }
  896. //---------------------------------------------------------------------
  897. #undef DPF_MODNAME
  898. #define DPF_MODNAME "CStateSet::Capture"
  899. void CStateSet::Capture(LPDIRECT3DDEVICEI pDevI, BOOL bFrontEndBuffer)
  900. {
  901. DWORD *p;
  902. DWORD dwSize;
  903. DWORD *pEnd;
  904. if (bFrontEndBuffer)
  905. {
  906. p = (DWORD*)m_FEOnlyBuffer.m_pBuffer;
  907. dwSize = m_FEOnlyBuffer.m_dwCurrentSize;
  908. }
  909. else
  910. {
  911. p = (DWORD*)m_DriverBuffer.m_pBuffer;
  912. dwSize = m_DriverBuffer.m_dwCurrentSize;
  913. }
  914. pEnd = (DWORD*)((BYTE*)p + dwSize);
  915. while (p < pEnd)
  916. {
  917. LPD3DHAL_DP2COMMAND pCommand = (LPD3DHAL_DP2COMMAND)p;
  918. p = (DWORD*)((BYTE*)p + sizeof(D3DHAL_DP2COMMAND));
  919. switch ((D3DHAL_DP2OPERATION)pCommand->bCommand)
  920. {
  921. case D3DDP2OP_RENDERSTATE:
  922. {
  923. for(DWORD i = 0; i < (DWORD)pCommand->wStateCount; ++i)
  924. {
  925. const D3DRENDERSTATETYPE state = (D3DRENDERSTATETYPE)*p++;
  926. *p++ = pDevI->rstates[state];
  927. }
  928. break;
  929. }
  930. case D3DDP2OP_SETLIGHT:
  931. {
  932. for(DWORD i = 0; i < (DWORD)pCommand->wStateCount; ++i)
  933. {
  934. LPD3DHAL_DP2SETLIGHT pData = (LPD3DHAL_DP2SETLIGHT)p;
  935. p = (DWORD*)((BYTE*)p + sizeof(D3DHAL_DP2SETLIGHT));
  936. if(pData->dwIndex >= pDevI->m_dwNumLights)
  937. {
  938. D3D_ERR("Unable to capture light state (light not set?)");
  939. throw D3DERR_LIGHT_SET_FAILED;
  940. }
  941. switch (pData->dwDataType)
  942. {
  943. case D3DHAL_SETLIGHT_ENABLE:
  944. if(!pDevI->m_pLights[pData->dwIndex].Enabled())
  945. pData->dwDataType = D3DHAL_SETLIGHT_DISABLE;
  946. break;
  947. case D3DHAL_SETLIGHT_DISABLE:
  948. if(pDevI->m_pLights[pData->dwIndex].Enabled())
  949. pData->dwDataType = D3DHAL_SETLIGHT_ENABLE;
  950. break;
  951. case D3DHAL_SETLIGHT_DATA:
  952. *((LPD3DLIGHT7)p) = pDevI->m_pLights[pData->dwIndex].m_Light;
  953. p = (LPDWORD)((LPBYTE)p + sizeof(D3DLIGHT7));
  954. break;
  955. }
  956. }
  957. break;
  958. }
  959. case D3DDP2OP_SETMATERIAL:
  960. {
  961. for(DWORD i = 0; i < (DWORD)pCommand->wStateCount; ++i)
  962. {
  963. LPD3DHAL_DP2SETMATERIAL pData = (LPD3DHAL_DP2SETMATERIAL)p;
  964. *pData = pDevI->lighting.material;
  965. p = (DWORD*)((BYTE*)p + sizeof(D3DHAL_DP2SETMATERIAL));
  966. }
  967. break;
  968. }
  969. case D3DDP2OP_SETTRANSFORM:
  970. {
  971. for(DWORD i = 0; i < (DWORD)pCommand->wStateCount; ++i)
  972. {
  973. LPD3DHAL_DP2SETTRANSFORM pData = (LPD3DHAL_DP2SETTRANSFORM)p;
  974. switch(pData->xfrmType)
  975. {
  976. case D3DTRANSFORMSTATE_WORLD:
  977. pData->matrix = *((LPD3DMATRIX)&pDevI->transform.world[0]);
  978. break;
  979. case D3DTRANSFORMSTATE_WORLD1:
  980. pData->matrix = *((LPD3DMATRIX)&pDevI->transform.world[1]);
  981. break;
  982. case D3DTRANSFORMSTATE_WORLD2:
  983. pData->matrix = *((LPD3DMATRIX)&pDevI->transform.world[2]);
  984. break;
  985. case D3DTRANSFORMSTATE_WORLD3:
  986. pData->matrix = *((LPD3DMATRIX)&pDevI->transform.world[3]);
  987. break;
  988. case D3DTRANSFORMSTATE_VIEW:
  989. pData->matrix = *((LPD3DMATRIX)&pDevI->transform.view);
  990. break;
  991. case D3DTRANSFORMSTATE_PROJECTION:
  992. pData->matrix = *((LPD3DMATRIX)&pDevI->transform.proj);
  993. break;
  994. case D3DTRANSFORMSTATE_TEXTURE0:
  995. pData->matrix = *((LPD3DMATRIX)&pDevI->mTexture[0]);
  996. break;
  997. case D3DTRANSFORMSTATE_TEXTURE1:
  998. pData->matrix = *((LPD3DMATRIX)&pDevI->mTexture[1]);
  999. break;
  1000. case D3DTRANSFORMSTATE_TEXTURE2:
  1001. pData->matrix = *((LPD3DMATRIX)&pDevI->mTexture[2]);
  1002. break;
  1003. case D3DTRANSFORMSTATE_TEXTURE3:
  1004. pData->matrix = *((LPD3DMATRIX)&pDevI->mTexture[3]);
  1005. break;
  1006. case D3DTRANSFORMSTATE_TEXTURE4:
  1007. pData->matrix = *((LPD3DMATRIX)&pDevI->mTexture[4]);
  1008. break;
  1009. case D3DTRANSFORMSTATE_TEXTURE5:
  1010. pData->matrix = *((LPD3DMATRIX)&pDevI->mTexture[5]);
  1011. break;
  1012. case D3DTRANSFORMSTATE_TEXTURE6:
  1013. pData->matrix = *((LPD3DMATRIX)&pDevI->mTexture[6]);
  1014. break;
  1015. case D3DTRANSFORMSTATE_TEXTURE7:
  1016. pData->matrix = *((LPD3DMATRIX)&pDevI->mTexture[7]);
  1017. break;
  1018. }
  1019. p = (DWORD*)((BYTE*)p + sizeof(D3DHAL_DP2SETTRANSFORM));
  1020. }
  1021. break;
  1022. }
  1023. case D3DDP2OP_TEXTURESTAGESTATE:
  1024. {
  1025. for(DWORD i = 0; i < (DWORD)pCommand->wStateCount; ++i)
  1026. {
  1027. LPD3DHAL_DP2TEXTURESTAGESTATE pData = (LPD3DHAL_DP2TEXTURESTAGESTATE)p;
  1028. pData->dwValue = pDevI->tsstates[pData->wStage][pData->TSState];
  1029. p = (DWORD*)((BYTE*)p + sizeof(D3DHAL_DP2TEXTURESTAGESTATE));
  1030. }
  1031. break;
  1032. }
  1033. case D3DDP2OP_FRONTENDDATA:
  1034. {
  1035. for(DWORD i = 0; i < (DWORD)pCommand->wStateCount; ++i)
  1036. {
  1037. LPD3DHAL_DP2FRONTENDDATA pData = (LPD3DHAL_DP2FRONTENDDATA)p;
  1038. if (pDevI->lpD3DMappedTexI[pData->wStage])
  1039. {
  1040. if(pDevI->lpD3DMappedTexI[pData->wStage]->D3DManaged())
  1041. pData->pTexture = pDevI->lpD3DMappedTexI[pData->wStage]->lpDDSSys;
  1042. else
  1043. pData->pTexture = pDevI->lpD3DMappedTexI[pData->wStage]->lpDDS;
  1044. }
  1045. else
  1046. {
  1047. pData->pTexture = NULL;
  1048. }
  1049. p = (DWORD*)((BYTE*)p + sizeof(D3DHAL_DP2FRONTENDDATA));
  1050. }
  1051. break;
  1052. }
  1053. case D3DDP2OP_VIEWPORTINFO:
  1054. {
  1055. for(DWORD i = 0; i < (DWORD)pCommand->wStateCount; ++i)
  1056. {
  1057. D3DVIEWPORT7 viewport;
  1058. LPD3DHAL_DP2VIEWPORTINFO lpVwpData = (LPD3DHAL_DP2VIEWPORTINFO)p;
  1059. lpVwpData->dwX = pDevI->m_Viewport.dwX;
  1060. lpVwpData->dwY = pDevI->m_Viewport.dwY;
  1061. lpVwpData->dwWidth = pDevI->m_Viewport.dwWidth;
  1062. lpVwpData->dwHeight = pDevI->m_Viewport.dwHeight;
  1063. p = (DWORD*)((BYTE*)p + sizeof(D3DHAL_DP2VIEWPORTINFO));
  1064. // The next command has to be D3DDP2OP_ZRANGE
  1065. p = (DWORD*)((BYTE*)p + sizeof(D3DHAL_DP2COMMAND));
  1066. LPD3DHAL_DP2ZRANGE pData = (LPD3DHAL_DP2ZRANGE)p;
  1067. pData->dvMinZ = pDevI->m_Viewport.dvMinZ;
  1068. pData->dvMaxZ = pDevI->m_Viewport.dvMaxZ;
  1069. p = (DWORD*)((BYTE*)p + sizeof(D3DHAL_DP2ZRANGE));
  1070. }
  1071. break;
  1072. }
  1073. case D3DDP2OP_SETCLIPPLANE:
  1074. {
  1075. for(DWORD i = 0; i < (DWORD)pCommand->wStateCount; ++i)
  1076. {
  1077. LPD3DHAL_DP2SETCLIPPLANE pData = (LPD3DHAL_DP2SETCLIPPLANE)p;
  1078. *((LPD3DVECTORH)pData->plane) = pDevI->transform.userClipPlane[pData->dwIndex];
  1079. p = (DWORD*)((BYTE*)p + sizeof(D3DHAL_DP2SETCLIPPLANE));
  1080. }
  1081. break;
  1082. }
  1083. #ifdef DBG
  1084. default:
  1085. DDASSERT(FALSE);
  1086. #endif
  1087. }
  1088. }
  1089. }
  1090. //=====================================================================
  1091. // CStateSetBuffer interface
  1092. //
  1093. #undef DPF_MODNAME
  1094. #define DPF_MODNAME "CStateSetBuffer::InsertCommand"
  1095. void CStateSetBuffer::InsertCommand(D3DHAL_DP2OPERATION op, LPVOID pData, DWORD dwDataSize)
  1096. {
  1097. const DWORD GROWSIZE = 1024;
  1098. if (m_pDP2CurrCommand != 0 && m_pDP2CurrCommand->bCommand == op)
  1099. {
  1100. if (dwDataSize + m_dwCurrentSize <= m_dwBufferSize)
  1101. {
  1102. ++m_pDP2CurrCommand->wStateCount;
  1103. memcpy(m_pBuffer + m_dwCurrentSize, pData, dwDataSize);
  1104. m_dwCurrentSize += dwDataSize;
  1105. return;
  1106. }
  1107. }
  1108. // Check for space
  1109. if (sizeof(D3DHAL_DP2COMMAND) + dwDataSize + m_dwCurrentSize > m_dwBufferSize)
  1110. {
  1111. // We need to grow the buffer
  1112. DWORD dwNewBufferSize = max(m_dwBufferSize + GROWSIZE, sizeof(D3DHAL_DP2COMMAND) + dwDataSize + m_dwCurrentSize);
  1113. BYTE *pTmp = new BYTE[dwNewBufferSize];
  1114. if (pTmp == NULL)
  1115. {
  1116. D3D_ERR("Not enough memory to create state block buffer");
  1117. throw DDERR_OUTOFMEMORY;
  1118. }
  1119. if (m_pBuffer)
  1120. {
  1121. memcpy(pTmp, m_pBuffer, m_dwCurrentSize);
  1122. delete [] m_pBuffer;
  1123. }
  1124. m_pBuffer = pTmp;
  1125. m_dwBufferSize = dwNewBufferSize;
  1126. }
  1127. // Add new instruction
  1128. m_pDP2CurrCommand = (LPD3DHAL_DP2COMMAND)(m_pBuffer + m_dwCurrentSize);
  1129. m_pDP2CurrCommand->bCommand = op;
  1130. m_pDP2CurrCommand->bReserved = 0;
  1131. m_pDP2CurrCommand->wStateCount = 1;
  1132. m_dwCurrentSize += sizeof(D3DHAL_DP2COMMAND);
  1133. memcpy(m_pBuffer + m_dwCurrentSize, pData, dwDataSize);
  1134. m_dwCurrentSize += dwDataSize;
  1135. return;
  1136. }
  1137. //=====================================================================
  1138. void InsertStateSetOp(LPDIRECT3DDEVICEI pDevI, DWORD dwOperation, DWORD dwParam, D3DSTATEBLOCKTYPE sbt)
  1139. {
  1140. CDirect3DDeviceIDP2 *device = static_cast<CDirect3DDeviceIDP2*>(pDevI);
  1141. LPD3DHAL_DP2STATESET pData;
  1142. pData = (LPD3DHAL_DP2STATESET)device->GetHalBufferPointer(D3DDP2OP_STATESET, sizeof(*pData));
  1143. pData->dwOperation = dwOperation;
  1144. pData->dwParam = dwParam;
  1145. pData->sbType = sbt;
  1146. }